diff --git a/doc/source/user_guide/tutorials/index.rst b/doc/source/user_guide/tutorials/index.rst index f982528585..0597e47be6 100644 --- a/doc/source/user_guide/tutorials/index.rst +++ b/doc/source/user_guide/tutorials/index.rst @@ -65,7 +65,7 @@ of our package background so you can understand how to work with it. Understand how to represent data in DPF: either from manual input either form result files. - .. grid-item-card:: Mesh analysis + .. grid-item-card:: Mesh exploration :link: ref_tutorials_mesh :link-type: ref :text-align: center diff --git a/doc/source/user_guide/tutorials/mesh/create_a_mesh_from_scratch.rst b/doc/source/user_guide/tutorials/mesh/create_a_mesh_from_scratch.rst new file mode 100644 index 0000000000..a592c0d038 --- /dev/null +++ b/doc/source/user_guide/tutorials/mesh/create_a_mesh_from_scratch.rst @@ -0,0 +1,158 @@ +.. _ref_tutorials_create_a_mesh_from_scratch: + +========================== +Create a mesh from scratch +========================== + +.. include:: ../../../links_and_refs.rst + +This tutorial demonstrates how to build a |MeshedRegion| from the scratch. + +The mesh object in DPF is a |MeshedRegion|. You can create your own |MeshedRegion| object and use it +with DPF operators. The ability to use scripting to create any DPF entity means +that you are not dependent on result files and can connect the DPF environment +with any Python tool. + +Here, we create a parallel piped mesh made of linear hexa elements. + +:jupyter-download-script:`Download tutorial as Python script` +:jupyter-download-notebook:`Download tutorial as Jupyter notebook` + +Import the necessary modules +---------------------------- + +Import the ``ansys.dpf.core`` module, including the operators module and the numpy library. + +.. jupyter-execute:: + + # Import the numpy library + import numpy as np + # Import the ``ansys.dpf.core`` module + from ansys.dpf import core as dpf + # Import the operators module + from ansys.dpf.core import operators as ops + +Define the mesh dimensions +-------------------------- + +.. jupyter-execute:: + + # Define the mesh dimensions + length = 0.1 + width = 0.05 + depth = 0.1 + num_nodes_in_length = 10 + num_nodes_in_width = 5 + num_nodes_in_depth = 10 + # Create a MeshedRegion object + my_meshed_region = dpf.MeshedRegion() + +Define the connectivity function +-------------------------------- + +To create a mesh you must define the nodes connectivity. This means to define +the nodes ids connected to each node. + +Here, we create a function that will find this connectivity. + +.. jupyter-execute:: + + def search_sequence_numpy(arr, seq): + """Find a sequence in an array and return its index.""" + indexes = np.where(np.isclose(arr, seq[0])) + for index in np.nditer(indexes[0]): + if index % 3 == 0: + if np.allclose(arr[index + 1], seq[1]) and np.allclose(arr[index + 2], seq[2]): + return index + return -1 + +Add nodes +--------- + +Add |Nodes| to the |MeshedRegion| object. + +.. jupyter-execute:: + + node_id = 1 + for i, x in enumerate( + [float(i) * length / float(num_nodes_in_length) for i in range(0, num_nodes_in_length)] + ): + for j, y in enumerate( + [float(i) * width / float(num_nodes_in_width) for i in range(0, num_nodes_in_width)] + ): + for k, z in enumerate( + [float(i) * depth / float(num_nodes_in_depth) for i in range(0, num_nodes_in_depth)] + ): + my_meshed_region.nodes.add_node(node_id, [x, y, z]) + node_id += 1 + +Get the nodes coordinates field. + +.. jupyter-execute:: + + my_nodes_coordinates = my_meshed_region.nodes.coordinates_field + +Set the mesh properties +----------------------- + +Set the mesh unit. + +.. jupyter-execute:: + + my_meshed_region.unit = "mm" + +Set the nodes coordinates. + +.. jupyter-execute:: + + # Get the nodes coordinates data + my_nodes_coordinates_data = my_nodes_coordinates.data + # As we use the connectivity function we need to get the data as a list + my_nodes_coordinates_data_list = my_nodes_coordinates.data_as_list + # Set the nodes scoping + my_coordinates_scoping = my_nodes_coordinates.scoping + +Add elements +------------ +Add |Elements| to the |MeshedRegion| object. + +.. jupyter-execute:: + + element_id = 1 + for i, x in enumerate( + [float(i) * length / float(num_nodes_in_length) for i in range(num_nodes_in_length - 1)] + ): + for j, y in enumerate( + [float(i) * width / float(num_nodes_in_width) for i in range(num_nodes_in_width - 1)] + ): + for k, z in enumerate( + [float(i) * depth / float(num_nodes_in_depth) for i in range(num_nodes_in_depth - 1)] + ): + coord1 = np.array([x, y, z]) + connectivity = [] + for xx in [x, x + length / float(num_nodes_in_length)]: + for yy in [y, y + width / float(num_nodes_in_width)]: + for zz in [z, z + depth / float(num_nodes_in_depth)]: + data_index = search_sequence_numpy(my_nodes_coordinates_data_list, [xx, yy, zz]) + scoping_index = int(data_index / 3) # 3components + connectivity.append(scoping_index) + # rearrange connectivity + tmp = connectivity[2] + connectivity[2] = connectivity[3] + connectivity[3] = tmp + tmp = connectivity[6] + connectivity[6] = connectivity[7] + connectivity[7] = tmp + my_meshed_region.elements.add_solid_element(element_id, connectivity) + element_id += 1 + +Plot the mesh +------------- + +You can check the mesh we just created with a plot. For more information on how to plot a mesh see +the :ref:`ref_tutorials_plotting_meshes` tutorial. + +.. jupyter-execute:: + + # Plot the mesh + my_meshed_region.plot() \ No newline at end of file diff --git a/doc/source/user_guide/tutorials/mesh/explore_mesh.rst b/doc/source/user_guide/tutorials/mesh/explore_mesh.rst new file mode 100644 index 0000000000..f23f748d5c --- /dev/null +++ b/doc/source/user_guide/tutorials/mesh/explore_mesh.rst @@ -0,0 +1,275 @@ +.. _ref_tutorials_explore_mesh: + +============== +Explore a mesh +============== + +:bdg-mapdl:`MAPDL` :bdg-lsdyna:`LSDYNA` :bdg-fluent:`Fluent` :bdg-cfx:`CFX` + +.. include:: ../../../links_and_refs.rst +.. |PropertyField| replace:: :class:`PropertyField ` +.. |element_types| replace:: :class:`list of available element types in a DPF mesh` + +This tutorial explains how to access a mesh data and metadata so it can be manipulated. + +:jupyter-download-script:`Download tutorial as Python script` +:jupyter-download-notebook:`Download tutorial as Jupyter notebook` + +Define the mesh +--------------- + +The mesh object in DPF is a |MeshedRegion|. You can obtain a |MeshedRegion| by creating your +own from scratch or by getting it from a result file. For more information check the +:ref:`ref_tutorials_create_a_mesh_from_scratch` and :ref:`ref_tutorials_get_mesh_from_result_file` tutorials. + +For this tutorial, we get a |MeshedRegion| from a result file. You can use one available in the |Examples| module. +For more information see the :ref:`ref_tutorials_get_mesh_from_result_file` tutorial. + +.. tab-set:: + + .. tab-item:: MAPDL + + .. jupyter-execute:: + + # Import the ``ansys.dpf.core`` module + from ansys.dpf import core as dpf + # Import the examples module + from ansys.dpf.core import examples + # Import the operators module + from ansys.dpf.core import operators as ops + + # Define the result file path + result_file_path_1 = examples.find_static_rst() + # Create the model + model_1 = dpf.Model(data_sources=result_file_path_1) + # Get the mesh + meshed_region_1 = model_1.metadata.meshed_region + + .. tab-item:: LSDYNA + + .. jupyter-execute:: + + # Import the ``ansys.dpf.core`` module + from ansys.dpf import core as dpf + # Import the examples module + from ansys.dpf.core import examples + # Import the operators module + from ansys.dpf.core import operators as ops + + # Define the result file path + result_file_path_2 = examples.download_d3plot_beam() + # Create the DataSources object + ds_2 = dpf.DataSources() + ds_2.set_result_file_path(filepath=result_file_path_2[0], key="d3plot") + ds_2.add_file_path(filepath=result_file_path_2[3], key="actunits") + # Create the model + model_2 = dpf.Model(data_sources=ds_2) + # Get the mesh + meshed_region_2 = model_2.metadata.meshed_region + + .. tab-item:: Fluent + + .. jupyter-execute:: + + # Import the ``ansys.dpf.core`` module + from ansys.dpf import core as dpf + # Import the examples module + from ansys.dpf.core import examples + # Import the operators module + from ansys.dpf.core import operators as ops + + # Define the result file path + result_file_path_3 = examples.download_fluent_axial_comp()["flprj"] + # Create the model + model_3 = dpf.Model(data_sources=result_file_path_3) + # Get the mesh + meshed_region_3 = model_3.metadata.meshed_region + + .. tab-item:: CFX + + .. jupyter-execute:: + + # Import the ``ansys.dpf.core`` module + from ansys.dpf import core as dpf + # Import the examples module + from ansys.dpf.core import examples + # Import the operators module + from ansys.dpf.core import operators as ops + + # Define the result file path + result_file_path_4 = examples.download_cfx_mixing_elbow() + # Create the model + model_4 = dpf.Model(data_sources=result_file_path_4) + # Get the mesh + meshed_region_4 = model_4.metadata.meshed_region + +Explore the mesh data +--------------------- + +You can access the mesh data by manipulating the |MeshedRegion| object methods. +The mesh data includes : + +- Unit; +- Nodes, elements and faces; +- Named selections. + +Check all the types of data you can get from a mesh at |MeshedRegion|. + +When instantiating nodes, elements, faces and named selections you get the correspondent DPF objects: +|Nodes|, |Elements|, |Faces| and |Scoping|. + +Here, we get the mesh nodes. + +.. tab-set:: + + .. tab-item:: MAPDL + + .. jupyter-execute:: + + # Get the mesh nodes + nodes_1 = meshed_region_1.nodes + + # Print the object type + print("Object type: ",type(nodes_1),'\n') + + # Print the nodes + print("Nodes: ", nodes_1) + + .. tab-item:: LSDYNA + + .. jupyter-execute:: + + # Get the mesh nodes + nodes_2 = meshed_region_2.nodes + + # Print the object type + print("Object type: ",type(nodes_2),'\n') + + # Print the nodes + print("Nodes: ", nodes_2) + + .. tab-item:: Fluent + + .. jupyter-execute:: + + # Get the mesh nodes + nodes_3 = meshed_region_3.nodes + + # Print the object type + print("Object type: ",type(nodes_3),'\n') + + # Print the nodes + print("Nodes: ", nodes_3) + + .. tab-item:: CFX + + .. jupyter-execute:: + + # Get the mesh nodes + nodes_4 = meshed_region_4.nodes + + # Print the object type + print("Object type: ",type(nodes_4),'\n') + + # Print the nodes + print("Nodes: ", nodes_4) + +Explore the mesh metadata +------------------------- + +You can access the mesh metadata by manipulating the |MeshedRegion| object properties. + +You can check which ones are available. + +.. tab-set:: + + .. tab-item:: MAPDL + + .. jupyter-execute:: + + # Get the available properties + available_props_1 = meshed_region_1.available_property_fields + + # Print the available properties + print("Available properties: ", available_props_1) + + .. tab-item:: LSDYNA + + .. jupyter-execute:: + + # Get the available properties + available_props_2 = meshed_region_2.available_property_fields + + # Print the available properties + print("Available properties: ", available_props_2) + + .. tab-item:: Fluent + + .. jupyter-execute:: + + # Get the available properties + available_props_3 = meshed_region_3.available_property_fields + + # Print the available properties + print("Available properties: ", available_props_3) + + .. tab-item:: CFX + + .. jupyter-execute:: + + # Get the available properties + available_props_4 = meshed_region_4.available_property_fields + + # Print the available properties + print("Available properties: ", available_props_4) + +You can also chose which property you want to extract. + +When extracting the properties you get a |PropertyField| with that information. Their data is mapped to +the entity they are defined at. + +The element type is given as a number. Check the |element_types| to find the +corresponding element name. + +.. tab-set:: + + .. tab-item:: MAPDL + + .. jupyter-execute:: + + # Get the element types on the mesh + el_types_1 = meshed_region_1.property_field(property_name="eltype") + + # Print the element types by element + print(el_types_1) + + + .. tab-item:: LSDYNA + + .. jupyter-execute:: + + # Get the element types on the mesh + el_types_2 = meshed_region_2.property_field(property_name="eltype") + + # Print the element types by element + print(el_types_2) + + .. tab-item:: Fluent + + .. jupyter-execute:: + + # Get the element types on the mesh + el_types_3 = meshed_region_3.property_field(property_name="eltype") + + # Print the element types by element + print(el_types_3) + + .. tab-item:: CFX + + .. jupyter-execute:: + + # Get the element types on the mesh + el_types_4 = meshed_region_4.property_field(property_name="eltype") + + # Print the element types by element + print(el_types_4) \ No newline at end of file diff --git a/doc/source/user_guide/tutorials/mesh/extract_mesh_in_split_parts.rst b/doc/source/user_guide/tutorials/mesh/extract_mesh_in_split_parts.rst new file mode 100644 index 0000000000..4f25fc36ec --- /dev/null +++ b/doc/source/user_guide/tutorials/mesh/extract_mesh_in_split_parts.rst @@ -0,0 +1,118 @@ +.. _ref_tutorials_extract_mesh_in_split_parts: + +============================= +Extract a mesh in split parts +============================= + +:bdg-fluent:`Fluent` :bdg-cfx:`CFX` + +.. include:: ../../../links_and_refs.rst +.. |MeshesContainer| replace:: :class:`MeshesContainer ` +.. |meshes_provider| replace:: :class:`mesh_provider ` + +This tutorial shows how to extract meshes split on a given space or time from a result file. + +To accomplish this goal, you must use the |meshes_provider| operator. + +:jupyter-download-script:`Download tutorial as Python script` +:jupyter-download-notebook:`Download tutorial as Jupyter notebook` + +Define the |DataSources| +------------------------ + +We must create a |DataSources| object so the |meshes_provider| operator can access the mesh. This object +manages paths to their files. + +For this tutorial, you can use a result file available in the |Examples| module. +For more information about how to import your own result file in DPF, see the :ref:`ref_tutorials_import_data` +tutorial section. + +.. tab-set:: + + .. tab-item:: Fluent + + .. jupyter-execute:: + + # Import the ``ansys.dpf.core`` module + from ansys.dpf import core as dpf + # Import the examples module + from ansys.dpf.core import examples + # Import the operators module + from ansys.dpf.core import operators as ops + + # Define the result file path + result_file_path_3 = examples.download_fluent_axial_comp()["flprj"] + # Create the DataSources object + ds_3 = dpf.DataSources(result_path=result_file_path_3) + + .. tab-item:: CFX + + .. jupyter-execute:: + + # Import the ``ansys.dpf.core`` module + from ansys.dpf import core as dpf + # Import the examples module + from ansys.dpf.core import examples + # Import the operators module + from ansys.dpf.core import operators as ops + + # Define the result file path + result_file_path_4 = examples.download_cfx_mixing_elbow() + # Create the DataSources object + ds_4 = dpf.DataSources(result_path=result_file_path_4) + +Extract the mesh in split parts +------------------------------- + +Instanciate and evaluate the |meshes_provider| operator. +The split meshes are given in a |MeshesContainer| and can be spatially or temporally varying. + +.. tab-set:: + + .. tab-item:: Fluent + + .. jupyter-execute:: + + # Instanciate the meshes_provider operator + meshes_31 = ops.mesh.meshes_provider(data_sources=ds_3).eval() + + # Print the meshes + print(meshes_31) + + .. tab-item:: CFX + + .. jupyter-execute:: + + # Instanciate the meshes_provider operator + meshes_41 = ops.mesh.meshes_provider(data_sources=ds_4).eval() + + # Print the meshes + print(meshes_41) + +Scope the mesh regions to be extracted in split parts +----------------------------------------------------- + +A region corresponds to a zone for Fluid and CFX results. You can specify the mesh regions you want to get by giving +the zones ids to the ``region_scoping`` argument. + +.. tab-set:: + + .. tab-item:: Fluent + + .. jupyter-execute:: + + # Instanciate the meshes_provider operator and specify a region + meshes_32 = ops.mesh.meshes_provider(data_sources=ds_3, region_scoping=[3,12]).eval() + + # Print the meshes + print(meshes_32) + + .. tab-item:: CFX + + .. jupyter-execute:: + + # Instanciate the meshes_provider operator specifying a region + meshes_42 = ops.mesh.meshes_provider(data_sources=ds_4, region_scoping=[5,8]).eval() + + # Print the meshes + print(meshes_42) diff --git a/doc/source/user_guide/tutorials/mesh/get_mesh_from_result_file.rst b/doc/source/user_guide/tutorials/mesh/get_mesh_from_result_file.rst new file mode 100644 index 0000000000..801f1e925a --- /dev/null +++ b/doc/source/user_guide/tutorials/mesh/get_mesh_from_result_file.rst @@ -0,0 +1,269 @@ +.. _ref_tutorials_get_mesh_from_result_file: + +============================= +Get a mesh from a result file +============================= + +:bdg-mapdl:`MAPDL` :bdg-lsdyna:`LSDYNA` :bdg-fluent:`Fluent` :bdg-cfx:`CFX` + +.. include:: ../../../links_and_refs.rst + +.. |mesh_provider| replace:: :class:`mesh_provider ` + +This tutorial explains how to extract a mesh from a result file. + +The mesh object in DPF is a |MeshedRegion|. You can obtain a |MeshedRegion| by creating your +own from scratch or by getting it from a result file. + +:jupyter-download-script:`Download tutorial as Python script` +:jupyter-download-notebook:`Download tutorial as Jupyter notebook` + +Import the result file +---------------------- + +First, import a result file. For this tutorial, you can use one available in the |Examples| module. +For more information about how to import your own result file in DPF, see the :ref:`ref_tutorials_import_data` +tutorials section. + +Here, we create a |DataSources| object so the data can be directly accessed by different +PyDPF-Core APIs. This object manages paths to their files. + +.. tab-set:: + + .. tab-item:: MAPDL + + .. jupyter-execute:: + + # Import the ``ansys.dpf.core`` module + from ansys.dpf import core as dpf + # Import the examples module + from ansys.dpf.core import examples + # Import the operators module + from ansys.dpf.core import operators as ops + + # Define the result file path + result_file_path_1 = examples.find_static_rst() + # Create the DataSources object + ds_1 = dpf.DataSources(result_path=result_file_path_1) + + .. tab-item:: LSDYNA + + .. jupyter-execute:: + + # Import the ``ansys.dpf.core`` module + from ansys.dpf import core as dpf + # Import the examples module + from ansys.dpf.core import examples + # Import the operators module + from ansys.dpf.core import operators as ops + + # Define the result file path + result_file_path_2 = examples.download_d3plot_beam() + # Create the DataSources object + ds_2 = dpf.DataSources() + ds_2.set_result_file_path(filepath=result_file_path_2[0], key="d3plot") + ds_2.add_file_path(filepath=result_file_path_2[3], key="actunits") + + .. tab-item:: Fluent + + .. jupyter-execute:: + + # Import the ``ansys.dpf.core`` module + from ansys.dpf import core as dpf + # Import the examples module + from ansys.dpf.core import examples + # Import the operators module + from ansys.dpf.core import operators as ops + + # Define the result file path + result_file_path_3 = examples.download_fluent_axial_comp()["flprj"] + # Create the DataSources object + ds_3 = dpf.DataSources(result_path=result_file_path_3) + + .. tab-item:: CFX + + .. jupyter-execute:: + + # Import the ``ansys.dpf.core`` module + from ansys.dpf import core as dpf + # Import the examples module + from ansys.dpf.core import examples + # Import the operators module + from ansys.dpf.core import operators as ops + # Define the result file path + result_file_path_4 = examples.download_cfx_mixing_elbow() + # Create the DataSources object + ds_4 = dpf.DataSources(result_path=result_file_path_4) + + +Get the mesh from the result file +--------------------------------- + +You can get the mesh from a result file by two methods: + +- :ref:`Using the DPF Model `; +- :ref:`Using the mesh_provider operator `. + +.. note:: + + A |Model| extracts a large amount of information by default (results, mesh and analysis data). + If using this helper takes a long time for processing the code, mind using a |DataSources| object + and instantiating operators directly with it. + +.. _get_mesh_model: + +Using the DPF |Model| +^^^^^^^^^^^^^^^^^^^^^ + +The |Model| is a helper designed to give shortcuts to access the analysis results +metadata and to instanciate results providers by opening a |DataSources| or a Streams. + +Get the |MeshedRegion| by instantiating a |Model| object and accessing its metadata. + +.. tab-set:: + + .. tab-item:: MAPDL + + .. jupyter-execute:: + + # Create the Model + model_1 = dpf.Model(data_sources=ds_1) + # Get the mesh + meshed_region_11 = model_1.metadata.meshed_region + + .. tab-item:: LSDYNA + + .. jupyter-execute:: + + # Create the Model + model_2 = dpf.Model(data_sources=ds_2) + # Get the mesh + meshed_region_21 = model_2.metadata.meshed_region + + .. tab-item:: Fluent + + .. jupyter-execute:: + + # Create the Model + model_3 = dpf.Model(data_sources=ds_3) + # Get the mesh + meshed_region_31 = model_3.metadata.meshed_region + + .. tab-item:: CFX + + .. jupyter-execute:: + + # Create the Model + model_4 = dpf.Model(data_sources=ds_4) + # Get the mesh + meshed_region_41 = model_4.metadata.meshed_region + +Printing the |MeshedRegion| displays the mesh dimensions: + +- Number of nodes and elements; +- Unit; +- Elements type. + +.. tab-set:: + + .. tab-item:: MAPDL + + .. jupyter-execute:: + + # Print the MeshedRegion + print(meshed_region_11) + + .. tab-item:: LSDYNA + + .. jupyter-execute:: + + # Print the MeshedRegion + print(meshed_region_21) + + .. tab-item:: Fluent + + .. jupyter-execute:: + + # Print the MeshedRegion + print(meshed_region_31) + + .. tab-item:: CFX + + .. jupyter-execute:: + + # Print the MeshedRegion + print(meshed_region_41) + +.. _get_mesh_mesh_provider: + +Using the |mesh_provider| operator +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Get the |MeshedRegion| by instantiating the |mesh_provider| operator with the +|DataSources| object as an argument. + +.. tab-set:: + + .. tab-item:: MAPDL + + .. jupyter-execute:: + + # Get the mesh with the mesh_provider operator + meshed_region_12 = ops.mesh.mesh_provider(data_sources=ds_1).eval() + + .. tab-item:: LSDYNA + + .. jupyter-execute:: + + # Get the mesh with the mesh_provider operator + meshed_region_22 = ops.mesh.mesh_provider(data_sources=ds_2).eval() + + .. tab-item:: Fluent + + .. jupyter-execute:: + + # Get the mesh with the mesh_provider operator + meshed_region_32 = ops.mesh.mesh_provider(data_sources=ds_3).eval() + + .. tab-item:: CFX + + .. jupyter-execute:: + + # Get the mesh with the mesh_provider operator + meshed_region_42 = ops.mesh.mesh_provider(data_sources=ds_4).eval() + +Printing the |MeshedRegion| displays the mesh dimensions: + +- Number of nodes and elements; +- Unit; +- Elements type. + +.. tab-set:: + + .. tab-item:: MAPDL + + .. jupyter-execute:: + + # Print the MeshedRegion + print(meshed_region_12) + + .. tab-item:: LSDYNA + + .. jupyter-execute:: + + # Print the MeshedRegion + print(meshed_region_22) + + .. tab-item:: Fluent + + .. jupyter-execute:: + + # Print the MeshedRegion + print(meshed_region_32) + + .. tab-item:: CFX + + .. jupyter-execute:: + + # Print the MeshedRegion + print(meshed_region_42) \ No newline at end of file diff --git a/doc/source/user_guide/tutorials/mesh/index.rst b/doc/source/user_guide/tutorials/mesh/index.rst index 8464839b40..bf0791ac94 100644 --- a/doc/source/user_guide/tutorials/mesh/index.rst +++ b/doc/source/user_guide/tutorials/mesh/index.rst @@ -15,47 +15,73 @@ These tutorials explains how to explore different attributes of a given mesh wit :margin: 2 .. grid-item-card:: Create a mesh from scratch - :link: ref_tutorials + :link: ref_tutorials_create_a_mesh_from_scratch :link-type: ref :text-align: center - This tutorial + This tutorial demonstrates how to build a mesh from the scratch. - .. grid-item-card:: Get the mesh from a result file - :link: ref_tutorials + .. grid-item-card:: Get a mesh from a result file + :link: ref_tutorials_get_mesh_from_result_file :link-type: ref :text-align: center - This tutorial + This tutorial explains how to extract a mesh from a result file. - .. grid-item-card:: Read the mesh metadata - :link: ref_tutorials + +++ + :bdg-mapdl:`MAPDL` :bdg-lsdyna:`LSDYNA` :bdg-fluent:`Fluent` :bdg-cfx:`CFX` + + .. grid-item-card:: Read a mesh metadata + :link: ref_tutorials_read_mesh_metadata :link-type: ref :text-align: center - This tutorial + This tutorial explains how to read a mesh metadata + (data about the elements, nodes, faces, region, zone ...) before + extracting the mesh from a result file. + + +++ + :bdg-lsdyna:`LSDYNA` :bdg-fluent:`Fluent` :bdg-cfx:`CFX` - .. grid-item-card:: Read the mesh - :link: ref_tutorials + + .. grid-item-card:: Explore a mesh + :link: ref_tutorials_explore_mesh :link-type: ref :text-align: center - This tutorial + This tutorial explains how to access a mesh data and metadata + so it can be manipulated. + + +++ + :bdg-mapdl:`MAPDL` :bdg-lsdyna:`LSDYNA` :bdg-fluent:`Fluent` :bdg-cfx:`CFX` - .. grid-item-card:: Read a subpart of the mesh - :link: ref_tutorials + .. grid-item-card:: Extract a mesh in split parts + :link: ref_tutorials_extract_mesh_in_split_parts :link-type: ref :text-align: center - This tutorial + This tutorial shows how to extract meshes split on a given space or time from a result file. - .. grid-item-card:: Split the mesh - :link: ref_tutorials + +++ + :bdg-fluent:`Fluent` :bdg-cfx:`CFX` + + .. grid-item-card:: Split a mesh + :link: ref_tutorials_split_mesh :link-type: ref :text-align: center - This tutorial + This tutorial shows how to split a mesh on a given property. + + +++ + :bdg-mapdl:`MAPDL` :bdg-lsdyna:`LSDYNA` :bdg-fluent:`Fluent` :bdg-cfx:`CFX` .. toctree:: :maxdepth: 2 :hidden: + + create_a_mesh_from_scratch.rst + get_mesh_from_result_file.rst + read_mesh_metadata.rst + explore_mesh.rst + extract_mesh_in_split_parts.rst + split_mesh.rst diff --git a/doc/source/user_guide/tutorials/mesh/read_mesh_metadata.rst b/doc/source/user_guide/tutorials/mesh/read_mesh_metadata.rst new file mode 100644 index 0000000000..46b6de0551 --- /dev/null +++ b/doc/source/user_guide/tutorials/mesh/read_mesh_metadata.rst @@ -0,0 +1,183 @@ +.. _ref_tutorials_read_mesh_metadata: + +==================== +Read a mesh metadata +==================== + +:bdg-lsdyna:`LSDYNA` :bdg-fluent:`Fluent` :bdg-cfx:`CFX` + +.. include:: ../../../links_and_refs.rst + +This tutorial explains how to read a mesh metadata (data about the elements, nodes, faces, region, zone ...) +before extracting the mesh from a result file. + +:jupyter-download-script:`Download tutorial as Python script` +:jupyter-download-notebook:`Download tutorial as Jupyter notebook` + +Get the result file +------------------- + +First, import a result file. For this tutorial, you can use one available in the |Examples| module. +For more information about how to import your own result file in DPF, see the :ref:`ref_tutorials_import_data` +tutorial section. + +.. tab-set:: + + .. tab-item:: LSDYNA + + .. jupyter-execute:: + + # Import the ``ansys.dpf.core`` module + from ansys.dpf import core as dpf + # Import the examples module + from ansys.dpf.core import examples + + # Define the result file path + result_file_path_2 = examples.download_d3plot_beam() + + .. tab-item:: Fluent + + .. jupyter-execute:: + + # Import the ``ansys.dpf.core`` module + from ansys.dpf import core as dpf + # Import the examples module + from ansys.dpf.core import examples + + # Define the result file path + result_file_path_3 = examples.download_fluent_axial_comp()["flprj"] + + .. tab-item:: CFX + + .. jupyter-execute:: + + # Import the ``ansys.dpf.core`` module + from ansys.dpf import core as dpf + # Import the examples module + from ansys.dpf.core import examples + + # Define the result file path + result_file_path_4 = examples.download_cfx_mixing_elbow() + +Create the |Model| +------------------ + +Create a |Model| object with the result file. The |Model| is a helper designed to give shortcuts to +access the analysis results metadata and to instanciate results providers by opening a |DataSources| or a Streams. + +.. tab-set:: + + .. tab-item:: LSDYNA + + .. jupyter-execute:: + + # Create the DataSources object + ds_2 = dpf.DataSources() + ds_2.set_result_file_path(filepath=result_file_path_2[0], key="d3plot") + ds_2.add_file_path(filepath=result_file_path_2[3], key="actunits") + # Create the Model + model_2 = dpf.Model(data_sources=ds_2) + + .. tab-item:: Fluent + + .. jupyter-execute:: + + # Create the Model + model_3 = dpf.Model(data_sources=result_file_path_3) + + .. tab-item:: CFX + + .. jupyter-execute:: + + # Create the Model + model_4 = dpf.Model(data_sources=result_file_path_4) + +Read the mesh metadata +---------------------- + +You can access the mesh metadata with the |MeshInfo| object. It reads the metadata information before extracting +the MeshedRegion from the result file. + +The mesh metadata information includes : + +- Properties; +- Parts; +- Faces; +- Bodies; +- Zones; +- Number of nodes and elements; +- Elements types. + +Get the the mesh metadata information and print the available ones. + +.. tab-set:: + + .. tab-item:: LSDYNA + + .. jupyter-execute:: + + # Get the mesh metadata information + mesh_info_2 = model_2.metadata.mesh_info + + # Print the mesh metadata information + print(mesh_info_2) + + .. tab-item:: Fluent + + .. jupyter-execute:: + + # Get the mesh metadata information + mesh_info_3 = model_3.metadata.mesh_info + + # Print the mesh metadata information + print(mesh_info_3) + + .. tab-item:: CFX + + .. jupyter-execute:: + + # Get the mesh metadata information + mesh_info_4 = model_4.metadata.mesh_info + + # Print the mesh metadata information + print(mesh_info_4) + +You can extract each of those mesh information by manipulating the |MeshInfo| object properties. + +For example, we can check the part names (for the LSDYNA result file) or the cell zone names +(for the Fluent or CFX result files): + +.. tab-set:: + + .. tab-item:: LSDYNA + + .. jupyter-execute:: + + # Get the part names + cell_zones_2 = mesh_info_2.get_property("part_names") + + # Print the part names + print(cell_zones_2) + + .. tab-item:: Fluent + + .. jupyter-execute:: + + # Get the cell zone names + cell_zones_3 = mesh_info_3.get_property("cell_zone_names") + + # Print the cell zone names + print(cell_zones_3) + + .. tab-item:: CFX + + .. jupyter-execute:: + + # Get the cell zone names + cell_zones_4 = mesh_info_4.get_property("cell_zone_names") + + # Print the cell zone names + print(cell_zones_4) + +For more information on reading a mesh from a LSDYNA, Fluent or CFX file check the :ref:`examples_lsdyna`, +:ref:`fluids_examples` and :ref:`examples_cfx` examples sections. \ No newline at end of file diff --git a/doc/source/user_guide/tutorials/mesh/split_mesh.rst b/doc/source/user_guide/tutorials/mesh/split_mesh.rst new file mode 100644 index 0000000000..44390cdb85 --- /dev/null +++ b/doc/source/user_guide/tutorials/mesh/split_mesh.rst @@ -0,0 +1,227 @@ +.. _ref_tutorials_split_mesh: + +============ +Split a mesh +============ + +:bdg-mapdl:`MAPDL` :bdg-lsdyna:`LSDYNA` :bdg-fluent:`Fluent` :bdg-cfx:`CFX` + +.. include:: ../../../links_and_refs.rst + +.. |MeshesContainer| replace:: :class:`MeshesContainer ` +.. |split_mesh| replace:: :class:`split_mesh ` +.. |split_on_property_type| replace:: :class:`split_on_property_type ` +.. |from_scopings| replace:: :class:`from_scopings ` +.. |ScopingsContainer| replace:: :class:`ScopingsContainer ` +.. |PropertyField| replace:: :class:`PropertyField ` + +This tutorial shows how to split a mesh on a give property. + +There are two approaches to accomplish this goal: + +- :ref:`Use the split_mesh operator to split a already existing MeshedRegion`; +- :ref:`Split the mesh scoping and create the split MeshedRegion objects `. + +:jupyter-download-script:`Download tutorial as Python script` +:jupyter-download-notebook:`Download tutorial as Jupyter notebook` + +Define the mesh +--------------- + +The mesh object in DPF is a |MeshedRegion|. You can obtain a |MeshedRegion| by creating your own from scratch or by getting it from a result file. For more +information check the :ref:`ref_tutorials_create_a_mesh_from_scratch` and :ref:`ref_tutorials_get_mesh_from_result_file` +tutorials. + +For this tutorial, we get a |MeshedRegion| from a result file. You can use one available in the |Examples| module. +For more information see the :ref:`ref_tutorials_get_mesh_from_result_file` tutorial. + +.. tab-set:: + + .. tab-item:: MAPDL + + .. jupyter-execute:: + + # Import the ``ansys.dpf.core`` module + from ansys.dpf import core as dpf + # Import the examples module + from ansys.dpf.core import examples + # Import the operators module + from ansys.dpf.core import operators as ops + + # Define the result file path + result_file_path_1 = examples.find_multishells_rst() + # Create the model + model_1 = dpf.Model(data_sources=result_file_path_1) + # Get the mesh + meshed_region_1 = model_1.metadata.meshed_region + + .. tab-item:: LSDYNA + + .. jupyter-execute:: + + # Import the ``ansys.dpf.core`` module + from ansys.dpf import core as dpf + # Import the examples module + from ansys.dpf.core import examples + # Import the operators module + from ansys.dpf.core import operators as ops + + # Define the result file path + result_file_path_2 = examples.download_d3plot_beam() + # Create the DataSources object + ds_2 = dpf.DataSources() + ds_2.set_result_file_path(filepath=result_file_path_2[0], key="d3plot") + ds_2.add_file_path(filepath=result_file_path_2[3], key="actunits") + # Create the model + model_2 = dpf.Model(data_sources=ds_2) + # Get the mesh + meshed_region_2 = model_2.metadata.meshed_region + + .. tab-item:: Fluent + + .. jupyter-execute:: + + # Import the ``ansys.dpf.core`` module + from ansys.dpf import core as dpf + # Import the examples module + from ansys.dpf.core import examples + # Import the operators module + from ansys.dpf.core import operators as ops + + # Define the result file path + result_file_path_3 = examples.download_fluent_axial_comp()["flprj"] + # Create the model + model_3 = dpf.Model(data_sources=result_file_path_3) + # Get the mesh + meshed_region_3 = model_3.metadata.meshed_region + + .. tab-item:: CFX + + .. jupyter-execute:: + + # Import the ``ansys.dpf.core`` module + from ansys.dpf import core as dpf + # Import the examples module + from ansys.dpf.core import examples + # Import the operators module + from ansys.dpf.core import operators as ops + + # Define the result file path + result_file_path_4 = examples.download_cfx_mixing_elbow() + # Create the model + model_4 = dpf.Model(data_sources=result_file_path_4) + # Get the mesh + meshed_region_4 = model_4.metadata.meshed_region + +.. _ref_first_approach_split_mesh: + +First approach +-------------- + +Use the |split_mesh| operator to split an already existing |MeshedRegion| based on a property. +Currently you can split a mesh by material or eltype. + +When you split a |MeshedRegion| the split parts are stored in the DPF collection called |MeshesContainer|. + +Here, we split the |MeshedRegion| by material. + +.. tab-set:: + + .. tab-item:: MAPDL + + .. jupyter-execute:: + + # Split the mesh by material + meshes_11 = ops.mesh.split_mesh(mesh=meshed_region_1,property="mat").eval() + + # Print the meshes + print(meshes_11) + + .. tab-item:: LSDYNA + + .. jupyter-execute:: + + # Split the mesh by material + meshes_21 = ops.mesh.split_mesh(mesh=meshed_region_2,property="mat").eval() + + # Print the meshes + print(meshes_21) + + .. tab-item:: Fluent + + .. jupyter-execute:: + + # Split the mesh by material + meshes_31 = ops.mesh.split_mesh(mesh=meshed_region_3,property="mat").eval() + + # Print the meshes + print(meshes_31) + + .. tab-item:: CFX + + .. jupyter-execute:: + + # Split the mesh by material + meshes_41 = ops.mesh.split_mesh(mesh=meshed_region_4,property="mat").eval() + # Print the meshes + print(meshes_41) + +.. _ref_second_approach_split_mesh: + +Second approach +--------------- + +First, use the |split_on_property_type| operator to split the mesh scoping. This operator splits a |Scoping| on given +properties (elshape and/or material, since 2025R1 it supports any scalar property field name contained in the mesh +property fields) and returns a |ScopingsContainer| with those split scopings. + +Finally, create the split |MeshedRegion| objects with the |from_scopings| operator. The split parts are stored +in the DPF collection called |MeshesContainer|. + +Here, we split the mesh scoping by material. + +.. tab-set:: + + .. tab-item:: MAPDL + + .. jupyter-execute:: + + # Define the scoping split by material + split_scoping_1 = ops.scoping.split_on_property_type(mesh=meshed_region_1, label1="mat").eval() + # Get the split meshes + meshes_12 = ops.mesh.from_scopings(scopings_container=split_scoping_1,mesh=meshed_region_1).eval() + # Print the meshes + print(meshes_12) + + .. tab-item:: LSDYNA + + .. jupyter-execute:: + + # Define the scoping split by material + split_scoping_2 = ops.scoping.split_on_property_type(mesh=meshed_region_2, label1="mat").eval() + # Get the split meshes + meshes_22 = ops.mesh.from_scopings(scopings_container=split_scoping_2,mesh=meshed_region_2).eval() + # Print the meshes + print(meshes_22) + + .. tab-item:: Fluent + + .. jupyter-execute:: + + # Define the scoping split by material + split_scoping_3 = ops.scoping.split_on_property_type(mesh=meshed_region_3, label1="mat").eval() + # Get the split meshes + meshes_32 = ops.mesh.from_scopings(scopings_container=split_scoping_3,mesh=meshed_region_3).eval() + # Print the meshes + print(meshes_32) + + .. tab-item:: CFX + + .. jupyter-execute:: + + # Define the scoping split by material + split_scoping_4 = ops.scoping.split_on_property_type(mesh=meshed_region_4, label1="mat").eval() + # Get the split meshes + meshes_42 = ops.mesh.from_scopings(scopings_container=split_scoping_4,mesh=meshed_region_4).eval() + # Print the meshes + print(meshes_42)