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
|