.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "examples/gallery_examples/gallery/04_lucid_toy_car.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code .. rst-class:: sphx-glr-example-title .. _sphx_glr_examples_gallery_examples_gallery_04_lucid_toy_car.py: .. _ref_toy_car_wrap: ================================== Wrap a toy car for a flow analysis ================================== **Summary**: This example demonstrates how to wrap a toy car for a flow analysis. Objective ~~~~~~~~~ This example wraps a toy car and volume meshes with a tetrahedral mesh with prisms. It uses several meshing utilities available in the ``lucid`` class for convenience and ease. .. image:: ../../../images/toy_car.png :align: center :width: 400 :alt: Toy car wrap. Procedure ~~~~~~~~~ #. Launch an Ansys Prime Server instance. #. Instantiate the meshing utilities from the ``lucid`` class. #. Import the geometry. #. Coarse wrap parts with holes to clean up. #. Extract the fluid region using a wrapper. #. Check that the wrap surface is closed and that the quality is suitable. #. Mesh only fluid with tetrahedral elements and boundary layer refinement. #. Create face zones from labels imported from the geometry. #. Print statistics on the generated mesh. #. Improve the mesh quality. #. Write a CAS file for use in the Fluent solver. #. Exit the PyPrimeMesh session. .. GENERATED FROM PYTHON SOURCE LINES 60-65 Launch Ansys Prime Server ~~~~~~~~~~~~~~~~~~~~~~~~~ Import all necessary modules and launch an instance of Ansys Prime Server. From the PyPrimeMesh client get the model. Instantiate meshing utilities from the ``lucid`` class. .. GENERATED FROM PYTHON SOURCE LINES 65-76 .. code-block:: Python import os import tempfile import ansys.meshing.prime as prime from ansys.meshing.prime.graphics import PrimePlotter prime_client = prime.launch_prime() model = prime_client.model mesh_util = prime.lucid.Mesh(model) .. GENERATED FROM PYTHON SOURCE LINES 77-81 Import geometry ~~~~~~~~~~~~~~~ Download the toy car geometry (FMD) file exported by SpaceClaim. Import the geometry and display everything except the tunnel. .. GENERATED FROM PYTHON SOURCE LINES 81-95 .. code-block:: Python # For Windows OS users, scdoc is also available: # toy_car = prime.examples.download_toy_car_scdoc() toy_car = prime.examples.download_toy_car_fmd() mesh_util.read(file_name=toy_car) scope = prime.ScopeDefinition(model, part_expression="* !*tunnel*") pl = PrimePlotter() pl.plot(model, scope) pl.show() .. tab-set:: .. tab-item:: Static Scene .. image-sg:: /examples/gallery_examples/gallery/images/sphx_glr_04_lucid_toy_car_001.png :alt: 04 lucid toy car :srcset: /examples/gallery_examples/gallery/images/sphx_glr_04_lucid_toy_car_001.png :class: sphx-glr-single-img .. tab-item:: Interactive Scene .. offlineviewer:: /home/runner/work/pyprimemesh/pyprimemesh/doc/source/examples/gallery_examples/gallery/images/sphx_glr_04_lucid_toy_car_001.vtksz .. GENERATED FROM PYTHON SOURCE LINES 96-104 Close holes ~~~~~~~~~~~ Several parts are open surfaces (with holes). Coarse wrap to close the holes and delete the originals. You could use leakage detection to close these regions. This example uses a coarse wrap and disables feature edge refinement to walk over the holes. As this is not the final wrap, this example does not remesh after the wrap. Wrapping each object in turn avoids coarse wrap bridging across narrow gaps. .. GENERATED FROM PYTHON SOURCE LINES 104-126 .. code-block:: Python coarse_wrap = {"cabin": 1.5, "exhaust": 0.6, "engine": 1.5} for part_name in coarse_wrap: # Each open part before wrap scope = prime.ScopeDefinition(model, part_expression=part_name) pl = PrimePlotter() pl.plot(model, scope) pl.show() closed_part = mesh_util.wrap( input_parts=part_name, max_size=coarse_wrap[part_name], remesh_postwrap=False, enable_feature_octree_refinement=False, ) # Closed part with no hole scope = prime.ScopeDefinition(model, part_expression=closed_part.name) pl = PrimePlotter() pl.plot(model, scope) pl.show() .. tab-set:: .. tab-item:: Static Scene .. image-sg:: /examples/gallery_examples/gallery/images/sphx_glr_04_lucid_toy_car_002.png :alt: 04 lucid toy car :srcset: /examples/gallery_examples/gallery/images/sphx_glr_04_lucid_toy_car_002.png :class: sphx-glr-single-img .. tab-item:: Interactive Scene .. offlineviewer:: /home/runner/work/pyprimemesh/pyprimemesh/doc/source/examples/gallery_examples/gallery/images/sphx_glr_04_lucid_toy_car_002.vtksz .. tab-set:: .. tab-item:: Static Scene .. image-sg:: /examples/gallery_examples/gallery/images/sphx_glr_04_lucid_toy_car_003.png :alt: 04 lucid toy car :srcset: /examples/gallery_examples/gallery/images/sphx_glr_04_lucid_toy_car_003.png :class: sphx-glr-single-img .. tab-item:: Interactive Scene .. offlineviewer:: /home/runner/work/pyprimemesh/pyprimemesh/doc/source/examples/gallery_examples/gallery/images/sphx_glr_04_lucid_toy_car_003.vtksz .. tab-set:: .. tab-item:: Static Scene .. image-sg:: /examples/gallery_examples/gallery/images/sphx_glr_04_lucid_toy_car_004.png :alt: 04 lucid toy car :srcset: /examples/gallery_examples/gallery/images/sphx_glr_04_lucid_toy_car_004.png :class: sphx-glr-single-img .. tab-item:: Interactive Scene .. offlineviewer:: /home/runner/work/pyprimemesh/pyprimemesh/doc/source/examples/gallery_examples/gallery/images/sphx_glr_04_lucid_toy_car_004.vtksz .. tab-set:: .. tab-item:: Static Scene .. image-sg:: /examples/gallery_examples/gallery/images/sphx_glr_04_lucid_toy_car_005.png :alt: 04 lucid toy car :srcset: /examples/gallery_examples/gallery/images/sphx_glr_04_lucid_toy_car_005.png :class: sphx-glr-single-img .. tab-item:: Interactive Scene .. offlineviewer:: /home/runner/work/pyprimemesh/pyprimemesh/doc/source/examples/gallery_examples/gallery/images/sphx_glr_04_lucid_toy_car_005.vtksz .. tab-set:: .. tab-item:: Static Scene .. image-sg:: /examples/gallery_examples/gallery/images/sphx_glr_04_lucid_toy_car_006.png :alt: 04 lucid toy car :srcset: /examples/gallery_examples/gallery/images/sphx_glr_04_lucid_toy_car_006.png :class: sphx-glr-single-img .. tab-item:: Interactive Scene .. offlineviewer:: /home/runner/work/pyprimemesh/pyprimemesh/doc/source/examples/gallery_examples/gallery/images/sphx_glr_04_lucid_toy_car_006.vtksz .. tab-set:: .. tab-item:: Static Scene .. image-sg:: /examples/gallery_examples/gallery/images/sphx_glr_04_lucid_toy_car_007.png :alt: 04 lucid toy car :srcset: /examples/gallery_examples/gallery/images/sphx_glr_04_lucid_toy_car_007.png :class: sphx-glr-single-img .. tab-item:: Interactive Scene .. offlineviewer:: /home/runner/work/pyprimemesh/pyprimemesh/doc/source/examples/gallery_examples/gallery/images/sphx_glr_04_lucid_toy_car_007.vtksz .. GENERATED FROM PYTHON SOURCE LINES 127-134 Extract fluid using a wrapper ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Wrap the full model and extract the largest internal region as the fluid. Create edges at intersecting regions to improve the quality. Refine mesh to avoid contact between different parts. The new wrap object replaces all original geometry unless ``keep_input`` is set to ``True``. Volumes are generated from the wrap for use later. .. GENERATED FROM PYTHON SOURCE LINES 134-145 .. code-block:: Python wrap_part = mesh_util.wrap( min_size=0.1, max_size=2.0, region_extract=prime.WrapRegion.LARGESTINTERNAL, create_intersection_loops=True, contact_prevention_size=0.1, ) print(model) .. rst-class:: sphx-glr-script-out .. code-block:: none Part Summary: Part Name: __wrap__.3 Part ID: 23 1 Edge Zonelets 93 Face Zonelets 0 Cell Zonelets 0 Edge Zones Edge Zone Name(s) : [] 5 Face Zones Face Zone Name(s) : [surface, surface.1, cabin, exhaust, engine] 6 Volume Zones Volume Zone Name(s) : [__wrap__.2, __wrap__.1, __wrap__, component25, component24, tunnel.1] 24 Label(s) Names: [___geom_features___, __extracted__features__, __intersect_loops__, __wrap__, __wrap__.1, __wrap__.2, cabin, component21, component22, component24, component25, engine, exhaust, ground, inlet, outer, outlet, overlap_floor, tunnel, unreferenced, wheel_1, wheel_2, wheel_3, wheel_4] Bounding box (-31.1366 -59.1336 1.49005) (29.3366 40.1337 52.0558) .. GENERATED FROM PYTHON SOURCE LINES 146-150 Check wrap ~~~~~~~~~~ Check that the wrap surface is closed and that the quality is suitable to use as surface mesh. .. GENERATED FROM PYTHON SOURCE LINES 150-180 .. code-block:: Python scope = prime.ScopeDefinition(model=model, part_expression=wrap_part.name) diag = prime.SurfaceSearch(model) diag_params = prime.SurfaceDiagnosticSummaryParams( model, scope=scope, compute_free_edges=True, compute_multi_edges=True, compute_self_intersections=True, ) diag_res = diag.get_surface_diagnostic_summary(diag_params) print('Number of free edges', diag_res.n_free_edges) print('Number of multi edges', diag_res.n_multi_edges) print('Number of self intersections', diag_res.n_self_intersections) face_quality_measures = [prime.FaceQualityMeasure.SKEWNESS, prime.FaceQualityMeasure.ASPECTRATIO] quality_params = prime.SurfaceQualitySummaryParams( model=model, scope=scope, face_quality_measures=face_quality_measures, quality_limit=[0.9, 20] ) quality = prime.SurfaceSearch(model) qual_summary_res = quality.get_surface_quality_summary(quality_params) for summary_res in qual_summary_res.quality_results: print("\nMax value of ", summary_res.measure_name, ": ", summary_res.max_quality) print("Faces above limit: ", summary_res.n_found) .. rst-class:: sphx-glr-script-out .. code-block:: none Number of free edges 0 Number of multi edges 0 Number of self intersections 0 Max value of Skewness : 0.892958 Faces above limit: 0 Max value of AspectRatio : 5.9153 Faces above limit: 0 .. GENERATED FROM PYTHON SOURCE LINES 181-190 Create zones ~~~~~~~~~~~~ Create face zones from labels imported from the geometry that can be used in the solver to define boundary conditions. If specifying individual labels to create zones, the order is important. The last label in the list wins. Providing no ``label_expression`` flattens all labels into zones. For example, if ``LabelA`` and ``LabelB`` are overlapping, three zones are created: ``LabelA``, ``LabelB``, and ``LabelA_LabelB``. .. GENERATED FROM PYTHON SOURCE LINES 190-195 .. code-block:: Python mesh_util.create_zones_from_labels() print(model) .. rst-class:: sphx-glr-script-out .. code-block:: none Part Summary: Part Name: __wrap__.3 Part ID: 23 1 Edge Zonelets 93 Face Zonelets 0 Cell Zonelets 0 Edge Zones Edge Zone Name(s) : [] 21 Face Zones Face Zone Name(s) : [surface, surface.1, cabin, exhaust, engine, __wrap__.2_engine_unreferenced, __wrap__.1_exhaust_unreferenced, __wrap___cabin_unreferenced, unreferenced_wheel_2, unreferenced_wheel_3, unreferenced_wheel_4, unreferenced_wheel_1, outer_unreferenced, component24_unreferenced, component25_unreferenced, tunnel_unreferenced, ground_overlap_floor_tunnel, inlet_tunnel, component21_unreferenced, component22_unreferenced, outlet_tunnel] 6 Volume Zones Volume Zone Name(s) : [__wrap__.2, __wrap__.1, __wrap__, component25, component24, tunnel.1] 24 Label(s) Names: [___geom_features___, __extracted__features__, __intersect_loops__, __wrap__, __wrap__.1, __wrap__.2, cabin, component21, component22, component24, component25, engine, exhaust, ground, inlet, outer, outlet, overlap_floor, tunnel, unreferenced, wheel_1, wheel_2, wheel_3, wheel_4] Bounding box (-31.1366 -59.1336 1.49005) (29.3366 40.1337 52.0558) .. GENERATED FROM PYTHON SOURCE LINES 196-203 Volume mesh ~~~~~~~~~~~ Mesh only fluid volume with tetrahedral elements and boundary layer refinement. This example does not mesh other volumetric regions. Volume zones exist already for volume meshing and passing to the solver. The largest face zonelet is used by default to define volume zone names at creation. After volume meshing, you can see that you have a cell zonelet in the part summary. .. GENERATED FROM PYTHON SOURCE LINES 203-228 .. code-block:: Python volume = prime.lucid.VolumeScope( part_expression=wrap_part.name, entity_expression="tunnel*", scope_evaluation_type=prime.ScopeEvaluationType.ZONES, ) # Use expressions to define which surfaces to grow inflation layers from mesh_util.volume_mesh( scope=volume, prism_layers=3, prism_surface_expression="*cabin*,*component*,*engine*,*exhaust*,*ground*,*outer*,*wheel*", prism_volume_expression="tunnel*", ) scope = prime.ScopeDefinition( model, label_expression="*cabin*,*component*,*engine*,*exhaust*,*ground*,*outer*,*wheel*,*outlet*", ) pl = PrimePlotter() pl.plot(model, scope) pl.show() print(model) .. tab-set:: .. tab-item:: Static Scene .. image-sg:: /examples/gallery_examples/gallery/images/sphx_glr_04_lucid_toy_car_008.png :alt: 04 lucid toy car :srcset: /examples/gallery_examples/gallery/images/sphx_glr_04_lucid_toy_car_008.png :class: sphx-glr-single-img .. tab-item:: Interactive Scene .. offlineviewer:: /home/runner/work/pyprimemesh/pyprimemesh/doc/source/examples/gallery_examples/gallery/images/sphx_glr_04_lucid_toy_car_008.vtksz .. rst-class:: sphx-glr-script-out .. code-block:: none Part Summary: Part Name: __wrap__.3 Part ID: 23 1 Edge Zonelets 93 Face Zonelets 1 Cell Zonelets 0 Edge Zones Edge Zone Name(s) : [] 21 Face Zones Face Zone Name(s) : [surface, surface.1, cabin, exhaust, engine, __wrap__.2_engine_unreferenced, __wrap__.1_exhaust_unreferenced, __wrap___cabin_unreferenced, unreferenced_wheel_2, unreferenced_wheel_3, unreferenced_wheel_4, unreferenced_wheel_1, outer_unreferenced, component24_unreferenced, component25_unreferenced, tunnel_unreferenced, ground_overlap_floor_tunnel, inlet_tunnel, component21_unreferenced, component22_unreferenced, outlet_tunnel] 6 Volume Zones Volume Zone Name(s) : [__wrap__.2, __wrap__.1, __wrap__, component25, component24, tunnel.1] 24 Label(s) Names: [___geom_features___, __extracted__features__, __intersect_loops__, __wrap__, __wrap__.1, __wrap__.2, cabin, component21, component22, component24, component25, engine, exhaust, ground, inlet, outer, outlet, overlap_floor, tunnel, unreferenced, wheel_1, wheel_2, wheel_3, wheel_4] Bounding box (-31.1366 -59.1336 1.49005) (29.3366 40.1337 52.0558) .. GENERATED FROM PYTHON SOURCE LINES 229-232 Print mesh stats ~~~~~~~~~~~~~~~~ Print statistics on the generated mesh. .. GENERATED FROM PYTHON SOURCE LINES 232-263 .. code-block:: Python vtool = prime.VolumeMeshTool(model=model) result = vtool.check_mesh(part_id=wrap_part.id, params=prime.CheckMeshParams(model=model)) print("Non positive volumes:", result.has_non_positive_volumes) print("Non positive areas:", result.has_non_positive_areas) print("Invalid shape:", result.has_invalid_shape) print("Left handed faces:", result.has_left_handed_faces) quality = prime.VolumeSearch(model) scope = prime.ScopeDefinition(model, part_expression=wrap_part.name) part_summary_res = wrap_part.get_summary( prime.PartSummaryParams(model=model, print_id=False, print_mesh=True) ) print("\nNo. of cells : ", part_summary_res.n_cells) qual_summary_res = quality.get_volume_quality_summary( prime.VolumeQualitySummaryParams( model=model, scope=scope, cell_quality_measures=[prime.CellQualityMeasure.SKEWNESS], quality_limit=[0.95], ) ) for summary_res in qual_summary_res.quality_results_part: print("\nMax value of ", summary_res.measure_name, ": ", summary_res.max_quality) print("Cells above limit: ", summary_res.n_found) .. rst-class:: sphx-glr-script-out .. code-block:: none Non positive volumes: False Non positive areas: False Invalid shape: False Left handed faces: False No. of cells : 3331834 Max value of Skewness : 0.999323 Cells above limit: 75 .. GENERATED FROM PYTHON SOURCE LINES 264-268 Improve quality ~~~~~~~~~~~~~~~ Because the mesh quality is poor, use the ``improve_by_auto_node_move`` method to improve the mesh. .. GENERATED FROM PYTHON SOURCE LINES 268-307 .. code-block:: Python improve = prime.VolumeMeshTool(model=model) params = prime.AutoNodeMoveParams( model=model, quality_measure=prime.CellQualityMeasure.SKEWNESS, target_quality=0.95, dihedral_angle=90, n_iterations_per_node=50, restrict_boundary_nodes_along_surface=True, n_attempts=10, ) improve.improve_by_auto_node_move( part_id=wrap_part.id, cell_zonelets=wrap_part.get_cell_zonelets(), boundary_zonelets=wrap_part.get_face_zonelets(), params=params, ) result = vtool.check_mesh(part_id=wrap_part.id, params=prime.CheckMeshParams(model=model)) print("Non positive volumes:", result.has_non_positive_volumes) print("Non positive areas:", result.has_non_positive_areas) print("Invalid shape:", result.has_invalid_shape) print("Left handed faces:", result.has_left_handed_faces) qual_summary_res = quality.get_volume_quality_summary( prime.VolumeQualitySummaryParams( model=model, scope=scope, cell_quality_measures=[prime.CellQualityMeasure.SKEWNESS], quality_limit=[0.95], ) ) for summary_res in qual_summary_res.quality_results_part: print("\nMax value of ", summary_res.measure_name, ": ", summary_res.max_quality) print("Cells above limit: ", summary_res.n_found) .. rst-class:: sphx-glr-script-out .. code-block:: none Non positive volumes: False Non positive areas: False Invalid shape: False Left handed faces: False Max value of Skewness : 0.949972 Cells above limit: 0 .. GENERATED FROM PYTHON SOURCE LINES 308-311 Write mesh ~~~~~~~~~~ Write a CAS file for use in the Fluent solver. .. GENERATED FROM PYTHON SOURCE LINES 311-317 .. code-block:: Python with tempfile.TemporaryDirectory() as temp_folder: mesh_file = os.path.join(temp_folder, "toy_car_lucid.cas") mesh_util.write(mesh_file) assert os.path.exists(mesh_file) print("\nExported file:\n", mesh_file) .. rst-class:: sphx-glr-script-out .. code-block:: none Exported file: /tmp/tmpyz3ekr50/toy_car_lucid.cas .. GENERATED FROM PYTHON SOURCE LINES 318-320 Exit PyPrimeMesh ~~~~~~~~~~~~~~~~ .. GENERATED FROM PYTHON SOURCE LINES 320-322 .. code-block:: Python prime_client.exit() .. rst-class:: sphx-glr-timing **Total running time of the script:** (2 minutes 51.872 seconds) .. _sphx_glr_download_examples_gallery_examples_gallery_04_lucid_toy_car.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: 04_lucid_toy_car.ipynb <04_lucid_toy_car.ipynb>` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: 04_lucid_toy_car.py <04_lucid_toy_car.py>` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_