Skip to content

Commit

Permalink
New testcase : F1 RW
Browse files Browse the repository at this point in the history
  • Loading branch information
agvarghe committed Jul 9, 2023
1 parent 16825ee commit 1a59742
Show file tree
Hide file tree
Showing 4 changed files with 463 additions and 0 deletions.
Binary file added doc/source/images/generic_rear_wing.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
315 changes: 315 additions & 0 deletions examples/gallery/lucid_generic_f1_rear_wing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,315 @@
"""
.. _ref_generic_f1_rw:
================================================================
Meshing a Generic F1 car rear wing for external aero simulation
================================================================
**Summary**: This example showcases the process of generating a mesh for a generic F1 rear wing
STL file model.
Objective
~~~~~~~~~~
The given example demonstrates the interconnection between various elements of the rear wing of
a generic F1 car, along with volume meshes, utilizing a poly-hexcore mesh containing prisms.To
simplify the process and enhance convenience, multiple meshing utilities provided in the
"lucid" class are employed.
.. image:: ../../../images/generic_rear_wing.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 STL geometry file for each component of the F1 rear wing.
* Merge all imported components into a single part.
* Use the connect operation to join the components together.
* Generate a surface mesh with curvature sizing to refine the mesh based on curvature.
* Extract Fluid Region by defining a material pount.
* Generate a volume mesh using poly-hexcore elements and apply boundary layer refinement.
* Print statistics on the generated mesh.
* Write a `.cas` file for use in the Fluent solver.
* Exit the PyPrimeMesh session.
"""

###############################################################################
# Launch Ansys Prime Server
# ~~~~~~~~~~~~~~~~~~~~~~~~~
# Import all necessary modules.
# 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 Generic F1 rear wing geometries (stl) files exported from SpaceClaim.
# Import each geometry from the example folder.
# Display the imported geometry.


f1_rw_drs = prime.examples.download_f1_rw_drs_stl()

f1_rw_enclosure = prime.examples.download_f1_rw_enclosure_stl()

f1_rw_end_plates = prime.examples.download_f1_rw_end_plates_stl()

f1_rw_main_plane = prime.examples.download_f1_rw_main_plane_stl()

for file_name in [f1_rw_drs, f1_rw_enclosure, f1_rw_end_plates, f1_rw_main_plane]:
mesh_util.read(file_name, append=True)

display = Graphics(model)
scope = prime.ScopeDefinition(model, part_expression="* !*enclosure*")

###############################################################################
# Merge Parts
# ~~~~~~~~~~~~~~~~~~~
# Establish the Global Size parameter to regulate mesh refinement.
# Merge all individual parts into a unified part named `f1_car_rear_wing`.

# Define Global sizes
model.set_global_sizing_params(prime.GlobalSizingParams(model, min=4, max=32, growth_rate=1.2))

# Create label per part
for part in model.parts:
part.add_labels_on_zonelets([part.name.split(".")[0]], part.get_face_zonelets())

# Merge Parts
merge_params = prime.MergePartsParams(model, merged_part_suggested_name="f1_car_rear_wing")
merge_result = model.merge_parts([part.id for part in model.parts], merge_params)
part = model.get_part_by_name(merge_result.merged_part_assigned_name)

###############################################################################
# Mesh Connect
# ~~~~~~~~~~~~~~~~~~~
# In order to generate a volume mesh for a closed domain, it is necessary to ensure
# that the components of the rear wing are properly connected.
# To achieve this, perform a connect operation using labels to join the components of
# the rear wing.
# Afterward, inspect the mesh to detect any edges that are not connected.

# Connect faces
mesh_util.connect_faces(part.name, face_labels="*", target_face_labels="*", tolerance=0.05)

# Diagnostics
surf_diag = prime.SurfaceSearch(model)
surf_report = surf_diag.get_surface_diagnostic_summary(
prime.SurfaceDiagnosticSummaryParams(
model,
compute_free_edges=True,
compute_self_intersections=True,
)
)
print(f"Total number of free edges present is {surf_report.n_free_edges}")

###############################################################################
# Define local size-control and Generate size-field
# ~~~~~~~~~~~~~~~~~~~
# In order to accurately represent the physics of the DRS wing, a limitation of 8 mm
# is imposed on the mesh size of the wing.
# This is accomplished by implementing curvature size control, which refines the
# mesh according to the curvature of the DRS surfaces.
# Additionally, to accurately capture the curved surfaces of other sections of the
# wing, curvature control is defined with a normal angle of 18 degrees.
# A volumetric size field is then computed based on the defined size control.

# Local Curvature size control on all components
curv_size_control_global = model.control_data.create_size_control(prime.SizingType.CURVATURE)
curv_size_params_global = prime.CurvatureSizingParams(model, normal_angle=18, min=8)
curv_size_control_global.set_curvature_sizing_params(curv_size_params_global)
curv_scope = prime.ScopeDefinition(
model,
entity_type=prime.ScopeEntity.FACEZONELETS,
part_expression="f1_car_rear_wing*",
)
curv_size_control_global.set_scope(curv_scope)
curv_size_control_global.set_suggested_name("curvature_global")

# local Curvature size control for DRS
curv_size_control = model.control_data.create_size_control(prime.SizingType.CURVATURE)
curv_size_params = prime.CurvatureSizingParams(model, normal_angle=18, max=4)
curv_size_control.set_curvature_sizing_params(curv_size_params)
curv_scope = prime.ScopeDefinition(
model,
entity_type=prime.ScopeEntity.FACEZONELETS,
part_expression="f1_car_rear_wing*",
label_expression="*drs*",
)
curv_size_control.set_scope(curv_scope)
curv_size_control.set_suggested_name("curvature_drs")

# Compute volumetric sizefield
compute_size = prime.SizeField(model)
vol_sf_params = prime.VolumetricSizeFieldComputeParams(model)
compute_size.compute_volumetric([curv_size_control.id], volumetric_sizefield_params=vol_sf_params)


###############################################################################
# Generate Surface Mesh
# ~~~~~~~~~~~~~~~~~~~
#
# Create a surface mesh for the rear wing using the defined size controls.
# To facilitate the definition of boundary conditions on the surfaces in the solver,
# generate face zones by utilizing the existing labels found in the rear wing model.

mesh_util.surface_mesh_with_size_controls(size_control_names="*curvature*")

# Create face-zones per label
for label in part.get_labels():
mesh_util.create_zones_from_labels(label_expression=label)

scope = prime.ScopeDefinition(model, part_expression="*", label_expression="* !*enclosure*")
display(
scope=scope,
)
###############################################################################
# Compute Volumetric Regions
# ~~~~~~~~~~~~~~~~~~~
# Compute the volume zones.

mesh_util.compute_volumes(part_expression=part.name, create_zones_per_volume=True)

###############################################################################
# Define Volume Controls
# ~~~~~~~~~~~~~~~~~~~
# In order to prevent the generation of a volume mesh within the solid wing,
# the type of a volume zone within the rear wing can be defined as "dead".
# To accomplish this, Volume Control is utilized to assign the type for the
# specific volume zone.
# Expressions are employed to define the volume zones that need to be filled, with
# "* !f1_rw_enclosure" indicating that it applies to all volume zones except
# for "f1_rw_enclosure".
volume_control_1 = model.control_data.create_volume_control()
volume_control_1.set_params(
prime.VolumeControlParams(
model,
cell_zonelet_type=prime.CellZoneletType.DEAD,
)
)
volume_control_1.set_scope(
prime.ScopeDefinition(
model, evaluation_type=prime.ScopeEvaluationType.ZONES, zone_expression="* !f1_rw_enclosure"
)
)


###############################################################################
# Define Prism Controls
# ~~~~~~~~~~~~~~~~~~~
# Prism control can be used to define inflation layers on the external aero surfaces.
# Specify the aero surfaces using labels, here prism scope is defined on zones associated
# with labels ``*drs*`` and ``*plane*``.
# The growth for the prism layer is control by defining offset type to
# be ``uniform`` with a first height of 0.5mm .

prism_control = model.control_data.create_prism_control()
prism_control.set_surface_scope(
prime.ScopeDefinition(
model,
evaluation_type=prime.ScopeEvaluationType.LABELS,
entity_type=prime.ScopeEntity.FACEZONELETS,
label_expression="*drs*, *plane*",
)
)
prism_control.set_volume_scope(
prime.ScopeDefinition(
model,
evaluation_type=prime.ScopeEvaluationType.ZONES,
entity_type=prime.ScopeEntity.VOLUME,
zone_expression="*f1_rw_enclosure*",
)
)
prism_control.set_growth_params(
prime.PrismControlGrowthParams(
model,
offset_type=prime.PrismControlOffsetType.UNIFORM,
n_layers=5,
first_height=0.5,
growth_rate=1.2,
)
)

###############################################################################
# Generate Volume Mesh
# ~~~~~~~~~~~~~~~~~~~
# Volume mesh with polyhedral elements and boundary layer refinement.

volume_mesh = prime.AutoMesh(model)
auto_mesh_param = prime.AutoMeshParams(
model,
prism_control_ids=[prism_control.id],
size_field_type=prime.SizeFieldType.VOLUMETRIC,
volume_fill_type=prime.VolumeFillType.HEXCOREPOLY,
volume_control_ids=[volume_control_1.id],
)
volume_mesh.mesh(part.id, auto_mesh_param)

###############################################################################
# Print mesh statistics
# ~~~~~~~~~~~~~~~~~~~~~

# Get meshed part
part = model.get_part_by_name("f1_car_rear_wing")

# Get statistics on the mesh
part_summary_res = part.get_summary(prime.PartSummaryParams(model=model))

# Get element quality on all parts in the model
search = prime.VolumeSearch(model=model)
params = prime.VolumeQualitySummaryParams(
model=model,
scope=prime.ScopeDefinition(model=model, part_expression="*"),
cell_quality_measures=[prime.CellQualityMeasure.INVERSEORTHOGONAL],
quality_limit=[0.9],
)
results = search.get_volume_quality_summary(params=params)

# Print statistics on meshed part
print(part_summary_res)
print(
"\nMaximum inverse-orthoginal quality of the Volume Mesh : ",
results.quality_results_part[0].max_quality,
)

# Mesh Check
result = prime.VolumeMeshTool(model).check_mesh(part.id, params=prime.CheckMeshParams(model))
print("\nMesh Check", result, sep="\n")

scope = prime.ScopeDefinition(model, part_expression="*", label_expression="* !*enclosure*")
display(
scope=scope,
)

###############################################################################
# Write mesh
# ~~~~~~~~~~
# Export as cas file for External Aero Simulations

with tempfile.TemporaryDirectory() as temp_folder:
print(temp_folder)
mesh_file = os.path.join(temp_folder, "f1_rear_wing_vol_mesh.cas")
mesh_util.write(mesh_file)
assert os.path.exists(mesh_file)
print("\nExported file:\n", mesh_file)


###############################################################################
# Exit PyPrimeMesh
# ~~~~~~~~~~~~~~~~

prime_client.exit()
4 changes: 4 additions & 0 deletions src/ansys/meshing/prime/examples/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
download_elbow_fmd,
download_elbow_pmdat,
download_elbow_scdoc,
download_f1_rw_drs_stl,
download_f1_rw_enclosure_stl,
download_f1_rw_end_plates_stl,
download_f1_rw_main_plane_stl,
download_pcb_pmdat,
download_pcb_scdoc,
download_pipe_tee_dsco,
Expand Down
Loading

0 comments on commit 1a59742

Please sign in to comment.