LCOV - code coverage report
Current view: top level - include/utils - MooseMeshElementConversionUtils.h (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #32971 (54bef8) with base c6cf66 Lines: 4 4 100.0 %
Date: 2026-05-29 20:35:17 Functions: 2 2 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //* This file is part of the MOOSE framework
       2             : //* https://mooseframework.inl.gov
       3             : //*
       4             : //* All rights reserved, see COPYRIGHT for full restrictions
       5             : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
       6             : //*
       7             : //* Licensed under LGPL 2.1, please see LICENSE for details
       8             : //* https://www.gnu.org/licenses/lgpl-2.1.html
       9             : 
      10             : #pragma once
      11             : 
      12             : #include "libmesh/replicated_mesh.h"
      13             : 
      14             : #include "MooseTypes.h"
      15             : 
      16             : namespace MooseMeshElementConversionUtils
      17             : {
      18             : // Define for comparing the key value of BCTuple
      19             : struct BCTupleKeyComp
      20             : {
      21      392694 :   bool operator()(const libMesh::BoundaryInfo::BCTuple & s, dof_id_type i) const
      22             :   {
      23      392694 :     return std::get<0>(s) < i;
      24             :   }
      25      189652 :   bool operator()(dof_id_type i, const libMesh::BoundaryInfo::BCTuple & s) const
      26             :   {
      27      189652 :     return i < std::get<0>(s);
      28             :   }
      29             : };
      30             : 
      31             : /**
      32             :  * Split a HEX8 element into six TET4 elements.
      33             :  * @param mesh The mesh to be modified
      34             :  * @param bdry_side_list A list that contains the boundary information of the original mesh
      35             :  * @param elem_id The id of the element to be split
      36             :  * @param converted_elems_ids a vector to record the ids of the newly created TET4 elements
      37             :  */
      38             : void hexElemSplitter(MeshBase & mesh,
      39             :                      const std::vector<libMesh::BoundaryInfo::BCTuple> & bdry_side_list,
      40             :                      const dof_id_type elem_id,
      41             :                      std::vector<dof_id_type> & converted_elems_ids);
      42             : 
      43             : /**
      44             :  * Split a PYRAMID5 element into two TET4 elements.
      45             :  * @param mesh The mesh to be modified
      46             :  * @param bdry_side_list A list that contains the boundary information of the original mesh
      47             :  * @param elem_id The id of the element to be split
      48             :  * @param converted_elems_ids a vector to record the ids of the newly created TET4 elements
      49             :  */
      50             : void pyramidElemSplitter(MeshBase & mesh,
      51             :                          const std::vector<libMesh::BoundaryInfo::BCTuple> & bdry_side_list,
      52             :                          const dof_id_type elem_id,
      53             :                          std::vector<dof_id_type> & converted_elems_ids);
      54             : 
      55             : /**
      56             :  * Split a PRISM6 element into three TET4 elements.
      57             :  * @param mesh The mesh to be modified
      58             :  * @param bdry_side_list A list that contains the boundary information of the original mesh
      59             :  * @param elem_id The id of the element to be split
      60             :  * @param converted_elems_ids a vector to record the ids of the newly created TET4 elements
      61             :  */
      62             : void prismElemSplitter(MeshBase & mesh,
      63             :                        const std::vector<libMesh::BoundaryInfo::BCTuple> & bdry_side_list,
      64             :                        const dof_id_type elem_id,
      65             :                        std::vector<dof_id_type> & converted_elems_ids);
      66             : 
      67             : /**
      68             :  * Split a polyhedron element into n_sides TET4 elements.
      69             :  * @param mesh The mesh to be modified
      70             :  * @param bdry_side_list A list that contains the boundary information of the original mesh
      71             :  * @param elem_id The id of the element to be split
      72             :  * @param converted_elems_ids a vector to record the ids of the newly created TET4 elements
      73             :  */
      74             : void polyhedronElemSplitter(MeshBase & mesh,
      75             :                             const std::vector<libMesh::BoundaryInfo::BCTuple> & bdry_side_list,
      76             :                             const dof_id_type elem_id,
      77             :                             std::vector<dof_id_type> & converted_elems_ids);
      78             : 
      79             : /**
      80             :  * Rotate a HEX8 element's nodes to ensure that the node with the minimum id is the first node;
      81             :  * and the node among its three neighboring nodes with the minimum id is the second node.
      82             :  * @param min_id_index The index of the node with the minimum id
      83             :  * @param sec_min_pos The index of the node among its three neighboring nodes with the minimum
      84             :  * id (see comments in the function for more details about how the index is defined)
      85             :  * @param face_rotation A vector to record the rotation of the faces of the HEX8 element
      86             :  * @param node_rotation a vector of node indices that can form a HEX8 element
      87             :  */
      88             : void nodeRotationHEX8(const unsigned int min_id_index,
      89             :                       const unsigned int sec_min_pos,
      90             :                       std::vector<unsigned int> & face_rotation,
      91             :                       std::vector<unsigned int> & node_rotation);
      92             : 
      93             : /**
      94             :  * Calculate the indices (within the element nodes) of the three neighboring nodes of a node in a
      95             :  * HEX8 element.
      96             :  * @param min_id_index The index of the node with the minimum id
      97             :  * @return a vector of the three neighboring nodes
      98             :  */
      99             : std::vector<unsigned int> neighborNodeIndicesHEX8(unsigned int min_id_index);
     100             : 
     101             : /**
     102             :  * For a vector of rotated nodes that can form a HEX8 element, create a vector of four-node sets
     103             :  * that can form TET4 elements to replace the original HEX8 element. All the QUAD4 faces of the
     104             :  * HEX8 element will be split by the diagonal line that involves the node with the minimum id of
     105             :  * that face.
     106             :  * @param hex_nodes A vector of pointers to the nodes that can form a HEX8 element
     107             :  * @param rotated_tet_face_indices A vector of vectors of the original face indices of the HEX8
     108             :  * element corresponding to the faces of the newly created TET4 elements
     109             :  * @param tet_nodes_list a vector of vectors of pointers to the nodes that can form TET4 elements
     110             :  */
     111             : void hexNodesToTetNodesDeterminer(std::vector<const Node *> & hex_nodes,
     112             :                                   std::vector<std::vector<unsigned int>> & rotated_tet_face_indices,
     113             :                                   std::vector<std::vector<const Node *>> & tet_nodes_list);
     114             : 
     115             : /**
     116             :  * For a HEX8 element, determine the direction of the diagonal line of each face that involves the
     117             :  * node with the minimum id of that face.
     118             :  * @param hex_nodes A vector of pointers to the nodes that can form a HEX8 element
     119             :  * @return a vector of boolean values indicating the direction of the diagonal line of each face
     120             :  */
     121             : std::vector<bool> quadFaceDiagonalDirectionsHex(const std::vector<const Node *> & hex_nodes);
     122             : 
     123             : /**
     124             :  * For a QUAD4 element, determine the direction of the diagonal line that involves the node with
     125             :  * the minimum id of that element.
     126             :  * @param quad_nodes A vector of pointers to the nodes that can form a QUAD4 element
     127             :  * @return a boolean value indicating the direction of the diagonal line
     128             :  */
     129             : bool quadFaceDiagonalDirection(const std::vector<const Node *> & quad_nodes);
     130             : 
     131             : /**
     132             :  * Creates sets of four nodes indices that can form TET4 elements to replace the original HEX8
     133             :  * element.
     134             :  * @param diagonal_directions A vector of boolean values indicating the direction of the diagonal
     135             :  * line of each face; true means the diagonal line is connecting node 0 and node 2, false means the
     136             :  * diagonal line is connecting node 1 and node 3 of that quad face
     137             :  * @param tet_face_indices A vector of vectors of the original face indices of the HEX8 element
     138             :  * corresponding to the faces of the newly created TET4 elements
     139             :  * @return a vector of vectors of node indices that can form TET4 elements
     140             :  */
     141             : std::vector<std::vector<unsigned int>>
     142             : tetNodesForHex(const std::vector<bool> diagonal_directions,
     143             :                std::vector<std::vector<unsigned int>> & tet_face_indices);
     144             : 
     145             : /**
     146             :  * Rotate a PRISM6 element nodes to ensure that the node with the minimum id is the first node.
     147             :  * @param min_id_index The index of the node, within the prism nodes, with the minimum id
     148             :  * @param face_rotation A vector to record the rotation of the faces of the PRISM6 element
     149             :  * @param node_rotation a vector of node indices that can form a PRISM6 element
     150             :  */
     151             : void nodeRotationPRISM6(unsigned int min_id_index,
     152             :                         std::vector<unsigned int> & face_rotation,
     153             :                         std::vector<unsigned int> & node_rotation);
     154             : 
     155             : /**
     156             :  * For a rotated nodes that can form a PRISM6 element, create a series of four-node set that can
     157             :  * form TET4 elements to replace the original PRISM6 element. All the QUAD4 face of the PRISM6
     158             :  * element will be split by the diagonal line that involves the node with the minimum id of that
     159             :  * face.
     160             :  * @param prism_nodes A vector of pointers to the nodes that can form a PRISM6 element
     161             :  * @param rotated_tet_face_indices A vector of vectors of the original face indices of the PRISM6
     162             :  * element corresponding to the faces of the newly created TET4 elements
     163             :  * @param tet_nodes_list a vector of vectors of pointers to the nodes that can form TET4 elements
     164             :  */
     165             : void
     166             : prismNodesToTetNodesDeterminer(std::vector<const Node *> & prism_nodes,
     167             :                                std::vector<std::vector<unsigned int>> & rotated_tet_face_indices,
     168             :                                std::vector<std::vector<const Node *>> & tet_nodes_list);
     169             : 
     170             : /**
     171             :  * Creates sets of four nodes indices that can form TET4 elements to replace the original PRISM6
     172             :  * element.
     173             :  * @param diagonal_direction A boolean value indicating the direction of the diagonal line of Face
     174             :  * 2
     175             :  * @param tet_face_indices A vector of vectors of the original face indices of the PRISM6 element
     176             :  * corresponding to the faces of the newly created TET4 elements
     177             :  * @return a vector of vectors of node indices that can form TET4 elements
     178             :  */
     179             : std::vector<std::vector<unsigned int>>
     180             : tetNodesForPrism(const bool diagonal_direction,
     181             :                  std::vector<std::vector<unsigned int>> & tet_face_indices);
     182             : 
     183             : /**
     184             :  * Rotate a PYRAMID5 element nodes to ensure that the node with the minimum id is the first node
     185             :  * for the bottom face.
     186             :  * @param min_id_index The index of the node, within the pyramid nodes, with the minimum id for the
     187             :  * bottom face
     188             :  * @param face_rotation A vector to record the rotation of the faces of the PYRAMID5 element
     189             :  * @param node_rotation a vector of node indices that can form a PYRAMID5 element
     190             :  */
     191             : void nodeRotationPYRAMID5(unsigned int min_id_index,
     192             :                           std::vector<unsigned int> & face_rotation,
     193             :                           std::vector<unsigned int> & node_rotation);
     194             : 
     195             : /**
     196             :  * For a rotated nodes that can form a PYRAMID5 element, create a series of four-node set that can
     197             :  * form TET4 elements to replace the original PYRAMID5 element. The QUAD4 face of the
     198             :  * PYRAMID5 element will be split by the diagonal line that involves the node with the minimum id
     199             :  * of that face.
     200             :  * @param pyramid_nodes A vector of pointers to the nodes that can form a PYRAMID5 element
     201             :  * @param rotated_tet_face_indices A vector of vectors of the original face indices of the
     202             :  * PYRAMID5 element corresponding to the faces of the newly created TET4 elements
     203             :  * @param tet_nodes_list a vector of vectors of pointers to the nodes that can form TET4 elements
     204             :  */
     205             : void
     206             : pyramidNodesToTetNodesDeterminer(std::vector<const Node *> & pyramid_nodes,
     207             :                                  std::vector<std::vector<unsigned int>> & rotated_tet_face_indices,
     208             :                                  std::vector<std::vector<const Node *>> & tet_nodes_list);
     209             : 
     210             : /**
     211             :  * Convert all the elements in a 3D mesh, consisting of only linear elements, into TET4 elements.
     212             :  * @param mesh The mesh to be converted
     213             :  * @param elems_to_process A vector of pairs of element ids and a bool indicating whether the
     214             :  * element needs to be fully retained or will be further processed in the following procedures
     215             :  * @param converted_elems_ids_to_track A vector of element ids that need to be tracked for being
     216             :  * further processed in the following procedures
     217             :  * @param block_id_to_remove The id of a new subdomain in the mesh containing all the elements to be
     218             :  * removed
     219             :  * @param delete_block_to_remove A bool indicating whether the block to be removed will be
     220             :  * deleted in this method
     221             :  */
     222             : void convert3DMeshToAllTet4(MeshBase & mesh,
     223             :                             const std::vector<std::pair<dof_id_type, bool>> & elems_to_process,
     224             :                             std::vector<dof_id_type> & converted_elems_ids_to_track,
     225             :                             const subdomain_id_type block_id_to_remove,
     226             :                             const bool delete_block_to_remove);
     227             : 
     228             : /**
     229             :  * Convert all the elements in a 3D mesh consisting of only linear elements into TET4 elements.
     230             :  * @param mesh The mesh to be converted
     231             :  */
     232             : void convert3DMeshToAllTet4(MeshBase & mesh);
     233             : 
     234             : /**
     235             :  * Collect the boundary information of the given element in a mesh.
     236             :  * @param bdry_side_list A list that contains the boundary information of the mesh
     237             :  * @param elem_id The id of the element to be processed
     238             :  * @param n_elem_sides The number of sides of the element
     239             :  * @param elem_side_list a vector of vectors to record the boundary information of the element
     240             :  */
     241             : void
     242             : elementBoundaryInfoCollector(const std::vector<libMesh::BoundaryInfo::BCTuple> & bdry_side_list,
     243             :                              const dof_id_type elem_id,
     244             :                              const unsigned short n_elem_sides,
     245             :                              std::vector<std::vector<boundary_id_type>> & elem_side_list);
     246             : 
     247             : /**
     248             :  * Convert the element to an element with TRI3 side-elements on the user-specified sides by
     249             :  * modifying the mesh.
     250             :  * @param mesh The mesh containing the element
     251             :  * @param elem_id The ID of the element to be converted
     252             :  * @param side_indices The indices of the sides to be converted
     253             :  * @param elem_side_info The boundary IDs associated with the sides of the element
     254             :  * @param subdomain_id_shift_base the reference id used to shift the subdomain ID for new elements
     255             :  */
     256             : void convertElem(MeshBase & mesh,
     257             :                  const dof_id_type & elem_id,
     258             :                  const std::vector<unsigned int> & side_indices,
     259             :                  const std::vector<std::vector<boundary_id_type>> & elem_side_info,
     260             :                  const SubdomainID & subdomain_id_shift_base);
     261             : 
     262             : /**
     263             :  * Convert a HEX8 element to elements with TRI3 surfaces on the given original QUAD4 side(s).
     264             :  * @param mesh The mesh containing the element
     265             :  * @param elem_id The ID of the HEX8 element to be converted
     266             :  * @param side_indices The indices of the QUAD4 sides to be converted to TRI3 sides
     267             :  * @param elem_side_info The boundary IDs associated with the sides of the HEX8 element
     268             :  * @param subdomain_id_shift_base the reference id used to shift the subdomain ID for new elements
     269             :  */
     270             : void convertHex8Elem(MeshBase & mesh,
     271             :                      const dof_id_type & elem_id,
     272             :                      const std::vector<unsigned int> & side_indices,
     273             :                      const std::vector<std::vector<boundary_id_type>> & elem_side_info,
     274             :                      const SubdomainID & subdomain_id_shift_base);
     275             : 
     276             : /**
     277             :  * Create one PYRAMID5 element based on a side and the centroid of the HEX8 element.
     278             :  * @param mesh The mesh containing the element
     279             :  * @param elem_id The ID of the HEX8 element to be converted
     280             :  * @param side_index The index of the side to be converted
     281             :  * @param new_node The new node created at the centroid of the HEX8 element
     282             :  * @param side_info The boundary IDs associated with the side of the HEX8 element
     283             :  * @param subdomain_id_shift_base the reference id used to shift the subdomain ID for new elements
     284             :  */
     285             : void createUnitPyramid5FromHex8(MeshBase & mesh,
     286             :                                 const dof_id_type & elem_id,
     287             :                                 const unsigned int & side_index,
     288             :                                 const Node * new_node,
     289             :                                 const std::vector<boundary_id_type> & side_info,
     290             :                                 const SubdomainID & subdomain_id_shift_base);
     291             : 
     292             : /**
     293             :  * Create two TET4 elements based on a side and the centroid of the HEX8 element.
     294             :  * @param mesh The mesh containing the element
     295             :  * @param elem_id The ID of the HEX8 element to be converted
     296             :  * @param side_index The index of the side to be converted
     297             :  * @param new_node The new node created at the centroid of the HEX8 element
     298             :  * @param side_info The boundary IDs associated with the side of the HEX8 element
     299             :  * @param subdomain_id_shift_base the reference id used to shift the subdomain ID for new elements
     300             :  */
     301             : void createUnitTet4FromHex8(MeshBase & mesh,
     302             :                             const dof_id_type & elem_id,
     303             :                             const unsigned int & side_index,
     304             :                             const Node * new_node,
     305             :                             const std::vector<boundary_id_type> & side_info,
     306             :                             const SubdomainID & subdomain_id_shift_base);
     307             : 
     308             : /**
     309             :  * Convert a PRISM6 element to elements with TRI3 surfaces on the given original QUAD4 side(s).
     310             :  * @param mesh The mesh containing the element
     311             :  * @param elem_id The ID of the PRISM6 element to be converted
     312             :  * @param side_indices The indices of the QUAD sides to be converted to TRI3 sides
     313             :  * @param elem_side_info The boundary IDs associated with the sides of the PRISM6 element
     314             :  * @param subdomain_id_shift_base the reference id used to shift the subdomain ID for new elements
     315             :  */
     316             : void convertPrism6Elem(MeshBase & mesh,
     317             :                        const dof_id_type & elem_id,
     318             :                        const std::vector<unsigned int> & side_indices,
     319             :                        const std::vector<std::vector<boundary_id_type>> & elem_side_info,
     320             :                        const SubdomainID & subdomain_id_shift_base);
     321             : /**
     322             :  * Create one or two TET4 elements based on a side and the centroid of the PRISM6 element.
     323             :  * @param mesh The mesh containing the element
     324             :  * @param elem_id The ID of the PRISM6 element to be converted
     325             :  * @param side_index The index of the side to be converted
     326             :  * @param new_node The new node created at the centroid of the PRISM6 element
     327             :  * @param side_info The boundary IDs associated with the side of the PRISM6 element
     328             :  * @param subdomain_id_shift_base the reference id used to shift the subdomain ID for new elements
     329             :  */
     330             : void createUnitTet4FromPrism6(MeshBase & mesh,
     331             :                               const dof_id_type & elem_id,
     332             :                               const unsigned int & side_index,
     333             :                               const Node * new_node,
     334             :                               const std::vector<boundary_id_type> & side_info,
     335             :                               const SubdomainID & subdomain_id_shift_base);
     336             : 
     337             : /**
     338             :  * Create a PYRAMID5 element opposite the sides converted to tets and the centroid of the PRISM6
     339             :  * element.
     340             :  * @param mesh The mesh containing the element
     341             :  * @param elem_id The ID of the PRISM6 element to be converted
     342             :  * @param side_index The index of the side to be converted
     343             :  * @param new_node The new node created at the centroid of the PRISM6 element
     344             :  * @param side_info The boundary IDs associated with the side of the PRISM6 element
     345             :  * @param subdomain_id_shift_base the reference id used to shift the subdomain ID for new elements
     346             :  */
     347             : void createUnitPyramid5FromPrism6(MeshBase & mesh,
     348             :                                   const dof_id_type & elem_id,
     349             :                                   const unsigned int & side_index,
     350             :                                   const Node * new_node,
     351             :                                   const std::vector<boundary_id_type> & side_info,
     352             :                                   const SubdomainID & subdomain_id_shift_base);
     353             : 
     354             : /**
     355             :  * Convert a PYRAMID5 element to elements with TRI3 surfaces on the original QUAD4 side.
     356             :  * @param mesh The mesh containing the element
     357             :  * @param elem_id The ID of the PYRAMID5 element to be converted
     358             :  * @param elem_side_info The boundary IDs associated with the sides of the PYRAMID
     359             :  * @param subdomain_id_shift_base the reference id used to shift the subdomain ID for new elements
     360             :  */
     361             : void convertPyramid5Elem(MeshBase & mesh,
     362             :                          const dof_id_type & elem_id,
     363             :                          const std::vector<std::vector<boundary_id_type>> & elem_side_info,
     364             :                          const SubdomainID & subdomain_id_shift_base);
     365             : 
     366             : /**
     367             :  * Retain the extra integer of the original element in a new element.
     368             :  * @param mesh The mesh containing the element
     369             :  * @param elem_id The ID of the original element
     370             :  * @param new_elem_ptr The pointer to the new element that will retain the extra integer
     371             :  */
     372             : void retainEEID(MeshBase & mesh, const dof_id_type & elem_id, Elem * new_elem_ptr);
     373             : 
     374             : /**
     375             :  * Generate a transition layer of elements with TRI3 surfaces on the given boundaries.
     376             :  * @param mesh The mesh to be modified
     377             :  * @param boundary_names A vector of boundary names on which the transition layer will be
     378             :  * generated
     379             :  * @param conversion_element_layer_number The number of element layers to be converted on the given
     380             :  * boundaries.
     381             :  * @param external_boundaries_checking Whether to check if the provided boundaries are external
     382             :  * boundaries
     383             :  */
     384             : void transitionLayerGenerator(MeshBase & mesh,
     385             :                               const std::vector<BoundaryName> & boundary_names,
     386             :                               const unsigned int conversion_element_layer_number,
     387             :                               const bool external_boundaries_checking);
     388             : 
     389             : /**
     390             :  * Assign a subdomain name suffix to the converted elements created during transition layer
     391             :  * generation.
     392             :  * @param mesh The mesh to be modified
     393             :  * @param original_subdomain_ids A set of original subdomain IDs of the mesh before conversion
     394             :  * @param sid_shift_base The base subdomain ID to shift the original elements because of the
     395             :  * element type change
     396             :  * @param tet_suffix The suffix to be added to the subdomain names of the converted TET4 elements
     397             :  * @param pyramid_suffix The suffix to be added to the subdomain names of the converted PYRAMID5
     398             :  * elements
     399             :  */
     400             : void assignConvertedElementsSubdomainNameSuffix(
     401             :     MeshBase & mesh,
     402             :     const std::set<subdomain_id_type> & original_subdomain_ids,
     403             :     const subdomain_id_type sid_shift_base,
     404             :     const SubdomainName & tet_suffix,
     405             :     const SubdomainName & pyramid_suffix);
     406             : }

Generated by: LCOV version 1.14