From 3b4b8be8ec0c356aab101c5bb789846d44c2aa4b Mon Sep 17 00:00:00 2001 From: dkunhamb Date: Wed, 6 Aug 2025 16:07:14 -0500 Subject: [PATCH 01/32] example --- doc/source/conf.py | 1 + examples/setup/01_setup.py | 65 ++++++++++++++++++++++++++++++++ examples/setup/out/test.mechdat | Bin 0 -> 4766920 bytes examples/setup/readme.txt | 4 ++ 4 files changed, 70 insertions(+) create mode 100644 examples/setup/01_setup.py create mode 100644 examples/setup/out/test.mechdat create mode 100644 examples/setup/readme.txt diff --git a/doc/source/conf.py b/doc/source/conf.py index 5ab185673..28a53c4dd 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -239,6 +239,7 @@ "sidebar_pages": ["changelog", "index"], }, "ansys_sphinx_theme_autoapi": {"project": project, "templates": "_templates/autoapi"}, + "show_nav_level": 0, } if BUILD_CHEATSHEET: diff --git a/examples/setup/01_setup.py b/examples/setup/01_setup.py new file mode 100644 index 000000000..409cf767d --- /dev/null +++ b/examples/setup/01_setup.py @@ -0,0 +1,65 @@ +""".. _ref_setup: + +App +--- + +This section has helper scripts for Embedded App +""" +# %% +# Create an embedded instance and open an existing Mechanical File +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +from ansys.mechanical.core import App +from ansys.mechanical.core.examples import delete_downloads, download_file + +mechdat_path = download_file("cantilever.mechdat", "pymechanical", "embedding") +app = App(db_file = mechdat_path, globals=globals()) +print(app) + + +# %% +# Import a Geometry File +# ~~~~~~~~~~~~~~~~~~~~~~ + +# sphinx_gallery_start_ignore +app.new() +# sphinx_gallery_end_ignore + +geom_file_path = download_file("Contact_Debonding_Example.agdb", "pymechanical", "embedding") +geometry_import = Model.GeometryImportGroup.AddGeometryImport() +geometry_import_format = (Ansys.Mechanical.DataModel.Enums.GeometryImportPreference.Format.Automatic) +geometry_import_preferences = Ansys.ACT.Mechanical.Utilities.GeometryImportPreferences() +geometry_import_preferences.ProcessLines = True +geometry_import_preferences.NamedSelectionKey = "" +geometry_import_preferences.ProcessNamedSelections = True +geometry_import_preferences.ProcessMaterialProperties = True +geometry_import.Import(geom_file_path, geometry_import_format, geometry_import_preferences) + + +# %% +# Plot and Print the Tree (To check model so far) +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +# Plot +app.plot() + +# Print the tree +app.print_tree() + + +# %% +# Save the model +# ~~~~~~~~~~~~~~~ +from pathlib import Path + +output_path = Path.cwd() / "out" +test_mechdat_path = str(output_path / "test.mechdat") +app.save_as(test_mechdat_path) + + +# sphinx_gallery_start_ignore +# Close the app +app.close() +# Delete the downloaded files +delete_downloads() +# sphinx_gallery_end_ignore \ No newline at end of file diff --git a/examples/setup/out/test.mechdat b/examples/setup/out/test.mechdat new file mode 100644 index 0000000000000000000000000000000000000000..c4795aaa0e90420949494b2db1ffce3373569ccf GIT binary patch literal 4766920 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 z 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 zn6@iO-CKW-<|G6N5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N 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 z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs 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 literal 0 HcmV?d00001 diff --git a/examples/setup/readme.txt b/examples/setup/readme.txt new file mode 100644 index 000000000..5769a4c43 --- /dev/null +++ b/examples/setup/readme.txt @@ -0,0 +1,4 @@ +Setup +----- + +Set up Embedding and configure From 37e5ec8b9a3691117ac8f9e1afeff8084033f4e1 Mon Sep 17 00:00:00 2001 From: dkunhamb Date: Mon, 11 Aug 2025 07:23:58 -0500 Subject: [PATCH 02/32] update order --- examples/{setup => 00_setup}/01_setup.py | 0 examples/{setup => 00_setup}/out/test.mechdat | Bin 4766920 -> 4766920 bytes examples/{setup => 00_setup}/readme.txt | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename examples/{setup => 00_setup}/01_setup.py (100%) rename examples/{setup => 00_setup}/out/test.mechdat (99%) rename examples/{setup => 00_setup}/readme.txt (100%) diff --git a/examples/setup/01_setup.py b/examples/00_setup/01_setup.py similarity index 100% rename from examples/setup/01_setup.py rename to examples/00_setup/01_setup.py diff --git a/examples/setup/out/test.mechdat b/examples/00_setup/out/test.mechdat similarity index 99% rename from examples/setup/out/test.mechdat rename to examples/00_setup/out/test.mechdat index c4795aaa0e90420949494b2db1ffce3373569ccf..aa09906c89176a3fa73d19879fae04fae0b2e48b 100644 GIT binary patch delta 11951 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 Z^WUE64WA;>8zkRJy^{u`H^}@#_&*xb3=IGP delta 11803 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 diff --git a/examples/setup/readme.txt b/examples/00_setup/readme.txt similarity index 100% rename from examples/setup/readme.txt rename to examples/00_setup/readme.txt From fda6a3f2abcfefd71b4fee803ef78f7caa54c87c Mon Sep 17 00:00:00 2001 From: dkunhamb Date: Mon, 11 Aug 2025 07:25:14 -0500 Subject: [PATCH 03/32] update ignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 45ebf2285..0cff3d997 100644 --- a/.gitignore +++ b/.gitignore @@ -200,6 +200,7 @@ doc/source/api/* # Examples files downloaded when building docs examples/01_basic/out/* +examples/00_setup/out/* # pymechanical-specific mylocal.ip From 1f2895f1ffd9327d0ab53bdc9dd733608767115e Mon Sep 17 00:00:00 2001 From: rs-bh-n Date: Wed, 20 Aug 2025 16:34:16 +0530 Subject: [PATCH 04/32] added overwrite --- examples/00_setup/01_setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/00_setup/01_setup.py b/examples/00_setup/01_setup.py index 409cf767d..3cf11094f 100644 --- a/examples/00_setup/01_setup.py +++ b/examples/00_setup/01_setup.py @@ -54,7 +54,7 @@ output_path = Path.cwd() / "out" test_mechdat_path = str(output_path / "test.mechdat") -app.save_as(test_mechdat_path) +app.save_as(test_mechdat_path, overwrite=True) # sphinx_gallery_start_ignore From c0a8049c276e6b1c946cbe96a00c6f20635ea927 Mon Sep 17 00:00:00 2001 From: rs-bh-n Date: Wed, 20 Aug 2025 22:57:43 +0530 Subject: [PATCH 05/32] setup - agdb changed --- examples/00_setup/01_setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/00_setup/01_setup.py b/examples/00_setup/01_setup.py index 3cf11094f..4f9e9d493 100644 --- a/examples/00_setup/01_setup.py +++ b/examples/00_setup/01_setup.py @@ -25,7 +25,7 @@ app.new() # sphinx_gallery_end_ignore -geom_file_path = download_file("Contact_Debonding_Example.agdb", "pymechanical", "embedding") +geom_file_path = download_file("example_06_bolt_pret_geom.agdb", "pymechanical", "00_basic") geometry_import = Model.GeometryImportGroup.AddGeometryImport() geometry_import_format = (Ansys.Mechanical.DataModel.Enums.GeometryImportPreference.Format.Automatic) geometry_import_preferences = Ansys.ACT.Mechanical.Utilities.GeometryImportPreferences() From 6bb5f9f13002865970be06ddf75b7d72b254197f Mon Sep 17 00:00:00 2001 From: rs-bh-n Date: Wed, 20 Aug 2025 23:34:23 +0530 Subject: [PATCH 06/32] geom in progress --- examples/00_setup/02_geometry.py | 205 +++++++++++++++++++++++++++++++ 1 file changed, 205 insertions(+) create mode 100644 examples/00_setup/02_geometry.py diff --git a/examples/00_setup/02_geometry.py b/examples/00_setup/02_geometry.py new file mode 100644 index 000000000..9bda0cd4c --- /dev/null +++ b/examples/00_setup/02_geometry.py @@ -0,0 +1,205 @@ +""".. _ref_geometry: + +Geometry +-------- + +This section has helper scripts for Geometry +""" +# %% +# Create an embedded instance and open an existing Mechanical File +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +from ansys.mechanical.core import App +from ansys.mechanical.core.examples import delete_downloads, download_file + +mechdat_path = download_file("cantilever.mechdat", "pymechanical", "embedding") +app = App(db_file=mechdat_path, globals=globals()) +print(app) + + +# %% +# Get all bodies +# ~~~~~~~~~~~~~~~~~ +body_objects = Model.Geometry.GetChildren(DataModelObjectCategory.Body, True) +# or +# bodies_objects = Model.Geometry.GetChildren(Ansys.ACT.Automation.Mechanical.Body, True) + +bodies = [body.GetGeoBody() for body in body_objects] # GeoBodyWrapper +# or +# import itertools +# nested_list = [x.Bodies for x in ExtAPI.DataModel.GeoData.Assemblies[0].AllParts] +# bodies = list(itertools.chain(*nested_list)) + +bo = body_objects[0] # Access Object Details and RMB options +b = bodies[0] # Access Geometric Properties: 'Area', 'GeoData', 'Centroid', 'Faces', etc. + +# %% +# Find Body with Largest Volume +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +ExtAPI.Application.ActiveUnitSystem = MechanicalUnitSystem.StandardNMM + +body_names_volumes = [] +for body in body_objects: + if body.Suppressed == 0 and body.Volume: + body_names_volumes.append((body.Name, body.Volume, body.GetGeoBody().Id)) + +sorted_name_vol = sorted(body_names_volumes) +bodyname, volu, bodyid = sorted_name_vol.pop() +print(f"Unit System is: {ExtAPI.Application.ActiveUnitSystem}") +print(f"Name of the Largest Body: '{bodyname}'") +print(f"Its Volume: {round(volu.Value, 2)} {volu.Unit}") +print(f"Its id: {bodyid}") + +# %% +# Find Body by its ID +# ~~~~~~~~~~~~~~~~~~~~~~ +b2 = ExtAPI.DataModel.GeoData.GeoEntityById(bodyid) +print(f"Body Name: {b2.Name}, Body Id: {b2.Id}") + +# %% +# Find the Part that the body belongs to +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +body_name = ExtAPI.DataModel.GeoData.GeoEntityById(363).Name +part_name = ExtAPI.DataModel.GeoData.GeoEntityById(363).Part.Name +print(f"The Body named '{body_name}' belongs to the part named '{part_name}'") + +# %% +# Find Body by its ID AND print its Faces, Centroid, etc. +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +body2 = ExtAPI.DataModel.GeoData.GeoEntityById(bodyid) + +face_ids = [face.Id for face in body2.Faces] +centroids_of_each_face = [ + ExtAPI.DataModel.GeoData.GeoEntityById(face_id).Centroid for face_id in face_ids +] +for face_id, centroid in zip(face_ids, centroids_of_each_face): + print(face_id, list(centroid)) + +# %% +# Get all Vertices +# ~~~~~~~~~~~~~~~~~~~ +vertices = [] +geo = ExtAPI.DataModel.GeoData +for asm in geo.Assemblies: + for part in asm.Parts: + for body in part.Bodies: + for i in range(0, body.Vertices.Count): + vertices.append(body.Vertices[i].Id) + +print(vertices) + +# %% +# Get all edges of a given length +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +ExtAPI.Application.ActiveUnitSystem = MechanicalUnitSystem.StandardNMM +use_length = 75 + +geo = ExtAPI.DataModel.GeoData +edgelist = [] + +for asm in geo.Assemblies: + for part in asm.Parts: + for body in part.Bodies: + for edge in body.Edges: + if abs(edge.Length - use_length) <= use_length * 0.01: + edgelist.append(edge.Id) +print(edgelist) + +# %% +# Get all circular edges of a given radius +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +import math + +radius = 10 +circumference = 2 * math.pi * radius + +geo = ExtAPI.DataModel.GeoData +circlelist = [] + +for asm in geo.Assemblies: + for part in asm.Parts: + for body in part.Bodies: + for edge in body.Edges: + if ( + abs(edge.Length - circumference) <= circumference * 0.01 + and str(edge.CurveType) == "GeoCurveCircle" + ): + circlelist.append(edge.Id) +print(circlelist) + +# %% +# Get Radius of a selected edge +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +my_edge = ExtAPI.DataModel.GeoData.GeoEntityById(185) +my_edge_radius = my_edge.Radius if str(my_edge.CurveType) == "GeoCurveCircle" else 0.0 +print(my_edge_radius) + +# %% +# Create a Named Selection from a list of body Ids +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +mylist = [bodyid] + +selection_manager = ExtAPI.SelectionManager +selection = ExtAPI.SelectionManager.CreateSelectionInfo( + SelectionTypeEnum.GeometryEntities +) +selection.Ids = mylist +selection_manager.NewSelection(selection) + +ns2 = ExtAPI.DataModel.Project.Model.AddNamedSelection() +ns2.Name = "bodies2" +ns2.Location = selection + +# %% +# Find a Named Selection with a prefix +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[ + Ansys.ACT.Automation.Mechanical.NamedSelection +](True) +my_nsel = [i for i in NSall if i.Name.startswith("b")][0] +print(my_nsel.Name) + +# %% +# Create a Named Selection of all bodies with a cylindrical face +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +geo = ExtAPI.DataModel.GeoData +cyl_body_ids = [] + +for asm in geo.Assemblies: + for part in asm.Parts: + for body in part.Bodies: + countcyl = 0 + for face in body.Faces: + if ( + face.SurfaceType + == Ansys.ACT.Interfaces.Geometry.GeoSurfaceTypeEnum.GeoSurfaceCylinder + ): + countcyl = countcyl + 1 + if countcyl != 0: + cyl_body_ids.append(body.Id) + +selection_manager = ExtAPI.SelectionManager +selection = ExtAPI.SelectionManager.CreateSelectionInfo( + SelectionTypeEnum.GeometryEntities +) +selection.Ids = cyl_body_ids + +model = ExtAPI.DataModel.Project.Model +ns2 = model.AddNamedSelection() +ns2.Name = "bodies_with_cyl_face" +ns2.Location = selection +selection_manager.ClearSelection() + +# %% +# Modify material assignment +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +allbodies = ExtAPI.DataModel.Project.Model.GetChildren( + DataModelObjectCategory.Body, True +) +for body in allbodies: + body.Material = "Structural Steel" + +# %% +# Get all Coordinate Systems +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +tree_CS = ExtAPI.DataModel.Project.Model.CoordinateSystems \ No newline at end of file From 909b5000787eb748157e83736caa4c190fef2249 Mon Sep 17 00:00:00 2001 From: rs-bh-n Date: Thu, 21 Aug 2025 07:39:08 +0530 Subject: [PATCH 07/32] geometry with new model --- examples/00_setup/02_geometry.py | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/examples/00_setup/02_geometry.py b/examples/00_setup/02_geometry.py index 9bda0cd4c..eca226607 100644 --- a/examples/00_setup/02_geometry.py +++ b/examples/00_setup/02_geometry.py @@ -5,16 +5,23 @@ This section has helper scripts for Geometry """ -# %% -# Create an embedded instance and open an existing Mechanical File -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ from ansys.mechanical.core import App from ansys.mechanical.core.examples import delete_downloads, download_file +app = App(globals=globals()) +geom_file_path = download_file("example_06_bolt_pret_geom.agdb", "pymechanical", "00_basic") +geometry_import = Model.GeometryImportGroup.AddGeometryImport() +geometry_import_format = Ansys.Mechanical.DataModel.Enums.GeometryImportPreference.Format.Automatic +geometry_import_preferences = Ansys.ACT.Mechanical.Utilities.GeometryImportPreferences() +geometry_import_preferences.ProcessLines = True +geometry_import_preferences.NamedSelectionKey = "" +geometry_import_preferences.ProcessNamedSelections = True +geometry_import_preferences.ProcessMaterialProperties = True +geometry_import.Import(geom_file_path, geometry_import_format, geometry_import_preferences) + +# Plot +app.plot() -mechdat_path = download_file("cantilever.mechdat", "pymechanical", "embedding") -app = App(db_file=mechdat_path, globals=globals()) -print(app) # %% @@ -59,8 +66,8 @@ # %% # Find the Part that the body belongs to # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -body_name = ExtAPI.DataModel.GeoData.GeoEntityById(363).Name -part_name = ExtAPI.DataModel.GeoData.GeoEntityById(363).Part.Name +body_name = ExtAPI.DataModel.GeoData.GeoEntityById(59).Name +part_name = ExtAPI.DataModel.GeoData.GeoEntityById(59).Part.Name print(f"The Body named '{body_name}' belongs to the part named '{part_name}'") # %% @@ -85,14 +92,13 @@ for body in part.Bodies: for i in range(0, body.Vertices.Count): vertices.append(body.Vertices[i].Id) - print(vertices) # %% # Get all edges of a given length # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ExtAPI.Application.ActiveUnitSystem = MechanicalUnitSystem.StandardNMM -use_length = 75 +use_length = 0.100 geo = ExtAPI.DataModel.GeoData edgelist = [] @@ -110,7 +116,7 @@ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ import math -radius = 10 +radius = 0.018 circumference = 2 * math.pi * radius geo = ExtAPI.DataModel.GeoData @@ -130,7 +136,7 @@ # %% # Get Radius of a selected edge # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -my_edge = ExtAPI.DataModel.GeoData.GeoEntityById(185) +my_edge = ExtAPI.DataModel.GeoData.GeoEntityById(27) my_edge_radius = my_edge.Radius if str(my_edge.CurveType) == "GeoCurveCircle" else 0.0 print(my_edge_radius) From 09f6407f140bcd9d664e050b7af5022b6a2230ea Mon Sep 17 00:00:00 2001 From: rs-bh-n Date: Thu, 21 Aug 2025 08:38:59 +0530 Subject: [PATCH 08/32] started connections page --- examples/00_setup/02_geometry.py | 4 + examples/00_setup/03_connections.py | 120 ++++++++++++++++++++++++++++ 2 files changed, 124 insertions(+) create mode 100644 examples/00_setup/03_connections.py diff --git a/examples/00_setup/02_geometry.py b/examples/00_setup/02_geometry.py index eca226607..6c220983c 100644 --- a/examples/00_setup/02_geometry.py +++ b/examples/00_setup/02_geometry.py @@ -6,6 +6,10 @@ This section has helper scripts for Geometry """ +# %% +# Import Geometry +# ~~~~~~~~~~~~~~~ + from ansys.mechanical.core import App from ansys.mechanical.core.examples import delete_downloads, download_file app = App(globals=globals()) diff --git a/examples/00_setup/03_connections.py b/examples/00_setup/03_connections.py new file mode 100644 index 000000000..a0167760a --- /dev/null +++ b/examples/00_setup/03_connections.py @@ -0,0 +1,120 @@ +""".. _ref_connections: + +Connections +----------- + +This section has helper scripts for Connections. +""" + + +# sphinx_gallery_start_ignore +from ansys.mechanical.core import App +from ansys.mechanical.core.examples import delete_downloads, download_file + +app = App(globals=globals()) +geom_file_path = download_file("example_06_bolt_pret_geom.agdb", "pymechanical", "00_basic") +geometry_import = Model.GeometryImportGroup.AddGeometryImport() +geometry_import_format = Ansys.Mechanical.DataModel.Enums.GeometryImportPreference.Format.Automatic +geometry_import_preferences = Ansys.ACT.Mechanical.Utilities.GeometryImportPreferences() +geometry_import_preferences.ProcessLines = True +geometry_import_preferences.NamedSelectionKey = "" +geometry_import_preferences.ProcessNamedSelections = True +geometry_import_preferences.ProcessMaterialProperties = True +geometry_import.Import(geom_file_path, geometry_import_format, geometry_import_preferences) +# sphinx_gallery_end_ignore + +app.plot() + + +# %% +# Get information about all Contacts Defined +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +all_contacts = ExtAPI.DataModel.Project.Model.Connections.GetChildren( + DataModelObjectCategory.ContactRegion, True +) +for contact in all_contacts: + print( + f"\n{contact.Parent.Name} > {contact.Name} : {contact.ContactType} : {contact.Suppressed} : {contact.ContactFormulation}" + ) + print("Contact: ", contact.ContactBodies, list(contact.SourceLocation.Ids)) + print("Target: ", contact.TargetBodies, list(contact.TargetLocation.Ids)) + +# %% +# Insert a Joint using face IDs +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +face1 = 44 +face2 = 251 + +model = ExtAPI.DataModel.Project.Model +j = model.Connections.AddJoint() + +reference_scoping = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.GeometryEntities) +reference_scoping.Ids = [face1] +j.ReferenceLocation = reference_scoping + +mobile_scoping = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.GeometryEntities) +mobile_scoping.Ids = [face2] +j.MobileLocation = mobile_scoping + +# %% +# Create Automatic Connections on a chosen named selection +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +contactgroup = ExtAPI.DataModel.Project.Model.Connections.AddConnectionGroup() +contactgroup.FaceFace = True +contactgroup.FaceEdge = contactgroup.FaceEdge.No +contactgroup.GroupBy = contactgroup.GroupBy.Faces +contactgroup.Priority = contactgroup.Priority.FaceOverEdge +contactgroup.InternalObject.DetectCylindricalFacesType = 1 + +NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[ + Ansys.ACT.Automation.Mechanical.NamedSelection +](True) +my_nsel = [i for i in NSall if i.Name == "bodies3"][0] + +contactgroup.Location = my_nsel +contactgroup.CreateAutomaticConnections() + +mytree = ExtAPI.DataModel.Tree +mytree.Refresh() + +# %% +# Create a Contact region using face named selections +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +c = ExtAPI.DataModel.Project.Model.Connections +c1 = c.AddContactRegion() +NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[ + Ansys.ACT.Automation.Mechanical.NamedSelection +](True) +a = [i for i in NSall if i.Name == "faces_tube"][0] +c1.TargetLocation = a +a = [i for i in NSall if i.Name == "faces_bracket"][0] +c1.SourceLocation = a + +# %% +# Define a Bearing +# ~~~~~~~~~~~~~~~~ +brg = ExtAPI.DataModel.Project.Model.Connections.AddBearing() +brg.ReferenceRotationPlane = RotationPlane.XY +brg.StiffnessK11.Output.DiscreteValues = [Quantity("11 [N/m]")] +brg.StiffnessK22.Output.DiscreteValues = [Quantity("22 [N/m]")] +brg.StiffnessK21.Output.DiscreteValues = [Quantity("21 [N/m]")] +brg.StiffnessK12.Output.DiscreteValues = [Quantity("12 [N/m]")] + +brg.DampingC11.Output.DiscreteValues = [Quantity("111 [N sec m^-1]")] +brg.DampingC22.Output.DiscreteValues = [Quantity("122 [N sec m^-1]")] +brg.DampingC12.Output.DiscreteValues = [Quantity("112 [N sec m^-1]")] +brg.DampingC21.Output.DiscreteValues = [Quantity("121 [N sec m^-1]")] + +NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[ + Ansys.ACT.Automation.Mechanical.NamedSelection +](True) +brg.ReferenceLocation = [i for i in NSall if i.Name == "f1"][0] +brg.MobileLocation = [i for i in NSall if i.Name == "f2"][0] + + +# sphinx_gallery_start_ignore +# Close the app +app.close() +# Delete the downloaded files +delete_downloads() +# sphinx_gallery_end_ignore From fcc1b9436131757700d60a312f43c58e247c310a Mon Sep 17 00:00:00 2001 From: rs-bh-n Date: Thu, 21 Aug 2025 12:07:22 +0530 Subject: [PATCH 09/32] connections done --- examples/00_setup/02_geometry.py | 2 + examples/00_setup/03_connections.py | 58 ++++++++++++++++++----------- 2 files changed, 38 insertions(+), 22 deletions(-) diff --git a/examples/00_setup/02_geometry.py b/examples/00_setup/02_geometry.py index 6c220983c..2aced82dc 100644 --- a/examples/00_setup/02_geometry.py +++ b/examples/00_setup/02_geometry.py @@ -26,6 +26,8 @@ # Plot app.plot() +# Print the tree +app.print_tree() # %% diff --git a/examples/00_setup/03_connections.py b/examples/00_setup/03_connections.py index a0167760a..ca8dc6eae 100644 --- a/examples/00_setup/03_connections.py +++ b/examples/00_setup/03_connections.py @@ -6,7 +6,6 @@ This section has helper scripts for Connections. """ - # sphinx_gallery_start_ignore from ansys.mechanical.core import App from ansys.mechanical.core.examples import delete_downloads, download_file @@ -25,6 +24,8 @@ app.plot() +# Print the tree +app.print_tree() # %% # Get information about all Contacts Defined @@ -39,22 +40,6 @@ print("Contact: ", contact.ContactBodies, list(contact.SourceLocation.Ids)) print("Target: ", contact.TargetBodies, list(contact.TargetLocation.Ids)) -# %% -# Insert a Joint using face IDs -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -face1 = 44 -face2 = 251 - -model = ExtAPI.DataModel.Project.Model -j = model.Connections.AddJoint() - -reference_scoping = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.GeometryEntities) -reference_scoping.Ids = [face1] -j.ReferenceLocation = reference_scoping - -mobile_scoping = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.GeometryEntities) -mobile_scoping.Ids = [face2] -j.MobileLocation = mobile_scoping # %% # Create Automatic Connections on a chosen named selection @@ -69,7 +54,7 @@ NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[ Ansys.ACT.Automation.Mechanical.NamedSelection ](True) -my_nsel = [i for i in NSall if i.Name == "bodies3"][0] +my_nsel = [i for i in NSall if i.Name == "bodies_5"][0] contactgroup.Location = my_nsel contactgroup.CreateAutomaticConnections() @@ -85,11 +70,35 @@ NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[ Ansys.ACT.Automation.Mechanical.NamedSelection ](True) -a = [i for i in NSall if i.Name == "faces_tube"][0] +a = [i for i in NSall if i.Name == "block1_washer_cont"][0] c1.TargetLocation = a -a = [i for i in NSall if i.Name == "faces_bracket"][0] +a = [i for i in NSall if i.Name == "block1_washer_targ"][0] c1.SourceLocation = a + +# %% +# Insert a Joint using face IDs +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +face1 = 135 +face2 = 160 + +from pathlib import Path # delete +output_path = Path.cwd() / "out" # delete +test_mechdat_path = str(output_path / "temporarycheck.mechdat") # delete +app.save_as(test_mechdat_path, overwrite=True) # delete + + +model = ExtAPI.DataModel.Project.Model +j = model.Connections.AddJoint() + +reference_scoping = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.GeometryEntities) +reference_scoping.Ids = [face1] +j.ReferenceLocation = reference_scoping + +mobile_scoping = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.GeometryEntities) +mobile_scoping.Ids = [face2] +j.MobileLocation = mobile_scoping + # %% # Define a Bearing # ~~~~~~~~~~~~~~~~ @@ -108,8 +117,8 @@ NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[ Ansys.ACT.Automation.Mechanical.NamedSelection ](True) -brg.ReferenceLocation = [i for i in NSall if i.Name == "f1"][0] -brg.MobileLocation = [i for i in NSall if i.Name == "f2"][0] +brg.ReferenceLocation = [i for i in NSall if i.Name == "shank_surface"][0] +brg.MobileLocation = [i for i in NSall if i.Name == "shank_surface"][0] # sphinx_gallery_start_ignore @@ -118,3 +127,8 @@ # Delete the downloaded files delete_downloads() # sphinx_gallery_end_ignore + + +# %% +# TODO : Change Model for Joint and Bearing +# ~~~~~~~~~~~~~~~~ \ No newline at end of file From a034c2fd49d17578560fa4892708c01aef8a82bc Mon Sep 17 00:00:00 2001 From: rs-bh-n Date: Thu, 21 Aug 2025 15:20:25 +0530 Subject: [PATCH 10/32] nsel ready --- examples/00_setup/02_geometry.py | 18 ++- examples/00_setup/03_connections.py | 8 ++ examples/00_setup/04_named_selections.py | 148 +++++++++++++++++++++++ examples/00_setup/05_mesh.py | 50 ++++++++ examples/00_setup/06_results.py | 47 +++++++ examples/00_setup/07_tree_objects.py | 50 ++++++++ 6 files changed, 320 insertions(+), 1 deletion(-) create mode 100644 examples/00_setup/04_named_selections.py create mode 100644 examples/00_setup/05_mesh.py create mode 100644 examples/00_setup/06_results.py create mode 100644 examples/00_setup/07_tree_objects.py diff --git a/examples/00_setup/02_geometry.py b/examples/00_setup/02_geometry.py index 2aced82dc..02e30dcde 100644 --- a/examples/00_setup/02_geometry.py +++ b/examples/00_setup/02_geometry.py @@ -214,4 +214,20 @@ # %% # Get all Coordinate Systems # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -tree_CS = ExtAPI.DataModel.Project.Model.CoordinateSystems \ No newline at end of file +tree_CS = ExtAPI.DataModel.Project.Model.CoordinateSystems + + +# sphinx_gallery_start_ignore +# Save the mechdat +from pathlib import Path + +output_path = Path.cwd() / "out" +test_mechdat_path = str(output_path / "test.mechdat") +# app.save_as(test_mechdat_path, overwrite=True) + + +# Close the app +app.close() +# Delete the downloaded files +delete_downloads() +# sphinx_gallery_end_ignore diff --git a/examples/00_setup/03_connections.py b/examples/00_setup/03_connections.py index ca8dc6eae..b02ca556e 100644 --- a/examples/00_setup/03_connections.py +++ b/examples/00_setup/03_connections.py @@ -122,6 +122,14 @@ # sphinx_gallery_start_ignore +# Save the mechdat +from pathlib import Path + +output_path = Path.cwd() / "out" +test_mechdat_path = str(output_path / "test.mechdat") +# app.save_as(test_mechdat_path, overwrite=True) + + # Close the app app.close() # Delete the downloaded files diff --git a/examples/00_setup/04_named_selections.py b/examples/00_setup/04_named_selections.py new file mode 100644 index 000000000..299d9a613 --- /dev/null +++ b/examples/00_setup/04_named_selections.py @@ -0,0 +1,148 @@ +""".. _ref_named_selections: + +Named Selections +---------------- + +This section has helper scripts for Named Selections. +""" + +# %% +# Import Geometry +# ~~~~~~~~~~~~~~~ + +from ansys.mechanical.core import App +from ansys.mechanical.core.examples import delete_downloads, download_file +app = App(globals=globals()) +geom_file_path = download_file("example_06_bolt_pret_geom.agdb", "pymechanical", "00_basic") +geometry_import = Model.GeometryImportGroup.AddGeometryImport() +geometry_import_format = Ansys.Mechanical.DataModel.Enums.GeometryImportPreference.Format.Automatic +geometry_import_preferences = Ansys.ACT.Mechanical.Utilities.GeometryImportPreferences() +geometry_import_preferences.ProcessLines = True +geometry_import_preferences.NamedSelectionKey = "" +geometry_import_preferences.ProcessNamedSelections = True +geometry_import_preferences.ProcessMaterialProperties = True +geometry_import.Import(geom_file_path, geometry_import_format, geometry_import_preferences) + +# Plot +app.plot() + +# Print the tree +app.print_tree() + + + +# %% +# Fetch all Named Selections +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +# ALL NAMED SELECTIONS +nsall = ExtAPI.DataModel.GetObjectsByType( + DataModelObjectCategory.NamedSelections.NamedSelection +) + +# %% +# Delete a named selection +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[ + Ansys.ACT.Automation.Mechanical.NamedSelection +](True) + +# Delete a named selection by name +a = [i for i in NSall if i.Name == "S1"][0] +a.Delete() + +# Alternative way to delete by name +b = ExtAPI.DataModel.Tree.GetObjectsByName("S1")[0] +b.Delete() + +# %% +# Create a named selection +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +selection_manager = ExtAPI.SelectionManager +selection = ExtAPI.SelectionManager.CreateSelectionInfo( + SelectionTypeEnum.GeometryEntities +) +selection.Ids = [1, 2, 3, 4] + +model = ExtAPI.DataModel.Project.Model +ns2 = model.AddNamedSelection() +ns2.Name = "faces" +ns2.Location = selection +selection_manager.ClearSelection() + +# %% +# Create a Named Selection by Worksheet +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +NS1 = DataModel.Project.Model.AddNamedSelection() +NS1.ScopingMethod = GeometryDefineByType.Worksheet +GenerationCriteria = NS1.GenerationCriteria + +Criterion1 = Ansys.ACT.Automation.Mechanical.NamedSelectionCriterion() +Criterion1.Action = SelectionActionType.Add +Criterion1.EntityType = SelectionType.GeoFace +Criterion1.Criterion = SelectionCriterionType.LocationY +Criterion1.Operator = SelectionOperatorType.Equal +Criterion1.Value = Quantity("0 [m]") +GenerationCriteria.Add(Criterion1) + +Criterion2 = Ansys.ACT.Automation.Mechanical.NamedSelectionCriterion() +Criterion2.Action = SelectionActionType.Add +Criterion2.EntityType = SelectionType.GeoFace +Criterion2.Criterion = SelectionCriterionType.LocationZ +Criterion2.Operator = SelectionOperatorType.Equal +Criterion2.Value = Quantity("0 [m]") +GenerationCriteria.Add(Criterion2) + +NS1.Generate() + +# %% +# Find a Named Selection +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[ + Ansys.ACT.Automation.Mechanical.NamedSelection +](True) + +# Find a named selection by name +a = [i for i in NSall if i.Name == "bodies2"][0] + +# Access entities in the named selection +entities = a.Entities +print(entities) + +# %% +# Identify Named Selections based on Name and Type +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[ + Ansys.ACT.Automation.Mechanical.NamedSelection +](True) + +# Filter named selections based on keywords in their names +keywords = ["fix", "bushing", "roller"] +ns1 = [i for i in NSall if keywords[0] in i.Name] +ns2 = [i for i in NSall if keywords[1] in i.Name] +ns3 = [i for i in NSall if keywords[2] in i.Name] +filtered = ns1 + ns2 + ns3 + +# Further filter based on entity type +VertexNsels = [ + i + for i in filtered + if str(ExtAPI.DataModel.GeoData.GeoEntityById(i.Ids[0]).Type) == "GeoVertex" +] + + + +# sphinx_gallery_start_ignore +# Save the mechdat +from pathlib import Path + +output_path = Path.cwd() / "out" +test_mechdat_path = str(output_path / "test.mechdat") +app.save_as(test_mechdat_path, overwrite=True) + + +# Close the app +app.close() +# Delete the downloaded files +delete_downloads() +# sphinx_gallery_end_ignore diff --git a/examples/00_setup/05_mesh.py b/examples/00_setup/05_mesh.py new file mode 100644 index 000000000..7ce201b57 --- /dev/null +++ b/examples/00_setup/05_mesh.py @@ -0,0 +1,50 @@ +""".. _ref_mesh: + +Mesh +---- + +This section has helper scripts for Named Selections. +""" + + +# %% +# Import Geometry +# ~~~~~~~~~~~~~~~ + +from ansys.mechanical.core import App +from ansys.mechanical.core.examples import delete_downloads, download_file +app = App(globals=globals()) +geom_file_path = download_file("example_06_bolt_pret_geom.agdb", "pymechanical", "00_basic") +geometry_import = Model.GeometryImportGroup.AddGeometryImport() +geometry_import_format = Ansys.Mechanical.DataModel.Enums.GeometryImportPreference.Format.Automatic +geometry_import_preferences = Ansys.ACT.Mechanical.Utilities.GeometryImportPreferences() +geometry_import_preferences.ProcessLines = True +geometry_import_preferences.NamedSelectionKey = "" +geometry_import_preferences.ProcessNamedSelections = True +geometry_import_preferences.ProcessMaterialProperties = True +geometry_import.Import(geom_file_path, geometry_import_format, geometry_import_preferences) + +# Plot +app.plot() + +# Print the tree +app.print_tree() + + + + + +# sphinx_gallery_start_ignore +# Save the mechdat +from pathlib import Path + +output_path = Path.cwd() / "out" +test_mechdat_path = str(output_path / "test.mechdat") +# app.save_as(test_mechdat_path, overwrite=True) + + +# Close the app +app.close() +# Delete the downloaded files +delete_downloads() +# sphinx_gallery_end_ignore diff --git a/examples/00_setup/06_results.py b/examples/00_setup/06_results.py new file mode 100644 index 000000000..13074c482 --- /dev/null +++ b/examples/00_setup/06_results.py @@ -0,0 +1,47 @@ +""".. _ref_results: + +Results +------- + +This section has helper scripts for Results. +""" + +# %% +# Import Geometry +# ~~~~~~~~~~~~~~~ + +from ansys.mechanical.core import App +from ansys.mechanical.core.examples import delete_downloads, download_file + +app = App(globals=globals()) +geom_file_path = download_file("example_06_bolt_pret_geom.agdb", "pymechanical", "00_basic") +geometry_import = Model.GeometryImportGroup.AddGeometryImport() +geometry_import_format = Ansys.Mechanical.DataModel.Enums.GeometryImportPreference.Format.Automatic +geometry_import_preferences = Ansys.ACT.Mechanical.Utilities.GeometryImportPreferences() +geometry_import_preferences.ProcessLines = True +geometry_import_preferences.NamedSelectionKey = "" +geometry_import_preferences.ProcessNamedSelections = True +geometry_import_preferences.ProcessMaterialProperties = True +geometry_import.Import(geom_file_path, geometry_import_format, geometry_import_preferences) + +# Plot +app.plot() + +# Print the tree +app.print_tree() + + +# sphinx_gallery_start_ignore +# Save the mechdat +from pathlib import Path + +output_path = Path.cwd() / "out" +test_mechdat_path = str(output_path / "test.mechdat") +# app.save_as(test_mechdat_path, overwrite=True) + + +# Close the app +app.close() +# Delete the downloaded files +delete_downloads() +# sphinx_gallery_end_ignore diff --git a/examples/00_setup/07_tree_objects.py b/examples/00_setup/07_tree_objects.py new file mode 100644 index 000000000..e1574c3b1 --- /dev/null +++ b/examples/00_setup/07_tree_objects.py @@ -0,0 +1,50 @@ +""".. _ref_tree_objects: + +Tree Objects +------------ + +This section has helper scripts for Tree Objects. +""" + + +# %% +# Import Geometry +# ~~~~~~~~~~~~~~~ + +from ansys.mechanical.core import App +from ansys.mechanical.core.examples import delete_downloads, download_file +app = App(globals=globals()) +geom_file_path = download_file("example_06_bolt_pret_geom.agdb", "pymechanical", "00_basic") +geometry_import = Model.GeometryImportGroup.AddGeometryImport() +geometry_import_format = Ansys.Mechanical.DataModel.Enums.GeometryImportPreference.Format.Automatic +geometry_import_preferences = Ansys.ACT.Mechanical.Utilities.GeometryImportPreferences() +geometry_import_preferences.ProcessLines = True +geometry_import_preferences.NamedSelectionKey = "" +geometry_import_preferences.ProcessNamedSelections = True +geometry_import_preferences.ProcessMaterialProperties = True +geometry_import.Import(geom_file_path, geometry_import_format, geometry_import_preferences) + +# Plot +app.plot() + +# Print the tree +app.print_tree() + + + + + +# sphinx_gallery_start_ignore +# Save the mechdat +from pathlib import Path + +output_path = Path.cwd() / "out" +test_mechdat_path = str(output_path / "test.mechdat") +# app.save_as(test_mechdat_path, overwrite=True) + + +# Close the app +app.close() +# Delete the downloaded files +delete_downloads() +# sphinx_gallery_end_ignore From 0377c050b34ecfe6a79cf20e4ab777006b9af58c Mon Sep 17 00:00:00 2001 From: rs-bh-n Date: Fri, 22 Aug 2025 00:15:22 +0530 Subject: [PATCH 11/32] results done --- examples/00_setup/04_named_selections.py | 44 +++----- examples/00_setup/05_mesh.py | 72 +++++++++++-- examples/00_setup/06_results.py | 127 ++++++++++++++++++++--- 3 files changed, 196 insertions(+), 47 deletions(-) diff --git a/examples/00_setup/04_named_selections.py b/examples/00_setup/04_named_selections.py index 299d9a613..0c0cce210 100644 --- a/examples/00_setup/04_named_selections.py +++ b/examples/00_setup/04_named_selections.py @@ -6,14 +6,13 @@ This section has helper scripts for Named Selections. """ -# %% -# Import Geometry -# ~~~~~~~~~~~~~~~ + +# sphinx_gallery_start_ignore from ansys.mechanical.core import App from ansys.mechanical.core.examples import delete_downloads, download_file app = App(globals=globals()) -geom_file_path = download_file("example_06_bolt_pret_geom.agdb", "pymechanical", "00_basic") +geom_file_path = download_file("example_05_td26_Rubber_Boot_Seal.agdb", "pymechanical", "00_basic") geometry_import = Model.GeometryImportGroup.AddGeometryImport() geometry_import_format = Ansys.Mechanical.DataModel.Enums.GeometryImportPreference.Format.Automatic geometry_import_preferences = Ansys.ACT.Mechanical.Utilities.GeometryImportPreferences() @@ -22,6 +21,7 @@ geometry_import_preferences.ProcessNamedSelections = True geometry_import_preferences.ProcessMaterialProperties = True geometry_import.Import(geom_file_path, geometry_import_format, geometry_import_preferences) +# sphinx_gallery_end_ignore # Plot app.plot() @@ -36,33 +36,27 @@ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # ALL NAMED SELECTIONS -nsall = ExtAPI.DataModel.GetObjectsByType( - DataModelObjectCategory.NamedSelections.NamedSelection -) +nsall = ExtAPI.DataModel.GetObjectsByType(DataModelObjectCategory.NamedSelections.NamedSelection) # %% # Delete a named selection # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[ - Ansys.ACT.Automation.Mechanical.NamedSelection -](True) +NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[Ansys.ACT.Automation.Mechanical.NamedSelection](True) # Delete a named selection by name -a = [i for i in NSall if i.Name == "S1"][0] +a = [i for i in NSall if i.Name == "Top_Face"][0] a.Delete() # Alternative way to delete by name -b = ExtAPI.DataModel.Tree.GetObjectsByName("S1")[0] +b = ExtAPI.DataModel.GetObjectsByName("Bottom_Face")[0] b.Delete() # %% # Create a named selection # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ selection_manager = ExtAPI.SelectionManager -selection = ExtAPI.SelectionManager.CreateSelectionInfo( - SelectionTypeEnum.GeometryEntities -) -selection.Ids = [1, 2, 3, 4] +selection = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.GeometryEntities) +selection.Ids = [216,221,224] model = ExtAPI.DataModel.Project.Model ns2 = model.AddNamedSelection() @@ -98,36 +92,32 @@ # %% # Find a Named Selection # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[ - Ansys.ACT.Automation.Mechanical.NamedSelection -](True) +NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[Ansys.ACT.Automation.Mechanical.NamedSelection](True) # Find a named selection by name -a = [i for i in NSall if i.Name == "bodies2"][0] +a = [i for i in NSall if i.Name == "Rubber_Bodies30"][0] # Access entities in the named selection entities = a.Entities -print(entities) +print(entities[0].Volume) # %% # Identify Named Selections based on Name and Type # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[ - Ansys.ACT.Automation.Mechanical.NamedSelection -](True) +NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[Ansys.ACT.Automation.Mechanical.NamedSelection](True) # Filter named selections based on keywords in their names -keywords = ["fix", "bushing", "roller"] +keywords = ["Rubber_Bodies30", "Inner_Faces30","Outer_Faces30"] ns1 = [i for i in NSall if keywords[0] in i.Name] ns2 = [i for i in NSall if keywords[1] in i.Name] ns3 = [i for i in NSall if keywords[2] in i.Name] filtered = ns1 + ns2 + ns3 # Further filter based on entity type -VertexNsels = [ +FaceNsels = [ i for i in filtered - if str(ExtAPI.DataModel.GeoData.GeoEntityById(i.Ids[0]).Type) == "GeoVertex" + if str(ExtAPI.DataModel.GeoData.GeoEntityById(i.Ids[0]).Type) == "GeoFace" ] diff --git a/examples/00_setup/05_mesh.py b/examples/00_setup/05_mesh.py index 7ce201b57..ca1b0f5ea 100644 --- a/examples/00_setup/05_mesh.py +++ b/examples/00_setup/05_mesh.py @@ -6,13 +6,10 @@ This section has helper scripts for Named Selections. """ - -# %% -# Import Geometry -# ~~~~~~~~~~~~~~~ - +# sphinx_gallery_start_ignore from ansys.mechanical.core import App from ansys.mechanical.core.examples import delete_downloads, download_file + app = App(globals=globals()) geom_file_path = download_file("example_06_bolt_pret_geom.agdb", "pymechanical", "00_basic") geometry_import = Model.GeometryImportGroup.AddGeometryImport() @@ -23,6 +20,8 @@ geometry_import_preferences.ProcessNamedSelections = True geometry_import_preferences.ProcessMaterialProperties = True geometry_import.Import(geom_file_path, geometry_import_format, geometry_import_preferences) +# sphinx_gallery_end_ignore + # Plot app.plot() @@ -31,7 +30,68 @@ app.print_tree() +# %% +# Insert a Local Meshing Control for a Named Selection +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +NSall = Model.NamedSelections.GetChildren[Ansys.ACT.Automation.Mechanical.NamedSelection](True) +use_nsel = [i for i in NSall if i.Name == "shank"][0] + +ms = Model.Mesh.AddAutomaticMethod() +ms.Location = use_nsel +ms.Method = ms.Method.AllTriAllTet +ms.Algorithm = ms.Algorithm.PatchConforming + + +# %% +# Generate Mesh +# ~~~~~~~~~~~~~ +Model.Mesh.GenerateMesh() +print(Model.Mesh.ObjectState) + + +# %% +# Get Element Count of a meshed body +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +meshdata = DataModel.MeshDataByName("Global") +print(use_nsel.Ids[0]) +geoBody = DataModel.GeoData.GeoEntityById(use_nsel.Ids[0]) +body = Model.Geometry.GetBody(geoBody) +meshregion = meshdata.MeshRegionById(geoBody.Id) +print(body.Name, meshregion.ElementCount) + + +# sphinx_gallery_start_ignore +Model.Mesh.ClearGeneratedData() +# sphinx_gallery_end_ignore + + +# %% +# Insert a Sweep Method (Scoping Method: Named Selection) +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +NSall = Model.NamedSelections.GetChildren[Ansys.ACT.Automation.Mechanical.NamedSelection](True) +use_nsel = [i for i in NSall if i.Name == "bodies_5"][0] + +mesh = Model.Mesh +mesh_method = mesh.AddAutomaticMethod() +mesh_method.Location = use_nsel +mesh_method.Method = MethodType.Sweep + +# %% +# Insert a Mesh Sizing Control (Scoping Method: Geometry Selection) +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +NSall = Model.NamedSelections.GetChildren[Ansys.ACT.Automation.Mechanical.NamedSelection](True) +ns = [i for i in NSall if "bottom_surface" in i.Name][0] + +bot_face = DataModel.GeoData.GeoEntityById(ns.Ids[0]) +body_ids = [edge.Id for edge in bot_face.Edges] +sel = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.GeometryEntities) +sel.Ids = body_ids +mesh = Model.Mesh +mesh_sizing = mesh.AddSizing() +mesh_sizing.Location = sel +mesh_sizing.Behavior = SizingBehavior.Hard # sphinx_gallery_start_ignore @@ -39,7 +99,7 @@ from pathlib import Path output_path = Path.cwd() / "out" -test_mechdat_path = str(output_path / "test.mechdat") +test_mechdat_path = str(output_path / "test5.mechdat") # app.save_as(test_mechdat_path, overwrite=True) diff --git a/examples/00_setup/06_results.py b/examples/00_setup/06_results.py index 13074c482..b580b4e41 100644 --- a/examples/00_setup/06_results.py +++ b/examples/00_setup/06_results.py @@ -6,23 +6,20 @@ This section has helper scripts for Results. """ -# %% -# Import Geometry -# ~~~~~~~~~~~~~~~ +# sphinx_gallery_start_ignore +import os from ansys.mechanical.core import App from ansys.mechanical.core.examples import delete_downloads, download_file -app = App(globals=globals()) -geom_file_path = download_file("example_06_bolt_pret_geom.agdb", "pymechanical", "00_basic") -geometry_import = Model.GeometryImportGroup.AddGeometryImport() -geometry_import_format = Ansys.Mechanical.DataModel.Enums.GeometryImportPreference.Format.Automatic -geometry_import_preferences = Ansys.ACT.Mechanical.Utilities.GeometryImportPreferences() -geometry_import_preferences.ProcessLines = True -geometry_import_preferences.NamedSelectionKey = "" -geometry_import_preferences.ProcessNamedSelections = True -geometry_import_preferences.ProcessMaterialProperties = True -geometry_import.Import(geom_file_path, geometry_import_format, geometry_import_preferences) +mechdat_path = download_file("example_03_simple_bolt_new.mechdat", "pymechanical", "00_basic") +app = App(db_file = mechdat_path, globals=globals()) +print(app) + + +# sphinx_gallery_end_ignore + + # Plot app.plot() @@ -30,6 +27,108 @@ # Print the tree app.print_tree() +# %% +# Solve +# ~~~~~ +static_struct = app.DataModel.AnalysisList[0] +static_struct.Solution.ClearGeneratedData() +print("Solution Status:", static_struct.Solution.Status) + +static_struct.Solution.Solve() +print("Solution Status:", static_struct.Solution.Status) + + +# %% +# Results that are accessible for GetResult +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +result_names = static_struct.GetResultsData().ResultNames +print("Available Results:", ", ".join(result_names)) + + +# %% +# List Result Objects that can be added +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +all_results = [x for x in dir(static_struct) if str(x)[:3]=="Add"] +print(all_results) + +# %% +# Insert a Result +# ~~~~~~~~~~~~~~~ + + +total_deformation = static_struct.Solution.AddTotalDeformation() +total_deformation.EvaluateAllResults() + + +# %% Access max and min of a result +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +minimum_deformation = total_deformation.Minimum +maximum_deformation = total_deformation.Maximum +print(f"Minimum Deformation: {minimum_deformation}") +print(f"Maximum Deformation: {maximum_deformation}") + +# %% +# Get Results by Node Number +# ~~~~~~~~~~~~~~~~~~~~~~~~~~ +node_number = 2000 +result_data = static_struct.GetResultsData() +node_values = result_data.GetResult("U").GetNodeValues(node_number) +print(f"Node {node_number} Values:", node_values) + +# %% +# Access other results +# ~~~~~~~~~~~~~~~~~~~~ + + +# Insert a command object +cs = static_struct.Solution.AddCommandSnippet() + +# %% +# Fatigue Results +# ~~~~~~~~~~~~~~~ +solution = static_struct.Solution +fatigue_tool = solution.AddFatigueTool() + +safety_factor = fatigue_tool.AddSafetyFactor() +selection = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.MeshNodes) +selection.Ids = [1, 2] +safety_factor.Location = selection +minimum = safety_factor.Minimum +print("Safety Factor Minimum:", minimum) + +# Export safety factor to a text file +fname = "safety_factor_results.txt" +safety_factor.ExportToTextFile(True, fname) + +# %% +# User-defined Result +# ~~~~~~~~~~~~~~~~~~~ +user_result = static_struct.Solution.AddUserDefinedResult() +print("User-defined Result Added:", user_result) + +# %% +# Get number of result sets +# ~~~~~~~~~~~~~~~~~~~~~~~~~ +reader = static_struct.GetResultsData() +result_set_count = reader.ListTimeFreq.Count +print("Number of Result Sets:", result_set_count) + + + +# %% +# Export all results in the tree to PNG (2D image) files +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +results = DataModel.GetObjectsByType(DataModelObjectCategory.Result) +for result in results: + result.Activate() + Graphics.Camera.SetSpecificViewOrientation(ViewOrientationType.Front) + image_path = os.path.join(os.getcwd(),"out",result.Name+".png") + Graphics.ExportImage(str(image_path), GraphicsImageExportFormat.PNG, Ansys.Mechanical.Graphics.GraphicsImageExportSettings()) +print("Done with Exporting Results") + + # sphinx_gallery_start_ignore # Save the mechdat @@ -43,5 +142,5 @@ # Close the app app.close() # Delete the downloaded files -delete_downloads() +# delete_downloads() # sphinx_gallery_end_ignore From 404cc5f469d260c7337cfbd1c6487b82023f7a69 Mon Sep 17 00:00:00 2001 From: rs-bh-n Date: Fri, 22 Aug 2025 00:22:09 +0530 Subject: [PATCH 12/32] started tree objects --- examples/00_setup/07_tree_objects.py | 130 ++++++++++++++++++++++++++- 1 file changed, 126 insertions(+), 4 deletions(-) diff --git a/examples/00_setup/07_tree_objects.py b/examples/00_setup/07_tree_objects.py index e1574c3b1..db9febbe1 100644 --- a/examples/00_setup/07_tree_objects.py +++ b/examples/00_setup/07_tree_objects.py @@ -7,14 +7,12 @@ """ -# %% -# Import Geometry -# ~~~~~~~~~~~~~~~ +# sphinx_gallery_start_ignore from ansys.mechanical.core import App from ansys.mechanical.core.examples import delete_downloads, download_file app = App(globals=globals()) -geom_file_path = download_file("example_06_bolt_pret_geom.agdb", "pymechanical", "00_basic") +geom_file_path = download_file("Valve.pmdb", "pymechanical", "embedding") geometry_import = Model.GeometryImportGroup.AddGeometryImport() geometry_import_format = Ansys.Mechanical.DataModel.Enums.GeometryImportPreference.Format.Automatic geometry_import_preferences = Ansys.ACT.Mechanical.Utilities.GeometryImportPreferences() @@ -23,6 +21,8 @@ geometry_import_preferences.ProcessNamedSelections = True geometry_import_preferences.ProcessMaterialProperties = True geometry_import.Import(geom_file_path, geometry_import_format, geometry_import_preferences) +# sphinx_gallery_end_ignore + # Plot app.plot() @@ -32,6 +32,128 @@ +# %% +# Accessing Geometry +# ~~~~~~~~~~~~~~~~~~ +# Example of accessing geometry by ID. + +body = ExtAPI.DataModel.GeoData.GeoEntityById(312) + +# %% +# Accessing Mesh Data +# ~~~~~~~~~~~~~~~~~~~~~~ +# Example of accessing mesh data by name. + +node = ExtAPI.DataModel.MeshDataByName("Global").NodeById(555) +element = ExtAPI.DataModel.MeshDataByName("Global").ElementById(444) + +# %% +# Accessing All Objects and Child Objects +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Examples of accessing all objects, bodies, named selections, and contact regions. + +# All tree objects +AllObj = ExtAPI.DataModel.Project.Model.GetChildren(DataModelObjectCategory.DataModelObject, True) + +# All bodies +all_bodies = ExtAPI.DataModel.Project.Model.GetChildren(DataModelObjectCategory.Body, True) + +# All named selections +ns_all = ExtAPI.DataModel.GetObjectsByType(DataModelObjectCategory.NamedSelections.NamedSelection) + +# All contact regions +abc = ExtAPI.DataModel.GetObjectsByType(DataModelObjectCategory.ContactRegion) +all_contacts = ExtAPI.DataModel.Project.Model.Connections.GetChildren(DataModelObjectCategory.ContactRegion, True) + +# A specific contact region +my_contact = [contact for contact in all_contacts if contact.Name == "Contact Region"][0] + +# All result objects of a specific type +all_norm_stress = ExtAPI.DataModel.GetObjectsByType(DataModelObjectCategory.Result.NormalStress) + +# Other examples +all_remote_points = ExtAPI.DataModel.GetObjectsByType(DataModelObjectCategory.RemotePoint) +ana = ExtAPI.DataModel.Tree.GetObjectsByType(DataModelObjectCategory.Analysis) + +# Using ACT Automation API +all_contacts2 = ExtAPI.DataModel.Project.Model.Connections.GetChildren[Ansys.ACT.Automation.Mechanical.Connections.ContactRegion](True) +all_remote_points2 = ExtAPI.DataModel.Project.Model.GetChildren[Ansys.ACT.Automation.Mechanical.RemotePoint](True) +all_folders = ExtAPI.DataModel.Project.Model.GetChildren[Ansys.ACT.Automation.Mechanical.TreeGroupingFolder](True) + +# %% +# Finding Duplicate Objects by Name +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Example of finding duplicate objects by name. + +import collections + +AllObj = ExtAPI.DataModel.Project.Model.GetChildren(DataModelObjectCategory.DataModelObject, True) +AllObjNames = [x.Name for x in AllObj] +duplicates_by_name = [item for item, count in collections.Counter(AllObjNames).items() if count > 1] +print(duplicates_by_name) + +# %% +# Using DataObjects and GetByName +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Example of using DataObjects and GetByName. + +c1 = 'Solution' +c2 = 'Far-field Sound Power Level Waterfall Diagram' +c = ExtAPI.DataModel.AnalysisList[0].DataObjects.GetByName(c1).DataObjects.GetByName(c2) + +# %% +# Using DataObjects, NamesByType, and GetByName +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Example of using DataObjects, NamesByType, and GetByName. + +new_contact_list = [] +dataobjects = ExtAPI.DataModel.AnalysisList[0].DataObjects +for group in dataobjects: + print(group.Type) +names = dataobjects.NamesByType('ContactGroup') +for name in names: + connet_data_objects = dataobjects.GetByName(name).DataObjects + c_names = connet_data_objects.Names + for c_name in c_names: + type_c = connet_data_objects.GetByName(c_name).Type + if type_c == 'ConnectionGroup': + contacts_list = connet_data_objects.GetByName(c_name).DataObjects.NamesByType('ContactRegion') + for contact in contacts_list: + contact_type = connet_data_objects.GetByName(c_name).DataObjects.GetByName(contact).PropertyValue('ContactType') + contact_state = connet_data_objects.GetByName(c_name).DataObjects.GetByName(contact).PropertyValue("Suppressed") + if contact_state == 0 and contact_type == 1: + new_contact_list.append(contact) +print(new_contact_list) + +# %% +# Using GetObjectsByName +# ~~~~~~~~~~~~~~~~~~~~~~~~~ +# Example of using GetObjectsByName. + +bb = ExtAPI.DataModel.GetObjectsByName("Gray Cast Iron")[0] + +# %% +# Accessing a Named Selection +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Example of accessing a named selection. + +NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[Ansys.ACT.Automation.Mechanical.NamedSelection](True) +my_nsel = [i for i in NSall if i.Name.startswith("b")][0] +my_nsel2 = [i for i in NSall if i.Name == "aaa"][0] + +# %% +# Get All Unsuppressed Bodies and Point Masses +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Example of getting all unsuppressed bodies and point masses. + +all_bodies = ExtAPI.DataModel.Project.Model.GetChildren(DataModelObjectCategory.Body, True) +all_bodies = [i for i in all_bodies if not i.Suppressed] +print(len(all_bodies)) + +all_pm = ExtAPI.DataModel.Project.Model.GetChildren(DataModelObjectCategory.PointMass, True) +all_pm = [i for i in all_pm if not i.Suppressed] + + # sphinx_gallery_start_ignore From d10343c152837d8b2011d1ec557f6bfb830c69af Mon Sep 17 00:00:00 2001 From: rs-bh-n Date: Fri, 22 Aug 2025 00:34:59 +0530 Subject: [PATCH 13/32] tree objects done --- examples/00_setup/07_tree_objects.py | 65 +++++++++++++++++++--------- 1 file changed, 44 insertions(+), 21 deletions(-) diff --git a/examples/00_setup/07_tree_objects.py b/examples/00_setup/07_tree_objects.py index db9febbe1..cc92eb3e8 100644 --- a/examples/00_setup/07_tree_objects.py +++ b/examples/00_setup/07_tree_objects.py @@ -6,11 +6,10 @@ This section has helper scripts for Tree Objects. """ - - # sphinx_gallery_start_ignore from ansys.mechanical.core import App from ansys.mechanical.core.examples import delete_downloads, download_file + app = App(globals=globals()) geom_file_path = download_file("Valve.pmdb", "pymechanical", "embedding") geometry_import = Model.GeometryImportGroup.AddGeometryImport() @@ -31,7 +30,6 @@ app.print_tree() - # %% # Accessing Geometry # ~~~~~~~~~~~~~~~~~~ @@ -63,7 +61,9 @@ # All contact regions abc = ExtAPI.DataModel.GetObjectsByType(DataModelObjectCategory.ContactRegion) -all_contacts = ExtAPI.DataModel.Project.Model.Connections.GetChildren(DataModelObjectCategory.ContactRegion, True) +all_contacts = ExtAPI.DataModel.Project.Model.Connections.GetChildren( + DataModelObjectCategory.ContactRegion, True +) # A specific contact region my_contact = [contact for contact in all_contacts if contact.Name == "Contact Region"][0] @@ -76,9 +76,15 @@ ana = ExtAPI.DataModel.Tree.GetObjectsByType(DataModelObjectCategory.Analysis) # Using ACT Automation API -all_contacts2 = ExtAPI.DataModel.Project.Model.Connections.GetChildren[Ansys.ACT.Automation.Mechanical.Connections.ContactRegion](True) -all_remote_points2 = ExtAPI.DataModel.Project.Model.GetChildren[Ansys.ACT.Automation.Mechanical.RemotePoint](True) -all_folders = ExtAPI.DataModel.Project.Model.GetChildren[Ansys.ACT.Automation.Mechanical.TreeGroupingFolder](True) +all_contacts2 = ExtAPI.DataModel.Project.Model.Connections.GetChildren[ + Ansys.ACT.Automation.Mechanical.Connections.ContactRegion +](True) +all_remote_points2 = ExtAPI.DataModel.Project.Model.GetChildren[ + Ansys.ACT.Automation.Mechanical.RemotePoint +](True) +all_folders = ExtAPI.DataModel.Project.Model.GetChildren[ + Ansys.ACT.Automation.Mechanical.TreeGroupingFolder +](True) # %% # Finding Duplicate Objects by Name @@ -92,14 +98,21 @@ duplicates_by_name = [item for item, count in collections.Counter(AllObjNames).items() if count > 1] print(duplicates_by_name) + +# sphinx_gallery_start_ignore +static_struct = Model.AddStaticStructuralAnalysis() +static_struct.Solution.AddEquivalentStress() +# sphinx_gallery_end_ignore + + # %% # Using DataObjects and GetByName # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Example of using DataObjects and GetByName. -c1 = 'Solution' -c2 = 'Far-field Sound Power Level Waterfall Diagram' -c = ExtAPI.DataModel.AnalysisList[0].DataObjects.GetByName(c1).DataObjects.GetByName(c2) +c1 = "Solution" +c2 = "Equivalent Stress" +c = DataModel.AnalysisList[0].DataObjects.GetByName(c1).DataObjects.GetByName(c2) # %% # Using DataObjects, NamesByType, and GetByName @@ -110,17 +123,27 @@ dataobjects = ExtAPI.DataModel.AnalysisList[0].DataObjects for group in dataobjects: print(group.Type) -names = dataobjects.NamesByType('ContactGroup') +names = dataobjects.NamesByType("ContactGroup") for name in names: connet_data_objects = dataobjects.GetByName(name).DataObjects c_names = connet_data_objects.Names for c_name in c_names: type_c = connet_data_objects.GetByName(c_name).Type - if type_c == 'ConnectionGroup': - contacts_list = connet_data_objects.GetByName(c_name).DataObjects.NamesByType('ContactRegion') + if type_c == "ConnectionGroup": + contacts_list = connet_data_objects.GetByName(c_name).DataObjects.NamesByType( + "ContactRegion" + ) for contact in contacts_list: - contact_type = connet_data_objects.GetByName(c_name).DataObjects.GetByName(contact).PropertyValue('ContactType') - contact_state = connet_data_objects.GetByName(c_name).DataObjects.GetByName(contact).PropertyValue("Suppressed") + contact_type = ( + connet_data_objects.GetByName(c_name) + .DataObjects.GetByName(contact) + .PropertyValue("ContactType") + ) + contact_state = ( + connet_data_objects.GetByName(c_name) + .DataObjects.GetByName(contact) + .PropertyValue("Suppressed") + ) if contact_state == 0 and contact_type == 1: new_contact_list.append(contact) print(new_contact_list) @@ -130,16 +153,18 @@ # ~~~~~~~~~~~~~~~~~~~~~~~~~ # Example of using GetObjectsByName. -bb = ExtAPI.DataModel.GetObjectsByName("Gray Cast Iron")[0] +bb = ExtAPI.DataModel.GetObjectsByName("Connector\Solid1")[0] # %% # Accessing a Named Selection # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Example of accessing a named selection. -NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[Ansys.ACT.Automation.Mechanical.NamedSelection](True) -my_nsel = [i for i in NSall if i.Name.startswith("b")][0] -my_nsel2 = [i for i in NSall if i.Name == "aaa"][0] +NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[ + Ansys.ACT.Automation.Mechanical.NamedSelection +](True) +my_nsel = [i for i in NSall if i.Name.startswith("NSF")][0] +my_nsel2 = [i for i in NSall if i.Name == "NSInsideFaces"][0] # %% # Get All Unsuppressed Bodies and Point Masses @@ -154,8 +179,6 @@ all_pm = [i for i in all_pm if not i.Suppressed] - - # sphinx_gallery_start_ignore # Save the mechdat from pathlib import Path From 0bcdbb632cefa67283f8e958316435360817f324 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 21 Aug 2025 19:12:11 +0000 Subject: [PATCH 14/32] chore: auto fixes from pre-commit hooks --- examples/00_setup/01_setup.py | 29 +++++++++++++-- examples/00_setup/02_geometry.py | 35 +++++++++++++----- examples/00_setup/03_connections.py | 25 ++++++++++++- examples/00_setup/04_named_selections.py | 47 ++++++++++++++++++------ examples/00_setup/05_mesh.py | 22 +++++++++++ examples/00_setup/06_results.py | 39 ++++++++++++++++---- examples/00_setup/07_tree_objects.py | 22 +++++++++++ 7 files changed, 186 insertions(+), 33 deletions(-) diff --git a/examples/00_setup/01_setup.py b/examples/00_setup/01_setup.py index 4f9e9d493..fdf88f431 100644 --- a/examples/00_setup/01_setup.py +++ b/examples/00_setup/01_setup.py @@ -1,3 +1,25 @@ +# Copyright (C) 2022 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + """.. _ref_setup: App @@ -5,6 +27,7 @@ This section has helper scripts for Embedded App """ + # %% # Create an embedded instance and open an existing Mechanical File # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -13,7 +36,7 @@ from ansys.mechanical.core.examples import delete_downloads, download_file mechdat_path = download_file("cantilever.mechdat", "pymechanical", "embedding") -app = App(db_file = mechdat_path, globals=globals()) +app = App(db_file=mechdat_path, globals=globals()) print(app) @@ -27,7 +50,7 @@ geom_file_path = download_file("example_06_bolt_pret_geom.agdb", "pymechanical", "00_basic") geometry_import = Model.GeometryImportGroup.AddGeometryImport() -geometry_import_format = (Ansys.Mechanical.DataModel.Enums.GeometryImportPreference.Format.Automatic) +geometry_import_format = Ansys.Mechanical.DataModel.Enums.GeometryImportPreference.Format.Automatic geometry_import_preferences = Ansys.ACT.Mechanical.Utilities.GeometryImportPreferences() geometry_import_preferences.ProcessLines = True geometry_import_preferences.NamedSelectionKey = "" @@ -62,4 +85,4 @@ app.close() # Delete the downloaded files delete_downloads() -# sphinx_gallery_end_ignore \ No newline at end of file +# sphinx_gallery_end_ignore diff --git a/examples/00_setup/02_geometry.py b/examples/00_setup/02_geometry.py index 02e30dcde..62aeafd32 100644 --- a/examples/00_setup/02_geometry.py +++ b/examples/00_setup/02_geometry.py @@ -1,3 +1,25 @@ +# Copyright (C) 2022 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + """.. _ref_geometry: Geometry @@ -12,6 +34,7 @@ from ansys.mechanical.core import App from ansys.mechanical.core.examples import delete_downloads, download_file + app = App(globals=globals()) geom_file_path = download_file("example_06_bolt_pret_geom.agdb", "pymechanical", "00_basic") geometry_import = Model.GeometryImportGroup.AddGeometryImport() @@ -152,9 +175,7 @@ mylist = [bodyid] selection_manager = ExtAPI.SelectionManager -selection = ExtAPI.SelectionManager.CreateSelectionInfo( - SelectionTypeEnum.GeometryEntities -) +selection = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.GeometryEntities) selection.Ids = mylist selection_manager.NewSelection(selection) @@ -191,9 +212,7 @@ cyl_body_ids.append(body.Id) selection_manager = ExtAPI.SelectionManager -selection = ExtAPI.SelectionManager.CreateSelectionInfo( - SelectionTypeEnum.GeometryEntities -) +selection = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.GeometryEntities) selection.Ids = cyl_body_ids model = ExtAPI.DataModel.Project.Model @@ -205,9 +224,7 @@ # %% # Modify material assignment # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -allbodies = ExtAPI.DataModel.Project.Model.GetChildren( - DataModelObjectCategory.Body, True -) +allbodies = ExtAPI.DataModel.Project.Model.GetChildren(DataModelObjectCategory.Body, True) for body in allbodies: body.Material = "Structural Steel" diff --git a/examples/00_setup/03_connections.py b/examples/00_setup/03_connections.py index b02ca556e..4f1f8864b 100644 --- a/examples/00_setup/03_connections.py +++ b/examples/00_setup/03_connections.py @@ -1,3 +1,25 @@ +# Copyright (C) 2022 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + """.. _ref_connections: Connections @@ -83,6 +105,7 @@ face2 = 160 from pathlib import Path # delete + output_path = Path.cwd() / "out" # delete test_mechdat_path = str(output_path / "temporarycheck.mechdat") # delete app.save_as(test_mechdat_path, overwrite=True) # delete @@ -139,4 +162,4 @@ # %% # TODO : Change Model for Joint and Bearing -# ~~~~~~~~~~~~~~~~ \ No newline at end of file +# ~~~~~~~~~~~~~~~~ diff --git a/examples/00_setup/04_named_selections.py b/examples/00_setup/04_named_selections.py index 0c0cce210..b965a006d 100644 --- a/examples/00_setup/04_named_selections.py +++ b/examples/00_setup/04_named_selections.py @@ -1,3 +1,25 @@ +# Copyright (C) 2022 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + """.. _ref_named_selections: Named Selections @@ -6,11 +28,10 @@ This section has helper scripts for Named Selections. """ - - # sphinx_gallery_start_ignore from ansys.mechanical.core import App from ansys.mechanical.core.examples import delete_downloads, download_file + app = App(globals=globals()) geom_file_path = download_file("example_05_td26_Rubber_Boot_Seal.agdb", "pymechanical", "00_basic") geometry_import = Model.GeometryImportGroup.AddGeometryImport() @@ -30,7 +51,6 @@ app.print_tree() - # %% # Fetch all Named Selections # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -41,7 +61,9 @@ # %% # Delete a named selection # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[Ansys.ACT.Automation.Mechanical.NamedSelection](True) +NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[ + Ansys.ACT.Automation.Mechanical.NamedSelection +](True) # Delete a named selection by name a = [i for i in NSall if i.Name == "Top_Face"][0] @@ -56,7 +78,7 @@ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ selection_manager = ExtAPI.SelectionManager selection = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.GeometryEntities) -selection.Ids = [216,221,224] +selection.Ids = [216, 221, 224] model = ExtAPI.DataModel.Project.Model ns2 = model.AddNamedSelection() @@ -92,7 +114,9 @@ # %% # Find a Named Selection # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[Ansys.ACT.Automation.Mechanical.NamedSelection](True) +NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[ + Ansys.ACT.Automation.Mechanical.NamedSelection +](True) # Find a named selection by name a = [i for i in NSall if i.Name == "Rubber_Bodies30"][0] @@ -104,10 +128,12 @@ # %% # Identify Named Selections based on Name and Type # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[Ansys.ACT.Automation.Mechanical.NamedSelection](True) +NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[ + Ansys.ACT.Automation.Mechanical.NamedSelection +](True) # Filter named selections based on keywords in their names -keywords = ["Rubber_Bodies30", "Inner_Faces30","Outer_Faces30"] +keywords = ["Rubber_Bodies30", "Inner_Faces30", "Outer_Faces30"] ns1 = [i for i in NSall if keywords[0] in i.Name] ns2 = [i for i in NSall if keywords[1] in i.Name] ns3 = [i for i in NSall if keywords[2] in i.Name] @@ -115,13 +141,10 @@ # Further filter based on entity type FaceNsels = [ - i - for i in filtered - if str(ExtAPI.DataModel.GeoData.GeoEntityById(i.Ids[0]).Type) == "GeoFace" + i for i in filtered if str(ExtAPI.DataModel.GeoData.GeoEntityById(i.Ids[0]).Type) == "GeoFace" ] - # sphinx_gallery_start_ignore # Save the mechdat from pathlib import Path diff --git a/examples/00_setup/05_mesh.py b/examples/00_setup/05_mesh.py index ca1b0f5ea..3eb037c75 100644 --- a/examples/00_setup/05_mesh.py +++ b/examples/00_setup/05_mesh.py @@ -1,3 +1,25 @@ +# Copyright (C) 2022 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + """.. _ref_mesh: Mesh diff --git a/examples/00_setup/06_results.py b/examples/00_setup/06_results.py index b580b4e41..dbcbf05b5 100644 --- a/examples/00_setup/06_results.py +++ b/examples/00_setup/06_results.py @@ -1,3 +1,25 @@ +# Copyright (C) 2022 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + """.. _ref_results: Results @@ -6,21 +28,20 @@ This section has helper scripts for Results. """ - # sphinx_gallery_start_ignore import os + from ansys.mechanical.core import App from ansys.mechanical.core.examples import delete_downloads, download_file mechdat_path = download_file("example_03_simple_bolt_new.mechdat", "pymechanical", "00_basic") -app = App(db_file = mechdat_path, globals=globals()) +app = App(db_file=mechdat_path, globals=globals()) print(app) # sphinx_gallery_end_ignore - # Plot app.plot() @@ -50,7 +71,7 @@ # List Result Objects that can be added # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -all_results = [x for x in dir(static_struct) if str(x)[:3]=="Add"] +all_results = [x for x in dir(static_struct) if str(x)[:3] == "Add"] print(all_results) # %% @@ -116,7 +137,6 @@ print("Number of Result Sets:", result_set_count) - # %% # Export all results in the tree to PNG (2D image) files # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -124,12 +144,15 @@ for result in results: result.Activate() Graphics.Camera.SetSpecificViewOrientation(ViewOrientationType.Front) - image_path = os.path.join(os.getcwd(),"out",result.Name+".png") - Graphics.ExportImage(str(image_path), GraphicsImageExportFormat.PNG, Ansys.Mechanical.Graphics.GraphicsImageExportSettings()) + image_path = os.path.join(os.getcwd(), "out", result.Name + ".png") + Graphics.ExportImage( + str(image_path), + GraphicsImageExportFormat.PNG, + Ansys.Mechanical.Graphics.GraphicsImageExportSettings(), + ) print("Done with Exporting Results") - # sphinx_gallery_start_ignore # Save the mechdat from pathlib import Path diff --git a/examples/00_setup/07_tree_objects.py b/examples/00_setup/07_tree_objects.py index cc92eb3e8..00513779a 100644 --- a/examples/00_setup/07_tree_objects.py +++ b/examples/00_setup/07_tree_objects.py @@ -1,3 +1,25 @@ +# Copyright (C) 2022 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + """.. _ref_tree_objects: Tree Objects From f6d18ba8dd888ee9760b496595b377a1eec91ca4 Mon Sep 17 00:00:00 2001 From: pyansys-ci-bot <92810346+pyansys-ci-bot@users.noreply.github.com> Date: Thu, 21 Aug 2025 19:13:57 +0000 Subject: [PATCH 15/32] chore: adding changelog file 1287.added.md [dependabot-skip] --- doc/changelog.d/1287.added.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 doc/changelog.d/1287.added.md diff --git a/doc/changelog.d/1287.added.md b/doc/changelog.d/1287.added.md new file mode 100644 index 000000000..4401a2e6a --- /dev/null +++ b/doc/changelog.d/1287.added.md @@ -0,0 +1 @@ +Update examples with code snippets From 0e02da802018896950f312480e2b205ad00699a3 Mon Sep 17 00:00:00 2001 From: rs-bh-n Date: Wed, 10 Sep 2025 01:12:09 +0530 Subject: [PATCH 16/32] loads added --- examples/00_setup/01_setup.py | 29 +-- examples/00_setup/02_geometry.py | 35 +-- examples/00_setup/03_connections.py | 25 +- examples/00_setup/04_named_selections.py | 47 +--- examples/00_setup/05_mesh.py | 22 -- examples/00_setup/06_loads.py | 232 ++++++++++++++++++ .../00_setup/{06_results.py => 07_results.py} | 39 +-- ...{07_tree_objects.py => 08_tree_objects.py} | 22 -- 8 files changed, 265 insertions(+), 186 deletions(-) create mode 100644 examples/00_setup/06_loads.py rename examples/00_setup/{06_results.py => 07_results.py} (68%) rename examples/00_setup/{07_tree_objects.py => 08_tree_objects.py} (84%) diff --git a/examples/00_setup/01_setup.py b/examples/00_setup/01_setup.py index fdf88f431..4f9e9d493 100644 --- a/examples/00_setup/01_setup.py +++ b/examples/00_setup/01_setup.py @@ -1,25 +1,3 @@ -# Copyright (C) 2022 - 2025 ANSYS, Inc. and/or its affiliates. -# SPDX-License-Identifier: MIT -# -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - """.. _ref_setup: App @@ -27,7 +5,6 @@ This section has helper scripts for Embedded App """ - # %% # Create an embedded instance and open an existing Mechanical File # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -36,7 +13,7 @@ from ansys.mechanical.core.examples import delete_downloads, download_file mechdat_path = download_file("cantilever.mechdat", "pymechanical", "embedding") -app = App(db_file=mechdat_path, globals=globals()) +app = App(db_file = mechdat_path, globals=globals()) print(app) @@ -50,7 +27,7 @@ geom_file_path = download_file("example_06_bolt_pret_geom.agdb", "pymechanical", "00_basic") geometry_import = Model.GeometryImportGroup.AddGeometryImport() -geometry_import_format = Ansys.Mechanical.DataModel.Enums.GeometryImportPreference.Format.Automatic +geometry_import_format = (Ansys.Mechanical.DataModel.Enums.GeometryImportPreference.Format.Automatic) geometry_import_preferences = Ansys.ACT.Mechanical.Utilities.GeometryImportPreferences() geometry_import_preferences.ProcessLines = True geometry_import_preferences.NamedSelectionKey = "" @@ -85,4 +62,4 @@ app.close() # Delete the downloaded files delete_downloads() -# sphinx_gallery_end_ignore +# sphinx_gallery_end_ignore \ No newline at end of file diff --git a/examples/00_setup/02_geometry.py b/examples/00_setup/02_geometry.py index 62aeafd32..02e30dcde 100644 --- a/examples/00_setup/02_geometry.py +++ b/examples/00_setup/02_geometry.py @@ -1,25 +1,3 @@ -# Copyright (C) 2022 - 2025 ANSYS, Inc. and/or its affiliates. -# SPDX-License-Identifier: MIT -# -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - """.. _ref_geometry: Geometry @@ -34,7 +12,6 @@ from ansys.mechanical.core import App from ansys.mechanical.core.examples import delete_downloads, download_file - app = App(globals=globals()) geom_file_path = download_file("example_06_bolt_pret_geom.agdb", "pymechanical", "00_basic") geometry_import = Model.GeometryImportGroup.AddGeometryImport() @@ -175,7 +152,9 @@ mylist = [bodyid] selection_manager = ExtAPI.SelectionManager -selection = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.GeometryEntities) +selection = ExtAPI.SelectionManager.CreateSelectionInfo( + SelectionTypeEnum.GeometryEntities +) selection.Ids = mylist selection_manager.NewSelection(selection) @@ -212,7 +191,9 @@ cyl_body_ids.append(body.Id) selection_manager = ExtAPI.SelectionManager -selection = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.GeometryEntities) +selection = ExtAPI.SelectionManager.CreateSelectionInfo( + SelectionTypeEnum.GeometryEntities +) selection.Ids = cyl_body_ids model = ExtAPI.DataModel.Project.Model @@ -224,7 +205,9 @@ # %% # Modify material assignment # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -allbodies = ExtAPI.DataModel.Project.Model.GetChildren(DataModelObjectCategory.Body, True) +allbodies = ExtAPI.DataModel.Project.Model.GetChildren( + DataModelObjectCategory.Body, True +) for body in allbodies: body.Material = "Structural Steel" diff --git a/examples/00_setup/03_connections.py b/examples/00_setup/03_connections.py index 4f1f8864b..b02ca556e 100644 --- a/examples/00_setup/03_connections.py +++ b/examples/00_setup/03_connections.py @@ -1,25 +1,3 @@ -# Copyright (C) 2022 - 2025 ANSYS, Inc. and/or its affiliates. -# SPDX-License-Identifier: MIT -# -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - """.. _ref_connections: Connections @@ -105,7 +83,6 @@ face2 = 160 from pathlib import Path # delete - output_path = Path.cwd() / "out" # delete test_mechdat_path = str(output_path / "temporarycheck.mechdat") # delete app.save_as(test_mechdat_path, overwrite=True) # delete @@ -162,4 +139,4 @@ # %% # TODO : Change Model for Joint and Bearing -# ~~~~~~~~~~~~~~~~ +# ~~~~~~~~~~~~~~~~ \ No newline at end of file diff --git a/examples/00_setup/04_named_selections.py b/examples/00_setup/04_named_selections.py index b965a006d..0c0cce210 100644 --- a/examples/00_setup/04_named_selections.py +++ b/examples/00_setup/04_named_selections.py @@ -1,25 +1,3 @@ -# Copyright (C) 2022 - 2025 ANSYS, Inc. and/or its affiliates. -# SPDX-License-Identifier: MIT -# -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - """.. _ref_named_selections: Named Selections @@ -28,10 +6,11 @@ This section has helper scripts for Named Selections. """ + + # sphinx_gallery_start_ignore from ansys.mechanical.core import App from ansys.mechanical.core.examples import delete_downloads, download_file - app = App(globals=globals()) geom_file_path = download_file("example_05_td26_Rubber_Boot_Seal.agdb", "pymechanical", "00_basic") geometry_import = Model.GeometryImportGroup.AddGeometryImport() @@ -51,6 +30,7 @@ app.print_tree() + # %% # Fetch all Named Selections # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -61,9 +41,7 @@ # %% # Delete a named selection # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[ - Ansys.ACT.Automation.Mechanical.NamedSelection -](True) +NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[Ansys.ACT.Automation.Mechanical.NamedSelection](True) # Delete a named selection by name a = [i for i in NSall if i.Name == "Top_Face"][0] @@ -78,7 +56,7 @@ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ selection_manager = ExtAPI.SelectionManager selection = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.GeometryEntities) -selection.Ids = [216, 221, 224] +selection.Ids = [216,221,224] model = ExtAPI.DataModel.Project.Model ns2 = model.AddNamedSelection() @@ -114,9 +92,7 @@ # %% # Find a Named Selection # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[ - Ansys.ACT.Automation.Mechanical.NamedSelection -](True) +NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[Ansys.ACT.Automation.Mechanical.NamedSelection](True) # Find a named selection by name a = [i for i in NSall if i.Name == "Rubber_Bodies30"][0] @@ -128,12 +104,10 @@ # %% # Identify Named Selections based on Name and Type # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[ - Ansys.ACT.Automation.Mechanical.NamedSelection -](True) +NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[Ansys.ACT.Automation.Mechanical.NamedSelection](True) # Filter named selections based on keywords in their names -keywords = ["Rubber_Bodies30", "Inner_Faces30", "Outer_Faces30"] +keywords = ["Rubber_Bodies30", "Inner_Faces30","Outer_Faces30"] ns1 = [i for i in NSall if keywords[0] in i.Name] ns2 = [i for i in NSall if keywords[1] in i.Name] ns3 = [i for i in NSall if keywords[2] in i.Name] @@ -141,10 +115,13 @@ # Further filter based on entity type FaceNsels = [ - i for i in filtered if str(ExtAPI.DataModel.GeoData.GeoEntityById(i.Ids[0]).Type) == "GeoFace" + i + for i in filtered + if str(ExtAPI.DataModel.GeoData.GeoEntityById(i.Ids[0]).Type) == "GeoFace" ] + # sphinx_gallery_start_ignore # Save the mechdat from pathlib import Path diff --git a/examples/00_setup/05_mesh.py b/examples/00_setup/05_mesh.py index 3eb037c75..ca1b0f5ea 100644 --- a/examples/00_setup/05_mesh.py +++ b/examples/00_setup/05_mesh.py @@ -1,25 +1,3 @@ -# Copyright (C) 2022 - 2025 ANSYS, Inc. and/or its affiliates. -# SPDX-License-Identifier: MIT -# -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - """.. _ref_mesh: Mesh diff --git a/examples/00_setup/06_loads.py b/examples/00_setup/06_loads.py new file mode 100644 index 000000000..f9a678ffb --- /dev/null +++ b/examples/00_setup/06_loads.py @@ -0,0 +1,232 @@ +""".. _ref_loads: + +Loads and BCs +------------- + +This script contains helper examples for applying loads and boundary conditions in Ansys Mechanical. +""" + +# sphinx_gallery_start_ignore +from ansys.mechanical.core import App +from ansys.mechanical.core.examples import delete_downloads, download_file + +app = App(globals=globals()) +geom_file_path = download_file("example_geometry.agdb", "pymechanical", "00_basic") +geometry_import = Model.GeometryImportGroup.AddGeometryImport() +geometry_import_format = Ansys.Mechanical.DataModel.Enums.GeometryImportPreference.Format.Automatic +geometry_import_preferences = Ansys.ACT.Mechanical.Utilities.GeometryImportPreferences() +geometry_import_preferences.ProcessLines = True +geometry_import_preferences.NamedSelectionKey = "" +geometry_import_preferences.ProcessNamedSelections = True +geometry_import_preferences.ProcessMaterialProperties = True +geometry_import.Import(geom_file_path, geometry_import_format, geometry_import_preferences) +# sphinx_gallery_end_ignore + + +# Plot +app.plot() + +# Print the tree +app.print_tree() + +# %% +# Add an Analysis +# ~~~~~~~~~~~~~~~ +analysis = Model.AddStaticStructuralAnalysis() + +# %% Apply Bolt Pretension by Face ID +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +analysis_settings = Model.Analyses[0].AnalysisSettings +analysis_settings.NumberOfSteps = 6 + +selection = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.GeometryEntities) +selection.Ids = [312] +csys1 = Model.CoordinateSystems.AddCoordinateSystem() +csys1.OriginLocation = selection + +pretension = Model.Analyses[0].AddBoltPretension() +pretension.Location = selection +pretension.CoordinateSystem = csys1 +pretension.SetDefineBy(1, BoltLoadDefineBy.Load) +pretension.Preload.Output.SetDiscreteValue(0, Quantity("1500[N]")) +for i in range(2, analysis_settings.NumberOfSteps + 1): + pretension.SetDefineBy(int(i), BoltLoadDefineBy.Lock) + +# %% +# Apply a Fixed Support +# ~~~~~~~~~~~~~~~~~~~~~ +support = Model.Analyses[0].AddFixedSupport() +support_scoping = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.GeometryEntities) +support_scoping.Ids = [67] +support.Location = support_scoping + +# %% +# Apply a Pressure on the First Face of the First Body +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +pressure = Model.Analyses[0].AddPressure() +part1 = Model.Geometry.Children[0] +body1 = part1.Children[0] +face1 = body1.GetGeoBody().Faces[0] # Get the first face of the body. +selection = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.GeometryEntities) +selection.Entities = [face1] +pressure.Location = selection +pressure.Magnitude.Inputs[0].DiscreteValues = [Quantity("0 [s]"), Quantity("1 [s]")] +pressure.Magnitude.Output.DiscreteValues = [Quantity("10 [Pa]"), Quantity("20 [Pa]")] + +# %% +# Apply a Pressure as a Formula +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +pressure = Model.Analyses[0].AddPressure() +pressure_scoping = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.GeometryEntities) +pressure_scoping.Ids = [196] +pressure.Location = pressure_scoping +pressure.Magnitude.Output.Formula = "10*time" + +# %% +# Apply a Force +# ~~~~~~~~~~~~~ +force = Model.Analyses[0].AddForce() +force_scoping = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.GeometryEntities) +force_scoping.Ids = [31] +force.Location = force_scoping +force.Magnitude.Output.DiscreteValues = [Quantity("11.3 [N]"), Quantity("12.85 [N]")] + +# %% +# Apply Force by Components +# ~~~~~~~~~~~~~~~~~~~~~~~~~ +force = Model.Analyses[0].AddForce() +force_scoping = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.GeometryEntities) +force_scoping.Ids = [31] +force.Location = force_scoping +force.DefineBy = LoadDefineBy.Components +force.ZComponent.Output.DiscreteValues = [Quantity("0 [N]"), Quantity("-9 [N]")] + +# %% +# Apply Nodal Forces by Components +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +nodes_list = [66, 89, 105, 315, 470] +force_quantities_list = ["100 [N]", "-200 [N]", "300 [N]", "-400 [N]", "500 [N]"] + +for i in range(len(nodes_list)): + N1 = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.MeshNodes) + N1.Ids = [nodes_list[i]] + ExtAPI.SelectionManager.NewSelection(N1) + + NS = ExtAPI.DataModel.Project.Model.AddNamedSelection() + NS.Name = "Node_" + str(nodes_list[i]) + + Force1 = ExtAPI.DataModel.Project.Model.Analyses[0].AddNodalForce() + Force1.Location = NS + Force1.Name = "NodeAtNode_" + str(nodes_list[i]) + Force1.YComponent.Output.DiscreteValues = [Quantity(force_quantities_list[i])] + Force1.DivideLoadByNodes = False + +# %% +# Apply Force and Fixed Support using Named Selections +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +selection_manager = ExtAPI.SelectionManager +selection = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.GeometryEntities) +selection.Ids = [312] + +model = ExtAPI.DataModel.Project.Model +ns2 = model.AddNamedSelection() +ns2.Name = "fixed" +ns2.Location = selection +selection_manager.ClearSelection() + +selection = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.GeometryEntities) +selection.Ids = [312] + +ns2 = model.AddNamedSelection() +ns2.Name = "force" +ns2.Location = selection +selection_manager.ClearSelection() + +NSall = Model.NamedSelections.GetChildren[Ansys.ACT.Automation.Mechanical.NamedSelection](True) +for_fixed_supp = [i for i in NSall if i.Name.startswith("fixed")][0] +for_force = [i for i in NSall if i.Name.startswith("force")][0] + +f = Model.Analyses[0].AddForce() +f.Location = for_force +f.Name = "Force1" +f.Magnitude.Output.DiscreteValues = [Quantity("10 [N]")] + +fs = model.Analyses[0].AddFixedSupport() +fs.Location = for_fixed_supp +fs.Name = "FixedSupport1" + +# %% +# Apply Radiation - Thermal Analysis +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +radn = Model.Analyses[1].AddRadiation() + +e = radn.Emissivity +e.Output.DiscreteValues = [Quantity("0.36")] + +t = radn.AmbientTemperature +t.Inputs[0].DiscreteValues = [Quantity("0 [sec]"), Quantity("1 [sec]")] +t.Output.DiscreteValues = [Quantity("22 [C]"), Quantity("2302 [C]")] + +# %% +# Apply Tabular Pressure for 5 Load Steps +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +pressureLoad = ExtAPI.DataModel.Project.Model.Analyses[0].AddPressure() +pressureLoad.Magnitude.Inputs[0].DiscreteValues = [ + Quantity("0 [sec]"), + Quantity("1 [sec]"), + Quantity("2 [sec]"), + Quantity("3 [sec]"), + Quantity("4 [sec]"), + Quantity("5 [sec]"), +] +pressureLoad.Magnitude.Output.DiscreteValues = [ + Quantity("0 [MPa]"), + Quantity("10 [MPa]"), + Quantity("30 [MPa]"), + Quantity("25 [MPa]"), + Quantity("-30 [MPa]"), + Quantity("100 [MPa]"), +] + +# %% +# Applying Direct FE Type Boundary Conditions +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +CSall = ExtAPI.DataModel.Project.Model.CoordinateSystems.GetChildren[Ansys.ACT.Automation.Mechanical.CoordinateSystem](True) +a = [i for i in CSall if i.Name == "cyl"][0] +NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[Ansys.ACT.Automation.Mechanical.NamedSelection](True) +n = [i for i in NSall if i.Name == "ns"][0] + +nf = ExtAPI.DataModel.Project.Model.Analyses[0].AddNodalForce() +nf.Location = n +nf.YComponent.Inputs[0].DiscreteValues = [Quantity("0 [sec]"), Quantity("1 [sec]")] +nf.IndependentVariable = LoadVariableVariationType.YValue +nf.XYZFunctionCoordinateSystem = a +nf.YComponent.Output.DiscreteValues = [Quantity("0 [N]"), Quantity("100[N]")] + +nd = ExtAPI.DataModel.Project.Model.Analyses[0].AddNodalDisplacement() +nd.Location = n +nd.YComponent.Inputs[0].DiscreteValues = [Quantity("0 [sec]"), Quantity("1 [sec]")] +nd.IndependentVariable = LoadVariableVariationType.YValue +nd.XYZFunctionCoordinateSystem = a +nd.YComponent.Output.DiscreteValues = [Quantity("0 [mm]"), Quantity("100[mm]")] + +np = ExtAPI.DataModel.Project.Model.Analyses[0].AddNodalPressure() +np.Location = n +np.Magnitude.Inputs[0].DiscreteValues = [Quantity("0 [sec]"), Quantity("1 [sec]")] +np.IndependentVariable = LoadVariableVariationType.YValue +np.XYZFunctionCoordinateSystem = a +np.Magnitude.Output.DiscreteValues = [Quantity("0 [Pa]"), Quantity("100[Pa]")] + +# sphinx_gallery_start_ignore +# Save the mechdat +from pathlib import Path + +output_path = Path.cwd() / "out" +test_mechdat_path = str(output_path / "test_loads.mechdat") +# app.save_as(test_mechdat_path, overwrite=True) + +# Close the app +app.close() +# Delete the downloaded files +delete_downloads() +# sphinx_gallery_end_ignore \ No newline at end of file diff --git a/examples/00_setup/06_results.py b/examples/00_setup/07_results.py similarity index 68% rename from examples/00_setup/06_results.py rename to examples/00_setup/07_results.py index dbcbf05b5..b580b4e41 100644 --- a/examples/00_setup/06_results.py +++ b/examples/00_setup/07_results.py @@ -1,25 +1,3 @@ -# Copyright (C) 2022 - 2025 ANSYS, Inc. and/or its affiliates. -# SPDX-License-Identifier: MIT -# -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - """.. _ref_results: Results @@ -28,20 +6,21 @@ This section has helper scripts for Results. """ + # sphinx_gallery_start_ignore import os - from ansys.mechanical.core import App from ansys.mechanical.core.examples import delete_downloads, download_file mechdat_path = download_file("example_03_simple_bolt_new.mechdat", "pymechanical", "00_basic") -app = App(db_file=mechdat_path, globals=globals()) +app = App(db_file = mechdat_path, globals=globals()) print(app) # sphinx_gallery_end_ignore + # Plot app.plot() @@ -71,7 +50,7 @@ # List Result Objects that can be added # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -all_results = [x for x in dir(static_struct) if str(x)[:3] == "Add"] +all_results = [x for x in dir(static_struct) if str(x)[:3]=="Add"] print(all_results) # %% @@ -137,6 +116,7 @@ print("Number of Result Sets:", result_set_count) + # %% # Export all results in the tree to PNG (2D image) files # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -144,15 +124,12 @@ for result in results: result.Activate() Graphics.Camera.SetSpecificViewOrientation(ViewOrientationType.Front) - image_path = os.path.join(os.getcwd(), "out", result.Name + ".png") - Graphics.ExportImage( - str(image_path), - GraphicsImageExportFormat.PNG, - Ansys.Mechanical.Graphics.GraphicsImageExportSettings(), - ) + image_path = os.path.join(os.getcwd(),"out",result.Name+".png") + Graphics.ExportImage(str(image_path), GraphicsImageExportFormat.PNG, Ansys.Mechanical.Graphics.GraphicsImageExportSettings()) print("Done with Exporting Results") + # sphinx_gallery_start_ignore # Save the mechdat from pathlib import Path diff --git a/examples/00_setup/07_tree_objects.py b/examples/00_setup/08_tree_objects.py similarity index 84% rename from examples/00_setup/07_tree_objects.py rename to examples/00_setup/08_tree_objects.py index 00513779a..cc92eb3e8 100644 --- a/examples/00_setup/07_tree_objects.py +++ b/examples/00_setup/08_tree_objects.py @@ -1,25 +1,3 @@ -# Copyright (C) 2022 - 2025 ANSYS, Inc. and/or its affiliates. -# SPDX-License-Identifier: MIT -# -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - """.. _ref_tree_objects: Tree Objects From 4bb69913da3412206fa308dab61c7ba54f4421c8 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 9 Sep 2025 19:42:29 +0000 Subject: [PATCH 17/32] chore: auto fixes from pre-commit hooks --- examples/00_setup/01_setup.py | 29 +++++++++++++-- examples/00_setup/02_geometry.py | 35 +++++++++++++----- examples/00_setup/03_connections.py | 25 ++++++++++++- examples/00_setup/04_named_selections.py | 47 ++++++++++++++++++------ examples/00_setup/05_mesh.py | 22 +++++++++++ examples/00_setup/06_loads.py | 38 ++++++++++++++++--- examples/00_setup/07_results.py | 39 ++++++++++++++++---- examples/00_setup/08_tree_objects.py | 22 +++++++++++ 8 files changed, 218 insertions(+), 39 deletions(-) diff --git a/examples/00_setup/01_setup.py b/examples/00_setup/01_setup.py index 4f9e9d493..fdf88f431 100644 --- a/examples/00_setup/01_setup.py +++ b/examples/00_setup/01_setup.py @@ -1,3 +1,25 @@ +# Copyright (C) 2022 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + """.. _ref_setup: App @@ -5,6 +27,7 @@ This section has helper scripts for Embedded App """ + # %% # Create an embedded instance and open an existing Mechanical File # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -13,7 +36,7 @@ from ansys.mechanical.core.examples import delete_downloads, download_file mechdat_path = download_file("cantilever.mechdat", "pymechanical", "embedding") -app = App(db_file = mechdat_path, globals=globals()) +app = App(db_file=mechdat_path, globals=globals()) print(app) @@ -27,7 +50,7 @@ geom_file_path = download_file("example_06_bolt_pret_geom.agdb", "pymechanical", "00_basic") geometry_import = Model.GeometryImportGroup.AddGeometryImport() -geometry_import_format = (Ansys.Mechanical.DataModel.Enums.GeometryImportPreference.Format.Automatic) +geometry_import_format = Ansys.Mechanical.DataModel.Enums.GeometryImportPreference.Format.Automatic geometry_import_preferences = Ansys.ACT.Mechanical.Utilities.GeometryImportPreferences() geometry_import_preferences.ProcessLines = True geometry_import_preferences.NamedSelectionKey = "" @@ -62,4 +85,4 @@ app.close() # Delete the downloaded files delete_downloads() -# sphinx_gallery_end_ignore \ No newline at end of file +# sphinx_gallery_end_ignore diff --git a/examples/00_setup/02_geometry.py b/examples/00_setup/02_geometry.py index 02e30dcde..62aeafd32 100644 --- a/examples/00_setup/02_geometry.py +++ b/examples/00_setup/02_geometry.py @@ -1,3 +1,25 @@ +# Copyright (C) 2022 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + """.. _ref_geometry: Geometry @@ -12,6 +34,7 @@ from ansys.mechanical.core import App from ansys.mechanical.core.examples import delete_downloads, download_file + app = App(globals=globals()) geom_file_path = download_file("example_06_bolt_pret_geom.agdb", "pymechanical", "00_basic") geometry_import = Model.GeometryImportGroup.AddGeometryImport() @@ -152,9 +175,7 @@ mylist = [bodyid] selection_manager = ExtAPI.SelectionManager -selection = ExtAPI.SelectionManager.CreateSelectionInfo( - SelectionTypeEnum.GeometryEntities -) +selection = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.GeometryEntities) selection.Ids = mylist selection_manager.NewSelection(selection) @@ -191,9 +212,7 @@ cyl_body_ids.append(body.Id) selection_manager = ExtAPI.SelectionManager -selection = ExtAPI.SelectionManager.CreateSelectionInfo( - SelectionTypeEnum.GeometryEntities -) +selection = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.GeometryEntities) selection.Ids = cyl_body_ids model = ExtAPI.DataModel.Project.Model @@ -205,9 +224,7 @@ # %% # Modify material assignment # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -allbodies = ExtAPI.DataModel.Project.Model.GetChildren( - DataModelObjectCategory.Body, True -) +allbodies = ExtAPI.DataModel.Project.Model.GetChildren(DataModelObjectCategory.Body, True) for body in allbodies: body.Material = "Structural Steel" diff --git a/examples/00_setup/03_connections.py b/examples/00_setup/03_connections.py index b02ca556e..4f1f8864b 100644 --- a/examples/00_setup/03_connections.py +++ b/examples/00_setup/03_connections.py @@ -1,3 +1,25 @@ +# Copyright (C) 2022 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + """.. _ref_connections: Connections @@ -83,6 +105,7 @@ face2 = 160 from pathlib import Path # delete + output_path = Path.cwd() / "out" # delete test_mechdat_path = str(output_path / "temporarycheck.mechdat") # delete app.save_as(test_mechdat_path, overwrite=True) # delete @@ -139,4 +162,4 @@ # %% # TODO : Change Model for Joint and Bearing -# ~~~~~~~~~~~~~~~~ \ No newline at end of file +# ~~~~~~~~~~~~~~~~ diff --git a/examples/00_setup/04_named_selections.py b/examples/00_setup/04_named_selections.py index 0c0cce210..b965a006d 100644 --- a/examples/00_setup/04_named_selections.py +++ b/examples/00_setup/04_named_selections.py @@ -1,3 +1,25 @@ +# Copyright (C) 2022 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + """.. _ref_named_selections: Named Selections @@ -6,11 +28,10 @@ This section has helper scripts for Named Selections. """ - - # sphinx_gallery_start_ignore from ansys.mechanical.core import App from ansys.mechanical.core.examples import delete_downloads, download_file + app = App(globals=globals()) geom_file_path = download_file("example_05_td26_Rubber_Boot_Seal.agdb", "pymechanical", "00_basic") geometry_import = Model.GeometryImportGroup.AddGeometryImport() @@ -30,7 +51,6 @@ app.print_tree() - # %% # Fetch all Named Selections # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -41,7 +61,9 @@ # %% # Delete a named selection # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[Ansys.ACT.Automation.Mechanical.NamedSelection](True) +NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[ + Ansys.ACT.Automation.Mechanical.NamedSelection +](True) # Delete a named selection by name a = [i for i in NSall if i.Name == "Top_Face"][0] @@ -56,7 +78,7 @@ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ selection_manager = ExtAPI.SelectionManager selection = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.GeometryEntities) -selection.Ids = [216,221,224] +selection.Ids = [216, 221, 224] model = ExtAPI.DataModel.Project.Model ns2 = model.AddNamedSelection() @@ -92,7 +114,9 @@ # %% # Find a Named Selection # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[Ansys.ACT.Automation.Mechanical.NamedSelection](True) +NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[ + Ansys.ACT.Automation.Mechanical.NamedSelection +](True) # Find a named selection by name a = [i for i in NSall if i.Name == "Rubber_Bodies30"][0] @@ -104,10 +128,12 @@ # %% # Identify Named Selections based on Name and Type # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[Ansys.ACT.Automation.Mechanical.NamedSelection](True) +NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[ + Ansys.ACT.Automation.Mechanical.NamedSelection +](True) # Filter named selections based on keywords in their names -keywords = ["Rubber_Bodies30", "Inner_Faces30","Outer_Faces30"] +keywords = ["Rubber_Bodies30", "Inner_Faces30", "Outer_Faces30"] ns1 = [i for i in NSall if keywords[0] in i.Name] ns2 = [i for i in NSall if keywords[1] in i.Name] ns3 = [i for i in NSall if keywords[2] in i.Name] @@ -115,13 +141,10 @@ # Further filter based on entity type FaceNsels = [ - i - for i in filtered - if str(ExtAPI.DataModel.GeoData.GeoEntityById(i.Ids[0]).Type) == "GeoFace" + i for i in filtered if str(ExtAPI.DataModel.GeoData.GeoEntityById(i.Ids[0]).Type) == "GeoFace" ] - # sphinx_gallery_start_ignore # Save the mechdat from pathlib import Path diff --git a/examples/00_setup/05_mesh.py b/examples/00_setup/05_mesh.py index ca1b0f5ea..3eb037c75 100644 --- a/examples/00_setup/05_mesh.py +++ b/examples/00_setup/05_mesh.py @@ -1,3 +1,25 @@ +# Copyright (C) 2022 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + """.. _ref_mesh: Mesh diff --git a/examples/00_setup/06_loads.py b/examples/00_setup/06_loads.py index f9a678ffb..a7172b0b0 100644 --- a/examples/00_setup/06_loads.py +++ b/examples/00_setup/06_loads.py @@ -1,3 +1,25 @@ +# Copyright (C) 2022 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + """.. _ref_loads: Loads and BCs @@ -52,7 +74,7 @@ for i in range(2, analysis_settings.NumberOfSteps + 1): pretension.SetDefineBy(int(i), BoltLoadDefineBy.Lock) -# %% +# %% # Apply a Fixed Support # ~~~~~~~~~~~~~~~~~~~~~ support = Model.Analyses[0].AddFixedSupport() @@ -91,7 +113,7 @@ force.Location = force_scoping force.Magnitude.Output.DiscreteValues = [Quantity("11.3 [N]"), Quantity("12.85 [N]")] -# %% +# %% # Apply Force by Components # ~~~~~~~~~~~~~~~~~~~~~~~~~ force = Model.Analyses[0].AddForce() @@ -101,7 +123,7 @@ force.DefineBy = LoadDefineBy.Components force.ZComponent.Output.DiscreteValues = [Quantity("0 [N]"), Quantity("-9 [N]")] -# %% +# %% # Apply Nodal Forces by Components # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ nodes_list = [66, 89, 105, 315, 470] @@ -191,9 +213,13 @@ # %% # Applying Direct FE Type Boundary Conditions # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -CSall = ExtAPI.DataModel.Project.Model.CoordinateSystems.GetChildren[Ansys.ACT.Automation.Mechanical.CoordinateSystem](True) +CSall = ExtAPI.DataModel.Project.Model.CoordinateSystems.GetChildren[ + Ansys.ACT.Automation.Mechanical.CoordinateSystem +](True) a = [i for i in CSall if i.Name == "cyl"][0] -NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[Ansys.ACT.Automation.Mechanical.NamedSelection](True) +NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[ + Ansys.ACT.Automation.Mechanical.NamedSelection +](True) n = [i for i in NSall if i.Name == "ns"][0] nf = ExtAPI.DataModel.Project.Model.Analyses[0].AddNodalForce() @@ -229,4 +255,4 @@ app.close() # Delete the downloaded files delete_downloads() -# sphinx_gallery_end_ignore \ No newline at end of file +# sphinx_gallery_end_ignore diff --git a/examples/00_setup/07_results.py b/examples/00_setup/07_results.py index b580b4e41..dbcbf05b5 100644 --- a/examples/00_setup/07_results.py +++ b/examples/00_setup/07_results.py @@ -1,3 +1,25 @@ +# Copyright (C) 2022 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + """.. _ref_results: Results @@ -6,21 +28,20 @@ This section has helper scripts for Results. """ - # sphinx_gallery_start_ignore import os + from ansys.mechanical.core import App from ansys.mechanical.core.examples import delete_downloads, download_file mechdat_path = download_file("example_03_simple_bolt_new.mechdat", "pymechanical", "00_basic") -app = App(db_file = mechdat_path, globals=globals()) +app = App(db_file=mechdat_path, globals=globals()) print(app) # sphinx_gallery_end_ignore - # Plot app.plot() @@ -50,7 +71,7 @@ # List Result Objects that can be added # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -all_results = [x for x in dir(static_struct) if str(x)[:3]=="Add"] +all_results = [x for x in dir(static_struct) if str(x)[:3] == "Add"] print(all_results) # %% @@ -116,7 +137,6 @@ print("Number of Result Sets:", result_set_count) - # %% # Export all results in the tree to PNG (2D image) files # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -124,12 +144,15 @@ for result in results: result.Activate() Graphics.Camera.SetSpecificViewOrientation(ViewOrientationType.Front) - image_path = os.path.join(os.getcwd(),"out",result.Name+".png") - Graphics.ExportImage(str(image_path), GraphicsImageExportFormat.PNG, Ansys.Mechanical.Graphics.GraphicsImageExportSettings()) + image_path = os.path.join(os.getcwd(), "out", result.Name + ".png") + Graphics.ExportImage( + str(image_path), + GraphicsImageExportFormat.PNG, + Ansys.Mechanical.Graphics.GraphicsImageExportSettings(), + ) print("Done with Exporting Results") - # sphinx_gallery_start_ignore # Save the mechdat from pathlib import Path diff --git a/examples/00_setup/08_tree_objects.py b/examples/00_setup/08_tree_objects.py index cc92eb3e8..00513779a 100644 --- a/examples/00_setup/08_tree_objects.py +++ b/examples/00_setup/08_tree_objects.py @@ -1,3 +1,25 @@ +# Copyright (C) 2022 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + """.. _ref_tree_objects: Tree Objects From 6039d76da6c4ae79c3d11be309ed41ad7cae845b Mon Sep 17 00:00:00 2001 From: rs-bh-n Date: Wed, 10 Sep 2025 21:21:05 +0530 Subject: [PATCH 18/32] loads ready --- examples/00_setup/06_loads.py | 72 ++++++++++++++++++++++------------- 1 file changed, 46 insertions(+), 26 deletions(-) diff --git a/examples/00_setup/06_loads.py b/examples/00_setup/06_loads.py index f9a678ffb..08c761c8e 100644 --- a/examples/00_setup/06_loads.py +++ b/examples/00_setup/06_loads.py @@ -7,11 +7,11 @@ """ # sphinx_gallery_start_ignore + from ansys.mechanical.core import App from ansys.mechanical.core.examples import delete_downloads, download_file - app = App(globals=globals()) -geom_file_path = download_file("example_geometry.agdb", "pymechanical", "00_basic") +geom_file_path = download_file("example_06_bolt_pret_geom.agdb", "pymechanical", "00_basic") geometry_import = Model.GeometryImportGroup.AddGeometryImport() geometry_import_format = Ansys.Mechanical.DataModel.Enums.GeometryImportPreference.Format.Automatic geometry_import_preferences = Ansys.ACT.Mechanical.Utilities.GeometryImportPreferences() @@ -20,8 +20,27 @@ geometry_import_preferences.ProcessNamedSelections = True geometry_import_preferences.ProcessMaterialProperties = True geometry_import.Import(geom_file_path, geometry_import_format, geometry_import_preferences) -# sphinx_gallery_end_ignore +Model.Mesh.GenerateMesh() + +selection_manager = ExtAPI.SelectionManager +selection = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.GeometryEntities) +selection.Ids = [30] +ns2 = Model.AddNamedSelection() +ns2.Name = "fixed" +ns2.Location = selection +selection_manager.ClearSelection() + +selection_manager = ExtAPI.SelectionManager +selection = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.GeometryEntities) +selection.Ids = [94] + +ns2 = Model.AddNamedSelection() +ns2.Name = "force" +ns2.Location = selection +selection_manager.ClearSelection() + +# sphinx_gallery_end_ignore # Plot app.plot() @@ -40,9 +59,10 @@ analysis_settings.NumberOfSteps = 6 selection = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.GeometryEntities) -selection.Ids = [312] +selection.Ids = [39] csys1 = Model.CoordinateSystems.AddCoordinateSystem() csys1.OriginLocation = selection +csys1.Name="cyl" pretension = Model.Analyses[0].AddBoltPretension() pretension.Location = selection @@ -57,7 +77,7 @@ # ~~~~~~~~~~~~~~~~~~~~~ support = Model.Analyses[0].AddFixedSupport() support_scoping = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.GeometryEntities) -support_scoping.Ids = [67] +support_scoping.Ids = [30] support.Location = support_scoping # %% @@ -78,7 +98,7 @@ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ pressure = Model.Analyses[0].AddPressure() pressure_scoping = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.GeometryEntities) -pressure_scoping.Ids = [196] +pressure_scoping.Ids = [95] pressure.Location = pressure_scoping pressure.Magnitude.Output.Formula = "10*time" @@ -87,7 +107,7 @@ # ~~~~~~~~~~~~~ force = Model.Analyses[0].AddForce() force_scoping = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.GeometryEntities) -force_scoping.Ids = [31] +force_scoping.Ids = [63] force.Location = force_scoping force.Magnitude.Output.DiscreteValues = [Quantity("11.3 [N]"), Quantity("12.85 [N]")] @@ -96,7 +116,7 @@ # ~~~~~~~~~~~~~~~~~~~~~~~~~ force = Model.Analyses[0].AddForce() force_scoping = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.GeometryEntities) -force_scoping.Ids = [31] +force_scoping.Ids = [63] force.Location = force_scoping force.DefineBy = LoadDefineBy.Components force.ZComponent.Output.DiscreteValues = [Quantity("0 [N]"), Quantity("-9 [N]")] @@ -104,18 +124,18 @@ # %% # Apply Nodal Forces by Components # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -nodes_list = [66, 89, 105, 315, 470] -force_quantities_list = ["100 [N]", "-200 [N]", "300 [N]", "-400 [N]", "500 [N]"] +nodes_list = [16,2329] +force_quantities_list = ["100 [N]", "-200 [N]"] for i in range(len(nodes_list)): N1 = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.MeshNodes) N1.Ids = [nodes_list[i]] ExtAPI.SelectionManager.NewSelection(N1) - NS = ExtAPI.DataModel.Project.Model.AddNamedSelection() + NS = Model.AddNamedSelection() NS.Name = "Node_" + str(nodes_list[i]) - Force1 = ExtAPI.DataModel.Project.Model.Analyses[0].AddNodalForce() + Force1 = Model.Analyses[0].AddNodalForce() Force1.Location = NS Force1.Name = "NodeAtNode_" + str(nodes_list[i]) Force1.YComponent.Output.DiscreteValues = [Quantity(force_quantities_list[i])] @@ -126,18 +146,17 @@ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ selection_manager = ExtAPI.SelectionManager selection = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.GeometryEntities) -selection.Ids = [312] +selection.Ids = [65] -model = ExtAPI.DataModel.Project.Model -ns2 = model.AddNamedSelection() +ns2 = Model.AddNamedSelection() ns2.Name = "fixed" ns2.Location = selection selection_manager.ClearSelection() selection = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.GeometryEntities) -selection.Ids = [312] +selection.Ids = [65] -ns2 = model.AddNamedSelection() +ns2 = Model.AddNamedSelection() ns2.Name = "force" ns2.Location = selection selection_manager.ClearSelection() @@ -151,14 +170,15 @@ f.Name = "Force1" f.Magnitude.Output.DiscreteValues = [Quantity("10 [N]")] -fs = model.Analyses[0].AddFixedSupport() +fs = Model.Analyses[0].AddFixedSupport() fs.Location = for_fixed_supp fs.Name = "FixedSupport1" # %% # Apply Radiation - Thermal Analysis # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -radn = Model.Analyses[1].AddRadiation() +analysis2 = Model.AddSteadyStateThermalAnalysis() +radn = analysis2.AddRadiation() e = radn.Emissivity e.Output.DiscreteValues = [Quantity("0.36")] @@ -170,7 +190,7 @@ # %% # Apply Tabular Pressure for 5 Load Steps # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -pressureLoad = ExtAPI.DataModel.Project.Model.Analyses[0].AddPressure() +pressureLoad = Model.Analyses[0].AddPressure() pressureLoad.Magnitude.Inputs[0].DiscreteValues = [ Quantity("0 [sec]"), Quantity("1 [sec]"), @@ -191,26 +211,26 @@ # %% # Applying Direct FE Type Boundary Conditions # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -CSall = ExtAPI.DataModel.Project.Model.CoordinateSystems.GetChildren[Ansys.ACT.Automation.Mechanical.CoordinateSystem](True) +CSall = Model.CoordinateSystems.GetChildren[Ansys.ACT.Automation.Mechanical.CoordinateSystem](True) a = [i for i in CSall if i.Name == "cyl"][0] -NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[Ansys.ACT.Automation.Mechanical.NamedSelection](True) -n = [i for i in NSall if i.Name == "ns"][0] +NSall = Model.NamedSelections.GetChildren[Ansys.ACT.Automation.Mechanical.NamedSelection](True) +n = [i for i in NSall if i.Name == "force"][0] -nf = ExtAPI.DataModel.Project.Model.Analyses[0].AddNodalForce() +nf = Model.Analyses[0].AddNodalForce() nf.Location = n nf.YComponent.Inputs[0].DiscreteValues = [Quantity("0 [sec]"), Quantity("1 [sec]")] nf.IndependentVariable = LoadVariableVariationType.YValue nf.XYZFunctionCoordinateSystem = a nf.YComponent.Output.DiscreteValues = [Quantity("0 [N]"), Quantity("100[N]")] -nd = ExtAPI.DataModel.Project.Model.Analyses[0].AddNodalDisplacement() +nd = Model.Analyses[0].AddNodalDisplacement() nd.Location = n nd.YComponent.Inputs[0].DiscreteValues = [Quantity("0 [sec]"), Quantity("1 [sec]")] nd.IndependentVariable = LoadVariableVariationType.YValue nd.XYZFunctionCoordinateSystem = a nd.YComponent.Output.DiscreteValues = [Quantity("0 [mm]"), Quantity("100[mm]")] -np = ExtAPI.DataModel.Project.Model.Analyses[0].AddNodalPressure() +np = Model.Analyses[0].AddNodalPressure() np.Location = n np.Magnitude.Inputs[0].DiscreteValues = [Quantity("0 [sec]"), Quantity("1 [sec]")] np.IndependentVariable = LoadVariableVariationType.YValue From 71b7d0ab3f1fd77e07da49e92cc5195c8a8f38ab Mon Sep 17 00:00:00 2001 From: rs-bh-n Date: Wed, 10 Sep 2025 21:25:51 +0530 Subject: [PATCH 19/32] loads ready --- examples/00_setup/06_loads.py | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/examples/00_setup/06_loads.py b/examples/00_setup/06_loads.py index c26adbf69..71231adf6 100644 --- a/examples/00_setup/06_loads.py +++ b/examples/00_setup/06_loads.py @@ -233,21 +233,10 @@ # %% # Applying Direct FE Type Boundary Conditions # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -<<<<<<< HEAD CSall = Model.CoordinateSystems.GetChildren[Ansys.ACT.Automation.Mechanical.CoordinateSystem](True) a = [i for i in CSall if i.Name == "cyl"][0] NSall = Model.NamedSelections.GetChildren[Ansys.ACT.Automation.Mechanical.NamedSelection](True) n = [i for i in NSall if i.Name == "force"][0] -======= -CSall = ExtAPI.DataModel.Project.Model.CoordinateSystems.GetChildren[ - Ansys.ACT.Automation.Mechanical.CoordinateSystem -](True) -a = [i for i in CSall if i.Name == "cyl"][0] -NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[ - Ansys.ACT.Automation.Mechanical.NamedSelection -](True) -n = [i for i in NSall if i.Name == "ns"][0] ->>>>>>> 4bb69913da3412206fa308dab61c7ba54f4421c8 nf = Model.Analyses[0].AddNodalForce() nf.Location = n From d52c496481f49bd4d1dee0c69927fc93263a23f9 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 10 Sep 2025 15:56:52 +0000 Subject: [PATCH 20/32] chore: auto fixes from pre-commit hooks --- examples/00_setup/06_loads.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/00_setup/06_loads.py b/examples/00_setup/06_loads.py index 71231adf6..da52a73d3 100644 --- a/examples/00_setup/06_loads.py +++ b/examples/00_setup/06_loads.py @@ -32,6 +32,7 @@ from ansys.mechanical.core import App from ansys.mechanical.core.examples import delete_downloads, download_file + app = App(globals=globals()) geom_file_path = download_file("example_06_bolt_pret_geom.agdb", "pymechanical", "00_basic") geometry_import = Model.GeometryImportGroup.AddGeometryImport() @@ -84,7 +85,7 @@ selection.Ids = [39] csys1 = Model.CoordinateSystems.AddCoordinateSystem() csys1.OriginLocation = selection -csys1.Name="cyl" +csys1.Name = "cyl" pretension = Model.Analyses[0].AddBoltPretension() pretension.Location = selection @@ -146,7 +147,7 @@ # %% # Apply Nodal Forces by Components # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -nodes_list = [16,2329] +nodes_list = [16, 2329] force_quantities_list = ["100 [N]", "-200 [N]"] for i in range(len(nodes_list)): From 2ff1e7e9f43454a53244c7256022e4ffde310621 Mon Sep 17 00:00:00 2001 From: rs-bh-n Date: Fri, 12 Sep 2025 22:57:42 +0530 Subject: [PATCH 21/32] comments added --- examples/00_setup/01_setup.py | 12 ++++++ examples/00_setup/02_geometry.py | 52 ++++++++++++++++++---- examples/00_setup/03_connections.py | 44 ++++++++++++++----- examples/00_setup/04_named_selections.py | 46 +++++++++++++------- examples/00_setup/05_mesh.py | 34 ++++++++++++--- examples/00_setup/06_loads.py | 26 +++++++++-- examples/00_setup/07_results.py | 40 +++++++++++++---- examples/00_setup/08_tree_objects.py | 55 +++++++++++++++--------- 8 files changed, 235 insertions(+), 74 deletions(-) diff --git a/examples/00_setup/01_setup.py b/examples/00_setup/01_setup.py index fdf88f431..9429b4fe1 100644 --- a/examples/00_setup/01_setup.py +++ b/examples/00_setup/01_setup.py @@ -36,10 +36,22 @@ from ansys.mechanical.core.examples import delete_downloads, download_file mechdat_path = download_file("cantilever.mechdat", "pymechanical", "embedding") + +# The following line creates an instance of the app, extracts the global API entry points, +# and merges them into your Python global variables. + app = App(db_file=mechdat_path, globals=globals()) print(app) +# Alternatively, you can use the update_globals method of the App class to update the global variables: +# The second argument, if set to False updates globals without enums like "SelectionTypeEnum" or "LoadDefineBy" +# app = App() +# app.update_globals(globals(), False) + +# For a specific version , use ; +# app = App(version=241) + # %% # Import a Geometry File # ~~~~~~~~~~~~~~~~~~~~~~ diff --git a/examples/00_setup/02_geometry.py b/examples/00_setup/02_geometry.py index 62aeafd32..d621b6a65 100644 --- a/examples/00_setup/02_geometry.py +++ b/examples/00_setup/02_geometry.py @@ -36,51 +36,70 @@ from ansys.mechanical.core.examples import delete_downloads, download_file app = App(globals=globals()) + +# Download the geometry file for the example geom_file_path = download_file("example_06_bolt_pret_geom.agdb", "pymechanical", "00_basic") +# Alternatively, you can specify a local file path +# or geom_file_path = r"C:\geometry.agdb" + +# Import the geometry into the Mechanical model geometry_import = Model.GeometryImportGroup.AddGeometryImport() geometry_import_format = Ansys.Mechanical.DataModel.Enums.GeometryImportPreference.Format.Automatic geometry_import_preferences = Ansys.ACT.Mechanical.Utilities.GeometryImportPreferences() + +# Set preferences for geometry import geometry_import_preferences.ProcessLines = True geometry_import_preferences.NamedSelectionKey = "" geometry_import_preferences.ProcessNamedSelections = True geometry_import_preferences.ProcessMaterialProperties = True + +# Perform the geometry import geometry_import.Import(geom_file_path, geometry_import_format, geometry_import_preferences) -# Plot +# Plot the imported geometry app.plot() -# Print the tree +# Print the tree structure of the Mechanical model app.print_tree() # %% # Get all bodies # ~~~~~~~~~~~~~~~~~ + +# Retrieve all body objects from the geometry body_objects = Model.Geometry.GetChildren(DataModelObjectCategory.Body, True) -# or +# Alternatively, use the following method: # bodies_objects = Model.Geometry.GetChildren(Ansys.ACT.Automation.Mechanical.Body, True) +# Extract geometric body wrappers for each body object bodies = [body.GetGeoBody() for body in body_objects] # GeoBodyWrapper # or # import itertools # nested_list = [x.Bodies for x in ExtAPI.DataModel.GeoData.Assemblies[0].AllParts] # bodies = list(itertools.chain(*nested_list)) +# Access details of the first body object and its geometric properties bo = body_objects[0] # Access Object Details and RMB options b = bodies[0] # Access Geometric Properties: 'Area', 'GeoData', 'Centroid', 'Faces', etc. # %% # Find Body with Largest Volume # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Set the active unit system to Standard NMM ExtAPI.Application.ActiveUnitSystem = MechanicalUnitSystem.StandardNMM +# Create a list of body names, volumes, and IDs for unsuppressed bodies body_names_volumes = [] for body in body_objects: if body.Suppressed == 0 and body.Volume: body_names_volumes.append((body.Name, body.Volume, body.GetGeoBody().Id)) +# Sort the list and retrieve the body with the largest volume sorted_name_vol = sorted(body_names_volumes) bodyname, volu, bodyid = sorted_name_vol.pop() + +# Print details of the largest body print(f"Unit System is: {ExtAPI.Application.ActiveUnitSystem}") print(f"Name of the Largest Body: '{bodyname}'") print(f"Its Volume: {round(volu.Value, 2)} {volu.Unit}") @@ -89,12 +108,14 @@ # %% # Find Body by its ID # ~~~~~~~~~~~~~~~~~~~~~~ +# Retrieve a body object using its ID b2 = ExtAPI.DataModel.GeoData.GeoEntityById(bodyid) print(f"Body Name: {b2.Name}, Body Id: {b2.Id}") # %% # Find the Part that the body belongs to # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Retrieve the name of a body and the part it belongs to using its ID body_name = ExtAPI.DataModel.GeoData.GeoEntityById(59).Name part_name = ExtAPI.DataModel.GeoData.GeoEntityById(59).Part.Name print(f"The Body named '{body_name}' belongs to the part named '{part_name}'") @@ -102,18 +123,24 @@ # %% # Find Body by its ID AND print its Faces, Centroid, etc. # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Retrieve a body object and its faces, centroids, etc. body2 = ExtAPI.DataModel.GeoData.GeoEntityById(bodyid) +# Get face IDs and centroids for each face face_ids = [face.Id for face in body2.Faces] centroids_of_each_face = [ ExtAPI.DataModel.GeoData.GeoEntityById(face_id).Centroid for face_id in face_ids ] + +# Print face IDs and their centroids for face_id, centroid in zip(face_ids, centroids_of_each_face): print(face_id, list(centroid)) # %% # Get all Vertices # ~~~~~~~~~~~~~~~~~~~ + +# Retrieve all vertex IDs from the geometry vertices = [] geo = ExtAPI.DataModel.GeoData for asm in geo.Assemblies: @@ -126,12 +153,14 @@ # %% # Get all edges of a given length # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Retrieve all edges with a specified length ExtAPI.Application.ActiveUnitSystem = MechanicalUnitSystem.StandardNMM use_length = 0.100 geo = ExtAPI.DataModel.GeoData edgelist = [] +# Iterate through assemblies, parts, and bodies to find edges of the given length for asm in geo.Assemblies: for part in asm.Parts: for body in part.Bodies: @@ -143,14 +172,16 @@ # %% # Get all circular edges of a given radius # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Retrieve all circular edges with a specified radius import math -radius = 0.018 -circumference = 2 * math.pi * radius +radius = 0.018 # Target radius +circumference = 2 * math.pi * radius # Calculate circumference geo = ExtAPI.DataModel.GeoData circlelist = [] +# Iterate through assemblies, parts, and bodies to find circular edges for asm in geo.Assemblies: for part in asm.Parts: for body in part.Bodies: @@ -165,6 +196,7 @@ # %% # Get Radius of a selected edge # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Retrieve the radius of a specific edge if it is circular my_edge = ExtAPI.DataModel.GeoData.GeoEntityById(27) my_edge_radius = my_edge.Radius if str(my_edge.CurveType) == "GeoCurveCircle" else 0.0 print(my_edge_radius) @@ -172,6 +204,7 @@ # %% # Create a Named Selection from a list of body Ids # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Create a named selection for a list of body IDs mylist = [bodyid] selection_manager = ExtAPI.SelectionManager @@ -186,6 +219,7 @@ # %% # Find a Named Selection with a prefix # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Retrieve a named selection whose name starts with a specific prefix NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[ Ansys.ACT.Automation.Mechanical.NamedSelection ](True) @@ -195,6 +229,7 @@ # %% # Create a Named Selection of all bodies with a cylindrical face # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + geo = ExtAPI.DataModel.GeoData cyl_body_ids = [] @@ -224,6 +259,7 @@ # %% # Modify material assignment # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Assign a specific material to all bodies in the model allbodies = ExtAPI.DataModel.Project.Model.GetChildren(DataModelObjectCategory.Body, True) for body in allbodies: body.Material = "Structural Steel" @@ -231,11 +267,12 @@ # %% # Get all Coordinate Systems # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Retrieve all coordinate systems in the model tree_CS = ExtAPI.DataModel.Project.Model.CoordinateSystems # sphinx_gallery_start_ignore -# Save the mechdat +# Save the Mechanical database file from pathlib import Path output_path = Path.cwd() / "out" @@ -243,8 +280,7 @@ # app.save_as(test_mechdat_path, overwrite=True) -# Close the app +# Close the application and delete downloaded files app.close() -# Delete the downloaded files delete_downloads() # sphinx_gallery_end_ignore diff --git a/examples/00_setup/03_connections.py b/examples/00_setup/03_connections.py index 4f1f8864b..f795160c4 100644 --- a/examples/00_setup/03_connections.py +++ b/examples/00_setup/03_connections.py @@ -33,28 +33,40 @@ from ansys.mechanical.core.examples import delete_downloads, download_file app = App(globals=globals()) + +# Download the geometry file for the example geom_file_path = download_file("example_06_bolt_pret_geom.agdb", "pymechanical", "00_basic") + +# Import the geometry into the Mechanical model geometry_import = Model.GeometryImportGroup.AddGeometryImport() geometry_import_format = Ansys.Mechanical.DataModel.Enums.GeometryImportPreference.Format.Automatic geometry_import_preferences = Ansys.ACT.Mechanical.Utilities.GeometryImportPreferences() + +# Set preferences for geometry import geometry_import_preferences.ProcessLines = True geometry_import_preferences.NamedSelectionKey = "" geometry_import_preferences.ProcessNamedSelections = True geometry_import_preferences.ProcessMaterialProperties = True + +# Perform the geometry import geometry_import.Import(geom_file_path, geometry_import_format, geometry_import_preferences) # sphinx_gallery_end_ignore +# Plot the imported geometry app.plot() -# Print the tree +# Print the tree structure of the Mechanical model app.print_tree() # %% # Get information about all Contacts Defined # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Retrieve all contact regions defined in the model all_contacts = ExtAPI.DataModel.Project.Model.Connections.GetChildren( DataModelObjectCategory.ContactRegion, True ) + +# Print details of each contact region for contact in all_contacts: print( f"\n{contact.Parent.Name} > {contact.Name} : {contact.ContactType} : {contact.Suppressed} : {contact.ContactFormulation}" @@ -66,6 +78,8 @@ # %% # Create Automatic Connections on a chosen named selection # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Create a new connection group for automatic connections + contactgroup = ExtAPI.DataModel.Project.Model.Connections.AddConnectionGroup() contactgroup.FaceFace = True contactgroup.FaceEdge = contactgroup.FaceEdge.No @@ -73,22 +87,28 @@ contactgroup.Priority = contactgroup.Priority.FaceOverEdge contactgroup.InternalObject.DetectCylindricalFacesType = 1 +# Retrieve a named selection for the connection group NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[ Ansys.ACT.Automation.Mechanical.NamedSelection ](True) my_nsel = [i for i in NSall if i.Name == "bodies_5"][0] +# Assign the named selection to the connection group and create automatic connections contactgroup.Location = my_nsel contactgroup.CreateAutomaticConnections() +# Refresh the tree structure to reflect the changes mytree = ExtAPI.DataModel.Tree mytree.Refresh() # %% # Create a Contact region using face named selections # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Add a new contact region to the model c = ExtAPI.DataModel.Project.Model.Connections c1 = c.AddContactRegion() + +# Retrieve named selections for the source and target locations NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[ Ansys.ACT.Automation.Mechanical.NamedSelection ](True) @@ -101,19 +121,22 @@ # %% # Insert a Joint using face IDs # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Define face IDs for the joint face1 = 135 face2 = 160 + from pathlib import Path # delete output_path = Path.cwd() / "out" # delete test_mechdat_path = str(output_path / "temporarycheck.mechdat") # delete app.save_as(test_mechdat_path, overwrite=True) # delete - +# Add a new joint to the model model = ExtAPI.DataModel.Project.Model j = model.Connections.AddJoint() +# Define the reference and mobile locations for the joint using face IDs reference_scoping = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.GeometryEntities) reference_scoping.Ids = [face1] j.ReferenceLocation = reference_scoping @@ -125,18 +148,25 @@ # %% # Define a Bearing # ~~~~~~~~~~~~~~~~ +# Add a new bearing connection to the model brg = ExtAPI.DataModel.Project.Model.Connections.AddBearing() + +# Set the reference rotation plane for the bearing brg.ReferenceRotationPlane = RotationPlane.XY + +# Define stiffness values for the bearing brg.StiffnessK11.Output.DiscreteValues = [Quantity("11 [N/m]")] brg.StiffnessK22.Output.DiscreteValues = [Quantity("22 [N/m]")] brg.StiffnessK21.Output.DiscreteValues = [Quantity("21 [N/m]")] brg.StiffnessK12.Output.DiscreteValues = [Quantity("12 [N/m]")] +# Define damping values for the bearing brg.DampingC11.Output.DiscreteValues = [Quantity("111 [N sec m^-1]")] brg.DampingC22.Output.DiscreteValues = [Quantity("122 [N sec m^-1]")] brg.DampingC12.Output.DiscreteValues = [Quantity("112 [N sec m^-1]")] brg.DampingC21.Output.DiscreteValues = [Quantity("121 [N sec m^-1]")] +# Retrieve named selections for the reference and mobile locations NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[ Ansys.ACT.Automation.Mechanical.NamedSelection ](True) @@ -145,7 +175,7 @@ # sphinx_gallery_start_ignore -# Save the mechdat +# Save the Mechanical database file from pathlib import Path output_path = Path.cwd() / "out" @@ -153,13 +183,7 @@ # app.save_as(test_mechdat_path, overwrite=True) -# Close the app +# Close the application and delete downloaded files app.close() -# Delete the downloaded files delete_downloads() # sphinx_gallery_end_ignore - - -# %% -# TODO : Change Model for Joint and Bearing -# ~~~~~~~~~~~~~~~~ diff --git a/examples/00_setup/04_named_selections.py b/examples/00_setup/04_named_selections.py index b965a006d..bf99bb802 100644 --- a/examples/00_setup/04_named_selections.py +++ b/examples/00_setup/04_named_selections.py @@ -33,66 +33,78 @@ from ansys.mechanical.core.examples import delete_downloads, download_file app = App(globals=globals()) +# Download the geometry file for the example geom_file_path = download_file("example_05_td26_Rubber_Boot_Seal.agdb", "pymechanical", "00_basic") + +# Import the geometry into the Mechanical model geometry_import = Model.GeometryImportGroup.AddGeometryImport() geometry_import_format = Ansys.Mechanical.DataModel.Enums.GeometryImportPreference.Format.Automatic geometry_import_preferences = Ansys.ACT.Mechanical.Utilities.GeometryImportPreferences() + +# Set preferences for geometry import geometry_import_preferences.ProcessLines = True geometry_import_preferences.NamedSelectionKey = "" geometry_import_preferences.ProcessNamedSelections = True geometry_import_preferences.ProcessMaterialProperties = True + +# Perform the geometry import geometry_import.Import(geom_file_path, geometry_import_format, geometry_import_preferences) # sphinx_gallery_end_ignore -# Plot +# Plot the imported geometry app.plot() -# Print the tree +# Print the tree structure of the Mechanical model app.print_tree() # %% # Fetch all Named Selections -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# ~~~~~~~~~~~~~~~~~~~~~~~~~~ -# ALL NAMED SELECTIONS +# Retrieve all named selections in the model nsall = ExtAPI.DataModel.GetObjectsByType(DataModelObjectCategory.NamedSelections.NamedSelection) # %% # Delete a named selection -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# ~~~~~~~~~~~~~~~~~~~~~~~~ +# Retrieve all named selections in the project NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[ Ansys.ACT.Automation.Mechanical.NamedSelection ](True) -# Delete a named selection by name +# Delete a named selection by its name a = [i for i in NSall if i.Name == "Top_Face"][0] a.Delete() -# Alternative way to delete by name +# Alternative way to delete a named selection by name b = ExtAPI.DataModel.GetObjectsByName("Bottom_Face")[0] b.Delete() # %% # Create a named selection -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# ~~~~~~~~~~~~~~~~~~~~~~~~ +# Create a new named selection for specific geometry entities selection_manager = ExtAPI.SelectionManager selection = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.GeometryEntities) selection.Ids = [216, 221, 224] +# Add the named selection to the model model = ExtAPI.DataModel.Project.Model ns2 = model.AddNamedSelection() -ns2.Name = "faces" +ns2.Name = "faces" # Set the name of the named selection ns2.Location = selection -selection_manager.ClearSelection() +selection_manager.ClearSelection() # Clear the selection after creation - delete # %% # Create a Named Selection by Worksheet -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Create a named selection using worksheet criteria NS1 = DataModel.Project.Model.AddNamedSelection() NS1.ScopingMethod = GeometryDefineByType.Worksheet GenerationCriteria = NS1.GenerationCriteria +# Add criteria to the worksheet for selecting entities Criterion1 = Ansys.ACT.Automation.Mechanical.NamedSelectionCriterion() Criterion1.Action = SelectionActionType.Add Criterion1.EntityType = SelectionType.GeoFace @@ -109,16 +121,18 @@ Criterion2.Value = Quantity("0 [m]") GenerationCriteria.Add(Criterion2) +# Generate the named selection based on the criteria NS1.Generate() # %% # Find a Named Selection -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# ~~~~~~~~~~~~~~~~~~~~~~ +# Retrieve all named selections in the project NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[ Ansys.ACT.Automation.Mechanical.NamedSelection ](True) -# Find a named selection by name +# Find a specific named selection by its name a = [i for i in NSall if i.Name == "Rubber_Bodies30"][0] # Access entities in the named selection @@ -128,6 +142,7 @@ # %% # Identify Named Selections based on Name and Type # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Retrieve all named selections in the project NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[ Ansys.ACT.Automation.Mechanical.NamedSelection ](True) @@ -139,7 +154,7 @@ ns3 = [i for i in NSall if keywords[2] in i.Name] filtered = ns1 + ns2 + ns3 -# Further filter based on entity type +# Further filter the named selections based on entity type FaceNsels = [ i for i in filtered if str(ExtAPI.DataModel.GeoData.GeoEntityById(i.Ids[0]).Type) == "GeoFace" ] @@ -154,8 +169,7 @@ app.save_as(test_mechdat_path, overwrite=True) -# Close the app +# Close the application and delete downloaded files app.close() -# Delete the downloaded files delete_downloads() # sphinx_gallery_end_ignore diff --git a/examples/00_setup/05_mesh.py b/examples/00_setup/05_mesh.py index 3eb037c75..f97a7e53a 100644 --- a/examples/00_setup/05_mesh.py +++ b/examples/00_setup/05_mesh.py @@ -33,32 +33,39 @@ from ansys.mechanical.core.examples import delete_downloads, download_file app = App(globals=globals()) + +# Download and import the geometry file geom_file_path = download_file("example_06_bolt_pret_geom.agdb", "pymechanical", "00_basic") geometry_import = Model.GeometryImportGroup.AddGeometryImport() + +# Define geometry import format and preferences geometry_import_format = Ansys.Mechanical.DataModel.Enums.GeometryImportPreference.Format.Automatic geometry_import_preferences = Ansys.ACT.Mechanical.Utilities.GeometryImportPreferences() geometry_import_preferences.ProcessLines = True geometry_import_preferences.NamedSelectionKey = "" geometry_import_preferences.ProcessNamedSelections = True geometry_import_preferences.ProcessMaterialProperties = True + +# Import the geometry into the project geometry_import.Import(geom_file_path, geometry_import_format, geometry_import_preferences) # sphinx_gallery_end_ignore -# Plot +# Plot the imported geometry app.plot() -# Print the tree +# Print the Mechanical tree structure app.print_tree() # %% # Insert a Local Meshing Control for a Named Selection # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - +# Get all named selections and pick the one named "shank" NSall = Model.NamedSelections.GetChildren[Ansys.ACT.Automation.Mechanical.NamedSelection](True) use_nsel = [i for i in NSall if i.Name == "shank"][0] +# Add an Automatic Method mesh control scoped to the named selection ms = Model.Mesh.AddAutomaticMethod() ms.Location = use_nsel ms.Method = ms.Method.AllTriAllTet @@ -68,6 +75,7 @@ # %% # Generate Mesh # ~~~~~~~~~~~~~ +# Generate the mesh and print mesh object state Model.Mesh.GenerateMesh() print(Model.Mesh.ObjectState) @@ -75,15 +83,21 @@ # %% # Get Element Count of a meshed body # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Access mesh data meshdata = DataModel.MeshDataByName("Global") print(use_nsel.Ids[0]) + +# Retrieve body entity from geometry geoBody = DataModel.GeoData.GeoEntityById(use_nsel.Ids[0]) body = Model.Geometry.GetBody(geoBody) + +# Get mesh region corresponding to that body and print element count meshregion = meshdata.MeshRegionById(geoBody.Id) print(body.Name, meshregion.ElementCount) # sphinx_gallery_start_ignore +# Clear the generated mesh to start fresh for next operations Model.Mesh.ClearGeneratedData() # sphinx_gallery_end_ignore @@ -91,9 +105,11 @@ # %% # Insert a Sweep Method (Scoping Method: Named Selection) # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Get all named selections and pick the one named "bodies_5" NSall = Model.NamedSelections.GetChildren[Ansys.ACT.Automation.Mechanical.NamedSelection](True) use_nsel = [i for i in NSall if i.Name == "bodies_5"][0] +# Add a sweep meshing method scoped to the named selection mesh = Model.Mesh mesh_method = mesh.AddAutomaticMethod() mesh_method.Location = use_nsel @@ -102,14 +118,19 @@ # %% # Insert a Mesh Sizing Control (Scoping Method: Geometry Selection) # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Get all named selections and pick the one containing "bottom_surface" NSall = Model.NamedSelections.GetChildren[Ansys.ACT.Automation.Mechanical.NamedSelection](True) ns = [i for i in NSall if "bottom_surface" in i.Name][0] +# Extract bottom face and its edges bot_face = DataModel.GeoData.GeoEntityById(ns.Ids[0]) body_ids = [edge.Id for edge in bot_face.Edges] + +# Create a geometry selection object from edges sel = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.GeometryEntities) sel.Ids = body_ids +# Apply mesh sizing control to the selection mesh = Model.Mesh mesh_sizing = mesh.AddSizing() mesh_sizing.Location = sel @@ -117,7 +138,8 @@ # sphinx_gallery_start_ignore -# Save the mechdat +# Save the project as a .mechdat file (currently commented out) + from pathlib import Path output_path = Path.cwd() / "out" @@ -125,8 +147,8 @@ # app.save_as(test_mechdat_path, overwrite=True) -# Close the app +# Close the Mechanical application app.close() -# Delete the downloaded files +# Delete any downloaded example files delete_downloads() # sphinx_gallery_end_ignore diff --git a/examples/00_setup/06_loads.py b/examples/00_setup/06_loads.py index 71231adf6..5b9ac3431 100644 --- a/examples/00_setup/06_loads.py +++ b/examples/00_setup/06_loads.py @@ -42,8 +42,11 @@ geometry_import_preferences.ProcessNamedSelections = True geometry_import_preferences.ProcessMaterialProperties = True geometry_import.Import(geom_file_path, geometry_import_format, geometry_import_preferences) + +# Generate mesh for the imported geometry Model.Mesh.GenerateMesh() +# Create named selections for fixed support and force application selection_manager = ExtAPI.SelectionManager selection = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.GeometryEntities) selection.Ids = [30] @@ -73,6 +76,7 @@ # %% # Add an Analysis # ~~~~~~~~~~~~~~~ +# Create a static structural analysis analysis = Model.AddStaticStructuralAnalysis() # %% Apply Bolt Pretension by Face ID @@ -80,23 +84,28 @@ analysis_settings = Model.Analyses[0].AnalysisSettings analysis_settings.NumberOfSteps = 6 +# Define coordinate system at face ID = 39 selection = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.GeometryEntities) selection.Ids = [39] csys1 = Model.CoordinateSystems.AddCoordinateSystem() csys1.OriginLocation = selection csys1.Name="cyl" +# Apply bolt pretension load pretension = Model.Analyses[0].AddBoltPretension() pretension.Location = selection pretension.CoordinateSystem = csys1 pretension.SetDefineBy(1, BoltLoadDefineBy.Load) pretension.Preload.Output.SetDiscreteValue(0, Quantity("1500[N]")) +# Lock the bolt for remaining steps for i in range(2, analysis_settings.NumberOfSteps + 1): pretension.SetDefineBy(int(i), BoltLoadDefineBy.Lock) # %% # Apply a Fixed Support # ~~~~~~~~~~~~~~~~~~~~~ +# Define a fixed support boundary condition on a specific geometry entity. + support = Model.Analyses[0].AddFixedSupport() support_scoping = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.GeometryEntities) support_scoping.Ids = [30] @@ -108,7 +117,7 @@ pressure = Model.Analyses[0].AddPressure() part1 = Model.Geometry.Children[0] body1 = part1.Children[0] -face1 = body1.GetGeoBody().Faces[0] # Get the first face of the body. +face1 = body1.GetGeoBody().Faces[0] # First face of first body selection = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.GeometryEntities) selection.Entities = [face1] pressure.Location = selection @@ -149,6 +158,7 @@ nodes_list = [16,2329] force_quantities_list = ["100 [N]", "-200 [N]"] +# Loop through nodes and apply nodal force for i in range(len(nodes_list)): N1 = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.MeshNodes) N1.Ids = [nodes_list[i]] @@ -166,6 +176,7 @@ # %% # Apply Force and Fixed Support using Named Selections # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Create named selections for force and fixed support selection_manager = ExtAPI.SelectionManager selection = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.GeometryEntities) selection.Ids = [65] @@ -183,10 +194,12 @@ ns2.Location = selection selection_manager.ClearSelection() +# Retrieve named selections NSall = Model.NamedSelections.GetChildren[Ansys.ACT.Automation.Mechanical.NamedSelection](True) for_fixed_supp = [i for i in NSall if i.Name.startswith("fixed")][0] for_force = [i for i in NSall if i.Name.startswith("force")][0] +# Apply load and support via named selections f = Model.Analyses[0].AddForce() f.Location = for_force f.Name = "Force1" @@ -233,11 +246,13 @@ # %% # Applying Direct FE Type Boundary Conditions # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Retrieve coordinate system named "cyl" and named selection "force" CSall = Model.CoordinateSystems.GetChildren[Ansys.ACT.Automation.Mechanical.CoordinateSystem](True) a = [i for i in CSall if i.Name == "cyl"][0] NSall = Model.NamedSelections.GetChildren[Ansys.ACT.Automation.Mechanical.NamedSelection](True) n = [i for i in NSall if i.Name == "force"][0] +# Nodal Force nf = Model.Analyses[0].AddNodalForce() nf.Location = n nf.YComponent.Inputs[0].DiscreteValues = [Quantity("0 [sec]"), Quantity("1 [sec]")] @@ -245,6 +260,7 @@ nf.XYZFunctionCoordinateSystem = a nf.YComponent.Output.DiscreteValues = [Quantity("0 [N]"), Quantity("100[N]")] +# Nodal Displacement nd = Model.Analyses[0].AddNodalDisplacement() nd.Location = n nd.YComponent.Inputs[0].DiscreteValues = [Quantity("0 [sec]"), Quantity("1 [sec]")] @@ -252,6 +268,7 @@ nd.XYZFunctionCoordinateSystem = a nd.YComponent.Output.DiscreteValues = [Quantity("0 [mm]"), Quantity("100[mm]")] +# Nodal Pressure np = Model.Analyses[0].AddNodalPressure() np.Location = n np.Magnitude.Inputs[0].DiscreteValues = [Quantity("0 [sec]"), Quantity("1 [sec]")] @@ -260,15 +277,16 @@ np.Magnitude.Output.DiscreteValues = [Quantity("0 [Pa]"), Quantity("100[Pa]")] # sphinx_gallery_start_ignore -# Save the mechdat +# Save the project as a mechdat file (currently commented out) + from pathlib import Path output_path = Path.cwd() / "out" test_mechdat_path = str(output_path / "test_loads.mechdat") # app.save_as(test_mechdat_path, overwrite=True) -# Close the app +# Close Mechanical application app.close() -# Delete the downloaded files +# Delete downloaded files delete_downloads() # sphinx_gallery_end_ignore diff --git a/examples/00_setup/07_results.py b/examples/00_setup/07_results.py index dbcbf05b5..fe1c2f7c6 100644 --- a/examples/00_setup/07_results.py +++ b/examples/00_setup/07_results.py @@ -31,10 +31,14 @@ # sphinx_gallery_start_ignore import os +# Import Mechanical API core and example utilities from ansys.mechanical.core import App from ansys.mechanical.core.examples import delete_downloads, download_file +# Download an example Mechanical database (.mechdat file) mechdat_path = download_file("example_03_simple_bolt_new.mechdat", "pymechanical", "00_basic") + +# Launch Mechanical and open the example database app = App(db_file=mechdat_path, globals=globals()) print(app) @@ -42,19 +46,23 @@ # sphinx_gallery_end_ignore -# Plot +# Plot the geometry of the model app.plot() -# Print the tree +# Print the Mechanical tree structure app.print_tree() # %% # Solve # ~~~~~ +# Access the first analysis system (Static Structural) static_struct = app.DataModel.AnalysisList[0] + +# Clear any previously generated solution data static_struct.Solution.ClearGeneratedData() print("Solution Status:", static_struct.Solution.Status) +# Run the solver static_struct.Solution.Solve() print("Solution Status:", static_struct.Solution.Status) @@ -62,7 +70,7 @@ # %% # Results that are accessible for GetResult # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - +# List names of results already available in the solution result_names = static_struct.GetResultsData().ResultNames print("Available Results:", ", ".join(result_names)) @@ -70,7 +78,7 @@ # %% # List Result Objects that can be added # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - +# Show all available result objects that can be inserted into the solution all_results = [x for x in dir(static_struct) if str(x)[:3] == "Add"] print(all_results) @@ -78,13 +86,14 @@ # Insert a Result # ~~~~~~~~~~~~~~~ - +# Add a Total Deformation result and evaluate it total_deformation = static_struct.Solution.AddTotalDeformation() total_deformation.EvaluateAllResults() # %% Access max and min of a result # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Retrieve the minimum and maximum values for total deformation minimum_deformation = total_deformation.Minimum maximum_deformation = total_deformation.Maximum print(f"Minimum Deformation: {minimum_deformation}") @@ -93,6 +102,7 @@ # %% # Get Results by Node Number # ~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Extract displacement ("U") results for a specific node ID node_number = 2000 result_data = static_struct.GetResultsData() node_values = result_data.GetResult("U").GetNodeValues(node_number) @@ -103,35 +113,45 @@ # ~~~~~~~~~~~~~~~~~~~~ -# Insert a command object +# Insert a command snippet into the solution (for custom APDL/commands) cs = static_struct.Solution.AddCommandSnippet() # %% # Fatigue Results # ~~~~~~~~~~~~~~~ +# Add a Fatigue Tool to the solution + solution = static_struct.Solution fatigue_tool = solution.AddFatigueTool() +# Insert a Safety Factor calculation under the fatigue tool safety_factor = fatigue_tool.AddSafetyFactor() + +# Scope safety factor evaluation to specific mesh nodes selection = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.MeshNodes) selection.Ids = [1, 2] safety_factor.Location = selection + +# Get the minimum safety factor value minimum = safety_factor.Minimum print("Safety Factor Minimum:", minimum) -# Export safety factor to a text file +# Export safety factor results to a text file fname = "safety_factor_results.txt" safety_factor.ExportToTextFile(True, fname) # %% # User-defined Result # ~~~~~~~~~~~~~~~~~~~ +# Insert a User-Defined Result object user_result = static_struct.Solution.AddUserDefinedResult() print("User-defined Result Added:", user_result) # %% # Get number of result sets # ~~~~~~~~~~~~~~~~~~~~~~~~~ +# Retrieve the number of available result sets (time/frequency steps) + reader = static_struct.GetResultsData() result_set_count = reader.ListTimeFreq.Count print("Number of Result Sets:", result_set_count) @@ -140,6 +160,7 @@ # %% # Export all results in the tree to PNG (2D image) files # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Iterate over all result objects and export each one to an image results = DataModel.GetObjectsByType(DataModelObjectCategory.Result) for result in results: result.Activate() @@ -154,7 +175,7 @@ # sphinx_gallery_start_ignore -# Save the mechdat +# Save the project as a .mechdat file from pathlib import Path output_path = Path.cwd() / "out" @@ -162,7 +183,8 @@ # app.save_as(test_mechdat_path, overwrite=True) -# Close the app +# Close Mechanical application + app.close() # Delete the downloaded files # delete_downloads() diff --git a/examples/00_setup/08_tree_objects.py b/examples/00_setup/08_tree_objects.py index 00513779a..9f190478d 100644 --- a/examples/00_setup/08_tree_objects.py +++ b/examples/00_setup/08_tree_objects.py @@ -32,37 +32,44 @@ from ansys.mechanical.core import App from ansys.mechanical.core.examples import delete_downloads, download_file +# Initialize the Mechanical application app = App(globals=globals()) + +# Download and import the geometry file geom_file_path = download_file("Valve.pmdb", "pymechanical", "embedding") geometry_import = Model.GeometryImportGroup.AddGeometryImport() geometry_import_format = Ansys.Mechanical.DataModel.Enums.GeometryImportPreference.Format.Automatic + +# Define geometry import format and preferences geometry_import_preferences = Ansys.ACT.Mechanical.Utilities.GeometryImportPreferences() geometry_import_preferences.ProcessLines = True geometry_import_preferences.NamedSelectionKey = "" geometry_import_preferences.ProcessNamedSelections = True geometry_import_preferences.ProcessMaterialProperties = True + +# Import the geometry into the project geometry_import.Import(geom_file_path, geometry_import_format, geometry_import_preferences) # sphinx_gallery_end_ignore -# Plot +# Plot the imported geometry app.plot() -# Print the tree +# Print the Mechanical tree structure app.print_tree() # %% # Accessing Geometry # ~~~~~~~~~~~~~~~~~~ -# Example of accessing geometry by ID. +# Access a specific geometry entity by its ID. body = ExtAPI.DataModel.GeoData.GeoEntityById(312) # %% # Accessing Mesh Data # ~~~~~~~~~~~~~~~~~~~~~~ -# Example of accessing mesh data by name. +# Access specific mesh data by name and ID. node = ExtAPI.DataModel.MeshDataByName("Global").NodeById(555) element = ExtAPI.DataModel.MeshDataByName("Global").ElementById(444) @@ -72,32 +79,32 @@ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Examples of accessing all objects, bodies, named selections, and contact regions. -# All tree objects +# Retrieve all objects in the tree AllObj = ExtAPI.DataModel.Project.Model.GetChildren(DataModelObjectCategory.DataModelObject, True) -# All bodies +# Retrieve all bodies all_bodies = ExtAPI.DataModel.Project.Model.GetChildren(DataModelObjectCategory.Body, True) -# All named selections +# Retrieve all named selections ns_all = ExtAPI.DataModel.GetObjectsByType(DataModelObjectCategory.NamedSelections.NamedSelection) -# All contact regions +# Retrieve all contact regions abc = ExtAPI.DataModel.GetObjectsByType(DataModelObjectCategory.ContactRegion) all_contacts = ExtAPI.DataModel.Project.Model.Connections.GetChildren( DataModelObjectCategory.ContactRegion, True ) -# A specific contact region +# Access a specific contact region by name my_contact = [contact for contact in all_contacts if contact.Name == "Contact Region"][0] -# All result objects of a specific type +# Retrieve all result objects of a specific type (e.g., Normal Stress) all_norm_stress = ExtAPI.DataModel.GetObjectsByType(DataModelObjectCategory.Result.NormalStress) -# Other examples +# Retrieve other objects such as remote points and analyses all_remote_points = ExtAPI.DataModel.GetObjectsByType(DataModelObjectCategory.RemotePoint) ana = ExtAPI.DataModel.Tree.GetObjectsByType(DataModelObjectCategory.Analysis) -# Using ACT Automation API +# Using the ACT Automation API to retrieve specific objects all_contacts2 = ExtAPI.DataModel.Project.Model.Connections.GetChildren[ Ansys.ACT.Automation.Mechanical.Connections.ContactRegion ](True) @@ -111,17 +118,21 @@ # %% # Finding Duplicate Objects by Name # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# Example of finding duplicate objects by name. +# Identify duplicate objects in the project tree based on their names. import collections +# Retrieve all objects and their names AllObj = ExtAPI.DataModel.Project.Model.GetChildren(DataModelObjectCategory.DataModelObject, True) AllObjNames = [x.Name for x in AllObj] + +# Find duplicate names duplicates_by_name = [item for item, count in collections.Counter(AllObjNames).items() if count > 1] print(duplicates_by_name) # sphinx_gallery_start_ignore +# Add a static structural analysis and equivalent stress result for testing static_struct = Model.AddStaticStructuralAnalysis() static_struct.Solution.AddEquivalentStress() # sphinx_gallery_end_ignore @@ -130,8 +141,8 @@ # %% # Using DataObjects and GetByName # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# Example of using DataObjects and GetByName. +# Access specific data objects by their names. c1 = "Solution" c2 = "Equivalent Stress" c = DataModel.AnalysisList[0].DataObjects.GetByName(c1).DataObjects.GetByName(c2) @@ -139,12 +150,14 @@ # %% # Using DataObjects, NamesByType, and GetByName # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# Example of using DataObjects, NamesByType, and GetByName. +# Access and filter contact regions based on their properties. new_contact_list = [] dataobjects = ExtAPI.DataModel.AnalysisList[0].DataObjects for group in dataobjects: print(group.Type) + +# Retrieve names of all contact groups names = dataobjects.NamesByType("ContactGroup") for name in names: connet_data_objects = dataobjects.GetByName(name).DataObjects @@ -173,14 +186,13 @@ # %% # Using GetObjectsByName # ~~~~~~~~~~~~~~~~~~~~~~~~~ -# Example of using GetObjectsByName. - +# Access a specific object by its name. bb = ExtAPI.DataModel.GetObjectsByName("Connector\Solid1")[0] # %% # Accessing a Named Selection # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# Example of accessing a named selection. +# Access specific named selections by their names. NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[ Ansys.ACT.Automation.Mechanical.NamedSelection @@ -193,16 +205,18 @@ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Example of getting all unsuppressed bodies and point masses. +# Retrieve all unsuppressed bodies all_bodies = ExtAPI.DataModel.Project.Model.GetChildren(DataModelObjectCategory.Body, True) all_bodies = [i for i in all_bodies if not i.Suppressed] print(len(all_bodies)) +# Retrieve all unsuppressed point masses all_pm = ExtAPI.DataModel.Project.Model.GetChildren(DataModelObjectCategory.PointMass, True) all_pm = [i for i in all_pm if not i.Suppressed] # sphinx_gallery_start_ignore -# Save the mechdat +# Save the Mechanical database file from pathlib import Path output_path = Path.cwd() / "out" @@ -210,8 +224,7 @@ # app.save_as(test_mechdat_path, overwrite=True) -# Close the app +# Close the application and delete downloaded files app.close() -# Delete the downloaded files delete_downloads() # sphinx_gallery_end_ignore From 55058e881984f2b0fa057995e4343847b332dc1b Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 12 Sep 2025 17:31:19 +0000 Subject: [PATCH 22/32] chore: auto fixes from pre-commit hooks --- examples/00_setup/02_geometry.py | 2 +- examples/00_setup/04_named_selections.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/00_setup/02_geometry.py b/examples/00_setup/02_geometry.py index d621b6a65..8e5983455 100644 --- a/examples/00_setup/02_geometry.py +++ b/examples/00_setup/02_geometry.py @@ -86,7 +86,7 @@ # %% # Find Body with Largest Volume # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# Set the active unit system to Standard NMM +# Set the active unit system to Standard NMM ExtAPI.Application.ActiveUnitSystem = MechanicalUnitSystem.StandardNMM # Create a list of body names, volumes, and IDs for unsuppressed bodies diff --git a/examples/00_setup/04_named_selections.py b/examples/00_setup/04_named_selections.py index bf99bb802..433d915aa 100644 --- a/examples/00_setup/04_named_selections.py +++ b/examples/00_setup/04_named_selections.py @@ -92,9 +92,9 @@ # Add the named selection to the model model = ExtAPI.DataModel.Project.Model ns2 = model.AddNamedSelection() -ns2.Name = "faces" # Set the name of the named selection +ns2.Name = "faces" # Set the name of the named selection ns2.Location = selection -selection_manager.ClearSelection() # Clear the selection after creation - delete +selection_manager.ClearSelection() # Clear the selection after creation - delete # %% # Create a Named Selection by Worksheet From 90b73d44255f7c4fb90cd87ce5122d139a5511c1 Mon Sep 17 00:00:00 2001 From: rs-bh-n Date: Fri, 12 Sep 2025 23:26:43 +0530 Subject: [PATCH 23/32] all htmls generated --- examples/00_setup/08_tree_objects.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/00_setup/08_tree_objects.py b/examples/00_setup/08_tree_objects.py index 9f190478d..0fdf4bf69 100644 --- a/examples/00_setup/08_tree_objects.py +++ b/examples/00_setup/08_tree_objects.py @@ -226,5 +226,5 @@ # Close the application and delete downloaded files app.close() -delete_downloads() +# delete_downloads() # sphinx_gallery_end_ignore From dc5068afff3bd9030d8456abaf182396d42311ab Mon Sep 17 00:00:00 2001 From: dkunhamb Date: Fri, 12 Sep 2025 13:32:39 -0500 Subject: [PATCH 24/32] fix style --- examples/00_setup/01_setup.py | 5 +++-- examples/00_setup/03_connections.py | 3 ++- examples/00_setup/06_loads.py | 24 ++++++++++++------------ examples/00_setup/07_results.py | 2 +- examples/00_setup/08_tree_objects.py | 2 +- 5 files changed, 19 insertions(+), 17 deletions(-) diff --git a/examples/00_setup/01_setup.py b/examples/00_setup/01_setup.py index 9429b4fe1..1866d5c7f 100644 --- a/examples/00_setup/01_setup.py +++ b/examples/00_setup/01_setup.py @@ -44,8 +44,9 @@ print(app) -# Alternatively, you can use the update_globals method of the App class to update the global variables: -# The second argument, if set to False updates globals without enums like "SelectionTypeEnum" or "LoadDefineBy" +# Alternatively, you can use the update_globals method of the App class to +# update the global variables.The second argument, if set to False updates +# globals without enums like "SelectionTypeEnum" or "LoadDefineBy" # app = App() # app.update_globals(globals(), False) diff --git a/examples/00_setup/03_connections.py b/examples/00_setup/03_connections.py index f795160c4..179c5e105 100644 --- a/examples/00_setup/03_connections.py +++ b/examples/00_setup/03_connections.py @@ -69,7 +69,8 @@ # Print details of each contact region for contact in all_contacts: print( - f"\n{contact.Parent.Name} > {contact.Name} : {contact.ContactType} : {contact.Suppressed} : {contact.ContactFormulation}" + f"\n{contact.Parent.Name} > {contact.Name} : {contact.ContactType} : " + f"{contact.Suppressed} : {contact.ContactFormulation}" ) print("Contact: ", contact.ContactBodies, list(contact.SourceLocation.Ids)) print("Target: ", contact.TargetBodies, list(contact.TargetLocation.Ids)) diff --git a/examples/00_setup/06_loads.py b/examples/00_setup/06_loads.py index d4fe2b15b..9425394a9 100644 --- a/examples/00_setup/06_loads.py +++ b/examples/00_setup/06_loads.py @@ -262,20 +262,20 @@ nf.YComponent.Output.DiscreteValues = [Quantity("0 [N]"), Quantity("100[N]")] # Nodal Displacement -nd = Model.Analyses[0].AddNodalDisplacement() -nd.Location = n -nd.YComponent.Inputs[0].DiscreteValues = [Quantity("0 [sec]"), Quantity("1 [sec]")] -nd.IndependentVariable = LoadVariableVariationType.YValue -nd.XYZFunctionCoordinateSystem = a -nd.YComponent.Output.DiscreteValues = [Quantity("0 [mm]"), Quantity("100[mm]")] +nodal_displacement = Model.Analyses[0].AddNodalDisplacement() +nodal_displacement.Location = n +nodal_displacement.YComponent.Inputs[0].DiscreteValues = [Quantity("0 [sec]"), Quantity("1 [sec]")] +nodal_displacement.IndependentVariable = LoadVariableVariationType.YValue +nodal_displacement.XYZFunctionCoordinateSystem = a +nodal_displacement.YComponent.Output.DiscreteValues = [Quantity("0 [mm]"), Quantity("100[mm]")] # Nodal Pressure -np = Model.Analyses[0].AddNodalPressure() -np.Location = n -np.Magnitude.Inputs[0].DiscreteValues = [Quantity("0 [sec]"), Quantity("1 [sec]")] -np.IndependentVariable = LoadVariableVariationType.YValue -np.XYZFunctionCoordinateSystem = a -np.Magnitude.Output.DiscreteValues = [Quantity("0 [Pa]"), Quantity("100[Pa]")] +nodal_pressure = Model.Analyses[0].AddNodalPressure() +nodal_pressure.Location = n +nodal_pressure.Magnitude.Inputs[0].DiscreteValues = [Quantity("0 [sec]"), Quantity("1 [sec]")] +nodal_pressure.IndependentVariable = LoadVariableVariationType.YValue +nodal_pressure.XYZFunctionCoordinateSystem = a +nodal_pressure.Magnitude.Output.DiscreteValues = [Quantity("0 [Pa]"), Quantity("100[Pa]")] # sphinx_gallery_start_ignore # Save the project as a mechdat file (currently commented out) diff --git a/examples/00_setup/07_results.py b/examples/00_setup/07_results.py index fe1c2f7c6..0bd5a699e 100644 --- a/examples/00_setup/07_results.py +++ b/examples/00_setup/07_results.py @@ -187,5 +187,5 @@ app.close() # Delete the downloaded files -# delete_downloads() +delete_downloads() # sphinx_gallery_end_ignore diff --git a/examples/00_setup/08_tree_objects.py b/examples/00_setup/08_tree_objects.py index 0fdf4bf69..9f190478d 100644 --- a/examples/00_setup/08_tree_objects.py +++ b/examples/00_setup/08_tree_objects.py @@ -226,5 +226,5 @@ # Close the application and delete downloaded files app.close() -# delete_downloads() +delete_downloads() # sphinx_gallery_end_ignore From 85234e45937afd89cb86b0c0855fa3e259afd2b3 Mon Sep 17 00:00:00 2001 From: dkunhamb Date: Fri, 12 Sep 2025 16:58:44 -0500 Subject: [PATCH 25/32] fix crash --- examples/00_setup/07_results.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/00_setup/07_results.py b/examples/00_setup/07_results.py index 0bd5a699e..02dbb13d7 100644 --- a/examples/00_setup/07_results.py +++ b/examples/00_setup/07_results.py @@ -138,7 +138,7 @@ # Export safety factor results to a text file fname = "safety_factor_results.txt" -safety_factor.ExportToTextFile(True, fname) +safety_factor.ExportToTextFile(fname) # %% # User-defined Result @@ -155,7 +155,7 @@ reader = static_struct.GetResultsData() result_set_count = reader.ListTimeFreq.Count print("Number of Result Sets:", result_set_count) - +reader.Dispose() # %% # Export all results in the tree to PNG (2D image) files From cb19e16814ef8c19a53f3a925c893794fc5c0df7 Mon Sep 17 00:00:00 2001 From: rs-bh-n Date: Sun, 14 Sep 2025 23:05:11 +0530 Subject: [PATCH 26/32] dispose added --- examples/00_setup/07_results.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/00_setup/07_results.py b/examples/00_setup/07_results.py index fe1c2f7c6..1e19b91be 100644 --- a/examples/00_setup/07_results.py +++ b/examples/00_setup/07_results.py @@ -155,7 +155,7 @@ reader = static_struct.GetResultsData() result_set_count = reader.ListTimeFreq.Count print("Number of Result Sets:", result_set_count) - +reader.Dispose() # %% # Export all results in the tree to PNG (2D image) files From 20a8e6a9fb8a85d6428c659c6442b21bc7d29a73 Mon Sep 17 00:00:00 2001 From: rs-bh-n Date: Thu, 18 Sep 2025 10:24:04 +0530 Subject: [PATCH 27/32] geom description --- examples/00_setup/02_geometry.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/00_setup/02_geometry.py b/examples/00_setup/02_geometry.py index 8e5983455..33545926b 100644 --- a/examples/00_setup/02_geometry.py +++ b/examples/00_setup/02_geometry.py @@ -25,7 +25,7 @@ Geometry -------- -This section has helper scripts for Geometry +This section contains utility scripts for working with Geometry, including importing, analyzing, and accessing geometric data, as well as utilizing it for downstream preprocessing operations in Mechanical simulations. """ # %% From 26a0af66facda6ea7cbff1a4a7ae8ac247bf8862 Mon Sep 17 00:00:00 2001 From: rs-bh-n Date: Thu, 18 Sep 2025 22:00:07 +0530 Subject: [PATCH 28/32] added more snippets from prompt forge --- examples/00_setup/01_setup.py | 14 +++ examples/00_setup/02_geometry.py | 68 ++++++++--- examples/00_setup/03_connections.py | 47 +++++-- examples/00_setup/04_named_selections.py | 39 ++++-- examples/00_setup/05_mesh.py | 15 ++- examples/00_setup/06_loads.py | 148 +++++++++++++++++++++++ examples/00_setup/08_tree_objects.py | 58 +++++---- 7 files changed, 325 insertions(+), 64 deletions(-) diff --git a/examples/00_setup/01_setup.py b/examples/00_setup/01_setup.py index 1866d5c7f..11290cd30 100644 --- a/examples/00_setup/01_setup.py +++ b/examples/00_setup/01_setup.py @@ -71,6 +71,20 @@ geometry_import_preferences.ProcessMaterialProperties = True geometry_import.Import(geom_file_path, geometry_import_format, geometry_import_preferences) +# %% +# Set Units +# ~~~~~~~~~~~~~~~~~~~~~~~ + +app.ExtAPI.Application.ActiveUnitSystem = MechanicalUnitSystem.StandardNMM +app.ExtAPI.Application.ActiveAngleUnit = AngleUnitType.Radian +app.ExtAPI.Application.ActiveAngularVelocityUnit=AngularVelocityUnitType.RadianPerSecond + +# %% +# View messages in Mechanical using PyMechanical +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +app.messages.show() + # %% # Plot and Print the Tree (To check model so far) diff --git a/examples/00_setup/02_geometry.py b/examples/00_setup/02_geometry.py index 33545926b..12aa36f7d 100644 --- a/examples/00_setup/02_geometry.py +++ b/examples/00_setup/02_geometry.py @@ -25,7 +25,7 @@ Geometry -------- -This section contains utility scripts for working with Geometry, including importing, analyzing, and accessing geometric data, as well as utilizing it for downstream preprocessing operations in Mechanical simulations. +This section contains utility scripts for working with Geometry, including importing, analyzing, and accessing geometric data, as well as utilizing it for downstream preprocessing operations in Mechanical simulations. Coordinate Systems too are covered here. """ # %% @@ -109,27 +109,27 @@ # Find Body by its ID # ~~~~~~~~~~~~~~~~~~~~~~ # Retrieve a body object using its ID -b2 = ExtAPI.DataModel.GeoData.GeoEntityById(bodyid) +b2 = DataModel.GeoData.GeoEntityById(bodyid) print(f"Body Name: {b2.Name}, Body Id: {b2.Id}") # %% # Find the Part that the body belongs to # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Retrieve the name of a body and the part it belongs to using its ID -body_name = ExtAPI.DataModel.GeoData.GeoEntityById(59).Name -part_name = ExtAPI.DataModel.GeoData.GeoEntityById(59).Part.Name +body_name = DataModel.GeoData.GeoEntityById(59).Name +part_name = DataModel.GeoData.GeoEntityById(59).Part.Name print(f"The Body named '{body_name}' belongs to the part named '{part_name}'") # %% # Find Body by its ID AND print its Faces, Centroid, etc. # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Retrieve a body object and its faces, centroids, etc. -body2 = ExtAPI.DataModel.GeoData.GeoEntityById(bodyid) +body2 = DataModel.GeoData.GeoEntityById(bodyid) # Get face IDs and centroids for each face face_ids = [face.Id for face in body2.Faces] centroids_of_each_face = [ - ExtAPI.DataModel.GeoData.GeoEntityById(face_id).Centroid for face_id in face_ids + DataModel.GeoData.GeoEntityById(face_id).Centroid for face_id in face_ids ] # Print face IDs and their centroids @@ -142,7 +142,7 @@ # Retrieve all vertex IDs from the geometry vertices = [] -geo = ExtAPI.DataModel.GeoData +geo = DataModel.GeoData for asm in geo.Assemblies: for part in asm.Parts: for body in part.Bodies: @@ -157,7 +157,7 @@ ExtAPI.Application.ActiveUnitSystem = MechanicalUnitSystem.StandardNMM use_length = 0.100 -geo = ExtAPI.DataModel.GeoData +geo = DataModel.GeoData edgelist = [] # Iterate through assemblies, parts, and bodies to find edges of the given length @@ -178,7 +178,7 @@ radius = 0.018 # Target radius circumference = 2 * math.pi * radius # Calculate circumference -geo = ExtAPI.DataModel.GeoData +geo = DataModel.GeoData circlelist = [] # Iterate through assemblies, parts, and bodies to find circular edges @@ -197,7 +197,7 @@ # Get Radius of a selected edge # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Retrieve the radius of a specific edge if it is circular -my_edge = ExtAPI.DataModel.GeoData.GeoEntityById(27) +my_edge = DataModel.GeoData.GeoEntityById(27) my_edge_radius = my_edge.Radius if str(my_edge.CurveType) == "GeoCurveCircle" else 0.0 print(my_edge_radius) @@ -212,7 +212,7 @@ selection.Ids = mylist selection_manager.NewSelection(selection) -ns2 = ExtAPI.DataModel.Project.Model.AddNamedSelection() +ns2 = Model.AddNamedSelection() ns2.Name = "bodies2" ns2.Location = selection @@ -220,7 +220,7 @@ # Find a Named Selection with a prefix # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Retrieve a named selection whose name starts with a specific prefix -NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[ +NSall = Model.NamedSelections.GetChildren[ Ansys.ACT.Automation.Mechanical.NamedSelection ](True) my_nsel = [i for i in NSall if i.Name.startswith("b")][0] @@ -230,7 +230,7 @@ # Create a Named Selection of all bodies with a cylindrical face # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -geo = ExtAPI.DataModel.GeoData +geo = DataModel.GeoData cyl_body_ids = [] for asm in geo.Assemblies: @@ -250,8 +250,7 @@ selection = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.GeometryEntities) selection.Ids = cyl_body_ids -model = ExtAPI.DataModel.Project.Model -ns2 = model.AddNamedSelection() +ns2 = Model.AddNamedSelection() ns2.Name = "bodies_with_cyl_face" ns2.Location = selection selection_manager.ClearSelection() @@ -260,15 +259,48 @@ # Modify material assignment # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Assign a specific material to all bodies in the model -allbodies = ExtAPI.DataModel.Project.Model.GetChildren(DataModelObjectCategory.Body, True) +allbodies = Model.GetChildren(DataModelObjectCategory.Body, True) for body in allbodies: body.Material = "Structural Steel" # %% # Get all Coordinate Systems -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# ~~~~~~~~~~~~~~~~~~~~~~~~~~ # Retrieve all coordinate systems in the model -tree_CS = ExtAPI.DataModel.Project.Model.CoordinateSystems +tree_CS = Model.CoordinateSystems + +# %% +# Add a cylindrical coordinate system +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Create a new coordinate system +csys = Model.CoordinateSystems.AddCoordinateSystem() +# place csys origin at arbitrary (0,25,50) location +csys.SetOriginLocation(Quantity(0,"in"), Quantity(25,"in"), Quantity(50,"in")) +# set primary X axis to arbitrary (1,2,3) direction +csys.PrimaryAxisDirection = Vector3D(1,2,3) + +# %% +# Add a cartesian coordinate system at a location (0,25,50) inches with primary X axis towards an arbitrary (1,2,3) direction +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Create a new coordinate system +csys = Model.CoordinateSystems.AddCoordinateSystem() +# place csys origin at arbitrary (0,25,50) location +csys.SetOriginLocation(Quantity(0,"in"), Quantity(25,"in"), Quantity(50,"in")) +# set primary X axis to arbitrary (1,2,3) direction +csys.PrimaryAxisDirection = Vector3D(1,2,3) + + + +# %% +# Find a coordinate system by name +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Create a new coordinate system +csys = app.Model.CoordinateSystems.AddCoordinateSystem() +# place csys origin at arbitrary (0,25,50) location +csys.SetOriginLocation(Quantity(0,"in"), Quantity(25,"in"), Quantity(50,"in")) +# set primary X axis to arbitrary (1,2,3) direction +csys.PrimaryAxisDirection = Vector3D(1,2,3) + # sphinx_gallery_start_ignore diff --git a/examples/00_setup/03_connections.py b/examples/00_setup/03_connections.py index 179c5e105..1b2cf3f9c 100644 --- a/examples/00_setup/03_connections.py +++ b/examples/00_setup/03_connections.py @@ -62,10 +62,14 @@ # Get information about all Contacts Defined # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Retrieve all contact regions defined in the model -all_contacts = ExtAPI.DataModel.Project.Model.Connections.GetChildren( +all_contacts = Model.Connections.GetChildren( DataModelObjectCategory.ContactRegion, True ) +# Print count of all contact regions +numContacts = all_contacts.Count +print("There are %s contact regions" % (numContacts) ) + # Print details of each contact region for contact in all_contacts: print( @@ -76,12 +80,13 @@ print("Target: ", contact.TargetBodies, list(contact.TargetLocation.Ids)) + # %% # Create Automatic Connections on a chosen named selection # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Create a new connection group for automatic connections -contactgroup = ExtAPI.DataModel.Project.Model.Connections.AddConnectionGroup() +contactgroup = Model.Connections.AddConnectionGroup() contactgroup.FaceFace = True contactgroup.FaceEdge = contactgroup.FaceEdge.No contactgroup.GroupBy = contactgroup.GroupBy.Faces @@ -89,7 +94,7 @@ contactgroup.InternalObject.DetectCylindricalFacesType = 1 # Retrieve a named selection for the connection group -NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[ +NSall = Model.NamedSelections.GetChildren[ Ansys.ACT.Automation.Mechanical.NamedSelection ](True) my_nsel = [i for i in NSall if i.Name == "bodies_5"][0] @@ -99,18 +104,17 @@ contactgroup.CreateAutomaticConnections() # Refresh the tree structure to reflect the changes -mytree = ExtAPI.DataModel.Tree -mytree.Refresh() +DataModel.Tree.Refresh() # %% # Create a Contact region using face named selections # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Add a new contact region to the model -c = ExtAPI.DataModel.Project.Model.Connections +c = DataModel.Project.Model.Connections c1 = c.AddContactRegion() # Retrieve named selections for the source and target locations -NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[ +NSall = Model.NamedSelections.GetChildren[ Ansys.ACT.Automation.Mechanical.NamedSelection ](True) a = [i for i in NSall if i.Name == "block1_washer_cont"][0] @@ -119,6 +123,17 @@ c1.SourceLocation = a +# %% +# Insert a fixed body to ground joint +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +connections = Model.Connections +fixed_joint = connections.AddJoint() +fixed_joint.ConnectionType=JointScopingType.BodyToGround +fixed_joint.Type = JointType.Fixed +fixed_joint.MobileLocation = app.DataModel.GetObjectsByName("block1_washer_cont")[0] + + + # %% # Insert a Joint using face IDs # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -134,8 +149,7 @@ app.save_as(test_mechdat_path, overwrite=True) # delete # Add a new joint to the model -model = ExtAPI.DataModel.Project.Model -j = model.Connections.AddJoint() +j = Model.Connections.AddJoint() # Define the reference and mobile locations for the joint using face IDs reference_scoping = ExtAPI.SelectionManager.CreateSelectionInfo(SelectionTypeEnum.GeometryEntities) @@ -146,11 +160,22 @@ mobile_scoping.Ids = [face2] j.MobileLocation = mobile_scoping +# %% +# Define a ground to body spring with 1 N/m stiffness scoped to preexisting named selection +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +connections = Model.Connections +spring = connections.AddSpring() +spring.ConnectionType=JointScopingType.BodyToGround +spring.LongitudinalStiffness = Quantity(1, "N m^-1") +spring.MobileScopingMethod = GeometryDefineByType.Component +spring.MobileScopeLocation = app.DataModel.GetObjectsByName("block1_washer_cont")[0] + + # %% # Define a Bearing # ~~~~~~~~~~~~~~~~ # Add a new bearing connection to the model -brg = ExtAPI.DataModel.Project.Model.Connections.AddBearing() +brg = Model.Connections.AddBearing() # Set the reference rotation plane for the bearing brg.ReferenceRotationPlane = RotationPlane.XY @@ -168,7 +193,7 @@ brg.DampingC21.Output.DiscreteValues = [Quantity("121 [N sec m^-1]")] # Retrieve named selections for the reference and mobile locations -NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[ +NSall = Model.NamedSelections.GetChildren[ Ansys.ACT.Automation.Mechanical.NamedSelection ](True) brg.ReferenceLocation = [i for i in NSall if i.Name == "shank_surface"][0] diff --git a/examples/00_setup/04_named_selections.py b/examples/00_setup/04_named_selections.py index 433d915aa..46f8084bb 100644 --- a/examples/00_setup/04_named_selections.py +++ b/examples/00_setup/04_named_selections.py @@ -63,13 +63,13 @@ # ~~~~~~~~~~~~~~~~~~~~~~~~~~ # Retrieve all named selections in the model -nsall = ExtAPI.DataModel.GetObjectsByType(DataModelObjectCategory.NamedSelections.NamedSelection) +nsall = DataModel.GetObjectsByType(DataModelObjectCategory.NamedSelections.NamedSelection) # %% # Delete a named selection # ~~~~~~~~~~~~~~~~~~~~~~~~ # Retrieve all named selections in the project -NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[ +NSall = Model.NamedSelections.GetChildren[ Ansys.ACT.Automation.Mechanical.NamedSelection ](True) @@ -78,7 +78,7 @@ a.Delete() # Alternative way to delete a named selection by name -b = ExtAPI.DataModel.GetObjectsByName("Bottom_Face")[0] +b = DataModel.GetObjectsByName("Bottom_Face")[0] b.Delete() # %% @@ -90,8 +90,7 @@ selection.Ids = [216, 221, 224] # Add the named selection to the model -model = ExtAPI.DataModel.Project.Model -ns2 = model.AddNamedSelection() +ns2 = Model.AddNamedSelection() ns2.Name = "faces" # Set the name of the named selection ns2.Location = selection selection_manager.ClearSelection() # Clear the selection after creation - delete @@ -100,10 +99,13 @@ # Create a Named Selection by Worksheet # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Create a named selection using worksheet criteria -NS1 = DataModel.Project.Model.AddNamedSelection() +NS1 = Model.AddNamedSelection() NS1.ScopingMethod = GeometryDefineByType.Worksheet GenerationCriteria = NS1.GenerationCriteria +# Let us create a named selection "faces_for_support" +# using worksheet for all faces at y=0 or z=0 m + # Add criteria to the worksheet for selecting entities Criterion1 = Ansys.ACT.Automation.Mechanical.NamedSelectionCriterion() Criterion1.Action = SelectionActionType.Add @@ -122,13 +124,32 @@ GenerationCriteria.Add(Criterion2) # Generate the named selection based on the criteria +NS1.Name="faces_for_support" NS1.Generate() + + +# %% +# Extract all the details of a named selection worksheet named "faces_for_support" +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +NSall=app.Model.NamedSelections.GetChildren[Ansys.ACT.Automation.Mechanical.NamedSelection](True) +my_nsel = [i for i in NSall if i.Name == "shaft"][0] +worksheet = my_nsel.GenerationCriteria +for i in range(0,len(list(worksheet))): + print(worksheet[i].Action) + print(worksheet[i].EntityType) + print(worksheet[i].Criterion) + print(worksheet[i].Operator) + print(worksheet[i].Value) + print(worksheet[i].CoordinateSystem.Name) + + + # %% # Find a Named Selection # ~~~~~~~~~~~~~~~~~~~~~~ # Retrieve all named selections in the project -NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[ +NSall = Model.NamedSelections.GetChildren[ Ansys.ACT.Automation.Mechanical.NamedSelection ](True) @@ -143,7 +164,7 @@ # Identify Named Selections based on Name and Type # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Retrieve all named selections in the project -NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[ +NSall = Model.NamedSelections.GetChildren[ Ansys.ACT.Automation.Mechanical.NamedSelection ](True) @@ -156,7 +177,7 @@ # Further filter the named selections based on entity type FaceNsels = [ - i for i in filtered if str(ExtAPI.DataModel.GeoData.GeoEntityById(i.Ids[0]).Type) == "GeoFace" + i for i in filtered if str(DataModel.GeoData.GeoEntityById(i.Ids[0]).Type) == "GeoFace" ] diff --git a/examples/00_setup/05_mesh.py b/examples/00_setup/05_mesh.py index f97a7e53a..c4b251d7d 100644 --- a/examples/00_setup/05_mesh.py +++ b/examples/00_setup/05_mesh.py @@ -57,6 +57,14 @@ # Print the Mechanical tree structure app.print_tree() +# %% +# Set Global Mesh Settings +# ~~~~~~~~~~~~~~~~~~~~~~~~ +mesh=Model.Mesh +mesh.ElementSize = Quantity('37 [mm]') +mesh.ElementOrder = ElementOrder.Linear + + # %% # Insert a Local Meshing Control for a Named Selection @@ -95,11 +103,10 @@ meshregion = meshdata.MeshRegionById(geoBody.Id) print(body.Name, meshregion.ElementCount) - -# sphinx_gallery_start_ignore -# Clear the generated mesh to start fresh for next operations +# %% +# Clear generated mesh +# ~~~~~~~~~~~~~~~~~~~~~~~~ Model.Mesh.ClearGeneratedData() -# sphinx_gallery_end_ignore # %% diff --git a/examples/00_setup/06_loads.py b/examples/00_setup/06_loads.py index 9425394a9..69498e590 100644 --- a/examples/00_setup/06_loads.py +++ b/examples/00_setup/06_loads.py @@ -153,6 +153,18 @@ force.DefineBy = LoadDefineBy.Components force.ZComponent.Output.DiscreteValues = [Quantity("0 [N]"), Quantity("-9 [N]")] +# %% +# Add a remote displacement with 6 degrees of freedom fixed +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +remote_disp = analysis.AddRemoteDisplacement() +remote_disp.XComponent.Output.DiscreteValues = [Quantity("0 [mm]")] +remote_disp.YComponent.Output.DiscreteValues = [Quantity("0 [mm]")] +remote_disp.ZComponent.Output.DiscreteValues = [Quantity("0 [mm]")] +remote_disp.RotationX.Output.DiscreteValues = [Quantity("0 [deg]")] +remote_disp.RotationY.Output.DiscreteValues = [Quantity("0 [deg]")] +remote_disp.RotationZ.Output.DiscreteValues = [Quantity("0 [deg]")] + + # %% # Apply Nodal Forces by Components # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -223,6 +235,37 @@ t.Inputs[0].DiscreteValues = [Quantity("0 [sec]"), Quantity("1 [sec]")] t.Output.DiscreteValues = [Quantity("22 [C]"), Quantity("2302 [C]")] +# %% +# Add a temperature load applied to a named selection +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +temp_bc = analysis2.AddTemperature() +temp_bc.Location = app.DataModel.GetObjectsByName("fixed")[0] +temp_bc.Magnitude.Output.DiscreteValues = [Quantity("22[C]"), Quantity("60[C]")] +temp_bc.Magnitude.Inputs[0].DiscreteValues = [Quantity("0 [sec]"), Quantity("1 [sec]"), Quantity("2 [sec]")] +temp_bc.Magnitude.Output.DiscreteValues = [Quantity("22[C]"), Quantity("50[C]"), Quantity("80[C]")] + + +# %% +# # %% +# Create a convection load +# ~~~~~~~~~~~~~~~~~~~~~~~~ +# analysis = app.Model.AddSteadyStateThermalAnalysis() +try: + named_sel = app.Model.NamedSelections.Children[0] +except: + print("Named Selection not found") + +convection = Model.Analyses[0].AddConvection() +if named_sel != None: + convection.Location = named_sel + +convection.AmbientTemperature.Inputs[0].DiscreteValues = [Quantity("0 [s]"), Quantity("1 [s]")] # Set the time values +convection.AmbientTemperature.Output.DiscreteValues = [Quantity('760 [C]'), Quantity('800 [C]')] # Set the Ambient Temperature values +convection.FilmCoefficient.Inputs[0].DiscreteValues = [Quantity("0 [s]"), Quantity("1 [s]")] # Set the time values +convection.FilmCoefficient.Output.DiscreteValues = [Quantity("100 [W m^-1 m^-1 K^-1]"), Quantity("150 [W m^-1 m^-1 K^-1]")] #Set the HTC values + + + # %% # Apply Tabular Pressure for 5 Load Steps # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -277,6 +320,111 @@ nodal_pressure.XYZFunctionCoordinateSystem = a nodal_pressure.Magnitude.Output.DiscreteValues = [Quantity("0 [Pa]"), Quantity("100[Pa]")] + +# %% +# Set Automatic Time Stepping setting for a specific Load Step +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +analysis_settings = Model.Analyses[0].AnalysisSettings +analysis_settings.CurrentStepNumber = 1 +print(analysis_settings.AutomaticTimeStepping ) + + +# %% +# Set Step end time +# ~~~~~~~~~~~~~~~~~ +analysis_settings.CurrentStepNumber = 5 +analysis_settings.StepEndTime = Quantity('0.1 [sec]') + +# %% +# Define Load steps with end times +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +analysis_settings.NumberOfSteps=3 + +analysis_settings.CurrentStepNumber = 1 +analysis_settings.StepEndTime = Quantity('1.0 [sec]') + +analysis_settings.CurrentStepNumber = 2 +analysis_settings.StepEndTime = Quantity('10.0 [sec]') + +analysis_settings.CurrentStepNumber = 3 +analysis_settings.StepEndTime = Quantity('100.0 [sec]') + + +# %% +# Define substep sizing using times +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +analysis_settings.CurrentStepNumber = 1 +analysis_settings.StepEndTime = Quantity('0.1 [sec]') +analysis_settings.AutomaticTimeStepping =analysis_settings.AutomaticTimeStepping.On +analysis_settings.DefineBy=analysis_settings.DefineBy.Time +analysis_settings.InitialTimeStep = Quantity("0.005 [s]") +analysis_settings.MaximumTimeStep = Quantity("0.5 [s]") +analysis_settings.MinimumTimeStep = Quantity("0.0005 [s]") + + +# %% +# Define substep sizing using steps +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +analysis_settings.CurrentStepNumber = 1 +analysis_settings.StepEndTime = Quantity('0.1 [sec]') +analysis_settings.AutomaticTimeStepping =analysis_settings.AutomaticTimeStepping.On +analysis_settings.DefineBy=analysis_settings.DefineBy.Substeps +analysis_settings.InitialSubsteps=15 +analysis_settings.MinimumSubsteps=5 +analysis_settings.MaximumSubsteps=50 + +# %% +# Set Iterative solver type for solution +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +analysis_settings.SolverType = SolverType.Iterative + +# other options from dir(SolverType) : +# analysis_settings.SolverType = SolverType.Direct +# analysis_settings.SolverType = SolverType.FullDamped +# analysis_settings.SolverType=SolverType.ProgramControlled +# analysis_settings.SolverType=SolverType.ReducedDamped +# analysis_settings.SolverType=SolverType.Subspace +# analysis_settings.SolverType=SolverType.Supernode +# analysis_settings.SolverType=SolverType.Unsymmetric + + +# %% +# Change the solver unit system +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +analysis_settings.SolverUnits = SolverUnitsControlType.Manual +analysis_settings.SolverUnitSystem = WBUnitSystemType.ConsistentMKS + +# %% +# Get path to the Solver files directory +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +solve_dir = analysis_settings.ScratchSolverFilesDirectory +print(solve_dir) + +# To get path to the scratch Solver files directory for an unsaved file +# solve_dir = analysis_settings.SolverFilesDirectory + + +# %% +# Solve an analysis +# ~~~~~~~~~~~~~~~~~ +Model.Analyses[0].Solution.Activate() +Model.Analyses[0].Solution.Solve(True) + + +# %% +# Set the step end time and time steps in Transient structural analysis +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# analysis = app.Model.AddTransientStructuralAnalysis() +analysis_settings=analysis.AnalysisSettings +analysis_settings.SetStepEndTime( 1, Quantity("0.4 [s]")) +analysis_settings.SetInitialTimeStep(1,Quantity("0.0001 [s]")) +analysis_settings.SetMinimumTimeStep(1,Quantity("0.0000001 [s]")) +analysis_settings.SetMaximumTimeStep(1,Quantity("0.01 [s]")) + + + + + # sphinx_gallery_start_ignore # Save the project as a mechdat file (currently commented out) diff --git a/examples/00_setup/08_tree_objects.py b/examples/00_setup/08_tree_objects.py index 9f190478d..b53ed2a48 100644 --- a/examples/00_setup/08_tree_objects.py +++ b/examples/00_setup/08_tree_objects.py @@ -64,15 +64,28 @@ # ~~~~~~~~~~~~~~~~~~ # Access a specific geometry entity by its ID. -body = ExtAPI.DataModel.GeoData.GeoEntityById(312) +body = DataModel.GeoData.GeoEntityById(312) + +# %% +# Print all visible properties of a tree +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +tree_object= DataModel.GetObjectsByName("Contact Region")[0] +for prop in tree_object.Properties: + print(f'{prop.Name}: {prop.InternalValue}') +# or +for tree_object in tree_object.VisibleProperties: + print(tree_object.Caption + " | " + tree_object.StringValue) + + + # %% # Accessing Mesh Data -# ~~~~~~~~~~~~~~~~~~~~~~ +# ~~~~~~~~~~~~~~~~~~~ # Access specific mesh data by name and ID. -node = ExtAPI.DataModel.MeshDataByName("Global").NodeById(555) -element = ExtAPI.DataModel.MeshDataByName("Global").ElementById(444) +node = DataModel.MeshDataByName("Global").NodeById(555) +element = DataModel.MeshDataByName("Global").ElementById(444) # %% # Accessing All Objects and Child Objects @@ -80,17 +93,17 @@ # Examples of accessing all objects, bodies, named selections, and contact regions. # Retrieve all objects in the tree -AllObj = ExtAPI.DataModel.Project.Model.GetChildren(DataModelObjectCategory.DataModelObject, True) +AllObj = Model.GetChildren(DataModelObjectCategory.DataModelObject, True) # Retrieve all bodies -all_bodies = ExtAPI.DataModel.Project.Model.GetChildren(DataModelObjectCategory.Body, True) +all_bodies = Model.GetChildren(DataModelObjectCategory.Body, True) # Retrieve all named selections -ns_all = ExtAPI.DataModel.GetObjectsByType(DataModelObjectCategory.NamedSelections.NamedSelection) +ns_all = DataModel.GetObjectsByType(DataModelObjectCategory.NamedSelections.NamedSelection) # Retrieve all contact regions -abc = ExtAPI.DataModel.GetObjectsByType(DataModelObjectCategory.ContactRegion) -all_contacts = ExtAPI.DataModel.Project.Model.Connections.GetChildren( +abc = DataModel.GetObjectsByType(DataModelObjectCategory.ContactRegion) +all_contacts = Model.Connections.GetChildren( DataModelObjectCategory.ContactRegion, True ) @@ -98,20 +111,20 @@ my_contact = [contact for contact in all_contacts if contact.Name == "Contact Region"][0] # Retrieve all result objects of a specific type (e.g., Normal Stress) -all_norm_stress = ExtAPI.DataModel.GetObjectsByType(DataModelObjectCategory.Result.NormalStress) +all_norm_stress = DataModel.GetObjectsByType(DataModelObjectCategory.Result.NormalStress) # Retrieve other objects such as remote points and analyses -all_remote_points = ExtAPI.DataModel.GetObjectsByType(DataModelObjectCategory.RemotePoint) -ana = ExtAPI.DataModel.Tree.GetObjectsByType(DataModelObjectCategory.Analysis) +all_remote_points = DataModel.GetObjectsByType(DataModelObjectCategory.RemotePoint) +ana = DataModel.Tree.GetObjectsByType(DataModelObjectCategory.Analysis) # Using the ACT Automation API to retrieve specific objects -all_contacts2 = ExtAPI.DataModel.Project.Model.Connections.GetChildren[ +all_contacts2 = Model.Connections.GetChildren[ Ansys.ACT.Automation.Mechanical.Connections.ContactRegion ](True) -all_remote_points2 = ExtAPI.DataModel.Project.Model.GetChildren[ +all_remote_points2 = Model.GetChildren[ Ansys.ACT.Automation.Mechanical.RemotePoint ](True) -all_folders = ExtAPI.DataModel.Project.Model.GetChildren[ +all_folders = Model.GetChildren[ Ansys.ACT.Automation.Mechanical.TreeGroupingFolder ](True) @@ -123,7 +136,7 @@ import collections # Retrieve all objects and their names -AllObj = ExtAPI.DataModel.Project.Model.GetChildren(DataModelObjectCategory.DataModelObject, True) +AllObj = Model.GetChildren(DataModelObjectCategory.DataModelObject, True) AllObjNames = [x.Name for x in AllObj] # Find duplicate names @@ -153,7 +166,7 @@ # Access and filter contact regions based on their properties. new_contact_list = [] -dataobjects = ExtAPI.DataModel.AnalysisList[0].DataObjects +dataobjects = DataModel.AnalysisList[0].DataObjects for group in dataobjects: print(group.Type) @@ -187,14 +200,14 @@ # Using GetObjectsByName # ~~~~~~~~~~~~~~~~~~~~~~~~~ # Access a specific object by its name. -bb = ExtAPI.DataModel.GetObjectsByName("Connector\Solid1")[0] +bb = DataModel.GetObjectsByName("Connector\Solid1")[0] # %% # Accessing a Named Selection # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Access specific named selections by their names. -NSall = ExtAPI.DataModel.Project.Model.NamedSelections.GetChildren[ +NSall = Model.NamedSelections.GetChildren[ Ansys.ACT.Automation.Mechanical.NamedSelection ](True) my_nsel = [i for i in NSall if i.Name.startswith("NSF")][0] @@ -202,19 +215,20 @@ # %% # Get All Unsuppressed Bodies and Point Masses -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Example of getting all unsuppressed bodies and point masses. # Retrieve all unsuppressed bodies -all_bodies = ExtAPI.DataModel.Project.Model.GetChildren(DataModelObjectCategory.Body, True) +all_bodies = Model.GetChildren(DataModelObjectCategory.Body, True) all_bodies = [i for i in all_bodies if not i.Suppressed] print(len(all_bodies)) # Retrieve all unsuppressed point masses -all_pm = ExtAPI.DataModel.Project.Model.GetChildren(DataModelObjectCategory.PointMass, True) +all_pm = Model.GetChildren(DataModelObjectCategory.PointMass, True) all_pm = [i for i in all_pm if not i.Suppressed] + # sphinx_gallery_start_ignore # Save the Mechanical database file from pathlib import Path From 8aacf8ab962a5255ace7487b5710c04c4ca8c86b Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 18 Sep 2025 16:30:41 +0000 Subject: [PATCH 29/32] chore: auto fixes from pre-commit hooks --- examples/00_setup/01_setup.py | 2 +- examples/00_setup/02_geometry.py | 22 +++----- examples/00_setup/03_connections.py | 24 +++----- examples/00_setup/04_named_selections.py | 20 ++----- examples/00_setup/05_mesh.py | 5 +- examples/00_setup/06_loads.py | 70 ++++++++++++++---------- examples/00_setup/08_tree_objects.py | 23 ++------ 7 files changed, 71 insertions(+), 95 deletions(-) diff --git a/examples/00_setup/01_setup.py b/examples/00_setup/01_setup.py index 11290cd30..d77ecda1e 100644 --- a/examples/00_setup/01_setup.py +++ b/examples/00_setup/01_setup.py @@ -77,7 +77,7 @@ app.ExtAPI.Application.ActiveUnitSystem = MechanicalUnitSystem.StandardNMM app.ExtAPI.Application.ActiveAngleUnit = AngleUnitType.Radian -app.ExtAPI.Application.ActiveAngularVelocityUnit=AngularVelocityUnitType.RadianPerSecond +app.ExtAPI.Application.ActiveAngularVelocityUnit = AngularVelocityUnitType.RadianPerSecond # %% # View messages in Mechanical using PyMechanical diff --git a/examples/00_setup/02_geometry.py b/examples/00_setup/02_geometry.py index 12aa36f7d..b0b13affe 100644 --- a/examples/00_setup/02_geometry.py +++ b/examples/00_setup/02_geometry.py @@ -128,9 +128,7 @@ # Get face IDs and centroids for each face face_ids = [face.Id for face in body2.Faces] -centroids_of_each_face = [ - DataModel.GeoData.GeoEntityById(face_id).Centroid for face_id in face_ids -] +centroids_of_each_face = [DataModel.GeoData.GeoEntityById(face_id).Centroid for face_id in face_ids] # Print face IDs and their centroids for face_id, centroid in zip(face_ids, centroids_of_each_face): @@ -220,9 +218,7 @@ # Find a Named Selection with a prefix # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Retrieve a named selection whose name starts with a specific prefix -NSall = Model.NamedSelections.GetChildren[ - Ansys.ACT.Automation.Mechanical.NamedSelection -](True) +NSall = Model.NamedSelections.GetChildren[Ansys.ACT.Automation.Mechanical.NamedSelection](True) my_nsel = [i for i in NSall if i.Name.startswith("b")][0] print(my_nsel.Name) @@ -275,9 +271,9 @@ # Create a new coordinate system csys = Model.CoordinateSystems.AddCoordinateSystem() # place csys origin at arbitrary (0,25,50) location -csys.SetOriginLocation(Quantity(0,"in"), Quantity(25,"in"), Quantity(50,"in")) +csys.SetOriginLocation(Quantity(0, "in"), Quantity(25, "in"), Quantity(50, "in")) # set primary X axis to arbitrary (1,2,3) direction -csys.PrimaryAxisDirection = Vector3D(1,2,3) +csys.PrimaryAxisDirection = Vector3D(1, 2, 3) # %% # Add a cartesian coordinate system at a location (0,25,50) inches with primary X axis towards an arbitrary (1,2,3) direction @@ -285,10 +281,9 @@ # Create a new coordinate system csys = Model.CoordinateSystems.AddCoordinateSystem() # place csys origin at arbitrary (0,25,50) location -csys.SetOriginLocation(Quantity(0,"in"), Quantity(25,"in"), Quantity(50,"in")) +csys.SetOriginLocation(Quantity(0, "in"), Quantity(25, "in"), Quantity(50, "in")) # set primary X axis to arbitrary (1,2,3) direction -csys.PrimaryAxisDirection = Vector3D(1,2,3) - +csys.PrimaryAxisDirection = Vector3D(1, 2, 3) # %% @@ -297,10 +292,9 @@ # Create a new coordinate system csys = app.Model.CoordinateSystems.AddCoordinateSystem() # place csys origin at arbitrary (0,25,50) location -csys.SetOriginLocation(Quantity(0,"in"), Quantity(25,"in"), Quantity(50,"in")) +csys.SetOriginLocation(Quantity(0, "in"), Quantity(25, "in"), Quantity(50, "in")) # set primary X axis to arbitrary (1,2,3) direction -csys.PrimaryAxisDirection = Vector3D(1,2,3) - +csys.PrimaryAxisDirection = Vector3D(1, 2, 3) # sphinx_gallery_start_ignore diff --git a/examples/00_setup/03_connections.py b/examples/00_setup/03_connections.py index 1b2cf3f9c..82addda6b 100644 --- a/examples/00_setup/03_connections.py +++ b/examples/00_setup/03_connections.py @@ -62,13 +62,11 @@ # Get information about all Contacts Defined # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Retrieve all contact regions defined in the model -all_contacts = Model.Connections.GetChildren( - DataModelObjectCategory.ContactRegion, True -) +all_contacts = Model.Connections.GetChildren(DataModelObjectCategory.ContactRegion, True) # Print count of all contact regions numContacts = all_contacts.Count -print("There are %s contact regions" % (numContacts) ) +print("There are %s contact regions" % (numContacts)) # Print details of each contact region for contact in all_contacts: @@ -80,7 +78,6 @@ print("Target: ", contact.TargetBodies, list(contact.TargetLocation.Ids)) - # %% # Create Automatic Connections on a chosen named selection # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -94,9 +91,7 @@ contactgroup.InternalObject.DetectCylindricalFacesType = 1 # Retrieve a named selection for the connection group -NSall = Model.NamedSelections.GetChildren[ - Ansys.ACT.Automation.Mechanical.NamedSelection -](True) +NSall = Model.NamedSelections.GetChildren[Ansys.ACT.Automation.Mechanical.NamedSelection](True) my_nsel = [i for i in NSall if i.Name == "bodies_5"][0] # Assign the named selection to the connection group and create automatic connections @@ -114,9 +109,7 @@ c1 = c.AddContactRegion() # Retrieve named selections for the source and target locations -NSall = Model.NamedSelections.GetChildren[ - Ansys.ACT.Automation.Mechanical.NamedSelection -](True) +NSall = Model.NamedSelections.GetChildren[Ansys.ACT.Automation.Mechanical.NamedSelection](True) a = [i for i in NSall if i.Name == "block1_washer_cont"][0] c1.TargetLocation = a a = [i for i in NSall if i.Name == "block1_washer_targ"][0] @@ -128,12 +121,11 @@ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ connections = Model.Connections fixed_joint = connections.AddJoint() -fixed_joint.ConnectionType=JointScopingType.BodyToGround +fixed_joint.ConnectionType = JointScopingType.BodyToGround fixed_joint.Type = JointType.Fixed fixed_joint.MobileLocation = app.DataModel.GetObjectsByName("block1_washer_cont")[0] - # %% # Insert a Joint using face IDs # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -165,7 +157,7 @@ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ connections = Model.Connections spring = connections.AddSpring() -spring.ConnectionType=JointScopingType.BodyToGround +spring.ConnectionType = JointScopingType.BodyToGround spring.LongitudinalStiffness = Quantity(1, "N m^-1") spring.MobileScopingMethod = GeometryDefineByType.Component spring.MobileScopeLocation = app.DataModel.GetObjectsByName("block1_washer_cont")[0] @@ -193,9 +185,7 @@ brg.DampingC21.Output.DiscreteValues = [Quantity("121 [N sec m^-1]")] # Retrieve named selections for the reference and mobile locations -NSall = Model.NamedSelections.GetChildren[ - Ansys.ACT.Automation.Mechanical.NamedSelection -](True) +NSall = Model.NamedSelections.GetChildren[Ansys.ACT.Automation.Mechanical.NamedSelection](True) brg.ReferenceLocation = [i for i in NSall if i.Name == "shank_surface"][0] brg.MobileLocation = [i for i in NSall if i.Name == "shank_surface"][0] diff --git a/examples/00_setup/04_named_selections.py b/examples/00_setup/04_named_selections.py index 46f8084bb..89b5699df 100644 --- a/examples/00_setup/04_named_selections.py +++ b/examples/00_setup/04_named_selections.py @@ -69,9 +69,7 @@ # Delete a named selection # ~~~~~~~~~~~~~~~~~~~~~~~~ # Retrieve all named selections in the project -NSall = Model.NamedSelections.GetChildren[ - Ansys.ACT.Automation.Mechanical.NamedSelection -](True) +NSall = Model.NamedSelections.GetChildren[Ansys.ACT.Automation.Mechanical.NamedSelection](True) # Delete a named selection by its name a = [i for i in NSall if i.Name == "Top_Face"][0] @@ -124,18 +122,17 @@ GenerationCriteria.Add(Criterion2) # Generate the named selection based on the criteria -NS1.Name="faces_for_support" +NS1.Name = "faces_for_support" NS1.Generate() - # %% # Extract all the details of a named selection worksheet named "faces_for_support" # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -NSall=app.Model.NamedSelections.GetChildren[Ansys.ACT.Automation.Mechanical.NamedSelection](True) +NSall = app.Model.NamedSelections.GetChildren[Ansys.ACT.Automation.Mechanical.NamedSelection](True) my_nsel = [i for i in NSall if i.Name == "shaft"][0] worksheet = my_nsel.GenerationCriteria -for i in range(0,len(list(worksheet))): +for i in range(0, len(list(worksheet))): print(worksheet[i].Action) print(worksheet[i].EntityType) print(worksheet[i].Criterion) @@ -144,14 +141,11 @@ print(worksheet[i].CoordinateSystem.Name) - # %% # Find a Named Selection # ~~~~~~~~~~~~~~~~~~~~~~ # Retrieve all named selections in the project -NSall = Model.NamedSelections.GetChildren[ - Ansys.ACT.Automation.Mechanical.NamedSelection -](True) +NSall = Model.NamedSelections.GetChildren[Ansys.ACT.Automation.Mechanical.NamedSelection](True) # Find a specific named selection by its name a = [i for i in NSall if i.Name == "Rubber_Bodies30"][0] @@ -164,9 +158,7 @@ # Identify Named Selections based on Name and Type # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Retrieve all named selections in the project -NSall = Model.NamedSelections.GetChildren[ - Ansys.ACT.Automation.Mechanical.NamedSelection -](True) +NSall = Model.NamedSelections.GetChildren[Ansys.ACT.Automation.Mechanical.NamedSelection](True) # Filter named selections based on keywords in their names keywords = ["Rubber_Bodies30", "Inner_Faces30", "Outer_Faces30"] diff --git a/examples/00_setup/05_mesh.py b/examples/00_setup/05_mesh.py index c4b251d7d..2215ebc85 100644 --- a/examples/00_setup/05_mesh.py +++ b/examples/00_setup/05_mesh.py @@ -60,12 +60,11 @@ # %% # Set Global Mesh Settings # ~~~~~~~~~~~~~~~~~~~~~~~~ -mesh=Model.Mesh -mesh.ElementSize = Quantity('37 [mm]') +mesh = Model.Mesh +mesh.ElementSize = Quantity("37 [mm]") mesh.ElementOrder = ElementOrder.Linear - # %% # Insert a Local Meshing Control for a Named Selection # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/examples/00_setup/06_loads.py b/examples/00_setup/06_loads.py index 69498e590..185b7e4f1 100644 --- a/examples/00_setup/06_loads.py +++ b/examples/00_setup/06_loads.py @@ -241,7 +241,11 @@ temp_bc = analysis2.AddTemperature() temp_bc.Location = app.DataModel.GetObjectsByName("fixed")[0] temp_bc.Magnitude.Output.DiscreteValues = [Quantity("22[C]"), Quantity("60[C]")] -temp_bc.Magnitude.Inputs[0].DiscreteValues = [Quantity("0 [sec]"), Quantity("1 [sec]"), Quantity("2 [sec]")] +temp_bc.Magnitude.Inputs[0].DiscreteValues = [ + Quantity("0 [sec]"), + Quantity("1 [sec]"), + Quantity("2 [sec]"), +] temp_bc.Magnitude.Output.DiscreteValues = [Quantity("22[C]"), Quantity("50[C]"), Quantity("80[C]")] @@ -259,11 +263,22 @@ if named_sel != None: convection.Location = named_sel -convection.AmbientTemperature.Inputs[0].DiscreteValues = [Quantity("0 [s]"), Quantity("1 [s]")] # Set the time values -convection.AmbientTemperature.Output.DiscreteValues = [Quantity('760 [C]'), Quantity('800 [C]')] # Set the Ambient Temperature values -convection.FilmCoefficient.Inputs[0].DiscreteValues = [Quantity("0 [s]"), Quantity("1 [s]")] # Set the time values -convection.FilmCoefficient.Output.DiscreteValues = [Quantity("100 [W m^-1 m^-1 K^-1]"), Quantity("150 [W m^-1 m^-1 K^-1]")] #Set the HTC values - +convection.AmbientTemperature.Inputs[0].DiscreteValues = [ + Quantity("0 [s]"), + Quantity("1 [s]"), +] # Set the time values +convection.AmbientTemperature.Output.DiscreteValues = [ + Quantity("760 [C]"), + Quantity("800 [C]"), +] # Set the Ambient Temperature values +convection.FilmCoefficient.Inputs[0].DiscreteValues = [ + Quantity("0 [s]"), + Quantity("1 [s]"), +] # Set the time values +convection.FilmCoefficient.Output.DiscreteValues = [ + Quantity("100 [W m^-1 m^-1 K^-1]"), + Quantity("150 [W m^-1 m^-1 K^-1]"), +] # Set the HTC values # %% @@ -326,37 +341,37 @@ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ analysis_settings = Model.Analyses[0].AnalysisSettings analysis_settings.CurrentStepNumber = 1 -print(analysis_settings.AutomaticTimeStepping ) +print(analysis_settings.AutomaticTimeStepping) # %% # Set Step end time # ~~~~~~~~~~~~~~~~~ analysis_settings.CurrentStepNumber = 5 -analysis_settings.StepEndTime = Quantity('0.1 [sec]') +analysis_settings.StepEndTime = Quantity("0.1 [sec]") # %% # Define Load steps with end times # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -analysis_settings.NumberOfSteps=3 +analysis_settings.NumberOfSteps = 3 analysis_settings.CurrentStepNumber = 1 -analysis_settings.StepEndTime = Quantity('1.0 [sec]') +analysis_settings.StepEndTime = Quantity("1.0 [sec]") analysis_settings.CurrentStepNumber = 2 -analysis_settings.StepEndTime = Quantity('10.0 [sec]') +analysis_settings.StepEndTime = Quantity("10.0 [sec]") analysis_settings.CurrentStepNumber = 3 -analysis_settings.StepEndTime = Quantity('100.0 [sec]') +analysis_settings.StepEndTime = Quantity("100.0 [sec]") # %% # Define substep sizing using times # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ analysis_settings.CurrentStepNumber = 1 -analysis_settings.StepEndTime = Quantity('0.1 [sec]') -analysis_settings.AutomaticTimeStepping =analysis_settings.AutomaticTimeStepping.On -analysis_settings.DefineBy=analysis_settings.DefineBy.Time +analysis_settings.StepEndTime = Quantity("0.1 [sec]") +analysis_settings.AutomaticTimeStepping = analysis_settings.AutomaticTimeStepping.On +analysis_settings.DefineBy = analysis_settings.DefineBy.Time analysis_settings.InitialTimeStep = Quantity("0.005 [s]") analysis_settings.MaximumTimeStep = Quantity("0.5 [s]") analysis_settings.MinimumTimeStep = Quantity("0.0005 [s]") @@ -366,12 +381,12 @@ # Define substep sizing using steps # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ analysis_settings.CurrentStepNumber = 1 -analysis_settings.StepEndTime = Quantity('0.1 [sec]') -analysis_settings.AutomaticTimeStepping =analysis_settings.AutomaticTimeStepping.On -analysis_settings.DefineBy=analysis_settings.DefineBy.Substeps -analysis_settings.InitialSubsteps=15 -analysis_settings.MinimumSubsteps=5 -analysis_settings.MaximumSubsteps=50 +analysis_settings.StepEndTime = Quantity("0.1 [sec]") +analysis_settings.AutomaticTimeStepping = analysis_settings.AutomaticTimeStepping.On +analysis_settings.DefineBy = analysis_settings.DefineBy.Substeps +analysis_settings.InitialSubsteps = 15 +analysis_settings.MinimumSubsteps = 5 +analysis_settings.MaximumSubsteps = 50 # %% # Set Iterative solver type for solution @@ -415,14 +430,11 @@ # Set the step end time and time steps in Transient structural analysis # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # analysis = app.Model.AddTransientStructuralAnalysis() -analysis_settings=analysis.AnalysisSettings -analysis_settings.SetStepEndTime( 1, Quantity("0.4 [s]")) -analysis_settings.SetInitialTimeStep(1,Quantity("0.0001 [s]")) -analysis_settings.SetMinimumTimeStep(1,Quantity("0.0000001 [s]")) -analysis_settings.SetMaximumTimeStep(1,Quantity("0.01 [s]")) - - - +analysis_settings = analysis.AnalysisSettings +analysis_settings.SetStepEndTime(1, Quantity("0.4 [s]")) +analysis_settings.SetInitialTimeStep(1, Quantity("0.0001 [s]")) +analysis_settings.SetMinimumTimeStep(1, Quantity("0.0000001 [s]")) +analysis_settings.SetMaximumTimeStep(1, Quantity("0.01 [s]")) # sphinx_gallery_start_ignore diff --git a/examples/00_setup/08_tree_objects.py b/examples/00_setup/08_tree_objects.py index b53ed2a48..fc064d282 100644 --- a/examples/00_setup/08_tree_objects.py +++ b/examples/00_setup/08_tree_objects.py @@ -69,16 +69,14 @@ # %% # Print all visible properties of a tree # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -tree_object= DataModel.GetObjectsByName("Contact Region")[0] +tree_object = DataModel.GetObjectsByName("Contact Region")[0] for prop in tree_object.Properties: - print(f'{prop.Name}: {prop.InternalValue}') + print(f"{prop.Name}: {prop.InternalValue}") # or for tree_object in tree_object.VisibleProperties: print(tree_object.Caption + " | " + tree_object.StringValue) - - # %% # Accessing Mesh Data # ~~~~~~~~~~~~~~~~~~~ @@ -103,9 +101,7 @@ # Retrieve all contact regions abc = DataModel.GetObjectsByType(DataModelObjectCategory.ContactRegion) -all_contacts = Model.Connections.GetChildren( - DataModelObjectCategory.ContactRegion, True -) +all_contacts = Model.Connections.GetChildren(DataModelObjectCategory.ContactRegion, True) # Access a specific contact region by name my_contact = [contact for contact in all_contacts if contact.Name == "Contact Region"][0] @@ -121,12 +117,8 @@ all_contacts2 = Model.Connections.GetChildren[ Ansys.ACT.Automation.Mechanical.Connections.ContactRegion ](True) -all_remote_points2 = Model.GetChildren[ - Ansys.ACT.Automation.Mechanical.RemotePoint -](True) -all_folders = Model.GetChildren[ - Ansys.ACT.Automation.Mechanical.TreeGroupingFolder -](True) +all_remote_points2 = Model.GetChildren[Ansys.ACT.Automation.Mechanical.RemotePoint](True) +all_folders = Model.GetChildren[Ansys.ACT.Automation.Mechanical.TreeGroupingFolder](True) # %% # Finding Duplicate Objects by Name @@ -207,9 +199,7 @@ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Access specific named selections by their names. -NSall = Model.NamedSelections.GetChildren[ - Ansys.ACT.Automation.Mechanical.NamedSelection -](True) +NSall = Model.NamedSelections.GetChildren[Ansys.ACT.Automation.Mechanical.NamedSelection](True) my_nsel = [i for i in NSall if i.Name.startswith("NSF")][0] my_nsel2 = [i for i in NSall if i.Name == "NSInsideFaces"][0] @@ -228,7 +218,6 @@ all_pm = [i for i in all_pm if not i.Suppressed] - # sphinx_gallery_start_ignore # Save the Mechanical database file from pathlib import Path From cf56b8cd4a6c09e100af22a73040f0ea9ba1ed06 Mon Sep 17 00:00:00 2001 From: dkunhamb Date: Mon, 6 Oct 2025 08:11:09 -0500 Subject: [PATCH 30/32] update files --- examples/00_setup/01_setup.py | 6 +++++- examples/00_setup/02_geometry.py | 2 +- examples/00_setup/03_connections.py | 4 +++- examples/00_setup/04_named_selections.py | 7 ++++++- examples/00_setup/05_mesh.py | 3 ++- examples/00_setup/06_loads.py | 2 +- examples/00_setup/07_results.py | 3 ++- examples/00_setup/08_tree_objects.py | 18 +++++++++++------- examples/00_setup/readme.txt | 4 +++- 9 files changed, 34 insertions(+), 15 deletions(-) diff --git a/examples/00_setup/01_setup.py b/examples/00_setup/01_setup.py index d77ecda1e..370babb8a 100644 --- a/examples/00_setup/01_setup.py +++ b/examples/00_setup/01_setup.py @@ -25,7 +25,11 @@ App --- -This section has helper scripts for Embedded App +This section has helper scripts to start an embedded instance of Mechanical Application and import/open a file . + +This is a prerequisite step for the other helper scripts in the following pages. + + """ # %% diff --git a/examples/00_setup/02_geometry.py b/examples/00_setup/02_geometry.py index b0b13affe..fbe895daa 100644 --- a/examples/00_setup/02_geometry.py +++ b/examples/00_setup/02_geometry.py @@ -25,7 +25,7 @@ Geometry -------- -This section contains utility scripts for working with Geometry, including importing, analyzing, and accessing geometric data, as well as utilizing it for downstream preprocessing operations in Mechanical simulations. Coordinate Systems too are covered here. +This section contains a few utility scripts for working with Geometry, including importing, analyzing, and accessing geometric data, as well as utilizing it for downstream preprocessing operations in Mechanical simulations. Coordinate Systems too are covered here. """ # %% diff --git a/examples/00_setup/03_connections.py b/examples/00_setup/03_connections.py index 82addda6b..eac87ddb1 100644 --- a/examples/00_setup/03_connections.py +++ b/examples/00_setup/03_connections.py @@ -25,7 +25,9 @@ Connections ----------- -This section has helper scripts for Connections. + +This section contains a few utility scripts for working with Connections. + """ # sphinx_gallery_start_ignore diff --git a/examples/00_setup/04_named_selections.py b/examples/00_setup/04_named_selections.py index 89b5699df..bebbdcc82 100644 --- a/examples/00_setup/04_named_selections.py +++ b/examples/00_setup/04_named_selections.py @@ -25,7 +25,7 @@ Named Selections ---------------- -This section has helper scripts for Named Selections. +This section contains a few utility scripts for creating , finding and using Named Selections. """ # sphinx_gallery_start_ignore @@ -129,8 +129,13 @@ # %% # Extract all the details of a named selection worksheet named "faces_for_support" # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +<<<<<<< HEAD +NSall=app.Model.NamedSelections.GetChildren[Ansys.ACT.Automation.Mechanical.NamedSelection](True) +my_nsel = [i for i in NSall if i.Name == "faces_for_support"][0] +======= NSall = app.Model.NamedSelections.GetChildren[Ansys.ACT.Automation.Mechanical.NamedSelection](True) my_nsel = [i for i in NSall if i.Name == "shaft"][0] +>>>>>>> 8aacf8ab962a5255ace7487b5710c04c4ca8c86b worksheet = my_nsel.GenerationCriteria for i in range(0, len(list(worksheet))): print(worksheet[i].Action) diff --git a/examples/00_setup/05_mesh.py b/examples/00_setup/05_mesh.py index 2215ebc85..492cf3c64 100644 --- a/examples/00_setup/05_mesh.py +++ b/examples/00_setup/05_mesh.py @@ -25,7 +25,8 @@ Mesh ---- -This section has helper scripts for Named Selections. +This section contains a few utility scripts for setting local and global Mesh Controls. + """ # sphinx_gallery_start_ignore diff --git a/examples/00_setup/06_loads.py b/examples/00_setup/06_loads.py index 185b7e4f1..4d2daae37 100644 --- a/examples/00_setup/06_loads.py +++ b/examples/00_setup/06_loads.py @@ -25,7 +25,7 @@ Loads and BCs ------------- -This script contains helper examples for applying loads and boundary conditions in Ansys Mechanical. +This script contains helper examples for applying loads and boundary conditions in Ansys Mechanical. Analysis Settings too are covered here. """ # sphinx_gallery_start_ignore diff --git a/examples/00_setup/07_results.py b/examples/00_setup/07_results.py index 02dbb13d7..8b04c4aa2 100644 --- a/examples/00_setup/07_results.py +++ b/examples/00_setup/07_results.py @@ -25,7 +25,8 @@ Results ------- -This section has helper scripts for Results. +This section contains a few utility scripts for result objects. + """ # sphinx_gallery_start_ignore diff --git a/examples/00_setup/08_tree_objects.py b/examples/00_setup/08_tree_objects.py index fc064d282..03d610a51 100644 --- a/examples/00_setup/08_tree_objects.py +++ b/examples/00_setup/08_tree_objects.py @@ -25,7 +25,8 @@ Tree Objects ------------ -This section has helper scripts for Tree Objects. +This section contains a few utility scripts for working with Tree Objects. + """ # sphinx_gallery_start_ignore @@ -66,6 +67,8 @@ body = DataModel.GeoData.GeoEntityById(312) +<<<<<<< HEAD +======= # %% # Print all visible properties of a tree # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -75,6 +78,7 @@ # or for tree_object in tree_object.VisibleProperties: print(tree_object.Caption + " | " + tree_object.StringValue) +>>>>>>> 8aacf8ab962a5255ace7487b5710c04c4ca8c86b # %% @@ -87,7 +91,7 @@ # %% # Accessing All Objects and Child Objects -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Examples of accessing all objects, bodies, named selections, and contact regions. # Retrieve all objects in the tree @@ -122,7 +126,7 @@ # %% # Finding Duplicate Objects by Name -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Identify duplicate objects in the project tree based on their names. import collections @@ -145,7 +149,7 @@ # %% # Using DataObjects and GetByName -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Access specific data objects by their names. c1 = "Solution" @@ -154,7 +158,7 @@ # %% # Using DataObjects, NamesByType, and GetByName -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Access and filter contact regions based on their properties. new_contact_list = [] @@ -190,13 +194,13 @@ # %% # Using GetObjectsByName -# ~~~~~~~~~~~~~~~~~~~~~~~~~ +# ~~~~~~~~~~~~~~~~~~~~~~ # Access a specific object by its name. bb = DataModel.GetObjectsByName("Connector\Solid1")[0] # %% # Accessing a Named Selection -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Access specific named selections by their names. NSall = Model.NamedSelections.GetChildren[Ansys.ACT.Automation.Mechanical.NamedSelection](True) diff --git a/examples/00_setup/readme.txt b/examples/00_setup/readme.txt index 5769a4c43..cc85d5066 100644 --- a/examples/00_setup/readme.txt +++ b/examples/00_setup/readme.txt @@ -1,4 +1,6 @@ Setup ----- -Set up Embedding and configure + +This directory contains a collection of helper scripts for Embedded Instance of PyMechanical.Each script focuses on a specific stage in the Ansys Mechanical workflow, providing utility and automation for common tasks. + From 0de3dc13fdc46f615d8e2533ab3098d11bc15fd0 Mon Sep 17 00:00:00 2001 From: dkunhamb Date: Mon, 6 Oct 2025 08:28:44 -0500 Subject: [PATCH 31/32] fix conflicts --- .pre-commit-config.yaml | 2 +- examples/00_setup/01_setup.py | 3 ++- examples/00_setup/02_geometry.py | 11 +++++++---- examples/00_setup/04_named_selections.py | 8 ++------ examples/00_setup/06_loads.py | 3 ++- examples/00_setup/08_tree_objects.py | 13 ------------- examples/00_setup/out/test.mechdat | Bin 4766920 -> 0 bytes 7 files changed, 14 insertions(+), 26 deletions(-) delete mode 100644 examples/00_setup/out/test.mechdat diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6302e4f27..f58936e6b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -21,7 +21,7 @@ repos: rev: 1.20.0 hooks: - id: blacken-docs - additional_dependencies: [black==24.10.0] + additional_dependencies: [black==25.9.0] - repo: https://github.com/pycqa/isort rev: 6.0.1 diff --git a/examples/00_setup/01_setup.py b/examples/00_setup/01_setup.py index 370babb8a..b967c6eb4 100644 --- a/examples/00_setup/01_setup.py +++ b/examples/00_setup/01_setup.py @@ -25,7 +25,8 @@ App --- -This section has helper scripts to start an embedded instance of Mechanical Application and import/open a file . +This section has helper scripts to start an embedded instance of Mechanical +Application and import/open a file. This is a prerequisite step for the other helper scripts in the following pages. diff --git a/examples/00_setup/02_geometry.py b/examples/00_setup/02_geometry.py index fbe895daa..fa78225d0 100644 --- a/examples/00_setup/02_geometry.py +++ b/examples/00_setup/02_geometry.py @@ -25,7 +25,10 @@ Geometry -------- -This section contains a few utility scripts for working with Geometry, including importing, analyzing, and accessing geometric data, as well as utilizing it for downstream preprocessing operations in Mechanical simulations. Coordinate Systems too are covered here. +This section contains a few utility scripts for working with Geometry, +including importing, analyzing, and accessing geometric data, as well +as utilizing it for downstream preprocessing operations in Mechanical +simulations. Coordinate Systems too are covered here. """ # %% @@ -276,9 +279,9 @@ csys.PrimaryAxisDirection = Vector3D(1, 2, 3) # %% -# Add a cartesian coordinate system at a location (0,25,50) inches with primary X axis towards an arbitrary (1,2,3) direction -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# Create a new coordinate system +# Add a cartesian coordinate system at a location (0,25,50) inches +# with primary X axis towards an arbitrary (1,2,3) direction +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ csys = Model.CoordinateSystems.AddCoordinateSystem() # place csys origin at arbitrary (0,25,50) location csys.SetOriginLocation(Quantity(0, "in"), Quantity(25, "in"), Quantity(50, "in")) diff --git a/examples/00_setup/04_named_selections.py b/examples/00_setup/04_named_selections.py index bebbdcc82..ce45ce48b 100644 --- a/examples/00_setup/04_named_selections.py +++ b/examples/00_setup/04_named_selections.py @@ -129,13 +129,9 @@ # %% # Extract all the details of a named selection worksheet named "faces_for_support" # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -<<<<<<< HEAD -NSall=app.Model.NamedSelections.GetChildren[Ansys.ACT.Automation.Mechanical.NamedSelection](True) -my_nsel = [i for i in NSall if i.Name == "faces_for_support"][0] -======= NSall = app.Model.NamedSelections.GetChildren[Ansys.ACT.Automation.Mechanical.NamedSelection](True) -my_nsel = [i for i in NSall if i.Name == "shaft"][0] ->>>>>>> 8aacf8ab962a5255ace7487b5710c04c4ca8c86b +my_nsel = [i for i in NSall if i.Name == "faces_for_support"][0] + worksheet = my_nsel.GenerationCriteria for i in range(0, len(list(worksheet))): print(worksheet[i].Action) diff --git a/examples/00_setup/06_loads.py b/examples/00_setup/06_loads.py index 4d2daae37..6fcd70b9d 100644 --- a/examples/00_setup/06_loads.py +++ b/examples/00_setup/06_loads.py @@ -25,7 +25,8 @@ Loads and BCs ------------- -This script contains helper examples for applying loads and boundary conditions in Ansys Mechanical. Analysis Settings too are covered here. +This script contains helper examples for applying loads and boundary +conditions in Ansys Mechanical. Analysis Settings too are covered here. """ # sphinx_gallery_start_ignore diff --git a/examples/00_setup/08_tree_objects.py b/examples/00_setup/08_tree_objects.py index 03d610a51..92e337182 100644 --- a/examples/00_setup/08_tree_objects.py +++ b/examples/00_setup/08_tree_objects.py @@ -67,19 +67,6 @@ body = DataModel.GeoData.GeoEntityById(312) -<<<<<<< HEAD -======= -# %% -# Print all visible properties of a tree -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -tree_object = DataModel.GetObjectsByName("Contact Region")[0] -for prop in tree_object.Properties: - print(f"{prop.Name}: {prop.InternalValue}") -# or -for tree_object in tree_object.VisibleProperties: - print(tree_object.Caption + " | " + tree_object.StringValue) ->>>>>>> 8aacf8ab962a5255ace7487b5710c04c4ca8c86b - # %% # Accessing Mesh Data diff --git a/examples/00_setup/out/test.mechdat b/examples/00_setup/out/test.mechdat deleted file mode 100644 index aa09906c89176a3fa73d19879fae04fae0b2e48b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4766920 zcmeF$30zOx{`mi0q0A{Nks=~Oljbs(L`9hrMJYl`iB!r^nIcm}nPpBAGNnYyR2&ge z86spZLqfk#ed?TZ&%NLK``_Q=@&7#@zjI&PqrKK%`@PnBujgKS%Q-8ohgh|2rrb=Z zJ!E8rMuKczwc%7#f8?CEu4`(zZn!_Wz9LayF0U^SNQx^GLhTAJ zS_*=c&@g^OS>H|2ZX~W5)i=aCsnykD>#uM5^r)-J)L&Ely#%Z+2ac>=QAYi~%BbIP z<9C?VE%bldXG%TA``JiKT>ejSMuu(c#u;xcF6%BtCka8iZvTo;wb$aEEFn>!K>faK z*soHe{at&fb~bT@ctJehA14#j@P_~E@X7UY*4xF;{a;53!lL>(rQQENZfAYm z@{}R}(@=Ho4OzWZ5G()N;QtRdYrl83d$D2PG?aqq3;eH+11MgRc> z5I_KdzkxuIXbrkTi0H>a=p*RV)wJub)C7n6YXi~mbULCRZPDFg?@D{hJuOcT2FNDCmK;au9oO-?U?<9+FEU0OB56GH_&4V2q1s}0tg_0 z00IagfB*srAbe?lxBbOXhQ%21Q0*~f&aG!CX4>M50pq7YwOd&QYrM#Z-c5LH~F+O_Z1E%dwM4sHkEtO z_0*WXZ96Bd4nLbS;i2=x8E;PBTVrihC9M`Jge~bM-ReSx)M@{xN*|>kFYtU3&{2A8 z^VdUCQu3nxjQ;V ze}8ps+ncED&vUnGR4?dmZZpqn!<}L4KRrW@zqmhiE!S#|)vo6@JdR3&`E7;EU zTDA3ONezc9ZyaRhQe<HT%1+9`24b~6UM90{3dMZ7qa}SvPEWP zzrv+my%p2@jLm6rWXYIL9Tn|=vzs^H@cnkl!iyu~JJ!6rnPzr9Zh>*1vhMO0zv30T z6gIKTEi~%$Vocu`CttVg>z8#gN74NKz}%%6X6485iE%|5L%b{Z#p0 z(>%ZBc@1_x?(MyGvdkp_VL|ILtREJ9PnbY<&Wth zWA1GlXr%h$ng6GaVG0S?8v9S(Uj1bJq%D)2bHbL~oBcWY^U|tk*>@s;KA(8+c38ml zHU3o(zLY3!boH?Bu&wYzpWIJjE%ST$oG{3}9Qwm-xmC9#v9b!uL&wN}(l%>mo8$iR zfajo3<)fw!8dBLqSEIDO(WJJqvOX)XX_P()RQdGrzWE@F?TK%XtI618?LX(bssG@C z{=E*3HXLqyqewXOqS9+@=JA6PH#;8k-l}|~x5<(44jNBG4@wp4w`uQtAhJgCey>iA zHQd62M;o-Mn$x41?PbI085(Yf1KVy{{_|a%PsuT6gDgT#zgO5FbRVxLF(rFru!_>Y zWkV;A*Sjd!V&*=ph!!(7)U-z|iFa)jS=BjMbgFnN>gF>}$+LNq_KoHd7Hg*bYGg7b za={r{>=8f!0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY** z5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0 z009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{ z1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009IL zKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~ z0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY** z5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0 z009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{ z1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009IL zKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~ z0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY** z5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0 z009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{ z1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009IL zKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~ z0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY** z5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0 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 zctv{kiho2qibfW{Pk)SGn^B)X^=Wul{yf8MQ6~S`OB&|8a(Y-KXKL zYgmK0PwhStufj{D^^Z@o-#@MUk3J1^)b`*&009ILKmY**5I_I{1Q0*~0R#|0009IL zKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~ z0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY** z5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0 z009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{ z1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009IL zKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~ z0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY** z5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0 z009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{ z1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009IL zKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~ z0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY** z5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0 z009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{ z1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009IL zKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~ z0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY** 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 zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0tCLh 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 z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t9LW%1cX15c4+>6EDvPV^)0I$m5PF4mwsMmMR630_m|yeZQ(tm*>u;s_UhYQl$Vy2B*JR(dE+q% zH@~y?)ROpc@oXk9-d7wo5+Fc;009DZOJKL~IL~aTTW4|_0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7{<9rA761SM02t(NJ%`YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r4E%ur DE6~0o From 990f8052b6ef170860fbf56c1ad050c4b2e6e9ad Mon Sep 17 00:00:00 2001 From: rs-bh-n Date: Tue, 7 Oct 2025 22:31:57 +0530 Subject: [PATCH 32/32] app removed in setup.py for extapi --- examples/00_setup/01_setup.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/00_setup/01_setup.py b/examples/00_setup/01_setup.py index b967c6eb4..47da7be1b 100644 --- a/examples/00_setup/01_setup.py +++ b/examples/00_setup/01_setup.py @@ -80,9 +80,9 @@ # Set Units # ~~~~~~~~~~~~~~~~~~~~~~~ -app.ExtAPI.Application.ActiveUnitSystem = MechanicalUnitSystem.StandardNMM -app.ExtAPI.Application.ActiveAngleUnit = AngleUnitType.Radian -app.ExtAPI.Application.ActiveAngularVelocityUnit = AngularVelocityUnitType.RadianPerSecond +ExtAPI.Application.ActiveUnitSystem = MechanicalUnitSystem.StandardNMM +ExtAPI.Application.ActiveAngleUnit = AngleUnitType.Radian +ExtAPI.Application.ActiveAngularVelocityUnit = AngularVelocityUnitType.RadianPerSecond # %% # View messages in Mechanical using PyMechanical