diff --git a/doc/source/images/generic_solid_block.png b/doc/source/images/generic_solid_block.png new file mode 100644 index 0000000000..478188a070 Binary files /dev/null and b/doc/source/images/generic_solid_block.png differ diff --git a/examples/gallery/00_lucid_file_IO.py b/examples/gallery/00_lucid_file_IO.py new file mode 100644 index 0000000000..78c5f2a545 --- /dev/null +++ b/examples/gallery/00_lucid_file_IO.py @@ -0,0 +1,166 @@ +""" +.. _ref_file_io: + +================================================================ +Exporting mesh in different file formats +================================================================ + +**Summary**: This example showcases the process of generating a mesh for block model +and exporting the mesh for different file formats. + +Objective +~~~~~~~~~~ + +The example demonstrates how to export mesh files for different mesh file formats +like *.cdb, *.cas , *.pmdat etc. + +.. image:: ../../../images/generic_solid_block.png + :align: center + :width: 800 + :alt: Generic F1 rear wing. + +Procedure +~~~~~~~~~~ +* Launch an Ansys Prime Server instance and instantiate the meshing utilities + from the ``lucid`` class. +* Import the CAD geometry file for the solid block. +* Generate surface mesh with a constant mesh size of 2mm. +* Generate volume mesh using tetrahedral elements and default settings . +* Export the mesh file as pmdat, cdb and cas format. +* Import the mesh file. +* Exit the PyPrimeMesh session. +""" + +############################################################################### +# Launch Ansys Prime Server +# ~~~~~~~~~~~~~~~~~~~~~~~~~ +# Import all necessary modules and +# launch an instance of Ansys Prime Server. +# Connect the PyPrimeMesh client and get the model. +# Instantiate meshing utilities from the ``lucid`` class. + +import os +import tempfile + +import ansys.meshing.prime as prime +from ansys.meshing.prime.graphics import Graphics + +prime_client = prime.launch_prime() +model = prime_client.model +mesh_util = prime.lucid.Mesh(model=model) +display = Graphics(model) + +############################################################################### +# Import geometry +# ~~~~~~~~~~~~~~~ +# Download the block CAD file named `pyprime_block_import.fmd` and +# Import the geometry into pyprimemesh. +# Display part details + +mesh_util.read(file_name=prime.examples.download_block_model_scdoc()) +print(model) + +############################################################################### +# Generate Mesh +# ~~~~~~~~~~~~~~~ +# Using Lucid api, generate a tri surface mesh that +# has a constant mesh size of 2mm . +# Display the surface mesh generated on the block and face-zonelet +# with named selection "my_group" . +# Generate volume mesh with default meshing algorithms. + +mesh_util.surface_mesh(min_size=2.0) + +display() + +display(scope=prime.ScopeDefinition(model, label_expression="my_group")) + +mesh_util.volume_mesh() + +############################################################################### +# Export mesh as PyPrimeMesh (*.pmdat) native format mesh file +# ~~~~~~~~~~~~~~~ +# PyPrimeMesh allows user to export mesh in its native format name pmdat. +# This configuration allows retaining the topology data along with mesh data. +# Similarly PyPrimeMesh allows export of mesh as *.cdb and *.cas. +# While exporting the mesh to Ansys MAPDL, the labels are converted to components containing nodes. +# Export of mesh to Ansys Fluent requires distinct non overlapping zones. For this the labels are +# converted to face zones. The topology data present is removed automatically when exporting to +# MAPDL and Fluent formats. + +# Export as PyPrimeMesh (*.pmdat) native format mesh file +temp_folder = tempfile.TemporaryDirectory() +mesh_file_pmdat = os.path.join(temp_folder.name, "pyprime_block_mesh.pmdat") +mesh_util.write(mesh_file_pmdat) +assert os.path.exists(mesh_file_pmdat) +print("\nExported file:\n", mesh_file_pmdat) + +############################################################################### +# Export mesh as Ansys MAPDL (*.cdb) format mesh file +# ~~~~~~~~~~~~~~~ +# PyPrimeMesh allows export of mesh as *.cdb and *.cas. +# While exporting the mesh to Ansys MAPDL, the labels are converted to components containing nodes. + +# mesh_file_cdb = os.path.join(temp_folder.name, "pyprime_block_mesh.cdb") +# mesh_util.write(mesh_file_cdb) +# assert os.path.exists(mesh_file_cdb) +# print("\nExported file:\n", mesh_file_cdb) + +############################################################################### +# Export mesh Fluent (*.cas) format mesh file +# ~~~~~~~~~~~~~~~ +# Export of mesh to Ansys Fluent requires distinct non overlapping zones. For this the labels are +# converted to face zones. The topology data present is removed automatically when exporting to +# MAPDL and Fluent formats. + +mesh_util.create_zones_from_labels("my_group") +print(model) + +# Export as Fluent (*.cas) format mesh file +mesh_file_cas = os.path.join(temp_folder.name, "pyprime_block_mesh.cas") +mesh_util.write(mesh_file_cas) +assert os.path.exists(mesh_file_cas) +print("\nExported file:\n", mesh_file_cas) + +############################################################################### +# Reading cdb and cas mesh files +# ~~~~~~~~~~~~~~~ +# Read the exported MADP mesh format file, it would be observed that +# the labels are exported as components of nodes. +# Display the imported geometry. +# Similarly after reading the Fluent format mesh file, its observed +# the zone name is retained and the remaining face zonelets that are not +# associated with a face zone(s) are merged to create a new zone named `wall` + +# mesh_util.read(mesh_file_cdb, append=False) +# print(model) + +mesh_util.read(mesh_file_cas, append=False) +print(model) + +############################################################################### +# Reading native mesh file geometry +# ~~~~~~~~~~~~~~~ +# Read the exported PyPrimeMesh(pmdat) native mesh format file, it would be observed that +# part contains both topology as well as mesh data. +# The topology data consist of facet data this is called as geom_zonelets, +# and the mesh generated exists as mesh zonelets. Here , while deleting the topology +# we are deleting the geom zonelets and retaining the mesh data. + +mesh_util.read(mesh_file_pmdat, append=False) + +print(model) +for part in model.parts: + if len(part.get_topo_faces()) > 0: + part.delete_topo_entities( + prime.DeleteTopoEntitiesParams( + model, delete_geom_zonelets=True, delete_mesh_zonelets=False + ) + ) +print(model) + +############################################################################### +# Exit PyPrimeMesh +# ~~~~~~~~~~~~~~~~ + +prime_client.exit() diff --git a/src/ansys/meshing/prime/examples/__init__.py b/src/ansys/meshing/prime/examples/__init__.py index 4d90b88b59..61a68eac09 100644 --- a/src/ansys/meshing/prime/examples/__init__.py +++ b/src/ansys/meshing/prime/examples/__init__.py @@ -1,5 +1,8 @@ from .download_utilities import DownloadManager from .examples import ( + download_block_model_fmd, + download_block_model_pmdat, + download_block_model_scdoc, download_bracket_dsco, download_bracket_fmd, download_bracket_scdoc, diff --git a/src/ansys/meshing/prime/examples/examples.py b/src/ansys/meshing/prime/examples/examples.py index f05b8bcef3..6661ba877c 100644 --- a/src/ansys/meshing/prime/examples/examples.py +++ b/src/ansys/meshing/prime/examples/examples.py @@ -36,6 +36,9 @@ "download_f1_rw_enclosure_stl", "download_f1_rw_end_plates_stl", "download_f1_rw_main_plane_stl", + "download_block_model_scdoc", + "download_block_model_fmd", + "download_block_model_pmdat", ] @@ -70,6 +73,9 @@ class Examples(Enum): F1_RW_END_PLATES_STL = {"filename": "f1_rw_enclosure.stl", "git_folder": "f1_rear_wing"} F1_RW_ENCLOSURE_STL = {"filename": "f1_rw_end_plates.stl", "git_folder": "f1_rear_wing"} F1_RW_MAIN_PLANE_STL = {"filename": "f1_rw_main_plane.stl", "git_folder": "f1_rear_wing"} + BLOCK_MODEL_SCDOC = {"filename": "pyprime_block_import.scdoc", "git_folder": "block_model"} + BLOCK_MODEL_FMD = {"filename": "pyprime_block_import.fmd", "git_folder": "block_model"} + BLOCK_MODEL_PMDAT = {"filename": "pyprime_block_import.pmdat", "git_folder": "block_model"} _DOWNLOADS = [] @@ -1010,7 +1016,7 @@ def download_f1_rw_drs_stl( >>> model = session.model >>> f1_rw_drs = prime_examples.download_f1_rw_drs_stl() >>> with prime.FileIO(model) as io: - >>> _ = io.read_pmdat(pcb, params=prime.FileReadParams(model)) + >>> _ = io.import_cad(f1_rw_drs, params=prime.ImportCADParams(model)) >>> print(model) """ @@ -1045,7 +1051,7 @@ def download_f1_rw_enclosure_stl( >>> model = session.model >>> f1_rw_enclosure = prime_examples.download_f1_rw_enclosure_stl() >>> with prime.FileIO(model) as io: - >>> _ = io.read_pmdat(pcb, params=prime.FileReadParams(model)) + >>> _ = io.import_cad(f1_rw_enclosure, params=prime.ImportCADParams(model)) >>> print(model) """ @@ -1080,7 +1086,7 @@ def download_f1_rw_end_plates_stl( >>> model = session.model >>> f1_rw_end_plates = prime_examples.download_f1_rw_end_plates_stl() >>> with prime.FileIO(model) as io: - >>> _ = io.read_pmdat(pcb, params=prime.FileReadParams(model)) + >>> _ = io.import_cad(f1_rw_end_plates, params=prime.ImportCADParams(model)) >>> print(model) """ @@ -1115,8 +1121,113 @@ def download_f1_rw_main_plane_stl( >>> model = session.model >>> f1_rw_main_plane = prime_examples.download_f1_rw_main_plane_stl() >>> with prime.FileIO(model) as io: - >>> _ = io.read_pmdat(pcb, params=prime.FileReadParams(model)) + >>> _ = io.import_cad(f1_rw_main_plane, params=prime.ImportCADParams(model)) >>> print(model) """ return get_file(Examples.F1_RW_MAIN_PLANE_STL, destination, force) + + +def download_block_model_scdoc( + destination: Optional[str] = None, force: bool = False +) -> Union[str, os.PathLike]: + """Download CAD file for the block model example. + + Parameters + ---------- + destination: Optional[str] + Destination for the file to be downloaded. + If nothing is provided, the default path in app data is used. + force: bool + Option to download the file. + If true, the file is always downloaded. + If false, an existing file in the cache may be reused. + + Returns + ------- + str + Local path to the downloaded file. + + Examples + -------- + >>> import ansys.meshing.prime as prime + >>> import ansys.meshing.prime.examples as prime_examples + >>> with prime.launch_prime() as session: + >>> model = session.model + >>> block_model = prime_examples.download_block_model_scdoc() + >>> with prime.FileIO(model) as io: + >>> _ = io.import_cad(block_model, params=prime.ImportCADParams(model)) + >>> print(model) + + """ + return get_file(Examples.BLOCK_MODEL_SCDOC, destination, force) + + +def download_block_model_fmd( + destination: Optional[str] = None, force: bool = False +) -> Union[str, os.PathLike]: + """Download CAD file for the block model example. + + Parameters + ---------- + destination: Optional[str] + Destination for the file to be downloaded. + If nothing is provided, the default path in app data is used. + force: bool + Option to download the file. + If true, the file is always downloaded. + If false, an existing file in the cache may be reused. + + Returns + ------- + str + Local path to the downloaded file. + + Examples + -------- + >>> import ansys.meshing.prime as prime + >>> import ansys.meshing.prime.examples as prime_examples + >>> with prime.launch_prime() as session: + >>> model = session.model + >>> block_model = prime_examples.download_block_model_fmd() + >>> with prime.FileIO(model) as io: + >>> _ = io.import_cad(block_model, params=prime.ImportCADParams(model)) + >>> print(model) + + """ + return get_file(Examples.BLOCK_MODEL_FMD, destination, force) + + +def download_block_model_pmdat( + destination: Optional[str] = None, force: bool = False +) -> Union[str, os.PathLike]: + """Download PMDAT file for the block model example. + + Parameters + ---------- + destination: Optional[str] + Destination for the file to be downloaded. + If nothing is provided, the default path in app data is used. + force: bool + Option to download the file. + If true, the file is always downloaded. + If false, an existing file in the cache may be reused. + + Returns + ------- + str + Local path to the downloaded file. + + Examples + -------- + >>> import ansys.meshing.prime as prime + >>> import ansys.meshing.prime.examples as prime_examples + >>> with prime.launch_prime() as session: + >>> model = session.model + >>> block_model = prime_examples.download_block_model_pmdat() + >>> with prime.FileIO(model) as io: + >>> _ = io.read_pmdat(block_model, params=prime.FileReadParams(model)) + >>> print(model) + + """ + return get_file(Examples.BLOCK_MODEL_PMDAT, destination, force)