generated from ansys/template
-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
370 additions
and
4 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,252 @@ | ||
""" | ||
.. _ref_file_io: | ||
================================================================ | ||
Exporting mesh in different file formats | ||
================================================================ | ||
**Summary**: This example demonstrates the procedure for creating a mesh for a block model | ||
and saving the resulting mesh in various file formats. | ||
Objective | ||
~~~~~~~~~~ | ||
The objective is to illustrate the process of exporting mesh files into a variety of | ||
mesh file formats, such as *.cdb, *.cas and *.pmdat. | ||
.. image:: ../../../images/generic_solid_block.png | ||
:align: center | ||
:width: 800 | ||
:alt: Generic Solid Block. | ||
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) | ||
|
||
############################################################################### | ||
# Import geometry | ||
# ~~~~~~~~~~~~~~~ | ||
# Download the CAD file named `pyprime_block_import.fmd` and | ||
# proceed to import its geometry into PyPrimeMesh. | ||
# Display part details by printing the model. **pyprime_block_import** | ||
# is the name of the part created. Topology exists in the form of the | ||
# following entities: Topo Edges, Topo Faces and Topo Volumes. | ||
# The topology data is preserved in the part when created from a cad file. | ||
# | ||
# Named Selections present in the CAD are imported as labels. In this case, the Named Selection | ||
# present in the CAD **my_group** is imported as a label. | ||
# The bodies present in the CAD are imported as Volume Zones, in this case the body **solid** is | ||
# imported as a volume zone. | ||
|
||
mesh_util.read(file_name=prime.examples.download_block_model_fmd()) | ||
print(model) | ||
|
||
############################################################################### | ||
# Generate Mesh | ||
# ~~~~~~~~~~~~~~~ | ||
# The topo faces consists of geom zonelets and mesh zonelets, | ||
# after CAD import geom zonelets are created, | ||
# theu consist of the tesselations present in the CAD. | ||
# Using Lucid api, User can generate a conformal mesh , this is called meshed zonelets. | ||
# Here a conformal mesh is created with a constant mesh size of 2mm . | ||
# One can display the mesh created for a set of topo faces | ||
# associated with named selection "my_group" by specifying the | ||
# label expression in display scope. | ||
# When topology | ||
# Finally, Generate volume mesh with default meshing algorithms. | ||
|
||
mesh_util.surface_mesh(min_size=2.0) | ||
display = Graphics(model) | ||
display() | ||
part = model.get_part_by_name("pyprime_block_import") | ||
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. | ||
# 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) | ||
# display() | ||
|
||
mesh_util.read(mesh_file_cas, append=False) | ||
print(model) | ||
display() | ||
############################################################################### | ||
# Reading native mesh file (pmdat) | ||
# ~~~~~~~~~~~~~~~ | ||
# Read the exported PyPrimeMesh(pmdat) native mesh format file, it would be observed that | ||
# part topology contains both geom zonelets as well as mesh zonelets. | ||
# 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 for solve purpose. | ||
|
||
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) | ||
############################################################################### | ||
# Part Summary and Mesh Statistics | ||
# ~~~~~~~~~~~~~~~ | ||
# Once the mesh is generated , PyPrimeMesh allows user to get an overall details of the surface | ||
# or volume mesh generated. Details regarding edgezonelets/facezonelets/cellzonelets can be | ||
# queried only after deleting the topology. | ||
# | ||
# PyPrimeMesh provides diagnostic tools for checking the surface mesh and volume mesh | ||
# generated. Here we would be diagnosing the quality of the surface mesh using the quality measures | ||
# Skewness and Aspect Ratio and checking the number of faces whose quality is above a target of 0.9 | ||
# and 20 , skewness and Aspect Ratio respectively. | ||
# | ||
# Similarly, the quality of the volume mesh generated for a part can be diagnosed. | ||
# Here we are the quality of the volume mesh generated using the quality measure | ||
# **Skewness** and reporting the number of cells with skewness > 0.85. | ||
# | ||
# The cells with quality greater than the target quality can be improved using ``AutoNodeMove`` | ||
# class. Here we are keeping a target quality (skewness) of 0.8 and defining the number | ||
# of attempts as 5 for improving the mesh quality using auto node move . | ||
|
||
part = model.get_part_by_name("pyprime_block_import") | ||
summary = part.get_summary(prime.PartSummaryParams(model)) | ||
print(summary.message) | ||
|
||
|
||
scope = prime.ScopeDefinition(model=model, part_expression=part.name) | ||
face_quality_measures = [prime.FaceQualityMeasure.SKEWNESS, prime.FaceQualityMeasure.ASPECTRATIO] | ||
face_quality_target = [0.9, 20] | ||
face_quality_params = prime.SurfaceQualitySummaryParams( | ||
model, | ||
face_quality_measures=face_quality_measures, | ||
quality_limit=face_quality_target, | ||
scope=scope, | ||
) | ||
|
||
face_diag = prime.SurfaceSearch(model) | ||
face_qual_summary = face_diag.get_surface_quality_summary(face_quality_params) | ||
for face_summary in face_qual_summary.quality_results: | ||
print("\nMax value of Face", face_summary.measure_name, ": ", face_summary.max_quality) | ||
print("Faces above limit: ", face_summary.n_found) | ||
|
||
cell_quality_measures = [prime.CellQualityMeasure.SKEWNESS] | ||
cell_quality_target = [0.8] | ||
cell_quality_params = prime.VolumeQualitySummaryParams( | ||
model, | ||
cell_quality_measures=cell_quality_measures, | ||
quality_limit=cell_quality_target, | ||
scope=scope, | ||
) | ||
|
||
volume_diag = prime.VolumeSearch(model) | ||
volume_qual_summary = volume_diag.get_volume_quality_summary(cell_quality_params) | ||
for vol_summary in volume_qual_summary.quality_results_part: | ||
print("\nMax value of Cell", vol_summary.measure_name, ": ", vol_summary.max_quality) | ||
print("Cells above limit: ", vol_summary.n_found) | ||
|
||
|
||
measure = prime.CellQualityMeasure.SKEWNESS | ||
target = 0.8 | ||
auto_mesh_params = prime.AutoNodeMoveParams( | ||
model, quality_measure=measure, target_quality=target, n_attempts=5 | ||
) | ||
vol_improve = prime.VolumeMeshTool(model) | ||
result = vol_improve.improve_by_auto_node_move( | ||
part.id, | ||
cell_zonelets=part.get_cell_zonelets(), | ||
boundary_zonelets=part.get_face_zonelets(), | ||
params=auto_mesh_params, | ||
) | ||
|
||
volume_qual_summary = volume_diag.get_volume_quality_summary(cell_quality_params) | ||
for vol_summary in volume_qual_summary.quality_results_part: | ||
print( | ||
"\nMax value of", | ||
vol_summary.measure_name, | ||
"after auto-node -move: ", | ||
vol_summary.max_quality, | ||
) | ||
print("Cells above limit: ", vol_summary.n_found) | ||
|
||
############################################################################### | ||
# Exit PyPrimeMesh | ||
# ~~~~~~~~~~~~~~~~ | ||
|
||
prime_client.exit() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.