Branch data Line data Source code
1 : : #include "moab/NestedRefine.hpp"
2 : : #include "moab/NestedRefineTemplates.hpp"
3 : : #include "moab/HalfFacetRep.hpp"
4 : : #include "moab/CpuTimer.hpp"
5 : : #include "moab/ReadUtilIface.hpp"
6 : : #include "Internals.hpp"
7 : : #include "MBTagConventions.hpp"
8 : :
9 : : #ifdef MOAB_HAVE_MPI
10 : : #include "moab/ParallelComm.hpp"
11 : : #include "moab/ParallelMergeMesh.hpp"
12 : : #include "moab/Skinner.hpp"
13 : : #endif
14 : :
15 : : #include <iostream>
16 : : #include <assert.h>
17 : : #include <vector>
18 : : #include <limits>
19 : : #include <cmath>
20 : :
21 : : namespace moab
22 : : {
23 : :
24 : 17 : NestedRefine::NestedRefine( Core* impl, ParallelComm* comm, EntityHandle rset )
25 [ + - ][ + - ]: 357 : : mbImpl( impl ), pcomm( comm ), _rset( rset )
[ + - ][ + - ]
[ + - ][ + +
# # # # #
# ]
26 : : {
27 : : ErrorCode error;
28 [ - + ]: 17 : assert( NULL != impl );
29 : :
30 : : #ifdef MOAB_HAVE_MPI
31 : : // Get the Parallel Comm instance to prepare all new sets to work in parallel
32 : : // in case the user did not provide any arguments
33 [ + + ][ + - ]: 17 : if( !comm ) pcomm = moab::ParallelComm::get_pcomm( mbImpl, 0 );
34 : : #endif
35 [ + - ]: 17 : error = initialize();
36 [ - + ]: 17 : if( error != MB_SUCCESS )
37 : : {
38 [ # # ][ # # ]: 0 : std::cout << "Error initializing NestedRefine\n" << std::endl;
39 : 0 : exit( 1 );
40 : : }
41 [ # # ]: 17 : }
42 : :
43 [ + - ][ + + ]: 374 : NestedRefine::~NestedRefine()
44 : : {
45 : : #ifdef MOAB_HAVE_AHF
46 : : ahf = NULL;
47 : : #else
48 [ + - ]: 17 : delete ahf;
49 : : #endif
50 : 17 : delete tm;
51 : 17 : }
52 : :
53 : 17 : ErrorCode NestedRefine::initialize()
54 : : {
55 : : ErrorCode error;
56 : :
57 [ + - ]: 17 : tm = new CpuTimer();
58 [ - + ]: 17 : if( !tm ) return MB_MEMORY_ALLOCATION_FAILED;
59 : :
60 : : #ifdef MOAB_HAVE_AHF
61 : : ahf = mbImpl->a_half_facet_rep();
62 : : #else
63 [ + - ]: 17 : ahf = new HalfFacetRep( mbImpl, pcomm, _rset, true );
64 [ - + ]: 17 : if( !ahf ) return MB_MEMORY_ALLOCATION_FAILED;
65 : : #endif
66 : :
67 : : // Check for mixed entity type
68 : 17 : bool chk_mixed = ahf->check_mixed_entity_type();
69 [ - + ][ # # ]: 17 : if( chk_mixed ) MB_SET_ERR( MB_NOT_IMPLEMENTED, "Encountered a mesh with mixed entity types" );
[ # # ][ # # ]
[ # # ][ # # ]
70 : :
71 [ - + ][ # # ]: 17 : error = ahf->initialize();MB_CHK_ERR( error );
72 [ - + ][ # # ]: 17 : error = ahf->get_entity_ranges( _inverts, _inedges, _infaces, _incells );MB_CHK_ERR( error );
73 : :
74 : : // Check for supported entity type
75 [ + + ]: 17 : if( !_incells.empty() )
76 : : {
77 : 6 : EntityType type = mbImpl->type_from_handle( _incells[0] );
78 [ + + ][ - + ]: 6 : if( type != MBTET && type != MBHEX )
79 [ # # ][ # # ]: 0 : MB_SET_ERR( MB_FAILURE, "Not supported 3D entity types: MBPRISM, MBPYRAMID, MBKNIFE, MBPOLYHEDRON" );
[ # # ][ # # ]
[ # # ]
80 : :
81 : 6 : meshdim = 3;
82 : 6 : elementype = type;
83 : : }
84 [ + + ]: 11 : else if( !_infaces.empty() )
85 : : {
86 : 8 : EntityType type = mbImpl->type_from_handle( _infaces[0] );
87 [ - + ][ # # ]: 8 : if( type == MBPOLYGON ) MB_SET_ERR( MB_FAILURE, "Not supported 2D entity type: POLYGON" );
[ # # ][ # # ]
[ # # ][ # # ]
88 : :
89 : 8 : meshdim = 2;
90 : 8 : elementype = type;
91 : : }
92 [ + - ]: 3 : else if( !_inedges.empty() )
93 : : {
94 : 3 : meshdim = 1;
95 : 3 : elementype = MBEDGE;
96 : : }
97 : : else
98 [ # # ][ # # ]: 0 : MB_SET_ERR( MB_NOT_IMPLEMENTED, "Encountered a mixed-dimensional or invalid mesh" );
[ # # ][ # # ]
[ # # ]
99 : :
100 : : // Initialize std::map to get indices of degrees.
101 [ + - ]: 17 : deg_index[2] = 0;
102 [ + - ]: 17 : deg_index[3] = 1;
103 [ + - ]: 17 : deg_index[5] = 2;
104 : :
105 : : // Set ghost flag to false
106 : 17 : hasghost = false;
107 : 17 : return MB_SUCCESS;
108 : : }
109 : :
110 : : /************************************************************
111 : : * Interface Functions *
112 : : ************************************************************/
113 : :
114 : 17 : ErrorCode NestedRefine::generate_mesh_hierarchy( int num_level, int* level_degrees,
115 : : std::vector< EntityHandle >& level_sets, bool optimize )
116 : : {
117 [ - + ]: 17 : assert( num_level > 0 );
118 : 17 : nlevels = num_level;
119 : :
120 : : ErrorCode error;
121 [ + - ]: 17 : std::vector< moab::EntityHandle > hmsets( num_level );
122 : :
123 [ + + ]: 17 : if( meshdim <= 2 )
124 : : {
125 [ + + ]: 43 : for( int i = 0; i < num_level; i++ )
126 : : {
127 [ + + ][ + + ]: 32 : assert( ( level_degrees[i] == 2 ) || ( level_degrees[i] == 3 ) || ( level_degrees[i] == 5 ) );
[ - + ]
128 : 32 : level_dsequence[i] = level_degrees[i];
129 : : }
130 : : }
131 : : else
132 : : {
133 [ + + ]: 22 : for( int i = 0; i < num_level; i++ )
134 : : {
135 [ + + ][ - + ]: 16 : assert( ( level_degrees[i] == 2 ) || ( level_degrees[i] == 3 ) );
136 : 16 : level_dsequence[i] = level_degrees[i];
137 : : }
138 : : }
139 : :
140 [ + - ][ + - ]: 17 : error = generate_hm( level_degrees, num_level, &hmsets[0], optimize );MB_CHK_ERR( error );
[ - + ][ # # ]
[ # # ]
141 : :
142 : : // copy the entity handles
143 [ + - ]: 17 : level_sets.resize( num_level + 1 );
144 [ + - ]: 17 : level_sets[0] = _rset;
145 [ + + ]: 65 : for( int i = 0; i < num_level; i++ )
146 [ + - ][ + - ]: 48 : level_sets[i + 1] = hmsets[i];
147 : :
148 : 17 : return MB_SUCCESS;
149 : : }
150 : :
151 : 85046 : ErrorCode NestedRefine::get_connectivity( EntityHandle ent, int level, std::vector< EntityHandle >& conn )
152 : : {
153 : : ErrorCode error;
154 : 85046 : EntityType type = mbImpl->type_from_handle( ent );
155 : : EntityHandle start_ent;
156 [ - + ]: 85046 : if( !conn.empty() ) conn.clear();
157 [ + + ]: 85046 : if( level > 0 )
158 : : {
159 [ + + ]: 83524 : if( type == MBEDGE )
160 : : {
161 : 1684 : conn.reserve( 2 );
162 : 1684 : start_ent = level_mesh[level - 1].start_edge;
163 : 1684 : EntityID offset = ID_FROM_HANDLE( ent ) - ID_FROM_HANDLE( start_ent );
164 : 1684 : conn.push_back( level_mesh[level - 1].edge_conn[2 * offset] );
165 : 1684 : conn.push_back( level_mesh[level - 1].edge_conn[2 * offset + 1] );
166 : : }
167 [ + + ][ + + ]: 81840 : else if( type == MBTRI || type == MBQUAD )
168 : : {
169 : 29763 : int num_corners = ahf->lConnMap2D[type - 2].num_verts_in_face;
170 : 29763 : conn.reserve( num_corners );
171 : 29763 : start_ent = level_mesh[level - 1].start_face;
172 : 29763 : EntityID offset = ID_FROM_HANDLE( ent ) - ID_FROM_HANDLE( start_ent );
173 : :
174 [ + + ]: 122660 : for( int i = 0; i < num_corners; i++ )
175 : 122660 : conn.push_back( level_mesh[level - 1].face_conn[num_corners * offset + i] );
176 : : }
177 [ + + ][ + - ]: 52077 : else if( type == MBTET || type == MBHEX )
178 : : {
179 [ + - ][ + - ]: 52077 : int index = ahf->get_index_in_lmap( *_incells.begin() );
180 : 52077 : int num_corners = ahf->lConnMap3D[index].num_verts_in_cell;
181 : 52077 : conn.reserve( num_corners );
182 : 52077 : start_ent = level_mesh[level - 1].start_cell;
183 : 52077 : EntityID offset = ID_FROM_HANDLE( ent ) - ID_FROM_HANDLE( start_ent );
184 [ + + ]: 386429 : for( int i = 0; i < num_corners; i++ )
185 : 386429 : conn.push_back( level_mesh[level - 1].cell_conn[num_corners * offset + i] );
186 : : }
187 : : else
188 [ # # ][ # # ]: 83524 : MB_SET_ERR( MB_FAILURE, "Requesting connectivity for an unsupported entity type" );
[ # # ][ # # ]
[ # # ]
189 : : }
190 : : else
191 : : {
192 [ - + ][ # # ]: 1522 : error = mbImpl->get_connectivity( &ent, 1, conn );MB_CHK_ERR( error );
193 : : }
194 : :
195 : 85046 : return MB_SUCCESS;
196 : : }
197 : :
198 : 10314 : ErrorCode NestedRefine::get_coordinates( EntityHandle* verts, int num_verts, int level, double* coords )
199 : : {
200 [ + - ]: 10314 : if( level > 0 )
201 : : {
202 : 10314 : EntityID vstart = ID_FROM_HANDLE( level_mesh[level - 1].start_vertex );
203 [ + + ]: 56113 : for( int i = 0; i < num_verts; i++ )
204 : : {
205 : 45799 : const EntityHandle& vid = verts[i];
206 : 45799 : EntityID offset = ID_FROM_HANDLE( vid ) - vstart;
207 : 45799 : coords[3 * i] = level_mesh[level - 1].coordinates[0][offset];
208 : 45799 : coords[3 * i + 1] = level_mesh[level - 1].coordinates[1][offset];
209 : 45799 : coords[3 * i + 2] = level_mesh[level - 1].coordinates[2][offset];
210 : : }
211 : : }
212 : : else
213 : : {
214 : : ErrorCode error;
215 [ # # ][ # # ]: 0 : error = mbImpl->get_coords( verts, num_verts, coords );MB_CHK_ERR( error );
216 : : }
217 : :
218 : 10314 : return MB_SUCCESS;
219 : : }
220 : :
221 : 105164 : ErrorCode NestedRefine::get_adjacencies( const EntityHandle source_entity, const unsigned int target_dimension,
222 : : std::vector< EntityHandle >& target_entities )
223 : :
224 : : {
225 : : ErrorCode error;
226 [ - + ][ # # ]: 105164 : error = ahf->get_adjacencies( source_entity, target_dimension, target_entities );MB_CHK_ERR( error );
227 : :
228 : 105164 : return MB_SUCCESS;
229 : : }
230 : :
231 : 111824 : ErrorCode NestedRefine::child_to_parent( EntityHandle child, int child_level, int parent_level, EntityHandle* parent )
232 : : {
233 [ + - ][ - + ]: 111824 : assert( ( child_level > 0 ) && ( child_level > parent_level ) );
234 : 111824 : EntityType type = mbImpl->type_from_handle( child );
235 [ - + ]: 111824 : assert( type != MBVERTEX );
236 : :
237 : : int child_index;
238 [ - + ]: 111824 : if( type == MBEDGE )
239 : 0 : child_index = child - level_mesh[child_level - 1].start_edge;
240 [ + + ][ + + ]: 111824 : else if( type == MBTRI || type == MBQUAD )
241 : 37216 : child_index = child - level_mesh[child_level - 1].start_face;
242 [ + + ][ + - ]: 74608 : else if( type == MBTET || type == MBHEX )
243 : 74608 : child_index = child - level_mesh[child_level - 1].start_cell;
244 : : else
245 [ # # ][ # # ]: 0 : MB_SET_ERR( MB_FAILURE, "Requesting parent for unsupported entity type" );
[ # # ][ # # ]
[ # # ]
246 : :
247 : : int parent_index;
248 : 111824 : int l = child_level - parent_level;
249 [ + + ]: 361464 : for( int i = 0; i < l; i++ )
250 : : {
251 : 249640 : int d = get_index_from_degree( level_dsequence[child_level - i - 1] );
252 : 249640 : int nch = refTemplates[type - 1][d].total_new_ents;
253 : 249640 : child_index = child_index / nch;
254 : : }
255 : 111824 : parent_index = child_index;
256 : :
257 [ - + ]: 111824 : if( type == MBEDGE )
258 : : {
259 [ # # ]: 0 : if( parent_level > 0 )
260 : 0 : *parent = level_mesh[parent_level - 1].start_edge + parent_index;
261 : : else
262 : 0 : *parent = _inedges[parent_index];
263 : : }
264 [ + + ][ + + ]: 111824 : else if( type == MBTRI || type == MBQUAD )
265 : : {
266 [ + + ]: 74432 : if( parent_level > 0 )
267 : 16976 : *parent = level_mesh[parent_level - 1].start_face + parent_index;
268 : : else
269 : 20240 : *parent = _infaces[parent_index];
270 : : }
271 [ + + ][ + - ]: 74608 : else if( type == MBTET || type == MBHEX )
272 : : {
273 [ + + ]: 74608 : if( parent_level > 0 )
274 : 39536 : *parent = level_mesh[parent_level - 1].start_cell + parent_index;
275 : : else
276 : 35072 : *parent = _incells[parent_index];
277 : : }
278 : :
279 : 111824 : return MB_SUCCESS;
280 : : }
281 : :
282 : 6000 : ErrorCode NestedRefine::parent_to_child( EntityHandle parent, int parent_level, int child_level,
283 : : std::vector< EntityHandle >& children )
284 : : {
285 [ + - ][ - + ]: 6000 : assert( ( child_level > 0 ) && ( child_level > parent_level ) );
286 : 6000 : EntityType type = mbImpl->type_from_handle( parent );
287 [ - + ]: 6000 : assert( type != MBVERTEX );
288 : :
289 : : int parent_index;
290 [ - + ]: 6000 : if( type == MBEDGE )
291 : : {
292 [ # # ]: 0 : if( parent_level > 0 )
293 : 0 : parent_index = parent - level_mesh[parent_level - 1].start_edge;
294 : : else
295 : 0 : parent_index = _inedges.index( parent );
296 : : }
297 [ + + ][ + + ]: 6000 : else if( type == MBTRI || type == MBQUAD )
298 : : {
299 [ + + ]: 2424 : if( parent_level > 0 )
300 : 1140 : parent_index = parent - level_mesh[parent_level - 1].start_face;
301 : : else
302 : 72 : parent_index = _infaces.index( parent );
303 : : }
304 [ + + ][ + - ]: 4788 : else if( type == MBTET || type == MBHEX )
305 : : {
306 [ + + ]: 9576 : if( parent_level > 0 )
307 : 4752 : parent_index = parent - level_mesh[parent_level - 1].start_cell;
308 : : else
309 : 36 : parent_index = _incells.index( parent );
310 : : }
311 : : else
312 [ # # ][ # # ]: 0 : MB_SET_ERR( MB_FAILURE, "Requesting children for unsupported entity type" );
[ # # ][ # # ]
[ # # ]
313 : :
314 : : int start, end;
315 : 6000 : start = end = parent_index;
316 [ + + ]: 12086 : for( int i = parent_level; i < child_level; i++ )
317 : : {
318 : 6086 : int d = get_index_from_degree( level_dsequence[i] );
319 : 6086 : int nch = refTemplates[type - 1][d].total_new_ents;
320 : 6086 : start = start * nch;
321 : 6086 : end = end * nch + nch - 1;
322 : : }
323 : :
324 : 6000 : int num_child = end - start;
325 : 6000 : children.reserve( num_child );
326 : :
327 [ + + ]: 114548 : for( int i = start; i <= end; i++ )
328 : : {
329 : : EntityHandle child;
330 [ - + ]: 108548 : if( type == MBEDGE )
331 : 0 : child = level_mesh[child_level - 1].start_edge + i;
332 [ + + ][ + + ]: 108548 : else if( type == MBTRI || type == MBQUAD )
333 : 33940 : child = level_mesh[child_level - 1].start_face + i;
334 [ + + ][ + - ]: 74608 : else if( type == MBTET || type == MBHEX )
335 : 74608 : child = level_mesh[child_level - 1].start_cell + i;
336 : :
337 [ + - ]: 108548 : children.push_back( child );
338 : : }
339 : :
340 : 6000 : return MB_SUCCESS;
341 : : }
342 : :
343 : 0 : ErrorCode NestedRefine::vertex_to_entities_up( EntityHandle vertex, int vert_level, int parent_level,
344 : : std::vector< EntityHandle >& incident_entities )
345 : : {
346 [ # # ]: 0 : assert( vert_level > parent_level );
347 : : ErrorCode error;
348 : :
349 : : // Step 1: Get the incident entities at the current level
350 [ # # ]: 0 : std::vector< EntityHandle > inents;
351 [ # # ]: 0 : if( meshdim == 1 )
352 : : {
353 [ # # ][ # # ]: 0 : error = ahf->get_up_adjacencies_1d( vertex, inents );MB_CHK_ERR( error );
[ # # ][ # # ]
354 : : }
355 [ # # ]: 0 : else if( meshdim == 2 )
356 : : {
357 [ # # ][ # # ]: 0 : error = ahf->get_up_adjacencies_vert_2d( vertex, inents );MB_CHK_ERR( error );
[ # # ][ # # ]
358 : : }
359 [ # # ]: 0 : else if( meshdim == 3 )
360 : : {
361 [ # # ][ # # ]: 0 : error = ahf->get_up_adjacencies_vert_3d( vertex, inents );MB_CHK_ERR( error );
[ # # ][ # # ]
362 : : }
363 : :
364 : : // Step 2: Loop over all the incident entities at the current level and gather their parents
365 [ # # ]: 0 : for( int i = 0; i < (int)inents.size(); i++ )
366 : : {
367 [ # # ]: 0 : EntityHandle ent = inents[i];
368 : : EntityHandle parent;
369 [ # # ][ # # ]: 0 : error = child_to_parent( ent, vert_level, parent_level, &parent );MB_CHK_ERR( error );
[ # # ][ # # ]
370 [ # # ]: 0 : incident_entities.push_back( parent );
371 : : }
372 : :
373 : : // Step 3: Sort and remove duplicates
374 [ # # ]: 0 : std::sort( incident_entities.begin(), incident_entities.end() );
375 : : incident_entities.erase( std::unique( incident_entities.begin(), incident_entities.end() ),
376 [ # # ][ # # ]: 0 : incident_entities.end() );
377 : :
378 : 0 : return MB_SUCCESS;
379 : : }
380 : :
381 : 0 : ErrorCode NestedRefine::vertex_to_entities_down( EntityHandle vertex, int vert_level, int child_level,
382 : : std::vector< EntityHandle >& incident_entities )
383 : : {
384 [ # # ]: 0 : assert( vert_level < child_level );
385 : : ErrorCode error;
386 : :
387 : : // Step 1: Get the incident entities at the current level
388 [ # # ]: 0 : std::vector< EntityHandle > inents;
389 [ # # ]: 0 : if( meshdim == 1 )
390 : : {
391 [ # # ][ # # ]: 0 : error = ahf->get_up_adjacencies_1d( vertex, inents );MB_CHK_ERR( error );
[ # # ][ # # ]
392 : : }
393 [ # # ]: 0 : else if( meshdim == 2 )
394 : : {
395 [ # # ][ # # ]: 0 : error = ahf->get_up_adjacencies_vert_2d( vertex, inents );MB_CHK_ERR( error );
[ # # ][ # # ]
396 : : }
397 [ # # ]: 0 : else if( meshdim == 3 )
398 : : {
399 [ # # ][ # # ]: 0 : error = ahf->get_up_adjacencies_vert_3d( vertex, inents );MB_CHK_ERR( error );
[ # # ][ # # ]
400 : : }
401 : :
402 : : // Step 2: Loop over all the incident entities at the current level and gather their parents
403 [ # # ]: 0 : std::vector< EntityHandle > childs;
404 [ # # ]: 0 : for( int i = 0; i < (int)inents.size(); i++ )
405 : : {
406 : 0 : childs.clear();
407 [ # # ]: 0 : EntityHandle ent = inents[i];
408 [ # # ][ # # ]: 0 : error = parent_to_child( ent, vert_level, child_level, childs );MB_CHK_ERR( error );
[ # # ][ # # ]
409 [ # # ]: 0 : for( int j = 0; j < (int)childs.size(); j++ )
410 [ # # ][ # # ]: 0 : incident_entities.push_back( childs[j] );
411 : : }
412 : :
413 : 0 : return MB_SUCCESS;
414 : : }
415 : :
416 : 0 : ErrorCode NestedRefine::get_vertex_duplicates( EntityHandle vertex, int level, EntityHandle& dupvertex )
417 : : {
418 [ # # ][ # # ]: 0 : if( ( vertex - *_inverts.begin() ) > _inverts.size() )
[ # # ]
419 [ # # ][ # # ]: 0 : MB_SET_ERR( MB_FAILURE, "Requesting duplicates for non-coarse vertices" );
[ # # ][ # # ]
[ # # ]
420 : :
421 [ # # ]: 0 : dupvertex = level_mesh[level - 1].start_vertex + ( vertex - *_inverts.begin() );
422 : :
423 : 0 : return MB_SUCCESS;
424 : : }
425 : :
426 : 0 : bool NestedRefine::is_entity_on_boundary( const EntityHandle& entity )
427 : : {
428 : 0 : bool is_border = false;
429 : 0 : EntityType type = mbImpl->type_from_handle( entity );
430 : :
431 [ # # ]: 0 : if( type == MBVERTEX )
432 : 0 : is_border = is_vertex_on_boundary( entity );
433 [ # # ]: 0 : else if( type == MBEDGE )
434 : 0 : is_border = is_edge_on_boundary( entity );
435 [ # # ][ # # ]: 0 : else if( type == MBTRI || type == MBQUAD )
436 : 0 : is_border = is_face_on_boundary( entity );
437 [ # # ][ # # ]: 0 : else if( type == MBTET || type == MBHEX )
438 : 0 : is_border = is_cell_on_boundary( entity );
439 : : else
440 [ # # ][ # # ]: 0 : MB_SET_ERR( MB_FAILURE, "Requesting boundary information for unsupported entity type" );
[ # # ][ # # ]
[ # # ]
441 : :
442 : 0 : return is_border;
443 : : }
444 : :
445 : 0 : ErrorCode NestedRefine::exchange_ghosts( std::vector< EntityHandle >& lsets, int num_glayers )
446 : : {
447 : : ErrorCode error;
448 : :
449 [ # # ]: 0 : if( hasghost ) return MB_SUCCESS;
450 : :
451 : 0 : hasghost = true;
452 : : #ifdef MOAB_HAVE_MPI
453 [ # # ][ # # ]: 0 : error = pcomm->exchange_ghost_cells( meshdim, 0, num_glayers, 0, true, false );MB_CHK_ERR( error );
454 : : {
455 [ # # ]: 0 : Range empty_range;
456 [ # # ][ # # ]: 0 : error = pcomm->exchange_tags( GLOBAL_ID_TAG_NAME, empty_range );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ][ # # ]
457 : : // error = pcomm->assign_global_ids(lsets[i], 0, 1, false, true, false);MB_CHK_ERR(error);
458 : : }
459 : : #else
460 : : MB_SET_ERR( MB_FAILURE, "Requesting ghost layers for a serial mesh" );
461 : : #endif
462 : :
463 [ # # ][ # # ]: 0 : Range* lverts = new Range[lsets.size()];
[ # # # #
# # ]
464 [ # # ][ # # ]: 0 : Range* lents = new Range[lsets.size()];
[ # # # # ]
465 [ # # ]: 0 : for( size_t i = 0; i < lsets.size(); i++ )
466 : : {
467 [ # # ][ # # ]: 0 : error = mbImpl->get_entities_by_dimension( lsets[i], meshdim, lents[i] );MB_CHK_ERR( error );
468 [ # # ][ # # ]: 0 : error = mbImpl->get_connectivity( lents[i], lverts[i] );MB_CHK_ERR( error );
469 : :
470 [ # # ]: 0 : for( int gl = 0; gl < num_glayers; gl++ )
471 : : {
472 [ # # ][ # # ]: 0 : error = mbImpl->get_adjacencies( lverts[i], meshdim, false, lents[i], Interface::UNION );MB_CHK_ERR( error );
473 [ # # ][ # # ]: 0 : error = mbImpl->get_connectivity( lents[i], lverts[i] );MB_CHK_ERR( error );
474 : : }
475 : : }
476 [ # # ]: 0 : for( size_t i = 0; i < lsets.size(); i++ )
477 : : {
478 [ # # ][ # # ]: 0 : error = mbImpl->add_entities( lsets[i], lverts[i] );MB_CHK_ERR( error );
479 [ # # ][ # # ]: 0 : error = mbImpl->add_entities( lsets[i], lents[i] );MB_CHK_ERR( error );
480 : : }
481 : :
482 [ # # ][ # # ]: 0 : delete[] lverts;
483 [ # # ][ # # ]: 0 : delete[] lents;
484 : 0 : return MB_SUCCESS;
485 : : }
486 : :
487 : 0 : ErrorCode NestedRefine::update_special_tags( int level, EntityHandle& lset )
488 : : {
489 [ # # ][ # # ]: 0 : assert( level > 0 && level < nlevels + 1 );
490 : :
491 : : ErrorCode error;
492 [ # # ]: 0 : std::vector< Tag > mtags( 3 );
493 : :
494 [ # # ][ # # ]: 0 : error = mbImpl->tag_get_handle( MATERIAL_SET_TAG_NAME, 1, MB_TYPE_INTEGER, mtags[0] );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ]
495 [ # # ][ # # ]: 0 : error = mbImpl->tag_get_handle( DIRICHLET_SET_TAG_NAME, 1, MB_TYPE_INTEGER, mtags[1] );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ]
496 [ # # ][ # # ]: 0 : error = mbImpl->tag_get_handle( NEUMANN_SET_TAG_NAME, 1, MB_TYPE_INTEGER, mtags[2] );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ]
497 : :
498 [ # # ]: 0 : for( int i = 0; i < 3; i++ )
499 : : {
500 : : // Gather sets of a particular tag
501 [ # # ]: 0 : Range sets;
502 [ # # ][ # # ]: 0 : error = mbImpl->get_entities_by_type_and_tag( _rset, MBENTITYSET, &mtags[i], NULL, 1, sets );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ]
503 : :
504 : : // Loop over all sets, gather entities in each set and add their children at all levels to
505 : : // the set
506 [ # # ][ # # ]: 0 : Range set_ents;
507 [ # # ]: 0 : Range::iterator set_it;
508 [ # # ][ # # ]: 0 : std::vector< EntityHandle > childs;
509 : :
510 [ # # ][ # # ]: 0 : for( set_it = sets.begin(); set_it != sets.end(); ++set_it )
[ # # ][ # # ]
[ # # ][ # # ]
511 : : {
512 : : // Get the entities in the set, recursively
513 [ # # ]: 0 : set_ents.clear();
514 : 0 : childs.clear();
515 [ # # ][ # # ]: 0 : error = mbImpl->get_entities_by_handle( *set_it, set_ents, true );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ]
516 : :
517 : : // Gather child entities at the input level
518 [ # # ][ # # ]: 0 : for( Range::iterator sit = set_ents.begin(); sit != set_ents.end(); sit++ )
[ # # ][ # # ]
[ # # ]
519 : : {
520 [ # # ][ # # ]: 0 : EntityType type = mbImpl->type_from_handle( *sit );
521 [ # # ]: 0 : if( type == MBVERTEX )
522 : : {
523 [ # # ]: 0 : Range conn;
524 [ # # ][ # # ]: 0 : std::vector< EntityHandle > cents;
525 [ # # ][ # # ]: 0 : error = vertex_to_entities_down( *sit, 0, level, cents );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ]
526 [ # # ][ # # ]: 0 : error = mbImpl->get_connectivity( ¢s[0], (int)cents.size(), conn, true );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ]
527 [ # # ][ # # ]: 0 : childs.insert( childs.end(), cents.begin(), cents.end() );
528 : : }
529 : : else
530 : : {
531 [ # # ][ # # ]: 0 : error = parent_to_child( *sit, 0, level, childs );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ]
532 : : }
533 : :
534 [ # # ]: 0 : std::sort( childs.begin(), childs.end() );
535 [ # # ][ # # ]: 0 : childs.erase( std::unique( childs.begin(), childs.end() ), childs.end() );
536 : :
537 : : // Add child entities to tagged sets
538 [ # # ][ # # ]: 0 : error = mbImpl->add_entities( *set_it, &childs[0], childs.size() );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ][ # # ]
539 : : }
540 : :
541 : : // Remove the coarse entities
542 [ # # ][ # # ]: 0 : error = mbImpl->remove_entities( *set_it, set_ents );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ]
543 : :
544 : : // Add
545 [ # # ][ # # ]: 0 : error = mbImpl->add_entities( lset, &( *set_it ), 1 );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ]
546 : : }
547 : 0 : }
548 : 0 : return MB_SUCCESS;
549 : : }
550 : :
551 : : /***********************************************
552 : : * Basic functionalities: generate HM *
553 : : ***********************************************/
554 : :
555 : 48 : ErrorCode NestedRefine::estimate_hm_storage( EntityHandle set, int level_degree, int cur_level, int hmest[4] )
556 : : {
557 : : ErrorCode error;
558 : :
559 : : // Obtain the size of input mesh.
560 : : int nverts_prev, nedges_prev, nfaces_prev, ncells_prev;
561 [ + + ]: 48 : if( cur_level )
562 : : {
563 : 31 : nverts_prev = level_mesh[cur_level - 1].num_verts;
564 : 31 : nedges_prev = level_mesh[cur_level - 1].num_edges;
565 : 31 : nfaces_prev = level_mesh[cur_level - 1].num_faces;
566 : 31 : ncells_prev = level_mesh[cur_level - 1].num_cells;
567 : : }
568 : : else
569 : : {
570 [ + - ]: 17 : nverts_prev = _inverts.size();
571 [ + - ]: 17 : nedges_prev = _inedges.size();
572 [ + - ]: 17 : nfaces_prev = _infaces.size();
573 [ + - ]: 17 : ncells_prev = _incells.size();
574 : : }
575 : :
576 : : // Estimate mesh size of current level mesh.
577 : 48 : int nedges = 0, nfaces = 0;
578 [ + - ][ - + ]: 48 : error = count_subentities( set, cur_level - 1, &nedges, &nfaces );MB_CHK_ERR( error );
[ # # ][ # # ]
579 : :
580 [ + - ]: 48 : int d = get_index_from_degree( level_degree );
581 : 48 : int nverts = refTemplates[MBEDGE - 1][d].nv_edge * nedges;
582 : 48 : hmest[0] = nverts_prev + nverts;
583 : 48 : hmest[1] = nedges_prev * refTemplates[MBEDGE - 1][d].total_new_ents;
584 : 48 : hmest[2] = 0;
585 : 48 : hmest[3] = 0;
586 : :
587 : : int findex, cindex;
588 [ + + ]: 48 : if( nfaces_prev != 0 )
589 : : {
590 : : EntityHandle start_face;
591 [ + + ]: 22 : if( cur_level )
592 : 14 : start_face = level_mesh[cur_level - 1].start_face;
593 : : else
594 [ + - ][ + - ]: 8 : start_face = *_infaces.begin();
595 [ + - ]: 22 : findex = mbImpl->type_from_handle( start_face ) - 1;
596 : 22 : hmest[2] = nfaces_prev * refTemplates[findex][d].total_new_ents;
597 : :
598 [ + - ]: 22 : if( meshdim == 2 ) hmest[0] += refTemplates[findex][d].nv_face * nfaces_prev;
599 : :
600 [ - + ]: 22 : if( meshdim == 3 ) hmest[1] += nfaces_prev * intFacEdg[findex - 1][d].nie;
601 : : }
602 : :
603 [ + + ]: 48 : if( ncells_prev != 0 )
604 : : {
605 [ + - ][ + - ]: 16 : cindex = mbImpl->type_from_handle( *( _incells.begin() ) ) - 1;
[ + - ]
606 : 16 : hmest[3] = ncells_prev * refTemplates[cindex][d].total_new_ents;
607 : :
608 : 16 : hmest[0] += refTemplates[cindex][d].nv_face * nfaces;
609 : 16 : hmest[0] += refTemplates[cindex][d].nv_cell * ncells_prev;
610 : : }
611 : :
612 : 48 : return MB_SUCCESS;
613 : : }
614 : :
615 : 48 : ErrorCode NestedRefine::create_hm_storage_single_level( EntityHandle* set, int cur_level, int estL[4] )
616 : : {
617 : : // Obtain chunks of memory for the current level. Add them to a particular meshset.
618 : : EntityHandle set_handle;
619 [ + - ][ - + ]: 48 : ErrorCode error = mbImpl->create_meshset( MESHSET_SET, set_handle );MB_CHK_SET_ERR( error, "Cannot create mesh for the current level" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
620 : 48 : *set = set_handle;
621 : :
622 : : ReadUtilIface* read_iface;
623 [ + - ][ - + ]: 48 : error = mbImpl->query_interface( read_iface );MB_CHK_ERR( error );
[ # # ][ # # ]
624 : :
625 : : // Vertices
626 : : error = read_iface->get_node_coords( 3, estL[0], 0, level_mesh[cur_level].start_vertex,
627 [ + - ][ - + ]: 48 : level_mesh[cur_level].coordinates );MB_CHK_ERR( error );
[ # # ][ # # ]
628 : 48 : level_mesh[cur_level].num_verts = estL[0];
629 : :
630 [ + - ]: 48 : Range newverts( level_mesh[cur_level].start_vertex, level_mesh[cur_level].start_vertex + estL[0] - 1 );
631 [ + - ][ - + ]: 48 : error = mbImpl->add_entities( *set, newverts );MB_CHK_ERR( error );
[ # # ][ # # ]
632 [ + - ]: 48 : level_mesh[cur_level].verts = newverts;
633 : :
634 : : Tag gidtag;
635 [ + - ][ - + ]: 48 : error = mbImpl->tag_get_handle( GLOBAL_ID_TAG_NAME, gidtag );MB_CHK_ERR( error );
[ # # ][ # # ]
636 [ + - ][ - + ]: 48 : error = read_iface->assign_ids( gidtag, newverts, level_mesh[cur_level].start_vertex );MB_CHK_ERR( error );
[ # # ][ # # ]
637 : :
638 : : // Edges
639 [ + + ]: 48 : if( estL[1] )
640 : : {
641 : 10 : error = read_iface->get_element_connect( estL[1], 2, MBEDGE, 0, level_mesh[cur_level].start_edge,
642 [ + - ][ - + ]: 10 : level_mesh[cur_level].edge_conn );MB_CHK_ERR( error );
[ # # ][ # # ]
643 : 10 : level_mesh[cur_level].num_edges = estL[1];
644 : :
645 [ + - ]: 10 : Range newedges( level_mesh[cur_level].start_edge, level_mesh[cur_level].start_edge + estL[1] - 1 );
646 [ + - ][ - + ]: 10 : error = mbImpl->add_entities( *set, newedges );MB_CHK_ERR( error );
[ # # ][ # # ]
647 [ + - ][ + - ]: 10 : level_mesh[cur_level].edges = newedges;
648 : : }
649 : : else
650 : 38 : level_mesh[cur_level].num_edges = 0;
651 : :
652 : : // Faces
653 [ + + ]: 48 : if( estL[2] )
654 : : {
655 [ + - ][ + - ]: 22 : EntityType type = mbImpl->type_from_handle( *( _infaces.begin() ) );
[ + - ]
656 : 22 : int nvpf = ahf->lConnMap2D[type - 2].num_verts_in_face;
657 : 22 : error = read_iface->get_element_connect( estL[2], nvpf, type, 0, level_mesh[cur_level].start_face,
658 [ + - ][ - + ]: 22 : level_mesh[cur_level].face_conn );MB_CHK_ERR( error );
[ # # ][ # # ]
659 : 22 : level_mesh[cur_level].num_faces = estL[2];
660 : :
661 [ + - ]: 22 : Range newfaces( level_mesh[cur_level].start_face, level_mesh[cur_level].start_face + estL[2] - 1 );
662 [ + - ][ - + ]: 22 : error = mbImpl->add_entities( *set, newfaces );MB_CHK_ERR( error );
[ # # ][ # # ]
663 [ + - ][ + - ]: 22 : level_mesh[cur_level].faces = newfaces;
664 : : }
665 : : else
666 : 26 : level_mesh[cur_level].num_faces = 0;
667 : :
668 : : // Cells
669 [ + + ]: 48 : if( estL[3] )
670 : : {
671 [ + - ][ + - ]: 16 : EntityType type = mbImpl->type_from_handle( *( _incells.begin() ) );
[ + - ]
672 [ + - ][ + - ]: 16 : int index = ahf->get_index_in_lmap( *_incells.begin() );
[ + - ]
673 : 16 : int nvpc = ahf->lConnMap3D[index].num_verts_in_cell;
674 : 16 : error = read_iface->get_element_connect( estL[3], nvpc, type, 0, level_mesh[cur_level].start_cell,
675 [ + - ][ - + ]: 16 : level_mesh[cur_level].cell_conn );MB_CHK_ERR( error );
[ # # ][ # # ]
676 : 16 : level_mesh[cur_level].num_cells = estL[3];
677 : :
678 [ + - ]: 16 : Range newcells( level_mesh[cur_level].start_cell, level_mesh[cur_level].start_cell + estL[3] - 1 );
679 [ + - ][ - + ]: 16 : error = mbImpl->add_entities( *set, newcells );MB_CHK_ERR( error );
[ # # ][ # # ]
680 [ + - ][ + - ]: 16 : level_mesh[cur_level].cells = newcells;
681 : : }
682 : : else
683 : 32 : level_mesh[cur_level].num_cells = 0;
684 : :
685 : : // Resize the ahf maps
686 : : error = ahf->resize_hf_maps( level_mesh[cur_level].start_vertex, level_mesh[cur_level].num_verts,
687 : : level_mesh[cur_level].start_edge, level_mesh[cur_level].num_edges,
688 : : level_mesh[cur_level].start_face, level_mesh[cur_level].num_faces,
689 [ + - ][ - + ]: 48 : level_mesh[cur_level].start_cell, level_mesh[cur_level].num_cells );MB_CHK_ERR( error );
[ # # ][ # # ]
690 : :
691 [ + - ][ - + ]: 48 : error = ahf->update_entity_ranges( *set );MB_CHK_ERR( error );
[ # # ][ # # ]
692 : :
693 : : // If the mesh type changes, then update the member variable in ahf to use the applicable
694 : : // adjacency matrix
695 : : MESHTYPE nwmesh = ahf->get_mesh_type( level_mesh[cur_level].num_verts, level_mesh[cur_level].num_edges,
696 [ + - ][ - + ]: 48 : level_mesh[cur_level].num_faces, level_mesh[cur_level].num_cells );MB_CHK_ERR( error );
[ # # ][ # # ]
697 [ - + ]: 48 : if( ahf->thismeshtype != nwmesh ) ahf->thismeshtype = nwmesh;
698 : :
699 : 48 : return MB_SUCCESS;
700 : : }
701 : :
702 : : /**********************************
703 : : * Hierarchical Mesh Generation *
704 : : * *********************************/
705 : :
706 : 17 : ErrorCode NestedRefine::generate_hm( int* level_degrees, int num_level, EntityHandle* hm_set, bool optimize )
707 : : {
708 : : ErrorCode error;
709 : :
710 : : Tag gidtag;
711 [ + - ][ - + ]: 17 : error = mbImpl->tag_get_handle( GLOBAL_ID_TAG_NAME, gidtag );MB_CHK_ERR( error );
[ # # ][ # # ]
712 : :
713 : 17 : nlevels = num_level;
714 : :
715 : 17 : timeall.tm_total = 0;
716 : 17 : timeall.tm_refine = 0;
717 : 17 : timeall.tm_resolve = 0;
718 : :
719 [ + + ]: 65 : for( int l = 0; l < num_level; l++ )
720 : : {
721 : : double tstart;
722 [ + - ]: 48 : tstart = tm->time_elapsed();
723 : :
724 : : // Estimate storage
725 : 48 : int hmest[4] = { 0, 0, 0, 0 };
726 : : EntityHandle set;
727 [ + + ]: 48 : if( l )
728 : 31 : set = hm_set[l - 1];
729 : : else
730 : 17 : set = _rset;
731 [ + - ][ - + ]: 48 : error = estimate_hm_storage( set, level_degrees[l], l, hmest );MB_CHK_ERR( error );
[ # # ][ # # ]
732 : :
733 : : // Create arrays for storing the current level
734 [ + - ][ - + ]: 48 : error = create_hm_storage_single_level( &hm_set[l], l, hmest );MB_CHK_ERR( error );
[ # # ][ # # ]
735 : :
736 : : // Copy the old vertices along with their coordinates
737 [ + - ][ - + ]: 48 : error = copy_vertices_from_prev_level( l );MB_CHK_ERR( error );
[ # # ][ # # ]
738 : :
739 : : // Create the new entities and new vertices
740 [ + - ][ - + ]: 48 : error = construct_hm_entities( l, level_degrees[l] );MB_CHK_ERR( error );
[ # # ][ # # ]
741 : :
742 [ + - ]: 48 : timeall.tm_refine += tm->time_elapsed() - tstart;
743 : :
744 : : // Go into parallel communication
745 [ + + ]: 48 : if( !optimize )
746 : : {
747 : : #ifdef MOAB_HAVE_MPI
748 [ + - ][ + - ]: 6 : if( pcomm && ( pcomm->size() > 1 ) )
[ - + ][ - + ]
749 : : {
750 [ # # ]: 0 : double tpstart = tm->time_elapsed();
751 [ # # ][ # # ]: 0 : error = resolve_shared_ents_parmerge( l, hm_set[l] );MB_CHK_ERR( error );
[ # # ][ # # ]
752 [ # # ]: 6 : timeall.tm_resolve += tm->time_elapsed() - tpstart;
753 : : }
754 : : #endif
755 : : }
756 : : }
757 : :
758 [ + + ]: 17 : if( optimize )
759 : : {
760 : : #ifdef MOAB_HAVE_MPI
761 [ - + ][ # # ]: 15 : if( pcomm && ( pcomm->size() > 1 ) )
[ # # ][ - + ]
762 : : {
763 [ # # ]: 0 : double tpstart = tm->time_elapsed();
764 [ # # ][ # # ]: 0 : error = resolve_shared_ents_opt( hm_set, nlevels );MB_CHK_ERR( error );
[ # # ][ # # ]
765 [ # # ]: 15 : timeall.tm_resolve = tm->time_elapsed() - tpstart;
766 : : }
767 : : #endif
768 : : }
769 : 17 : timeall.tm_total = timeall.tm_refine + timeall.tm_resolve;
770 : :
771 : 17 : return MB_SUCCESS;
772 : : }
773 : :
774 : 48 : ErrorCode NestedRefine::construct_hm_entities( int cur_level, int deg )
775 : : {
776 : : ErrorCode error;
777 : :
778 : : // Generate mesh for current level by refining previous level.
779 [ + + ]: 48 : if( ahf->thismeshtype == CURVE )
780 : : {
781 [ - + ][ # # ]: 10 : error = construct_hm_1D( cur_level, deg );MB_CHK_ERR( error );
782 : : }
783 [ + + ][ - + ]: 60 : else if( ahf->thismeshtype == SURFACE || ahf->thismeshtype == SURFACE_MIXED )
784 : : {
785 [ - + ][ # # ]: 22 : error = construct_hm_2D( cur_level, deg );MB_CHK_ERR( error );
786 : : }
787 : : else
788 : : {
789 [ - + ][ # # ]: 16 : error = construct_hm_3D( cur_level, deg );MB_CHK_ERR( error );
790 : : }
791 : :
792 : 48 : return MB_SUCCESS;
793 : : }
794 : :
795 : 10 : ErrorCode NestedRefine::construct_hm_1D( int cur_level, int deg )
796 : : {
797 : : ErrorCode error;
798 : : int nverts_prev, nents_prev;
799 [ + + ]: 10 : if( cur_level )
800 : : {
801 : 7 : nverts_prev = level_mesh[cur_level - 1].num_verts;
802 : 7 : nents_prev = level_mesh[cur_level - 1].num_edges;
803 : : }
804 : : else
805 : : {
806 [ + - ]: 3 : nverts_prev = _inverts.size();
807 [ + - ]: 3 : nents_prev = _inedges.size();
808 : : }
809 : :
810 [ + - ]: 10 : int d = get_index_from_degree( deg );
811 : 10 : int vtotal = 2 + refTemplates[0][d].total_new_verts;
812 [ + - ]: 10 : std::vector< EntityHandle > vbuffer( vtotal );
813 : :
814 [ + - ]: 20 : std::vector< EntityHandle > conn;
815 : 10 : int count_nents = 0;
816 : 10 : int count_verts = nverts_prev;
817 : :
818 : : // Step 1: Create the subentities via refinement of the previous mesh
819 [ + + ]: 865 : for( int eid = 0; eid < nents_prev; eid++ )
820 : : {
821 : 855 : conn.clear();
822 : :
823 : : // EntityHandle of the working edge
824 : : EntityHandle edge;
825 [ + + ]: 855 : if( cur_level )
826 : 840 : edge = level_mesh[cur_level - 1].start_edge + eid;
827 : : else
828 [ + - ]: 15 : edge = _inedges[eid]; // Makes the assumption initial mesh is contiguous in memory
829 : :
830 [ + - ][ - + ]: 855 : error = get_connectivity( edge, cur_level, conn );MB_CHK_ERR( error );
[ # # ][ # # ]
831 : :
832 : : // Add the vertex handles to vbuffer for the current level for the working edge
833 : :
834 : : // Since the old vertices are copied first, their local indices do not change as new levels
835 : : // are added. Clearly the local indices of the new vertices introduced in the current level
836 : : // is still the same when the old vertices are copied. Thus, there is no need to explicitly
837 : : // store another map between the old and duplicates in the subsequent levels. The second
838 : : // part in the following sum is the local index in the previous level.
839 : :
840 : : // Add the corners to the vbuffer first.
841 : :
842 [ + + ]: 2565 : for( int i = 0; i < (int)conn.size(); i++ )
843 : : {
844 [ + + ]: 1710 : if( cur_level )
845 [ + - ][ + - ]: 1680 : vbuffer[i] = level_mesh[cur_level].start_vertex + ( conn[i] - level_mesh[cur_level - 1].start_vertex );
846 : : else
847 [ + - ][ + - ]: 30 : vbuffer[i] = level_mesh[cur_level].start_vertex + ( conn[i] - *_inverts.begin() );
[ + - ][ + - ]
848 : : }
849 : :
850 : : // Adding rest of the entityhandles to working buffer for vertices.
851 : 855 : int num_new_verts = refTemplates[0][d].total_new_verts;
852 : :
853 [ + + ]: 1990 : for( int i = 0; i < num_new_verts; i++ )
854 : : {
855 [ + - ]: 1135 : vbuffer[i + 2] = level_mesh[cur_level].start_vertex + count_verts;
856 : 1135 : count_verts += 1;
857 : : }
858 : :
859 : : // Use the template to obtain the subentities
860 : : int id1, id2;
861 : 855 : int etotal = refTemplates[0][d].total_new_ents;
862 [ + - ]: 855 : std::vector< EntityHandle > ent_buffer( etotal );
863 : :
864 [ + + ]: 2845 : for( int i = 0; i < etotal; i++ )
865 : : {
866 : 1990 : id1 = refTemplates[0][d].ents_conn[i][0];
867 : 1990 : id2 = refTemplates[0][d].ents_conn[i][1];
868 [ + - ]: 1990 : level_mesh[cur_level].edge_conn[2 * ( count_nents )] = vbuffer[id1];
869 [ + - ]: 1990 : level_mesh[cur_level].edge_conn[2 * ( count_nents ) + 1] = vbuffer[id2];
870 [ + - ]: 1990 : ent_buffer[i] = level_mesh[cur_level].start_edge + count_nents;
871 : 1990 : count_nents += 1;
872 : : };
873 : :
874 [ + - ][ + - ]: 855 : error = update_local_ahf( deg, MBEDGE, &vbuffer[0], &ent_buffer[0], etotal );MB_CHK_ERR( error );
[ + - ][ - + ]
[ # # ][ # # ]
875 : :
876 : : // Compute the coordinates of the new vertices: Linear interpolation
877 : : int idx;
878 : : double xi;
879 [ + + ][ + - ]: 1990 : for( int i = 0; i < num_new_verts; i++ )
880 : : {
881 : 1135 : xi = refTemplates[0][d].vert_nat_coord[i][0];
882 [ + - ]: 1135 : idx = vbuffer[i + 2] - level_mesh[cur_level].start_vertex; // index of new vertex in current level
883 [ + + ]: 1135 : if( cur_level )
884 : : {
885 [ + - ]: 1090 : id1 = conn[0] - level_mesh[cur_level - 1].start_vertex; // index of old end vertices in current level
886 [ + - ]: 1090 : id2 = conn[1] - level_mesh[cur_level - 1].start_vertex;
887 : : }
888 : : else
889 : : {
890 [ + - ][ + - ]: 45 : id1 = _inverts.index( conn[0] );
891 [ + - ][ + - ]: 45 : id2 = _inverts.index( conn[1] );
892 : : }
893 : :
894 [ + - ]: 1135 : level_mesh[cur_level].coordinates[0][idx] =
895 [ + - ][ + - ]: 1135 : ( 1 - xi ) * level_mesh[cur_level].coordinates[0][id1] + xi * level_mesh[cur_level].coordinates[0][id2];
896 [ + - ]: 1135 : level_mesh[cur_level].coordinates[1][idx] =
897 [ + - ][ + - ]: 1135 : ( 1 - xi ) * level_mesh[cur_level].coordinates[1][id1] + xi * level_mesh[cur_level].coordinates[1][id2];
898 [ + - ]: 1135 : level_mesh[cur_level].coordinates[2][idx] =
899 [ + - ][ + - ]: 1135 : ( 1 - xi ) * level_mesh[cur_level].coordinates[2][id1] + xi * level_mesh[cur_level].coordinates[2][id2];
900 : : }
901 : 855 : }
902 : :
903 [ + - ][ - + ]: 10 : error = update_global_ahf( MBEDGE, cur_level, deg );MB_CHK_ERR( error );
[ # # ][ # # ]
904 : :
905 : 20 : return MB_SUCCESS;
906 : : }
907 : :
908 : 0 : ErrorCode NestedRefine::construct_hm_1D( int cur_level, int deg, EntityType type,
909 : : std::vector< EntityHandle >& trackverts )
910 : : {
911 : : ErrorCode error;
912 : :
913 : : int nedges_prev;
914 [ # # ]: 0 : if( cur_level )
915 : 0 : nedges_prev = level_mesh[cur_level - 1].num_edges;
916 : : else
917 [ # # ]: 0 : nedges_prev = _inedges.size();
918 : :
919 [ # # ]: 0 : int d = get_index_from_degree( deg );
920 : 0 : int nve = refTemplates[0][d].nv_edge;
921 : 0 : int vtotal = 2 + refTemplates[0][d].total_new_verts;
922 : 0 : int etotal = refTemplates[0][d].total_new_ents;
923 : 0 : int ne = 0, dim = 0, index = 0;
924 [ # # ][ # # ]: 0 : if( type == MBTRI || type == MBQUAD )
925 : : {
926 : 0 : index = type - 2;
927 : 0 : ne = ahf->lConnMap2D[index].num_verts_in_face;
928 : 0 : dim = 2;
929 : : }
930 [ # # ][ # # ]: 0 : else if( type == MBTET || type == MBHEX )
931 : : {
932 [ # # ][ # # ]: 0 : index = ahf->get_index_in_lmap( *( _incells.begin() ) );
[ # # ]
933 : 0 : ne = ahf->lConnMap3D[index].num_edges_in_cell;
934 : 0 : dim = 3;
935 : : }
936 : :
937 [ # # ]: 0 : std::vector< EntityHandle > vbuffer( vtotal );
938 [ # # ]: 0 : std::vector< EntityHandle > ent_buffer( etotal );
939 : :
940 [ # # ][ # # ]: 0 : std::vector< EntityHandle > adjents, econn, fconn;
[ # # ]
941 [ # # ]: 0 : std::vector< int > leids;
942 : 0 : int count_nents = 0;
943 : :
944 : : // Loop over all the edges and gather the vertices to be used for refinement
945 [ # # ]: 0 : for( int eid = 0; eid < nedges_prev; eid++ )
946 : : {
947 : 0 : adjents.clear();
948 : 0 : leids.clear();
949 : 0 : econn.clear();
950 : 0 : fconn.clear();
951 [ # # ]: 0 : for( int i = 0; i < vtotal; i++ )
952 [ # # ]: 0 : vbuffer[i] = 0;
953 [ # # ]: 0 : for( int i = 0; i < etotal; i++ )
954 [ # # ]: 0 : ent_buffer[i] = 0;
955 : :
956 : : EntityHandle edge;
957 [ # # ]: 0 : if( cur_level )
958 : 0 : edge = level_mesh[cur_level - 1].start_edge + eid;
959 : : else
960 [ # # ]: 0 : edge = _inedges[eid];
961 : :
962 [ # # ][ # # ]: 0 : error = get_connectivity( edge, cur_level, econn );MB_CHK_ERR( error );
[ # # ][ # # ]
963 : :
964 [ # # ]: 0 : for( int i = 0; i < (int)econn.size(); i++ )
965 : : {
966 [ # # ]: 0 : if( cur_level )
967 [ # # ][ # # ]: 0 : vbuffer[i] = level_mesh[cur_level].start_vertex + ( econn[i] - level_mesh[cur_level - 1].start_vertex );
968 : : else
969 [ # # ][ # # ]: 0 : vbuffer[i] = level_mesh[cur_level].start_vertex + ( econn[i] - *_inverts.begin() );
[ # # ][ # # ]
970 : : }
971 : :
972 : 0 : int fid = -1, lid = -1, idx1 = -1, idx2 = -1;
973 : :
974 [ # # ]: 0 : if( dim == 2 )
975 : : {
976 [ # # ][ # # ]: 0 : error = ahf->get_up_adjacencies_2d( edge, adjents, &leids );MB_CHK_ERR( error );
[ # # ][ # # ]
977 [ # # ]: 0 : if( cur_level )
978 [ # # ]: 0 : fid = adjents[0] - level_mesh[cur_level - 1].start_face;
979 : : else
980 [ # # ][ # # ]: 0 : fid = _infaces.index( adjents[0] );
981 : :
982 [ # # ]: 0 : lid = leids[0];
983 : 0 : idx1 = lid;
984 : 0 : idx2 = ahf->lConnMap2D[index].next[lid];
985 : : }
986 [ # # ]: 0 : else if( dim == 3 )
987 : : {
988 [ # # ][ # # ]: 0 : error = ahf->get_up_adjacencies_edg_3d( edge, adjents, &leids );MB_CHK_ERR( error );
[ # # ][ # # ]
989 [ # # ]: 0 : if( cur_level )
990 [ # # ]: 0 : fid = adjents[0] - level_mesh[cur_level - 1].start_cell;
991 : : else
992 [ # # ][ # # ]: 0 : fid = _incells.index( adjents[0] );
993 : :
994 [ # # ]: 0 : lid = leids[0];
995 : 0 : idx1 = ahf->lConnMap3D[index].e2v[lid][0];
996 : 0 : idx2 = ahf->lConnMap3D[index].e2v[lid][1];
997 : : }
998 : :
999 [ # # ][ # # ]: 0 : error = get_connectivity( adjents[0], cur_level, fconn );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ]
1000 : :
1001 : 0 : bool orient = false;
1002 [ # # ][ # # ]: 0 : if( ( fconn[idx1] == econn[0] ) && ( fconn[idx2] == econn[1] ) ) orient = true;
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1003 : :
1004 [ # # ]: 0 : if( orient )
1005 : : {
1006 [ # # ]: 0 : for( int j = 0; j < nve; j++ )
1007 [ # # ][ # # ]: 0 : vbuffer[j + 2] = trackverts[fid * ne * nve + nve * lid + j];
1008 : : }
1009 : : else
1010 : : {
1011 [ # # ]: 0 : for( int j = 0; j < nve; j++ )
1012 [ # # ][ # # ]: 0 : vbuffer[( nve - j - 1 ) + 2] = trackverts[fid * ne * nve + nve * lid + j];
1013 : : }
1014 : :
1015 : : // Use the template to obtain the subentities
1016 : : int id1, id2;
1017 : :
1018 [ # # ]: 0 : for( int i = 0; i < etotal; i++ )
1019 : : {
1020 : 0 : id1 = refTemplates[0][d].ents_conn[i][0];
1021 : 0 : id2 = refTemplates[0][d].ents_conn[i][1];
1022 [ # # ]: 0 : level_mesh[cur_level].edge_conn[2 * ( count_nents )] = vbuffer[id1];
1023 [ # # ]: 0 : level_mesh[cur_level].edge_conn[2 * ( count_nents ) + 1] = vbuffer[id2];
1024 [ # # ]: 0 : ent_buffer[i] = level_mesh[cur_level].start_edge + count_nents;
1025 : :
1026 : 0 : count_nents += 1;
1027 : : };
1028 : :
1029 [ # # ][ # # ]: 0 : error = update_local_ahf( deg, MBEDGE, &vbuffer[0], &ent_buffer[0], etotal );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ][ # # ]
1030 : : }
1031 : :
1032 [ # # ][ # # ]: 0 : error = update_global_ahf_1D_sub( cur_level, deg );MB_CHK_ERR( error );
[ # # ][ # # ]
1033 : :
1034 : 0 : return MB_SUCCESS;
1035 : : }
1036 : :
1037 : 22 : ErrorCode NestedRefine::construct_hm_2D( int cur_level, int deg )
1038 : : {
1039 : : ErrorCode error;
1040 : : int nverts_prev, nents_prev;
1041 [ + + ]: 22 : if( cur_level )
1042 : : {
1043 : 14 : nverts_prev = level_mesh[cur_level - 1].num_verts;
1044 : 14 : nents_prev = level_mesh[cur_level - 1].num_faces;
1045 : : }
1046 : : else
1047 : : {
1048 [ + - ]: 8 : nverts_prev = _inverts.size();
1049 [ + - ]: 8 : nents_prev = _infaces.size();
1050 : : }
1051 : :
1052 : : // Create some book-keeping arrays over the old mesh to avoid introducing duplicate vertices and
1053 : : // calculating vertices more than once.
1054 [ + - ][ + - ]: 22 : EntityType ftype = mbImpl->type_from_handle( *_infaces.begin() );
[ + - ]
1055 : 22 : int nepf = ahf->lConnMap2D[ftype - 2].num_verts_in_face;
1056 : 22 : int findex = ftype - 1;
1057 : :
1058 [ + - ]: 22 : int d = get_index_from_degree( deg );
1059 : 22 : int tnv = refTemplates[findex][d].total_new_verts;
1060 : 22 : int vtotal = nepf + tnv;
1061 [ + - ]: 22 : std::vector< EntityHandle > vbuffer( vtotal );
1062 : 22 : int etotal = refTemplates[findex][d].total_new_ents;
1063 [ + - ]: 44 : std::vector< EntityHandle > ent_buffer( etotal );
1064 : :
1065 : 22 : int nve = refTemplates[findex][d].nv_edge;
1066 [ + - ]: 44 : std::vector< EntityHandle > trackvertsF( nents_prev * nepf * nve, 0 );
1067 : 22 : int cur_nverts = level_mesh[cur_level].num_verts;
1068 [ + - ]: 44 : std::vector< int > flag_verts( cur_nverts - nverts_prev, 0 );
1069 : :
1070 : 22 : int count_nverts = nverts_prev;
1071 : 22 : int count_nents = 0;
1072 [ + - ][ + - ]: 44 : std::vector< EntityHandle > conn, cur_conn;
1073 : :
1074 : : // Step 1: Create the subentities via refinement of the previous mesh
1075 [ + + ]: 5566 : for( int fid = 0; fid < nents_prev; fid++ )
1076 : : {
1077 : 5544 : conn.clear();
1078 : 5544 : cur_conn.clear();
1079 [ + + ]: 52873 : for( int i = 0; i < vtotal; i++ )
1080 [ + - ]: 47329 : vbuffer[i] = 0;
1081 [ + + ]: 40556 : for( int i = 0; i < etotal; i++ )
1082 [ + - ]: 35012 : ent_buffer[i] = 0;
1083 : :
1084 : : // EntityHandle of the working face
1085 : : EntityHandle face;
1086 [ + + ]: 5544 : if( cur_level )
1087 : 5300 : face = level_mesh[cur_level - 1].start_face + fid;
1088 : : else
1089 [ + - ]: 244 : face = _infaces[fid];
1090 : :
1091 [ + - ][ - + ]: 5544 : error = get_connectivity( face, cur_level, conn );MB_CHK_ERR( error );
[ # # ][ # # ]
1092 : :
1093 : : // Step 1: Add vertices from the current level for the working face that will be used for
1094 : : // subdivision.
1095 : : // Add the corners to vbuffer
1096 [ + + ]: 22723 : for( int i = 0; i < (int)conn.size(); i++ )
1097 : : {
1098 [ + + ]: 17179 : if( cur_level )
1099 [ + - ][ + - ]: 16430 : vbuffer[i] = level_mesh[cur_level].start_vertex + ( conn[i] - level_mesh[cur_level - 1].start_vertex );
1100 : : else
1101 [ + - ][ + - ]: 749 : vbuffer[i] = level_mesh[cur_level].start_vertex + ( conn[i] - *_inverts.begin() );
[ + - ][ + - ]
1102 : :
1103 [ + - ][ + - ]: 17179 : cur_conn.push_back( vbuffer[i] );
1104 : : }
1105 : :
1106 : : // Gather vertices already added to tracking array due to refinement of the sibling faces
1107 : :
1108 [ + + ]: 22723 : for( int i = 0; i < nepf; i++ )
1109 : : {
1110 [ + + ]: 40728 : for( int j = 0; j < nve; j++ )
1111 : : {
1112 : 23549 : int id = refTemplates[findex][d].vert_on_edges[i][j];
1113 [ + - ][ + - ]: 23549 : vbuffer[id] = trackvertsF[fid * nve * nepf + nve * i + j];
1114 : : }
1115 : : }
1116 : :
1117 : : // Add the remaining vertex handles to vbuffer for the current level for the working face
1118 [ + + ]: 35694 : for( int i = 0; i < tnv; i++ )
1119 : : {
1120 [ + - ][ + + ]: 30150 : if( !vbuffer[i + nepf] )
1121 : : {
1122 [ + - ]: 18759 : vbuffer[i + nepf] = level_mesh[cur_level].start_vertex + count_nverts;
1123 : 18759 : count_nverts += 1;
1124 : : }
1125 : : }
1126 : :
1127 : : // Step 2: Create the subentities using the template and the vbuffer
1128 : : int idx;
1129 [ + + ]: 40556 : for( int i = 0; i < etotal; i++ )
1130 : : {
1131 [ + + ]: 147878 : for( int k = 0; k < nepf; k++ )
1132 : : {
1133 : 112866 : idx = refTemplates[findex][d].ents_conn[i][k];
1134 [ + - ]: 112866 : level_mesh[cur_level].face_conn[nepf * count_nents + k] = vbuffer[idx];
1135 : : }
1136 [ + - ]: 35012 : ent_buffer[i] = level_mesh[cur_level].start_face + count_nents;
1137 : 35012 : count_nents += 1;
1138 : : }
1139 : :
1140 : : // Step 3: Update the local AHF maps
1141 [ + - ][ + - ]: 5544 : error = update_local_ahf( deg, ftype, &vbuffer[0], &ent_buffer[0], etotal );MB_CHK_ERR( error );
[ + - ][ - + ]
[ # # ][ # # ]
1142 : :
1143 : : // Step 4: Add the new vertices to the tracking array
1144 : : int id;
1145 : :
1146 [ + + ]: 22723 : for( int i = 0; i < nepf; i++ )
1147 : : {
1148 : : // Add the vertices to trackvertsF for fid
1149 [ + + ]: 40728 : for( int j = 0; j < nve; j++ )
1150 : : {
1151 : 23549 : id = refTemplates[findex][d].vert_on_edges[i][j];
1152 [ + - ][ + - ]: 23549 : trackvertsF[fid * nepf * nve + nve * i + j] = vbuffer[id];
1153 : : }
1154 : :
1155 [ + - ]: 17179 : std::vector< EntityHandle > sibfids;
1156 [ + - ]: 34358 : std::vector< int > sibleids;
[ + - + ]
1157 [ + - ]: 34358 : std::vector< int > siborient;
[ + - + ]
1158 : :
1159 : : // Add the vertices to trackvertsF for siblings of fid, if any.
1160 [ + - ][ - + ]: 17179 : error = ahf->get_up_adjacencies_2d( face, i, false, sibfids, &sibleids, &siborient );MB_CHK_ERR( error );
[ # # ][ # # ]
1161 : :
1162 [ + + ]: 17179 : if( !sibfids.size() ) continue;
1163 : :
1164 [ + + ]: 34205 : for( int s = 0; s < (int)sibfids.size(); s++ )
[ + - + ]
1165 : : {
1166 : : int sibid;
1167 [ + + ]: 17026 : if( cur_level )
1168 [ + - ]: 16302 : sibid = sibfids[s] - level_mesh[cur_level - 1].start_face;
1169 : : else
1170 [ + - ][ + - ]: 724 : sibid = sibfids[s] - *_infaces.begin();
[ + - ]
1171 : :
1172 [ + - ][ + + ]: 17026 : if( siborient[s] ) // Same half-edge direction as the current half-edge
1173 : : {
1174 [ + + ]: 608 : for( int j = 0; j < nve; j++ )
1175 : : {
1176 : 464 : id = refTemplates[findex][d].vert_on_edges[i][j];
1177 [ + - ][ + - ]: 464 : trackvertsF[sibid * nepf * nve + nve * sibleids[s] + j] = vbuffer[id];
[ + - ]
1178 : : }
1179 : : }
1180 : : else
1181 : : {
1182 [ + + ]: 39722 : for( int j = 0; j < nve; j++ )
1183 : : {
1184 : 22840 : id = refTemplates[findex][d].vert_on_edges[i][nve - j - 1];
1185 [ + - ][ + - ]: 22840 : trackvertsF[sibid * nepf * nve + nve * sibleids[s] + j] = vbuffer[id];
[ + - ]
1186 : : }
1187 : : }
1188 : : }
1189 : 17179 : }
1190 : :
1191 : : // Step 5: Compute the coordinates of the new vertices, avoids computing more than once via
1192 : : // the flag_verts array.
1193 [ + - ]: 5544 : std::vector< double > corner_coords( nepf * 3 );
1194 [ + - ][ + - ]: 5544 : error = get_coordinates( &cur_conn[0], nepf, cur_level + 1, &corner_coords[0] );MB_CHK_ERR( error );
[ + - ][ - + ]
[ # # ][ # # ]
1195 : :
1196 [ + - ][ + - ]: 5544 : error = compute_coordinates( cur_level, deg, ftype, &vbuffer[0], vtotal, &corner_coords[0], flag_verts,
1197 [ + - ][ - + ]: 5544 : nverts_prev );MB_CHK_ERR( error );
[ # # ][ # # ]
[ + - ]
1198 : 5544 : }
1199 : :
1200 : : // Step 6: Update the global maps
1201 [ + - ][ - + ]: 22 : error = update_global_ahf( ftype, cur_level, deg );MB_CHK_ERR( error );
[ # # ][ # # ]
1202 : :
1203 : : // Step 7: If edges exists, refine them.
1204 [ + - ][ - + ]: 22 : if( !_inedges.empty() )
1205 : : {
1206 [ # # ][ # # ]: 0 : error = construct_hm_1D( cur_level, deg, ftype, trackvertsF );MB_CHK_ERR( error );
[ # # ][ # # ]
1207 : : }
1208 : :
1209 : 44 : return MB_SUCCESS;
1210 : : }
1211 : :
1212 : 0 : ErrorCode NestedRefine::construct_hm_2D( int cur_level, int deg, EntityType type,
1213 : : std::vector< EntityHandle >& trackvertsE,
1214 : : std::vector< EntityHandle >& trackvertsF )
1215 : : {
1216 : : ErrorCode error;
1217 : :
1218 : 0 : EntityType ftype = MBTRI;
1219 [ # # ]: 0 : if( type == MBHEX ) ftype = MBQUAD;
1220 : :
1221 [ # # ]: 0 : int d = get_index_from_degree( deg );
1222 : 0 : int findex = ftype - 1;
1223 [ # # ][ # # ]: 0 : int cidx = ahf->get_index_in_lmap( *( _incells.begin() ) );
[ # # ]
1224 : :
1225 : 0 : int nepf = ahf->lConnMap2D[ftype - 2].num_verts_in_face;
1226 : 0 : int nepc = ahf->lConnMap3D[cidx].num_edges_in_cell;
1227 : 0 : int nfpc = ahf->lConnMap3D[cidx].num_faces_in_cell;
1228 : :
1229 : 0 : int tnv = refTemplates[findex][d].total_new_verts;
1230 : 0 : int nve = refTemplates[findex][d].nv_edge;
1231 : 0 : int nvf = refTemplates[findex][d].nv_face;
1232 : 0 : int vtotal = nepf + tnv;
1233 : 0 : int etotal = refTemplates[findex][d].total_new_ents;
1234 : :
1235 [ # # ]: 0 : std::vector< EntityHandle > vbuffer( vtotal );
1236 [ # # ]: 0 : std::vector< EntityHandle > ent_buffer( etotal );
1237 : :
1238 [ # # ][ # # ]: 0 : std::vector< EntityHandle > adjents, fconn, cconn;
[ # # ]
1239 [ # # ]: 0 : std::vector< int > leids;
1240 : 0 : int count_nents = 0;
1241 : :
1242 : : int nents_prev, ecount;
1243 [ # # ]: 0 : if( cur_level )
1244 : : {
1245 : 0 : nents_prev = level_mesh[cur_level - 1].num_faces;
1246 : 0 : ecount = level_mesh[cur_level - 1].num_edges * refTemplates[MBEDGE - 1][d].total_new_ents;
1247 : : ;
1248 : : }
1249 : : else
1250 : : {
1251 [ # # ]: 0 : nents_prev = _infaces.size();
1252 [ # # ]: 0 : ecount = _inedges.size() * refTemplates[MBEDGE - 1][d].total_new_ents;
1253 : : ;
1254 : : }
1255 : :
1256 : : // Step 1: Create the subentities via refinement of the previous mesh
1257 [ # # ]: 0 : for( int it = 0; it < nents_prev; it++ )
1258 : : {
1259 : 0 : fconn.clear();
1260 : 0 : cconn.clear();
1261 : 0 : adjents.clear();
1262 : 0 : leids.clear();
1263 [ # # ]: 0 : for( int i = 0; i < vtotal; i++ )
1264 [ # # ]: 0 : vbuffer[i] = 0;
1265 [ # # ]: 0 : for( int i = 0; i < etotal; i++ )
1266 [ # # ]: 0 : ent_buffer[i] = 0;
1267 : :
1268 : : // EntityHandle of the working face
1269 : : EntityHandle face;
1270 [ # # ]: 0 : if( cur_level )
1271 : 0 : face = level_mesh[cur_level - 1].start_face + it;
1272 : : else
1273 [ # # ]: 0 : face = _infaces[it];
1274 : :
1275 [ # # ][ # # ]: 0 : error = get_connectivity( face, cur_level, fconn );MB_CHK_ERR( error );
[ # # ][ # # ]
1276 : :
1277 : : // Add the new handles for old connectivity in the buffer
1278 [ # # ]: 0 : for( int i = 0; i < (int)fconn.size(); i++ )
1279 : : {
1280 [ # # ]: 0 : if( cur_level )
1281 [ # # ][ # # ]: 0 : vbuffer[i] = level_mesh[cur_level].start_vertex + ( fconn[i] - level_mesh[cur_level - 1].start_vertex );
1282 : : else
1283 [ # # ][ # # ]: 0 : vbuffer[i] = level_mesh[cur_level].start_vertex + ( fconn[i] - *_inverts.begin() );
[ # # ][ # # ]
1284 : : }
1285 : :
1286 : : // Add handles for vertices on edges and faces from the already refined cell
1287 : : int fid, lid;
1288 [ # # ][ # # ]: 0 : error = ahf->get_up_adjacencies_face_3d( face, adjents, &leids );MB_CHK_ERR( error );
[ # # ][ # # ]
1289 : :
1290 [ # # ]: 0 : if( cur_level )
1291 [ # # ]: 0 : fid = adjents[0] - level_mesh[cur_level - 1].start_cell;
1292 : : else
1293 [ # # ][ # # ]: 0 : fid = _incells.index( adjents[0] );
1294 : :
1295 [ # # ]: 0 : lid = leids[0];
1296 : :
1297 [ # # ][ # # ]: 0 : error = get_connectivity( adjents[0], cur_level, cconn );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ]
1298 : :
1299 : : // Find the orientation w.r.t the half-face and then add vertices properly.
1300 [ # # ]: 0 : std::vector< EntityHandle > fac_conn( nepf );
1301 [ # # ][ # # ]: 0 : std::vector< EntityHandle > lfac_conn( nepf );
1302 [ # # ]: 0 : for( int j = 0; j < nepf; j++ )
1303 : : {
1304 [ # # ][ # # ]: 0 : fac_conn[j] = fconn[j];
1305 : 0 : int id = ahf->lConnMap3D[cidx].hf2v[lid][j];
1306 [ # # ][ # # ]: 0 : lfac_conn[j] = cconn[id];
1307 : : }
1308 : :
1309 [ # # ][ # # ]: 0 : std::vector< int > le_idx, indices;
[ # # ][ # # ]
1310 : :
1311 [ # # ][ # # ]: 0 : error = reorder_indices( deg, &fac_conn[0], &lfac_conn[0], nepf, le_idx, indices );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ][ # # ]
1312 : :
1313 : : // Add the existing vertices on edges of the already refined cell to the vbuffer
1314 [ # # ]: 0 : for( int j = 0; j < nepf; j++ )
1315 : : {
1316 [ # # ]: 0 : int id = le_idx[j]; // Corresponding local edge
1317 : 0 : int idx = ahf->lConnMap3D[cidx].f2leid[lid][id]; // Local edge in the cell
1318 : :
1319 : : // Get the orientation of the local edge of the face wrt the corresponding local edge in
1320 : : // the cell
1321 : 0 : bool eorient = false;
1322 : 0 : int fnext = ahf->lConnMap2D[ftype - 2].next[j];
1323 : 0 : int idx1 = ahf->lConnMap3D[cidx].e2v[idx][0];
1324 : 0 : int idx2 = ahf->lConnMap3D[cidx].e2v[idx][1];
1325 [ # # ][ # # ]: 0 : if( ( fconn[j] == cconn[idx1] ) && ( fconn[fnext] == cconn[idx2] ) ) eorient = true;
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1326 : :
1327 [ # # ]: 0 : if( eorient )
1328 : : {
1329 [ # # ]: 0 : for( int k = 0; k < nve; k++ )
1330 : : {
1331 : 0 : int ind = refTemplates[findex][d].vert_on_edges[j][k];
1332 [ # # ][ # # ]: 0 : vbuffer[ind] = trackvertsE[fid * nepc * nve + nve * idx + k];
1333 : : }
1334 : : }
1335 : : else
1336 : : {
1337 [ # # ]: 0 : for( int k = 0; k < nve; k++ )
1338 : : {
1339 : 0 : int ind = refTemplates[findex][d].vert_on_edges[j][nve - k - 1];
1340 [ # # ][ # # ]: 0 : vbuffer[ind] = trackvertsE[fid * nepc * nve + nve * idx + k];
1341 : : }
1342 : : }
1343 : : }
1344 : :
1345 : : // Add the existing vertices on the face of the refine cell to vbuffer
1346 [ # # ]: 0 : if( nvf )
1347 : : {
1348 [ # # ]: 0 : for( int k = 0; k < nvf; k++ )
1349 : : {
1350 : 0 : int ind = refTemplates[findex][d].vert_on_faces[0][k];
1351 [ # # ][ # # ]: 0 : vbuffer[ind] = trackvertsF[fid * nfpc * nvf + nvf * lid + indices[k] - 1];
[ # # ]
1352 : : }
1353 : : }
1354 : :
1355 : : // Create the subentities using the template and the vbuffer
1356 [ # # ]: 0 : for( int i = 0; i < etotal; i++ )
1357 : : {
1358 [ # # ]: 0 : for( int k = 0; k < nepf; k++ )
1359 : : {
1360 : 0 : int idx = refTemplates[findex][d].ents_conn[i][k];
1361 [ # # ]: 0 : level_mesh[cur_level].face_conn[nepf * count_nents + k] = vbuffer[idx];
1362 : : }
1363 [ # # ]: 0 : ent_buffer[i] = level_mesh[cur_level].start_face + count_nents;
1364 : 0 : count_nents += 1;
1365 : : }
1366 : :
1367 [ # # ][ # # ]: 0 : error = update_local_ahf( deg, ftype, &vbuffer[0], &ent_buffer[0], etotal );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ][ # # ]
1368 : :
1369 : : // Create the interior edges
1370 : : int id1, id2;
1371 : :
1372 : 0 : int ne = intFacEdg[ftype - 2][d].nie;
1373 [ # # ][ # # ]: 0 : for( int i = 0; i < ne; i++ )
1374 : : {
1375 : 0 : id1 = intFacEdg[ftype - 2][d].ieconn[i][0];
1376 : 0 : id2 = intFacEdg[ftype - 2][d].ieconn[i][1];
1377 [ # # ]: 0 : level_mesh[cur_level].edge_conn[2 * ( ecount )] = vbuffer[id1];
1378 [ # # ]: 0 : level_mesh[cur_level].edge_conn[2 * ( ecount ) + 1] = vbuffer[id2];
1379 : 0 : ecount += 1;
1380 : : }
1381 : 0 : }
1382 : :
1383 : : // Step 6: Update the global maps
1384 [ # # ][ # # ]: 0 : error = update_global_ahf_2D_sub( cur_level, deg );MB_CHK_ERR( error );
[ # # ][ # # ]
1385 : :
1386 : : // Step 7: Update the hf-maps for the edges
1387 [ # # ][ # # ]: 0 : error = update_ahf_1D( cur_level );MB_CHK_ERR( error );
[ # # ][ # # ]
1388 : :
1389 : 0 : return MB_SUCCESS;
1390 : : }
1391 : :
1392 : 16 : ErrorCode NestedRefine::construct_hm_3D( int cur_level, int deg )
1393 : : {
1394 : : ErrorCode error;
1395 [ + - ][ + - ]: 16 : EntityType type = mbImpl->type_from_handle( *( _incells.begin() ) );
1396 [ + + ]: 16 : if( type == MBTET )
1397 : : {
1398 [ - + ][ # # ]: 8 : error = subdivide_tets( cur_level, deg );MB_CHK_ERR( error );
1399 : : }
1400 : : else
1401 : : {
1402 [ - + ][ # # ]: 8 : error = subdivide_cells( type, cur_level, deg );MB_CHK_ERR( error );
1403 : : }
1404 : :
1405 : 16 : return MB_SUCCESS;
1406 : : }
1407 : :
1408 : 8 : ErrorCode NestedRefine::subdivide_cells( EntityType type, int cur_level, int deg )
1409 : : {
1410 : : ErrorCode error;
1411 : : int nverts_prev, nents_prev;
1412 [ + + ]: 8 : if( cur_level )
1413 : : {
1414 : 5 : nverts_prev = level_mesh[cur_level - 1].num_verts;
1415 : 5 : nents_prev = level_mesh[cur_level - 1].num_cells;
1416 : : }
1417 : : else
1418 : : {
1419 [ + - ]: 3 : nverts_prev = _inverts.size();
1420 [ + - ]: 3 : nents_prev = _incells.size();
1421 : : }
1422 : :
1423 : : // Create some book-keeping arrays over the parent mesh to avoid introducing duplicate vertices
1424 : 8 : int cindex = type - 1;
1425 [ + - ]: 8 : int d = get_index_from_degree( deg );
1426 : 8 : int ne = refTemplates[cindex][d].nv_edge;
1427 : 8 : int nvf = refTemplates[cindex][d].nv_face;
1428 : 8 : int nvtotal = refTemplates[cindex][d].total_new_verts;
1429 : :
1430 [ + - ][ + - ]: 8 : int index = ahf->get_index_in_lmap( *( _incells.begin() ) );
[ + - ]
1431 : 8 : int nvpc = ahf->lConnMap3D[index].num_verts_in_cell;
1432 : 8 : int nepc = ahf->lConnMap3D[index].num_edges_in_cell;
1433 : 8 : int nfpc = ahf->lConnMap3D[index].num_faces_in_cell;
1434 : :
1435 : 8 : int vtotal = nvpc + nvtotal;
1436 [ + - ]: 8 : std::vector< EntityHandle > vbuffer( vtotal );
1437 : :
1438 [ + - ]: 16 : std::vector< EntityHandle > trackvertsC_edg( nepc * ne * nents_prev, 0 );
1439 [ + - ]: 16 : std::vector< EntityHandle > trackvertsC_face( nfpc * nvf * nents_prev, 0 );
1440 : :
1441 : 8 : int cur_nverts = level_mesh[cur_level].num_verts;
1442 [ + - ]: 16 : std::vector< int > flag_verts( cur_nverts - nverts_prev, 0 );
1443 : :
1444 : 8 : int count_nverts = nverts_prev;
1445 : 8 : int count_ents = 0;
1446 [ + - ][ + - ]: 16 : std::vector< EntityHandle > conn, cur_conn;
1447 : :
1448 : : // Step 1: Create the subentities via refinement of the previous mesh
1449 [ + + ]: 2393 : for( int cid = 0; cid < nents_prev; cid++ )
1450 : : {
1451 : 2385 : conn.clear();
1452 : 2385 : cur_conn.clear();
1453 [ + + ]: 68260 : for( int i = 0; i < vtotal; i++ )
1454 [ + - ]: 65875 : vbuffer[i] = 0;
1455 : :
1456 : : // EntityHandle of the working cell
1457 : : EntityHandle cell;
1458 [ + + ]: 2385 : if( cur_level )
1459 : 2376 : cell = level_mesh[cur_level - 1].start_cell + cid;
1460 : : else
1461 [ + - ]: 9 : cell = _incells[cid];
1462 : :
1463 [ + - ][ - + ]: 2385 : error = get_connectivity( cell, cur_level, conn );MB_CHK_ERR( error );
[ # # ][ # # ]
1464 : :
1465 : : // Step 1: Add vertices from the current level for the working face that will be used for
1466 : : // subdivision.
1467 : : // Add the corners to vbuffer
1468 [ + + ]: 21465 : for( int i = 0; i < (int)conn.size(); i++ )
1469 : : {
1470 [ + + ]: 19080 : if( cur_level )
1471 [ + - ][ + - ]: 19008 : vbuffer[i] = level_mesh[cur_level].start_vertex + ( conn[i] - level_mesh[cur_level - 1].start_vertex );
1472 : : else
1473 [ + - ][ + - ]: 72 : vbuffer[i] = level_mesh[cur_level].start_vertex + ( conn[i] - *_inverts.begin() );
[ + - ][ + - ]
1474 : :
1475 [ + - ][ + - ]: 19080 : cur_conn.push_back( vbuffer[i] );
1476 : : }
1477 : :
1478 : : // Gather vertices already added to tracking array due to refinement of the sibling cells
1479 [ + + ]: 31005 : for( int i = 0; i < nepc; i++ )
1480 : : {
1481 [ + + ]: 57720 : for( int j = 0; j < ne; j++ )
1482 : : {
1483 : 29100 : int idx = refTemplates[cindex][d].vert_on_edges[i][j];
1484 [ + - ][ + - ]: 29100 : vbuffer[idx] = trackvertsC_edg[cid * nepc * ne + ne * i + j];
1485 : : }
1486 : : }
1487 : :
1488 : : // Add remaining new vertex handles
1489 [ + + ]: 16695 : for( int i = 0; i < nfpc; i++ )
1490 : : {
1491 [ + + ]: 29340 : for( int j = 0; j < nvf; j++ )
1492 : : {
1493 : 15030 : int idx = refTemplates[cindex][d].vert_on_faces[i][j];
1494 [ + - ][ + - ]: 15030 : vbuffer[idx] = trackvertsC_face[cid * nfpc * nvf + nvf * i + j];
1495 : : }
1496 : : }
1497 : :
1498 : : // Add the remaining vertex handles to vbuffer for the current level for the working cell
1499 [ + + ]: 49180 : for( int i = 0; i < nvtotal; i++ )
1500 : : {
1501 [ + - ][ + + ]: 46795 : if( !vbuffer[i + nvpc] )
1502 : : {
1503 [ + - ]: 19995 : vbuffer[i + nvpc] = level_mesh[cur_level].start_vertex + count_nverts;
1504 : 19995 : count_nverts += 1;
1505 : : }
1506 : : }
1507 : :
1508 : : // Step 2: Use the template to obtain the subentities. The coordinates and local ahf maps
1509 : : // are also constructed. Connectivity of the children
1510 : 2385 : int etotal = refTemplates[type - 1][d].total_new_ents;
1511 [ + - ]: 2385 : std::vector< EntityHandle > ent_buffer( etotal );
1512 : :
1513 [ + + ]: 22225 : for( int i = 0; i < etotal; i++ )
1514 : : {
1515 [ + + ]: 178560 : for( int k = 0; k < nvpc; k++ )
1516 : : {
1517 : 158720 : int idx = refTemplates[type - 1][d].ents_conn[i][k];
1518 [ + - ]: 158720 : level_mesh[cur_level].cell_conn[nvpc * count_ents + k] = vbuffer[idx];
1519 : : }
1520 [ + - ]: 19840 : ent_buffer[i] = level_mesh[cur_level].start_cell + count_ents;
1521 : 19840 : count_ents += 1;
1522 : : }
1523 : :
1524 : : // Step 3: Update local ahf maps
1525 [ + - ][ + - ]: 2385 : error = update_local_ahf( deg, type, &vbuffer[0], &ent_buffer[0], etotal );MB_CHK_ERR( error );
[ + - ][ - + ]
[ # # ][ # # ]
1526 : :
1527 : : // Step 4: Update tracking information
1528 [ + - ][ + - ]: 2385 : error = update_tracking_verts( cell, cur_level, deg, trackvertsC_edg, trackvertsC_face, &vbuffer[0] );MB_CHK_ERR( error );
[ - + ][ # # ]
[ # # ]
1529 : :
1530 : : // Step 5: Coordinates of the new vertices
1531 [ + - ][ + - ]: 4770 : std::vector< double > corner_coords( nvpc * 3 );
1532 [ + - ][ + - ]: 2385 : error = get_coordinates( &cur_conn[0], nvpc, cur_level + 1, &corner_coords[0] );MB_CHK_ERR( error );
[ + - ][ - + ]
[ # # ][ # # ]
1533 : :
1534 [ + - ][ + - ]: 2385 : error = compute_coordinates( cur_level, deg, type, &vbuffer[0], vtotal, &corner_coords[0], flag_verts,
1535 [ + - ][ - + ]: 2385 : nverts_prev );MB_CHK_ERR( error );
[ # # ][ # # ]
[ + - ]
1536 : 2385 : }
1537 : :
1538 : : // error = ahf->print_tags(3);
1539 : :
1540 : : // Step 6: Update the global maps
1541 [ + - ][ - + ]: 8 : error = update_global_ahf( type, cur_level, deg );MB_CHK_ERR( error );
[ # # ][ # # ]
1542 : :
1543 : : // Step 7: If edges exists, refine them as well.
1544 [ - + ]: 8 : if( level_mesh[cur_level].num_edges != 0 )
1545 : : {
1546 [ # # ][ # # ]: 0 : error = construct_hm_1D( cur_level, deg, type, trackvertsC_edg );MB_CHK_ERR( error );
[ # # ][ # # ]
1547 : : }
1548 : :
1549 : : // Step 8: If faces exists, refine them as well.
1550 [ + - ][ - + ]: 8 : if( !_infaces.empty() )
1551 : : {
1552 [ # # ][ # # ]: 0 : error = construct_hm_2D( cur_level, deg, type, trackvertsC_edg, trackvertsC_face );MB_CHK_ERR( error );
[ # # ][ # # ]
1553 : : }
1554 : :
1555 : : // error = ahf->print_tags(3);
1556 : :
1557 : 16 : return MB_SUCCESS;
1558 : : }
1559 : :
1560 : 8 : ErrorCode NestedRefine::subdivide_tets( int cur_level, int deg )
1561 : : {
1562 : : ErrorCode error;
1563 : : int nverts_prev, nents_prev;
1564 [ + + ]: 8 : if( cur_level )
1565 : : {
1566 : 5 : nverts_prev = level_mesh[cur_level - 1].num_verts;
1567 : 5 : nents_prev = level_mesh[cur_level - 1].num_cells;
1568 : : }
1569 : : else
1570 : : {
1571 [ + - ]: 3 : nverts_prev = _inverts.size();
1572 [ + - ]: 3 : nents_prev = _incells.size();
1573 : : }
1574 : :
1575 : 8 : EntityType type = MBTET;
1576 : 8 : int cindex = type - 1;
1577 [ + - ]: 8 : int d = get_index_from_degree( deg );
1578 : 8 : int ne = refTemplates[cindex][d].nv_edge;
1579 : 8 : int nvf = refTemplates[cindex][d].nv_face;
1580 : 8 : int nvtotal = refTemplates[cindex][d].total_new_verts;
1581 : :
1582 [ + - ][ + - ]: 8 : int index = ahf->get_index_in_lmap( *( _incells.begin() ) );
[ + - ]
1583 : 8 : int nvpc = ahf->lConnMap3D[index].num_verts_in_cell;
1584 : 8 : int nepc = ahf->lConnMap3D[index].num_edges_in_cell;
1585 : 8 : int nfpc = ahf->lConnMap3D[index].num_faces_in_cell;
1586 : :
1587 : : // Create vertex buffer
1588 : 8 : int vtotal = nvpc + nvtotal;
1589 [ + - ]: 8 : std::vector< EntityHandle > vbuffer( vtotal );
1590 : :
1591 : : // Create book-keeping arrays over the parent mesh to avoid introducing duplicate vertices
1592 [ + - ]: 16 : std::vector< EntityHandle > trackvertsC_edg( nepc * ne * nents_prev, 0 );
1593 [ + - ]: 16 : std::vector< EntityHandle > trackvertsC_face( nfpc * nvf * nents_prev, 0 );
1594 : :
1595 : 8 : int cur_nverts = level_mesh[cur_level].num_verts;
1596 [ + - ]: 16 : std::vector< int > flag_verts( cur_nverts - nverts_prev, 0 );
1597 [ + - ]: 16 : std::vector< int > cell_patterns( nents_prev, 0 );
1598 : :
1599 : 8 : int count_nverts = nverts_prev;
1600 : 8 : int count_ents = 0;
1601 [ + - ][ + - ]: 16 : std::vector< EntityHandle > conn, cur_conn;
1602 : :
1603 : : // Step 1: Create the subentities via refinement of the previous mesh
1604 [ + + ]: 2393 : for( int cid = 0; cid < nents_prev; cid++ )
1605 : : {
1606 : 2385 : conn.clear();
1607 : 2385 : cur_conn.clear();
1608 [ + + ]: 26635 : for( int i = 0; i < vtotal; i++ )
1609 [ + - ]: 24250 : vbuffer[i] = 0;
1610 : :
1611 : : // EntityHandle of the working cell
1612 : : EntityHandle cell;
1613 [ + + ]: 2385 : if( cur_level )
1614 : 2376 : cell = level_mesh[cur_level - 1].start_cell + cid;
1615 : : else
1616 [ + - ]: 9 : cell = _incells[cid];
1617 : :
1618 [ + - ][ - + ]: 2385 : error = get_connectivity( cell, cur_level, conn );MB_CHK_ERR( error );
[ # # ][ # # ]
1619 : :
1620 : : // Step 1: Add vertices from the current level for the working face that will be used for
1621 : : // subdivision.
1622 : : // Add the corners to vbuffer
1623 [ + + ]: 11925 : for( int i = 0; i < (int)conn.size(); i++ )
1624 : : {
1625 [ + + ]: 9540 : if( cur_level )
1626 [ + - ][ + - ]: 9504 : vbuffer[i] = level_mesh[cur_level].start_vertex + ( conn[i] - level_mesh[cur_level - 1].start_vertex );
1627 : : else
1628 [ + - ][ + - ]: 36 : vbuffer[i] = level_mesh[cur_level].start_vertex + ( conn[i] - *_inverts.begin() );
[ + - ][ + - ]
1629 : :
1630 [ + - ][ + - ]: 9540 : cur_conn.push_back( vbuffer[i] );
1631 : : }
1632 : :
1633 : : // Gather vertices already added to tracking array due to refinement of the sibling cells
1634 [ + + ]: 16695 : for( int i = 0; i < nepc; i++ )
1635 : : {
1636 [ + + ]: 28860 : for( int j = 0; j < ne; j++ )
1637 : : {
1638 : 14550 : int idx = refTemplates[cindex][d].vert_on_edges[i][j];
1639 [ + - ][ + - ]: 14550 : vbuffer[idx] = trackvertsC_edg[cid * nepc * ne + ne * i + j];
1640 : : }
1641 : : }
1642 : :
1643 : : // Add remaining new vertex handles
1644 [ + + ]: 11925 : for( int i = 0; i < nfpc; i++ )
1645 : : {
1646 [ + + ]: 9700 : for( int j = 0; j < nvf; j++ )
1647 : : {
1648 : 160 : int idx = refTemplates[cindex][d].vert_on_faces[i][j];
1649 [ + - ][ + - ]: 160 : vbuffer[idx] = trackvertsC_face[cid * nfpc * nvf + nvf * i + j];
1650 : : }
1651 : : }
1652 : :
1653 : : // Add the remaining vertex handles to vbuffer for the current level for the working cell
1654 [ + + ]: 17095 : for( int i = 0; i < nvtotal; i++ )
1655 : : {
1656 [ + - ][ + + ]: 14710 : if( !vbuffer[i + nvpc] )
1657 : : {
1658 [ + - ]: 3580 : vbuffer[i + nvpc] = level_mesh[cur_level].start_vertex + count_nverts;
1659 : 3580 : count_nverts += 1;
1660 : : }
1661 : : }
1662 : :
1663 : : // Step 2: Coordinates of the new vertices
1664 [ + - ]: 2385 : std::vector< double > corner_coords( nvpc * 3 );
1665 [ + - ][ + - ]: 2385 : error = get_coordinates( &cur_conn[0], nvpc, cur_level + 1, &corner_coords[0] );MB_CHK_ERR( error );
[ + - ][ - + ]
[ # # ][ # # ]
1666 : :
1667 [ + - ][ + - ]: 2385 : error = compute_coordinates( cur_level, deg, type, &vbuffer[0], vtotal, &corner_coords[0], flag_verts,
1668 [ + - ][ - + ]: 2385 : nverts_prev );MB_CHK_ERR( error );
[ # # ][ # # ]
1669 : :
1670 : : // Step 3: Choose the tet refine pattern to be used for this tet
1671 [ + - ][ + - ]: 2385 : int diag = find_shortest_diagonal_octahedron( cur_level, deg, &vbuffer[0] );
1672 : 2385 : int pat_id = diag + 2;
1673 [ + - ]: 2385 : cell_patterns[cid] = pat_id;
1674 : :
1675 : : // Step 4: Use the template to obtain the subentities. The coordinates and local ahf maps
1676 : : // are also constructed. Connectivity of the children
1677 : 2385 : int etotal = refTemplates[pat_id][d].total_new_ents;
1678 [ + - ][ + - ]: 4770 : std::vector< EntityHandle > ent_buffer( etotal );
1679 : :
1680 [ + + ]: 22225 : for( int i = 0; i < etotal; i++ )
1681 : : {
1682 [ + + ]: 99200 : for( int k = 0; k < nvpc; k++ )
1683 : : {
1684 : 79360 : int idx = refTemplates[pat_id][d].ents_conn[i][k];
1685 [ + - ]: 79360 : level_mesh[cur_level].cell_conn[nvpc * count_ents + k] = vbuffer[idx];
1686 : : }
1687 [ + - ]: 19840 : ent_buffer[i] = level_mesh[cur_level].start_cell + count_ents;
1688 : 19840 : count_ents += 1;
1689 : : }
1690 : :
1691 : : // Step 5: Update local ahf maps
1692 [ + - ][ + - ]: 2385 : error = update_local_ahf( deg, MBTET, pat_id, &vbuffer[0], &ent_buffer[0], etotal );MB_CHK_ERR( error );
[ + - ][ - + ]
[ # # ][ # # ]
1693 : :
1694 : : // Step 6: Update tracking information
1695 [ + - ][ + - ]: 2385 : error = update_tracking_verts( cell, cur_level, deg, trackvertsC_edg, trackvertsC_face, &vbuffer[0] );MB_CHK_ERR( error );
[ - + ][ # # ]
[ # # ][ + - ]
1696 : 2385 : }
1697 : :
1698 : : // Step 7: Update the global maps
1699 : : // error = update_global_ahf(cur_level, deg, cell_patterns); MB_CHK_ERR(error);
1700 [ + - ][ - + ]: 8 : error = update_global_ahf( type, cur_level, deg, &cell_patterns );MB_CHK_ERR( error );
[ # # ][ # # ]
1701 : :
1702 : : // Step 8: If edges exists, refine them as well.
1703 [ - + ]: 8 : if( level_mesh[cur_level].num_edges != 0 )
1704 : : {
1705 [ # # ][ # # ]: 0 : error = construct_hm_1D( cur_level, deg, type, trackvertsC_edg );MB_CHK_ERR( error );
[ # # ][ # # ]
1706 : : }
1707 : :
1708 : : // Step 9: If faces exists, refine them as well.
1709 [ + - ][ - + ]: 8 : if( !_infaces.empty() )
1710 : : {
1711 [ # # ][ # # ]: 0 : error = construct_hm_2D( cur_level, deg, type, trackvertsC_edg, trackvertsC_face );MB_CHK_ERR( error );
[ # # ][ # # ]
1712 : : }
1713 : :
1714 : 16 : return MB_SUCCESS;
1715 : : }
1716 : :
1717 : 10314 : ErrorCode NestedRefine::compute_coordinates( int cur_level, int deg, EntityType type, EntityHandle* vbuffer, int vtotal,
1718 : : double* corner_coords, std::vector< int >& vflag, int nverts_prev )
1719 : : {
1720 : 10314 : EntityHandle vstart = level_mesh[cur_level].start_vertex;
1721 : 10314 : int d = get_index_from_degree( deg );
1722 : :
1723 [ + + ]: 10314 : if( type == MBTRI )
1724 : : {
1725 : : double xi, eta, N[3];
1726 [ + - ][ + - ]: 4997 : int findex = mbImpl->type_from_handle( *( _infaces.begin() ) ) - 1;
[ + - ]
1727 : :
1728 [ + + ]: 25142 : for( int i = 3; i < vtotal; i++ )
1729 : : {
1730 [ + - ][ + + ]: 20145 : if( vflag[vbuffer[i] - vstart - nverts_prev] ) continue;
1731 : :
1732 : 11210 : xi = refTemplates[findex][d].vert_nat_coord[i - 3][0];
1733 : 11210 : eta = refTemplates[findex][d].vert_nat_coord[i - 3][1];
1734 : 11210 : N[0] = 1 - xi - eta;
1735 : 11210 : N[1] = xi;
1736 : 11210 : N[2] = eta;
1737 : :
1738 : 11210 : double x = 0, y = 0, z = 0;
1739 [ + + ]: 44840 : for( int j = 0; j < 3; j++ )
1740 : : {
1741 : 33630 : x += N[j] * corner_coords[3 * j];
1742 : 33630 : y += N[j] * corner_coords[3 * j + 1];
1743 : 33630 : z += N[j] * corner_coords[3 * j + 2];
1744 : : }
1745 : :
1746 [ + - ]: 11210 : level_mesh[cur_level].coordinates[0][vbuffer[i] - vstart] = x;
1747 [ + - ]: 11210 : level_mesh[cur_level].coordinates[1][vbuffer[i] - vstart] = y;
1748 [ + - ]: 11210 : level_mesh[cur_level].coordinates[2][vbuffer[i] - vstart] = z;
1749 [ + - ]: 11210 : vflag[vbuffer[i] - vstart - nverts_prev] = 1;
1750 : : }
1751 : : }
1752 [ + + ]: 5317 : else if( type == MBQUAD )
1753 : : {
1754 : : double xi, eta, N[4];
1755 [ + - ][ + - ]: 547 : int findex = mbImpl->type_from_handle( *( _infaces.begin() ) ) - 1;
[ + - ]
1756 : :
1757 [ + + ]: 10552 : for( int i = 4; i < vtotal; i++ )
1758 : : {
1759 [ + - ][ + + ]: 10005 : if( vflag[vbuffer[i] - vstart - nverts_prev] ) continue;
1760 : :
1761 : 7549 : xi = refTemplates[findex][d].vert_nat_coord[i - 4][0];
1762 : 7549 : eta = refTemplates[findex][d].vert_nat_coord[i - 4][1];
1763 : 7549 : N[0] = ( 1 - xi ) * ( 1 - eta ) / 4;
1764 : 7549 : N[1] = ( 1 + xi ) * ( 1 - eta ) / 4;
1765 : 7549 : N[2] = ( 1 + xi ) * ( 1 + eta ) / 4, N[3] = ( 1 - xi ) * ( 1 + eta ) / 4;
1766 : :
1767 : 7549 : double x = 0, y = 0, z = 0;
1768 [ + + ]: 37745 : for( int j = 0; j < 4; j++ )
1769 : : {
1770 : 30196 : x += N[j] * corner_coords[3 * j];
1771 : 30196 : y += N[j] * corner_coords[3 * j + 1];
1772 : 30196 : z += N[j] * corner_coords[3 * j + 2];
1773 : : }
1774 : :
1775 [ + - ]: 7549 : level_mesh[cur_level].coordinates[0][vbuffer[i] - vstart] = x;
1776 [ + - ]: 7549 : level_mesh[cur_level].coordinates[1][vbuffer[i] - vstart] = y;
1777 [ + - ]: 7549 : level_mesh[cur_level].coordinates[2][vbuffer[i] - vstart] = z;
1778 [ + - ]: 7549 : vflag[vbuffer[i] - vstart - nverts_prev] = 1;
1779 : : }
1780 : : }
1781 [ + + ]: 4770 : else if( type == MBTET )
1782 : : {
1783 : : double xi, eta, mu, N[4];
1784 [ + - ][ + - ]: 2385 : int cindex = mbImpl->type_from_handle( *( _incells.begin() ) ) - 1;
[ + - ]
1785 : :
1786 [ + + ]: 17095 : for( int i = 4; i < vtotal; i++ )
1787 : : {
1788 [ + - ][ + + ]: 14710 : if( vflag[vbuffer[i] - vstart - nverts_prev] ) continue;
1789 : :
1790 : 3580 : xi = refTemplates[cindex][d].vert_nat_coord[i - 4][0];
1791 : 3580 : eta = refTemplates[cindex][d].vert_nat_coord[i - 4][1];
1792 : 3580 : mu = refTemplates[cindex][d].vert_nat_coord[i - 4][2];
1793 : :
1794 : 3580 : N[0] = 1 - xi - eta - mu;
1795 : 3580 : N[1] = xi;
1796 : 3580 : N[2] = eta, N[3] = mu;
1797 : :
1798 : 3580 : double x = 0, y = 0, z = 0;
1799 [ + + ]: 17900 : for( int j = 0; j < 4; j++ )
1800 : : {
1801 : 14320 : x += N[j] * corner_coords[3 * j];
1802 : 14320 : y += N[j] * corner_coords[3 * j + 1];
1803 : 14320 : z += N[j] * corner_coords[3 * j + 2];
1804 : : }
1805 : :
1806 [ + - ]: 3580 : level_mesh[cur_level].coordinates[0][vbuffer[i] - vstart] = x;
1807 [ + - ]: 3580 : level_mesh[cur_level].coordinates[1][vbuffer[i] - vstart] = y;
1808 [ + - ]: 3580 : level_mesh[cur_level].coordinates[2][vbuffer[i] - vstart] = z;
1809 [ + - ]: 3580 : vflag[vbuffer[i] - vstart - nverts_prev] = 1;
1810 : : }
1811 : : }
1812 [ - + ]: 2385 : else if( type == MBPRISM )
1813 : : {
1814 : : double xi, eta, mu, N[6];
1815 [ # # ][ # # ]: 0 : int cindex = mbImpl->type_from_handle( *( _incells.begin() ) ) - 1;
[ # # ]
1816 : :
1817 [ # # ]: 0 : for( int i = 6; i < vtotal; i++ )
1818 : : {
1819 [ # # ][ # # ]: 0 : if( vflag[vbuffer[i] - vstart - nverts_prev] ) continue;
1820 : :
1821 : 0 : xi = refTemplates[cindex][d].vert_nat_coord[i - 6][0];
1822 : 0 : eta = refTemplates[cindex][d].vert_nat_coord[i - 6][1];
1823 : 0 : mu = refTemplates[cindex][d].vert_nat_coord[i - 6][2];
1824 : :
1825 : 0 : N[0] = ( 1 - xi - eta ) * ( 1 - mu ), N[1] = xi * ( 1 - mu ), N[2] = eta * ( 1 - mu ),
1826 : 0 : N[3] = ( 1 - xi - eta ) * ( 1 + mu ), N[4] = xi * ( 1 + mu ), N[5] = eta * ( 1 + mu );
1827 : :
1828 : 0 : double x = 0, y = 0, z = 0;
1829 [ # # ]: 0 : for( int j = 0; j < 6; j++ )
1830 : : {
1831 : 0 : x += N[j] * corner_coords[3 * j];
1832 : 0 : y += N[j] * corner_coords[3 * j + 1];
1833 : 0 : z += N[j] * corner_coords[3 * j + 2];
1834 : : }
1835 : :
1836 [ # # ]: 0 : level_mesh[cur_level].coordinates[0][vbuffer[i] - vstart] = x;
1837 [ # # ]: 0 : level_mesh[cur_level].coordinates[1][vbuffer[i] - vstart] = y;
1838 [ # # ]: 0 : level_mesh[cur_level].coordinates[2][vbuffer[i] - vstart] = z;
1839 [ # # ]: 0 : vflag[vbuffer[i] - vstart - nverts_prev] = 1;
1840 : : }
1841 : : }
1842 [ + - ]: 2385 : else if( type == MBHEX )
1843 : : {
1844 : : double xi, eta, mu, N[8];
1845 : : double d1, d2, d3, s1, s2, s3;
1846 [ + - ][ + - ]: 2385 : int cindex = mbImpl->type_from_handle( *( _incells.begin() ) ) - 1;
[ + - ]
1847 : :
1848 [ + + ]: 49180 : for( int i = 8; i < vtotal; i++ )
1849 : : {
1850 : :
1851 [ + - ][ + + ]: 46795 : if( vflag[vbuffer[i] - vstart - nverts_prev] ) continue;
1852 : :
1853 : 19995 : xi = refTemplates[cindex][d].vert_nat_coord[i - 8][0];
1854 : 19995 : eta = refTemplates[cindex][d].vert_nat_coord[i - 8][1];
1855 : 19995 : mu = refTemplates[cindex][d].vert_nat_coord[i - 8][2];
1856 : :
1857 : 19995 : d1 = 1 - xi;
1858 : 19995 : d2 = 1 - eta;
1859 : 19995 : d3 = 1 - mu;
1860 : 19995 : s1 = 1 + xi;
1861 : 19995 : s2 = 1 + eta;
1862 : 19995 : s3 = 1 + mu;
1863 : 19995 : N[0] = ( d1 * d2 * d3 ) / 8;
1864 : 19995 : N[1] = ( s1 * d2 * d3 ) / 8;
1865 : 19995 : N[2] = ( s1 * s2 * d3 ) / 8;
1866 : 19995 : N[3] = ( d1 * s2 * d3 ) / 8;
1867 : 19995 : N[4] = ( d1 * d2 * s3 ) / 8;
1868 : 19995 : N[5] = ( s1 * d2 * s3 ) / 8;
1869 : 19995 : N[6] = ( s1 * s2 * s3 ) / 8;
1870 : 19995 : N[7] = ( d1 * s2 * s3 ) / 8;
1871 : :
1872 : 19995 : double x = 0, y = 0, z = 0;
1873 [ + + ]: 179955 : for( int j = 0; j < 8; j++ )
1874 : : {
1875 : 159960 : x += N[j] * corner_coords[3 * j];
1876 : 159960 : y += N[j] * corner_coords[3 * j + 1];
1877 : 159960 : z += N[j] * corner_coords[3 * j + 2];
1878 : : }
1879 : :
1880 [ + - ]: 19995 : level_mesh[cur_level].coordinates[0][vbuffer[i] - vstart] = x;
1881 [ + - ]: 19995 : level_mesh[cur_level].coordinates[1][vbuffer[i] - vstart] = y;
1882 [ + - ]: 19995 : level_mesh[cur_level].coordinates[2][vbuffer[i] - vstart] = z;
1883 : :
1884 [ + - ]: 19995 : vflag[vbuffer[i] - vstart - nverts_prev] = 1;
1885 : : }
1886 : : }
1887 : 10314 : return MB_SUCCESS;
1888 : : }
1889 : : /**********************************
1890 : : * Parallel Communication *
1891 : : * ********************************/
1892 : :
1893 : : #ifdef MOAB_HAVE_MPI
1894 : 0 : ErrorCode NestedRefine::resolve_shared_ents_parmerge( int level, EntityHandle levelset )
1895 : : {
1896 : : // TEMP: Add the adjacencies for MOAB-native DS
1897 : : // NOTE (VSM): This is expensive since it creates a doubly
1898 : : // redundant copy of the adjacency data in both MOAB-native
1899 : : // and AHF. Need to fix this with AHF optimized branch.
1900 : : ErrorCode error;
1901 : : ReadUtilIface* read_iface;
1902 [ # # ][ # # ]: 0 : error = mbImpl->query_interface( read_iface );MB_CHK_ERR( error );
[ # # ][ # # ]
1903 [ # # ]: 0 : if( level_mesh[level].num_edges != 0 )
1904 : : {
1905 : : error = read_iface->update_adjacencies( level_mesh[level].start_edge, level_mesh[level].num_edges, 2,
1906 [ # # ][ # # ]: 0 : level_mesh[level].edge_conn );MB_CHK_ERR( error );
[ # # ][ # # ]
1907 : : }
1908 [ # # ]: 0 : if( level_mesh[level].num_faces != 0 )
1909 : : {
1910 [ # # ][ # # ]: 0 : EntityType type = mbImpl->type_from_handle( *( _infaces.begin() ) );
[ # # ]
1911 : 0 : int nvpf = ahf->lConnMap2D[type - 2].num_verts_in_face;
1912 : : error = read_iface->update_adjacencies( level_mesh[level].start_face, level_mesh[level].num_faces, nvpf,
1913 [ # # ][ # # ]: 0 : level_mesh[level].face_conn );MB_CHK_ERR( error );
[ # # ][ # # ]
1914 : : }
1915 [ # # ]: 0 : if( level_mesh[level].num_cells != 0 )
1916 : : {
1917 [ # # ][ # # ]: 0 : int index = ahf->get_index_in_lmap( *_incells.begin() );
[ # # ]
1918 : 0 : int nvpc = ahf->lConnMap3D[index].num_verts_in_cell;
1919 : : error = read_iface->update_adjacencies( level_mesh[level].start_cell, level_mesh[level].num_cells, nvpc,
1920 [ # # ][ # # ]: 0 : level_mesh[level].cell_conn );MB_CHK_ERR( error );
[ # # ][ # # ]
1921 : : }
1922 : :
1923 [ # # ][ # # ]: 0 : if( pcomm->size() > 1 )
1924 : : {
1925 : :
1926 : : // get all entities on the rootset
1927 [ # # ][ # # ]: 0 : moab::Range vtxs, edgs, facs, elms;
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1928 [ # # ][ # # ]: 0 : error = mbImpl->get_entities_by_dimension( levelset, 0, vtxs, false );MB_CHK_ERR( error );
[ # # ][ # # ]
1929 [ # # ][ # # ]: 0 : error = mbImpl->get_entities_by_dimension( levelset, 1, edgs, false );MB_CHK_ERR( error );
[ # # ][ # # ]
1930 [ # # ][ # # ]: 0 : error = mbImpl->get_entities_by_dimension( levelset, 2, facs, false );MB_CHK_ERR( error );
[ # # ][ # # ]
1931 [ # # ][ # # ]: 0 : error = mbImpl->get_entities_by_dimension( levelset, 3, elms, false );MB_CHK_ERR( error );
[ # # ][ # # ]
1932 : :
1933 : : // set the parallel partition tag data
1934 : : moab::Tag part_tag;
1935 [ # # ]: 0 : int partid = pcomm->rank(), dum_id = -1;
1936 : : error = mbImpl->tag_get_handle( "PARALLEL_PARTITION", 1, moab::MB_TYPE_INTEGER, part_tag,
1937 [ # # ][ # # ]: 0 : moab::MB_TAG_CREAT | moab::MB_TAG_SPARSE, &dum_id );MB_CHK_ERR( error );
[ # # ][ # # ]
1938 [ # # ][ # # ]: 0 : error = mbImpl->tag_set_data( part_tag, &levelset, 1, &partid );MB_CHK_ERR( error );
[ # # ][ # # ]
1939 : : //
1940 : : // Now that we have the local piece of the mesh refined consistently,
1941 : : // call parallel merge instead of resolved_shared to stitch together the meshes
1942 : : // and to handle parallel communication of remote proc/entity-handle pairs for
1943 : : // shared + non-owned interfaces entities.
1944 : : //
1945 : : // TODO: This needs to be replaced by the following scheme in the future as
1946 : : // an optimization step.
1947 : : // > Assign global IDs consistently for shared entities so that parallel
1948 : : // > resolve shared ents can happen out of the box. This is the fastest option.
1949 : :
1950 [ # # ][ # # ]: 0 : ParallelMergeMesh pm( pcomm, 1e-08 );
1951 [ # # ][ # # ]: 0 : error = pm.merge( levelset, true );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ]
1952 : :
1953 : : //
1954 : : // Parallel Communication complete - all entities resolved
1955 : : //
1956 : : }
1957 : 0 : return MB_SUCCESS;
1958 : : }
1959 : :
1960 : 0 : ErrorCode NestedRefine::resolve_shared_ents_opt( EntityHandle* hm_set, int num_levels )
1961 : : {
1962 [ # # ][ # # ]: 0 : assert( pcomm->size() > 1 );
1963 : :
1964 : : ErrorCode error;
1965 : :
1966 : : // Step 1A: Pre-processing: setting the parallel partition tag data
1967 [ # # ]: 0 : for( int i = 0; i < num_levels; i++ )
1968 : : {
1969 : : Tag part_tag;
1970 [ # # ]: 0 : int partid = pcomm->rank(), dum_id = -1;
1971 : : error = mbImpl->tag_get_handle( "PARALLEL_PARTITION", 1, moab::MB_TYPE_INTEGER, part_tag,
1972 [ # # ][ # # ]: 0 : moab::MB_TAG_CREAT | moab::MB_TAG_SPARSE, &dum_id );MB_CHK_ERR( error );
[ # # ][ # # ]
1973 [ # # ][ # # ]: 0 : error = mbImpl->tag_set_data( part_tag, &hm_set[i], 1, &partid );MB_CHK_ERR( error );
[ # # ][ # # ]
1974 : : }
1975 : :
1976 : : // Step 1B: Pre-processing: gather all shared entities and list entities shared with each
1977 : : // sharing processor
1978 : :
1979 : : // All shared processors
1980 [ # # ]: 0 : std::set< unsigned int > shprocs;
1981 [ # # ][ # # ]: 0 : error = pcomm->get_comm_procs( shprocs );MB_CHK_ERR( error );
[ # # ][ # # ]
1982 : :
1983 [ # # ]: 0 : std::vector< int > sharedprocs;
1984 [ # # ][ # # ]: 0 : for( std::set< unsigned int >::iterator it = shprocs.begin(); it != shprocs.end(); it++ )
[ # # ]
1985 [ # # ][ # # ]: 0 : sharedprocs.push_back( *it );
1986 : 0 : int nprocs = sharedprocs.size();
1987 : :
1988 : : // Create buffer variables storing the entities to be sent and received
1989 [ # # ]: 0 : std::vector< std::vector< int > > nsharedEntsperproc( nprocs );
1990 [ # # ]: 0 : std::vector< std::vector< EntityHandle > > localBuffs( nprocs );
1991 [ # # ]: 0 : std::vector< std::vector< EntityHandle > > remlocalBuffs( nprocs );
1992 [ # # ]: 0 : std::vector< std::vector< EntityHandle > > remoteBuffs( nprocs );
1993 : :
1994 : : int i;
1995 [ # # ]: 0 : Range sharedentities;
1996 : :
1997 [ # # ]: 0 : for( i = 0; i < nprocs; i++ )
1998 : : {
1999 : : // List of shared entities at the coarsest level
2000 [ # # ]: 0 : sharedentities.clear();
2001 [ # # ][ # # ]: 0 : error = pcomm->get_shared_entities( sharedprocs[i], sharedentities, -1, true );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ]
2002 : :
2003 : : // Get the list shared edges and vertices that are not part of the shared edges
2004 [ # # ]: 0 : Range allEnts;
2005 [ # # ][ # # ]: 0 : error = collect_shared_entities_by_dimension( sharedentities, allEnts );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ]
2006 : :
2007 [ # # ][ # # ]: 0 : Range V0, E0, F0;
[ # # ][ # # ]
[ # # ][ # # ]
2008 [ # # ][ # # ]: 0 : V0 = allEnts.subset_by_dimension( 0 );
2009 [ # # ][ # # ]: 0 : E0 = allEnts.subset_by_dimension( 1 );
2010 [ # # ][ # # ]: 0 : F0 = allEnts.subset_by_dimension( 2 );
2011 : :
2012 : : // Step 2A: Prepare msg to be sent:
2013 : : //
2014 : : // FList = <F, FC, FE> where F, FC and FE are vectors containing the faces, their
2015 : : // connectivities and edges. F = <F_0, F_1, F_2, ..., F_L> where
2016 : : // F_0 is the list of shared faces at the coarsest level,
2017 : : // F_i are the list of children faces at subsequent levels.
2018 : : // FC vector contains the connectivities of F_i's and FE vector contains the bounding edges
2019 : : // of F_i's.
2020 : : //
2021 : : // EList = <E, EC> where E and EC are vectors containing the edges and their connectivities.
2022 : : // E = <E_0, E_1, ..., E_L> where
2023 : : // E_0 is the list of shared edges at the coarsest level and
2024 : : // E_i are the list of children edges at subsequent levels.
2025 : : // The EC vector contains the connectivities of E_i's.
2026 : : //
2027 : : // VList = <V> = <V_0, V_1, ...., V_L> where V_0 are shared vertices at the coarsest level
2028 : : // and V_i are the duplicates in the subsequent levels.
2029 : :
2030 [ # # ][ # # ]: 0 : std::vector< EntityHandle > locFList, remFList;
[ # # ][ # # ]
2031 [ # # ][ # # ]: 0 : std::vector< EntityHandle > locEList, remEList;
[ # # ][ # # ]
2032 [ # # ][ # # ]: 0 : std::vector< EntityHandle > locVList, remVList;
[ # # ][ # # ]
2033 : :
2034 : : // collect faces
2035 [ # # ][ # # ]: 0 : if( !F0.empty() )
2036 : : {
2037 [ # # ][ # # ]: 0 : error = collect_FList( sharedprocs[i], F0, locFList, remFList );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ][ # # ]
2038 : : }
2039 : :
2040 : : // collect edges
2041 [ # # ][ # # ]: 0 : if( !E0.empty() )
2042 : : {
2043 [ # # ][ # # ]: 0 : error = collect_EList( sharedprocs[i], E0, locEList, remEList );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ][ # # ]
2044 : : }
2045 : :
2046 : : // collect vertices
2047 [ # # ][ # # ]: 0 : if( !V0.empty() )
2048 : : {
2049 [ # # ][ # # ]: 0 : error = collect_VList( sharedprocs[i], V0, locVList, remVList );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ][ # # ]
2050 : : }
2051 : :
2052 : : // Step 2B: Add data to NR local buffer to be sent
2053 [ # # ][ # # ]: 0 : std::vector< int > msgsz;
2054 [ # # ][ # # ]: 0 : msgsz.push_back( F0.size() );
2055 [ # # ]: 0 : msgsz.push_back( locFList.size() );
2056 [ # # ][ # # ]: 0 : msgsz.push_back( E0.size() );
2057 [ # # ]: 0 : msgsz.push_back( locEList.size() );
2058 [ # # ][ # # ]: 0 : msgsz.push_back( V0.size() );
2059 [ # # ]: 0 : msgsz.push_back( locVList.size() );
2060 [ # # ][ # # ]: 0 : nsharedEntsperproc[i].insert( nsharedEntsperproc[i].end(), msgsz.begin(), msgsz.end() );
[ # # ]
2061 : :
2062 [ # # ][ # # ]: 0 : if( !F0.empty() )
2063 : : {
2064 [ # # ][ # # ]: 0 : localBuffs[i].insert( localBuffs[i].end(), locFList.begin(), locFList.end() );
[ # # ]
2065 [ # # ][ # # ]: 0 : remlocalBuffs[i].insert( remlocalBuffs[i].end(), remFList.begin(), remFList.end() );
[ # # ]
2066 : : }
2067 [ # # ][ # # ]: 0 : if( !E0.empty() )
2068 : : {
2069 [ # # ][ # # ]: 0 : localBuffs[i].insert( localBuffs[i].end(), locEList.begin(), locEList.end() );
[ # # ]
2070 [ # # ][ # # ]: 0 : remlocalBuffs[i].insert( remlocalBuffs[i].end(), remEList.begin(), remEList.end() );
[ # # ]
2071 : : }
2072 [ # # ][ # # ]: 0 : if( !V0.empty() )
2073 : : {
2074 [ # # ][ # # ]: 0 : localBuffs[i].insert( localBuffs[i].end(), locVList.begin(), locVList.end() );
[ # # ]
2075 [ # # ][ # # ]: 0 : remlocalBuffs[i].insert( remlocalBuffs[i].end(), remVList.begin(), remVList.end() );
[ # # ]
2076 : : }
2077 : 0 : }
2078 : :
2079 : : // Step 3: Send and receive the remote collection of child ents
2080 [ # # ][ # # ]: 0 : error = pcomm->send_recv_entities( sharedprocs, nsharedEntsperproc, remlocalBuffs, remoteBuffs );MB_CHK_ERR( error );
[ # # ][ # # ]
2081 : :
2082 : : // Step 5: Resolve shared child entities and update parallel tags
2083 [ # # ]: 0 : std::multimap< EntityHandle, int > rprocs;
2084 [ # # ]: 0 : std::multimap< EntityHandle, EntityHandle > rhandles;
2085 : :
2086 [ # # ][ # # ]: 0 : error = decipher_remote_handles( sharedprocs, nsharedEntsperproc, localBuffs, remoteBuffs, rprocs, rhandles );MB_CHK_ERR( error );
[ # # ][ # # ]
2087 : :
2088 : : // Step 6: Update pcomm tags
2089 [ # # ][ # # ]: 0 : error = update_parallel_tags( rprocs, rhandles );MB_CHK_ERR( error );
[ # # ][ # # ]
2090 : :
2091 : 0 : return MB_SUCCESS;
2092 : : }
2093 : :
2094 : 0 : ErrorCode NestedRefine::collect_shared_entities_by_dimension( Range sharedEnts, Range& allEnts )
2095 : : {
2096 : : ErrorCode error;
2097 : :
2098 [ # # ][ # # ]: 0 : Range F0, E0, V0, E0all, V0all;
[ # # ][ # # ]
[ # # ]
2099 [ # # ]: 0 : std::vector< EntityHandle > ents;
2100 : :
2101 [ # # ][ # # ]: 0 : F0 = sharedEnts.subset_by_dimension( 2 );
2102 [ # # ][ # # ]: 0 : E0all = sharedEnts.subset_by_dimension( 1 );
2103 [ # # ][ # # ]: 0 : V0all = sharedEnts.subset_by_dimension( 0 );
2104 : :
2105 [ # # ][ # # ]: 0 : if( !F0.empty() )
2106 : : {
2107 [ # # ][ # # ]: 0 : Range edges, verts;
[ # # ]
2108 : :
2109 [ # # ][ # # ]: 0 : for( Range::iterator it = F0.begin(); it != F0.end(); it++ )
[ # # ][ # # ]
[ # # ]
2110 : : {
2111 : 0 : ents.clear();
2112 [ # # ][ # # ]: 0 : error = ahf->get_adjacencies( *it, 1, ents );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ]
2113 [ # # ][ # # ]: 0 : std::copy( ents.begin(), ents.end(), range_inserter( edges ) );
2114 : 0 : ents.clear();
2115 [ # # ][ # # ]: 0 : error = mbImpl->get_connectivity( &( *it ), 0, ents );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ]
2116 [ # # ][ # # ]: 0 : std::copy( ents.begin(), ents.end(), range_inserter( verts ) );
2117 : : }
2118 : :
2119 [ # # ][ # # ]: 0 : E0 = subtract( E0all, edges );
2120 [ # # ][ # # ]: 0 : if( !E0.empty() )
2121 : : {
2122 [ # # ][ # # ]: 0 : for( Range::iterator it = E0.begin(); it != E0.end(); it++ )
[ # # ][ # # ]
[ # # ]
2123 : : {
2124 : 0 : ents.clear();
2125 [ # # ][ # # ]: 0 : error = mbImpl->get_connectivity( &( *it ), 0, ents );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ]
2126 [ # # ][ # # ]: 0 : std::copy( ents.begin(), ents.end(), range_inserter( verts ) );
2127 : : }
2128 : : }
2129 [ # # ][ # # ]: 0 : V0 = subtract( V0all, verts );
[ # # ]
2130 : : }
2131 [ # # ][ # # ]: 0 : else if( !E0all.empty() )
2132 : : {
2133 [ # # ]: 0 : Range verts;
2134 [ # # ][ # # ]: 0 : for( Range::iterator it = E0all.begin(); it != E0all.end(); it++ )
[ # # ][ # # ]
[ # # ]
2135 : : {
2136 : 0 : ents.clear();
2137 [ # # ][ # # ]: 0 : error = mbImpl->get_connectivity( &( *it ), 1, ents );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ]
2138 [ # # ][ # # ]: 0 : std::copy( ents.begin(), ents.end(), range_inserter( verts ) );
2139 : : }
2140 [ # # ]: 0 : E0 = E0all;
2141 [ # # ][ # # ]: 0 : V0 = subtract( V0all, verts );
[ # # ]
2142 : : }
2143 [ # # ][ # # ]: 0 : else if( !V0all.empty() )
2144 : : {
2145 [ # # ]: 0 : V0 = V0all;
2146 : : }
2147 : : else
2148 [ # # ][ # # ]: 0 : MB_SET_ERR( MB_FAILURE, "Trying to pack unsupported sub-entities for shared interface entities" );
[ # # ][ # # ]
[ # # ]
2149 : :
2150 [ # # ][ # # ]: 0 : if( !F0.empty() ) std::copy( F0.begin(), F0.end(), range_inserter( allEnts ) );
[ # # ][ # # ]
[ # # ][ # # ]
2151 [ # # ][ # # ]: 0 : if( !E0.empty() ) std::copy( E0.begin(), E0.end(), range_inserter( allEnts ) );
[ # # ][ # # ]
[ # # ][ # # ]
2152 [ # # ][ # # ]: 0 : if( !V0.empty() ) std::copy( V0.begin(), V0.end(), range_inserter( allEnts ) );
[ # # ][ # # ]
[ # # ][ # # ]
2153 : :
2154 : 0 : return MB_SUCCESS;
2155 : : }
2156 : :
2157 : 0 : ErrorCode NestedRefine::collect_FList( int to_proc, Range faces, std::vector< EntityHandle >& FList,
2158 : : std::vector< EntityHandle >& RList )
2159 : : {
2160 : : ErrorCode error;
2161 : :
2162 : 0 : FList.clear();
2163 [ # # ][ # # ]: 0 : std::vector< EntityHandle > F, FC, FE, lF, lFC, lFE, rF, rFC, rFE;
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
2164 [ # # ][ # # ]: 0 : std::vector< EntityHandle > childEnts, conn, fedges;
[ # # ]
2165 : :
2166 [ # # ][ # # ]: 0 : for( Range::iterator it = faces.begin(); it != faces.end(); it++ )
[ # # ][ # # ]
[ # # ]
2167 : : {
2168 [ # # ]: 0 : EntityHandle face = *it;
2169 : 0 : conn.clear();
2170 : 0 : fedges.clear();
2171 [ # # ][ # # ]: 0 : error = mbImpl->get_connectivity( &face, 1, conn );MB_CHK_ERR( error );
[ # # ][ # # ]
2172 [ # # ][ # # ]: 0 : error = ahf->get_face_edges( *it, fedges );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ]
2173 : :
2174 : : // add local handles
2175 [ # # ][ # # ]: 0 : lF.push_back( *it );
2176 [ # # ]: 0 : lFC.insert( lFC.end(), conn.begin(), conn.end() );
2177 [ # # ]: 0 : lFE.insert( lFE.end(), fedges.begin(), fedges.end() );
2178 : :
2179 : : // replace local handles with remote handles on to_proc
2180 : 0 : EntityHandle rval = 0;
2181 [ # # ][ # # ]: 0 : error = pcomm->get_remote_handles( &face, &rval, 1, to_proc );MB_CHK_ERR( error );
[ # # ][ # # ]
2182 [ # # ]: 0 : rF.push_back( rval );
2183 : :
2184 [ # # ]: 0 : for( int i = 0; i < (int)conn.size(); i++ )
2185 : : {
2186 [ # # ][ # # ]: 0 : error = pcomm->get_remote_handles( &conn[i], &rval, 1, to_proc );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ]
2187 [ # # ]: 0 : rFC.push_back( rval );
2188 : :
2189 [ # # ][ # # ]: 0 : error = pcomm->get_remote_handles( &fedges[i], &rval, 1, to_proc );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ]
2190 [ # # ]: 0 : rFE.push_back( rval );
2191 : : }
2192 : : }
2193 : :
2194 [ # # ]: 0 : for( int l = 0; l < nlevels; l++ )
2195 : : {
2196 [ # # ][ # # ]: 0 : for( Range::iterator it = faces.begin(); it != faces.end(); it++ )
[ # # ][ # # ]
[ # # ]
2197 : : {
2198 : 0 : childEnts.clear();
2199 [ # # ][ # # ]: 0 : error = parent_to_child( *it, 0, l + 1, childEnts );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ]
2200 : :
2201 [ # # ]: 0 : for( int i = 0; i < (int)childEnts.size(); i++ )
2202 : : {
2203 : 0 : conn.clear();
2204 : 0 : fedges.clear();
2205 [ # # ][ # # ]: 0 : error = mbImpl->get_connectivity( &childEnts[i], 1, conn );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ]
2206 [ # # ][ # # ]: 0 : error = ahf->get_face_edges( childEnts[i], fedges );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ]
2207 : :
2208 [ # # ][ # # ]: 0 : F.push_back( childEnts[i] );
2209 [ # # ]: 0 : FC.insert( FC.end(), conn.begin(), conn.end() );
2210 [ # # ]: 0 : FE.insert( FE.end(), fedges.begin(), fedges.end() );
2211 : : }
2212 : : }
2213 : : }
2214 : :
2215 [ # # ]: 0 : FList.insert( FList.end(), lF.begin(), lF.end() );
2216 [ # # ]: 0 : FList.insert( FList.end(), F.begin(), F.end() );
2217 [ # # ]: 0 : FList.insert( FList.end(), lFC.begin(), lFC.end() );
2218 [ # # ]: 0 : FList.insert( FList.end(), FC.begin(), FC.end() );
2219 [ # # ]: 0 : FList.insert( FList.end(), lFE.begin(), lFE.end() );
2220 [ # # ]: 0 : FList.insert( FList.end(), FE.begin(), FE.end() );
2221 : :
2222 [ # # ]: 0 : RList.insert( RList.end(), rF.begin(), rF.end() );
2223 [ # # ]: 0 : RList.insert( RList.end(), F.begin(), F.end() );
2224 [ # # ]: 0 : RList.insert( RList.end(), rFC.begin(), rFC.end() );
2225 [ # # ]: 0 : RList.insert( RList.end(), FC.begin(), FC.end() );
2226 [ # # ]: 0 : RList.insert( RList.end(), rFE.begin(), rFE.end() );
2227 [ # # ]: 0 : RList.insert( RList.end(), FE.begin(), FE.end() );
2228 : :
2229 : 0 : return MB_SUCCESS;
2230 : : }
2231 : :
2232 : 0 : ErrorCode NestedRefine::collect_EList( int to_proc, Range edges, std::vector< EntityHandle >& EList,
2233 : : std::vector< EntityHandle >& RList )
2234 : : {
2235 : : ErrorCode error;
2236 : 0 : EList.clear();
2237 [ # # ][ # # ]: 0 : std::vector< EntityHandle > E, EC, lE, lEC, rE, rEC;
[ # # ][ # # ]
[ # # ][ # # ]
2238 [ # # ][ # # ]: 0 : std::vector< EntityHandle > childEnts, conn;
2239 : :
2240 : : // Add the edges and their connectivities at the coarsest level first.
2241 [ # # ][ # # ]: 0 : for( Range::iterator it = edges.begin(); it != edges.end(); it++ )
[ # # ][ # # ]
[ # # ]
2242 : : {
2243 [ # # ]: 0 : EntityHandle edg = *it;
2244 : 0 : conn.clear();
2245 [ # # ][ # # ]: 0 : error = mbImpl->get_connectivity( &edg, 1, conn );MB_CHK_ERR( error );
[ # # ][ # # ]
2246 : :
2247 : : // add local handles
2248 [ # # ]: 0 : lE.push_back( edg );
2249 [ # # ]: 0 : lEC.insert( lEC.end(), conn.begin(), conn.end() );
2250 : :
2251 : : // replace local handles with remote handle on to_proc
2252 : 0 : EntityHandle rval = 0;
2253 [ # # ][ # # ]: 0 : error = pcomm->get_remote_handles( &edg, &rval, 1, to_proc );MB_CHK_ERR( error );
[ # # ][ # # ]
2254 [ # # ]: 0 : rE.push_back( rval );
2255 [ # # ][ # # ]: 0 : error = pcomm->get_remote_handles( &conn[0], &rval, 1, to_proc );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ]
2256 [ # # ]: 0 : rEC.push_back( rval );
2257 [ # # ][ # # ]: 0 : error = pcomm->get_remote_handles( &conn[1], &rval, 1, to_proc );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ]
2258 [ # # ]: 0 : rEC.push_back( rval );
2259 : : }
2260 : :
2261 : : // Add the edges and their connectivities at subsequent levels.
2262 [ # # ]: 0 : for( int l = 0; l < nlevels; l++ )
2263 : : {
2264 [ # # ][ # # ]: 0 : for( Range::iterator it = edges.begin(); it != edges.end(); it++ )
[ # # ][ # # ]
[ # # ]
2265 : : {
2266 : 0 : childEnts.clear();
2267 [ # # ][ # # ]: 0 : error = parent_to_child( *it, 0, l + 1, childEnts );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ]
2268 : :
2269 [ # # ]: 0 : for( int i = 0; i < (int)childEnts.size(); i++ )
2270 : : {
2271 : 0 : conn.clear();
2272 [ # # ][ # # ]: 0 : error = mbImpl->get_connectivity( &childEnts[i], 1, conn );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ]
2273 [ # # ][ # # ]: 0 : E.push_back( childEnts[i] );
2274 [ # # ]: 0 : EC.insert( EC.end(), conn.begin(), conn.end() );
2275 : : }
2276 : : }
2277 : : }
2278 : :
2279 [ # # ]: 0 : EList.insert( EList.end(), lE.begin(), lE.end() );
2280 [ # # ]: 0 : EList.insert( EList.end(), E.begin(), E.end() );
2281 [ # # ]: 0 : EList.insert( EList.end(), lEC.begin(), lEC.end() );
2282 [ # # ]: 0 : EList.insert( EList.end(), EC.begin(), EC.end() );
2283 : :
2284 [ # # ]: 0 : RList.insert( RList.end(), rE.begin(), rE.end() );
2285 [ # # ]: 0 : RList.insert( RList.end(), E.begin(), E.end() );
2286 [ # # ]: 0 : RList.insert( RList.end(), rEC.begin(), rEC.end() );
2287 [ # # ]: 0 : RList.insert( RList.end(), EC.begin(), EC.end() );
2288 : :
2289 : 0 : return MB_SUCCESS;
2290 : : }
2291 : :
2292 : 0 : ErrorCode NestedRefine::collect_VList( int to_proc, Range verts, std::vector< EntityHandle >& VList,
2293 : : std::vector< EntityHandle >& RList )
2294 : : {
2295 : : ErrorCode error;
2296 [ # # ][ # # ]: 0 : std::vector< EntityHandle > V, lV, rV;
[ # # ]
2297 : 0 : VList.clear();
2298 : :
2299 : : // Add the vertices at the coarsest level first.
2300 [ # # ][ # # ]: 0 : for( Range::iterator it = verts.begin(); it != verts.end(); it++ )
[ # # ][ # # ]
[ # # ]
2301 : : {
2302 [ # # ]: 0 : EntityHandle v = *it;
2303 : :
2304 [ # # ]: 0 : lV.push_back( v );
2305 : 0 : EntityHandle rval = 0;
2306 [ # # ][ # # ]: 0 : error = pcomm->get_remote_handles( &v, &rval, 1, to_proc );MB_CHK_ERR( error );
[ # # ][ # # ]
2307 : :
2308 [ # # ]: 0 : rV.push_back( rval );
2309 : : }
2310 : :
2311 : : // Add the vertices at the subsequent levels .
2312 [ # # ]: 0 : for( int l = 0; l < nlevels; l++ )
2313 : : {
2314 [ # # ][ # # ]: 0 : for( Range::iterator it = verts.begin(); it != verts.end(); it++ )
[ # # ][ # # ]
[ # # ]
2315 : : {
2316 : 0 : EntityHandle dupvert = 0;
2317 [ # # ][ # # ]: 0 : error = get_vertex_duplicates( *it, l + 1, dupvert );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ]
2318 [ # # ]: 0 : V.push_back( dupvert );
2319 : : }
2320 : : }
2321 : :
2322 : : // local vertex handles at the coarsest level
2323 [ # # ]: 0 : VList.insert( VList.end(), lV.begin(), lV.end() );
2324 [ # # ]: 0 : VList.insert( VList.end(), V.begin(), V.end() );
2325 : :
2326 : : // remote vertex handles at the coarsest level
2327 [ # # ]: 0 : RList.insert( RList.end(), rV.begin(), rV.end() );
2328 [ # # ]: 0 : RList.insert( RList.end(), V.begin(), V.end() );
2329 : :
2330 : 0 : return MB_SUCCESS;
2331 : : }
2332 : :
2333 : 0 : ErrorCode NestedRefine::decipher_remote_handles( std::vector< int >& sharedprocs,
2334 : : std::vector< std::vector< int > >& auxinfo,
2335 : : std::vector< std::vector< EntityHandle > >& localbuffers,
2336 : : std::vector< std::vector< EntityHandle > >& remotebuffers,
2337 : : std::multimap< EntityHandle, int >& remProcs,
2338 : : std::multimap< EntityHandle, EntityHandle >& remHandles )
2339 : : {
2340 : : ErrorCode error;
2341 : :
2342 : : int i;
2343 : 0 : int nprocs = sharedprocs.size();
2344 : :
2345 [ # # ]: 0 : for( i = 0; i < nprocs; i++ )
2346 : : {
2347 [ # # ]: 0 : std::vector< int > msgsz;
2348 [ # # ][ # # ]: 0 : for( int j = 0; j < (int)auxinfo[i].size(); j++ )
2349 : : {
2350 [ # # ][ # # ]: 0 : msgsz.push_back( auxinfo[i][j] );
[ # # ]
2351 : : }
2352 : :
2353 [ # # ][ # # ]: 0 : if( msgsz[0] != 0 ) // Faces
2354 : : {
2355 : : // Get the local and remote face handles from the buffers
2356 [ # # ][ # # ]: 0 : std::vector< EntityHandle > LFList, RFList;
[ # # ]
2357 [ # # ][ # # ]: 0 : LFList.insert( LFList.end(), localbuffers[i].begin(), localbuffers[i].begin() + msgsz[1] );
[ # # ][ # # ]
[ # # ]
2358 [ # # ][ # # ]: 0 : RFList.insert( RFList.end(), remotebuffers[i].begin(), remotebuffers[i].begin() + msgsz[1] );
[ # # ][ # # ]
[ # # ]
2359 : :
2360 [ # # ][ # # ]: 0 : error = decipher_remote_handles_face( sharedprocs[i], msgsz[0], LFList, RFList, remProcs, remHandles );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ][ # # ]
2361 : :
2362 [ # # ][ # # ]: 0 : if( msgsz[2] != 0 ) // Edges
2363 : : {
2364 [ # # ][ # # ]: 0 : std::vector< EntityHandle > LEList, REList;
[ # # ]
2365 [ # # ][ # # ]: 0 : LEList.insert( LEList.end(), localbuffers[i].begin() + msgsz[1] + 1,
[ # # ]
2366 [ # # ][ # # ]: 0 : localbuffers[i].begin() + msgsz[1] + msgsz[3] );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
2367 [ # # ][ # # ]: 0 : REList.insert( REList.end(), remotebuffers[i].begin() + msgsz[1] + 1,
[ # # ]
2368 [ # # ][ # # ]: 0 : remotebuffers[i].begin() + msgsz[1] + msgsz[3] );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
2369 : :
2370 [ # # ][ # # ]: 0 : error = decipher_remote_handles_edge( sharedprocs[i], msgsz[2], LEList, REList, remProcs, remHandles );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ][ # # ]
2371 : :
2372 [ # # ][ # # ]: 0 : if( msgsz[4] != 0 ) // Vertices
2373 : : {
2374 : : // Get the local and remote face handles from the buffers
2375 [ # # ][ # # ]: 0 : std::vector< EntityHandle > LVList, RVList;
[ # # ]
2376 [ # # ][ # # ]: 0 : LVList.insert( LVList.end(), localbuffers[i].begin() + msgsz[1] + msgsz[3] + 1,
[ # # ][ # # ]
[ # # ]
2377 [ # # ][ # # ]: 0 : localbuffers[i].begin() + msgsz[1] + msgsz[3] + msgsz[5] );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
2378 [ # # ][ # # ]: 0 : RVList.insert( RVList.end(), remotebuffers[i].begin() + msgsz[1] + msgsz[3] + 1,
[ # # ][ # # ]
[ # # ]
2379 [ # # ][ # # ]: 0 : remotebuffers[i].begin() + msgsz[1] + msgsz[3] + msgsz[5] );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
2380 : :
2381 [ # # ][ # # ]: 0 : error = decipher_remote_handles_vertex( sharedprocs[i], msgsz[4], LVList, RVList, remProcs,
2382 [ # # ][ # # ]: 0 : remHandles );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ][ # # ]
2383 : 0 : }
2384 : : }
2385 [ # # ][ # # ]: 0 : else if( msgsz[4] != 0 ) // Vertices
2386 : : {
2387 : : // Get the local and remote face handles from the buffers
2388 [ # # ][ # # ]: 0 : std::vector< EntityHandle > LVList, RVList;
[ # # ]
2389 [ # # ][ # # ]: 0 : LVList.insert( LVList.end(), localbuffers[i].begin() + msgsz[1] + 1,
[ # # ]
2390 [ # # ][ # # ]: 0 : localbuffers[i].begin() + msgsz[1] + msgsz[5] );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
2391 [ # # ][ # # ]: 0 : RVList.insert( RVList.end(), remotebuffers[i].begin() + msgsz[1] + 1,
[ # # ]
2392 [ # # ][ # # ]: 0 : remotebuffers[i].begin() + msgsz[1] + msgsz[5] );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
2393 : :
2394 : : error =
2395 [ # # ][ # # ]: 0 : decipher_remote_handles_vertex( sharedprocs[i], msgsz[4], LVList, RVList, remProcs, remHandles );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
2396 : 0 : }
2397 : : }
2398 : :
2399 [ # # ][ # # ]: 0 : else if( msgsz[2] != 0 ) // Edges
2400 : : {
2401 : : // Get the local and remote face handles from the buffers
2402 [ # # ][ # # ]: 0 : std::vector< EntityHandle > LEList, REList;
[ # # ]
2403 [ # # ][ # # ]: 0 : LEList.insert( LEList.end(), localbuffers[i].begin(), localbuffers[i].begin() + msgsz[3] );
[ # # ][ # # ]
[ # # ]
2404 [ # # ][ # # ]: 0 : REList.insert( REList.end(), remotebuffers[i].begin(), remotebuffers[i].begin() + msgsz[3] );
[ # # ][ # # ]
[ # # ]
2405 : :
2406 [ # # ][ # # ]: 0 : error = decipher_remote_handles_edge( sharedprocs[i], msgsz[2], LEList, REList, remProcs, remHandles );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ][ # # ]
2407 : :
2408 [ # # ][ # # ]: 0 : if( msgsz[4] != 0 ) // Vertices
2409 : : {
2410 : : // Get the local and remote face handles from the buffers
2411 [ # # ][ # # ]: 0 : std::vector< EntityHandle > LVList, RVList;
[ # # ]
2412 [ # # ][ # # ]: 0 : LVList.insert( LVList.end(), localbuffers[i].begin() + msgsz[3] + 1,
[ # # ]
2413 [ # # ][ # # ]: 0 : localbuffers[i].begin() + msgsz[3] + msgsz[5] );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
2414 [ # # ][ # # ]: 0 : RVList.insert( RVList.end(), remotebuffers[i].begin() + msgsz[3] + 1,
[ # # ]
2415 [ # # ][ # # ]: 0 : remotebuffers[i].begin() + msgsz[3] + msgsz[5] );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
2416 : :
2417 : : error =
2418 [ # # ][ # # ]: 0 : decipher_remote_handles_vertex( sharedprocs[i], msgsz[4], LVList, RVList, remProcs, remHandles );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
2419 : 0 : }
2420 : : }
2421 : :
2422 [ # # ][ # # ]: 0 : else if( msgsz[4] != 0 ) // Vertices
2423 : : {
2424 : : // Get the local and remote face handles from the buffers
2425 [ # # ][ # # ]: 0 : std::vector< EntityHandle > LVList, RVList;
[ # # ]
2426 [ # # ][ # # ]: 0 : LVList.insert( LVList.end(), localbuffers[i].begin(), localbuffers[i].end() );
[ # # ]
2427 [ # # ][ # # ]: 0 : RVList.insert( RVList.end(), remotebuffers[i].begin(), remotebuffers[i].end() );
[ # # ]
2428 : :
2429 [ # # ][ # # ]: 0 : error = decipher_remote_handles_vertex( sharedprocs[i], msgsz[4], LVList, RVList, remProcs, remHandles );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
2430 : : }
2431 : : else
2432 [ # # ][ # # ]: 0 : MB_SET_ERR( MB_FAILURE, "Trying to decipher entities other than verts, edges, faces" );
[ # # ][ # # ]
[ # # ][ # # ]
2433 : 0 : }
2434 : :
2435 : 0 : return MB_SUCCESS;
2436 : : }
2437 : :
2438 : 0 : ErrorCode NestedRefine::decipher_remote_handles_face( int shared_proc, int numfaces,
2439 : : std::vector< EntityHandle >& localFaceList,
2440 : : std::vector< EntityHandle >& remFaceList,
2441 : : std::multimap< EntityHandle, int >& remProcs,
2442 : : std::multimap< EntityHandle, EntityHandle >& remHandles )
2443 : : {
2444 : : ErrorCode error;
2445 : :
2446 [ # # ]: 0 : for( int i = 0; i < numfaces; i++ )
2447 : : {
2448 : : // find local and remote handles of the coarsest face
2449 [ # # ]: 0 : EntityHandle Lface = localFaceList[i];
2450 : : int Rface_idx =
2451 [ # # ][ # # ]: 0 : ( std::find( remFaceList.begin(), remFaceList.begin() + numfaces - 1, Lface ) ) - remFaceList.begin();
[ # # ][ # # ]
2452 : :
2453 : : // get connectivities of the local and remote coarsest faces
2454 [ # # ][ # # ]: 0 : std::vector< EntityHandle > Lface_conn, Rface_conn;
[ # # ]
2455 [ # # ][ # # ]: 0 : error = get_data_from_buff( 2, 1, 0, i, numfaces, localFaceList, Lface_conn );MB_CHK_ERR( error );
[ # # ][ # # ]
2456 [ # # ][ # # ]: 0 : error = get_data_from_buff( 2, 1, 0, Rface_idx, numfaces, remFaceList, Rface_conn );MB_CHK_ERR( error );
[ # # ][ # # ]
2457 : :
2458 : : // find the combination difference between local and remote coarsest face
2459 [ # # ][ # # ]: 0 : std::vector< int > cmap;
2460 : 0 : int comb = 0;
2461 : 0 : int nvF = (int)Lface_conn.size();
2462 [ # # ][ # # ]: 0 : error = reorder_indices( &Lface_conn[0], &Rface_conn[0], nvF, &cmap[0], comb );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
2463 : :
2464 : : // go into loop over all levels
2465 [ # # ][ # # ]: 0 : std::vector< EntityHandle > lchildents, lparents;
[ # # ][ # # ]
2466 [ # # ][ # # ]: 0 : std::vector< EntityHandle > lcents, rcents;
[ # # ][ # # ]
2467 : : int lidx, ridx;
2468 : :
2469 [ # # ][ # # ]: 0 : for( int l = 0; l < nlevels; l++ )
2470 : : {
2471 : 0 : lchildents.clear();
2472 : 0 : lparents.clear();
2473 : 0 : lcents.clear();
2474 : 0 : rcents.clear();
2475 : :
2476 : : // obtain children at the current level
2477 [ # # ][ # # ]: 0 : error = get_data_from_buff( 2, 0, l + 1, i, numfaces, localFaceList, lchildents );MB_CHK_ERR( error );
[ # # ][ # # ]
2478 : :
2479 : : // obtain parents at the previous level
2480 [ # # ][ # # ]: 0 : if( l == 0 ) { lparents.push_back( Lface ); }
2481 : : else
2482 : : {
2483 [ # # ][ # # ]: 0 : error = get_data_from_buff( 2, 0, l, i, numfaces, localFaceList, lparents );MB_CHK_ERR( error );
[ # # ][ # # ]
2484 : : }
2485 : :
2486 : : //#children at the previous level and the current level
2487 [ # # ]: 0 : EntityType ftype = mbImpl->type_from_handle( Lface );
2488 [ # # ]: 0 : int d = get_index_from_degree( level_dsequence[l] );
2489 : 0 : int nch = refTemplates[ftype - 1][d].total_new_ents;
2490 [ # # ]: 0 : std::vector< int > fmap;
2491 [ # # ][ # # ]: 0 : error = reorder_indices( level_dsequence[l], nvF, comb, &fmap[0] );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ]
2492 : :
2493 : : // loop over all the lparents
2494 [ # # ][ # # ]: 0 : for( int j = 0; j < (int)lparents.size(); j++ )
2495 : : {
2496 : : // list local childrent at the current level
2497 [ # # ][ # # ]: 0 : lidx = std::find( localFaceList.begin(), localFaceList.end(), lparents[j] ) - localFaceList.begin();
[ # # ]
2498 [ # # ][ # # ]: 0 : error = get_data_from_buff( 2, 0, l + 1, lidx, numfaces, localFaceList, lcents );MB_CHK_ERR( error );
[ # # ][ # # ]
2499 : :
2500 : : // find the corresponding remote of lparent and its children
2501 : 0 : EntityHandle rparent = 0;
2502 [ # # ][ # # ]: 0 : error = check_for_parallelinfo( lparents[j], shared_proc, remHandles, remProcs, rparent );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ]
2503 [ # # ][ # # ]: 0 : ridx = std::find( remFaceList.begin(), remFaceList.end(), rparent ) - remFaceList.begin();
2504 [ # # ][ # # ]: 0 : error = get_data_from_buff( 2, 0, l + 1, ridx, numfaces, remFaceList, rcents );MB_CHK_ERR( error );
[ # # ][ # # ]
2505 : :
2506 : : // match up local face with remote handles according to cmap
2507 [ # # ][ # # ]: 0 : std::vector< EntityHandle > lconn, rconn, ledg, redg;
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
2508 [ # # ][ # # ]: 0 : for( int k = 0; k < nch; k++ )
2509 : : {
2510 : 0 : lconn.clear();
2511 : 0 : rconn.clear();
2512 : 0 : ledg.clear();
2513 : 0 : redg.clear();
2514 : :
2515 : : // matching the local children face handles with their remotes
2516 [ # # ][ # # ]: 0 : bool found = check_for_parallelinfo( lcents[k], shared_proc, remProcs );
2517 [ # # ]: 0 : if( !found )
2518 : : {
2519 [ # # ][ # # ]: 0 : remProcs.insert( std::pair< EntityHandle, int >( lcents[k], shared_proc ) );
[ # # ]
2520 [ # # ][ # # ]: 0 : remHandles.insert( std::pair< EntityHandle, EntityHandle >( lcents[k], rcents[fmap[k]] ) );
[ # # ][ # # ]
[ # # ]
2521 : : }
2522 : :
2523 : : // find indices of the matched child face
2524 [ # # ][ # # ]: 0 : lidx = std::find( localFaceList.begin(), localFaceList.end(), lcents[k] ) - localFaceList.begin();
[ # # ]
2525 [ # # ][ # # ]: 0 : ridx = std::find( remFaceList.begin(), remFaceList.end(), rcents[fmap[k]] ) - remFaceList.begin();
[ # # ][ # # ]
2526 : :
2527 : : // find bounding edges and connectivity of the matched child face
2528 [ # # ][ # # ]: 0 : error = get_data_from_buff( 2, 2, l + 1, lidx, numfaces, localFaceList, ledg );MB_CHK_ERR( error );
[ # # ][ # # ]
2529 [ # # ][ # # ]: 0 : error = get_data_from_buff( 2, 1, l + 1, lidx, numfaces, localFaceList, lconn );MB_CHK_ERR( error );
[ # # ][ # # ]
2530 [ # # ][ # # ]: 0 : error = get_data_from_buff( 2, 2, l + 1, ridx, numfaces, remFaceList, redg );MB_CHK_ERR( error );
[ # # ][ # # ]
2531 [ # # ][ # # ]: 0 : error = get_data_from_buff( 2, 1, l + 1, ridx, numfaces, remFaceList, rconn );MB_CHK_ERR( error );
[ # # ][ # # ]
2532 : :
2533 : : // now match the handles of the bounding edges and the vertices using
2534 : : // combination difference
2535 [ # # ]: 0 : for( int m = 0; m < (int)ledg.size(); m++ )
2536 : : {
2537 [ # # ][ # # ]: 0 : found = check_for_parallelinfo( ledg[m], shared_proc, remProcs );
2538 : :
2539 [ # # ]: 0 : if( !found )
2540 : : {
2541 [ # # ][ # # ]: 0 : remProcs.insert( std::pair< EntityHandle, int >( ledg[m], shared_proc ) );
[ # # ]
2542 [ # # ][ # # ]: 0 : remHandles.insert( std::pair< EntityHandle, EntityHandle >( ledg[m], redg[cmap[m]] ) );
[ # # ][ # # ]
[ # # ]
2543 : : }
2544 : :
2545 [ # # ][ # # ]: 0 : found = check_for_parallelinfo( lconn[m], shared_proc, remProcs );
2546 : :
2547 [ # # ]: 0 : if( !found )
2548 : : {
2549 [ # # ][ # # ]: 0 : remProcs.insert( std::pair< EntityHandle, int >( lconn[m], shared_proc ) );
[ # # ]
2550 [ # # ][ # # ]: 0 : remHandles.insert( std::pair< EntityHandle, EntityHandle >( lconn[m], rconn[cmap[m]] ) );
[ # # ][ # # ]
[ # # ]
2551 : : }
2552 : : }
2553 : : }
2554 : 0 : }
2555 : 0 : }
2556 : 0 : }
2557 : :
2558 : 0 : return MB_SUCCESS;
2559 : : }
2560 : :
2561 : 0 : ErrorCode NestedRefine::decipher_remote_handles_edge( int shared_proc, int numedges,
2562 : : std::vector< EntityHandle >& localEdgeList,
2563 : : std::vector< EntityHandle >& remEdgeList,
2564 : : std::multimap< EntityHandle, int >& remProcs,
2565 : : std::multimap< EntityHandle, EntityHandle >& remHandles )
2566 : : {
2567 : : ErrorCode error;
2568 : :
2569 [ # # ]: 0 : for( int i = 0; i < numedges; i++ )
2570 : : {
2571 [ # # ]: 0 : EntityHandle Ledge = localEdgeList[i];
2572 : : int Redge_idx =
2573 [ # # ][ # # ]: 0 : ( std::find( remEdgeList.begin(), remEdgeList.begin() + numedges - 1, Ledge ) ) - remEdgeList.begin();
[ # # ][ # # ]
2574 : :
2575 [ # # ][ # # ]: 0 : std::vector< EntityHandle > Ledge_conn, Redge_conn;
[ # # ]
2576 [ # # ][ # # ]: 0 : error = get_data_from_buff( 1, 1, 0, i, numedges, localEdgeList, Ledge_conn );MB_CHK_ERR( error );
[ # # ][ # # ]
2577 [ # # ][ # # ]: 0 : error = get_data_from_buff( 1, 1, 0, Redge_idx, numedges, remEdgeList, Redge_conn );MB_CHK_ERR( error );
[ # # ][ # # ]
2578 : :
2579 : 0 : bool orient = true;
2580 [ # # ][ # # ]: 0 : if( ( Ledge_conn[0] == Redge_conn[1] ) && ( Ledge_conn[1] == Redge_conn[0] ) ) orient = false;
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
2581 : :
2582 [ # # ][ # # ]: 0 : if( orient ) assert( ( Ledge_conn[0] == Redge_conn[0] ) && ( Ledge_conn[1] == Redge_conn[1] ) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
2583 : :
2584 [ # # ][ # # ]: 0 : std::vector< EntityHandle > lchildEdgs, rchildEdgs, lconn, rconn;
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
2585 [ # # ][ # # ]: 0 : for( int l = 0; l < nlevels; l++ )
2586 : : {
2587 : 0 : lchildEdgs.clear();
2588 : 0 : rchildEdgs.clear();
2589 [ # # ][ # # ]: 0 : error = get_data_from_buff( 1, 0, l + 1, i, numedges, localEdgeList, lchildEdgs );MB_CHK_ERR( error );
[ # # ][ # # ]
2590 [ # # ][ # # ]: 0 : error = get_data_from_buff( 1, 0, l + 1, Redge_idx, numedges, remEdgeList, rchildEdgs );MB_CHK_ERR( error );
[ # # ][ # # ]
2591 : :
2592 : 0 : int nchd = lchildEdgs.size();
2593 [ # # ]: 0 : if( orient )
2594 : : {
2595 [ # # ]: 0 : for( int j = 0; j < nchd; j++ )
2596 : : {
2597 : : // match entityhandles of child edges
2598 [ # # ][ # # ]: 0 : bool found = check_for_parallelinfo( lchildEdgs[j], shared_proc, remProcs );
2599 [ # # ]: 0 : if( !found )
2600 : : {
2601 [ # # ][ # # ]: 0 : remProcs.insert( std::pair< EntityHandle, int >( lchildEdgs[j], shared_proc ) );
[ # # ]
2602 [ # # ][ # # ]: 0 : remHandles.insert( std::pair< EntityHandle, EntityHandle >( lchildEdgs[j], rchildEdgs[j] ) );
[ # # ][ # # ]
2603 : : }
2604 : :
2605 : : // match entityhandles of child vertices
2606 : 0 : lconn.clear();
2607 : 0 : rconn.clear();
2608 : :
2609 : : int lidx =
2610 [ # # ][ # # ]: 0 : std::find( localEdgeList.begin(), localEdgeList.end(), lchildEdgs[j] ) - localEdgeList.begin();
[ # # ]
2611 [ # # ][ # # ]: 0 : int ridx = std::find( remEdgeList.begin(), remEdgeList.end(), rchildEdgs[j] ) - remEdgeList.begin();
[ # # ]
2612 : :
2613 [ # # ][ # # ]: 0 : error = get_data_from_buff( 1, 1, l + 1, lidx, numedges, localEdgeList, lconn );MB_CHK_ERR( error );
[ # # ][ # # ]
2614 [ # # ][ # # ]: 0 : error = get_data_from_buff( 1, 1, l + 1, ridx, numedges, remEdgeList, rconn );MB_CHK_ERR( error );
[ # # ][ # # ]
2615 : :
2616 [ # # ][ # # ]: 0 : found = check_for_parallelinfo( lconn[0], shared_proc, remProcs );
2617 [ # # ]: 0 : if( !found )
2618 : : {
2619 [ # # ][ # # ]: 0 : remProcs.insert( std::pair< EntityHandle, int >( lconn[0], shared_proc ) );
[ # # ]
2620 [ # # ][ # # ]: 0 : remHandles.insert( std::pair< EntityHandle, EntityHandle >( lconn[0], rconn[0] ) );
[ # # ][ # # ]
2621 : : }
2622 [ # # ][ # # ]: 0 : found = check_for_parallelinfo( lconn[1], shared_proc, remProcs );
2623 [ # # ]: 0 : if( !found )
2624 : : {
2625 [ # # ][ # # ]: 0 : remProcs.insert( std::pair< EntityHandle, int >( lconn[1], shared_proc ) );
[ # # ]
2626 [ # # ][ # # ]: 0 : remHandles.insert( std::pair< EntityHandle, EntityHandle >( lconn[1], rconn[0] ) );
[ # # ][ # # ]
2627 : : }
2628 : : }
2629 : : }
2630 : :
2631 : : else
2632 : : {
2633 [ # # ]: 0 : for( int j = 0; j < nchd; j++ )
2634 : : {
2635 : : // match entityhandles of child edges
2636 [ # # ][ # # ]: 0 : bool found = check_for_parallelinfo( lchildEdgs[j], shared_proc, remProcs );
2637 : :
2638 [ # # ]: 0 : if( !found )
2639 : : {
2640 [ # # ][ # # ]: 0 : remProcs.insert( std::pair< EntityHandle, int >( lchildEdgs[j], shared_proc ) );
[ # # ]
2641 : : remHandles.insert(
2642 [ # # ][ # # ]: 0 : std::pair< EntityHandle, EntityHandle >( lchildEdgs[j], rchildEdgs[nchd - j - 1] ) );
[ # # ][ # # ]
2643 : : }
2644 : :
2645 : : // match entityhandles of child vertices
2646 : 0 : lconn.clear();
2647 : 0 : rconn.clear();
2648 : :
2649 : : int lidx =
2650 [ # # ][ # # ]: 0 : std::find( localEdgeList.begin(), localEdgeList.end(), lchildEdgs[j] ) - localEdgeList.begin();
[ # # ]
2651 [ # # ][ # # ]: 0 : int ridx = std::find( remEdgeList.begin(), remEdgeList.end(), rchildEdgs[nchd - j - 1] ) -
[ # # ]
2652 : 0 : remEdgeList.begin();
2653 : :
2654 [ # # ][ # # ]: 0 : error = get_data_from_buff( 1, 1, l + 1, lidx, numedges, localEdgeList, lconn );MB_CHK_ERR( error );
[ # # ][ # # ]
2655 [ # # ][ # # ]: 0 : error = get_data_from_buff( 1, 1, l + 1, ridx, numedges, remEdgeList, rconn );MB_CHK_ERR( error );
[ # # ][ # # ]
2656 [ # # ][ # # ]: 0 : found = check_for_parallelinfo( lconn[0], shared_proc, remProcs );
2657 : :
2658 [ # # ]: 0 : if( !found )
2659 : : {
2660 [ # # ][ # # ]: 0 : remProcs.insert( std::pair< EntityHandle, int >( lconn[0], shared_proc ) );
[ # # ]
2661 [ # # ][ # # ]: 0 : remHandles.insert( std::pair< EntityHandle, EntityHandle >( lconn[0], rconn[1] ) );
[ # # ][ # # ]
2662 : : }
2663 : :
2664 [ # # ][ # # ]: 0 : found = check_for_parallelinfo( lconn[1], shared_proc, remProcs );
2665 [ # # ]: 0 : if( !found )
2666 : : {
2667 [ # # ][ # # ]: 0 : remProcs.insert( std::pair< EntityHandle, int >( lconn[1], shared_proc ) );
[ # # ]
2668 [ # # ][ # # ]: 0 : remHandles.insert( std::pair< EntityHandle, EntityHandle >( lconn[1], rconn[1] ) );
[ # # ][ # # ]
2669 : : }
2670 : : }
2671 : : }
2672 : : }
2673 : 0 : }
2674 : :
2675 : 0 : return MB_SUCCESS;
2676 : : }
2677 : :
2678 : 0 : ErrorCode NestedRefine::decipher_remote_handles_vertex( int shared_proc, int numverts,
2679 : : std::vector< EntityHandle >& localVertexList,
2680 : : std::vector< EntityHandle >& remVertexList,
2681 : : std::multimap< EntityHandle, int >& remProcs,
2682 : : std::multimap< EntityHandle, EntityHandle >& remHandles )
2683 : : {
2684 : : // LVList = <V> where V = <LV0, LV1, ..,LVL>
2685 : : // RVList = <V> where V = <LV0', RV1, ..,RVL>, LV0' is the local handles of coarsest vertices
2686 : : // but in the order in which they appear on the remote/shared proc
2687 : :
2688 : : ErrorCode error;
2689 : :
2690 [ # # ]: 0 : for( int i = 0; i < numverts; i++ )
2691 : : {
2692 [ # # ]: 0 : EntityHandle v = localVertexList[i];
2693 : : int Rvert_idx =
2694 [ # # ][ # # ]: 0 : ( std::find( remVertexList.begin(), remVertexList.begin() + numverts - 1, v ) ) - remVertexList.begin();
[ # # ][ # # ]
2695 : :
2696 [ # # ][ # # ]: 0 : std::vector< EntityHandle > lverts, rverts;
[ # # ]
2697 [ # # ][ # # ]: 0 : for( int l = 0; l < nlevels; l++ )
2698 : : {
2699 [ # # ][ # # ]: 0 : error = get_data_from_buff( 0, 0, l + 1, i, numverts, localVertexList, lverts );MB_CHK_ERR( error );
[ # # ][ # # ]
2700 [ # # ][ # # ]: 0 : error = get_data_from_buff( 0, 0, l + 1, Rvert_idx, numverts, remVertexList, rverts );MB_CHK_ERR( error );
[ # # ][ # # ]
2701 : :
2702 [ # # ][ # # ]: 0 : bool found = check_for_parallelinfo( lverts[0], shared_proc, remProcs );
2703 [ # # ]: 0 : if( !found )
2704 : : {
2705 [ # # ][ # # ]: 0 : remProcs.insert( std::pair< EntityHandle, int >( lverts[0], shared_proc ) );
[ # # ]
2706 [ # # ][ # # ]: 0 : remHandles.insert( std::pair< EntityHandle, EntityHandle >( lverts[0], rverts[0] ) );
[ # # ][ # # ]
2707 : : }
2708 : : }
2709 : 0 : }
2710 : :
2711 : 0 : return MB_SUCCESS;
2712 : : }
2713 : :
2714 : 0 : ErrorCode NestedRefine::update_parallel_tags( std::multimap< EntityHandle, int >& remProcs,
2715 : : std::multimap< EntityHandle, EntityHandle >& remHandles )
2716 : : {
2717 : : ErrorCode error;
2718 : :
2719 [ # # ]: 0 : std::vector< int > rprocs;
2720 [ # # ]: 0 : std::vector< EntityHandle > rhandles;
2721 : :
2722 [ # # ]: 0 : std::multimap< EntityHandle, int >::iterator it;
2723 [ # # ]: 0 : std::pair< std::multimap< EntityHandle, int >::iterator, std::multimap< EntityHandle, int >::iterator > it_procs;
2724 : : std::pair< std::multimap< EntityHandle, EntityHandle >::iterator,
2725 : : std::multimap< EntityHandle, EntityHandle >::iterator >
2726 [ # # ]: 0 : it_handles;
2727 : :
2728 : 0 : it = remProcs.begin();
2729 [ # # ][ # # ]: 0 : while( it != remProcs.end() )
2730 : : {
2731 : 0 : rprocs.clear();
2732 : 0 : rhandles.clear();
2733 : :
2734 [ # # ]: 0 : EntityHandle entity = it->first;
2735 [ # # ]: 0 : it_procs = remProcs.equal_range( entity );
2736 [ # # ]: 0 : it_handles = remHandles.equal_range( entity );
2737 : :
2738 [ # # ][ # # ]: 0 : for( std::multimap< EntityHandle, int >::iterator pit = it_procs.first; pit != it_procs.second; pit++ )
[ # # ]
2739 [ # # ][ # # ]: 0 : rprocs.push_back( pit->second );
2740 [ # # ][ # # ]: 0 : for( std::multimap< EntityHandle, EntityHandle >::iterator pit = it_handles.first; pit != it_handles.second;
[ # # ]
2741 : : pit++ )
2742 [ # # ][ # # ]: 0 : rhandles.push_back( pit->second );
2743 : :
2744 [ # # ][ # # ]: 0 : error = pcomm->update_remote_data( entity, rprocs, rhandles );MB_CHK_ERR( error );
[ # # ][ # # ]
2745 : :
2746 [ # # ][ # # ]: 0 : it = remProcs.upper_bound( it->first );
2747 : : }
2748 : :
2749 : 0 : return MB_SUCCESS;
2750 : : }
2751 : :
2752 : 0 : ErrorCode NestedRefine::get_data_from_buff( int listtype, int datatype, int level, int entity_index, int nentities,
2753 : : std::vector< EntityHandle >& buffer, std::vector< EntityHandle >& data )
2754 : : {
2755 : : /**
2756 : : * listtype = 2, 1, 0 for FList (faces), EList (edge) and VList (vertices), respectively
2757 : : * datatype = 0(entityhandles of entities at level 0 and their children upto nlevels, in the
2758 : : *case of vertices its the duplicate vertices at subsequent levels), = 1(connectivity for the
2759 : : *above), = 2(subentities, only case is edges from FList) entity_index = integer index of the
2760 : : *entity in the buffer nentities = number of entities at the coarsest level i.e., |F0| or |E0|
2761 : : *or |V0|
2762 : : *
2763 : : * Two types of queries:
2764 : : * 1) Given an entity, find its children at a particular level.
2765 : : * 2) Given any entity at any level , find its connectivity (or bounding edges)
2766 : : *
2767 : : **/
2768 : :
2769 : 0 : data.clear();
2770 : :
2771 [ # # ]: 0 : if( listtype == 2 ) // FList
2772 : : {
2773 : : // FList = <F, FC, FE> where F = <F0, F1, ..,FL>, FC = <FC0, FC1, .., FCL> and FE = <FE0,
2774 : : // FE1, .., FEL>
2775 [ # # ]: 0 : if( datatype == 0 ) // requesting child entities
2776 : : {
2777 : 0 : EntityType ftype = mbImpl->type_from_handle( buffer[0] );
2778 : :
2779 : : int start, end, toadd, prev;
2780 : 0 : start = end = entity_index;
2781 : 0 : toadd = prev = nentities;
2782 [ # # ]: 0 : for( int i = 0; i < level; i++ )
2783 : : {
2784 : 0 : int d = get_index_from_degree( level_dsequence[i] );
2785 : 0 : int nch = refTemplates[ftype - 1][d].total_new_ents;
2786 : 0 : start = start * nch;
2787 : 0 : end = end * nch + nch - 1;
2788 [ # # ]: 0 : if( i < level - 1 )
2789 : : {
2790 : 0 : prev = prev * nch;
2791 : 0 : toadd += prev;
2792 : : }
2793 : : }
2794 : :
2795 : 0 : start += toadd;
2796 : 0 : end += toadd;
2797 : :
2798 : 0 : int num_child = end - start + 1;
2799 : 0 : data.reserve( num_child );
2800 : :
2801 [ # # ]: 0 : for( int i = start; i <= end; i++ )
2802 : : {
2803 [ # # ]: 0 : EntityHandle child = buffer[i];
2804 [ # # ]: 0 : data.push_back( child );
2805 : : }
2806 : : }
2807 [ # # ]: 0 : else if( datatype == 1 ) // requesting connectivity of an entity
2808 : : {
2809 : 0 : EntityType ftype = mbImpl->type_from_handle( buffer[0] );
2810 : 0 : int nepf = ahf->lConnMap2D[ftype - 2].num_verts_in_face;
2811 : :
2812 : 0 : int toadd = nentities, prev = nentities;
2813 [ # # ]: 0 : for( int i = 0; i < nlevels; i++ )
2814 : : {
2815 : 0 : int d = get_index_from_degree( level_dsequence[i] );
2816 : 0 : int nch = refTemplates[ftype - 1][d].total_new_ents;
2817 : 0 : prev = prev * nch;
2818 : 0 : toadd += prev;
2819 : : }
2820 : :
2821 [ # # ]: 0 : for( int i = 0; i < nepf; i++ )
2822 : 0 : data.push_back( buffer[toadd + nepf * entity_index + i] );
2823 : : }
2824 [ # # ]: 0 : else if( datatype == 2 ) // requesting bounding edges of an entity
2825 : : {
2826 : 0 : EntityType ftype = mbImpl->type_from_handle( buffer[0] );
2827 : 0 : int nepf = ahf->lConnMap2D[ftype - 2].num_verts_in_face;
2828 : :
2829 : 0 : int toadd = nentities, prev = nentities;
2830 [ # # ]: 0 : for( int i = 0; i < nlevels; i++ )
2831 : : {
2832 : 0 : int d = get_index_from_degree( level_dsequence[i] );
2833 : 0 : int nch = refTemplates[ftype - 1][d].total_new_ents;
2834 : 0 : prev = prev * nch;
2835 : 0 : toadd += prev;
2836 : : }
2837 : 0 : toadd += toadd * nepf;
2838 : :
2839 [ # # ]: 0 : for( int i = 0; i < nepf; i++ )
2840 : 0 : data.push_back( buffer[toadd + nepf * entity_index + i] );
2841 : : }
2842 : : else
2843 [ # # ][ # # ]: 0 : MB_SET_ERR( MB_FAILURE, "Requesting invalid info from buffer for faces" );
[ # # ][ # # ]
[ # # ]
2844 : : }
2845 [ # # ]: 0 : else if( listtype == 1 ) // EList
2846 : : {
2847 : : // EList = <E, EC> where E = <E0, E1, ..,EL> and EC = <EC0, EC1, .., ECL>
2848 [ # # ]: 0 : if( datatype == 0 ) // requesting child entities
2849 : : {
2850 : : int start, end, toadd, prev;
2851 : 0 : start = end = entity_index;
2852 : 0 : toadd = prev = nentities;
2853 [ # # ]: 0 : for( int i = 0; i < level; i++ )
2854 : : {
2855 : 0 : int d = get_index_from_degree( level_dsequence[i] );
2856 : 0 : int nch = refTemplates[MBEDGE - 1][d].total_new_ents;
2857 : 0 : start = start * nch;
2858 : 0 : end = end * nch + nch - 1;
2859 : :
2860 [ # # ]: 0 : if( i < level - 1 )
2861 : : {
2862 : 0 : prev = prev * nch;
2863 : 0 : toadd += prev;
2864 : : }
2865 : : }
2866 : :
2867 : 0 : start += toadd;
2868 : 0 : end += toadd;
2869 : :
2870 : 0 : int num_child = end - start + 1;
2871 : 0 : data.reserve( num_child );
2872 : :
2873 [ # # ]: 0 : for( int i = start; i <= end; i++ )
2874 : : {
2875 [ # # ]: 0 : EntityHandle child = buffer[i];
2876 [ # # ]: 0 : data.push_back( child );
2877 : : }
2878 : : }
2879 [ # # ]: 0 : else if( datatype == 1 ) // requesting connectivities of child entities
2880 : : {
2881 : 0 : int toadd = nentities, prev = nentities;
2882 [ # # ]: 0 : for( int i = 0; i < nlevels; i++ )
2883 : : {
2884 : 0 : int d = get_index_from_degree( level_dsequence[i] );
2885 : 0 : int nch = refTemplates[MBEDGE - 1][d].total_new_ents;
2886 : 0 : prev = prev * nch;
2887 : 0 : toadd += prev;
2888 : : }
2889 : :
2890 : 0 : data.push_back( buffer[toadd + 2 * entity_index] );
2891 : 0 : data.push_back( buffer[toadd + 2 * entity_index + 1] );
2892 : : }
2893 : : else
2894 [ # # ][ # # ]: 0 : MB_SET_ERR( MB_FAILURE, "Requesting invalid info from buffer for edges" );
[ # # ][ # # ]
[ # # ]
2895 : : }
2896 [ # # ]: 0 : else if( listtype == 0 ) // VList
2897 : : {
2898 : : // VList = <V> where V = <V0, V1, ..,VL>
2899 [ # # ]: 0 : if( datatype == 0 )
2900 : : {
2901 : 0 : int idx = level * nentities + entity_index;
2902 : 0 : data.push_back( buffer[idx] );
2903 : : }
2904 : : else
2905 [ # # ][ # # ]: 0 : MB_SET_ERR( MB_FAILURE, "Requesting invalid info from buffer for vertices" );
[ # # ][ # # ]
[ # # ]
2906 : : }
2907 : : else
2908 [ # # ][ # # ]: 0 : MB_SET_ERR( MB_FAILURE, "Requesting invalid info from buffer" );
[ # # ][ # # ]
[ # # ]
2909 : :
2910 : 0 : return MB_SUCCESS;
2911 : : }
2912 : :
2913 : 0 : bool NestedRefine::check_for_parallelinfo( EntityHandle entity, int proc, std::multimap< EntityHandle, int >& remProcs )
2914 : : {
2915 : 0 : bool found = false;
2916 : :
2917 [ # # ]: 0 : std::pair< std::multimap< EntityHandle, int >::iterator, std::multimap< EntityHandle, int >::iterator > it_hes;
2918 [ # # ]: 0 : it_hes = remProcs.equal_range( entity );
2919 : :
2920 [ # # ][ # # ]: 0 : for( std::multimap< EntityHandle, int >::iterator it = it_hes.first; it != it_hes.second; ++it )
[ # # ]
2921 : : {
2922 [ # # ][ # # ]: 0 : if( it->second == proc )
2923 : : {
2924 : 0 : found = true;
2925 : 0 : break;
2926 : : }
2927 : : }
2928 : :
2929 : 0 : return found;
2930 : : }
2931 : :
2932 : 0 : ErrorCode NestedRefine::check_for_parallelinfo( EntityHandle entity, int proc,
2933 : : std::multimap< EntityHandle, EntityHandle >& remHandles,
2934 : : std::multimap< EntityHandle, int >& remProcs, EntityHandle& rhandle )
2935 : : {
2936 : : // shared procs for given entity
2937 [ # # ]: 0 : std::pair< std::multimap< EntityHandle, int >::iterator, std::multimap< EntityHandle, int >::iterator > it_ps;
2938 [ # # ]: 0 : it_ps = remProcs.equal_range( entity );
2939 : :
2940 : : // shared remote handles for given entity
2941 : : std::pair< std::multimap< EntityHandle, EntityHandle >::iterator,
2942 : : std::multimap< EntityHandle, EntityHandle >::iterator >
2943 [ # # ]: 0 : it_hs;
2944 [ # # ]: 0 : it_hs = remHandles.equal_range( entity );
2945 : :
2946 [ # # ]: 0 : std::multimap< EntityHandle, int >::iterator itp;
2947 [ # # ]: 0 : std::multimap< EntityHandle, EntityHandle >::iterator ith;
2948 : :
2949 [ # # ][ # # ]: 0 : for( itp = it_ps.first, ith = it_hs.first; itp != it_ps.second; ++itp, ++ith )
[ # # ][ # # ]
2950 : : {
2951 [ # # ][ # # ]: 0 : if( itp->second == proc )
2952 : : {
2953 [ # # ]: 0 : rhandle = ith->second;
2954 : 0 : break;
2955 : : }
2956 : : }
2957 : :
2958 : 0 : return MB_SUCCESS;
2959 : : }
2960 : :
2961 : : #endif
2962 : :
2963 : : /**********************************
2964 : : * Update AHF maps *
2965 : : * ********************************/
2966 : :
2967 : 11169 : ErrorCode NestedRefine::update_local_ahf( int deg, EntityType type, int pat_id, EntityHandle* vbuffer,
2968 : : EntityHandle* ent_buffer, int etotal )
2969 : : {
2970 : : ErrorCode error;
2971 : 11169 : int nhf = 0, nv = 0, total_new_verts = 0;
2972 [ + - ]: 11169 : int d = get_index_from_degree( deg );
2973 : :
2974 : : // Get the number of half-facets
2975 [ + + ]: 11169 : if( type == MBEDGE )
2976 : : {
2977 : 855 : nhf = 2;
2978 : 855 : nv = 2;
2979 : 855 : total_new_verts = refTemplates[0][d].total_new_verts;
2980 : : }
2981 [ + + ][ + + ]: 10314 : else if( type == MBTRI || type == MBQUAD )
2982 : : {
2983 : 5544 : nhf = ahf->lConnMap2D[type - 2].num_verts_in_face;
2984 : 5544 : nv = nhf;
2985 : 5544 : total_new_verts = refTemplates[pat_id][d].total_new_verts;
2986 : : }
2987 [ + + ][ + - ]: 4770 : else if( type == MBTET || type == MBHEX )
2988 : : {
2989 [ + - ][ + - ]: 4770 : int index = ahf->get_index_in_lmap( *_incells.begin() );
[ + - ]
2990 : 4770 : nhf = ahf->lConnMap3D[index].num_faces_in_cell;
2991 : 4770 : nv = ahf->lConnMap3D[index].num_verts_in_cell;
2992 : 4770 : total_new_verts = refTemplates[pat_id][d].total_new_verts;
2993 : : }
2994 : :
2995 [ + - ]: 11169 : std::vector< EntityHandle > ent;
2996 [ + - ]: 22338 : std::vector< int > lid;
2997 : :
2998 : : // Update the vertex to half-facet map
2999 [ + + ]: 103959 : for( int i = 0; i < total_new_verts; i++ )
3000 : : {
3001 : 92790 : ent.clear();
3002 : 92790 : lid.clear();
3003 : 92790 : EntityHandle vid = vbuffer[i + nv];
3004 [ + - ][ - + ]: 92790 : error = ahf->get_incident_map( type, vid, ent, lid );MB_CHK_ERR( error );
[ # # ][ # # ]
3005 : :
3006 [ + - ][ + + ]: 92790 : if( ent[0] ) continue;
3007 : :
3008 : 43469 : int id = refTemplates[pat_id][d].v2hf[i + nv][0] - 1;
3009 [ + - ]: 43469 : ent[0] = ent_buffer[id];
3010 [ + - ]: 43469 : lid[0] = refTemplates[pat_id][d].v2hf[i + nv][1];
3011 : :
3012 [ + - ][ - + ]: 43469 : error = ahf->set_incident_map( type, vid, ent, lid );MB_CHK_ERR( error );
[ # # ][ # # ]
3013 : : }
3014 : :
3015 : : // Update the sibling half-facet map
3016 [ + + ]: 87851 : for( int i = 0; i < etotal; i++ )
3017 : : {
3018 [ + - ]: 76682 : std::vector< EntityHandle > sib_entids( nhf );
3019 [ + - ][ + - ]: 153364 : std::vector< int > sib_lids( nhf );
3020 : :
3021 [ + - ][ + - ]: 76682 : error = ahf->get_sibling_map( type, ent_buffer[i], &sib_entids[0], &sib_lids[0], nhf );MB_CHK_ERR( error );
[ + - ][ - + ]
[ # # ][ # # ]
3022 : :
3023 [ + + ]: 391928 : for( int l = 0; l < nhf; l++ )
3024 : : {
3025 [ + - ][ + + ]: 315246 : if( sib_entids[l] ) continue;
3026 : :
3027 : : // Fill out the sibling values
3028 : 227542 : int id = refTemplates[pat_id][d].ents_opphfs[i][2 * l];
3029 [ + + ]: 227542 : if( id )
3030 : : {
3031 [ + - ]: 87704 : sib_entids[l] = ent_buffer[id - 1];
3032 [ + - ]: 87704 : sib_lids[l] = refTemplates[pat_id][d].ents_opphfs[i][2 * l + 1];
3033 : : }
3034 : : else
3035 : : {
3036 [ + - ]: 139838 : sib_entids[l] = 0;
3037 [ + - ]: 139838 : sib_lids[l] = 0;
3038 : : }
3039 : : }
3040 : :
3041 [ + - ][ + - ]: 76682 : error = ahf->set_sibling_map( type, ent_buffer[i], &sib_entids[0], &sib_lids[0], nhf );MB_CHK_ERR( error );
[ + - ][ - + ]
[ # # ][ # # ]
3042 : :
3043 [ + + ][ + - ]: 391928 : for( int l = 0; l < nhf; l++ )
3044 : : {
3045 [ + - ][ + + ]: 315246 : if( sib_entids[l] )
3046 : : {
3047 : :
3048 : 175408 : EntityHandle set_entid = ent_buffer[i];
3049 : 175408 : int set_lid = l;
3050 : :
3051 [ + - ][ + - ]: 175408 : error = ahf->set_sibling_map( type, sib_entids[l], sib_lids[l], set_entid, set_lid );MB_CHK_ERR( error );
[ + - ][ - + ]
[ # # ][ # # ]
3052 : : }
3053 : : }
3054 : 76682 : }
3055 : 22338 : return MB_SUCCESS;
3056 : : }
3057 : :
3058 : 8784 : ErrorCode NestedRefine::update_local_ahf( int deg, EntityType type, EntityHandle* vbuffer, EntityHandle* ent_buffer,
3059 : : int etotal )
3060 : : {
3061 : : ErrorCode error;
3062 [ - + ]: 8784 : assert( type != MBTET );
3063 [ - + ][ # # ]: 8784 : error = update_local_ahf( deg, type, type - 1, vbuffer, ent_buffer, etotal );MB_CHK_ERR( error );
3064 : :
3065 : 8784 : return MB_SUCCESS;
3066 : : }
3067 : :
3068 : 48 : ErrorCode NestedRefine::update_global_ahf( EntityType type, int cur_level, int deg, std::vector< int >* pattern_ids )
3069 : : {
3070 : :
3071 : : ErrorCode error;
3072 : :
3073 : : // Get the number of half-facets and number of children of each type
3074 [ + + ]: 48 : if( type == MBEDGE )
3075 : : {
3076 [ - + ]: 10 : assert( pattern_ids == NULL );
3077 [ - + ][ # # ]: 10 : error = update_global_ahf_1D( cur_level, deg );MB_CHK_ERR( error );
3078 : : }
3079 [ + + ][ + + ]: 60 : else if( type == MBTRI || type == MBQUAD )
3080 : : {
3081 [ - + ]: 22 : assert( pattern_ids == NULL );
3082 [ - + ][ # # ]: 22 : error = update_global_ahf_2D( cur_level, deg );MB_CHK_ERR( error );
3083 : : }
3084 [ + + ]: 16 : else if( type == MBHEX )
3085 : : {
3086 [ - + ]: 8 : assert( pattern_ids == NULL );
3087 [ - + ][ # # ]: 8 : error = update_global_ahf_3D( cur_level, deg );MB_CHK_ERR( error );
3088 : : }
3089 [ + - ]: 8 : else if( type == MBTET )
3090 : : {
3091 [ - + ]: 8 : assert( pattern_ids != NULL );
3092 [ - + ][ # # ]: 8 : error = update_global_ahf_3D( cur_level, deg, pattern_ids );MB_CHK_ERR( error );
3093 : : }
3094 : : else
3095 [ # # ][ # # ]: 0 : MB_SET_ERR( MB_NOT_IMPLEMENTED, "Requesting AHF update for an unsupported mesh entity type" );
[ # # ][ # # ]
[ # # ]
3096 : :
3097 : 48 : return MB_SUCCESS;
3098 : : }
3099 : :
3100 : : /*ErrorCode NestedRefine::update_global_ahf(int cur_level, int deg, std::vector<int> &pattern_ids)
3101 : : {
3102 : : ErrorCode error;
3103 : : error = update_global_ahf_3D(cur_level, deg, pattern_ids); MB_CHK_ERR(error);
3104 : :
3105 : : return MB_SUCCESS;
3106 : : }*/
3107 : :
3108 : 10 : ErrorCode NestedRefine::update_global_ahf_1D( int cur_level, int deg )
3109 : : {
3110 : : ErrorCode error;
3111 [ + - ]: 10 : int d = get_index_from_degree( deg );
3112 : : int nhf, nchilds, nverts_prev, nents_prev;
3113 : 10 : nhf = 2;
3114 : 10 : nchilds = refTemplates[0][d].total_new_ents;
3115 [ + + ]: 10 : if( cur_level )
3116 : : {
3117 : 7 : nverts_prev = level_mesh[cur_level - 1].num_verts;
3118 : 7 : nents_prev = level_mesh[cur_level - 1].num_edges;
3119 : : }
3120 : : else
3121 : : {
3122 [ + - ]: 3 : nverts_prev = _inverts.size();
3123 [ + - ]: 3 : nents_prev = _inedges.size();
3124 : : }
3125 : :
3126 [ + - ][ + - ]: 20 : std::vector< EntityHandle > inci_ent, child_ents;
3127 [ + - ][ + - ]: 20 : std::vector< int > inci_lid, child_lids;
3128 : :
3129 : : // Update the vertex to half-facet maps for duplicate vertices
3130 [ + + ]: 871 : for( int i = 0; i < nverts_prev; i++ )
3131 : : {
3132 : 861 : inci_ent.clear();
3133 : 861 : inci_lid.clear();
3134 : 861 : child_ents.clear();
3135 : 861 : child_lids.clear();
3136 : :
3137 : : // Vertex id in the previous mesh and the current one
3138 : : EntityHandle vid;
3139 [ + + ]: 861 : if( cur_level )
3140 : 844 : vid = level_mesh[cur_level - 1].start_vertex + i;
3141 : : else
3142 [ + - ]: 17 : vid = _inverts[i];
3143 : 861 : EntityHandle cur_vid = level_mesh[cur_level].start_vertex + i;
3144 : :
3145 : : // Get the incident half-vert in the previous mesh
3146 [ + - ][ - + ]: 861 : error = ahf->get_incident_map( MBEDGE, vid, inci_ent, inci_lid );MB_CHK_ERR( error );
[ # # ][ # # ]
3147 : :
3148 : : // Obtain the corresponding incident child in the current mesh
3149 [ + - ][ + - ]: 861 : int lvid = get_local_vid( vid, inci_ent[0], cur_level - 1 );
3150 [ - + ][ # # ]: 861 : if( lvid < 0 ) MB_SET_ERR( MB_FAILURE, "did not find local vertex ix " );
[ # # ][ # # ]
[ # # ][ # # ]
3151 : 861 : int chid = refTemplates[0][d].v2hf[lvid][0] - 1;
3152 : :
3153 : : int pid;
3154 [ + + ]: 861 : if( cur_level )
3155 [ + - ]: 844 : pid = inci_ent[0] - level_mesh[cur_level - 1].start_edge;
3156 : : else
3157 [ + - ][ + - ]: 17 : pid = inci_ent[0] - *_inedges.begin();
[ + - ]
3158 : :
3159 : 861 : int ind = nchilds * pid;
3160 : :
3161 [ + - ]: 861 : child_ents.push_back( level_mesh[cur_level].start_edge + ind + chid );
3162 [ + - ]: 861 : child_lids.push_back( refTemplates[0][d].v2hf[lvid][1] );
3163 : :
3164 [ + - ][ - + ]: 861 : error = ahf->set_incident_map( MBEDGE, cur_vid, child_ents, child_lids );MB_CHK_ERR( error );
[ # # ][ # # ]
3165 : : }
3166 : :
3167 : : // Update the sibling half-facet maps across entities
3168 [ + + ]: 865 : for( int i = 0; i < nents_prev; i++ )
3169 : : {
3170 : : EntityHandle ent;
3171 [ + + ]: 855 : if( cur_level )
3172 : 840 : ent = level_mesh[cur_level - 1].start_edge + i;
3173 : : else
3174 [ + - ]: 15 : ent = _inedges[i];
3175 : :
3176 [ + - ]: 855 : std::vector< EntityHandle > sib_entids( nhf );
3177 [ + - ][ + - ]: 1710 : std::vector< int > sib_lids( nhf );
3178 : :
3179 [ + - ][ + - ]: 855 : error = ahf->get_sibling_map( MBEDGE, ent, &sib_entids[0], &sib_lids[0], nhf );MB_CHK_ERR( error );
[ + - ][ - + ]
[ # # ][ # # ]
3180 : :
3181 : : int id, idx;
3182 : :
3183 [ + + ][ + - ]: 2565 : for( int l = 0; l < nhf; l++ )
3184 : : {
3185 [ + - ][ + + ]: 1710 : if( !sib_entids[l] ) continue;
3186 : :
3187 : : // Find the child incident on the half-facet
3188 : 1692 : id = refTemplates[0][d].ents_on_pent[l][1] - 1;
3189 : 1692 : idx = nchilds * i;
3190 : 1692 : EntityHandle child_ent = level_mesh[cur_level].start_edge + idx + id;
3191 : 1692 : int ch_lid = l;
3192 : :
3193 : : // Find the sibling of the child
3194 [ + - ]: 1692 : std::vector< EntityHandle > sib_childs( nhf );
3195 [ + - ]: 3384 : std::vector< int > sib_chlids( nhf );
[ + - - ]
3196 : :
3197 [ + - ][ + - ]: 1692 : error = ahf->get_sibling_map( MBEDGE, child_ent, &sib_childs[0], &sib_chlids[0], nhf );MB_CHK_ERR( error );
[ + - ][ - + ]
[ # # ][ # # ]
3198 : :
3199 : : // If the sibling already exists, dont do anything
3200 [ + - ][ - + ]: 1692 : if( sib_childs[ch_lid] ) continue;
3201 : :
3202 : : // Get the correponding child of the sibling of the current parent
3203 : : int psib;
3204 [ + + ]: 1692 : if( cur_level )
3205 [ + - ]: 1668 : psib = sib_entids[l] - level_mesh[cur_level - 1].start_edge;
3206 : : else
3207 [ + - ][ + - ]: 24 : psib = sib_entids[l] - *_inedges.begin();
[ + - ]
3208 : :
3209 [ + - ]: 1692 : int plid = sib_lids[l];
3210 : :
3211 : 1692 : id = refTemplates[0][d].ents_on_pent[plid][1] - 1;
3212 : 1692 : idx = nchilds * psib;
3213 : :
3214 : 1692 : EntityHandle psib_child = level_mesh[cur_level].start_edge + idx + id;
3215 : 1692 : int psib_chlid = plid;
3216 : :
3217 : : // Set the siblings
3218 [ + - ]: 1692 : sib_childs[ch_lid] = psib_child;
3219 [ + - ]: 1692 : sib_chlids[ch_lid] = psib_chlid;
3220 : :
3221 [ + - ][ + - ]: 1692 : error = ahf->set_sibling_map( MBEDGE, child_ent, &sib_childs[0], &sib_chlids[0], nhf );MB_CHK_ERR( error );
[ + - ][ - + ]
[ # # ][ # # ]
[ + - - ]
3222 : 1692 : }
3223 : 855 : }
3224 : :
3225 : 20 : return MB_SUCCESS;
3226 : : }
3227 : :
3228 : 0 : ErrorCode NestedRefine::update_global_ahf_1D_sub( int cur_level, int deg )
3229 : : {
3230 : : ErrorCode error;
3231 [ # # ]: 0 : int d = get_index_from_degree( deg );
3232 : : int nhf, nchilds, nents_prev;
3233 : 0 : nhf = 2;
3234 : 0 : nchilds = refTemplates[0][d].total_new_ents;
3235 [ # # ]: 0 : if( cur_level ) { nents_prev = level_mesh[cur_level - 1].num_edges; }
3236 : : else
3237 : : {
3238 [ # # ]: 0 : nents_prev = _inedges.size();
3239 : : }
3240 : :
3241 : : // Update the sibling half-facet maps across entities
3242 : :
3243 [ # # ]: 0 : std::vector< EntityHandle > conn;
3244 [ # # ]: 0 : for( int i = 0; i < nents_prev; i++ )
3245 : : {
3246 : : EntityHandle ent;
3247 [ # # ]: 0 : if( cur_level )
3248 : 0 : ent = level_mesh[cur_level - 1].start_edge + i;
3249 : : else
3250 [ # # ]: 0 : ent = _inedges[i];
3251 : :
3252 : : // Set incident hv maps
3253 : 0 : conn.clear();
3254 [ # # ][ # # ]: 0 : error = get_connectivity( ent, cur_level, conn );MB_CHK_ERR( error );
[ # # ][ # # ]
3255 : :
3256 [ # # ][ # # ]: 0 : std::vector< EntityHandle > inci_ent, child_ents;
[ # # ]
3257 [ # # ][ # # ]: 0 : std::vector< int > inci_lid, child_lids;
[ # # ][ # # ]
3258 [ # # ]: 0 : for( int j = 0; j < 2; j++ )
3259 : : {
3260 : 0 : inci_ent.clear();
3261 : 0 : inci_lid.clear();
3262 : 0 : child_ents.clear();
3263 : 0 : child_lids.clear();
3264 : :
3265 : : // Get the entityhandle of the vertex from previous level in the current level
3266 : : EntityHandle cur_vid;
3267 [ # # ]: 0 : if( cur_level )
3268 [ # # ]: 0 : cur_vid = level_mesh[cur_level].start_vertex + ( conn[j] - level_mesh[cur_level - 1].start_vertex );
3269 : : else
3270 [ # # ][ # # ]: 0 : cur_vid = level_mesh[cur_level].start_vertex + ( conn[j] - *_inverts.begin() );
[ # # ]
3271 : :
3272 : : // Obtain the incident half-facet. If exists, then no need to assign another
3273 [ # # ][ # # ]: 0 : error = ahf->get_incident_map( MBEDGE, cur_vid, inci_ent, inci_lid );MB_CHK_ERR( error );
[ # # ][ # # ]
3274 [ # # ][ # # ]: 0 : if( inci_ent[0] != 0 ) continue;
3275 : :
3276 : : // Get the incident half-facet on the old vertex
3277 [ # # ][ # # ]: 0 : error = ahf->get_incident_map( MBEDGE, conn[j], inci_ent, inci_lid );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ]
3278 : :
3279 : : // Obtain the corresponding incident child in the current mesh
3280 [ # # ][ # # ]: 0 : int lvid = get_local_vid( conn[j], inci_ent[0], cur_level - 1 );
[ # # ]
3281 [ # # ][ # # ]: 0 : if( lvid < 0 ) MB_SET_ERR( MB_FAILURE, "did not find local vertex ix " );
[ # # ][ # # ]
[ # # ][ # # ]
3282 : 0 : int chid = refTemplates[0][d].v2hf[lvid][0] - 1;
3283 : :
3284 : : int pid;
3285 [ # # ]: 0 : if( cur_level )
3286 [ # # ]: 0 : pid = inci_ent[0] - level_mesh[cur_level - 1].start_edge;
3287 : : else
3288 [ # # ][ # # ]: 0 : pid = inci_ent[0] - *_inedges.begin();
[ # # ]
3289 : :
3290 : 0 : int ind = nchilds * pid;
3291 : :
3292 [ # # ]: 0 : child_ents.push_back( level_mesh[cur_level].start_edge + ind + chid );
3293 [ # # ]: 0 : child_lids.push_back( refTemplates[0][d].v2hf[lvid][1] );
3294 : :
3295 [ # # ][ # # ]: 0 : error = ahf->set_incident_map( MBEDGE, cur_vid, child_ents, child_lids );MB_CHK_ERR( error );
[ # # ][ # # ]
3296 : : }
3297 : :
3298 [ # # ][ # # ]: 0 : std::vector< EntityHandle > sib_entids( nhf );
3299 [ # # ][ # # ]: 0 : std::vector< int > sib_lids( nhf );
3300 : :
3301 [ # # ][ # # ]: 0 : error = ahf->get_sibling_map( MBEDGE, ent, &sib_entids[0], &sib_lids[0], nhf );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ][ # # ]
3302 : :
3303 : : int id, idx;
3304 : :
3305 [ # # ][ # # ]: 0 : for( int l = 0; l < nhf; l++ )
3306 : : {
3307 [ # # ][ # # ]: 0 : if( !sib_entids[l] ) continue;
3308 : :
3309 : : // Find the child incident on the half-facet
3310 : 0 : id = refTemplates[0][d].ents_on_pent[l][1] - 1;
3311 : 0 : idx = nchilds * i;
3312 : 0 : EntityHandle child_ent = level_mesh[cur_level].start_edge + idx + id;
3313 : 0 : int ch_lid = l;
3314 : :
3315 : : // Find the sibling of the child
3316 [ # # ]: 0 : std::vector< EntityHandle > sib_childs( nhf );
3317 [ # # ]: 0 : std::vector< int > sib_chlids( nhf );
[ # # # ]
3318 : :
3319 [ # # ][ # # ]: 0 : error = ahf->get_sibling_map( MBEDGE, child_ent, &sib_childs[0], &sib_chlids[0], nhf );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ][ # # ]
3320 : :
3321 : : // If the sibling already exists, dont do anything
3322 [ # # ][ # # ]: 0 : if( sib_childs[ch_lid] ) continue;
3323 : :
3324 : : // Get the correponding child of the sibling of the current parent
3325 : : int psib;
3326 [ # # ]: 0 : if( cur_level )
3327 [ # # ]: 0 : psib = sib_entids[l] - level_mesh[cur_level - 1].start_edge;
3328 : : else
3329 [ # # ][ # # ]: 0 : psib = sib_entids[l] - *_inedges.begin();
[ # # ]
3330 : :
3331 [ # # ]: 0 : int plid = sib_lids[l];
3332 : :
3333 : 0 : id = refTemplates[0][d].ents_on_pent[plid][1] - 1;
3334 : 0 : idx = nchilds * psib;
3335 : :
3336 : 0 : EntityHandle psib_child = level_mesh[cur_level].start_edge + idx + id;
3337 : 0 : int psib_chlid = plid;
3338 : :
3339 : : // Set the siblings
3340 [ # # ]: 0 : sib_childs[ch_lid] = psib_child;
3341 [ # # ]: 0 : sib_chlids[ch_lid] = psib_chlid;
3342 : :
3343 [ # # ][ # # ]: 0 : error = ahf->set_sibling_map( MBEDGE, child_ent, &sib_childs[0], &sib_chlids[0], nhf );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # ]
3344 : 0 : }
3345 : 0 : }
3346 : :
3347 : 0 : return MB_SUCCESS;
3348 : : }
3349 : :
3350 : 0 : ErrorCode NestedRefine::update_ahf_1D( int cur_level )
3351 : : {
3352 : : ErrorCode error;
3353 [ # # ][ # # ]: 0 : error = ahf->determine_sibling_halfverts( level_mesh[cur_level].verts, level_mesh[cur_level].edges );MB_CHK_ERR( error );
3354 : :
3355 [ # # ][ # # ]: 0 : error = ahf->determine_incident_halfverts( level_mesh[cur_level].edges );MB_CHK_ERR( error );
3356 : :
3357 : 0 : return MB_SUCCESS;
3358 : : }
3359 : :
3360 : 22 : ErrorCode NestedRefine::update_global_ahf_2D( int cur_level, int deg )
3361 : : {
3362 : : ErrorCode error;
3363 : :
3364 [ + - ][ + - ]: 22 : EntityType type = mbImpl->type_from_handle( *_infaces.begin() );
[ + - ]
3365 : : int nhf, nchilds, nverts_prev, nents_prev;
3366 : :
3367 : 22 : nhf = ahf->lConnMap2D[type - 2].num_verts_in_face;
3368 [ + - ]: 22 : int d = get_index_from_degree( deg );
3369 : 22 : nchilds = refTemplates[type - 1][d].total_new_ents;
3370 : :
3371 [ + + ]: 22 : if( cur_level )
3372 : : {
3373 : 14 : nverts_prev = level_mesh[cur_level - 1].num_verts;
3374 : 14 : nents_prev = level_mesh[cur_level - 1].num_faces;
3375 : : }
3376 : : else
3377 : : {
3378 [ + - ]: 8 : nverts_prev = _inverts.size();
3379 [ + - ]: 8 : nents_prev = _infaces.size();
3380 : : }
3381 : :
3382 [ + - ][ + - ]: 44 : std::vector< EntityHandle > inci_ent, child_ents;
3383 [ + - ][ + - ]: 44 : std::vector< int > inci_lid, child_lids;
3384 : :
3385 : : // Update the vertex to half-edge maps for old/duplicate vertices
3386 [ + + ]: 3253 : for( int i = 0; i < nverts_prev; i++ )
3387 : : {
3388 : 3231 : inci_ent.clear();
3389 : 3231 : inci_lid.clear();
3390 : 3231 : child_ents.clear();
3391 : 3231 : child_lids.clear();
3392 : :
3393 : : // Vertex id in the previous mesh
3394 : : EntityHandle vid;
3395 [ + + ]: 3231 : if( cur_level )
3396 : 3069 : vid = level_mesh[cur_level - 1].start_vertex + i;
3397 : : else
3398 [ + - ]: 162 : vid = _inverts[i];
3399 : 3231 : EntityHandle cur_vid = level_mesh[cur_level].start_vertex + i;
3400 : :
3401 : : // Get the incident half-vert in the previous mesh
3402 [ + - ][ - + ]: 3231 : error = ahf->get_incident_map( type, vid, inci_ent, inci_lid );MB_CHK_ERR( error );
[ # # ][ # # ]
3403 : :
3404 : : // Obtain the corresponding incident child in the current mesh
3405 [ + + ]: 6462 : for( int j = 0; j < (int)inci_ent.size(); j++ )
3406 : : {
3407 [ + - ][ + - ]: 3231 : int lvid = get_local_vid( vid, inci_ent[j], cur_level - 1 );
3408 [ - + ][ # # ]: 3231 : if( lvid < 0 ) MB_SET_ERR( MB_FAILURE, "did not find local vertex ix " );
[ # # ][ # # ]
[ # # ][ # # ]
3409 : 3231 : int chid = refTemplates[type - 1][d].v2hf[lvid][0] - 1;
3410 : :
3411 : : int pid;
3412 [ + + ]: 3231 : if( cur_level )
3413 [ + - ]: 3069 : pid = inci_ent[j] - level_mesh[cur_level - 1].start_face;
3414 : : else
3415 [ + - ][ + - ]: 162 : pid = inci_ent[j] - *_infaces.begin();
[ + - ]
3416 : :
3417 : 3231 : int ind = nchilds * pid;
3418 : :
3419 [ + - ]: 3231 : child_ents.push_back( level_mesh[cur_level].start_face + ind + chid );
3420 [ + - ]: 3231 : child_lids.push_back( refTemplates[type - 1][d].v2hf[lvid][1] );
3421 : : }
3422 [ + - ][ - + ]: 3231 : error = ahf->set_incident_map( type, cur_vid, child_ents, child_lids );MB_CHK_ERR( error );
[ # # ][ # # ]
3423 : : }
3424 : :
3425 : : EntityHandle fedge[2];
3426 : :
3427 : : // Update the sibling half-facet maps across entities
3428 [ + + ]: 5566 : for( int i = 0; i < nents_prev; i++ )
3429 : : {
3430 : : EntityHandle ent;
3431 [ + + ]: 5544 : if( cur_level )
3432 : 5300 : ent = level_mesh[cur_level - 1].start_face + i;
3433 : : else
3434 [ + - ]: 244 : ent = _infaces[i];
3435 : :
3436 [ + - ]: 5544 : std::vector< EntityHandle > fid_conn;
3437 [ + - ]: 5544 : error = get_connectivity( ent, cur_level, fid_conn );
3438 [ - + ]: 5544 : if( MB_SUCCESS != error ) return error;
3439 : :
3440 [ + - ][ + - ]: 11088 : std::vector< EntityHandle > sib_entids( nhf );
3441 [ + - ][ + - ]: 11088 : std::vector< int > sib_lids( nhf );
3442 : :
3443 [ + - ][ + - ]: 5544 : error = ahf->get_sibling_map( type, ent, &sib_entids[0], &sib_lids[0], nhf );MB_CHK_ERR( error );
[ + - ][ - + ]
[ # # ][ # # ]
3444 : :
3445 : : int id, idx;
3446 : :
3447 [ + + ][ + - ]: 22723 : for( int l = 0; l < nhf; l++ )
3448 : : {
3449 [ + - ][ + + ]: 17179 : if( !sib_entids[l] ) continue;
3450 : :
3451 : 16792 : int nidx = ahf->lConnMap2D[type - 2].next[l];
3452 [ + - ]: 16792 : fedge[0] = fid_conn[l];
3453 [ + - ]: 16792 : fedge[1] = fid_conn[nidx];
3454 : :
3455 [ + - ]: 16792 : EntityHandle sfid = sib_entids[l];
3456 [ + - ]: 16792 : int slid = sib_lids[l];
3457 : :
3458 [ + - ]: 16792 : std::vector< EntityHandle > conn;
3459 [ + - ]: 16792 : error = get_connectivity( sfid, cur_level, conn );
3460 [ - + ]: 16792 : if( MB_SUCCESS != error ) return error;
3461 : :
3462 : 16792 : bool orient = true;
3463 : 16792 : nidx = ahf->lConnMap2D[type - 2].next[slid];
3464 [ + - ][ + + ]: 16792 : if( ( fedge[1] == conn[slid] ) && ( fedge[0] == conn[nidx] ) ) orient = false;
[ + - ][ + - ]
[ + + ]
3465 : :
3466 [ + + ][ + - ]: 16792 : if( orient ) assert( ( fedge[0] == conn[slid] ) && ( fedge[1] == conn[nidx] ) );
[ + - ][ + - ]
[ - + ]
3467 : :
3468 : : // Find the childrens incident on the half-facet
3469 : 16792 : int nch = refTemplates[type - 1][d].ents_on_pent[l][0];
3470 : 16792 : idx = nchilds * i;
3471 : :
3472 : : // Loop over all the incident childrens
3473 [ + + ][ + - ]: 56134 : for( int k = 0; k < nch; k++ )
3474 : : {
3475 : 39342 : id = refTemplates[type - 1][d].ents_on_pent[l][k + 1] - 1;
3476 : 39342 : EntityHandle child_ent = level_mesh[cur_level].start_face + idx + id;
3477 : 39342 : int child_lid = l;
3478 : :
3479 : : // Find the sibling of the child
3480 : : EntityHandle child_sibent;
3481 : : int child_siblid;
3482 [ + - ][ - + ]: 39342 : error = ahf->get_sibling_map( type, child_ent, child_lid, child_sibent, child_siblid );MB_CHK_ERR( error );
[ # # ][ # # ]
3483 : :
3484 [ - + ]: 39342 : if( child_sibent != 0 ) continue;
3485 : :
3486 : : // Get the correponding child of the sibling of the current parent
3487 : : int psib;
3488 [ + + ]: 39342 : if( cur_level )
3489 : 37808 : psib = sfid - level_mesh[cur_level - 1].start_face;
3490 : : else
3491 [ + - ][ + - ]: 1534 : psib = sfid - *_infaces.begin();
3492 : :
3493 : 39342 : int plid = slid;
3494 : :
3495 [ + + ]: 39342 : if( orient )
3496 : 304 : id = refTemplates[type - 1][d].ents_on_pent[plid][k + 1] - 1;
3497 : : else
3498 : 39038 : id = refTemplates[type - 1][d].ents_on_pent[plid][nch - k] - 1;
3499 : :
3500 : 39342 : int sidx = nchilds * psib;
3501 : :
3502 : 39342 : EntityHandle psib_child = level_mesh[cur_level].start_face + sidx + id;
3503 : 39342 : int psib_chlid = plid;
3504 : :
3505 : : // Set the siblings
3506 [ + - ][ - + ]: 39342 : error = ahf->set_sibling_map( type, child_ent, child_lid, psib_child, psib_chlid );MB_CHK_ERR( error );
[ # # ][ # # ]
3507 : : }
3508 : 16792 : }
3509 : 5544 : }
3510 : :
3511 : 44 : return MB_SUCCESS;
3512 : : }
3513 : :
3514 : 0 : ErrorCode NestedRefine::update_global_ahf_2D_sub( int cur_level, int deg )
3515 : : {
3516 : : ErrorCode error;
3517 [ # # ]: 0 : int d = get_index_from_degree( deg );
3518 [ # # ][ # # ]: 0 : EntityType type = mbImpl->type_from_handle( *_infaces.begin() );
[ # # ]
3519 : : int nhf, nchilds, nents_prev;
3520 : 0 : nhf = ahf->lConnMap2D[type - 2].num_verts_in_face;
3521 : 0 : nchilds = refTemplates[type - 1][d].total_new_ents;
3522 : :
3523 [ # # ]: 0 : if( cur_level )
3524 : 0 : nents_prev = level_mesh[cur_level - 1].num_faces;
3525 : : else
3526 [ # # ]: 0 : nents_prev = _infaces.size();
3527 : :
3528 : : EntityHandle fedge[2];
3529 : :
3530 : : // Update the sibling half-facet maps across entities
3531 [ # # ]: 0 : for( int i = 0; i < nents_prev; i++ )
3532 : : {
3533 : : EntityHandle ent;
3534 [ # # ]: 0 : if( cur_level )
3535 : 0 : ent = level_mesh[cur_level - 1].start_face + i;
3536 : : else
3537 [ # # ]: 0 : ent = _infaces[i];
3538 : :
3539 [ # # ]: 0 : std::vector< EntityHandle > fid_conn;
3540 [ # # ]: 0 : error = get_connectivity( ent, cur_level, fid_conn );
3541 [ # # ]: 0 : if( MB_SUCCESS != error ) return error;
3542 : :
3543 [ # # ][ # # ]: 0 : std::vector< EntityHandle > inci_ent, child_ents;
[ # # ][ # # ]
3544 [ # # ][ # # ]: 0 : std::vector< int > inci_lid, child_lids;
[ # # ][ # # ]
3545 : :
3546 : : // Set incident half-edges
3547 [ # # ]: 0 : for( int j = 0; j < nhf; j++ )
3548 : : {
3549 : 0 : inci_ent.clear();
3550 : 0 : inci_lid.clear();
3551 : 0 : child_ents.clear();
3552 : 0 : child_lids.clear();
3553 : : EntityHandle cur_vid;
3554 [ # # ]: 0 : if( cur_level )
3555 [ # # ]: 0 : cur_vid = level_mesh[cur_level].start_vertex + ( fid_conn[j] - level_mesh[cur_level - 1].start_vertex );
3556 : : else
3557 [ # # ][ # # ]: 0 : cur_vid = level_mesh[cur_level].start_vertex + ( fid_conn[j] - *_inverts.begin() );
[ # # ]
3558 : :
3559 : : // Obtain the incident half-facet. If exists, then no need to assign another
3560 [ # # ][ # # ]: 0 : error = ahf->get_incident_map( type, cur_vid, inci_ent, inci_lid );MB_CHK_ERR( error );
[ # # ][ # # ]
3561 [ # # ][ # # ]: 0 : if( inci_ent[0] != 0 ) continue;
3562 : :
3563 : : // Get the incident half-facet on the old vertex
3564 [ # # ][ # # ]: 0 : error = ahf->get_incident_map( type, fid_conn[j], inci_ent, inci_lid );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ]
3565 : :
3566 : : // Obtain the corresponding incident child in the current mesh
3567 [ # # ]: 0 : for( int k = 0; k < (int)inci_ent.size(); k++ )
3568 : : {
3569 [ # # ][ # # ]: 0 : int lvid = get_local_vid( fid_conn[j], inci_ent[k], cur_level - 1 );
[ # # ]
3570 [ # # ][ # # ]: 0 : if( lvid < 0 ) MB_SET_ERR( MB_FAILURE, "did not find local vertex ix " );
[ # # ][ # # ]
[ # # ][ # # ]
3571 : 0 : int chid = refTemplates[type - 1][d].v2hf[lvid][0] - 1;
3572 : :
3573 : : int pid;
3574 [ # # ]: 0 : if( cur_level )
3575 [ # # ]: 0 : pid = inci_ent[k] - level_mesh[cur_level - 1].start_face;
3576 : : else
3577 [ # # ][ # # ]: 0 : pid = inci_ent[k] - *_infaces.begin();
[ # # ]
3578 : :
3579 : 0 : int ind = nchilds * pid;
3580 : :
3581 [ # # ]: 0 : child_ents.push_back( level_mesh[cur_level].start_face + ind + chid );
3582 [ # # ]: 0 : child_lids.push_back( refTemplates[type - 1][d].v2hf[lvid][1] );
3583 : : }
3584 : :
3585 [ # # ][ # # ]: 0 : error = ahf->set_incident_map( type, cur_vid, child_ents, child_lids );MB_CHK_ERR( error );
[ # # ][ # # ]
3586 : : }
3587 : :
3588 : : // Set sibling half-edges
3589 [ # # ][ # # ]: 0 : std::vector< EntityHandle > sib_entids( nhf );
3590 [ # # ][ # # ]: 0 : std::vector< int > sib_lids( nhf );
3591 : :
3592 [ # # ][ # # ]: 0 : error = ahf->get_sibling_map( type, ent, &sib_entids[0], &sib_lids[0], nhf );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ][ # # ]
3593 : :
3594 : : int id, idx;
3595 : :
3596 [ # # ][ # # ]: 0 : for( int l = 0; l < nhf; l++ )
3597 : : {
3598 [ # # ][ # # ]: 0 : if( !sib_entids[l] ) continue;
3599 : :
3600 : 0 : int nidx = ahf->lConnMap2D[type - 2].next[l];
3601 [ # # ]: 0 : fedge[0] = fid_conn[l];
3602 [ # # ]: 0 : fedge[1] = fid_conn[nidx];
3603 : :
3604 [ # # ]: 0 : EntityHandle sfid = sib_entids[l];
3605 [ # # ]: 0 : int slid = sib_lids[l];
3606 : :
3607 [ # # ]: 0 : std::vector< EntityHandle > conn;
3608 [ # # ][ # # ]: 0 : error = get_connectivity( sfid, cur_level, conn );MB_CHK_ERR( error );
[ # # ][ # # ]
3609 : :
3610 [ # # ][ # # ]: 0 : assert( (int)conn.size() > nidx && (int)conn.size() > slid );
3611 : :
3612 : 0 : bool orient = true;
3613 : 0 : nidx = ahf->lConnMap2D[type - 2].next[slid];
3614 [ # # ][ # # ]: 0 : if( ( fedge[1] == conn[slid] ) && ( fedge[0] == conn[nidx] ) ) orient = false;
[ # # ][ # # ]
[ # # ]
3615 : :
3616 [ # # ][ # # ]: 0 : if( orient ) assert( ( fedge[0] == conn[slid] ) && ( fedge[1] == conn[nidx] ) );
[ # # ][ # # ]
[ # # ]
3617 : :
3618 : : // Find the childrens incident on the half-facet
3619 : 0 : int nch = refTemplates[type - 1][d].ents_on_pent[l][0];
3620 : 0 : idx = nchilds * i;
3621 : :
3622 : : // Loop over all the incident childrens
3623 [ # # ][ # # ]: 0 : for( int k = 0; k < nch; k++ )
3624 : : {
3625 : 0 : id = refTemplates[type - 1][d].ents_on_pent[l][k + 1] - 1;
3626 : 0 : EntityHandle child_ent = level_mesh[cur_level].start_face + idx + id;
3627 : 0 : int child_lid = l;
3628 : :
3629 : : // Find the sibling of the child
3630 : : EntityHandle child_sibent;
3631 : : int child_siblid;
3632 [ # # ][ # # ]: 0 : error = ahf->get_sibling_map( type, child_ent, child_lid, child_sibent, child_siblid );MB_CHK_ERR( error );
[ # # ][ # # ]
3633 : :
3634 [ # # ]: 0 : if( child_sibent != 0 ) continue;
3635 : :
3636 : : // Get the correponding child of the sibling of the current parent
3637 : : int psib;
3638 [ # # ]: 0 : if( cur_level )
3639 : 0 : psib = sfid - level_mesh[cur_level - 1].start_face;
3640 : : else
3641 [ # # ][ # # ]: 0 : psib = sfid - *_infaces.begin();
3642 : :
3643 : 0 : int plid = slid;
3644 : :
3645 [ # # ]: 0 : if( orient )
3646 : 0 : id = refTemplates[type - 1][d].ents_on_pent[plid][k + 1] - 1;
3647 : : else
3648 : 0 : id = refTemplates[type - 1][d].ents_on_pent[plid][nch - k] - 1;
3649 : :
3650 : 0 : int sidx = nchilds * psib;
3651 : :
3652 : 0 : EntityHandle psib_child = level_mesh[cur_level].start_face + sidx + id;
3653 : 0 : int psib_chlid = plid;
3654 : :
3655 : : // Set the siblings
3656 [ # # ][ # # ]: 0 : error = ahf->set_sibling_map( type, child_ent, child_lid, psib_child, psib_chlid );MB_CHK_ERR( error );
[ # # ][ # # ]
3657 : : }
3658 : 0 : }
3659 : 0 : }
3660 : :
3661 : 0 : return MB_SUCCESS;
3662 : : }
3663 : :
3664 : 16 : ErrorCode NestedRefine::update_global_ahf_3D( int cur_level, int deg, std::vector< int >* pattern_ids )
3665 : : {
3666 : : ErrorCode error;
3667 : : int nvpc, ne, nhf, nchilds, nverts_prev, nents_prev;
3668 : :
3669 [ + - ][ + - ]: 16 : EntityType type = mbImpl->type_from_handle( *_incells.begin() );
[ + - ]
3670 [ + - ][ + - ]: 16 : int index = ahf->get_index_in_lmap( *_incells.begin() );
[ + - ]
3671 [ + - ]: 16 : int d = get_index_from_degree( deg );
3672 : :
3673 : 16 : nhf = ahf->lConnMap3D[index].num_faces_in_cell;
3674 : 16 : ne = ahf->lConnMap3D[index].num_edges_in_cell;
3675 : 16 : nvpc = ahf->lConnMap3D[index].num_verts_in_cell;
3676 : 16 : nchilds = refTemplates[type - 1][d].total_new_ents;
3677 : :
3678 [ + + ]: 16 : if( cur_level )
3679 : : {
3680 : 10 : nverts_prev = level_mesh[cur_level - 1].num_verts;
3681 : 10 : nents_prev = level_mesh[cur_level - 1].num_cells;
3682 : : }
3683 : : else
3684 : : {
3685 [ + - ]: 6 : nverts_prev = _inverts.size();
3686 [ + - ]: 6 : nents_prev = _incells.size();
3687 : : }
3688 : :
3689 [ + - ][ + - ]: 32 : std::vector< EntityHandle > inci_ent, child_ents;
3690 [ + - ][ + - ]: 32 : std::vector< int > inci_lid, child_lids;
3691 : :
3692 : : // Step 1: Update the V2HF maps for old/duplicate vertices
3693 [ + + ]: 3881 : for( int i = 0; i < nverts_prev; i++ )
3694 : : {
3695 : 3865 : inci_ent.clear();
3696 : 3865 : inci_lid.clear();
3697 : 3865 : child_ents.clear();
3698 : 3865 : child_lids.clear();
3699 : :
3700 : : // Vertex id in the previous mesh
3701 : : EntityHandle vid;
3702 [ + + ]: 3865 : if( cur_level )
3703 : 3805 : vid = level_mesh[cur_level - 1].start_vertex + i;
3704 : : else
3705 [ + - ]: 60 : vid = _inverts[i];
3706 : 3865 : EntityHandle cur_vid = level_mesh[cur_level].start_vertex + i;
3707 : :
3708 : : // Get the incident half-vert in the previous mesh
3709 [ + - ][ - + ]: 3865 : error = ahf->get_incident_map( type, vid, inci_ent, inci_lid );MB_CHK_ERR( error );
[ # # ][ # # ]
3710 : :
3711 : : // Obtain the corresponding incident child in the current mesh
3712 [ + + ]: 7730 : for( int j = 0; j < (int)inci_ent.size(); j++ )
3713 : : {
3714 [ + - ][ + - ]: 3865 : int lvid = get_local_vid( vid, inci_ent[j], cur_level - 1 );
3715 [ - + ][ # # ]: 3865 : if( lvid < 0 ) MB_SET_ERR( MB_FAILURE, "did not find local vertex ix " );
[ # # ][ # # ]
[ # # ][ # # ]
3716 : 3865 : int chid = refTemplates[type - 1][d].v2hf[lvid][0] - 1;
3717 : :
3718 : : int pid;
3719 [ + + ]: 3865 : if( cur_level )
3720 [ + - ]: 3805 : pid = inci_ent[j] - level_mesh[cur_level - 1].start_cell;
3721 : : else
3722 [ + - ][ + - ]: 60 : pid = inci_ent[j] - *_incells.begin();
[ + - ]
3723 : :
3724 : 3865 : int ind = nchilds * pid;
3725 : :
3726 : : // EntityHandle child_ent = level_mesh[cur_level].start_cell + ind+chid ;
3727 : : // int child_lid = refTemplates[type-1][d].v2hf[lvid][1];
3728 [ + - ]: 3865 : child_ents.push_back( level_mesh[cur_level].start_cell + ind + chid );
3729 [ + - ]: 3865 : child_lids.push_back( refTemplates[type - 1][d].v2hf[lvid][1] );
3730 : : }
3731 : :
3732 [ + - ][ - + ]: 3865 : error = ahf->set_incident_map( type, cur_vid, child_ents, child_lids );MB_CHK_ERR( error );
[ # # ][ # # ]
3733 : : }
3734 : :
3735 : : // error = ahf->determine_incident_halffaces( level_mesh[cur_level].cells);MB_CHK_ERR(error);
3736 : :
3737 : : // Step 2: Update SIBHFS maps
3738 [ + + ]: 4786 : for( int i = 0; i < nents_prev; i++ )
3739 : : {
3740 : : EntityHandle ent;
3741 [ + + ]: 4770 : if( cur_level )
3742 : 4752 : ent = level_mesh[cur_level - 1].start_cell + i;
3743 : : else
3744 [ + - ]: 18 : ent = _incells[i];
3745 : :
3746 [ + - ]: 4770 : std::vector< EntityHandle > sib_entids( nhf );
3747 [ + - ][ + - ]: 9540 : std::vector< int > sib_lids( nhf );
3748 : :
3749 [ + - ][ + - ]: 4770 : error = ahf->get_sibling_map( type, ent, &sib_entids[0], &sib_lids[0], nhf );MB_CHK_ERR( error );
[ + - ][ - + ]
[ # # ][ # # ]
3750 : :
3751 : : int id, idx;
3752 : :
3753 [ + + ]: 28620 : for( int l = 0; l < nhf; l++ )
3754 : : {
3755 : :
3756 [ + - ][ + + ]: 23850 : if( !sib_entids[l] ) continue;
3757 : :
3758 : : // Get the number of children incident on this half-face
3759 : : int pat_id;
3760 [ + + ]: 21640 : if( type == MBTET )
3761 [ + - ]: 8800 : pat_id = ( *pattern_ids )[i];
3762 : : else
3763 : 12840 : pat_id = type - 1;
3764 : 21640 : int nch = refTemplates[pat_id][d].ents_on_pent[l][0];
3765 : :
3766 : : // Get the order of children indices incident on this half-face
3767 [ + - ]: 21640 : std::vector< int > id_sib( nch );
3768 [ + + ]: 109520 : for( int k = 0; k < nch; k++ )
3769 [ + - ]: 87880 : id_sib[k] = 0;
3770 : :
3771 [ + - ][ + - ]: 21640 : error = reorder_indices( cur_level, deg, ent, l, sib_entids[l], sib_lids[l], 1, &id_sib[0] );MB_CHK_ERR( error );
[ + - ][ + - ]
[ - + ][ # # ]
[ # # ]
3772 : :
3773 : : // Get the parent index of the sibling cell
3774 : : int psib;
3775 [ + + ]: 21640 : if( cur_level )
3776 [ + - ]: 21608 : psib = sib_entids[l] - level_mesh[cur_level - 1].start_cell;
3777 : : else
3778 [ + - ][ + - ]: 32 : psib = sib_entids[l] - *_incells.begin();
[ + - ]
3779 : :
3780 [ + - ]: 21640 : int plid = sib_lids[l];
3781 : 21640 : int sidx = nchilds * psib;
3782 : : int sibpat_id;
3783 [ + + ]: 21640 : if( type == MBTET )
3784 [ + - ]: 8800 : sibpat_id = ( *pattern_ids )[psib];
3785 : : else
3786 : 12840 : sibpat_id = type - 1;
3787 : :
3788 : : // Loop over all the childs incident on the working half-face
3789 : 21640 : idx = nchilds * i;
3790 : :
3791 [ + + ][ + - ]: 109520 : for( int k = 0; k < nch; k++ )
3792 : : {
3793 : 87880 : id = refTemplates[pat_id][d].ents_on_pent[l][k + 1] - 1;
3794 : 87880 : EntityHandle child_ent = level_mesh[cur_level].start_cell + idx + id;
3795 : 87880 : int child_lid = l;
3796 : :
3797 : : // Find the sibling of the working child
3798 : : EntityHandle child_sibent;
3799 : : int child_siblid;
3800 [ + - ][ - + ]: 87880 : error = ahf->get_sibling_map( type, child_ent, child_lid, child_sibent, child_siblid );MB_CHK_ERR( error );
[ # # ][ # # ]
3801 : :
3802 [ + + ]: 87880 : if( child_sibent != 0 ) continue;
3803 : :
3804 : : // Get the correponding child of the sibling of the current parent
3805 : : // We have already computed the order the children on incident corresponding to the
3806 : : // working half-face
3807 [ + - ]: 43940 : id = refTemplates[sibpat_id][d].ents_on_pent[plid][id_sib[k]] - 1;
3808 : :
3809 : 43940 : EntityHandle psib_child = level_mesh[cur_level].start_cell + sidx + id;
3810 : 43940 : int psib_chlid = plid;
3811 : :
3812 : : // Set the siblings of children incident on current half-face
3813 [ + - ][ - + ]: 43940 : error = ahf->set_sibling_map( type, child_ent, child_lid, psib_child, psib_chlid );MB_CHK_ERR( error );
[ # # ][ # # ]
3814 : :
3815 : : // Set the sibling of the sibling of the children to the children
3816 [ + - ][ - + ]: 43940 : error = ahf->set_sibling_map( type, psib_child, psib_chlid, child_ent, child_lid );MB_CHK_ERR( error );
[ # # ][ # # ]
3817 : : }
3818 : 21640 : }
3819 : :
3820 : : // Loop over edges to check if there are any non-manifold edges. If there are then the v2hfs
3821 : : // map should be updated for the new vertices on it.
3822 : : const EntityHandle* conn;
3823 [ + - ][ - + ]: 4770 : error = mbImpl->get_connectivity( ent, conn, nvpc );MB_CHK_ERR( error );
[ # # ][ # # ]
3824 : :
3825 : 4770 : int nv = refTemplates[type - 1][d].nv_edge; //#verts on each edge
3826 [ + + ][ + - ]: 47700 : for( int l = 0; l < ne; l++ )
3827 : : {
3828 : 42930 : id = ahf->lConnMap3D[index].e2v[l][0];
3829 : 42930 : EntityHandle v_start = conn[id];
3830 : 42930 : id = ahf->lConnMap3D[index].e2v[l][1];
3831 : 42930 : EntityHandle v_end = conn[id];
3832 : :
3833 : 42930 : bool visited = false;
3834 : :
3835 [ + - ][ + - ]: 85860 : std::vector< EntityHandle > inci_ent1, inci_ent2;
[ + - - ]
3836 [ + - ][ + - ]: 85860 : std::vector< int > inci_lid1, inci_lid2;
[ + - - ]
[ + - - ]
3837 [ + - ][ - + ]: 42930 : error = ahf->get_incident_map( type, v_start, inci_ent1, inci_lid1 );MB_CHK_ERR( error );
[ # # ][ # # ]
3838 [ + - ][ - + ]: 42930 : error = ahf->get_incident_map( type, v_end, inci_ent2, inci_lid2 );MB_CHK_ERR( error );
[ # # ][ # # ]
3839 : :
3840 [ - + ][ # # ]: 42930 : if( inci_ent1.size() > 1 && inci_ent2.size() > 1 )
[ - + ]
3841 : : {
3842 [ # # ]: 0 : std::vector< EntityHandle > cell_comps;
3843 [ # # ]: 0 : std::vector< int > leid_comps;
[ # # # ]
3844 : :
3845 [ # # ][ # # ]: 0 : error = ahf->get_up_adjacencies_edg_3d_comp( ent, l, cell_comps, &leid_comps );MB_CHK_ERR( error );
[ # # ][ # # ]
3846 : :
3847 : 0 : int ncomps = cell_comps.size();
3848 [ # # ]: 0 : std::vector< EntityHandle > edgverts;
[ # # # ]
3849 [ # # ]: 0 : std::vector< EntityHandle > compchildents( nv * ncomps );
[ # # # ]
3850 [ # # ]: 0 : std::vector< int > compchildlfids( nv * ncomps );
[ # # # ]
3851 : :
3852 [ # # ]: 0 : for( int s = 0; s < nv * ncomps; s++ )
3853 : : {
3854 [ # # ]: 0 : compchildents[s] = 0;
3855 [ # # ]: 0 : compchildlfids[s] = 0;
3856 : : }
3857 : :
3858 [ # # ]: 0 : for( int j = 0; j < (int)cell_comps.size(); j++ )
3859 : : {
3860 : : int ind;
3861 [ # # ]: 0 : if( cur_level )
3862 [ # # ][ # # ]: 0 : ind = level_mesh[cur_level - 1].cells.index( cell_comps[j] );
3863 : : else
3864 [ # # ][ # # ]: 0 : ind = _incells.index( cell_comps[j] );
3865 : :
3866 [ # # ]: 0 : for( int k = 0; k < nv; k++ )
3867 : : {
3868 [ # # ]: 0 : int chid = refTemplates[type - 1][d].ents_on_vedge[leid_comps[j]][3 * k] - 1;
3869 [ # # ]: 0 : int lfid = refTemplates[type - 1][d].ents_on_vedge[leid_comps[j]][3 * k + 1];
3870 [ # # ]: 0 : int lvid = refTemplates[type - 1][d].ents_on_vedge[leid_comps[j]][3 * k + 2];
3871 : :
3872 : 0 : EntityHandle childcell = level_mesh[cur_level].start_cell + ind * nchilds + chid;
3873 : :
3874 : : const EntityHandle* econn;
3875 [ # # ][ # # ]: 0 : error = mbImpl->get_connectivity( childcell, econn, nvpc );MB_CHK_ERR( error );
[ # # ][ # # ]
3876 : :
3877 : 0 : EntityHandle vert = econn[lvid];
3878 : :
3879 [ # # ][ # # ]: 0 : if( ahf->check_nonmanifold_vertices( type, vert ) )
3880 : : {
3881 : 0 : visited = true;
3882 : 0 : break;
3883 : : }
3884 : :
3885 [ # # ]: 0 : if( edgverts.empty() )
3886 : : {
3887 [ # # ]: 0 : edgverts.push_back( vert );
3888 [ # # ]: 0 : compchildents[0] = childcell;
3889 [ # # ]: 0 : compchildlfids[0] = lfid;
3890 : : }
3891 : : else
3892 : : {
3893 : 0 : std::vector< EntityHandle >::iterator it;
3894 [ # # ]: 0 : it = find( edgverts.begin(), edgverts.end(), vert );
3895 [ # # ]: 0 : int indx = it - edgverts.begin();
3896 : :
3897 [ # # ][ # # ]: 0 : if( it == edgverts.end() )
3898 : : {
3899 [ # # ]: 0 : edgverts.push_back( vert );
3900 [ # # ]: 0 : compchildents[k * ncomps] = childcell;
3901 [ # # ]: 0 : compchildlfids[k * ncomps] = lfid;
3902 : : }
3903 : : else
3904 : : {
3905 [ # # ]: 0 : compchildents[indx * ncomps + j] = childcell;
3906 [ # # ]: 0 : compchildlfids[indx * ncomps + j] = lfid;
3907 : : }
3908 : : }
3909 : : }
3910 : : }
3911 : :
3912 [ # # ]: 0 : if( visited ) { break; }
3913 : :
3914 : : // Set the incident half-facet map
3915 [ # # ]: 0 : for( int k = 0; k < nv; k++ )
[ # # # ]
3916 : : {
3917 [ # # ]: 0 : std::vector< EntityHandle > set_childents;
3918 [ # # ][ # # ]: 0 : std::vector< int > set_childlfids;
3919 [ # # ]: 0 : for( int j = 0; j < ncomps; j++ )
3920 : : {
3921 [ # # ][ # # ]: 0 : set_childents.push_back( compchildents[k * ncomps + j] );
3922 [ # # ][ # # ]: 0 : set_childlfids.push_back( compchildlfids[k * ncomps + j] );
3923 : : }
3924 : :
3925 [ # # ][ # # ]: 0 : error = ahf->set_incident_map( type, edgverts[k], set_childents, set_childlfids );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ][ # # ]
3926 [ + - - ]: 42930 : }
3927 : : }
3928 : 42930 : }
3929 : 4770 : }
3930 : :
3931 : 32 : return MB_SUCCESS;
3932 : : }
3933 : :
3934 : 0 : ErrorCode NestedRefine::get_lid_inci_child( EntityType type, int deg, int lfid, int leid, std::vector< int >& child_ids,
3935 : : std::vector< int >& child_lvids )
3936 : : {
3937 [ # # ][ # # ]: 0 : int index = ahf->get_index_in_lmap( *_incells.begin() );
3938 : 0 : int d = get_index_from_degree( deg );
3939 : :
3940 : : // int lv0 = ahf->lConnMap3D[index].e2v[leid][0];
3941 : : // int lv1 = ahf->lConnMap3D[index].e2v[leid][1];
3942 : 0 : int nvpc = ahf->lConnMap3D[index].num_verts_in_cell;
3943 : :
3944 : 0 : int nv = refTemplates[type - 1][d].nv_edge;
3945 : 0 : int nch = refTemplates[type - 1][d].ents_on_pent[lfid][0];
3946 : :
3947 [ # # ]: 0 : for( int i = 0; i < nch; i++ )
3948 : : {
3949 : 0 : int id = refTemplates[type - 1][d].ents_on_pent[lfid][i + 1] - 1;
3950 [ # # ]: 0 : for( int j = 0; j < nvpc; j++ )
3951 : : {
3952 : 0 : int lv = refTemplates[type - 1][d].ents_conn[id][j];
3953 [ # # ]: 0 : for( int k = 0; k < nv; k++ )
3954 : : {
3955 [ # # ]: 0 : if( lv == refTemplates[type - 1][d].vert_on_edges[leid][k] )
3956 : : {
3957 [ # # ]: 0 : child_ids.push_back( id );
3958 [ # # ]: 0 : child_lvids.push_back( j );
3959 : : }
3960 : : }
3961 : : }
3962 : : }
3963 : :
3964 : 0 : return MB_SUCCESS;
3965 : : }
3966 : :
3967 : : /* **********************************
3968 : : * * Boundary Functions *
3969 : : ************************************/
3970 : :
3971 : 0 : bool NestedRefine::is_vertex_on_boundary( const EntityHandle& vertex )
3972 : : {
3973 : : ErrorCode error;
3974 : : EntityHandle sibents[27];
3975 : : int siblids[27];
3976 [ # # ]: 0 : std::vector< EntityHandle > ent;
3977 [ # # ]: 0 : std::vector< int > lid;
3978 : :
3979 : : int nhf;
3980 [ # # ]: 0 : if( elementype == MBEDGE )
3981 : 0 : nhf = 2;
3982 [ # # ][ # # ]: 0 : else if( ( elementype == MBTRI ) || ( elementype == MBQUAD ) )
3983 : 0 : nhf = ahf->lConnMap2D[elementype - 2].num_verts_in_face;
3984 [ # # ][ # # ]: 0 : else if( ( elementype == MBTET ) || ( elementype == MBHEX ) )
3985 : : {
3986 [ # # ][ # # ]: 0 : int idx = ahf->get_index_in_lmap( *_incells.begin() );
[ # # ]
3987 : 0 : nhf = ahf->lConnMap3D[idx].num_faces_in_cell;
3988 : : }
3989 : : else
3990 [ # # ][ # # ]: 0 : MB_SET_ERR( MB_FAILURE, "Requesting vertex boundary information for an unsupported entity type" );
[ # # ][ # # ]
[ # # ]
3991 : :
3992 [ # # ][ # # ]: 0 : error = ahf->get_incident_map( elementype, vertex, ent, lid );MB_CHK_ERR( error );
[ # # ][ # # ]
3993 [ # # ][ # # ]: 0 : error = ahf->get_sibling_map( elementype, ent[0], &sibents[0], &siblids[0], nhf );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ]
3994 : :
3995 [ # # ]: 0 : return ( sibents[lid[0]] == 0 );
3996 : : }
3997 : :
3998 : 0 : bool NestedRefine::is_edge_on_boundary( const EntityHandle& entity )
3999 : : {
4000 : : ErrorCode error;
4001 : 0 : bool is_border = false;
4002 [ # # ]: 0 : if( meshdim == 1 ) // The edge has a vertex on the boundary in the curve mesh
4003 : : {
4004 : : EntityHandle sibents[2];
4005 : : int siblids[2];
4006 [ # # ][ # # ]: 0 : error = ahf->get_sibling_map( MBEDGE, entity, &sibents[0], &siblids[0], 2 );MB_CHK_ERR( error );
[ # # ][ # # ]
4007 [ # # ]: 0 : for( int i = 0; i < 2; i++ )
4008 : : {
4009 [ # # ]: 0 : if( sibents[i] == 0 )
4010 : : {
4011 : 0 : is_border = true;
4012 : 0 : break;
4013 : : }
4014 : : }
4015 : : }
4016 [ # # ]: 0 : else if( meshdim == 2 ) // The edge is on the boundary of the 2d mesh
4017 : : {
4018 [ # # ]: 0 : std::vector< EntityHandle > adjents;
4019 [ # # ][ # # ]: 0 : error = ahf->get_up_adjacencies_2d( entity, adjents );MB_CHK_ERR( error );
[ # # ][ # # ]
4020 [ # # ][ # # ]: 0 : if( adjents.size() == 1 ) is_border = true;
4021 : : }
4022 [ # # ]: 0 : else if( meshdim == 3 ) // The edge is part of a face on the boundary of the 3d mesh
4023 : : {
4024 [ # # ]: 0 : std::vector< EntityHandle > adjents;
4025 [ # # ][ # # ]: 0 : std::vector< int > leids;
4026 [ # # ][ # # ]: 0 : error = ahf->get_up_adjacencies_edg_3d( entity, adjents, &leids );MB_CHK_ERR( error );
[ # # ][ # # ]
4027 [ # # ]: 0 : assert( !adjents.empty() );
4028 : :
4029 [ # # ][ # # ]: 0 : int index = ahf->get_index_in_lmap( adjents[0] );
4030 : 0 : int nhf = ahf->lConnMap3D[index].num_faces_in_cell;
4031 : :
4032 [ # # ][ # # ]: 0 : for( int i = 0; i < (int)adjents.size(); i++ )
4033 : : {
4034 : : EntityHandle sibents[6];
4035 : : int siblids[6];
4036 [ # # ][ # # ]: 0 : error = ahf->get_sibling_map( elementype, adjents[0], &sibents[0], &siblids[0], nhf );MB_CHK_ERR( error );
[ # # ][ # # ]
[ # # ]
4037 [ # # ]: 0 : for( int k = 0; k < 2; k++ )
4038 : : {
4039 [ # # ]: 0 : int hf = ahf->lConnMap3D[index].e2hf[leids[0]][k];
4040 [ # # ]: 0 : if( sibents[hf] == 0 )
4041 : : {
4042 : 0 : is_border = true;
4043 : 0 : break;
4044 : : }
4045 : : }
4046 : 0 : }
4047 : : }
4048 : 0 : return is_border;
4049 : : }
4050 : :
4051 : 0 : bool NestedRefine::is_face_on_boundary( const EntityHandle& entity )
4052 : : {
4053 : : ErrorCode error;
4054 : 0 : bool is_border = false;
4055 : :
4056 [ # # ]: 0 : if( meshdim == 1 )
4057 [ # # ][ # # ]: 0 : MB_SET_ERR( MB_FAILURE, "Requesting boundary information for a face entity type on a curve mesh" );
[ # # ][ # # ]
[ # # ]
4058 [ # # ]: 0 : else if( meshdim == 2 ) // The face has a local edge on the boundary of the 2d mesh
4059 : : {
4060 : : EntityHandle sibents[4];
4061 : : int siblids[4];
4062 : 0 : int nepf = ahf->lConnMap2D[elementype - 2].num_verts_in_face;
4063 [ # # ][ # # ]: 0 : error = ahf->get_sibling_map( elementype, entity, &sibents[0], &siblids[0], nepf );MB_CHK_ERR( error );
[ # # ][ # # ]
4064 : :
4065 [ # # ]: 0 : for( int i = 0; i < nepf; i++ )
4066 : : {
4067 [ # # ]: 0 : if( sibents[i] == 0 )
4068 : : {
4069 : 0 : is_border = true;
4070 : 0 : break;
4071 : : }
4072 : : }
4073 : : }
4074 [ # # ]: 0 : else if( meshdim == 3 ) // The face lies on the boundary of the 3d mesh
4075 : : {
4076 [ # # ]: 0 : std::vector< EntityHandle > adjents;
4077 [ # # ][ # # ]: 0 : error = ahf->get_up_adjacencies_face_3d( entity, adjents );MB_CHK_ERR( error );
[ # # ][ # # ]
4078 [ # # ][ # # ]: 0 : if( adjents.size() == 1 ) is_border = true;
4079 : : }
4080 : 0 : return is_border;
4081 : : }
4082 : :
4083 : 0 : bool NestedRefine::is_cell_on_boundary( const EntityHandle& entity )
4084 : : {
4085 [ # # ]: 0 : if( meshdim != 3 )
4086 [ # # ][ # # ]: 0 : MB_SET_ERR( MB_FAILURE, "Requesting boundary information for a cell entity type on a curve or surface mesh" );
[ # # ][ # # ]
[ # # ]
4087 : :
4088 : 0 : bool is_border = false;
4089 [ # # ][ # # ]: 0 : int index = ahf->get_index_in_lmap( *_incells.begin() );
[ # # ]
4090 : 0 : int nfpc = ahf->lConnMap3D[index].num_faces_in_cell;
4091 : : EntityHandle sibents[6];
4092 : : int siblids[6];
4093 : :
4094 [ # # ][ # # ]: 0 : ErrorCode error = ahf->get_sibling_map( elementype, entity, &sibents[0], &siblids[0], nfpc );MB_CHK_ERR( error );
[ # # ][ # # ]
4095 : :
4096 [ # # ]: 0 : for( int i = 0; i < nfpc; i++ )
4097 : : {
4098 [ # # ]: 0 : if( sibents[i] == 0 )
4099 : : {
4100 : 0 : is_border = true;
4101 : 0 : break;
4102 : : }
4103 : : }
4104 : 0 : return is_border;
4105 : : }
4106 : :
4107 : : /* **********************************
4108 : : * Helper Functions *
4109 : : ************************************/
4110 : 48 : ErrorCode NestedRefine::copy_vertices_from_prev_level( int cur_level )
4111 : : {
4112 : : ErrorCode error;
4113 : :
4114 [ + + ]: 48 : if( cur_level )
4115 : : {
4116 : 31 : int nverts_prev = level_mesh[cur_level - 1].num_verts;
4117 [ + + ]: 7749 : for( int i = 0; i < nverts_prev; i++ )
4118 : : {
4119 : 7718 : level_mesh[cur_level].coordinates[0][i] = level_mesh[cur_level - 1].coordinates[0][i];
4120 : 7718 : level_mesh[cur_level].coordinates[1][i] = level_mesh[cur_level - 1].coordinates[1][i];
4121 : 7718 : level_mesh[cur_level].coordinates[2][i] = level_mesh[cur_level - 1].coordinates[2][i];
4122 : : }
4123 : : }
4124 : : else // Copy the vertices from the input mesh
4125 : : {
4126 [ + - ]: 17 : int nverts_in = _inverts.size();
4127 [ + - ]: 17 : std::vector< double > vcoords( 3 * nverts_in );
4128 [ + - ][ + - ]: 17 : error = mbImpl->get_coords( _inverts, &vcoords[0] );MB_CHK_ERR( error );
[ - + ][ # # ]
[ # # ]
4129 : :
4130 [ + + ][ + - ]: 256 : for( int i = 0; i < nverts_in; i++ )
4131 : : {
4132 [ + - ][ + - ]: 239 : level_mesh[cur_level].coordinates[0][i] = vcoords[3 * i];
4133 [ + - ][ + - ]: 239 : level_mesh[cur_level].coordinates[1][i] = vcoords[3 * i + 1];
4134 [ + - ][ + - ]: 239 : level_mesh[cur_level].coordinates[2][i] = vcoords[3 * i + 2];
4135 : 17 : }
4136 : : }
4137 : 48 : return MB_SUCCESS;
4138 : : // To add: Map from old vertices to new duplicates: NOT NEEDED
4139 : : }
4140 : :
4141 : 4770 : ErrorCode NestedRefine::update_tracking_verts( EntityHandle cid, int cur_level, int deg,
4142 : : std::vector< EntityHandle >& trackvertsC_edg,
4143 : : std::vector< EntityHandle >& trackvertsC_face, EntityHandle* vbuffer )
4144 : : {
4145 : : // The vertices in the vbuffer are added to appropriate edges and faces of cells that are
4146 : : // incident on the working cell.
4147 : : ErrorCode error;
4148 : :
4149 : : EntityHandle cstart_prev;
4150 [ + + ]: 4770 : if( cur_level )
4151 : 4752 : cstart_prev = level_mesh[cur_level - 1].start_cell;
4152 : : else
4153 [ + - ]: 18 : cstart_prev = *_incells.begin();
4154 : :
4155 : 4770 : EntityType cell_type = mbImpl->type_from_handle( cstart_prev );
4156 : 4770 : int cindex = cell_type - 1;
4157 : 4770 : int d = get_index_from_degree( deg );
4158 : :
4159 : 4770 : int nve = refTemplates[cindex][d].nv_edge;
4160 : 4770 : int nvf = refTemplates[cindex][d].nv_face;
4161 : :
4162 [ + - ][ + - ]: 4770 : int index = ahf->get_index_in_lmap( *( _incells.begin() ) );
4163 : 4770 : int nepc = ahf->lConnMap3D[index].num_edges_in_cell;
4164 : 4770 : int nfpc = ahf->lConnMap3D[index].num_faces_in_cell;
4165 : :
4166 : : // Step 1: Add the vertices on an edge of the working cell to tracking array of incident cells.
4167 [ + + ]: 47700 : for( int i = 0; i < nepc; i++ )
4168 : : {
4169 : : // Add the vertices to edges of the current cell
4170 [ + + ]: 86580 : for( int j = 0; j < nve; j++ )
4171 : : {
4172 : 43650 : int id = refTemplates[cindex][d].vert_on_edges[i][j];
4173 : 43650 : int idx = cid - cstart_prev;
4174 : 43650 : int aid = idx * nve * nepc + nve * i + j;
4175 : :
4176 [ + - ][ + + ]: 43650 : if( !trackvertsC_edg[aid] ) trackvertsC_edg[aid] = vbuffer[id];
[ + - ]
4177 : : }
4178 : :
4179 : : // Obtain all the incident cells
4180 [ + - ]: 42930 : std::vector< EntityHandle > inc_cids;
4181 [ + - ][ + - ]: 85860 : std::vector< int > inc_leids, inc_orient;
[ + - + ]
[ + - + ]
4182 : :
4183 [ + - ][ - + ]: 42930 : error = ahf->get_up_adjacencies_edg_3d( cid, i, inc_cids, &inc_leids, &inc_orient );MB_CHK_ERR( error );
[ # # ][ # # ]
4184 : :
4185 [ + + ]: 42930 : if( inc_cids.size() == 1 ) continue;
4186 : :
4187 : : // Add the vertices to the edges of the incident cells
4188 [ + + ]: 213404 : for( int k = 0; k < (int)inc_cids.size(); k++ )
[ + - + ]
4189 : : {
4190 [ + - ][ + + ]: 170474 : if( inc_cids[k] == cid ) continue;
4191 : :
4192 [ + - ]: 128030 : int idx = inc_cids[k] - cstart_prev;
4193 : :
4194 [ + - ][ + + ]: 128030 : if( inc_orient[k] ) // Same edge direction as the current edge
4195 : : {
4196 [ + + ]: 144240 : for( int j = 0; j < nve; j++ )
4197 : : {
4198 : 72512 : int id = refTemplates[cindex][d].vert_on_edges[i][j];
4199 [ + - ]: 72512 : int aid = idx * nve * nepc + nve * inc_leids[k] + j;
4200 : :
4201 [ + - ][ + + ]: 72512 : if( !trackvertsC_edg[aid] ) trackvertsC_edg[aid] = vbuffer[id];
[ + - ]
4202 : : }
4203 : : }
4204 : : else
4205 : : {
4206 [ + + ]: 113192 : for( int j = 0; j < nve; j++ )
4207 : : {
4208 : 56890 : int id = refTemplates[cindex][d].vert_on_edges[i][nve - j - 1];
4209 [ + - ]: 56890 : int aid = idx * nve * nepc + nve * inc_leids[k] + j;
4210 : :
4211 [ + - ][ + + ]: 56890 : if( !trackvertsC_edg[aid] ) trackvertsC_edg[aid] = vbuffer[id];
[ + - ]
4212 : : }
4213 : : }
4214 : : }
4215 : 42930 : }
4216 : :
4217 : : // Step 2: Add the vertices on a face of the working cell to tracking array of incident cells.
4218 [ + + ]: 4770 : if( nvf )
4219 : : {
4220 : :
4221 [ + + ]: 16895 : for( int i = 0; i < nfpc; i++ )
4222 : : {
4223 : : // Add vertices to the tracking array of vertices on faces for the current cell
4224 [ + - ]: 14470 : std::vector< EntityHandle > face_vbuf( nvf, 0 );
4225 [ + + ]: 29660 : for( int j = 0; j < nvf; j++ )
4226 : : {
4227 : 15190 : int id = refTemplates[cindex][d].vert_on_faces[i][j];
4228 : 15190 : int idx = cid - cstart_prev;
4229 : 15190 : int aid = idx * nvf * nfpc + nvf * i + j;
4230 : :
4231 [ + - ][ + + ]: 15190 : if( !trackvertsC_face[aid] ) trackvertsC_face[aid] = vbuffer[id];
[ + - ]
4232 : :
4233 [ + - ]: 15190 : face_vbuf[j] = vbuffer[id];
4234 : : }
4235 : :
4236 : : // Obtain all the incident cells
4237 [ + - ]: 28940 : std::vector< EntityHandle > sib_cids;
[ + - + ]
4238 [ + - ]: 28940 : std::vector< int > sib_lfids;
[ + - + ]
4239 [ + - ][ - + ]: 14470 : error = ahf->get_up_adjacencies_face_3d( cid, i, sib_cids, &sib_lfids );MB_CHK_ERR( error );
[ # # ][ # # ]
4240 : :
4241 [ + + ]: 14470 : if( sib_cids.size() == 1 ) continue;
4242 : :
4243 : : // Reorder the vertex local ids incident on the half-face
4244 [ + - ]: 27422 : std::vector< int > id_sib( nvf );
[ + - + ]
4245 [ + + ]: 26360 : for( int k = 0; k < nvf; k++ )
4246 [ + - ]: 13408 : id_sib[k] = 0;
4247 : :
4248 [ + - ][ + - ]: 12952 : error = reorder_indices( cur_level, deg, sib_cids[1], sib_lfids[1], cid, i, 0, &id_sib[0] );MB_CHK_ERR( error );
[ + - ][ + - ]
[ - + ][ # # ]
[ # # ]
4249 : :
4250 : : // Add vertices to the tracking array of vertices on faces for the sibling cell of the
4251 : : // current cell
4252 [ + + ][ + - ]: 26360 : for( int j = 0; j < nvf; j++ )
4253 : : {
4254 [ + - ]: 13408 : int idx = sib_cids[1] - cstart_prev;
4255 [ + - ]: 13408 : int aid = idx * nvf * nfpc + nvf * sib_lfids[1] + j;
4256 : :
4257 [ + - ][ + + ]: 13408 : if( !trackvertsC_face[aid] ) trackvertsC_face[aid] = face_vbuf[id_sib[j] - 1];
[ + - ][ + - ]
[ + - ]
4258 : : }
4259 : 14470 : }
4260 : : }
4261 : 4770 : return MB_SUCCESS;
4262 : : }
4263 : :
4264 : 34592 : ErrorCode NestedRefine::reorder_indices( int cur_level, int deg, EntityHandle cell, int lfid, EntityHandle sib_cell,
4265 : : int sib_lfid, int index, int* id_sib )
4266 : : {
4267 : : // Reorders the indices of either vertices or children cell local ids to match with order of the
4268 : : // given cell and a local face. index = 0 : vertices,
4269 : : // = 1 : face
4270 : :
4271 [ + + ][ - + ]: 34592 : assert( deg == 2 || deg == 3 );
4272 : :
4273 : : ErrorCode error;
4274 [ + - ][ + - ]: 34592 : int idx = ahf->get_index_in_lmap( *_incells.begin() );
4275 : 34592 : int nvF = ahf->lConnMap3D[idx].hf2v_num[lfid];
4276 : 34592 : int nco = permutation[nvF - 3].num_comb;
4277 : :
4278 [ + + ][ + + ]: 34592 : if( !index && ( ( nvF == 3 && deg == 3 ) || ( nvF == 4 && deg == 2 ) ) ) { id_sib[0] = 1; }
[ - + ][ + - ]
[ + + ]
4279 : : else
4280 : : {
4281 : : // Get connectivity of the cell and its sibling cell
4282 [ + - ][ + - ]: 43584 : std::vector< EntityHandle > conn, sib_conn;
[ + - ]
4283 [ + - ][ - + ]: 21792 : error = get_connectivity( cell, cur_level, conn );MB_CHK_ERR( error );
[ # # ][ # # ]
4284 : :
4285 [ + - ][ - + ]: 21792 : error = get_connectivity( sib_cell, cur_level, sib_conn );MB_CHK_ERR( error );
[ # # ][ # # ]
4286 : :
4287 : : // Get the connectivity of the local face in the cell and its sibling
4288 [ + - ][ + - ]: 43584 : std::vector< EntityHandle > lface( nvF );
4289 [ + - ][ + - ]: 43584 : std::vector< EntityHandle > lface_sib( nvF );
4290 [ + + ]: 100160 : for( int i = 0; i < nvF; i++ )
4291 : : {
4292 : 78368 : int id = ahf->lConnMap3D[idx].hf2v[lfid][i];
4293 [ + - ][ + - ]: 78368 : lface[i] = conn[id];
4294 : :
4295 : 78368 : id = ahf->lConnMap3D[idx].hf2v[sib_lfid][i];
4296 [ + - ][ + - ]: 78368 : lface_sib[i] = sib_conn[id];
4297 : : }
4298 : :
4299 : : // Find the combination
4300 : 21792 : int c = 0;
4301 [ + - ]: 61196 : for( int i = 0; i < nco; i++ )
4302 : : {
4303 : 61196 : int count = 0;
4304 [ + + ]: 283116 : for( int j = 0; j < nvF; j++ )
4305 : : {
4306 : 221920 : int id = permutation[nvF - 3].comb[i][j];
4307 [ + - ][ + - ]: 221920 : if( lface[j] == lface_sib[id] ) count += 1;
[ + + ]
4308 : : }
4309 : :
4310 [ + + ]: 61196 : if( count == nvF )
4311 : : {
4312 : 21792 : c = i;
4313 : 21792 : break;
4314 : : }
4315 : : }
4316 : :
4317 [ - + ][ # # ]: 21792 : if( c > nco ) MB_SET_ERR( MB_FAILURE, "Getting a combination number more than currently supported" );
[ # # ][ # # ]
[ # # ][ # # ]
4318 : :
4319 : : // Get the ordered indices
4320 [ + + ][ + - ]: 21792 : if( ( ( !index ) && ( nvF == 4 ) && ( deg == 3 ) ) || ( deg == 2 ) )
[ - + ][ + + ]
4321 : : {
4322 [ + + ]: 107640 : for( int i = 0; i < 4; i++ )
4323 : 21528 : id_sib[i] = permutation[nvF - 3].porder2[c][i];
4324 : : }
4325 : : else
4326 : : {
4327 [ + + ][ + - ]: 24168 : for( int i = 0; i < 9; i++ )
4328 : 2376 : id_sib[i] = permutation[nvF - 3].porder3[c][i];
4329 : 21792 : }
4330 : : }
4331 : :
4332 : 34592 : return MB_SUCCESS;
4333 : : }
4334 : :
4335 : 0 : ErrorCode NestedRefine::reorder_indices( int deg, EntityHandle* face1_conn, EntityHandle* face2_conn, int nvF,
4336 : : std::vector< int >& lemap, std::vector< int >& vidx, int* leorient )
4337 : : {
4338 : : // Given the connectivities of two faces, get the permuted indices w.r.t first face.
4339 : : // Step 1: First find the orientation
4340 : 0 : int nco = permutation[nvF - 3].num_comb;
4341 : 0 : int c = 0;
4342 [ # # ]: 0 : for( int i = 0; i < nco; i++ )
4343 : : {
4344 : 0 : int count = 0;
4345 [ # # ]: 0 : for( int j = 0; j < nvF; j++ )
4346 : : {
4347 : 0 : int id = permutation[nvF - 3].comb[i][j];
4348 [ # # ]: 0 : if( face1_conn[j] == face2_conn[id] ) count += 1;
4349 : : }
4350 : :
4351 [ # # ]: 0 : if( count == nvF )
4352 : : {
4353 : 0 : c = i;
4354 : 0 : break;
4355 : : }
4356 : : }
4357 : :
4358 [ # # ][ # # ]: 0 : if( c > nco ) MB_SET_ERR( MB_FAILURE, "Getting a combination number more than currently supported" );
[ # # ][ # # ]
[ # # ][ # # ]
4359 : :
4360 : : // Add the corresponding local edges
4361 : 0 : lemap.reserve( nvF );
4362 [ # # ]: 0 : for( int i = 0; i < nvF; i++ )
4363 : : {
4364 : 0 : lemap.push_back( permutation[nvF - 3].lemap[c][i] );
4365 : : }
4366 [ # # ]: 0 : if( leorient ) leorient[0] = permutation[nvF - 3].orient[c];
4367 : :
4368 [ # # ][ # # ]: 0 : if( nvF == 3 && deg == 2 ) return MB_SUCCESS;
4369 : :
4370 [ # # ][ # # ]: 0 : if( ( nvF == 3 && deg == 3 ) || ( nvF == 4 && deg == 2 ) ) { vidx.push_back( 1 ); }
[ # # ][ # # ]
[ # # ]
4371 [ # # ][ # # ]: 0 : else if( nvF == 4 && deg == 3 )
4372 : : {
4373 [ # # ]: 0 : for( int i = 0; i < 4; i++ )
4374 : 0 : vidx.push_back( permutation[nvF - 3].porder2[c][i] );
4375 : : }
4376 : :
4377 : 0 : return MB_SUCCESS;
4378 : : }
4379 : :
4380 : 0 : ErrorCode NestedRefine::reorder_indices( int deg, int nvF, int comb, int* childfid_map )
4381 : : {
4382 : : // Given connectivities of two faces and a degree, get the permuted indices of the children
4383 : : // faces w.r.t first face.
4384 : :
4385 [ # # ][ # # ]: 0 : assert( deg == 2 || deg == 3 );
4386 : :
4387 : : // Get the ordered indices
4388 [ # # ]: 0 : if( deg == 2 )
4389 : : {
4390 [ # # ]: 0 : for( int i = 0; i < 4; i++ )
4391 : 0 : childfid_map[i] = permutation[nvF - 3].porder2[comb][i];
4392 : : }
4393 : : else
4394 : : {
4395 [ # # ]: 0 : for( int i = 0; i < 9; i++ )
4396 : 0 : childfid_map[i] = permutation[nvF - 3].porder3[comb][i];
4397 : : }
4398 : :
4399 : 0 : return MB_SUCCESS;
4400 : : }
4401 : :
4402 : 0 : ErrorCode NestedRefine::reorder_indices( EntityHandle* face1_conn, EntityHandle* face2_conn, int nvF, int* conn_map,
4403 : : int& comb, int* orient )
4404 : : {
4405 : : // Given connectivities of two faces and a degree, get the permuted indices of the children
4406 : : // faces w.r.t first face.
4407 : :
4408 : : // Step 1: First find the combination
4409 : 0 : int nco = permutation[nvF - 3].num_comb;
4410 : 0 : int c = 0;
4411 [ # # ]: 0 : for( int i = 0; i < nco; i++ )
4412 : : {
4413 : 0 : int count = 0;
4414 [ # # ]: 0 : for( int j = 0; j < nvF; j++ )
4415 : : {
4416 : 0 : int id = permutation[nvF - 3].comb[i][j];
4417 [ # # ]: 0 : if( face1_conn[j] == face2_conn[id] ) count += 1;
4418 : : }
4419 : :
4420 [ # # ]: 0 : if( count == nvF )
4421 : : {
4422 : 0 : c = i;
4423 : 0 : break;
4424 : : }
4425 : : }
4426 : :
4427 [ # # ][ # # ]: 0 : if( c > nco ) MB_SET_ERR( MB_FAILURE, "Getting a combination number more than currently supported" );
[ # # ][ # # ]
[ # # ][ # # ]
4428 : :
4429 : 0 : comb = c;
4430 : :
4431 [ # # ]: 0 : if( orient ) orient[0] = permutation[nvF - 3].orient[c];
4432 : :
4433 [ # # ]: 0 : for( int j = 0; j < nvF; j++ )
4434 : : {
4435 : 0 : conn_map[j] = permutation[nvF - 3].comb[c][j];
4436 : : }
4437 : :
4438 : 0 : return MB_SUCCESS;
4439 : : }
4440 : :
4441 : 48 : ErrorCode NestedRefine::count_subentities( EntityHandle set, int cur_level, int* nedges, int* nfaces )
4442 : : {
4443 : : ErrorCode error;
4444 : :
4445 [ + + ]: 48 : if( cur_level >= 0 )
4446 : : {
4447 [ + - ][ + - ]: 62 : Range edges, faces, cells;
[ + - ][ + - ]
[ + - ]
4448 : :
4449 [ + - ][ - + ]: 31 : error = mbImpl->get_entities_by_dimension( set, 1, edges );MB_CHK_ERR( error );
[ # # ][ # # ]
4450 : :
4451 [ + - ][ - + ]: 31 : error = mbImpl->get_entities_by_dimension( set, 2, faces );MB_CHK_ERR( error );
[ # # ][ # # ]
4452 : :
4453 [ + - ][ - + ]: 31 : error = mbImpl->get_entities_by_dimension( set, 3, cells );MB_CHK_ERR( error );
[ # # ][ # # ]
4454 : :
4455 [ + - ][ - + ]: 62 : error = ahf->count_subentities( edges, faces, cells, nedges, nfaces );MB_CHK_ERR( error );
[ # # ][ # # ]
[ + - ]
4456 : : }
4457 : : else
4458 : : {
4459 [ - + ][ # # ]: 17 : error = ahf->count_subentities( _inedges, _infaces, _incells, nedges, nfaces );MB_CHK_ERR( error );
4460 : : }
4461 : :
4462 : 48 : return MB_SUCCESS;
4463 : : }
4464 : :
4465 : 2385 : ErrorCode NestedRefine::get_octahedron_corner_coords( int cur_level, int deg, EntityHandle* vbuffer, double* ocoords )
4466 : : {
4467 : 2385 : int lid[6] = { 0, 0, 0, 0, 0, 0 };
4468 : :
4469 [ + + ]: 2385 : if( deg == 2 )
4470 : : {
4471 : 2345 : lid[0] = 5;
4472 : 2345 : lid[1] = 8;
4473 : 2345 : lid[2] = 9;
4474 : 2345 : lid[3] = 6;
4475 : 2345 : lid[4] = 4;
4476 : 2345 : lid[5] = 7;
4477 : : }
4478 [ + - ]: 40 : else if( deg == 3 )
4479 : : {
4480 : 40 : lid[0] = 19;
4481 : 40 : lid[1] = 16;
4482 : 40 : lid[2] = 18;
4483 : 40 : lid[3] = 9;
4484 : 40 : lid[4] = 4;
4485 : 40 : lid[5] = 10;
4486 : : }
4487 : :
4488 : 2385 : EntityHandle vstart = level_mesh[cur_level].start_vertex;
4489 : :
4490 [ + + ]: 16695 : for( int i = 0; i < 6; i++ )
4491 : : {
4492 : 14310 : EntityHandle vid = vbuffer[lid[i]];
4493 [ + - ]: 14310 : ocoords[3 * i] = level_mesh[cur_level].coordinates[0][vid - vstart];
4494 [ + - ]: 14310 : ocoords[3 * i + 1] = level_mesh[cur_level].coordinates[1][vid - vstart];
4495 [ + - ]: 14310 : ocoords[3 * i + 2] = level_mesh[cur_level].coordinates[2][vid - vstart];
4496 : : }
4497 : :
4498 : 2385 : return MB_SUCCESS;
4499 : : }
4500 : :
4501 : 2385 : int NestedRefine::find_shortest_diagonal_octahedron( int cur_level, int deg, EntityHandle* vbuffer )
4502 : : {
4503 : : ErrorCode error;
4504 : : double coords[18];
4505 [ + - ]: 2385 : error = get_octahedron_corner_coords( cur_level, deg, vbuffer, coords );
4506 [ - + ][ # # ]: 2385 : if( error != MB_SUCCESS ) MB_SET_ERR( MB_FAILURE, "Error in obtaining octahedron corner coordinates" );
[ # # ][ # # ]
[ # # ][ # # ]
4507 : :
4508 : 2385 : int diag_map[6] = { 1, 3, 2, 4, 5, 0 };
4509 : 2385 : double length = std::numeric_limits< double >::max();
4510 : :
4511 : 2385 : int diag = 0;
4512 : : double x, y, z;
4513 : 2385 : x = y = z = 0;
4514 : :
4515 [ + + ]: 9540 : for( int d = 0; d < 3; d++ )
4516 : : {
4517 : 7155 : int id1 = diag_map[2 * d];
4518 : 7155 : int id2 = diag_map[2 * d + 1];
4519 : 7155 : x = coords[3 * id1] - coords[3 * id2];
4520 : 7155 : y = coords[3 * id1 + 1] - coords[3 * id2 + 1];
4521 : 7155 : z = coords[3 * id1 + 2] - coords[3 * id2 + 2];
4522 : 7155 : double dlen = sqrt( x * x + y * y + z * z );
4523 [ + + ]: 7155 : if( dlen < length )
4524 : : {
4525 : 3560 : length = dlen;
4526 : 3560 : diag = d + 1;
4527 : : }
4528 : : }
4529 : :
4530 : 2385 : return diag;
4531 : : }
4532 : :
4533 : 7957 : int NestedRefine::get_local_vid( EntityHandle vid, EntityHandle ent, int level )
4534 : : {
4535 : : ErrorCode error;
4536 : : // Given a vertex, find its local id in the given entity
4537 [ + - ]: 7957 : std::vector< EntityHandle > conn;
4538 : :
4539 [ + - ]: 7957 : error = get_connectivity( ent, level + 1, conn );
4540 [ - + ][ # # ]: 7957 : if( error != MB_SUCCESS ) MB_SET_ERR( MB_FAILURE, "Error in getting connectivity of the requested entity" );
[ # # ][ # # ]
[ # # ][ # # ]
4541 : :
4542 : 7957 : int lid = -1;
4543 [ + - ]: 20690 : for( int i = 0; i < (int)conn.size(); i++ )
4544 : : {
4545 [ + - ][ + + ]: 20690 : if( conn[i] == vid )
4546 : : {
4547 : 7957 : lid = i;
4548 : 7957 : break;
4549 : : }
4550 : : }
4551 [ - + ][ # # ]: 7957 : if( lid < 0 ) MB_SET_ERR( MB_FAILURE, "Error in getting local vertex id in the given entity" );
[ # # ][ # # ]
[ # # ][ # # ]
4552 : 7957 : return lid;
4553 : : }
4554 : :
4555 : 282123 : int NestedRefine::get_index_from_degree( int degree )
4556 : : {
4557 [ + - ]: 282123 : int d = deg_index.find( degree )->second;
4558 : 282123 : return d;
4559 : : }
4560 : :
4561 : : /*
4562 : : ErrorCode NestedRefine::print_maps_1D(int level)
4563 : : {
4564 : : ErrorCode error;
4565 : : int nv, ne;
4566 : : nv = level_mesh[level].num_verts;
4567 : : ne = level_mesh[level].num_edges;
4568 : :
4569 : : EntityHandle start_edge = level_mesh[level].start_edge;
4570 : :
4571 : : //V2HV
4572 : : std::cout<<"<V2HV_EID, V2HV_LVID>"<<std::endl;
4573 : : for (int i=0; i<nv; i++)
4574 : : {
4575 : : EntityHandle eid=0;
4576 : : int lvid=0;
4577 : : EntityHandle vid = level_mesh[level].start_vertex+i;
4578 : : error = ahf->get_incident_map(MBEDGE, vid, eid, lvid); MB_CHK_ERR(error);
4579 : :
4580 : : std::cout<<"For vertex = "<<vid<<"::Incident halfvertex "<<eid<<" "<<lvid<<std::endl;
4581 : : }
4582 : :
4583 : : //SIBHVS
4584 : : std::cout<<"start_edge = "<<start_edge<<std::endl;
4585 : : std::cout<<"<SIBHVS_EID,SIBHVS_LVID>"<<std::endl;
4586 : : for (int i=0; i<ne; i++)
4587 : : {
4588 : : EntityHandle ent = start_edge+i;
4589 : :
4590 : : EntityHandle eid[2]; int lvid[2];
4591 : : error = ahf->get_sibling_map(MBEDGE, ent, &eid[0], &lvid[0], 2); MB_CHK_ERR(error);
4592 : : std::cout<<"<"<<eid[0]<<","<<lvid[0]<<">"<<" "<<"<"<<eid[1]<<","<<lvid[1]<<">"<<std::endl;
4593 : : }
4594 : :
4595 : : return MB_SUCCESS;
4596 : : }
4597 : :
4598 : : ErrorCode NestedRefine::print_maps_2D(int level, EntityType type)
4599 : : {
4600 : : ErrorCode error;
4601 : : int nv, nf;
4602 : : nv = level_mesh[level].num_verts;
4603 : : nf = level_mesh[level].num_faces;
4604 : :
4605 : : EntityHandle start_face = level_mesh[level].start_face;
4606 : :
4607 : : //V2HV
4608 : : std::cout<<"<V2HE_FID, V2HE_LEID>"<<std::endl;
4609 : : for (int i=0; i<nv; i++)
4610 : : {
4611 : : EntityHandle fid=0;
4612 : : int leid=0;
4613 : : EntityHandle vid = level_mesh[level].start_vertex+i;
4614 : : error = ahf->get_incident_map(type, vid, fid, leid); MB_CHK_ERR(error);
4615 : :
4616 : : std::cout<<"For vertex = "<<vid<<"::Incident halfedge "<<fid<<" "<<leid<<std::endl;
4617 : : }
4618 : :
4619 : : //SIBHES
4620 : : std::cout<<"start_face = "<<start_face<<std::endl;
4621 : : std::cout<<"<SIBHES_FID,SIBHES_LEID>"<<std::endl;
4622 : : EntityType ftype = mbImpl->type_from_handle(*_infaces.begin());
4623 : : int nepf = ahf->lConnMap2D[ftype-2].num_verts_in_face;
4624 : :
4625 : : EntityHandle *fid = new EntityHandle[nepf];
4626 : : int *leid = new int[nepf];
4627 : :
4628 : : for (int i=0; i<nf; i++)
4629 : : {
4630 : : for (int j=0; j<nepf; j++)
4631 : : {
4632 : : fid[j] = 0;
4633 : : leid[j] = 0;
4634 : : }
4635 : :
4636 : : EntityHandle ent = start_face+i;
4637 : : error = ahf->get_sibling_map(type, ent, fid, leid, nepf); MB_CHK_ERR(error);
4638 : :
4639 : : for (int j=0; j<nepf; j++){
4640 : : std::cout<<"<"<<fid[j]<<","<<leid[j]<<">"<<" ";
4641 : : }
4642 : : std::cout<<std::endl;
4643 : : }
4644 : :
4645 : : delete [] fid;
4646 : : delete [] leid;
4647 : :
4648 : : return MB_SUCCESS;
4649 : : }
4650 : :
4651 : : ErrorCode NestedRefine::print_maps_3D(int level, EntityType type)
4652 : : {
4653 : : ErrorCode error;
4654 : : int nv, nc;
4655 : : nv = level_mesh[level].num_verts;
4656 : : nc = level_mesh[level].num_cells;
4657 : : EntityHandle start_cell = level_mesh[level].start_cell;
4658 : :
4659 : : //V2HF
4660 : : std::cout<<"<V2HF_CID, V2HF_LFID>"<<std::endl;
4661 : : for (int i=0; i<nv; i++)
4662 : : {
4663 : : EntityHandle cid=0;
4664 : : int lfid=0;
4665 : : EntityHandle vid = level_mesh[level].start_vertex+i;
4666 : : error = ahf->get_incident_map(type, vid, cid, lfid); MB_CHK_ERR(error);
4667 : :
4668 : : std::cout<<"For vertex = "<<vid<<"::Incident halfface "<<cid<<" "<<lfid<<std::endl;
4669 : : }
4670 : :
4671 : : //SIBHFS
4672 : : std::cout<<"start_cell = "<<start_cell<<std::endl;
4673 : : std::cout<<"<SIBHFS_CID,SIBHFS_LFID>"<<std::endl;
4674 : : int index = ahf->get_index_in_lmap(start_cell);
4675 : : int nfpc = ahf->lConnMap3D[index].num_faces_in_cell;
4676 : :
4677 : : EntityHandle *cid = new EntityHandle[nfpc];
4678 : : int *lfid = new int[nfpc];
4679 : : for (int i=0; i<nc; i++)
4680 : : {
4681 : : for (int k=0; k<nfpc; k++)
4682 : : {
4683 : : cid[k] = 0;
4684 : : lfid[k] = 0;
4685 : : }
4686 : :
4687 : : EntityHandle ent = start_cell+i;
4688 : : error = ahf->get_sibling_map(type, ent, cid, lfid, nfpc); MB_CHK_ERR(error);
4689 : :
4690 : : for (int j=0; j<nfpc; j++){
4691 : : std::cout<<"<"<<cid[j]<<","<<lfid[j]<<">"<<" ";
4692 : : }
4693 : : std::cout<<std::endl;
4694 : : }
4695 : :
4696 : : delete [] cid;
4697 : : delete [] lfid;
4698 : :
4699 : : return MB_SUCCESS;
4700 : : }
4701 : :
4702 : : */
4703 [ + - ][ + - ]: 8 : } // namespace moab
|