LCOV - code coverage report
Current view: top level - src - CN.cpp (source / functions) Hit Total Coverage
Test: coverage_sk.info Lines: 189 329 57.4 %
Date: 2020-12-16 07:07:30 Functions: 21 68 30.9 %
Branches: 195 449 43.4 %

           Branch data     Line data    Source code
       1                 :            : /**
       2                 :            :  * MOAB, a Mesh-Oriented datABase, is a software component for creating,
       3                 :            :  * storing and accessing finite element mesh data.
       4                 :            :  *
       5                 :            :  * Copyright 2004 Sandia Corporation.  Under the terms of Contract
       6                 :            :  * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government
       7                 :            :  * retains certain rights in this software.
       8                 :            :  *
       9                 :            :  * This library is free software; you can redistribute it and/or
      10                 :            :  * modify it under the terms of the GNU Lesser General Public
      11                 :            :  * License as published by the Free Software Foundation; either
      12                 :            :  * version 2.1 of the License, or (at your option) any later version.
      13                 :            :  *
      14                 :            :  */
      15                 :            : 
      16                 :            : #include "moab/CN.hpp"
      17                 :            : #include "MBCNArrays.hpp"
      18                 :            : #include "MBCN.h"
      19                 :            : #include <assert.h>
      20                 :            : #include <string.h>
      21                 :            : #include <iterator>
      22                 :            : 
      23                 :            : namespace moab
      24                 :            : {
      25                 :            : 
      26                 :            : const char* CN::entityTypeNames[] = { "Vertex", "Edge",  "Tri", "Quad",       "Polygon",   "Tet",    "Pyramid",
      27                 :            :                                       "Prism",  "Knife", "Hex", "Polyhedron", "EntitySet", "MaxType" };
      28                 :            : 
      29                 :            : short int CN::numberBasis = 0;
      30                 :            : 
      31                 :            : short int CN::permuteVec[MBMAXTYPE][3][MAX_SUB_ENTITIES + 1];
      32                 :            : short int CN::revPermuteVec[MBMAXTYPE][3][MAX_SUB_ENTITIES + 1];
      33                 :            : 
      34                 :            : const DimensionPair CN::TypeDimensionMap[] = {
      35                 :            :     DimensionPair( MBVERTEX, MBVERTEX ),       DimensionPair( MBEDGE, MBEDGE ),
      36                 :            :     DimensionPair( MBTRI, MBPOLYGON ),         DimensionPair( MBTET, MBPOLYHEDRON ),
      37                 :            :     DimensionPair( MBENTITYSET, MBENTITYSET ), DimensionPair( MBMAXTYPE, MBMAXTYPE )
      38                 :            : };
      39                 :            : 
      40                 :            : short CN::increasingInts[] = { 0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
      41                 :            :                                20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39 };
      42                 :            : 
      43                 :            : //! set the basis of the numbering system; may or may not do things besides setting the
      44                 :            : //! member variable
      45                 :          0 : void CN::SetBasis( const int in_basis )
      46                 :            : {
      47                 :          0 :     numberBasis = in_basis;
      48                 :          0 : }
      49                 :            : 
      50                 :            : /// Get the dimension pair corresponding to a dimension
      51                 :          0 : DimensionPair CN::getDimPair( int entity_type )
      52                 :            : {
      53                 :          0 :     return TypeDimensionMap[entity_type];
      54                 :            : }
      55                 :            : 
      56                 :            : //! return a type for the given name
      57                 :        222 : EntityType CN::EntityTypeFromName( const char* name )
      58                 :            : {
      59 [ +  - ][ +  - ]:        730 :     for( EntityType i = MBVERTEX; i < MBMAXTYPE; i++ )
      60                 :            :     {
      61         [ +  + ]:        730 :         if( 0 == strcmp( name, entityTypeNames[i] ) ) return i;
      62                 :            :     }
      63                 :            : 
      64                 :        222 :     return MBMAXTYPE;
      65                 :            : }
      66                 :            : 
      67                 :       3789 : void CN::SubEntityNodeIndices( const EntityType this_topo, const int num_nodes, const int sub_dimension,
      68                 :            :                                const int sub_index, EntityType& subentity_topo, int& num_sub_entity_nodes,
      69                 :            :                                int sub_entity_conn[] )
      70                 :            : {
      71                 :            :     // If asked for a node, the special case...
      72         [ -  + ]:       3789 :     if( sub_dimension == 0 )
      73                 :            :     {
      74         [ #  # ]:          0 :         assert( sub_index < num_nodes );
      75                 :          0 :         subentity_topo       = MBVERTEX;
      76                 :          0 :         num_sub_entity_nodes = 1;
      77                 :          0 :         sub_entity_conn[0]   = sub_index;
      78                 :       3789 :         return;
      79                 :            :     }
      80                 :            : 
      81         [ +  - ]:       3789 :     const int ho_bits    = HasMidNodes( this_topo, num_nodes );
      82         [ +  - ]:       3789 :     subentity_topo       = SubEntityType( this_topo, sub_dimension, sub_index );
      83         [ +  - ]:       3789 :     num_sub_entity_nodes = VerticesPerEntity( subentity_topo );
      84                 :       3789 :     const short* corners = mConnectivityMap[this_topo][sub_dimension - 1].conn[sub_index];
      85         [ +  - ]:       3789 :     std::copy( corners, corners + num_sub_entity_nodes, sub_entity_conn );
      86                 :            : 
      87                 :            :     int sub_sub_corners[MAX_SUB_ENTITY_VERTICES];
      88                 :            :     int side, sense, offset;
      89         [ +  + ]:       9641 :     for( int dim = 1; dim <= sub_dimension; ++dim )
      90                 :            :     {
      91         [ +  + ]:       5852 :         if( !( ho_bits & ( 1 << dim ) ) ) continue;
      92                 :            : 
      93         [ +  - ]:       1480 :         const short num_mid = NumSubEntities( subentity_topo, dim );
      94         [ +  + ]:       4148 :         for( int i = 0; i < num_mid; ++i )
      95                 :            :         {
      96         [ +  - ]:       2668 :             const EntityType sub_sub_topo = SubEntityType( subentity_topo, dim, i );
      97         [ +  - ]:       2668 :             const int sub_sub_num_vert    = VerticesPerEntity( sub_sub_topo );
      98         [ +  - ]:       2668 :             SubEntityVertexIndices( subentity_topo, dim, i, sub_sub_corners );
      99                 :            : 
     100         [ +  + ]:       8748 :             for( int j = 0; j < sub_sub_num_vert; ++j )
     101                 :       6080 :                 sub_sub_corners[j] = corners[sub_sub_corners[j]];
     102         [ +  - ]:       2668 :             SideNumber( this_topo, sub_sub_corners, sub_sub_num_vert, dim, side, sense, offset );
     103         [ +  - ]:       2668 :             sub_entity_conn[num_sub_entity_nodes++] = HONodeIndex( this_topo, num_nodes, dim, side );
     104                 :            :         }
     105                 :            :     }
     106                 :            : }
     107                 :            : 
     108                 :            : //! return the vertices of the specified sub entity
     109                 :            : //! \param parent_conn Connectivity of parent entity
     110                 :            : //! \param parent_type Entity type of parent entity
     111                 :            : //! \param sub_dimension Dimension of sub-entity being queried
     112                 :            : //! \param sub_index Index of sub-entity being queried
     113                 :            : //! \param sub_entity_conn Connectivity of sub-entity, based on parent_conn and canonical
     114                 :            : //!           ordering for parent_type
     115                 :            : //! \param num_sub_vertices Number of vertices in sub-entity
     116                 :          0 : void CN::SubEntityConn( const void* parent_conn, const EntityType parent_type, const int sub_dimension,
     117                 :            :                         const int sub_index, void* sub_entity_conn, int& num_sub_vertices )
     118                 :            : {
     119                 :            :     static int sub_indices[MAX_SUB_ENTITY_VERTICES];
     120                 :            : 
     121                 :          0 :     SubEntityVertexIndices( parent_type, sub_dimension, sub_index, sub_indices );
     122                 :            : 
     123                 :          0 :     num_sub_vertices       = VerticesPerEntity( SubEntityType( parent_type, sub_dimension, sub_index ) );
     124                 :          0 :     void** parent_conn_ptr = static_cast< void** >( const_cast< void* >( parent_conn ) );
     125                 :          0 :     void** sub_conn_ptr    = static_cast< void** >( sub_entity_conn );
     126         [ #  # ]:          0 :     for( int i = 0; i < num_sub_vertices; i++ )
     127                 :          0 :         sub_conn_ptr[i] = parent_conn_ptr[sub_indices[i]];
     128                 :          0 : }
     129                 :            : 
     130                 :            : //! given an entity and a target dimension & side number, get that entity
     131                 :        299 : short int CN::AdjacentSubEntities( const EntityType this_type, const int* source_indices, const int num_source_indices,
     132                 :            :                                    const int source_dim, const int target_dim, std::vector< int >& index_list,
     133                 :            :                                    const int operation_type )
     134                 :            : {
     135                 :            :     // first get all the vertex indices
     136         [ +  - ]:        299 :     std::vector< int > tmp_indices;
     137                 :        299 :     const int* it1 = source_indices;
     138                 :            : 
     139 [ +  - ][ +  - ]:        299 :     assert( source_dim <= 3 && target_dim >= 0 && target_dim <= 3 &&
         [ +  + ][ -  + ]
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
     140                 :            :             // make sure we're not stepping off the end of the array;
     141                 :            :             ( ( source_dim > 0 && *it1 < mConnectivityMap[this_type][source_dim - 1].num_sub_elements ) ||
     142                 :            :               ( source_dim == 0 &&
     143                 :            :                 *it1 < mConnectivityMap[this_type][Dimension( this_type ) - 1].num_corners_per_sub_element[0] ) ) &&
     144         [ +  - ]:        299 :             *it1 >= 0 );
     145                 :            : 
     146                 :            : #define MUC CN::mUpConnMap[this_type][source_dim][target_dim]
     147                 :            : 
     148                 :            :     // if we're looking for the vertices of a single side, return them in
     149                 :            :     // the canonical ordering; otherwise, return them in sorted order
     150 [ +  + ][ +  + ]:        299 :     if( num_source_indices == 1 && 0 == target_dim && source_dim != target_dim )
                 [ +  - ]
     151                 :            :     {
     152                 :            : 
     153                 :            :         // element of mConnectivityMap should be for this type and for one
     154                 :            :         // less than source_dim, which should give the connectivity of that sub element
     155                 :        201 :         const ConnMap& cm = mConnectivityMap[this_type][source_dim - 1];
     156                 :        201 :         std::copy( cm.conn[source_indices[0]],
     157                 :        402 :                    cm.conn[source_indices[0]] + cm.num_corners_per_sub_element[source_indices[0]],
     158 [ +  - ][ +  - ]:        201 :                    std::back_inserter( index_list ) );
     159                 :        201 :         return 0;
     160                 :            :     }
     161                 :            : 
     162                 :            :     // now go through source indices, folding adjacencies into target list
     163         [ +  + ]:        265 :     for( it1 = source_indices; it1 != source_indices + num_source_indices; it1++ )
     164                 :            :     {
     165                 :            :         // *it1 is the side index
     166                 :            :         // at start of iteration, index_list has the target list
     167                 :            : 
     168                 :            :         // if a union, or first iteration and index list was empty, copy the list
     169 [ +  - ][ +  + ]:        167 :         if( operation_type == CN::UNION || ( it1 == source_indices && index_list.empty() ) )
         [ +  - ][ +  + ]
     170                 :            :         {
     171                 :         98 :             std::copy( MUC.targets_per_source_element[*it1],
     172                 :        196 :                        MUC.targets_per_source_element[*it1] + MUC.num_targets_per_source_element[*it1],
     173 [ +  - ][ +  - ]:         98 :                        std::back_inserter( index_list ) );
     174                 :            :         }
     175                 :            :         else
     176                 :            :         {
     177                 :            :             // else we're intersecting, and have a non-empty list; intersect with this target list
     178                 :         69 :             tmp_indices.clear();
     179         [ +  + ]:        248 :             for( int i = MUC.num_targets_per_source_element[*it1] - 1; i >= 0; i-- )
     180 [ +  - ][ +  - ]:        179 :                 if( std::find( index_list.begin(), index_list.end(), MUC.targets_per_source_element[*it1][i] ) !=
                 [ +  + ]
     181                 :            :                     index_list.end() )
     182         [ +  - ]:         84 :                     tmp_indices.push_back( MUC.targets_per_source_element[*it1][i] );
     183                 :            :             //      std::set_intersection(MUC.targets_per_source_element[*it1],
     184                 :            :             //                            MUC.targets_per_source_element[*it1]+
     185                 :            :             //                            MUC.num_targets_per_source_element[*it1],
     186                 :            :             //                            index_list.begin(), index_list.end(),
     187                 :            :             //                            std::back_inserter(tmp_indices));
     188                 :         69 :             index_list.swap( tmp_indices );
     189                 :            : 
     190                 :            :             // if we're at this point and the list is empty, the intersection will be NULL;
     191                 :            :             // return if so
     192         [ -  + ]:         69 :             if( index_list.empty() ) return 0;
     193                 :            :         }
     194                 :            :     }
     195                 :            : 
     196 [ -  + ][ #  # ]:         98 :     if( operation_type == CN::UNION && num_source_indices != 1 )
     197                 :            :     {
     198                 :            :         // need to sort then unique the list
     199         [ #  # ]:          0 :         std::sort( index_list.begin(), index_list.end() );
     200 [ #  # ][ #  # ]:          0 :         index_list.erase( std::unique( index_list.begin(), index_list.end() ), index_list.end() );
     201                 :            :     }
     202                 :            : 
     203                 :        299 :     return 0;
     204                 :            : }
     205                 :            : 
     206                 :            : template < typename T >
     207                 :       2146 : static short int side_number( const T* parent_conn, const EntityType parent_type, const T* child_conn,
     208                 :            :                               const int child_num_verts, const int child_dim, int& side_no, int& sense, int& offset )
     209                 :            : {
     210 [ #  # ][ #  # ]:       2146 :     int parent_num_verts = CN::VerticesPerEntity( parent_type );
         [ +  - ][ #  # ]
         [ #  # ][ +  - ]
     211                 :            :     int side_indices[8];
     212 [ #  # ][ #  # ]:       2146 :     assert( sizeof( side_indices ) / sizeof( side_indices[0] ) >= (size_t)child_num_verts );
         [ -  + ][ #  # ]
         [ #  # ][ -  + ]
     213                 :            : 
     214 [ #  # ][ #  # ]:       9460 :     for( int i = 0; i < child_num_verts; i++ )
         [ +  + ][ #  # ]
         [ #  # ][ +  + ]
     215                 :            :     {
     216 [ #  # ][ #  # ]:       7334 :         side_indices[i] = std::find( parent_conn, parent_conn + parent_num_verts, child_conn[i] ) - parent_conn;
         [ +  - ][ #  # ]
         [ #  # ][ +  - ]
     217 [ #  # ][ #  # ]:       7334 :         if( side_indices[i] == parent_num_verts ) return -1;
         [ +  + ][ #  # ]
         [ #  # ][ -  + ]
     218                 :            :     }
     219                 :            : 
     220 [ #  # ][ #  # ]:       2146 :     return CN::SideNumber( parent_type, &side_indices[0], child_num_verts, child_dim, side_no, sense, offset );
         [ +  - ][ #  # ]
         [ #  # ][ +  - ]
     221                 :            : }
     222                 :            : 
     223                 :        224 : short int CN::SideNumber( const EntityType parent_type, const int* parent_conn, const int* child_conn,
     224                 :            :                           const int child_num_verts, const int child_dim, int& side_no, int& sense, int& offset )
     225                 :            : {
     226                 :        224 :     return side_number( parent_conn, parent_type, child_conn, child_num_verts, child_dim, side_no, sense, offset );
     227                 :            : }
     228                 :            : 
     229                 :          0 : short int CN::SideNumber( const EntityType parent_type, const unsigned int* parent_conn, const unsigned int* child_conn,
     230                 :            :                           const int child_num_verts, const int child_dim, int& side_no, int& sense, int& offset )
     231                 :            : {
     232                 :          0 :     return side_number( parent_conn, parent_type, child_conn, child_num_verts, child_dim, side_no, sense, offset );
     233                 :            : }
     234                 :          0 : short int CN::SideNumber( const EntityType parent_type, const long* parent_conn, const long* child_conn,
     235                 :            :                           const int child_num_verts, const int child_dim, int& side_no, int& sense, int& offset )
     236                 :            : {
     237                 :          0 :     return side_number( parent_conn, parent_type, child_conn, child_num_verts, child_dim, side_no, sense, offset );
     238                 :            : }
     239                 :       1922 : short int CN::SideNumber( const EntityType parent_type, const unsigned long* parent_conn,
     240                 :            :                           const unsigned long* child_conn, const int child_num_verts, const int child_dim, int& side_no,
     241                 :            :                           int& sense, int& offset )
     242                 :            : {
     243                 :       1922 :     return side_number( parent_conn, parent_type, child_conn, child_num_verts, child_dim, side_no, sense, offset );
     244                 :            : }
     245                 :            : 
     246                 :          0 : short int CN::SideNumber( const EntityType parent_type, const unsigned long long* parent_conn,
     247                 :            :                           const unsigned long long* child_conn, const int child_num_verts, const int child_dim,
     248                 :            :                           int& side_no, int& sense, int& offset )
     249                 :            : 
     250                 :            : {
     251                 :          0 :     return side_number( parent_conn, parent_type, child_conn, child_num_verts, child_dim, side_no, sense, offset );
     252                 :            : }
     253                 :            : 
     254                 :          0 : short int CN::SideNumber( const EntityType parent_type, void* const* parent_conn, void* const* child_conn,
     255                 :            :                           const int child_num_verts, const int child_dim, int& side_no, int& sense, int& offset )
     256                 :            : {
     257                 :          0 :     return side_number( parent_conn, parent_type, child_conn, child_num_verts, child_dim, side_no, sense, offset );
     258                 :            : }
     259                 :            : 
     260                 :       9001 : short int CN::SideNumber( const EntityType parent_type, const int* child_conn_indices, const int child_num_verts,
     261                 :            :                           const int child_dim, int& side_no, int& sense, int& offset )
     262                 :            : {
     263         [ +  - ]:       9001 :     int parent_dim       = Dimension( parent_type );
     264         [ +  - ]:       9001 :     int parent_num_verts = VerticesPerEntity( parent_type );
     265                 :            : 
     266                 :            :     // degenerate case (vertex), output == input
     267         [ -  + ]:       9001 :     if( child_dim == 0 )
     268                 :            :     {
     269         [ #  # ]:          0 :         if( child_num_verts != 1 ) return -1;
     270                 :          0 :         side_no = *child_conn_indices;
     271                 :          0 :         sense = offset = 0;
     272                 :            :     }
     273                 :            : 
     274                 :            :     // given a parent and child element, find the corresponding side number
     275                 :            : 
     276                 :            :     // dim_diff should be -1, 0 or 1 (same dimension, one less dimension, two less, resp.)
     277 [ +  - ][ -  + ]:       9001 :     if( child_dim > parent_dim || child_dim < 0 ) return -1;
     278                 :            : 
     279                 :            :     // different types of same dimension won't be the same
     280 [ +  + ][ -  + ]:       9001 :     if( parent_dim == child_dim && parent_num_verts != child_num_verts )
     281                 :            :     {
     282                 :          0 :         side_no = -1;
     283                 :          0 :         sense   = 0;
     284                 :          0 :         return 0;
     285                 :            :     }
     286                 :            : 
     287                 :            :     // loop over the sub-elements, comparing to child connectivity
     288                 :            :     int sub_conn_indices[10];
     289 [ +  - ][ +  + ]:      30418 :     for( int i = 0; i < NumSubEntities( parent_type, child_dim ); i++ )
     290                 :            :     {
     291 [ +  - ][ +  - ]:      30417 :         int sub_size = VerticesPerEntity( SubEntityType( parent_type, child_dim, i ) );
     292         [ +  + ]:      30417 :         if( sub_size != child_num_verts ) continue;
     293                 :            : 
     294         [ +  - ]:      30180 :         SubEntityVertexIndices( parent_type, child_dim, i, sub_conn_indices );
     295         [ +  - ]:      30180 :         bool they_match = ConnectivityMatch( child_conn_indices, sub_conn_indices, sub_size, sense, offset );
     296         [ +  + ]:      30180 :         if( they_match )
     297                 :            :         {
     298                 :       9000 :             side_no = i;
     299                 :       9000 :             return 0;
     300                 :            :         }
     301                 :            :     }
     302                 :            : 
     303                 :            :     // if we've gotten here, we don't match
     304                 :          1 :     side_no = -1;
     305                 :            : 
     306                 :            :     // return value is no success
     307                 :       9001 :     return 1;
     308                 :            : }
     309                 :            : 
     310                 :            : //! return the dimension and index of the opposite side, given parent entity type and child
     311                 :            : //! dimension and index.  This function is only defined for certain types of parent/child types:
     312                 :            : //! (Parent, Child dim->Opposite dim):
     313                 :            : //!  (Tri, 1->0), (Tri, 0->1), (Quad, 1->1), (Quad, 0->0),
     314                 :            : //!  (Tet, 2->0), (Tet, 1->1), (Tet, 0->2),
     315                 :            : //!  (Hex, 2->2), (Hex, 1->1)(diagonally across element), (Hex, 0->0) (diagonally across element)
     316                 :            : //! All other parent types and child dimensions return an error.
     317                 :            : //!
     318                 :            : //! \param parent_type The type of parent element
     319                 :            : //! \param child_type The type of child element
     320                 :            : //! \param child_index The index of the child element
     321                 :            : //! \param opposite_index The index of the opposite element
     322                 :            : //! \return status Returns 0 if successful, -1 if not
     323                 :         54 : short int CN::OppositeSide( const EntityType parent_type, const int child_index, const int child_dim,
     324                 :            :                             int& opposite_index, int& opposite_dim )
     325                 :            : {
     326   [ -  +  +  +  :         54 :     switch( parent_type )
                   +  - ]
     327                 :            :     {
     328                 :            :         case MBEDGE:
     329         [ #  # ]:          0 :             if( 0 != child_dim )
     330                 :          0 :                 return -1;
     331                 :            :             else
     332                 :          0 :                 opposite_index = 1 - child_index;
     333                 :          0 :             opposite_dim = 0;
     334                 :          0 :             break;
     335                 :            : 
     336                 :            :         case MBTRI:
     337      [ +  +  - ]:          6 :             switch( child_dim )
     338                 :            :             {
     339                 :            :                 case 0:
     340                 :          3 :                     opposite_dim   = 1;
     341                 :          3 :                     opposite_index = ( child_index + 1 ) % 3;
     342                 :          3 :                     break;
     343                 :            :                 case 1:
     344                 :          3 :                     opposite_dim   = 0;
     345                 :          3 :                     opposite_index = ( child_index + 2 ) % 3;
     346                 :          3 :                     break;
     347                 :            :                 default:
     348                 :          0 :                     return -1;
     349                 :            :             }
     350                 :          6 :             break;
     351                 :            : 
     352                 :            :         case MBQUAD:
     353         [ +  - ]:          8 :             switch( child_dim )
     354                 :            :             {
     355                 :            :                 case 0:
     356                 :            :                 case 1:
     357                 :          8 :                     opposite_dim   = child_dim;
     358                 :          8 :                     opposite_index = ( child_index + 2 ) % 4;
     359                 :          8 :                     break;
     360                 :            :                 default:
     361                 :          0 :                     return -1;
     362                 :            :             }
     363                 :          8 :             break;
     364                 :            : 
     365                 :            :         case MBTET:
     366   [ +  +  +  - ]:         14 :             switch( child_dim )
     367                 :            :             {
     368                 :            :                 case 0:
     369                 :          4 :                     opposite_dim   = 2;
     370                 :          4 :                     opposite_index = ( child_index + 1 ) % 3 + 2 * ( child_index / 3 );
     371                 :          4 :                     break;
     372                 :            :                 case 1:
     373                 :          6 :                     opposite_dim   = 1;
     374         [ +  + ]:          6 :                     opposite_index = child_index < 3 ? 3 + ( child_index + 2 ) % 3 : ( child_index + 1 ) % 3;
     375                 :          6 :                     break;
     376                 :            :                 case 2:
     377                 :          4 :                     opposite_dim   = 0;
     378                 :          4 :                     opposite_index = ( child_index + 2 ) % 3 + child_index / 3;
     379                 :          4 :                     break;
     380                 :            :                 default:
     381                 :          0 :                     return -1;
     382                 :            :             }
     383                 :         14 :             break;
     384                 :            :         case MBHEX:
     385                 :         26 :             opposite_dim = child_dim;
     386   [ +  +  +  - ]:         26 :             switch( child_dim )
     387                 :            :             {
     388                 :            :                 case 0:
     389         [ +  + ]:          8 :                     opposite_index = child_index < 4 ? 4 + ( child_index + 2 ) % 4 : ( child_index - 2 ) % 4;
     390                 :          8 :                     break;
     391                 :            :                 case 1:
     392                 :         12 :                     opposite_index = 4 * ( 2 - child_index / 4 ) + ( child_index + 2 ) % 4;
     393                 :         12 :                     break;
     394                 :            :                 case 2:
     395         [ +  + ]:          6 :                     opposite_index = child_index < 4 ? ( child_index + 2 ) % 4 : 9 - child_index;
     396                 :          6 :                     break;
     397                 :            :                 default:
     398                 :          0 :                     return -1;
     399                 :            :             }
     400                 :         26 :             break;
     401                 :            : 
     402                 :            :         default:
     403                 :          0 :             return -1;
     404                 :            :     }
     405                 :            : 
     406                 :         54 :     return 0;
     407                 :            : }
     408                 :            : 
     409                 :            : template < typename T >
     410                 :      31807 : inline bool connectivity_match( const T* conn1_i, const T* conn2_i, const int num_vertices, int& direct, int& offset )
     411                 :            : {
     412                 :            : 
     413                 :            :     bool they_match;
     414                 :            : 
     415                 :            :     // special test for 2 handles, since we don't want to wrap the list in this
     416                 :            :     // case
     417 [ #  # ][ #  # ]:      31807 :     if( num_vertices == 2 )
         [ +  + ][ #  # ]
         [ #  # ][ +  + ]
     418                 :            :     {
     419                 :      23258 :         they_match = false;
     420 [ #  # ][ #  # ]:      23258 :         if( conn1_i[0] == conn2_i[0] && conn1_i[1] == conn2_i[1] )
         [ #  # ][ #  # ]
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ +  + ][ +  + ]
     421                 :            :         {
     422                 :       3872 :             direct     = 1;
     423                 :       3872 :             they_match = true;
     424                 :       3872 :             offset     = 0;
     425                 :            :         }
     426 [ #  # ][ #  # ]:      19386 :         else if( conn1_i[0] == conn2_i[1] && conn1_i[1] == conn2_i[0] )
         [ #  # ][ #  # ]
         [ +  - ][ +  - ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ +  + ][ +  + ]
     427                 :            :         {
     428                 :       2989 :             they_match = true;
     429                 :       2989 :             direct     = -1;
     430                 :      23258 :             offset     = 1;
     431                 :            :         }
     432                 :            :     }
     433                 :            : 
     434                 :            :     else
     435                 :            :     {
     436                 :            :         const T* iter;
     437                 :       8549 :         iter = std::find( &conn2_i[0], &conn2_i[num_vertices], conn1_i[0] );
     438 [ #  # ][ #  # ]:       8549 :         if( iter == &conn2_i[num_vertices] ) return false;
         [ +  + ][ #  # ]
         [ #  # ][ +  + ]
     439                 :            : 
     440                 :       5061 :         they_match = true;
     441                 :            : 
     442                 :       5061 :         offset = iter - conn2_i;
     443                 :            :         int i;
     444                 :            : 
     445                 :            :         // first compare forward
     446 [ #  # ][ #  # ]:      10163 :         for( i = 1; i < num_vertices; ++i )
         [ +  + ][ #  # ]
         [ #  # ][ +  + ]
     447                 :            :         {
     448 [ #  # ][ #  # ]:       8536 :             if( conn1_i[i] != conn2_i[( offset + i ) % num_vertices] )
         [ +  + ][ #  # ]
         [ #  # ][ +  + ]
     449                 :            :             {
     450                 :       3434 :                 they_match = false;
     451                 :       3434 :                 break;
     452                 :            :             }
     453                 :            :         }
     454                 :            : 
     455 [ #  # ][ #  # ]:       5061 :         if( they_match == true )
         [ +  + ][ #  # ]
         [ #  # ][ +  + ]
     456                 :            :         {
     457                 :       1627 :             direct = 1;
     458                 :       1627 :             return they_match;
     459                 :            :         }
     460                 :            : 
     461                 :       3434 :         they_match = true;
     462                 :            : 
     463                 :            :         // then compare reverse
     464 [ #  # ][ #  # ]:       6375 :         for( i = 1; i < num_vertices; i++ )
         [ +  + ][ #  # ]
         [ #  # ][ +  + ]
     465                 :            :         {
     466 [ #  # ][ #  # ]:       5640 :             if( conn1_i[i] != conn2_i[( offset + num_vertices - i ) % num_vertices] )
         [ +  + ][ #  # ]
         [ #  # ][ +  + ]
     467                 :            :             {
     468                 :       2699 :                 they_match = false;
     469                 :       2699 :                 break;
     470                 :            :             }
     471                 :            :         }
     472 [ #  # ][ #  # ]:       3434 :         if( they_match ) { direct = -1; }
         [ +  + ][ #  # ]
         [ #  # ][ +  + ]
     473                 :            :     }
     474                 :            : 
     475                 :      26692 :     return they_match;
     476                 :            : }
     477                 :            : 
     478                 :      30180 : bool CN::ConnectivityMatch( const int* conn1_i, const int* conn2_i, const int num_vertices, int& direct, int& offset )
     479                 :            : {
     480                 :      30180 :     return connectivity_match< int >( conn1_i, conn2_i, num_vertices, direct, offset );
     481                 :            : }
     482                 :            : 
     483                 :          0 : bool CN::ConnectivityMatch( const unsigned int* conn1_i, const unsigned int* conn2_i, const int num_vertices,
     484                 :            :                             int& direct, int& offset )
     485                 :            : {
     486                 :          0 :     return connectivity_match< unsigned int >( conn1_i, conn2_i, num_vertices, direct, offset );
     487                 :            : }
     488                 :            : 
     489                 :          0 : bool CN::ConnectivityMatch( const long* conn1_i, const long* conn2_i, const int num_vertices, int& direct, int& offset )
     490                 :            : {
     491                 :          0 :     return connectivity_match< long >( conn1_i, conn2_i, num_vertices, direct, offset );
     492                 :            : }
     493                 :            : 
     494                 :       1627 : bool CN::ConnectivityMatch( const unsigned long* conn1_i, const unsigned long* conn2_i, const int num_vertices,
     495                 :            :                             int& direct, int& offset )
     496                 :            : {
     497                 :       1627 :     return connectivity_match< unsigned long >( conn1_i, conn2_i, num_vertices, direct, offset );
     498                 :            : }
     499                 :            : 
     500                 :          0 : bool CN::ConnectivityMatch( const unsigned long long* conn1_i, const unsigned long long* conn2_i,
     501                 :            :                             const int num_vertices, int& direct, int& offset )
     502                 :            : {
     503                 :          0 :     return connectivity_match< unsigned long long >( conn1_i, conn2_i, num_vertices, direct, offset );
     504                 :            : }
     505                 :            : 
     506                 :          0 : bool CN::ConnectivityMatch( void* const* conn1_i, void* const* conn2_i, const int num_vertices, int& direct,
     507                 :            :                             int& offset )
     508                 :            : {
     509                 :          0 :     return connectivity_match< void* >( conn1_i, conn2_i, num_vertices, direct, offset );
     510                 :            : }
     511                 :            : 
     512                 :            : //! for an entity of this type and a specified subfacet (dimension and index), return
     513                 :            : //! the index of the higher order node for that entity in this entity's connectivity array
     514                 :       3596 : short int CN::HONodeIndex( const EntityType this_type, const int num_verts, const int subfacet_dim,
     515                 :            :                            const int subfacet_index )
     516                 :            : {
     517                 :            :     int i;
     518                 :            :     int has_mids[4];
     519         [ +  - ]:       3596 :     HasMidNodes( this_type, num_verts, has_mids );
     520                 :            : 
     521                 :            :     // if we have no mid nodes on the subfacet_dim, we have no index
     522 [ +  - ][ -  + ]:       3596 :     if( subfacet_index != -1 && !has_mids[subfacet_dim] ) return -1;
     523                 :            : 
     524                 :            :     // put start index at last index (one less than the number of vertices
     525                 :            :     // plus the index basis)
     526         [ +  - ]:       3596 :     int index = VerticesPerEntity( this_type ) - 1 + numberBasis;
     527                 :            : 
     528                 :            :     // for each subfacet dimension less than the target subfacet dim which has mid nodes,
     529                 :            :     // add the number of subfacets of that dimension to the index
     530         [ +  + ]:       4256 :     for( i = 1; i < subfacet_dim; i++ )
     531 [ +  + ][ +  - ]:        660 :         if( has_mids[i] ) index += NumSubEntities( this_type, i );
     532                 :            : 
     533                 :            :     // now add the index of this subfacet, or one if we're asking about the entity as a whole
     534 [ -  + ][ #  # ]:       3596 :     if( subfacet_index == -1 && has_mids[subfacet_dim] )
     535                 :            :         // want the index of the last ho node on this subfacet
     536         [ #  # ]:          0 :         index += NumSubEntities( this_type, subfacet_dim );
     537                 :            : 
     538 [ +  - ][ +  - ]:       3596 :     else if( subfacet_index != -1 && has_mids[subfacet_dim] )
     539                 :       3596 :         index += subfacet_index + 1 - numberBasis;
     540                 :            : 
     541                 :            :     // that's it
     542                 :       3596 :     return index;
     543                 :            : }
     544                 :            : 
     545                 :            : //! given data about an element and a vertex in that element, return the dimension
     546                 :            : //! and index of the sub-entity that the vertex resolves.  If it does not resolve a
     547                 :            : //! sub-entity, either because it's a corner node or it's not in the element, -1 is
     548                 :            : //! returned in both return values
     549                 :        431 : void CN::HONodeParent( EntityType elem_type, int num_verts, int ho_index, int& parent_dim, int& parent_index )
     550                 :            : {
     551                 :            :     // begin with error values
     552                 :        431 :     parent_dim = parent_index = -1;
     553                 :            : 
     554                 :            :     // given the number of verts and the element type, get the hasmidnodes solution
     555                 :            :     int has_mids[4];
     556         [ +  - ]:        431 :     HasMidNodes( elem_type, num_verts, has_mids );
     557                 :            : 
     558         [ +  - ]:        431 :     int index     = VerticesPerEntity( elem_type ) - 1;
     559         [ +  - ]:        431 :     const int dim = Dimension( elem_type );
     560                 :            : 
     561                 :            :     // keep a running sum of the ho node indices for this type of element, and stop
     562                 :            :     // when you get to the dimension which has the ho node
     563         [ +  + ]:        547 :     for( int i = 1; i < dim; i++ )
     564                 :            :     {
     565         [ +  + ]:        527 :         if( has_mids[i] )
     566                 :            :         {
     567 [ +  - ][ +  + ]:        469 :             if( ho_index <= index + NumSubEntities( elem_type, i ) )
     568                 :            :             {
     569                 :            :                 // the ho_index resolves an entity of dimension i, so set the return values
     570                 :            :                 // and break out of the loop
     571                 :        411 :                 parent_dim   = i;
     572                 :        411 :                 parent_index = ho_index - index - 1;
     573                 :        431 :                 return;
     574                 :            :             }
     575                 :            :             else
     576                 :            :             {
     577         [ +  - ]:         58 :                 index += NumSubEntities( elem_type, i );
     578                 :            :             }
     579                 :            :         }
     580                 :            :     }
     581                 :            : 
     582                 :            :     // mid region node case
     583 [ +  - ][ +  - ]:         20 :     if( has_mids[dim] && ho_index == index + 1 )
     584                 :            :     {
     585                 :         20 :         parent_dim   = dim;
     586                 :         20 :         parent_index = 0;
     587                 :            :     }
     588                 :            : }
     589                 :            : 
     590                 :       4353 : const char* CN::EntityTypeName( const EntityType this_type )
     591                 :            : {
     592                 :       4353 :     return entityTypeNames[this_type];
     593                 :            : }
     594                 :            : 
     595                 :            : }  // namespace moab
     596                 :            : 
     597                 :            : using moab::CN;
     598                 :            : using moab::EntityType;
     599                 :            : 
     600                 :            : //! get the basis of the numbering system
     601                 :          0 : void MBCN_GetBasis( int* rval )
     602                 :            : {
     603                 :          0 :     *rval = CN::GetBasis();
     604                 :          0 : }
     605                 :            : 
     606                 :            : //! set the basis of the numbering system
     607                 :          0 : void MBCN_SetBasis( const int in_basis )
     608                 :            : {
     609                 :          0 :     CN::SetBasis( in_basis );
     610                 :          0 : }
     611                 :            : 
     612                 :            : //! return the string type name for this type
     613                 :          0 : void MBCN_EntityTypeName( const int this_type, char* rval, int rval_len )
     614                 :            : {
     615                 :          0 :     const char* rval_tmp = CN::EntityTypeName( (EntityType)this_type );
     616                 :          0 :     int rval_len_tmp     = strlen( rval_tmp );
     617         [ #  # ]:          0 :     rval_len_tmp         = ( rval_len_tmp < rval_len ? rval_len_tmp : rval_len );
     618                 :          0 :     strncpy( rval, rval_tmp, rval_len_tmp );
     619                 :          0 : }
     620                 :            : 
     621                 :            : //! given a name, find the corresponding entity type
     622                 :          0 : void MBCN_EntityTypeFromName( const char* name, int* rval )
     623                 :            : {
     624                 :          0 :     *rval = CN::EntityTypeFromName( name );
     625                 :          0 : }
     626                 :            : 
     627                 :            : //! return the topological entity dimension
     628                 :          0 : void MBCN_Dimension( const int t, int* rval )
     629                 :            : {
     630                 :          0 :     *rval = CN::Dimension( (EntityType)t );
     631                 :          0 : }
     632                 :            : 
     633                 :            : //! return the number of (corner) vertices contained in the specified type.
     634                 :          0 : void MBCN_VerticesPerEntity( const int t, int* rval )
     635                 :            : {
     636                 :          0 :     *rval = CN::VerticesPerEntity( (EntityType)t );
     637                 :          0 : }
     638                 :            : 
     639                 :            : //! return the number of sub-entities bounding the entity.
     640                 :          0 : void MBCN_NumSubEntities( const int t, const int d, int* rval )
     641                 :            : {
     642                 :          0 :     *rval = CN::NumSubEntities( (EntityType)t, d );
     643                 :          0 : }
     644                 :            : 
     645                 :            : //! return the type of a particular sub-entity.
     646                 :            : //! \param this_type Type of entity for which sub-entity type is being queried
     647                 :            : //! \param sub_dimension Topological dimension of sub-entity whose type is being queried
     648                 :            : //! \param index Index of sub-entity whose type is being queried
     649                 :            : //! \return type Entity type of sub-entity with specified dimension and index
     650                 :          0 : void MBCN_SubEntityType( const int this_type, const int sub_dimension, const int index, int* rval )
     651                 :            : 
     652                 :            : {
     653                 :            : 
     654                 :          0 :     *rval = CN::SubEntityType( (EntityType)this_type, sub_dimension, index );
     655                 :          0 : }
     656                 :            : 
     657                 :            : //! return the vertex indices of the specified sub-entity.
     658                 :            : //! \param this_type Type of entity for which sub-entity connectivity is being queried
     659                 :            : //! \param sub_dimension Dimension of sub-entity
     660                 :            : //! \param sub_index Index of sub-entity
     661                 :            : //! \param sub_entity_conn Connectivity of sub-entity (returned to calling function)
     662                 :          0 : void MBCN_SubEntityVertexIndices( const int this_type, const int sub_dimension, const int sub_index,
     663                 :            :                                   int sub_entity_conn[] )
     664                 :            : {
     665                 :          0 :     CN::SubEntityVertexIndices( (EntityType)this_type, sub_dimension, sub_index, sub_entity_conn );
     666                 :          0 : }
     667                 :            : 
     668                 :            : //! return the vertices of the specified sub entity
     669                 :            : //! \param parent_conn Connectivity of parent entity
     670                 :            : //! \param parent_type Entity type of parent entity
     671                 :            : //! \param sub_dimension Dimension of sub-entity being queried
     672                 :            : //! \param sub_index Index of sub-entity being queried
     673                 :            : //! \param sub_entity_conn Connectivity of sub-entity, based on parent_conn and canonical
     674                 :            : //!           ordering for parent_type
     675                 :            : //! \param num_sub_vertices Number of vertices in sub-entity
     676                 :            : //  void MBCN_SubEntityConn(const void *parent_conn, const int parent_type,
     677                 :            : //                            const int sub_dimension,
     678                 :            : //                            const int sub_index,
     679                 :            : //                            void *sub_entity_conn, int &num_sub_vertices) {return
     680                 :            : //                            CN::SubEntityConn();}
     681                 :            : 
     682                 :            : //! For a specified set of sides of given dimension, return the intersection
     683                 :            : //! or union of all sides of specified target dimension adjacent to those sides.
     684                 :            : //! \param this_type Type of entity for which sub-entity connectivity is being queried
     685                 :            : //! \param source_indices Indices of sides being queried
     686                 :            : //! \param num_source_indices Number of entries in <em>source_indices</em>
     687                 :            : //! \param source_dim Dimension of source entity
     688                 :            : //! \param target_dim Dimension of target entity
     689                 :            : //! \param index_list Indices of target entities (returned)
     690                 :            : //! \param num_indices Number of indices of target entities (returned)
     691                 :            : //! \param operation_type Specify either CN::INTERSECT (0) or CN::UNION (1) to get intersection
     692                 :            : //!        or union of target entity lists over source entities
     693                 :            : //! \param rval Error code indicating success or failure (returned)
     694                 :          0 : void MBCN_AdjacentSubEntities( const int this_type, const int* source_indices, const int num_source_indices,
     695                 :            :                                const int source_dim, const int target_dim, int* index_list, int* num_indices,
     696                 :            :                                const int operation_type, int* rval )
     697                 :            : {
     698         [ #  # ]:          0 :     std::vector< int > tmp_index_list;
     699                 :            :     *rval = CN::AdjacentSubEntities( (EntityType)this_type, source_indices, num_source_indices, source_dim, target_dim,
     700         [ #  # ]:          0 :                                      tmp_index_list, operation_type );
     701         [ #  # ]:          0 :     std::copy( tmp_index_list.begin(), tmp_index_list.end(), index_list );
     702                 :          0 :     *num_indices = tmp_index_list.size();
     703                 :          0 : }
     704                 :            : 
     705                 :            : //! return the side index represented in the input sub-entity connectivity
     706                 :            : //! \param parent_type Entity type of parent entity
     707                 :            : //! \param child_conn_indices Child connectivity to query, specified as indices
     708                 :            : //!                           into the connectivity list of the parent.
     709                 :            : //! \param child_num_verts Number of values in <em>child_conn_indices</em>
     710                 :            : //! \param child_dim Dimension of child entity being queried
     711                 :            : //! \param side_no Side number of child entity (returned)
     712                 :            : //! \param sense Sense of child entity with respect to order in <em>child_conn</em> (returned)
     713                 :            : //! \param offset Offset of <em>child_conn</em> with respect to canonical ordering data (returned)
     714                 :            : //! \return status Returns zero if successful, -1 if not
     715                 :          0 : void MBCN_SideNumber( const int parent_type, const int* child_conn_indices, const int child_num_verts,
     716                 :            :                       const int child_dim, int* side_no, int* sense, int* offset )
     717                 :            : {
     718                 :            :     CN::SideNumber( (EntityType)parent_type, child_conn_indices, child_num_verts, child_dim, *side_no, *sense,
     719                 :          0 :                     *offset );
     720                 :          0 : }
     721                 :            : 
     722                 :          0 : void MBCN_SideNumberInt( const int* parent_conn, const EntityType parent_type, const int* child_conn,
     723                 :            :                          const int child_num_verts, const int child_dim, int* side_no, int* sense, int* offset )
     724                 :            : {
     725                 :          0 :     moab::side_number( parent_conn, parent_type, child_conn, child_num_verts, child_dim, *side_no, *sense, *offset );
     726                 :          0 : }
     727                 :            : 
     728                 :          0 : void MBCN_SideNumberUint( const unsigned int* parent_conn, const EntityType parent_type, const unsigned int* child_conn,
     729                 :            :                           const int child_num_verts, const int child_dim, int* side_no, int* sense, int* offset )
     730                 :            : {
     731                 :          0 :     moab::side_number( parent_conn, parent_type, child_conn, child_num_verts, child_dim, *side_no, *sense, *offset );
     732                 :          0 : }
     733                 :            : 
     734                 :          0 : void MBCN_SideNumberLong( const long* parent_conn, const EntityType parent_type, const long* child_conn,
     735                 :            :                           const int child_num_verts, const int child_dim, int* side_no, int* sense, int* offset )
     736                 :            : {
     737                 :          0 :     moab::side_number( parent_conn, parent_type, child_conn, child_num_verts, child_dim, *side_no, *sense, *offset );
     738                 :          0 : }
     739                 :            : 
     740                 :          0 : void MBCN_SideNumberUlong( const unsigned long* parent_conn, const EntityType parent_type,
     741                 :            :                            const unsigned long* child_conn, const int child_num_verts, const int child_dim,
     742                 :            :                            int* side_no, int* sense, int* offset )
     743                 :            : {
     744                 :          0 :     moab::side_number( parent_conn, parent_type, child_conn, child_num_verts, child_dim, *side_no, *sense, *offset );
     745                 :          0 : }
     746                 :            : 
     747                 :          0 : void MBCN_SideNumberVoid( void* const* parent_conn, const EntityType parent_type, void* const* child_conn,
     748                 :            :                           const int child_num_verts, const int child_dim, int* side_no, int* sense, int* offset )
     749                 :            : {
     750                 :          0 :     moab::side_number( parent_conn, parent_type, child_conn, child_num_verts, child_dim, *side_no, *sense, *offset );
     751                 :          0 : }
     752                 :            : 
     753                 :            : //! return the dimension and index of the opposite side, given parent entity type and child
     754                 :            : //! dimension and index.  This function is only defined for certain types of parent/child types:
     755                 :            : //! (Parent, Child dim->Opposite dim):
     756                 :            : //!  (Tri, 1->0), (Tri, 0->1), (Quad, 1->1), (Quad, 0->0),
     757                 :            : //!  (Tet, 2->0), (Tet, 1->1), (Tet, 0->2),
     758                 :            : //!  (Hex, 2->2), (Hex, 1->1)(diagonally across element), (Hex, 0->0) (diagonally across element)
     759                 :            : //! All other parent types and child dimensions return an error.
     760                 :            : //!
     761                 :            : //! \param parent_type The type of parent element
     762                 :            : //! \param child_type The type of child element
     763                 :            : //! \param child_index The index of the child element
     764                 :            : //! \param opposite_index The index of the opposite element
     765                 :            : //! \return status Returns 0 if successful, -1 if not
     766                 :          0 : void MBCN_OppositeSide( const int parent_type, const int child_index, const int child_dim, int* opposite_index,
     767                 :            :                         int* opposite_dim, int* rval )
     768                 :            : {
     769                 :          0 :     *rval = CN::OppositeSide( (EntityType)parent_type, child_index, child_dim, *opposite_index, *opposite_dim );
     770                 :          0 : }
     771                 :            : 
     772                 :            : //! given two connectivity arrays, determine whether or not they represent the same entity.
     773                 :            : //! \param conn1 Connectivity array of first entity
     774                 :            : //! \param conn2 Connectivity array of second entity
     775                 :            : //! \param num_vertices Number of entries in <em>conn1</em> and <em>conn2</em>
     776                 :            : //! \param direct If positive, entities have the same sense (returned)
     777                 :            : //! \param offset Offset of <em>conn2</em>'s first vertex in <em>conn1</em>
     778                 :            : //! \return rval Returns true if <em>conn1</em> and <em>conn2</em> match
     779                 :          0 : void MBCN_ConnectivityMatchInt( const int* conn1, const int* conn2, const int num_vertices, int* direct, int* offset,
     780                 :            :                                 int* rval )
     781                 :            : {
     782                 :          0 :     *rval = CN::ConnectivityMatch( conn1, conn2, num_vertices, *direct, *offset );
     783                 :          0 : }
     784                 :            : 
     785                 :          0 : void MBCN_ConnectivityMatchUint( const unsigned int* conn1, const unsigned int* conn2, const int num_vertices,
     786                 :            :                                  int* direct, int* offset, int* rval )
     787                 :            : {
     788                 :          0 :     *rval = CN::ConnectivityMatch( conn1, conn2, num_vertices, *direct, *offset );
     789                 :          0 : }
     790                 :            : 
     791                 :          0 : void MBCN_ConnectivityMatchLong( const long* conn1, const long* conn2, const int num_vertices, int* direct, int* offset,
     792                 :            :                                  int* rval )
     793                 :            : {
     794                 :          0 :     *rval = CN::ConnectivityMatch( conn1, conn2, num_vertices, *direct, *offset );
     795                 :          0 : }
     796                 :            : 
     797                 :          0 : void MBCN_ConnectivityMatchUlong( const unsigned long* conn1, const unsigned long* conn2, const int num_vertices,
     798                 :            :                                   int* direct, int* offset, int* rval )
     799                 :            : {
     800                 :          0 :     *rval = CN::ConnectivityMatch( conn1, conn2, num_vertices, *direct, *offset );
     801                 :          0 : }
     802                 :            : 
     803                 :          0 : void MBCN_ConnectivityMatchVoid( void* const* conn1, void* const* conn2, const int num_vertices, int* direct,
     804                 :            :                                  int* offset, int* rval )
     805                 :            : {
     806                 :          0 :     *rval = CN::ConnectivityMatch( conn1, conn2, num_vertices, *direct, *offset );
     807                 :          0 : }
     808                 :            : 
     809                 :            : //! true if entities of a given type and number of nodes indicates mid edge nodes are present.
     810                 :            : //! \param this_type Type of entity for which sub-entity connectivity is being queried
     811                 :            : //! \param num_verts Number of nodes defining entity
     812                 :            : //! \return int Returns true if <em>this_type</em> combined with <em>num_nodes</em> indicates
     813                 :            : //!  mid-edge nodes are likely
     814                 :          0 : void MBCN_HasMidEdgeNodes( const int this_type, const int num_verts, int* rval )
     815                 :            : {
     816                 :          0 :     *rval = CN::HasMidEdgeNodes( (EntityType)this_type, num_verts );
     817                 :          0 : }
     818                 :            : 
     819                 :            : //! true if entities of a given type and number of nodes indicates mid face nodes are present.
     820                 :            : //! \param this_type Type of entity for which sub-entity connectivity is being queried
     821                 :            : //! \param num_verts Number of nodes defining entity
     822                 :            : //! \return int Returns true if <em>this_type</em> combined with <em>num_nodes</em> indicates
     823                 :            : //!  mid-face nodes are likely
     824                 :          0 : void MBCN_HasMidFaceNodes( const int this_type, const int num_verts, int* rval )
     825                 :            : {
     826                 :          0 :     *rval = CN::HasMidFaceNodes( (EntityType)this_type, num_verts );
     827                 :          0 : }
     828                 :            : 
     829                 :            : //! true if entities of a given type and number of nodes indicates mid region nodes are present.
     830                 :            : //! \param this_type Type of entity for which sub-entity connectivity is being queried
     831                 :            : //! \param num_verts Number of nodes defining entity
     832                 :            : //! \return int Returns true if <em>this_type</em> combined with <em>num_nodes</em> indicates
     833                 :            : //!  mid-region nodes are likely
     834                 :          0 : void MBCN_HasMidRegionNodes( const int this_type, const int num_verts, int* rval )
     835                 :            : {
     836                 :          0 :     *rval = CN::HasMidRegionNodes( (EntityType)this_type, num_verts );
     837                 :          0 : }
     838                 :            : 
     839                 :            : //! true if entities of a given type and number of nodes indicates mid edge/face/region nodes
     840                 :            : //! are present.
     841                 :            : //! \param this_type Type of entity for which sub-entity connectivity is being queried
     842                 :            : //! \param num_verts Number of nodes defining entity
     843                 :            : //! \param mid_nodes If <em>mid_nodes[i], i=1..3</em> is true, indicates that mid-edge
     844                 :            : //!    (i=1), mid-face (i=2), and/or mid-region (i=3) nodes are likely
     845                 :          0 : void MBCN_HasMidNodes( const int this_type, const int num_verts, int mid_nodes[4] )
     846                 :            : {
     847                 :          0 :     return CN::HasMidNodes( (EntityType)this_type, num_verts, mid_nodes );
     848                 :            : }
     849                 :            : 
     850                 :            : //! given data about an element and a vertex in that element, return the dimension
     851                 :            : //! and index of the sub-entity that the vertex resolves.  If it does not resolve a
     852                 :            : //! sub-entity, either because it's a corner node or it's not in the element, -1 is
     853                 :            : //! returned in both return values.
     854                 :            : //! \param elem_type Type of entity being queried
     855                 :            : //! \param num_nodes The number of nodes in the element connectivity
     856                 :            : //! \param ho_node_index The position of the HO node in the connectivity list (zero based)
     857                 :            : //! \param parent_dim Dimension of sub-entity high-order node resolves (returned)
     858                 :            : //! \param parent_index Index of sub-entity high-order node resolves (returned)
     859                 :          0 : void MBCN_HONodeParent( int elem_type, int num_nodes, int ho_node_index, int* parent_dim, int* parent_index )
     860                 :            : {
     861                 :          0 :     return CN::HONodeParent( (EntityType)elem_type, num_nodes, ho_node_index, *parent_dim, *parent_index );
     862                 :            : }
     863                 :            : 
     864                 :            : //! for an entity of this type with num_verts vertices, and a specified subfacet
     865                 :            : //! (dimension and index), return the index of the higher order node for that entity
     866                 :            : //! in this entity's connectivity array
     867                 :            : //! \param this_type Type of entity being queried
     868                 :            : //! \param num_verts Number of vertices for the entity being queried
     869                 :            : //! \param subfacet_dim Dimension of sub-entity being queried
     870                 :            : //! \param subfacet_index Index of sub-entity being queried
     871                 :            : //! \return index Index of sub-entity's higher-order node
     872                 :          0 : void MBCN_HONodeIndex( const int this_type, const int num_verts, const int subfacet_dim, const int subfacet_index,
     873                 :            :                        int* rval )
     874                 :            : 
     875                 :            : {
     876                 :            : 
     877                 :          0 :     *rval = CN::HONodeIndex( (EntityType)this_type, num_verts, subfacet_dim, subfacet_index );
     878                 :          0 : }
     879                 :            : 
     880                 :            : namespace moab
     881                 :            : {
     882                 :            : 
     883                 :            : template < typename T >
     884                 :            : inline int permute_this( EntityType t, const int dim, T* conn, const int indices_per_ent, const int num_entries )
     885                 :            : {
     886                 :            :     T tmp_conn[MAX_SUB_ENTITIES];
     887                 :            :     assert( indices_per_ent <= CN::permuteVec[t][dim][MAX_SUB_ENTITIES] );
     888                 :            :     if( indices_per_ent > CN::permuteVec[t][dim][MAX_SUB_ENTITIES] ) return 1;
     889                 :            :     short int* tvec = CN::permuteVec[t][dim];
     890                 :            :     T* pvec         = conn;
     891                 :            :     for( int j = 0; j < num_entries; j++ )
     892                 :            :     {
     893                 :            :         for( int i = 0; i < indices_per_ent; i++ )
     894                 :            :             tmp_conn[tvec[i]] = pvec[i];
     895                 :            :         memcpy( pvec, tmp_conn, indices_per_ent * sizeof( T ) );
     896                 :            :         pvec += indices_per_ent;
     897                 :            :     }
     898                 :            : 
     899                 :            :     return 0;
     900                 :            : }
     901                 :            : 
     902                 :            : template < typename T >
     903                 :            : inline int rev_permute_this( EntityType t, const int dim, T* conn, const int indices_per_ent, const int num_entries )
     904                 :            : {
     905                 :            :     T tmp_conn[MAX_SUB_ENTITIES];
     906                 :            :     assert( indices_per_ent <= CN::revPermuteVec[t][dim][MAX_SUB_ENTITIES] );
     907                 :            :     if( indices_per_ent > CN::revPermuteVec[t][dim][MAX_SUB_ENTITIES] ) return 1;
     908                 :            :     short int* tvec = CN::revPermuteVec[t][dim];
     909                 :            :     T* pvec         = conn;
     910                 :            :     for( int j = 0; j < num_entries; j++ )
     911                 :            :     {
     912                 :            :         for( int i = 0; i < indices_per_ent; i++ )
     913                 :            :             tmp_conn[i] = pvec[tvec[i]];
     914                 :            :         memcpy( pvec, tmp_conn, indices_per_ent * sizeof( T ) );
     915                 :            :         pvec += indices_per_ent;
     916                 :            :     }
     917                 :            : 
     918                 :            :     return 0;
     919                 :            : }
     920                 :            : 
     921                 :    7934963 : short int CN::Dimension( const EntityType t )
     922                 :            : {
     923                 :    7934963 :     return mConnectivityMap[t][0].topo_dimension;
     924                 :            : }
     925                 :            : 
     926                 :   15156450 : short int CN::VerticesPerEntity( const EntityType t )
     927                 :            : {
     928                 :            :     return ( MBVERTEX == t
     929                 :            :                  ? (short int)1
     930         [ +  + ]:   15156450 :                  : mConnectivityMap[t][mConnectivityMap[t][0].topo_dimension - 1].num_corners_per_sub_element[0] );
     931                 :            : }
     932                 :            : 
     933                 :     546750 : short int CN::NumSubEntities( const EntityType t, const int d )
     934                 :            : {
     935         [ +  + ]:     546749 :     return ( t != MBVERTEX && d > 0 ? mConnectivityMap[t][d - 1].num_sub_elements
     936 [ +  + ][ +  - ]:    1093499 :                                     : ( d ? (short int)-1 : VerticesPerEntity( t ) ) );
     937                 :            : }
     938                 :            : 
     939                 :            : //! return the type of a particular sub-entity.
     940                 :     301713 : EntityType CN::SubEntityType( const EntityType this_type, const int sub_dimension, const int index )
     941                 :            : {
     942                 :            :     return ( !sub_dimension ? MBVERTEX
     943         [ -  + ]:     298432 :                             : ( Dimension( this_type ) == sub_dimension && 0 == index
     944                 :            :                                     ? this_type
     945   [ +  +  +  + ]:     600145 :                                     : mConnectivityMap[this_type][sub_dimension - 1].target_type[index] ) );
     946                 :            : }
     947                 :            : 
     948                 :     445186 : const short* CN::SubEntityVertexIndices( const EntityType this_type, const int sub_dimension, const int index,
     949                 :            :                                          EntityType& sub_type, int& n )
     950                 :            : {
     951         [ +  + ]:     445186 :     if( sub_dimension == 0 )
     952                 :            :     {
     953                 :       4353 :         n        = 1;
     954                 :       4353 :         sub_type = MBVERTEX;
     955                 :       4353 :         return increasingInts + index;
     956                 :            :     }
     957                 :            :     else
     958                 :            :     {
     959                 :     440833 :         const CN::ConnMap& map = mConnectivityMap[this_type][sub_dimension - 1];
     960                 :     440833 :         sub_type               = map.target_type[index];
     961                 :     440833 :         n                      = map.num_corners_per_sub_element[index];
     962                 :     440833 :         return map.conn[index];
     963                 :            :     }
     964                 :            : }
     965                 :            : 
     966                 :            : //! Permute this vector
     967                 :            : inline int CN::permuteThis( const EntityType t, const int dim, int* pvec, const int num_indices, const int num_entries )
     968                 :            : {
     969                 :            :     return permute_this( t, dim, pvec, num_indices, num_entries );
     970                 :            : }
     971                 :            : inline int CN::permuteThis( const EntityType t, const int dim, unsigned int* pvec, const int num_indices,
     972                 :            :                             const int num_entries )
     973                 :            : {
     974                 :            :     return permute_this( t, dim, pvec, num_indices, num_entries );
     975                 :            : }
     976                 :            : inline int CN::permuteThis( const EntityType t, const int dim, long* pvec, const int num_indices,
     977                 :            :                             const int num_entries )
     978                 :            : {
     979                 :            :     return permute_this( t, dim, pvec, num_indices, num_entries );
     980                 :            : }
     981                 :            : inline int CN::permuteThis( const EntityType t, const int dim, void** pvec, const int num_indices,
     982                 :            :                             const int num_entries )
     983                 :            : {
     984                 :            :     return permute_this( t, dim, pvec, num_indices, num_entries );
     985                 :            : }
     986                 :            : 
     987                 :            : //! Reverse permute this vector
     988                 :            : inline int CN::revPermuteThis( const EntityType t, const int dim, int* pvec, const int num_indices,
     989                 :            :                                const int num_entries )
     990                 :            : {
     991                 :            :     return rev_permute_this( t, dim, pvec, num_indices, num_entries );
     992                 :            : }
     993                 :            : inline int CN::revPermuteThis( const EntityType t, const int dim, unsigned int* pvec, const int num_indices,
     994                 :            :                                const int num_entries )
     995                 :            : {
     996                 :            :     return rev_permute_this( t, dim, pvec, num_indices, num_entries );
     997                 :            : }
     998                 :            : inline int CN::revPermuteThis( const EntityType t, const int dim, long* pvec, const int num_indices,
     999                 :            :                                const int num_entries )
    1000                 :            : {
    1001                 :            :     return rev_permute_this( t, dim, pvec, num_indices, num_entries );
    1002                 :            : }
    1003                 :            : inline int CN::revPermuteThis( const EntityType t, const int dim, void** pvec, const int num_indices,
    1004                 :            :                                const int num_entries )
    1005                 :            : {
    1006                 :            :     return rev_permute_this( t, dim, pvec, num_indices, num_entries );
    1007                 :            : }
    1008                 :            : 
    1009                 :            : }  // namespace moab

Generated by: LCOV version 1.11