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

Generated by: LCOV version 1.14