Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
00001 #include "moab/NestedRefine.hpp" 00002 #include "moab/NestedRefineTemplates.hpp" 00003 #include "moab/HalfFacetRep.hpp" 00004 #include "moab/CpuTimer.hpp" 00005 #include "moab/ReadUtilIface.hpp" 00006 #include "Internals.hpp" 00007 #include "MBTagConventions.hpp" 00008 00009 #ifdef MOAB_HAVE_MPI 00010 #include "moab/ParallelComm.hpp" 00011 #include "moab/ParallelMergeMesh.hpp" 00012 #include "moab/Skinner.hpp" 00013 #endif 00014 00015 #include <iostream> 00016 #include <cassert> 00017 #include <vector> 00018 #include <limits> 00019 #include <cmath> 00020 00021 namespace moab 00022 { 00023 00024 NestedRefine::NestedRefine( Core* impl, ParallelComm* comm, EntityHandle rset ) 00025 : mbImpl( impl ), pcomm( comm ), _rset( rset ) 00026 { 00027 ErrorCode error; 00028 assert( NULL != impl ); 00029 00030 #ifdef MOAB_HAVE_MPI 00031 // Get the Parallel Comm instance to prepare all new sets to work in parallel 00032 // in case the user did not provide any arguments 00033 if( !comm ) pcomm = moab::ParallelComm::get_pcomm( mbImpl, 0 ); 00034 #endif 00035 error = initialize(); 00036 if( error != MB_SUCCESS ) 00037 { 00038 std::cout << "Error initializing NestedRefine\n" << std::endl; 00039 exit( 1 ); 00040 } 00041 } 00042 00043 NestedRefine::~NestedRefine() 00044 { 00045 #ifdef MOAB_HAVE_AHF 00046 ahf = NULL; 00047 #else 00048 delete ahf; 00049 #endif 00050 delete tm; 00051 } 00052 00053 ErrorCode NestedRefine::initialize() 00054 { 00055 ErrorCode error; 00056 00057 tm = new CpuTimer(); 00058 if( !tm ) return MB_MEMORY_ALLOCATION_FAILED; 00059 00060 #ifdef MOAB_HAVE_AHF 00061 ahf = mbImpl->a_half_facet_rep(); 00062 #else 00063 ahf = new HalfFacetRep( mbImpl, pcomm, _rset, true ); 00064 if( !ahf ) return MB_MEMORY_ALLOCATION_FAILED; 00065 #endif 00066 00067 // Check for mixed entity type 00068 bool chk_mixed = ahf->check_mixed_entity_type(); 00069 if( chk_mixed ) MB_SET_ERR( MB_NOT_IMPLEMENTED, "Encountered a mesh with mixed entity types" ); 00070 00071 error = ahf->initialize();MB_CHK_ERR( error ); 00072 error = ahf->get_entity_ranges( _inverts, _inedges, _infaces, _incells );MB_CHK_ERR( error ); 00073 00074 // Check for supported entity type 00075 if( !_incells.empty() ) 00076 { 00077 EntityType type = mbImpl->type_from_handle( _incells[0] ); 00078 if( type != MBTET && type != MBHEX ) 00079 MB_SET_ERR( MB_FAILURE, "Not supported 3D entity types: MBPRISM, MBPYRAMID, MBKNIFE, MBPOLYHEDRON" ); 00080 00081 meshdim = 3; 00082 elementype = type; 00083 } 00084 else if( !_infaces.empty() ) 00085 { 00086 EntityType type = mbImpl->type_from_handle( _infaces[0] ); 00087 if( type == MBPOLYGON ) MB_SET_ERR( MB_FAILURE, "Not supported 2D entity type: POLYGON" ); 00088 00089 meshdim = 2; 00090 elementype = type; 00091 } 00092 else if( !_inedges.empty() ) 00093 { 00094 meshdim = 1; 00095 elementype = MBEDGE; 00096 } 00097 else 00098 MB_SET_ERR( MB_NOT_IMPLEMENTED, "Encountered a mixed-dimensional or invalid mesh" ); 00099 00100 // Initialize std::map to get indices of degrees. 00101 deg_index[2] = 0; 00102 deg_index[3] = 1; 00103 deg_index[5] = 2; 00104 00105 // Set ghost flag to false 00106 hasghost = false; 00107 return MB_SUCCESS; 00108 } 00109 00110 /************************************************************ 00111 * Interface Functions * 00112 ************************************************************/ 00113 00114 ErrorCode NestedRefine::generate_mesh_hierarchy( int num_level, 00115 int* level_degrees, 00116 std::vector< EntityHandle >& level_sets, 00117 bool optimize ) 00118 { 00119 assert( num_level > 0 ); 00120 nlevels = num_level; 00121 00122 ErrorCode error; 00123 std::vector< moab::EntityHandle > hmsets( num_level ); 00124 00125 if( meshdim <= 2 ) 00126 { 00127 for( int i = 0; i < num_level; i++ ) 00128 { 00129 assert( ( level_degrees[i] == 2 ) || ( level_degrees[i] == 3 ) || ( level_degrees[i] == 5 ) ); 00130 level_dsequence[i] = level_degrees[i]; 00131 } 00132 } 00133 else 00134 { 00135 for( int i = 0; i < num_level; i++ ) 00136 { 00137 assert( ( level_degrees[i] == 2 ) || ( level_degrees[i] == 3 ) ); 00138 level_dsequence[i] = level_degrees[i]; 00139 } 00140 } 00141 00142 error = generate_hm( level_degrees, num_level, &hmsets[0], optimize );MB_CHK_ERR( error ); 00143 00144 // copy the entity handles 00145 level_sets.resize( num_level + 1 ); 00146 level_sets[0] = _rset; 00147 for( int i = 0; i < num_level; i++ ) 00148 level_sets[i + 1] = hmsets[i]; 00149 00150 return MB_SUCCESS; 00151 } 00152 00153 ErrorCode NestedRefine::get_connectivity( EntityHandle ent, int level, std::vector< EntityHandle >& conn ) 00154 { 00155 ErrorCode error; 00156 EntityType type = mbImpl->type_from_handle( ent ); 00157 EntityHandle start_ent; 00158 if( !conn.empty() ) conn.clear(); 00159 if( level > 0 ) 00160 { 00161 if( type == MBEDGE ) 00162 { 00163 conn.reserve( 2 ); 00164 start_ent = level_mesh[level - 1].start_edge; 00165 EntityID offset = ID_FROM_HANDLE( ent ) - ID_FROM_HANDLE( start_ent ); 00166 conn.push_back( level_mesh[level - 1].edge_conn[2 * offset] ); 00167 conn.push_back( level_mesh[level - 1].edge_conn[2 * offset + 1] ); 00168 } 00169 else if( type == MBTRI || type == MBQUAD ) 00170 { 00171 int num_corners = ahf->lConnMap2D[type - 2].num_verts_in_face; 00172 conn.reserve( num_corners ); 00173 start_ent = level_mesh[level - 1].start_face; 00174 EntityID offset = ID_FROM_HANDLE( ent ) - ID_FROM_HANDLE( start_ent ); 00175 00176 for( int i = 0; i < num_corners; i++ ) 00177 conn.push_back( level_mesh[level - 1].face_conn[num_corners * offset + i] ); 00178 } 00179 else if( type == MBTET || type == MBHEX ) 00180 { 00181 int index = ahf->get_index_in_lmap( *_incells.begin() ); 00182 int num_corners = ahf->lConnMap3D[index].num_verts_in_cell; 00183 conn.reserve( num_corners ); 00184 start_ent = level_mesh[level - 1].start_cell; 00185 EntityID offset = ID_FROM_HANDLE( ent ) - ID_FROM_HANDLE( start_ent ); 00186 for( int i = 0; i < num_corners; i++ ) 00187 conn.push_back( level_mesh[level - 1].cell_conn[num_corners * offset + i] ); 00188 } 00189 else 00190 MB_SET_ERR( MB_FAILURE, "Requesting connectivity for an unsupported entity type" ); 00191 } 00192 else 00193 { 00194 error = mbImpl->get_connectivity( &ent, 1, conn );MB_CHK_ERR( error ); 00195 } 00196 00197 return MB_SUCCESS; 00198 } 00199 00200 ErrorCode NestedRefine::get_coordinates( EntityHandle* verts, int num_verts, int level, double* coords ) 00201 { 00202 if( level > 0 ) 00203 { 00204 EntityID vstart = ID_FROM_HANDLE( level_mesh[level - 1].start_vertex ); 00205 for( int i = 0; i < num_verts; i++ ) 00206 { 00207 const EntityHandle& vid = verts[i]; 00208 EntityID offset = ID_FROM_HANDLE( vid ) - vstart; 00209 coords[3 * i] = level_mesh[level - 1].coordinates[0][offset]; 00210 coords[3 * i + 1] = level_mesh[level - 1].coordinates[1][offset]; 00211 coords[3 * i + 2] = level_mesh[level - 1].coordinates[2][offset]; 00212 } 00213 } 00214 else 00215 { 00216 ErrorCode error; 00217 error = mbImpl->get_coords( verts, num_verts, coords );MB_CHK_ERR( error ); 00218 } 00219 00220 return MB_SUCCESS; 00221 } 00222 00223 ErrorCode NestedRefine::get_adjacencies( const EntityHandle source_entity, 00224 const unsigned int target_dimension, 00225 std::vector< EntityHandle >& target_entities ) 00226 00227 { 00228 ErrorCode error; 00229 error = ahf->get_adjacencies( source_entity, target_dimension, target_entities );MB_CHK_ERR( error ); 00230 00231 return MB_SUCCESS; 00232 } 00233 00234 ErrorCode NestedRefine::child_to_parent( EntityHandle child, int child_level, int parent_level, EntityHandle* parent ) 00235 { 00236 assert( ( child_level > 0 ) && ( child_level > parent_level ) ); 00237 EntityType type = mbImpl->type_from_handle( child ); 00238 assert( type != MBVERTEX ); 00239 00240 int child_index; 00241 if( type == MBEDGE ) 00242 child_index = child - level_mesh[child_level - 1].start_edge; 00243 else if( type == MBTRI || type == MBQUAD ) 00244 child_index = child - level_mesh[child_level - 1].start_face; 00245 else if( type == MBTET || type == MBHEX ) 00246 child_index = child - level_mesh[child_level - 1].start_cell; 00247 else 00248 MB_SET_ERR( MB_FAILURE, "Requesting parent for unsupported entity type" ); 00249 00250 int parent_index; 00251 int l = child_level - parent_level; 00252 for( int i = 0; i < l; i++ ) 00253 { 00254 int d = get_index_from_degree( level_dsequence[child_level - i - 1] ); 00255 int nch = refTemplates[type - 1][d].total_new_ents; 00256 child_index = child_index / nch; 00257 } 00258 parent_index = child_index; 00259 00260 if( type == MBEDGE ) 00261 { 00262 if( parent_level > 0 ) 00263 *parent = level_mesh[parent_level - 1].start_edge + parent_index; 00264 else 00265 *parent = _inedges[parent_index]; 00266 } 00267 else if( type == MBTRI || type == MBQUAD ) 00268 { 00269 if( parent_level > 0 ) 00270 *parent = level_mesh[parent_level - 1].start_face + parent_index; 00271 else 00272 *parent = _infaces[parent_index]; 00273 } 00274 else if( type == MBTET || type == MBHEX ) 00275 { 00276 if( parent_level > 0 ) 00277 *parent = level_mesh[parent_level - 1].start_cell + parent_index; 00278 else 00279 *parent = _incells[parent_index]; 00280 } 00281 00282 return MB_SUCCESS; 00283 } 00284 00285 ErrorCode NestedRefine::parent_to_child( EntityHandle parent, 00286 int parent_level, 00287 int child_level, 00288 std::vector< EntityHandle >& children ) 00289 { 00290 assert( ( child_level > 0 ) && ( child_level > parent_level ) ); 00291 EntityType type = mbImpl->type_from_handle( parent ); 00292 assert( type != MBVERTEX ); 00293 00294 int parent_index; 00295 if( type == MBEDGE ) 00296 { 00297 if( parent_level > 0 ) 00298 parent_index = parent - level_mesh[parent_level - 1].start_edge; 00299 else 00300 parent_index = _inedges.index( parent ); 00301 } 00302 else if( type == MBTRI || type == MBQUAD ) 00303 { 00304 if( parent_level > 0 ) 00305 parent_index = parent - level_mesh[parent_level - 1].start_face; 00306 else 00307 parent_index = _infaces.index( parent ); 00308 } 00309 else if( type == MBTET || type == MBHEX ) 00310 { 00311 if( parent_level > 0 ) 00312 parent_index = parent - level_mesh[parent_level - 1].start_cell; 00313 else 00314 parent_index = _incells.index( parent ); 00315 } 00316 else 00317 MB_SET_ERR( MB_FAILURE, "Requesting children for unsupported entity type" ); 00318 00319 int start, end; 00320 start = end = parent_index; 00321 for( int i = parent_level; i < child_level; i++ ) 00322 { 00323 int d = get_index_from_degree( level_dsequence[i] ); 00324 int nch = refTemplates[type - 1][d].total_new_ents; 00325 start = start * nch; 00326 end = end * nch + nch - 1; 00327 } 00328 00329 int num_child = end - start; 00330 children.reserve( num_child ); 00331 00332 for( int i = start; i <= end; i++ ) 00333 { 00334 EntityHandle child; 00335 if( type == MBEDGE ) 00336 child = level_mesh[child_level - 1].start_edge + i; 00337 else if( type == MBTRI || type == MBQUAD ) 00338 child = level_mesh[child_level - 1].start_face + i; 00339 else if( type == MBTET || type == MBHEX ) 00340 child = level_mesh[child_level - 1].start_cell + i; 00341 00342 children.push_back( child ); 00343 } 00344 00345 return MB_SUCCESS; 00346 } 00347 00348 ErrorCode NestedRefine::vertex_to_entities_up( EntityHandle vertex, 00349 int vert_level, 00350 int parent_level, 00351 std::vector< EntityHandle >& incident_entities ) 00352 { 00353 assert( vert_level > parent_level ); 00354 ErrorCode error; 00355 00356 // Step 1: Get the incident entities at the current level 00357 std::vector< EntityHandle > inents; 00358 if( meshdim == 1 ) 00359 { 00360 error = ahf->get_up_adjacencies_1d( vertex, inents );MB_CHK_ERR( error ); 00361 } 00362 else if( meshdim == 2 ) 00363 { 00364 error = ahf->get_up_adjacencies_vert_2d( vertex, inents );MB_CHK_ERR( error ); 00365 } 00366 else if( meshdim == 3 ) 00367 { 00368 error = ahf->get_up_adjacencies_vert_3d( vertex, inents );MB_CHK_ERR( error ); 00369 } 00370 00371 // Step 2: Loop over all the incident entities at the current level and gather their parents 00372 for( int i = 0; i < (int)inents.size(); i++ ) 00373 { 00374 EntityHandle ent = inents[i]; 00375 EntityHandle parent; 00376 error = child_to_parent( ent, vert_level, parent_level, &parent );MB_CHK_ERR( error ); 00377 incident_entities.push_back( parent ); 00378 } 00379 00380 // Step 3: Sort and remove duplicates 00381 std::sort( incident_entities.begin(), incident_entities.end() ); 00382 incident_entities.erase( std::unique( incident_entities.begin(), incident_entities.end() ), 00383 incident_entities.end() ); 00384 00385 return MB_SUCCESS; 00386 } 00387 00388 ErrorCode NestedRefine::vertex_to_entities_down( EntityHandle vertex, 00389 int vert_level, 00390 int child_level, 00391 std::vector< EntityHandle >& incident_entities ) 00392 { 00393 assert( vert_level < child_level ); 00394 ErrorCode error; 00395 00396 // Step 1: Get the incident entities at the current level 00397 std::vector< EntityHandle > inents; 00398 if( meshdim == 1 ) 00399 { 00400 error = ahf->get_up_adjacencies_1d( vertex, inents );MB_CHK_ERR( error ); 00401 } 00402 else if( meshdim == 2 ) 00403 { 00404 error = ahf->get_up_adjacencies_vert_2d( vertex, inents );MB_CHK_ERR( error ); 00405 } 00406 else if( meshdim == 3 ) 00407 { 00408 error = ahf->get_up_adjacencies_vert_3d( vertex, inents );MB_CHK_ERR( error ); 00409 } 00410 00411 // Step 2: Loop over all the incident entities at the current level and gather their parents 00412 std::vector< EntityHandle > childs; 00413 for( int i = 0; i < (int)inents.size(); i++ ) 00414 { 00415 childs.clear(); 00416 EntityHandle ent = inents[i]; 00417 error = parent_to_child( ent, vert_level, child_level, childs );MB_CHK_ERR( error ); 00418 for( int j = 0; j < (int)childs.size(); j++ ) 00419 incident_entities.push_back( childs[j] ); 00420 } 00421 00422 return MB_SUCCESS; 00423 } 00424 00425 ErrorCode NestedRefine::get_vertex_duplicates( EntityHandle vertex, int level, EntityHandle& dupvertex ) 00426 { 00427 if( ( vertex - *_inverts.begin() ) > _inverts.size() ) 00428 MB_SET_ERR( MB_FAILURE, "Requesting duplicates for non-coarse vertices" ); 00429 00430 dupvertex = level_mesh[level - 1].start_vertex + ( vertex - *_inverts.begin() ); 00431 00432 return MB_SUCCESS; 00433 } 00434 00435 bool NestedRefine::is_entity_on_boundary( const EntityHandle& entity ) 00436 { 00437 bool is_border = false; 00438 EntityType type = mbImpl->type_from_handle( entity ); 00439 00440 if( type == MBVERTEX ) 00441 is_border = is_vertex_on_boundary( entity ); 00442 else if( type == MBEDGE ) 00443 is_border = is_edge_on_boundary( entity ); 00444 else if( type == MBTRI || type == MBQUAD ) 00445 is_border = is_face_on_boundary( entity ); 00446 else if( type == MBTET || type == MBHEX ) 00447 is_border = is_cell_on_boundary( entity ); 00448 else 00449 MB_SET_ERR( MB_FAILURE, "Requesting boundary information for unsupported entity type" ); 00450 00451 return is_border; 00452 } 00453 00454 ErrorCode NestedRefine::exchange_ghosts( std::vector< EntityHandle >& lsets, int num_glayers ) 00455 { 00456 ErrorCode error; 00457 00458 if( hasghost ) return MB_SUCCESS; 00459 00460 hasghost = true; 00461 #ifdef MOAB_HAVE_MPI 00462 error = pcomm->exchange_ghost_cells( meshdim, 0, num_glayers, 0, true, false );MB_CHK_ERR( error ); 00463 { 00464 Range empty_range; 00465 error = pcomm->exchange_tags( GLOBAL_ID_TAG_NAME, empty_range );MB_CHK_ERR( error ); 00466 // error = pcomm->assign_global_ids(lsets[i], 0, 1, false, true, false);MB_CHK_ERR(error); 00467 } 00468 #else 00469 MB_SET_ERR( MB_FAILURE, "Requesting ghost layers for a serial mesh" ); 00470 #endif 00471 00472 Range* lverts = new Range[lsets.size()]; 00473 Range* lents = new Range[lsets.size()]; 00474 for( size_t i = 0; i < lsets.size(); i++ ) 00475 { 00476 error = mbImpl->get_entities_by_dimension( lsets[i], meshdim, lents[i] );MB_CHK_ERR( error ); 00477 error = mbImpl->get_connectivity( lents[i], lverts[i] );MB_CHK_ERR( error ); 00478 00479 for( int gl = 0; gl < num_glayers; gl++ ) 00480 { 00481 error = mbImpl->get_adjacencies( lverts[i], meshdim, false, lents[i], Interface::UNION );MB_CHK_ERR( error ); 00482 error = mbImpl->get_connectivity( lents[i], lverts[i] );MB_CHK_ERR( error ); 00483 } 00484 } 00485 for( size_t i = 0; i < lsets.size(); i++ ) 00486 { 00487 error = mbImpl->add_entities( lsets[i], lverts[i] );MB_CHK_ERR( error ); 00488 error = mbImpl->add_entities( lsets[i], lents[i] );MB_CHK_ERR( error ); 00489 } 00490 00491 delete[] lverts; 00492 delete[] lents; 00493 return MB_SUCCESS; 00494 } 00495 00496 ErrorCode NestedRefine::update_special_tags( int level, EntityHandle& lset ) 00497 { 00498 assert( level > 0 && level < nlevels + 1 ); 00499 00500 ErrorCode error; 00501 std::vector< Tag > mtags( 3 ); 00502 00503 error = mbImpl->tag_get_handle( MATERIAL_SET_TAG_NAME, 1, MB_TYPE_INTEGER, mtags[0] );MB_CHK_ERR( error ); 00504 error = mbImpl->tag_get_handle( DIRICHLET_SET_TAG_NAME, 1, MB_TYPE_INTEGER, mtags[1] );MB_CHK_ERR( error ); 00505 error = mbImpl->tag_get_handle( NEUMANN_SET_TAG_NAME, 1, MB_TYPE_INTEGER, mtags[2] );MB_CHK_ERR( error ); 00506 00507 for( int i = 0; i < 3; i++ ) 00508 { 00509 // Gather sets of a particular tag 00510 Range sets; 00511 error = mbImpl->get_entities_by_type_and_tag( _rset, MBENTITYSET, &mtags[i], NULL, 1, sets );MB_CHK_ERR( error ); 00512 00513 // Loop over all sets, gather entities in each set and add their children at all levels to 00514 // the set 00515 Range set_ents; 00516 Range::iterator set_it; 00517 std::vector< EntityHandle > childs; 00518 00519 for( set_it = sets.begin(); set_it != sets.end(); ++set_it ) 00520 { 00521 // Get the entities in the set, recursively 00522 set_ents.clear(); 00523 childs.clear(); 00524 error = mbImpl->get_entities_by_handle( *set_it, set_ents, true );MB_CHK_ERR( error ); 00525 00526 // Gather child entities at the input level 00527 for( Range::iterator sit = set_ents.begin(); sit != set_ents.end(); sit++ ) 00528 { 00529 EntityType type = mbImpl->type_from_handle( *sit ); 00530 if( type == MBVERTEX ) 00531 { 00532 Range conn; 00533 std::vector< EntityHandle > cents; 00534 error = vertex_to_entities_down( *sit, 0, level, cents );MB_CHK_ERR( error ); 00535 error = mbImpl->get_connectivity( ¢s[0], (int)cents.size(), conn, true );MB_CHK_ERR( error ); 00536 childs.insert( childs.end(), cents.begin(), cents.end() ); 00537 } 00538 else 00539 { 00540 error = parent_to_child( *sit, 0, level, childs );MB_CHK_ERR( error ); 00541 } 00542 00543 std::sort( childs.begin(), childs.end() ); 00544 childs.erase( std::unique( childs.begin(), childs.end() ), childs.end() ); 00545 00546 // Add child entities to tagged sets 00547 error = mbImpl->add_entities( *set_it, &childs[0], childs.size() );MB_CHK_ERR( error ); 00548 } 00549 00550 // Remove the coarse entities 00551 error = mbImpl->remove_entities( *set_it, set_ents );MB_CHK_ERR( error ); 00552 00553 // Add 00554 error = mbImpl->add_entities( lset, &( *set_it ), 1 );MB_CHK_ERR( error ); 00555 } 00556 } 00557 return MB_SUCCESS; 00558 } 00559 00560 /*********************************************** 00561 * Basic functionalities: generate HM * 00562 ***********************************************/ 00563 00564 ErrorCode NestedRefine::estimate_hm_storage( EntityHandle set, int level_degree, int cur_level, int hmest[4] ) 00565 { 00566 ErrorCode error; 00567 00568 // Obtain the size of input mesh. 00569 int nverts_prev, nedges_prev, nfaces_prev, ncells_prev; 00570 if( cur_level ) 00571 { 00572 nverts_prev = level_mesh[cur_level - 1].num_verts; 00573 nedges_prev = level_mesh[cur_level - 1].num_edges; 00574 nfaces_prev = level_mesh[cur_level - 1].num_faces; 00575 ncells_prev = level_mesh[cur_level - 1].num_cells; 00576 } 00577 else 00578 { 00579 nverts_prev = _inverts.size(); 00580 nedges_prev = _inedges.size(); 00581 nfaces_prev = _infaces.size(); 00582 ncells_prev = _incells.size(); 00583 } 00584 00585 // Estimate mesh size of current level mesh. 00586 int nedges = 0, nfaces = 0; 00587 error = count_subentities( set, cur_level - 1, &nedges, &nfaces );MB_CHK_ERR( error ); 00588 00589 int d = get_index_from_degree( level_degree ); 00590 int nverts = refTemplates[MBEDGE - 1][d].nv_edge * nedges; 00591 hmest[0] = nverts_prev + nverts; 00592 hmest[1] = nedges_prev * refTemplates[MBEDGE - 1][d].total_new_ents; 00593 hmest[2] = 0; 00594 hmest[3] = 0; 00595 00596 int findex, cindex; 00597 if( nfaces_prev != 0 ) 00598 { 00599 EntityHandle start_face; 00600 if( cur_level ) 00601 start_face = level_mesh[cur_level - 1].start_face; 00602 else 00603 start_face = *_infaces.begin(); 00604 findex = mbImpl->type_from_handle( start_face ) - 1; 00605 hmest[2] = nfaces_prev * refTemplates[findex][d].total_new_ents; 00606 00607 if( meshdim == 2 ) hmest[0] += refTemplates[findex][d].nv_face * nfaces_prev; 00608 00609 if( meshdim == 3 ) hmest[1] += nfaces_prev * intFacEdg[findex - 1][d].nie; 00610 } 00611 00612 if( ncells_prev != 0 ) 00613 { 00614 cindex = mbImpl->type_from_handle( *( _incells.begin() ) ) - 1; 00615 hmest[3] = ncells_prev * refTemplates[cindex][d].total_new_ents; 00616 00617 hmest[0] += refTemplates[cindex][d].nv_face * nfaces; 00618 hmest[0] += refTemplates[cindex][d].nv_cell * ncells_prev; 00619 } 00620 00621 return MB_SUCCESS; 00622 } 00623 00624 ErrorCode NestedRefine::create_hm_storage_single_level( EntityHandle* set, int cur_level, int estL[4] ) 00625 { 00626 // Obtain chunks of memory for the current level. Add them to a particular meshset. 00627 EntityHandle set_handle; 00628 ErrorCode error = mbImpl->create_meshset( MESHSET_SET, set_handle );MB_CHK_SET_ERR( error, "Cannot create mesh for the current level" ); 00629 *set = set_handle; 00630 00631 ReadUtilIface* read_iface; 00632 error = mbImpl->query_interface( read_iface );MB_CHK_ERR( error ); 00633 00634 // Vertices 00635 error = read_iface->get_node_coords( 3, estL[0], 0, level_mesh[cur_level].start_vertex, 00636 level_mesh[cur_level].coordinates );MB_CHK_ERR( error ); 00637 level_mesh[cur_level].num_verts = estL[0]; 00638 00639 Range newverts( level_mesh[cur_level].start_vertex, level_mesh[cur_level].start_vertex + estL[0] - 1 ); 00640 error = mbImpl->add_entities( *set, newverts );MB_CHK_ERR( error ); 00641 level_mesh[cur_level].verts = newverts; 00642 00643 Tag gidtag; 00644 error = mbImpl->tag_get_handle( GLOBAL_ID_TAG_NAME, gidtag );MB_CHK_ERR( error ); 00645 error = read_iface->assign_ids( gidtag, newverts, level_mesh[cur_level].start_vertex );MB_CHK_ERR( error ); 00646 00647 // Edges 00648 if( estL[1] ) 00649 { 00650 error = read_iface->get_element_connect( estL[1], 2, MBEDGE, 0, level_mesh[cur_level].start_edge, 00651 level_mesh[cur_level].edge_conn );MB_CHK_ERR( error ); 00652 level_mesh[cur_level].num_edges = estL[1]; 00653 00654 Range newedges( level_mesh[cur_level].start_edge, level_mesh[cur_level].start_edge + estL[1] - 1 ); 00655 error = mbImpl->add_entities( *set, newedges );MB_CHK_ERR( error ); 00656 level_mesh[cur_level].edges = newedges; 00657 } 00658 else 00659 level_mesh[cur_level].num_edges = 0; 00660 00661 // Faces 00662 if( estL[2] ) 00663 { 00664 EntityType type = mbImpl->type_from_handle( *( _infaces.begin() ) ); 00665 int nvpf = ahf->lConnMap2D[type - 2].num_verts_in_face; 00666 error = read_iface->get_element_connect( estL[2], nvpf, type, 0, level_mesh[cur_level].start_face, 00667 level_mesh[cur_level].face_conn );MB_CHK_ERR( error ); 00668 level_mesh[cur_level].num_faces = estL[2]; 00669 00670 Range newfaces( level_mesh[cur_level].start_face, level_mesh[cur_level].start_face + estL[2] - 1 ); 00671 error = mbImpl->add_entities( *set, newfaces );MB_CHK_ERR( error ); 00672 level_mesh[cur_level].faces = newfaces; 00673 } 00674 else 00675 level_mesh[cur_level].num_faces = 0; 00676 00677 // Cells 00678 if( estL[3] ) 00679 { 00680 EntityType type = mbImpl->type_from_handle( *( _incells.begin() ) ); 00681 int index = ahf->get_index_in_lmap( *_incells.begin() ); 00682 int nvpc = ahf->lConnMap3D[index].num_verts_in_cell; 00683 error = read_iface->get_element_connect( estL[3], nvpc, type, 0, level_mesh[cur_level].start_cell, 00684 level_mesh[cur_level].cell_conn );MB_CHK_ERR( error ); 00685 level_mesh[cur_level].num_cells = estL[3]; 00686 00687 Range newcells( level_mesh[cur_level].start_cell, level_mesh[cur_level].start_cell + estL[3] - 1 ); 00688 error = mbImpl->add_entities( *set, newcells );MB_CHK_ERR( error ); 00689 level_mesh[cur_level].cells = newcells; 00690 } 00691 else 00692 level_mesh[cur_level].num_cells = 0; 00693 00694 // Resize the ahf maps 00695 error = ahf->resize_hf_maps( level_mesh[cur_level].start_vertex, level_mesh[cur_level].num_verts, 00696 level_mesh[cur_level].start_edge, level_mesh[cur_level].num_edges, 00697 level_mesh[cur_level].start_face, level_mesh[cur_level].num_faces, 00698 level_mesh[cur_level].start_cell, level_mesh[cur_level].num_cells );MB_CHK_ERR( error ); 00699 00700 error = ahf->update_entity_ranges( *set );MB_CHK_ERR( error ); 00701 00702 // If the mesh type changes, then update the member variable in ahf to use the applicable 00703 // adjacency matrix 00704 MESHTYPE nwmesh = ahf->get_mesh_type( level_mesh[cur_level].num_verts, level_mesh[cur_level].num_edges, 00705 level_mesh[cur_level].num_faces, level_mesh[cur_level].num_cells );MB_CHK_ERR( error ); 00706 if( ahf->thismeshtype != nwmesh ) ahf->thismeshtype = nwmesh; 00707 00708 return MB_SUCCESS; 00709 } 00710 00711 /********************************** 00712 * Hierarchical Mesh Generation * 00713 * *********************************/ 00714 00715 ErrorCode NestedRefine::generate_hm( int* level_degrees, int num_level, EntityHandle* hm_set, bool optimize ) 00716 { 00717 ErrorCode error; 00718 00719 Tag gidtag; 00720 error = mbImpl->tag_get_handle( GLOBAL_ID_TAG_NAME, gidtag );MB_CHK_ERR( error ); 00721 00722 nlevels = num_level; 00723 00724 timeall.tm_total = 0; 00725 timeall.tm_refine = 0; 00726 timeall.tm_resolve = 0; 00727 00728 for( int l = 0; l < num_level; l++ ) 00729 { 00730 double tstart; 00731 tstart = tm->time_elapsed(); 00732 00733 // Estimate storage 00734 int hmest[4] = { 0, 0, 0, 0 }; 00735 EntityHandle set; 00736 if( l ) 00737 set = hm_set[l - 1]; 00738 else 00739 set = _rset; 00740 error = estimate_hm_storage( set, level_degrees[l], l, hmest );MB_CHK_ERR( error ); 00741 00742 // Create arrays for storing the current level 00743 error = create_hm_storage_single_level( &hm_set[l], l, hmest );MB_CHK_ERR( error ); 00744 00745 // Copy the old vertices along with their coordinates 00746 error = copy_vertices_from_prev_level( l );MB_CHK_ERR( error ); 00747 00748 // Create the new entities and new vertices 00749 error = construct_hm_entities( l, level_degrees[l] );MB_CHK_ERR( error ); 00750 00751 timeall.tm_refine += tm->time_elapsed() - tstart; 00752 00753 // Go into parallel communication 00754 if( !optimize ) 00755 { 00756 #ifdef MOAB_HAVE_MPI 00757 if( pcomm && ( pcomm->size() > 1 ) ) 00758 { 00759 double tpstart = tm->time_elapsed(); 00760 error = resolve_shared_ents_parmerge( l, hm_set[l] );MB_CHK_ERR( error ); 00761 timeall.tm_resolve += tm->time_elapsed() - tpstart; 00762 } 00763 #endif 00764 } 00765 } 00766 00767 if( optimize ) 00768 { 00769 #ifdef MOAB_HAVE_MPI 00770 if( pcomm && ( pcomm->size() > 1 ) ) 00771 { 00772 double tpstart = tm->time_elapsed(); 00773 error = resolve_shared_ents_opt( hm_set, nlevels );MB_CHK_ERR( error ); 00774 timeall.tm_resolve = tm->time_elapsed() - tpstart; 00775 } 00776 #endif 00777 } 00778 timeall.tm_total = timeall.tm_refine + timeall.tm_resolve; 00779 00780 return MB_SUCCESS; 00781 } 00782 00783 ErrorCode NestedRefine::construct_hm_entities( int cur_level, int deg ) 00784 { 00785 ErrorCode error; 00786 00787 // Generate mesh for current level by refining previous level. 00788 if( ahf->thismeshtype == CURVE ) 00789 { 00790 error = construct_hm_1D( cur_level, deg );MB_CHK_ERR( error ); 00791 } 00792 else if( ahf->thismeshtype == SURFACE || ahf->thismeshtype == SURFACE_MIXED ) 00793 { 00794 error = construct_hm_2D( cur_level, deg );MB_CHK_ERR( error ); 00795 } 00796 else 00797 { 00798 error = construct_hm_3D( cur_level, deg );MB_CHK_ERR( error ); 00799 } 00800 00801 return MB_SUCCESS; 00802 } 00803 00804 ErrorCode NestedRefine::construct_hm_1D( int cur_level, int deg ) 00805 { 00806 ErrorCode error; 00807 int nverts_prev, nents_prev; 00808 if( cur_level ) 00809 { 00810 nverts_prev = level_mesh[cur_level - 1].num_verts; 00811 nents_prev = level_mesh[cur_level - 1].num_edges; 00812 } 00813 else 00814 { 00815 nverts_prev = _inverts.size(); 00816 nents_prev = _inedges.size(); 00817 } 00818 00819 int d = get_index_from_degree( deg ); 00820 int vtotal = 2 + refTemplates[0][d].total_new_verts; 00821 std::vector< EntityHandle > vbuffer( vtotal ); 00822 00823 std::vector< EntityHandle > conn; 00824 int count_nents = 0; 00825 int count_verts = nverts_prev; 00826 00827 // Step 1: Create the subentities via refinement of the previous mesh 00828 for( int eid = 0; eid < nents_prev; eid++ ) 00829 { 00830 conn.clear(); 00831 00832 // EntityHandle of the working edge 00833 EntityHandle edge; 00834 if( cur_level ) 00835 edge = level_mesh[cur_level - 1].start_edge + eid; 00836 else 00837 edge = _inedges[eid]; // Makes the assumption initial mesh is contiguous in memory 00838 00839 error = get_connectivity( edge, cur_level, conn );MB_CHK_ERR( error ); 00840 00841 // Add the vertex handles to vbuffer for the current level for the working edge 00842 00843 // Since the old vertices are copied first, their local indices do not change as new levels 00844 // are added. Clearly the local indices of the new vertices introduced in the current level 00845 // is still the same when the old vertices are copied. Thus, there is no need to explicitly 00846 // store another map between the old and duplicates in the subsequent levels. The second 00847 // part in the following sum is the local index in the previous level. 00848 00849 // Add the corners to the vbuffer first. 00850 00851 for( int i = 0; i < (int)conn.size(); i++ ) 00852 { 00853 if( cur_level ) 00854 vbuffer[i] = level_mesh[cur_level].start_vertex + ( conn[i] - level_mesh[cur_level - 1].start_vertex ); 00855 else 00856 vbuffer[i] = level_mesh[cur_level].start_vertex + ( conn[i] - *_inverts.begin() ); 00857 } 00858 00859 // Adding rest of the entityhandles to working buffer for vertices. 00860 int num_new_verts = refTemplates[0][d].total_new_verts; 00861 00862 for( int i = 0; i < num_new_verts; i++ ) 00863 { 00864 vbuffer[i + 2] = level_mesh[cur_level].start_vertex + count_verts; 00865 count_verts += 1; 00866 } 00867 00868 // Use the template to obtain the subentities 00869 int id1, id2; 00870 int etotal = refTemplates[0][d].total_new_ents; 00871 std::vector< EntityHandle > ent_buffer( etotal ); 00872 00873 for( int i = 0; i < etotal; i++ ) 00874 { 00875 id1 = refTemplates[0][d].ents_conn[i][0]; 00876 id2 = refTemplates[0][d].ents_conn[i][1]; 00877 level_mesh[cur_level].edge_conn[2 * ( count_nents )] = vbuffer[id1]; 00878 level_mesh[cur_level].edge_conn[2 * ( count_nents ) + 1] = vbuffer[id2]; 00879 ent_buffer[i] = level_mesh[cur_level].start_edge + count_nents; 00880 count_nents += 1; 00881 }; 00882 00883 error = update_local_ahf( deg, MBEDGE, &vbuffer[0], &ent_buffer[0], etotal );MB_CHK_ERR( error ); 00884 00885 // Compute the coordinates of the new vertices: Linear interpolation 00886 int idx; 00887 double xi; 00888 for( int i = 0; i < num_new_verts; i++ ) 00889 { 00890 xi = refTemplates[0][d].vert_nat_coord[i][0]; 00891 idx = vbuffer[i + 2] - level_mesh[cur_level].start_vertex; // index of new vertex in current level 00892 if( cur_level ) 00893 { 00894 id1 = conn[0] - level_mesh[cur_level - 1].start_vertex; // index of old end vertices in current level 00895 id2 = conn[1] - level_mesh[cur_level - 1].start_vertex; 00896 } 00897 else 00898 { 00899 id1 = _inverts.index( conn[0] ); 00900 id2 = _inverts.index( conn[1] ); 00901 } 00902 00903 level_mesh[cur_level].coordinates[0][idx] = 00904 ( 1 - xi ) * level_mesh[cur_level].coordinates[0][id1] + xi * level_mesh[cur_level].coordinates[0][id2]; 00905 level_mesh[cur_level].coordinates[1][idx] = 00906 ( 1 - xi ) * level_mesh[cur_level].coordinates[1][id1] + xi * level_mesh[cur_level].coordinates[1][id2]; 00907 level_mesh[cur_level].coordinates[2][idx] = 00908 ( 1 - xi ) * level_mesh[cur_level].coordinates[2][id1] + xi * level_mesh[cur_level].coordinates[2][id2]; 00909 } 00910 } 00911 00912 error = update_global_ahf( MBEDGE, cur_level, deg );MB_CHK_ERR( error ); 00913 00914 return MB_SUCCESS; 00915 } 00916 00917 ErrorCode NestedRefine::construct_hm_1D( int cur_level, 00918 int deg, 00919 EntityType type, 00920 std::vector< EntityHandle >& trackverts ) 00921 { 00922 ErrorCode error; 00923 00924 int nedges_prev; 00925 if( cur_level ) 00926 nedges_prev = level_mesh[cur_level - 1].num_edges; 00927 else 00928 nedges_prev = _inedges.size(); 00929 00930 int d = get_index_from_degree( deg ); 00931 int nve = refTemplates[0][d].nv_edge; 00932 int vtotal = 2 + refTemplates[0][d].total_new_verts; 00933 int etotal = refTemplates[0][d].total_new_ents; 00934 int ne = 0, dim = 0, index = 0; 00935 if( type == MBTRI || type == MBQUAD ) 00936 { 00937 index = type - 2; 00938 ne = ahf->lConnMap2D[index].num_verts_in_face; 00939 dim = 2; 00940 } 00941 else if( type == MBTET || type == MBHEX ) 00942 { 00943 index = ahf->get_index_in_lmap( *( _incells.begin() ) ); 00944 ne = ahf->lConnMap3D[index].num_edges_in_cell; 00945 dim = 3; 00946 } 00947 00948 std::vector< EntityHandle > vbuffer( vtotal ); 00949 std::vector< EntityHandle > ent_buffer( etotal ); 00950 00951 std::vector< EntityHandle > adjents, econn, fconn; 00952 std::vector< int > leids; 00953 int count_nents = 0; 00954 00955 // Loop over all the edges and gather the vertices to be used for refinement 00956 for( int eid = 0; eid < nedges_prev; eid++ ) 00957 { 00958 adjents.clear(); 00959 leids.clear(); 00960 econn.clear(); 00961 fconn.clear(); 00962 for( int i = 0; i < vtotal; i++ ) 00963 vbuffer[i] = 0; 00964 for( int i = 0; i < etotal; i++ ) 00965 ent_buffer[i] = 0; 00966 00967 EntityHandle edge; 00968 if( cur_level ) 00969 edge = level_mesh[cur_level - 1].start_edge + eid; 00970 else 00971 edge = _inedges[eid]; 00972 00973 error = get_connectivity( edge, cur_level, econn );MB_CHK_ERR( error ); 00974 00975 for( int i = 0; i < (int)econn.size(); i++ ) 00976 { 00977 if( cur_level ) 00978 vbuffer[i] = level_mesh[cur_level].start_vertex + ( econn[i] - level_mesh[cur_level - 1].start_vertex ); 00979 else 00980 vbuffer[i] = level_mesh[cur_level].start_vertex + ( econn[i] - *_inverts.begin() ); 00981 } 00982 00983 int fid = -1, lid = -1, idx1 = -1, idx2 = -1; 00984 00985 if( dim == 2 ) 00986 { 00987 error = ahf->get_up_adjacencies_2d( edge, adjents, &leids );MB_CHK_ERR( error ); 00988 if( cur_level ) 00989 fid = adjents[0] - level_mesh[cur_level - 1].start_face; 00990 else 00991 fid = _infaces.index( adjents[0] ); 00992 00993 lid = leids[0]; 00994 idx1 = lid; 00995 idx2 = ahf->lConnMap2D[index].next[lid]; 00996 } 00997 else if( dim == 3 ) 00998 { 00999 error = ahf->get_up_adjacencies_edg_3d( edge, adjents, &leids );MB_CHK_ERR( error ); 01000 if( cur_level ) 01001 fid = adjents[0] - level_mesh[cur_level - 1].start_cell; 01002 else 01003 fid = _incells.index( adjents[0] ); 01004 01005 lid = leids[0]; 01006 idx1 = ahf->lConnMap3D[index].e2v[lid][0]; 01007 idx2 = ahf->lConnMap3D[index].e2v[lid][1]; 01008 } 01009 01010 error = get_connectivity( adjents[0], cur_level, fconn );MB_CHK_ERR( error ); 01011 01012 bool orient = false; 01013 if( ( fconn[idx1] == econn[0] ) && ( fconn[idx2] == econn[1] ) ) orient = true; 01014 01015 if( orient ) 01016 { 01017 for( int j = 0; j < nve; j++ ) 01018 vbuffer[j + 2] = trackverts[fid * ne * nve + nve * lid + j]; 01019 } 01020 else 01021 { 01022 for( int j = 0; j < nve; j++ ) 01023 vbuffer[( nve - j - 1 ) + 2] = trackverts[fid * ne * nve + nve * lid + j]; 01024 } 01025 01026 // Use the template to obtain the subentities 01027 int id1, id2; 01028 01029 for( int i = 0; i < etotal; i++ ) 01030 { 01031 id1 = refTemplates[0][d].ents_conn[i][0]; 01032 id2 = refTemplates[0][d].ents_conn[i][1]; 01033 level_mesh[cur_level].edge_conn[2 * ( count_nents )] = vbuffer[id1]; 01034 level_mesh[cur_level].edge_conn[2 * ( count_nents ) + 1] = vbuffer[id2]; 01035 ent_buffer[i] = level_mesh[cur_level].start_edge + count_nents; 01036 01037 count_nents += 1; 01038 }; 01039 01040 error = update_local_ahf( deg, MBEDGE, &vbuffer[0], &ent_buffer[0], etotal );MB_CHK_ERR( error ); 01041 } 01042 01043 error = update_global_ahf_1D_sub( cur_level, deg );MB_CHK_ERR( error ); 01044 01045 return MB_SUCCESS; 01046 } 01047 01048 ErrorCode NestedRefine::construct_hm_2D( int cur_level, int deg ) 01049 { 01050 ErrorCode error; 01051 int nverts_prev, nents_prev; 01052 if( cur_level ) 01053 { 01054 nverts_prev = level_mesh[cur_level - 1].num_verts; 01055 nents_prev = level_mesh[cur_level - 1].num_faces; 01056 } 01057 else 01058 { 01059 nverts_prev = _inverts.size(); 01060 nents_prev = _infaces.size(); 01061 } 01062 01063 // Create some book-keeping arrays over the old mesh to avoid introducing duplicate vertices and 01064 // calculating vertices more than once. 01065 EntityType ftype = mbImpl->type_from_handle( *_infaces.begin() ); 01066 int nepf = ahf->lConnMap2D[ftype - 2].num_verts_in_face; 01067 int findex = ftype - 1; 01068 01069 int d = get_index_from_degree( deg ); 01070 int tnv = refTemplates[findex][d].total_new_verts; 01071 int vtotal = nepf + tnv; 01072 std::vector< EntityHandle > vbuffer( vtotal ); 01073 int etotal = refTemplates[findex][d].total_new_ents; 01074 std::vector< EntityHandle > ent_buffer( etotal ); 01075 01076 int nve = refTemplates[findex][d].nv_edge; 01077 std::vector< EntityHandle > trackvertsF( nents_prev * nepf * nve, 0 ); 01078 int cur_nverts = level_mesh[cur_level].num_verts; 01079 std::vector< int > flag_verts( cur_nverts - nverts_prev, 0 ); 01080 01081 int count_nverts = nverts_prev; 01082 int count_nents = 0; 01083 std::vector< EntityHandle > conn, cur_conn; 01084 01085 // Step 1: Create the subentities via refinement of the previous mesh 01086 for( int fid = 0; fid < nents_prev; fid++ ) 01087 { 01088 conn.clear(); 01089 cur_conn.clear(); 01090 for( int i = 0; i < vtotal; i++ ) 01091 vbuffer[i] = 0; 01092 for( int i = 0; i < etotal; i++ ) 01093 ent_buffer[i] = 0; 01094 01095 // EntityHandle of the working face 01096 EntityHandle face; 01097 if( cur_level ) 01098 face = level_mesh[cur_level - 1].start_face + fid; 01099 else 01100 face = _infaces[fid]; 01101 01102 error = get_connectivity( face, cur_level, conn );MB_CHK_ERR( error ); 01103 01104 // Step 1: Add vertices from the current level for the working face that will be used for 01105 // subdivision. 01106 // Add the corners to vbuffer 01107 for( int i = 0; i < (int)conn.size(); i++ ) 01108 { 01109 if( cur_level ) 01110 vbuffer[i] = level_mesh[cur_level].start_vertex + ( conn[i] - level_mesh[cur_level - 1].start_vertex ); 01111 else 01112 vbuffer[i] = level_mesh[cur_level].start_vertex + ( conn[i] - *_inverts.begin() ); 01113 01114 cur_conn.push_back( vbuffer[i] ); 01115 } 01116 01117 // Gather vertices already added to tracking array due to refinement of the sibling faces 01118 01119 for( int i = 0; i < nepf; i++ ) 01120 { 01121 for( int j = 0; j < nve; j++ ) 01122 { 01123 int id = refTemplates[findex][d].vert_on_edges[i][j]; 01124 vbuffer[id] = trackvertsF[fid * nve * nepf + nve * i + j]; 01125 } 01126 } 01127 01128 // Add the remaining vertex handles to vbuffer for the current level for the working face 01129 for( int i = 0; i < tnv; i++ ) 01130 { 01131 if( !vbuffer[i + nepf] ) 01132 { 01133 vbuffer[i + nepf] = level_mesh[cur_level].start_vertex + count_nverts; 01134 count_nverts += 1; 01135 } 01136 } 01137 01138 // Step 2: Create the subentities using the template and the vbuffer 01139 int idx; 01140 for( int i = 0; i < etotal; i++ ) 01141 { 01142 for( int k = 0; k < nepf; k++ ) 01143 { 01144 idx = refTemplates[findex][d].ents_conn[i][k]; 01145 level_mesh[cur_level].face_conn[nepf * count_nents + k] = vbuffer[idx]; 01146 } 01147 ent_buffer[i] = level_mesh[cur_level].start_face + count_nents; 01148 count_nents += 1; 01149 } 01150 01151 // Step 3: Update the local AHF maps 01152 error = update_local_ahf( deg, ftype, &vbuffer[0], &ent_buffer[0], etotal );MB_CHK_ERR( error ); 01153 01154 // Step 4: Add the new vertices to the tracking array 01155 int id; 01156 01157 for( int i = 0; i < nepf; i++ ) 01158 { 01159 // Add the vertices to trackvertsF for fid 01160 for( int j = 0; j < nve; j++ ) 01161 { 01162 id = refTemplates[findex][d].vert_on_edges[i][j]; 01163 trackvertsF[fid * nepf * nve + nve * i + j] = vbuffer[id]; 01164 } 01165 01166 std::vector< EntityHandle > sibfids; 01167 std::vector< int > sibleids; 01168 std::vector< int > siborient; 01169 01170 // Add the vertices to trackvertsF for siblings of fid, if any. 01171 error = ahf->get_up_adjacencies_2d( face, i, false, sibfids, &sibleids, &siborient );MB_CHK_ERR( error ); 01172 01173 if( !sibfids.size() ) continue; 01174 01175 for( int s = 0; s < (int)sibfids.size(); s++ ) 01176 { 01177 int sibid; 01178 if( cur_level ) 01179 sibid = sibfids[s] - level_mesh[cur_level - 1].start_face; 01180 else 01181 sibid = sibfids[s] - *_infaces.begin(); 01182 01183 if( siborient[s] ) // Same half-edge direction as the current half-edge 01184 { 01185 for( int j = 0; j < nve; j++ ) 01186 { 01187 id = refTemplates[findex][d].vert_on_edges[i][j]; 01188 trackvertsF[sibid * nepf * nve + nve * sibleids[s] + j] = vbuffer[id]; 01189 } 01190 } 01191 else 01192 { 01193 for( int j = 0; j < nve; j++ ) 01194 { 01195 id = refTemplates[findex][d].vert_on_edges[i][nve - j - 1]; 01196 trackvertsF[sibid * nepf * nve + nve * sibleids[s] + j] = vbuffer[id]; 01197 } 01198 } 01199 } 01200 } 01201 01202 // Step 5: Compute the coordinates of the new vertices, avoids computing more than once via 01203 // the flag_verts array. 01204 std::vector< double > corner_coords( nepf * 3 ); 01205 error = get_coordinates( &cur_conn[0], nepf, cur_level + 1, &corner_coords[0] );MB_CHK_ERR( error ); 01206 01207 error = compute_coordinates( cur_level, deg, ftype, &vbuffer[0], vtotal, &corner_coords[0], flag_verts, 01208 nverts_prev );MB_CHK_ERR( error ); 01209 } 01210 01211 // Step 6: Update the global maps 01212 error = update_global_ahf( ftype, cur_level, deg );MB_CHK_ERR( error ); 01213 01214 // Step 7: If edges exists, refine them. 01215 if( !_inedges.empty() ) 01216 { 01217 error = construct_hm_1D( cur_level, deg, ftype, trackvertsF );MB_CHK_ERR( error ); 01218 } 01219 01220 return MB_SUCCESS; 01221 } 01222 01223 ErrorCode NestedRefine::construct_hm_2D( int cur_level, 01224 int deg, 01225 EntityType type, 01226 std::vector< EntityHandle >& trackvertsE, 01227 std::vector< EntityHandle >& trackvertsF ) 01228 { 01229 ErrorCode error; 01230 01231 EntityType ftype = MBTRI; 01232 if( type == MBHEX ) ftype = MBQUAD; 01233 01234 int d = get_index_from_degree( deg ); 01235 int findex = ftype - 1; 01236 int cidx = ahf->get_index_in_lmap( *( _incells.begin() ) ); 01237 01238 int nepf = ahf->lConnMap2D[ftype - 2].num_verts_in_face; 01239 int nepc = ahf->lConnMap3D[cidx].num_edges_in_cell; 01240 int nfpc = ahf->lConnMap3D[cidx].num_faces_in_cell; 01241 01242 int tnv = refTemplates[findex][d].total_new_verts; 01243 int nve = refTemplates[findex][d].nv_edge; 01244 int nvf = refTemplates[findex][d].nv_face; 01245 int vtotal = nepf + tnv; 01246 int etotal = refTemplates[findex][d].total_new_ents; 01247 01248 std::vector< EntityHandle > vbuffer( vtotal ); 01249 std::vector< EntityHandle > ent_buffer( etotal ); 01250 01251 std::vector< EntityHandle > adjents, fconn, cconn; 01252 std::vector< int > leids; 01253 int count_nents = 0; 01254 01255 int nents_prev, ecount; 01256 if( cur_level ) 01257 { 01258 nents_prev = level_mesh[cur_level - 1].num_faces; 01259 ecount = level_mesh[cur_level - 1].num_edges * refTemplates[MBEDGE - 1][d].total_new_ents; 01260 ; 01261 } 01262 else 01263 { 01264 nents_prev = _infaces.size(); 01265 ecount = _inedges.size() * refTemplates[MBEDGE - 1][d].total_new_ents; 01266 ; 01267 } 01268 01269 // Step 1: Create the subentities via refinement of the previous mesh 01270 for( int it = 0; it < nents_prev; it++ ) 01271 { 01272 fconn.clear(); 01273 cconn.clear(); 01274 adjents.clear(); 01275 leids.clear(); 01276 for( int i = 0; i < vtotal; i++ ) 01277 vbuffer[i] = 0; 01278 for( int i = 0; i < etotal; i++ ) 01279 ent_buffer[i] = 0; 01280 01281 // EntityHandle of the working face 01282 EntityHandle face; 01283 if( cur_level ) 01284 face = level_mesh[cur_level - 1].start_face + it; 01285 else 01286 face = _infaces[it]; 01287 01288 error = get_connectivity( face, cur_level, fconn );MB_CHK_ERR( error ); 01289 01290 // Add the new handles for old connectivity in the buffer 01291 for( int i = 0; i < (int)fconn.size(); i++ ) 01292 { 01293 if( cur_level ) 01294 vbuffer[i] = level_mesh[cur_level].start_vertex + ( fconn[i] - level_mesh[cur_level - 1].start_vertex ); 01295 else 01296 vbuffer[i] = level_mesh[cur_level].start_vertex + ( fconn[i] - *_inverts.begin() ); 01297 } 01298 01299 // Add handles for vertices on edges and faces from the already refined cell 01300 int fid, lid; 01301 error = ahf->get_up_adjacencies_face_3d( face, adjents, &leids );MB_CHK_ERR( error ); 01302 01303 if( cur_level ) 01304 fid = adjents[0] - level_mesh[cur_level - 1].start_cell; 01305 else 01306 fid = _incells.index( adjents[0] ); 01307 01308 lid = leids[0]; 01309 01310 error = get_connectivity( adjents[0], cur_level, cconn );MB_CHK_ERR( error ); 01311 01312 // Find the orientation w.r.t the half-face and then add vertices properly. 01313 std::vector< EntityHandle > fac_conn( nepf ); 01314 std::vector< EntityHandle > lfac_conn( nepf ); 01315 for( int j = 0; j < nepf; j++ ) 01316 { 01317 fac_conn[j] = fconn[j]; 01318 int id = ahf->lConnMap3D[cidx].hf2v[lid][j]; 01319 lfac_conn[j] = cconn[id]; 01320 } 01321 01322 std::vector< int > le_idx, indices; 01323 01324 error = reorder_indices( deg, &fac_conn[0], &lfac_conn[0], nepf, le_idx, indices );MB_CHK_ERR( error ); 01325 01326 // Add the existing vertices on edges of the already refined cell to the vbuffer 01327 for( int j = 0; j < nepf; j++ ) 01328 { 01329 int id = le_idx[j]; // Corresponding local edge 01330 int idx = ahf->lConnMap3D[cidx].f2leid[lid][id]; // Local edge in the cell 01331 01332 // Get the orientation of the local edge of the face wrt the corresponding local edge in 01333 // the cell 01334 bool eorient = false; 01335 int fnext = ahf->lConnMap2D[ftype - 2].next[j]; 01336 int idx1 = ahf->lConnMap3D[cidx].e2v[idx][0]; 01337 int idx2 = ahf->lConnMap3D[cidx].e2v[idx][1]; 01338 if( ( fconn[j] == cconn[idx1] ) && ( fconn[fnext] == cconn[idx2] ) ) eorient = true; 01339 01340 if( eorient ) 01341 { 01342 for( int k = 0; k < nve; k++ ) 01343 { 01344 int ind = refTemplates[findex][d].vert_on_edges[j][k]; 01345 vbuffer[ind] = trackvertsE[fid * nepc * nve + nve * idx + k]; 01346 } 01347 } 01348 else 01349 { 01350 for( int k = 0; k < nve; k++ ) 01351 { 01352 int ind = refTemplates[findex][d].vert_on_edges[j][nve - k - 1]; 01353 vbuffer[ind] = trackvertsE[fid * nepc * nve + nve * idx + k]; 01354 } 01355 } 01356 } 01357 01358 // Add the existing vertices on the face of the refine cell to vbuffer 01359 if( nvf ) 01360 { 01361 for( int k = 0; k < nvf; k++ ) 01362 { 01363 int ind = refTemplates[findex][d].vert_on_faces[0][k]; 01364 vbuffer[ind] = trackvertsF[fid * nfpc * nvf + nvf * lid + indices[k] - 1]; 01365 } 01366 } 01367 01368 // Create the subentities using the template and the vbuffer 01369 for( int i = 0; i < etotal; i++ ) 01370 { 01371 for( int k = 0; k < nepf; k++ ) 01372 { 01373 int idx = refTemplates[findex][d].ents_conn[i][k]; 01374 level_mesh[cur_level].face_conn[nepf * count_nents + k] = vbuffer[idx]; 01375 } 01376 ent_buffer[i] = level_mesh[cur_level].start_face + count_nents; 01377 count_nents += 1; 01378 } 01379 01380 error = update_local_ahf( deg, ftype, &vbuffer[0], &ent_buffer[0], etotal );MB_CHK_ERR( error ); 01381 01382 // Create the interior edges 01383 int id1, id2; 01384 01385 int ne = intFacEdg[ftype - 2][d].nie; 01386 for( int i = 0; i < ne; i++ ) 01387 { 01388 id1 = intFacEdg[ftype - 2][d].ieconn[i][0]; 01389 id2 = intFacEdg[ftype - 2][d].ieconn[i][1]; 01390 level_mesh[cur_level].edge_conn[2 * ( ecount )] = vbuffer[id1]; 01391 level_mesh[cur_level].edge_conn[2 * ( ecount ) + 1] = vbuffer[id2]; 01392 ecount += 1; 01393 } 01394 } 01395 01396 // Step 6: Update the global maps 01397 error = update_global_ahf_2D_sub( cur_level, deg );MB_CHK_ERR( error ); 01398 01399 // Step 7: Update the hf-maps for the edges 01400 error = update_ahf_1D( cur_level );MB_CHK_ERR( error ); 01401 01402 return MB_SUCCESS; 01403 } 01404 01405 ErrorCode NestedRefine::construct_hm_3D( int cur_level, int deg ) 01406 { 01407 ErrorCode error; 01408 EntityType type = mbImpl->type_from_handle( *( _incells.begin() ) ); 01409 if( type == MBTET ) 01410 { 01411 error = subdivide_tets( cur_level, deg );MB_CHK_ERR( error ); 01412 } 01413 else 01414 { 01415 error = subdivide_cells( type, cur_level, deg );MB_CHK_ERR( error ); 01416 } 01417 01418 return MB_SUCCESS; 01419 } 01420 01421 ErrorCode NestedRefine::subdivide_cells( EntityType type, int cur_level, int deg ) 01422 { 01423 ErrorCode error; 01424 int nverts_prev, nents_prev; 01425 if( cur_level ) 01426 { 01427 nverts_prev = level_mesh[cur_level - 1].num_verts; 01428 nents_prev = level_mesh[cur_level - 1].num_cells; 01429 } 01430 else 01431 { 01432 nverts_prev = _inverts.size(); 01433 nents_prev = _incells.size(); 01434 } 01435 01436 // Create some book-keeping arrays over the parent mesh to avoid introducing duplicate vertices 01437 int cindex = type - 1; 01438 int d = get_index_from_degree( deg ); 01439 int ne = refTemplates[cindex][d].nv_edge; 01440 int nvf = refTemplates[cindex][d].nv_face; 01441 int nvtotal = refTemplates[cindex][d].total_new_verts; 01442 01443 int index = ahf->get_index_in_lmap( *( _incells.begin() ) ); 01444 int nvpc = ahf->lConnMap3D[index].num_verts_in_cell; 01445 int nepc = ahf->lConnMap3D[index].num_edges_in_cell; 01446 int nfpc = ahf->lConnMap3D[index].num_faces_in_cell; 01447 01448 int vtotal = nvpc + nvtotal; 01449 std::vector< EntityHandle > vbuffer( vtotal ); 01450 01451 std::vector< EntityHandle > trackvertsC_edg( nepc * ne * nents_prev, 0 ); 01452 std::vector< EntityHandle > trackvertsC_face( nfpc * nvf * nents_prev, 0 ); 01453 01454 int cur_nverts = level_mesh[cur_level].num_verts; 01455 std::vector< int > flag_verts( cur_nverts - nverts_prev, 0 ); 01456 01457 int count_nverts = nverts_prev; 01458 int count_ents = 0; 01459 std::vector< EntityHandle > conn, cur_conn; 01460 01461 // Step 1: Create the subentities via refinement of the previous mesh 01462 for( int cid = 0; cid < nents_prev; cid++ ) 01463 { 01464 conn.clear(); 01465 cur_conn.clear(); 01466 for( int i = 0; i < vtotal; i++ ) 01467 vbuffer[i] = 0; 01468 01469 // EntityHandle of the working cell 01470 EntityHandle cell; 01471 if( cur_level ) 01472 cell = level_mesh[cur_level - 1].start_cell + cid; 01473 else 01474 cell = _incells[cid]; 01475 01476 error = get_connectivity( cell, cur_level, conn );MB_CHK_ERR( error ); 01477 01478 // Step 1: Add vertices from the current level for the working face that will be used for 01479 // subdivision. 01480 // Add the corners to vbuffer 01481 for( int i = 0; i < (int)conn.size(); i++ ) 01482 { 01483 if( cur_level ) 01484 vbuffer[i] = level_mesh[cur_level].start_vertex + ( conn[i] - level_mesh[cur_level - 1].start_vertex ); 01485 else 01486 vbuffer[i] = level_mesh[cur_level].start_vertex + ( conn[i] - *_inverts.begin() ); 01487 01488 cur_conn.push_back( vbuffer[i] ); 01489 } 01490 01491 // Gather vertices already added to tracking array due to refinement of the sibling cells 01492 for( int i = 0; i < nepc; i++ ) 01493 { 01494 for( int j = 0; j < ne; j++ ) 01495 { 01496 int idx = refTemplates[cindex][d].vert_on_edges[i][j]; 01497 vbuffer[idx] = trackvertsC_edg[cid * nepc * ne + ne * i + j]; 01498 } 01499 } 01500 01501 // Add remaining new vertex handles 01502 for( int i = 0; i < nfpc; i++ ) 01503 { 01504 for( int j = 0; j < nvf; j++ ) 01505 { 01506 int idx = refTemplates[cindex][d].vert_on_faces[i][j]; 01507 vbuffer[idx] = trackvertsC_face[cid * nfpc * nvf + nvf * i + j]; 01508 } 01509 } 01510 01511 // Add the remaining vertex handles to vbuffer for the current level for the working cell 01512 for( int i = 0; i < nvtotal; i++ ) 01513 { 01514 if( !vbuffer[i + nvpc] ) 01515 { 01516 vbuffer[i + nvpc] = level_mesh[cur_level].start_vertex + count_nverts; 01517 count_nverts += 1; 01518 } 01519 } 01520 01521 // Step 2: Use the template to obtain the subentities. The coordinates and local ahf maps 01522 // are also constructed. Connectivity of the children 01523 int etotal = refTemplates[type - 1][d].total_new_ents; 01524 std::vector< EntityHandle > ent_buffer( etotal ); 01525 01526 for( int i = 0; i < etotal; i++ ) 01527 { 01528 for( int k = 0; k < nvpc; k++ ) 01529 { 01530 int idx = refTemplates[type - 1][d].ents_conn[i][k]; 01531 level_mesh[cur_level].cell_conn[nvpc * count_ents + k] = vbuffer[idx]; 01532 } 01533 ent_buffer[i] = level_mesh[cur_level].start_cell + count_ents; 01534 count_ents += 1; 01535 } 01536 01537 // Step 3: Update local ahf maps 01538 error = update_local_ahf( deg, type, &vbuffer[0], &ent_buffer[0], etotal );MB_CHK_ERR( error ); 01539 01540 // Step 4: Update tracking information 01541 error = update_tracking_verts( cell, cur_level, deg, trackvertsC_edg, trackvertsC_face, &vbuffer[0] );MB_CHK_ERR( error ); 01542 01543 // Step 5: Coordinates of the new vertices 01544 std::vector< double > corner_coords( nvpc * 3 ); 01545 error = get_coordinates( &cur_conn[0], nvpc, cur_level + 1, &corner_coords[0] );MB_CHK_ERR( error ); 01546 01547 error = compute_coordinates( cur_level, deg, type, &vbuffer[0], vtotal, &corner_coords[0], flag_verts, 01548 nverts_prev );MB_CHK_ERR( error ); 01549 } 01550 01551 // error = ahf->print_tags(3); 01552 01553 // Step 6: Update the global maps 01554 error = update_global_ahf( type, cur_level, deg );MB_CHK_ERR( error ); 01555 01556 // Step 7: If edges exists, refine them as well. 01557 if( level_mesh[cur_level].num_edges != 0 ) 01558 { 01559 error = construct_hm_1D( cur_level, deg, type, trackvertsC_edg );MB_CHK_ERR( error ); 01560 } 01561 01562 // Step 8: If faces exists, refine them as well. 01563 if( !_infaces.empty() ) 01564 { 01565 error = construct_hm_2D( cur_level, deg, type, trackvertsC_edg, trackvertsC_face );MB_CHK_ERR( error ); 01566 } 01567 01568 // error = ahf->print_tags(3); 01569 01570 return MB_SUCCESS; 01571 } 01572 01573 ErrorCode NestedRefine::subdivide_tets( int cur_level, int deg ) 01574 { 01575 ErrorCode error; 01576 int nverts_prev, nents_prev; 01577 if( cur_level ) 01578 { 01579 nverts_prev = level_mesh[cur_level - 1].num_verts; 01580 nents_prev = level_mesh[cur_level - 1].num_cells; 01581 } 01582 else 01583 { 01584 nverts_prev = _inverts.size(); 01585 nents_prev = _incells.size(); 01586 } 01587 01588 EntityType type = MBTET; 01589 int cindex = type - 1; 01590 int d = get_index_from_degree( deg ); 01591 int ne = refTemplates[cindex][d].nv_edge; 01592 int nvf = refTemplates[cindex][d].nv_face; 01593 int nvtotal = refTemplates[cindex][d].total_new_verts; 01594 01595 int index = ahf->get_index_in_lmap( *( _incells.begin() ) ); 01596 int nvpc = ahf->lConnMap3D[index].num_verts_in_cell; 01597 int nepc = ahf->lConnMap3D[index].num_edges_in_cell; 01598 int nfpc = ahf->lConnMap3D[index].num_faces_in_cell; 01599 01600 // Create vertex buffer 01601 int vtotal = nvpc + nvtotal; 01602 std::vector< EntityHandle > vbuffer( vtotal ); 01603 01604 // Create book-keeping arrays over the parent mesh to avoid introducing duplicate vertices 01605 std::vector< EntityHandle > trackvertsC_edg( nepc * ne * nents_prev, 0 ); 01606 std::vector< EntityHandle > trackvertsC_face( nfpc * nvf * nents_prev, 0 ); 01607 01608 int cur_nverts = level_mesh[cur_level].num_verts; 01609 std::vector< int > flag_verts( cur_nverts - nverts_prev, 0 ); 01610 std::vector< int > cell_patterns( nents_prev, 0 ); 01611 01612 int count_nverts = nverts_prev; 01613 int count_ents = 0; 01614 std::vector< EntityHandle > conn, cur_conn; 01615 01616 // Step 1: Create the subentities via refinement of the previous mesh 01617 for( int cid = 0; cid < nents_prev; cid++ ) 01618 { 01619 conn.clear(); 01620 cur_conn.clear(); 01621 for( int i = 0; i < vtotal; i++ ) 01622 vbuffer[i] = 0; 01623 01624 // EntityHandle of the working cell 01625 EntityHandle cell; 01626 if( cur_level ) 01627 cell = level_mesh[cur_level - 1].start_cell + cid; 01628 else 01629 cell = _incells[cid]; 01630 01631 error = get_connectivity( cell, cur_level, conn );MB_CHK_ERR( error ); 01632 01633 // Step 1: Add vertices from the current level for the working face that will be used for 01634 // subdivision. 01635 // Add the corners to vbuffer 01636 for( int i = 0; i < (int)conn.size(); i++ ) 01637 { 01638 if( cur_level ) 01639 vbuffer[i] = level_mesh[cur_level].start_vertex + ( conn[i] - level_mesh[cur_level - 1].start_vertex ); 01640 else 01641 vbuffer[i] = level_mesh[cur_level].start_vertex + ( conn[i] - *_inverts.begin() ); 01642 01643 cur_conn.push_back( vbuffer[i] ); 01644 } 01645 01646 // Gather vertices already added to tracking array due to refinement of the sibling cells 01647 for( int i = 0; i < nepc; i++ ) 01648 { 01649 for( int j = 0; j < ne; j++ ) 01650 { 01651 int idx = refTemplates[cindex][d].vert_on_edges[i][j]; 01652 vbuffer[idx] = trackvertsC_edg[cid * nepc * ne + ne * i + j]; 01653 } 01654 } 01655 01656 // Add remaining new vertex handles 01657 for( int i = 0; i < nfpc; i++ ) 01658 { 01659 for( int j = 0; j < nvf; j++ ) 01660 { 01661 int idx = refTemplates[cindex][d].vert_on_faces[i][j]; 01662 vbuffer[idx] = trackvertsC_face[cid * nfpc * nvf + nvf * i + j]; 01663 } 01664 } 01665 01666 // Add the remaining vertex handles to vbuffer for the current level for the working cell 01667 for( int i = 0; i < nvtotal; i++ ) 01668 { 01669 if( !vbuffer[i + nvpc] ) 01670 { 01671 vbuffer[i + nvpc] = level_mesh[cur_level].start_vertex + count_nverts; 01672 count_nverts += 1; 01673 } 01674 } 01675 01676 // Step 2: Coordinates of the new vertices 01677 std::vector< double > corner_coords( nvpc * 3 ); 01678 error = get_coordinates( &cur_conn[0], nvpc, cur_level + 1, &corner_coords[0] );MB_CHK_ERR( error ); 01679 01680 error = compute_coordinates( cur_level, deg, type, &vbuffer[0], vtotal, &corner_coords[0], flag_verts, 01681 nverts_prev );MB_CHK_ERR( error ); 01682 01683 // Step 3: Choose the tet refine pattern to be used for this tet 01684 int diag = find_shortest_diagonal_octahedron( cur_level, deg, &vbuffer[0] ); 01685 int pat_id = diag + 2; 01686 cell_patterns[cid] = pat_id; 01687 01688 // Step 4: Use the template to obtain the subentities. The coordinates and local ahf maps 01689 // are also constructed. Connectivity of the children 01690 int etotal = refTemplates[pat_id][d].total_new_ents; 01691 std::vector< EntityHandle > ent_buffer( etotal ); 01692 01693 for( int i = 0; i < etotal; i++ ) 01694 { 01695 for( int k = 0; k < nvpc; k++ ) 01696 { 01697 int idx = refTemplates[pat_id][d].ents_conn[i][k]; 01698 level_mesh[cur_level].cell_conn[nvpc * count_ents + k] = vbuffer[idx]; 01699 } 01700 ent_buffer[i] = level_mesh[cur_level].start_cell + count_ents; 01701 count_ents += 1; 01702 } 01703 01704 // Step 5: Update local ahf maps 01705 error = update_local_ahf( deg, MBTET, pat_id, &vbuffer[0], &ent_buffer[0], etotal );MB_CHK_ERR( error ); 01706 01707 // Step 6: Update tracking information 01708 error = update_tracking_verts( cell, cur_level, deg, trackvertsC_edg, trackvertsC_face, &vbuffer[0] );MB_CHK_ERR( error ); 01709 } 01710 01711 // Step 7: Update the global maps 01712 // error = update_global_ahf(cur_level, deg, cell_patterns); MB_CHK_ERR(error); 01713 error = update_global_ahf( type, cur_level, deg, &cell_patterns );MB_CHK_ERR( error ); 01714 01715 // Step 8: If edges exists, refine them as well. 01716 if( level_mesh[cur_level].num_edges != 0 ) 01717 { 01718 error = construct_hm_1D( cur_level, deg, type, trackvertsC_edg );MB_CHK_ERR( error ); 01719 } 01720 01721 // Step 9: If faces exists, refine them as well. 01722 if( !_infaces.empty() ) 01723 { 01724 error = construct_hm_2D( cur_level, deg, type, trackvertsC_edg, trackvertsC_face );MB_CHK_ERR( error ); 01725 } 01726 01727 return MB_SUCCESS; 01728 } 01729 01730 ErrorCode NestedRefine::compute_coordinates( int cur_level, 01731 int deg, 01732 EntityType type, 01733 EntityHandle* vbuffer, 01734 int vtotal, 01735 double* corner_coords, 01736 std::vector< int >& vflag, 01737 int nverts_prev ) 01738 { 01739 EntityHandle vstart = level_mesh[cur_level].start_vertex; 01740 int d = get_index_from_degree( deg ); 01741 01742 if( type == MBTRI ) 01743 { 01744 double xi, eta, N[3]; 01745 int findex = mbImpl->type_from_handle( *( _infaces.begin() ) ) - 1; 01746 01747 for( int i = 3; i < vtotal; i++ ) 01748 { 01749 if( vflag[vbuffer[i] - vstart - nverts_prev] ) continue; 01750 01751 xi = refTemplates[findex][d].vert_nat_coord[i - 3][0]; 01752 eta = refTemplates[findex][d].vert_nat_coord[i - 3][1]; 01753 N[0] = 1 - xi - eta; 01754 N[1] = xi; 01755 N[2] = eta; 01756 01757 double x = 0, y = 0, z = 0; 01758 for( int j = 0; j < 3; j++ ) 01759 { 01760 x += N[j] * corner_coords[3 * j]; 01761 y += N[j] * corner_coords[3 * j + 1]; 01762 z += N[j] * corner_coords[3 * j + 2]; 01763 } 01764 01765 level_mesh[cur_level].coordinates[0][vbuffer[i] - vstart] = x; 01766 level_mesh[cur_level].coordinates[1][vbuffer[i] - vstart] = y; 01767 level_mesh[cur_level].coordinates[2][vbuffer[i] - vstart] = z; 01768 vflag[vbuffer[i] - vstart - nverts_prev] = 1; 01769 } 01770 } 01771 else if( type == MBQUAD ) 01772 { 01773 double xi, eta, N[4]; 01774 int findex = mbImpl->type_from_handle( *( _infaces.begin() ) ) - 1; 01775 01776 for( int i = 4; i < vtotal; i++ ) 01777 { 01778 if( vflag[vbuffer[i] - vstart - nverts_prev] ) continue; 01779 01780 xi = refTemplates[findex][d].vert_nat_coord[i - 4][0]; 01781 eta = refTemplates[findex][d].vert_nat_coord[i - 4][1]; 01782 N[0] = ( 1 - xi ) * ( 1 - eta ) / 4; 01783 N[1] = ( 1 + xi ) * ( 1 - eta ) / 4; 01784 N[2] = ( 1 + xi ) * ( 1 + eta ) / 4, N[3] = ( 1 - xi ) * ( 1 + eta ) / 4; 01785 01786 double x = 0, y = 0, z = 0; 01787 for( int j = 0; j < 4; j++ ) 01788 { 01789 x += N[j] * corner_coords[3 * j]; 01790 y += N[j] * corner_coords[3 * j + 1]; 01791 z += N[j] * corner_coords[3 * j + 2]; 01792 } 01793 01794 level_mesh[cur_level].coordinates[0][vbuffer[i] - vstart] = x; 01795 level_mesh[cur_level].coordinates[1][vbuffer[i] - vstart] = y; 01796 level_mesh[cur_level].coordinates[2][vbuffer[i] - vstart] = z; 01797 vflag[vbuffer[i] - vstart - nverts_prev] = 1; 01798 } 01799 } 01800 else if( type == MBTET ) 01801 { 01802 double xi, eta, mu, N[4]; 01803 int cindex = mbImpl->type_from_handle( *( _incells.begin() ) ) - 1; 01804 01805 for( int i = 4; i < vtotal; i++ ) 01806 { 01807 if( vflag[vbuffer[i] - vstart - nverts_prev] ) continue; 01808 01809 xi = refTemplates[cindex][d].vert_nat_coord[i - 4][0]; 01810 eta = refTemplates[cindex][d].vert_nat_coord[i - 4][1]; 01811 mu = refTemplates[cindex][d].vert_nat_coord[i - 4][2]; 01812 01813 N[0] = 1 - xi - eta - mu; 01814 N[1] = xi; 01815 N[2] = eta, N[3] = mu; 01816 01817 double x = 0, y = 0, z = 0; 01818 for( int j = 0; j < 4; j++ ) 01819 { 01820 x += N[j] * corner_coords[3 * j]; 01821 y += N[j] * corner_coords[3 * j + 1]; 01822 z += N[j] * corner_coords[3 * j + 2]; 01823 } 01824 01825 level_mesh[cur_level].coordinates[0][vbuffer[i] - vstart] = x; 01826 level_mesh[cur_level].coordinates[1][vbuffer[i] - vstart] = y; 01827 level_mesh[cur_level].coordinates[2][vbuffer[i] - vstart] = z; 01828 vflag[vbuffer[i] - vstart - nverts_prev] = 1; 01829 } 01830 } 01831 else if( type == MBPRISM ) 01832 { 01833 double xi, eta, mu, N[6]; 01834 int cindex = mbImpl->type_from_handle( *( _incells.begin() ) ) - 1; 01835 01836 for( int i = 6; i < vtotal; i++ ) 01837 { 01838 if( vflag[vbuffer[i] - vstart - nverts_prev] ) continue; 01839 01840 xi = refTemplates[cindex][d].vert_nat_coord[i - 6][0]; 01841 eta = refTemplates[cindex][d].vert_nat_coord[i - 6][1]; 01842 mu = refTemplates[cindex][d].vert_nat_coord[i - 6][2]; 01843 01844 N[0] = ( 1 - xi - eta ) * ( 1 - mu ), N[1] = xi * ( 1 - mu ), N[2] = eta * ( 1 - mu ), 01845 N[3] = ( 1 - xi - eta ) * ( 1 + mu ), N[4] = xi * ( 1 + mu ), N[5] = eta * ( 1 + mu ); 01846 01847 double x = 0, y = 0, z = 0; 01848 for( int j = 0; j < 6; j++ ) 01849 { 01850 x += N[j] * corner_coords[3 * j]; 01851 y += N[j] * corner_coords[3 * j + 1]; 01852 z += N[j] * corner_coords[3 * j + 2]; 01853 } 01854 01855 level_mesh[cur_level].coordinates[0][vbuffer[i] - vstart] = x; 01856 level_mesh[cur_level].coordinates[1][vbuffer[i] - vstart] = y; 01857 level_mesh[cur_level].coordinates[2][vbuffer[i] - vstart] = z; 01858 vflag[vbuffer[i] - vstart - nverts_prev] = 1; 01859 } 01860 } 01861 else if( type == MBHEX ) 01862 { 01863 double xi, eta, mu, N[8]; 01864 double d1, d2, d3, s1, s2, s3; 01865 int cindex = mbImpl->type_from_handle( *( _incells.begin() ) ) - 1; 01866 01867 for( int i = 8; i < vtotal; i++ ) 01868 { 01869 01870 if( vflag[vbuffer[i] - vstart - nverts_prev] ) continue; 01871 01872 xi = refTemplates[cindex][d].vert_nat_coord[i - 8][0]; 01873 eta = refTemplates[cindex][d].vert_nat_coord[i - 8][1]; 01874 mu = refTemplates[cindex][d].vert_nat_coord[i - 8][2]; 01875 01876 d1 = 1 - xi; 01877 d2 = 1 - eta; 01878 d3 = 1 - mu; 01879 s1 = 1 + xi; 01880 s2 = 1 + eta; 01881 s3 = 1 + mu; 01882 N[0] = ( d1 * d2 * d3 ) / 8; 01883 N[1] = ( s1 * d2 * d3 ) / 8; 01884 N[2] = ( s1 * s2 * d3 ) / 8; 01885 N[3] = ( d1 * s2 * d3 ) / 8; 01886 N[4] = ( d1 * d2 * s3 ) / 8; 01887 N[5] = ( s1 * d2 * s3 ) / 8; 01888 N[6] = ( s1 * s2 * s3 ) / 8; 01889 N[7] = ( d1 * s2 * s3 ) / 8; 01890 01891 double x = 0, y = 0, z = 0; 01892 for( int j = 0; j < 8; j++ ) 01893 { 01894 x += N[j] * corner_coords[3 * j]; 01895 y += N[j] * corner_coords[3 * j + 1]; 01896 z += N[j] * corner_coords[3 * j + 2]; 01897 } 01898 01899 level_mesh[cur_level].coordinates[0][vbuffer[i] - vstart] = x; 01900 level_mesh[cur_level].coordinates[1][vbuffer[i] - vstart] = y; 01901 level_mesh[cur_level].coordinates[2][vbuffer[i] - vstart] = z; 01902 01903 vflag[vbuffer[i] - vstart - nverts_prev] = 1; 01904 } 01905 } 01906 return MB_SUCCESS; 01907 } 01908 /********************************** 01909 * Parallel Communication * 01910 * ********************************/ 01911 01912 #ifdef MOAB_HAVE_MPI 01913 ErrorCode NestedRefine::resolve_shared_ents_parmerge( int level, EntityHandle levelset ) 01914 { 01915 // TEMP: Add the adjacencies for MOAB-native DS 01916 // NOTE (VSM): This is expensive since it creates a doubly 01917 // redundant copy of the adjacency data in both MOAB-native 01918 // and AHF. Need to fix this with AHF optimized branch. 01919 ErrorCode error; 01920 ReadUtilIface* read_iface; 01921 error = mbImpl->query_interface( read_iface );MB_CHK_ERR( error ); 01922 if( level_mesh[level].num_edges != 0 ) 01923 { 01924 error = read_iface->update_adjacencies( level_mesh[level].start_edge, level_mesh[level].num_edges, 2, 01925 level_mesh[level].edge_conn );MB_CHK_ERR( error ); 01926 } 01927 if( level_mesh[level].num_faces != 0 ) 01928 { 01929 EntityType type = mbImpl->type_from_handle( *( _infaces.begin() ) ); 01930 int nvpf = ahf->lConnMap2D[type - 2].num_verts_in_face; 01931 error = read_iface->update_adjacencies( level_mesh[level].start_face, level_mesh[level].num_faces, nvpf, 01932 level_mesh[level].face_conn );MB_CHK_ERR( error ); 01933 } 01934 if( level_mesh[level].num_cells != 0 ) 01935 { 01936 int index = ahf->get_index_in_lmap( *_incells.begin() ); 01937 int nvpc = ahf->lConnMap3D[index].num_verts_in_cell; 01938 error = read_iface->update_adjacencies( level_mesh[level].start_cell, level_mesh[level].num_cells, nvpc, 01939 level_mesh[level].cell_conn );MB_CHK_ERR( error ); 01940 } 01941 01942 if( pcomm->size() > 1 ) 01943 { 01944 01945 // get all entities on the rootset 01946 moab::Range vtxs, edgs, facs, elms; 01947 error = mbImpl->get_entities_by_dimension( levelset, 0, vtxs, false );MB_CHK_ERR( error ); 01948 error = mbImpl->get_entities_by_dimension( levelset, 1, edgs, false );MB_CHK_ERR( error ); 01949 error = mbImpl->get_entities_by_dimension( levelset, 2, facs, false );MB_CHK_ERR( error ); 01950 error = mbImpl->get_entities_by_dimension( levelset, 3, elms, false );MB_CHK_ERR( error ); 01951 01952 // set the parallel partition tag data 01953 moab::Tag part_tag; 01954 int partid = pcomm->rank(), dum_id = -1; 01955 error = mbImpl->tag_get_handle( "PARALLEL_PARTITION", 1, moab::MB_TYPE_INTEGER, part_tag, 01956 moab::MB_TAG_CREAT | moab::MB_TAG_SPARSE, &dum_id );MB_CHK_ERR( error ); 01957 error = mbImpl->tag_set_data( part_tag, &levelset, 1, &partid );MB_CHK_ERR( error ); 01958 // 01959 // Now that we have the local piece of the mesh refined consistently, 01960 // call parallel merge instead of resolved_shared to stitch together the meshes 01961 // and to handle parallel communication of remote proc/entity-handle pairs for 01962 // shared + non-owned interfaces entities. 01963 // 01964 // TODO: This needs to be replaced by the following scheme in the future as 01965 // an optimization step. 01966 // > Assign global IDs consistently for shared entities so that parallel 01967 // > resolve shared ents can happen out of the box. This is the fastest option. 01968 01969 ParallelMergeMesh pm( pcomm, 1e-08 ); 01970 error = pm.merge( levelset, true );MB_CHK_ERR( error ); 01971 01972 // 01973 // Parallel Communication complete - all entities resolved 01974 // 01975 } 01976 return MB_SUCCESS; 01977 } 01978 01979 ErrorCode NestedRefine::resolve_shared_ents_opt( EntityHandle* hm_set, int num_levels ) 01980 { 01981 assert( pcomm->size() > 1 ); 01982 01983 ErrorCode error; 01984 01985 // Step 1A: Pre-processing: setting the parallel partition tag data 01986 for( int i = 0; i < num_levels; i++ ) 01987 { 01988 Tag part_tag; 01989 int partid = pcomm->rank(), dum_id = -1; 01990 error = mbImpl->tag_get_handle( "PARALLEL_PARTITION", 1, moab::MB_TYPE_INTEGER, part_tag, 01991 moab::MB_TAG_CREAT | moab::MB_TAG_SPARSE, &dum_id );MB_CHK_ERR( error ); 01992 error = mbImpl->tag_set_data( part_tag, &hm_set[i], 1, &partid );MB_CHK_ERR( error ); 01993 } 01994 01995 // Step 1B: Pre-processing: gather all shared entities and list entities shared with each 01996 // sharing processor 01997 01998 // All shared processors 01999 std::set< unsigned int > shprocs; 02000 error = pcomm->get_comm_procs( shprocs );MB_CHK_ERR( error ); 02001 02002 std::vector< int > sharedprocs; 02003 for( std::set< unsigned int >::iterator it = shprocs.begin(); it != shprocs.end(); it++ ) 02004 sharedprocs.push_back( *it ); 02005 int nprocs = sharedprocs.size(); 02006 02007 // Create buffer variables storing the entities to be sent and received 02008 std::vector< std::vector< int > > nsharedEntsperproc( nprocs ); 02009 std::vector< std::vector< EntityHandle > > localBuffs( nprocs ); 02010 std::vector< std::vector< EntityHandle > > remlocalBuffs( nprocs ); 02011 std::vector< std::vector< EntityHandle > > remoteBuffs( nprocs ); 02012 02013 int i; 02014 Range sharedentities; 02015 02016 for( i = 0; i < nprocs; i++ ) 02017 { 02018 // List of shared entities at the coarsest level 02019 sharedentities.clear(); 02020 error = pcomm->get_shared_entities( sharedprocs[i], sharedentities, -1, true );MB_CHK_ERR( error ); 02021 02022 // Get the list shared edges and vertices that are not part of the shared edges 02023 Range allEnts; 02024 error = collect_shared_entities_by_dimension( sharedentities, allEnts );MB_CHK_ERR( error ); 02025 02026 Range V0, E0, F0; 02027 V0 = allEnts.subset_by_dimension( 0 ); 02028 E0 = allEnts.subset_by_dimension( 1 ); 02029 F0 = allEnts.subset_by_dimension( 2 ); 02030 02031 // Step 2A: Prepare msg to be sent: 02032 // 02033 // FList = <F, FC, FE> where F, FC and FE are vectors containing the faces, their 02034 // connectivities and edges. F = <F_0, F_1, F_2, ..., F_L> where 02035 // F_0 is the list of shared faces at the coarsest level, 02036 // F_i are the list of children faces at subsequent levels. 02037 // FC vector contains the connectivities of F_i's and FE vector contains the bounding edges 02038 // of F_i's. 02039 // 02040 // EList = <E, EC> where E and EC are vectors containing the edges and their connectivities. 02041 // E = <E_0, E_1, ..., E_L> where 02042 // E_0 is the list of shared edges at the coarsest level and 02043 // E_i are the list of children edges at subsequent levels. 02044 // The EC vector contains the connectivities of E_i's. 02045 // 02046 // VList = <V> = <V_0, V_1, ...., V_L> where V_0 are shared vertices at the coarsest level 02047 // and V_i are the duplicates in the subsequent levels. 02048 02049 std::vector< EntityHandle > locFList, remFList; 02050 std::vector< EntityHandle > locEList, remEList; 02051 std::vector< EntityHandle > locVList, remVList; 02052 02053 // collect faces 02054 if( !F0.empty() ) 02055 { 02056 error = collect_FList( sharedprocs[i], F0, locFList, remFList );MB_CHK_ERR( error ); 02057 } 02058 02059 // collect edges 02060 if( !E0.empty() ) 02061 { 02062 error = collect_EList( sharedprocs[i], E0, locEList, remEList );MB_CHK_ERR( error ); 02063 } 02064 02065 // collect vertices 02066 if( !V0.empty() ) 02067 { 02068 error = collect_VList( sharedprocs[i], V0, locVList, remVList );MB_CHK_ERR( error ); 02069 } 02070 02071 // Step 2B: Add data to NR local buffer to be sent 02072 std::vector< int > msgsz; 02073 msgsz.push_back( F0.size() ); 02074 msgsz.push_back( locFList.size() ); 02075 msgsz.push_back( E0.size() ); 02076 msgsz.push_back( locEList.size() ); 02077 msgsz.push_back( V0.size() ); 02078 msgsz.push_back( locVList.size() ); 02079 nsharedEntsperproc[i].insert( nsharedEntsperproc[i].end(), msgsz.begin(), msgsz.end() ); 02080 02081 if( !F0.empty() ) 02082 { 02083 localBuffs[i].insert( localBuffs[i].end(), locFList.begin(), locFList.end() ); 02084 remlocalBuffs[i].insert( remlocalBuffs[i].end(), remFList.begin(), remFList.end() ); 02085 } 02086 if( !E0.empty() ) 02087 { 02088 localBuffs[i].insert( localBuffs[i].end(), locEList.begin(), locEList.end() ); 02089 remlocalBuffs[i].insert( remlocalBuffs[i].end(), remEList.begin(), remEList.end() ); 02090 } 02091 if( !V0.empty() ) 02092 { 02093 localBuffs[i].insert( localBuffs[i].end(), locVList.begin(), locVList.end() ); 02094 remlocalBuffs[i].insert( remlocalBuffs[i].end(), remVList.begin(), remVList.end() ); 02095 } 02096 } 02097 02098 // Step 3: Send and receive the remote collection of child ents 02099 error = pcomm->send_recv_entities( sharedprocs, nsharedEntsperproc, remlocalBuffs, remoteBuffs );MB_CHK_ERR( error ); 02100 02101 // Step 5: Resolve shared child entities and update parallel tags 02102 std::multimap< EntityHandle, int > rprocs; 02103 std::multimap< EntityHandle, EntityHandle > rhandles; 02104 02105 error = decipher_remote_handles( sharedprocs, nsharedEntsperproc, localBuffs, remoteBuffs, rprocs, rhandles );MB_CHK_ERR( error ); 02106 02107 // Step 6: Update pcomm tags 02108 error = update_parallel_tags( rprocs, rhandles );MB_CHK_ERR( error ); 02109 02110 return MB_SUCCESS; 02111 } 02112 02113 ErrorCode NestedRefine::collect_shared_entities_by_dimension( Range sharedEnts, Range& allEnts ) 02114 { 02115 ErrorCode error; 02116 02117 Range F0, E0, V0, E0all, V0all; 02118 std::vector< EntityHandle > ents; 02119 02120 F0 = sharedEnts.subset_by_dimension( 2 ); 02121 E0all = sharedEnts.subset_by_dimension( 1 ); 02122 V0all = sharedEnts.subset_by_dimension( 0 ); 02123 02124 if( !F0.empty() ) 02125 { 02126 Range edges, verts; 02127 02128 for( Range::iterator it = F0.begin(); it != F0.end(); it++ ) 02129 { 02130 ents.clear(); 02131 error = ahf->get_adjacencies( *it, 1, ents );MB_CHK_ERR( error ); 02132 std::copy( ents.begin(), ents.end(), range_inserter( edges ) ); 02133 ents.clear(); 02134 error = mbImpl->get_connectivity( &( *it ), 0, ents );MB_CHK_ERR( error ); 02135 std::copy( ents.begin(), ents.end(), range_inserter( verts ) ); 02136 } 02137 02138 E0 = subtract( E0all, edges ); 02139 if( !E0.empty() ) 02140 { 02141 for( Range::iterator it = E0.begin(); it != E0.end(); it++ ) 02142 { 02143 ents.clear(); 02144 error = mbImpl->get_connectivity( &( *it ), 0, ents );MB_CHK_ERR( error ); 02145 std::copy( ents.begin(), ents.end(), range_inserter( verts ) ); 02146 } 02147 } 02148 V0 = subtract( V0all, verts ); 02149 } 02150 else if( !E0all.empty() ) 02151 { 02152 Range verts; 02153 for( Range::iterator it = E0all.begin(); it != E0all.end(); it++ ) 02154 { 02155 ents.clear(); 02156 error = mbImpl->get_connectivity( &( *it ), 1, ents );MB_CHK_ERR( error ); 02157 std::copy( ents.begin(), ents.end(), range_inserter( verts ) ); 02158 } 02159 E0 = E0all; 02160 V0 = subtract( V0all, verts ); 02161 } 02162 else if( !V0all.empty() ) 02163 { 02164 V0 = V0all; 02165 } 02166 else 02167 MB_SET_ERR( MB_FAILURE, "Trying to pack unsupported sub-entities for shared interface entities" ); 02168 02169 if( !F0.empty() ) std::copy( F0.begin(), F0.end(), range_inserter( allEnts ) ); 02170 if( !E0.empty() ) std::copy( E0.begin(), E0.end(), range_inserter( allEnts ) ); 02171 if( !V0.empty() ) std::copy( V0.begin(), V0.end(), range_inserter( allEnts ) ); 02172 02173 return MB_SUCCESS; 02174 } 02175 02176 ErrorCode NestedRefine::collect_FList( int to_proc, 02177 Range faces, 02178 std::vector< EntityHandle >& FList, 02179 std::vector< EntityHandle >& RList ) 02180 { 02181 ErrorCode error; 02182 02183 FList.clear(); 02184 std::vector< EntityHandle > F, FC, FE, lF, lFC, lFE, rF, rFC, rFE; 02185 std::vector< EntityHandle > childEnts, conn, fedges; 02186 02187 for( Range::iterator it = faces.begin(); it != faces.end(); it++ ) 02188 { 02189 EntityHandle face = *it; 02190 conn.clear(); 02191 fedges.clear(); 02192 error = mbImpl->get_connectivity( &face, 1, conn );MB_CHK_ERR( error ); 02193 error = ahf->get_face_edges( *it, fedges );MB_CHK_ERR( error ); 02194 02195 // add local handles 02196 lF.push_back( *it ); 02197 lFC.insert( lFC.end(), conn.begin(), conn.end() ); 02198 lFE.insert( lFE.end(), fedges.begin(), fedges.end() ); 02199 02200 // replace local handles with remote handles on to_proc 02201 EntityHandle rval = 0; 02202 error = pcomm->get_remote_handles( &face, &rval, 1, to_proc );MB_CHK_ERR( error ); 02203 rF.push_back( rval ); 02204 02205 for( int i = 0; i < (int)conn.size(); i++ ) 02206 { 02207 error = pcomm->get_remote_handles( &conn[i], &rval, 1, to_proc );MB_CHK_ERR( error ); 02208 rFC.push_back( rval ); 02209 02210 error = pcomm->get_remote_handles( &fedges[i], &rval, 1, to_proc );MB_CHK_ERR( error ); 02211 rFE.push_back( rval ); 02212 } 02213 } 02214 02215 for( int l = 0; l < nlevels; l++ ) 02216 { 02217 for( Range::iterator it = faces.begin(); it != faces.end(); it++ ) 02218 { 02219 childEnts.clear(); 02220 error = parent_to_child( *it, 0, l + 1, childEnts );MB_CHK_ERR( error ); 02221 02222 for( int i = 0; i < (int)childEnts.size(); i++ ) 02223 { 02224 conn.clear(); 02225 fedges.clear(); 02226 error = mbImpl->get_connectivity( &childEnts[i], 1, conn );MB_CHK_ERR( error ); 02227 error = ahf->get_face_edges( childEnts[i], fedges );MB_CHK_ERR( error ); 02228 02229 F.push_back( childEnts[i] ); 02230 FC.insert( FC.end(), conn.begin(), conn.end() ); 02231 FE.insert( FE.end(), fedges.begin(), fedges.end() ); 02232 } 02233 } 02234 } 02235 02236 FList.insert( FList.end(), lF.begin(), lF.end() ); 02237 FList.insert( FList.end(), F.begin(), F.end() ); 02238 FList.insert( FList.end(), lFC.begin(), lFC.end() ); 02239 FList.insert( FList.end(), FC.begin(), FC.end() ); 02240 FList.insert( FList.end(), lFE.begin(), lFE.end() ); 02241 FList.insert( FList.end(), FE.begin(), FE.end() ); 02242 02243 RList.insert( RList.end(), rF.begin(), rF.end() ); 02244 RList.insert( RList.end(), F.begin(), F.end() ); 02245 RList.insert( RList.end(), rFC.begin(), rFC.end() ); 02246 RList.insert( RList.end(), FC.begin(), FC.end() ); 02247 RList.insert( RList.end(), rFE.begin(), rFE.end() ); 02248 RList.insert( RList.end(), FE.begin(), FE.end() ); 02249 02250 return MB_SUCCESS; 02251 } 02252 02253 ErrorCode NestedRefine::collect_EList( int to_proc, 02254 Range edges, 02255 std::vector< EntityHandle >& EList, 02256 std::vector< EntityHandle >& RList ) 02257 { 02258 ErrorCode error; 02259 EList.clear(); 02260 std::vector< EntityHandle > E, EC, lE, lEC, rE, rEC; 02261 std::vector< EntityHandle > childEnts, conn; 02262 02263 // Add the edges and their connectivities at the coarsest level first. 02264 for( Range::iterator it = edges.begin(); it != edges.end(); it++ ) 02265 { 02266 EntityHandle edg = *it; 02267 conn.clear(); 02268 error = mbImpl->get_connectivity( &edg, 1, conn );MB_CHK_ERR( error ); 02269 02270 // add local handles 02271 lE.push_back( edg ); 02272 lEC.insert( lEC.end(), conn.begin(), conn.end() ); 02273 02274 // replace local handles with remote handle on to_proc 02275 EntityHandle rval = 0; 02276 error = pcomm->get_remote_handles( &edg, &rval, 1, to_proc );MB_CHK_ERR( error ); 02277 rE.push_back( rval ); 02278 error = pcomm->get_remote_handles( &conn[0], &rval, 1, to_proc );MB_CHK_ERR( error ); 02279 rEC.push_back( rval ); 02280 error = pcomm->get_remote_handles( &conn[1], &rval, 1, to_proc );MB_CHK_ERR( error ); 02281 rEC.push_back( rval ); 02282 } 02283 02284 // Add the edges and their connectivities at subsequent levels. 02285 for( int l = 0; l < nlevels; l++ ) 02286 { 02287 for( Range::iterator it = edges.begin(); it != edges.end(); it++ ) 02288 { 02289 childEnts.clear(); 02290 error = parent_to_child( *it, 0, l + 1, childEnts );MB_CHK_ERR( error ); 02291 02292 for( int i = 0; i < (int)childEnts.size(); i++ ) 02293 { 02294 conn.clear(); 02295 error = mbImpl->get_connectivity( &childEnts[i], 1, conn );MB_CHK_ERR( error ); 02296 E.push_back( childEnts[i] ); 02297 EC.insert( EC.end(), conn.begin(), conn.end() ); 02298 } 02299 } 02300 } 02301 02302 EList.insert( EList.end(), lE.begin(), lE.end() ); 02303 EList.insert( EList.end(), E.begin(), E.end() ); 02304 EList.insert( EList.end(), lEC.begin(), lEC.end() ); 02305 EList.insert( EList.end(), EC.begin(), EC.end() ); 02306 02307 RList.insert( RList.end(), rE.begin(), rE.end() ); 02308 RList.insert( RList.end(), E.begin(), E.end() ); 02309 RList.insert( RList.end(), rEC.begin(), rEC.end() ); 02310 RList.insert( RList.end(), EC.begin(), EC.end() ); 02311 02312 return MB_SUCCESS; 02313 } 02314 02315 ErrorCode NestedRefine::collect_VList( int to_proc, 02316 Range verts, 02317 std::vector< EntityHandle >& VList, 02318 std::vector< EntityHandle >& RList ) 02319 { 02320 ErrorCode error; 02321 std::vector< EntityHandle > V, lV, rV; 02322 VList.clear(); 02323 02324 // Add the vertices at the coarsest level first. 02325 for( Range::iterator it = verts.begin(); it != verts.end(); it++ ) 02326 { 02327 EntityHandle v = *it; 02328 02329 lV.push_back( v ); 02330 EntityHandle rval = 0; 02331 error = pcomm->get_remote_handles( &v, &rval, 1, to_proc );MB_CHK_ERR( error ); 02332 02333 rV.push_back( rval ); 02334 } 02335 02336 // Add the vertices at the subsequent levels . 02337 for( int l = 0; l < nlevels; l++ ) 02338 { 02339 for( Range::iterator it = verts.begin(); it != verts.end(); it++ ) 02340 { 02341 EntityHandle dupvert = 0; 02342 error = get_vertex_duplicates( *it, l + 1, dupvert );MB_CHK_ERR( error ); 02343 V.push_back( dupvert ); 02344 } 02345 } 02346 02347 // local vertex handles at the coarsest level 02348 VList.insert( VList.end(), lV.begin(), lV.end() ); 02349 VList.insert( VList.end(), V.begin(), V.end() ); 02350 02351 // remote vertex handles at the coarsest level 02352 RList.insert( RList.end(), rV.begin(), rV.end() ); 02353 RList.insert( RList.end(), V.begin(), V.end() ); 02354 02355 return MB_SUCCESS; 02356 } 02357 02358 ErrorCode NestedRefine::decipher_remote_handles( std::vector< int >& sharedprocs, 02359 std::vector< std::vector< int > >& auxinfo, 02360 std::vector< std::vector< EntityHandle > >& localbuffers, 02361 std::vector< std::vector< EntityHandle > >& remotebuffers, 02362 std::multimap< EntityHandle, int >& remProcs, 02363 std::multimap< EntityHandle, EntityHandle >& remHandles ) 02364 { 02365 ErrorCode error; 02366 02367 int i; 02368 int nprocs = sharedprocs.size(); 02369 02370 for( i = 0; i < nprocs; i++ ) 02371 { 02372 std::vector< int > msgsz; 02373 for( int j = 0; j < (int)auxinfo[i].size(); j++ ) 02374 { 02375 msgsz.push_back( auxinfo[i][j] ); 02376 } 02377 02378 if( msgsz[0] != 0 ) // Faces 02379 { 02380 // Get the local and remote face handles from the buffers 02381 std::vector< EntityHandle > LFList, RFList; 02382 LFList.insert( LFList.end(), localbuffers[i].begin(), localbuffers[i].begin() + msgsz[1] ); 02383 RFList.insert( RFList.end(), remotebuffers[i].begin(), remotebuffers[i].begin() + msgsz[1] ); 02384 02385 error = decipher_remote_handles_face( sharedprocs[i], msgsz[0], LFList, RFList, remProcs, remHandles );MB_CHK_ERR( error ); 02386 02387 if( msgsz[2] != 0 ) // Edges 02388 { 02389 std::vector< EntityHandle > LEList, REList; 02390 LEList.insert( LEList.end(), localbuffers[i].begin() + msgsz[1] + 1, 02391 localbuffers[i].begin() + msgsz[1] + msgsz[3] ); 02392 REList.insert( REList.end(), remotebuffers[i].begin() + msgsz[1] + 1, 02393 remotebuffers[i].begin() + msgsz[1] + msgsz[3] ); 02394 02395 error = decipher_remote_handles_edge( sharedprocs[i], msgsz[2], LEList, REList, remProcs, remHandles );MB_CHK_ERR( error ); 02396 02397 if( msgsz[4] != 0 ) // Vertices 02398 { 02399 // Get the local and remote face handles from the buffers 02400 std::vector< EntityHandle > LVList, RVList; 02401 LVList.insert( LVList.end(), localbuffers[i].begin() + msgsz[1] + msgsz[3] + 1, 02402 localbuffers[i].begin() + msgsz[1] + msgsz[3] + msgsz[5] ); 02403 RVList.insert( RVList.end(), remotebuffers[i].begin() + msgsz[1] + msgsz[3] + 1, 02404 remotebuffers[i].begin() + msgsz[1] + msgsz[3] + msgsz[5] ); 02405 02406 error = decipher_remote_handles_vertex( sharedprocs[i], msgsz[4], LVList, RVList, remProcs, 02407 remHandles );MB_CHK_ERR( error ); 02408 } 02409 } 02410 else if( msgsz[4] != 0 ) // Vertices 02411 { 02412 // Get the local and remote face handles from the buffers 02413 std::vector< EntityHandle > LVList, RVList; 02414 LVList.insert( LVList.end(), localbuffers[i].begin() + msgsz[1] + 1, 02415 localbuffers[i].begin() + msgsz[1] + msgsz[5] ); 02416 RVList.insert( RVList.end(), remotebuffers[i].begin() + msgsz[1] + 1, 02417 remotebuffers[i].begin() + msgsz[1] + msgsz[5] ); 02418 02419 error = 02420 decipher_remote_handles_vertex( sharedprocs[i], msgsz[4], LVList, RVList, remProcs, remHandles );MB_CHK_ERR( error ); 02421 } 02422 } 02423 02424 else if( msgsz[2] != 0 ) // Edges 02425 { 02426 // Get the local and remote face handles from the buffers 02427 std::vector< EntityHandle > LEList, REList; 02428 LEList.insert( LEList.end(), localbuffers[i].begin(), localbuffers[i].begin() + msgsz[3] ); 02429 REList.insert( REList.end(), remotebuffers[i].begin(), remotebuffers[i].begin() + msgsz[3] ); 02430 02431 error = decipher_remote_handles_edge( sharedprocs[i], msgsz[2], LEList, REList, remProcs, remHandles );MB_CHK_ERR( error ); 02432 02433 if( msgsz[4] != 0 ) // Vertices 02434 { 02435 // Get the local and remote face handles from the buffers 02436 std::vector< EntityHandle > LVList, RVList; 02437 LVList.insert( LVList.end(), localbuffers[i].begin() + msgsz[3] + 1, 02438 localbuffers[i].begin() + msgsz[3] + msgsz[5] ); 02439 RVList.insert( RVList.end(), remotebuffers[i].begin() + msgsz[3] + 1, 02440 remotebuffers[i].begin() + msgsz[3] + msgsz[5] ); 02441 02442 error = 02443 decipher_remote_handles_vertex( sharedprocs[i], msgsz[4], LVList, RVList, remProcs, remHandles );MB_CHK_ERR( error ); 02444 } 02445 } 02446 02447 else if( msgsz[4] != 0 ) // Vertices 02448 { 02449 // Get the local and remote face handles from the buffers 02450 std::vector< EntityHandle > LVList, RVList; 02451 LVList.insert( LVList.end(), localbuffers[i].begin(), localbuffers[i].end() ); 02452 RVList.insert( RVList.end(), remotebuffers[i].begin(), remotebuffers[i].end() ); 02453 02454 error = decipher_remote_handles_vertex( sharedprocs[i], msgsz[4], LVList, RVList, remProcs, remHandles );MB_CHK_ERR( error ); 02455 } 02456 else 02457 MB_SET_ERR( MB_FAILURE, "Trying to decipher entities other than verts, edges, faces" ); 02458 } 02459 02460 return MB_SUCCESS; 02461 } 02462 02463 ErrorCode NestedRefine::decipher_remote_handles_face( int shared_proc, 02464 int numfaces, 02465 std::vector< EntityHandle >& localFaceList, 02466 std::vector< EntityHandle >& remFaceList, 02467 std::multimap< EntityHandle, int >& remProcs, 02468 std::multimap< EntityHandle, EntityHandle >& remHandles ) 02469 { 02470 ErrorCode error; 02471 02472 for( int i = 0; i < numfaces; i++ ) 02473 { 02474 // find local and remote handles of the coarsest face 02475 EntityHandle Lface = localFaceList[i]; 02476 int Rface_idx = 02477 ( std::find( remFaceList.begin(), remFaceList.begin() + numfaces - 1, Lface ) ) - remFaceList.begin(); 02478 02479 // get connectivities of the local and remote coarsest faces 02480 std::vector< EntityHandle > Lface_conn, Rface_conn; 02481 error = get_data_from_buff( 2, 1, 0, i, numfaces, localFaceList, Lface_conn );MB_CHK_ERR( error ); 02482 error = get_data_from_buff( 2, 1, 0, Rface_idx, numfaces, remFaceList, Rface_conn );MB_CHK_ERR( error ); 02483 02484 // find the combination difference between local and remote coarsest face 02485 std::vector< int > cmap; 02486 int comb = 0; 02487 int nvF = (int)Lface_conn.size(); 02488 error = reorder_indices( &Lface_conn[0], &Rface_conn[0], nvF, &cmap[0], comb );MB_CHK_ERR( error ); 02489 02490 // go into loop over all levels 02491 std::vector< EntityHandle > lchildents, lparents; 02492 std::vector< EntityHandle > lcents, rcents; 02493 int lidx, ridx; 02494 02495 for( int l = 0; l < nlevels; l++ ) 02496 { 02497 lchildents.clear(); 02498 lparents.clear(); 02499 lcents.clear(); 02500 rcents.clear(); 02501 02502 // obtain children at the current level 02503 error = get_data_from_buff( 2, 0, l + 1, i, numfaces, localFaceList, lchildents );MB_CHK_ERR( error ); 02504 02505 // obtain parents at the previous level 02506 if( l == 0 ) 02507 { 02508 lparents.push_back( Lface ); 02509 } 02510 else 02511 { 02512 error = get_data_from_buff( 2, 0, l, i, numfaces, localFaceList, lparents );MB_CHK_ERR( error ); 02513 } 02514 02515 //#children at the previous level and the current level 02516 EntityType ftype = mbImpl->type_from_handle( Lface ); 02517 int d = get_index_from_degree( level_dsequence[l] ); 02518 int nch = refTemplates[ftype - 1][d].total_new_ents; 02519 std::vector< int > fmap; 02520 error = reorder_indices( level_dsequence[l], nvF, comb, &fmap[0] );MB_CHK_ERR( error ); 02521 02522 // loop over all the lparents 02523 for( int j = 0; j < (int)lparents.size(); j++ ) 02524 { 02525 // list local childrent at the current level 02526 lidx = std::find( localFaceList.begin(), localFaceList.end(), lparents[j] ) - localFaceList.begin(); 02527 error = get_data_from_buff( 2, 0, l + 1, lidx, numfaces, localFaceList, lcents );MB_CHK_ERR( error ); 02528 02529 // find the corresponding remote of lparent and its children 02530 EntityHandle rparent = 0; 02531 error = check_for_parallelinfo( lparents[j], shared_proc, remHandles, remProcs, rparent );MB_CHK_ERR( error ); 02532 ridx = std::find( remFaceList.begin(), remFaceList.end(), rparent ) - remFaceList.begin(); 02533 error = get_data_from_buff( 2, 0, l + 1, ridx, numfaces, remFaceList, rcents );MB_CHK_ERR( error ); 02534 02535 // match up local face with remote handles according to cmap 02536 std::vector< EntityHandle > lconn, rconn, ledg, redg; 02537 for( int k = 0; k < nch; k++ ) 02538 { 02539 lconn.clear(); 02540 rconn.clear(); 02541 ledg.clear(); 02542 redg.clear(); 02543 02544 // matching the local children face handles with their remotes 02545 bool found = check_for_parallelinfo( lcents[k], shared_proc, remProcs ); 02546 if( !found ) 02547 { 02548 remProcs.insert( std::pair< EntityHandle, int >( lcents[k], shared_proc ) ); 02549 remHandles.insert( std::pair< EntityHandle, EntityHandle >( lcents[k], rcents[fmap[k]] ) ); 02550 } 02551 02552 // find indices of the matched child face 02553 lidx = std::find( localFaceList.begin(), localFaceList.end(), lcents[k] ) - localFaceList.begin(); 02554 ridx = std::find( remFaceList.begin(), remFaceList.end(), rcents[fmap[k]] ) - remFaceList.begin(); 02555 02556 // find bounding edges and connectivity of the matched child face 02557 error = get_data_from_buff( 2, 2, l + 1, lidx, numfaces, localFaceList, ledg );MB_CHK_ERR( error ); 02558 error = get_data_from_buff( 2, 1, l + 1, lidx, numfaces, localFaceList, lconn );MB_CHK_ERR( error ); 02559 error = get_data_from_buff( 2, 2, l + 1, ridx, numfaces, remFaceList, redg );MB_CHK_ERR( error ); 02560 error = get_data_from_buff( 2, 1, l + 1, ridx, numfaces, remFaceList, rconn );MB_CHK_ERR( error ); 02561 02562 // now match the handles of the bounding edges and the vertices using 02563 // combination difference 02564 for( int m = 0; m < (int)ledg.size(); m++ ) 02565 { 02566 found = check_for_parallelinfo( ledg[m], shared_proc, remProcs ); 02567 02568 if( !found ) 02569 { 02570 remProcs.insert( std::pair< EntityHandle, int >( ledg[m], shared_proc ) ); 02571 remHandles.insert( std::pair< EntityHandle, EntityHandle >( ledg[m], redg[cmap[m]] ) ); 02572 } 02573 02574 found = check_for_parallelinfo( lconn[m], shared_proc, remProcs ); 02575 02576 if( !found ) 02577 { 02578 remProcs.insert( std::pair< EntityHandle, int >( lconn[m], shared_proc ) ); 02579 remHandles.insert( std::pair< EntityHandle, EntityHandle >( lconn[m], rconn[cmap[m]] ) ); 02580 } 02581 } 02582 } 02583 } 02584 } 02585 } 02586 02587 return MB_SUCCESS; 02588 } 02589 02590 ErrorCode NestedRefine::decipher_remote_handles_edge( int shared_proc, 02591 int numedges, 02592 std::vector< EntityHandle >& localEdgeList, 02593 std::vector< EntityHandle >& remEdgeList, 02594 std::multimap< EntityHandle, int >& remProcs, 02595 std::multimap< EntityHandle, EntityHandle >& remHandles ) 02596 { 02597 ErrorCode error; 02598 02599 for( int i = 0; i < numedges; i++ ) 02600 { 02601 EntityHandle Ledge = localEdgeList[i]; 02602 int Redge_idx = 02603 ( std::find( remEdgeList.begin(), remEdgeList.begin() + numedges - 1, Ledge ) ) - remEdgeList.begin(); 02604 02605 std::vector< EntityHandle > Ledge_conn, Redge_conn; 02606 error = get_data_from_buff( 1, 1, 0, i, numedges, localEdgeList, Ledge_conn );MB_CHK_ERR( error ); 02607 error = get_data_from_buff( 1, 1, 0, Redge_idx, numedges, remEdgeList, Redge_conn );MB_CHK_ERR( error ); 02608 02609 bool orient = true; 02610 if( ( Ledge_conn[0] == Redge_conn[1] ) && ( Ledge_conn[1] == Redge_conn[0] ) ) orient = false; 02611 02612 if( orient ) assert( ( Ledge_conn[0] == Redge_conn[0] ) && ( Ledge_conn[1] == Redge_conn[1] ) ); 02613 02614 std::vector< EntityHandle > lchildEdgs, rchildEdgs, lconn, rconn; 02615 for( int l = 0; l < nlevels; l++ ) 02616 { 02617 lchildEdgs.clear(); 02618 rchildEdgs.clear(); 02619 error = get_data_from_buff( 1, 0, l + 1, i, numedges, localEdgeList, lchildEdgs );MB_CHK_ERR( error ); 02620 error = get_data_from_buff( 1, 0, l + 1, Redge_idx, numedges, remEdgeList, rchildEdgs );MB_CHK_ERR( error ); 02621 02622 int nchd = lchildEdgs.size(); 02623 if( orient ) 02624 { 02625 for( int j = 0; j < nchd; j++ ) 02626 { 02627 // match entityhandles of child edges 02628 bool found = check_for_parallelinfo( lchildEdgs[j], shared_proc, remProcs ); 02629 if( !found ) 02630 { 02631 remProcs.insert( std::pair< EntityHandle, int >( lchildEdgs[j], shared_proc ) ); 02632 remHandles.insert( std::pair< EntityHandle, EntityHandle >( lchildEdgs[j], rchildEdgs[j] ) ); 02633 } 02634 02635 // match entityhandles of child vertices 02636 lconn.clear(); 02637 rconn.clear(); 02638 02639 int lidx = 02640 std::find( localEdgeList.begin(), localEdgeList.end(), lchildEdgs[j] ) - localEdgeList.begin(); 02641 int ridx = std::find( remEdgeList.begin(), remEdgeList.end(), rchildEdgs[j] ) - remEdgeList.begin(); 02642 02643 error = get_data_from_buff( 1, 1, l + 1, lidx, numedges, localEdgeList, lconn );MB_CHK_ERR( error ); 02644 error = get_data_from_buff( 1, 1, l + 1, ridx, numedges, remEdgeList, rconn );MB_CHK_ERR( error ); 02645 02646 found = check_for_parallelinfo( lconn[0], shared_proc, remProcs ); 02647 if( !found ) 02648 { 02649 remProcs.insert( std::pair< EntityHandle, int >( lconn[0], shared_proc ) ); 02650 remHandles.insert( std::pair< EntityHandle, EntityHandle >( lconn[0], rconn[0] ) ); 02651 } 02652 found = check_for_parallelinfo( lconn[1], shared_proc, remProcs ); 02653 if( !found ) 02654 { 02655 remProcs.insert( std::pair< EntityHandle, int >( lconn[1], shared_proc ) ); 02656 remHandles.insert( std::pair< EntityHandle, EntityHandle >( lconn[1], rconn[0] ) ); 02657 } 02658 } 02659 } 02660 02661 else 02662 { 02663 for( int j = 0; j < nchd; j++ ) 02664 { 02665 // match entityhandles of child edges 02666 bool found = check_for_parallelinfo( lchildEdgs[j], shared_proc, remProcs ); 02667 02668 if( !found ) 02669 { 02670 remProcs.insert( std::pair< EntityHandle, int >( lchildEdgs[j], shared_proc ) ); 02671 remHandles.insert( 02672 std::pair< EntityHandle, EntityHandle >( lchildEdgs[j], rchildEdgs[nchd - j - 1] ) ); 02673 } 02674 02675 // match entityhandles of child vertices 02676 lconn.clear(); 02677 rconn.clear(); 02678 02679 int lidx = 02680 std::find( localEdgeList.begin(), localEdgeList.end(), lchildEdgs[j] ) - localEdgeList.begin(); 02681 int ridx = std::find( remEdgeList.begin(), remEdgeList.end(), rchildEdgs[nchd - j - 1] ) - 02682 remEdgeList.begin(); 02683 02684 error = get_data_from_buff( 1, 1, l + 1, lidx, numedges, localEdgeList, lconn );MB_CHK_ERR( error ); 02685 error = get_data_from_buff( 1, 1, l + 1, ridx, numedges, remEdgeList, rconn );MB_CHK_ERR( error ); 02686 found = check_for_parallelinfo( lconn[0], shared_proc, remProcs ); 02687 02688 if( !found ) 02689 { 02690 remProcs.insert( std::pair< EntityHandle, int >( lconn[0], shared_proc ) ); 02691 remHandles.insert( std::pair< EntityHandle, EntityHandle >( lconn[0], rconn[1] ) ); 02692 } 02693 02694 found = check_for_parallelinfo( lconn[1], shared_proc, remProcs ); 02695 if( !found ) 02696 { 02697 remProcs.insert( std::pair< EntityHandle, int >( lconn[1], shared_proc ) ); 02698 remHandles.insert( std::pair< EntityHandle, EntityHandle >( lconn[1], rconn[1] ) ); 02699 } 02700 } 02701 } 02702 } 02703 } 02704 02705 return MB_SUCCESS; 02706 } 02707 02708 ErrorCode NestedRefine::decipher_remote_handles_vertex( int shared_proc, 02709 int numverts, 02710 std::vector< EntityHandle >& localVertexList, 02711 std::vector< EntityHandle >& remVertexList, 02712 std::multimap< EntityHandle, int >& remProcs, 02713 std::multimap< EntityHandle, EntityHandle >& remHandles ) 02714 { 02715 // LVList = <V> where V = <LV0, LV1, ..,LVL> 02716 // RVList = <V> where V = <LV0', RV1, ..,RVL>, LV0' is the local handles of coarsest vertices 02717 // but in the order in which they appear on the remote/shared proc 02718 02719 ErrorCode error; 02720 02721 for( int i = 0; i < numverts; i++ ) 02722 { 02723 EntityHandle v = localVertexList[i]; 02724 int Rvert_idx = 02725 ( std::find( remVertexList.begin(), remVertexList.begin() + numverts - 1, v ) ) - remVertexList.begin(); 02726 02727 std::vector< EntityHandle > lverts, rverts; 02728 for( int l = 0; l < nlevels; l++ ) 02729 { 02730 error = get_data_from_buff( 0, 0, l + 1, i, numverts, localVertexList, lverts );MB_CHK_ERR( error ); 02731 error = get_data_from_buff( 0, 0, l + 1, Rvert_idx, numverts, remVertexList, rverts );MB_CHK_ERR( error ); 02732 02733 bool found = check_for_parallelinfo( lverts[0], shared_proc, remProcs ); 02734 if( !found ) 02735 { 02736 remProcs.insert( std::pair< EntityHandle, int >( lverts[0], shared_proc ) ); 02737 remHandles.insert( std::pair< EntityHandle, EntityHandle >( lverts[0], rverts[0] ) ); 02738 } 02739 } 02740 } 02741 02742 return MB_SUCCESS; 02743 } 02744 02745 ErrorCode NestedRefine::update_parallel_tags( std::multimap< EntityHandle, int >& remProcs, 02746 std::multimap< EntityHandle, EntityHandle >& remHandles ) 02747 { 02748 ErrorCode error; 02749 02750 std::vector< int > rprocs; 02751 std::vector< EntityHandle > rhandles; 02752 02753 std::multimap< EntityHandle, int >::iterator it; 02754 std::pair< std::multimap< EntityHandle, int >::iterator, std::multimap< EntityHandle, int >::iterator > it_procs; 02755 std::pair< std::multimap< EntityHandle, EntityHandle >::iterator, 02756 std::multimap< EntityHandle, EntityHandle >::iterator > 02757 it_handles; 02758 02759 it = remProcs.begin(); 02760 while( it != remProcs.end() ) 02761 { 02762 rprocs.clear(); 02763 rhandles.clear(); 02764 02765 EntityHandle entity = it->first; 02766 it_procs = remProcs.equal_range( entity ); 02767 it_handles = remHandles.equal_range( entity ); 02768 02769 for( std::multimap< EntityHandle, int >::iterator pit = it_procs.first; pit != it_procs.second; pit++ ) 02770 rprocs.push_back( pit->second ); 02771 for( std::multimap< EntityHandle, EntityHandle >::iterator pit = it_handles.first; pit != it_handles.second; 02772 pit++ ) 02773 rhandles.push_back( pit->second ); 02774 02775 error = pcomm->update_remote_data( entity, rprocs, rhandles );MB_CHK_ERR( error ); 02776 02777 it = remProcs.upper_bound( it->first ); 02778 } 02779 02780 return MB_SUCCESS; 02781 } 02782 02783 ErrorCode NestedRefine::get_data_from_buff( int listtype, 02784 int datatype, 02785 int level, 02786 int entity_index, 02787 int nentities, 02788 std::vector< EntityHandle >& buffer, 02789 std::vector< EntityHandle >& data ) 02790 { 02791 /** 02792 * listtype = 2, 1, 0 for FList (faces), EList (edge) and VList (vertices), respectively 02793 * datatype = 0(entityhandles of entities at level 0 and their children upto nlevels, in the 02794 *case of vertices its the duplicate vertices at subsequent levels), = 1(connectivity for the 02795 *above), = 2(subentities, only case is edges from FList) entity_index = integer index of the 02796 *entity in the buffer nentities = number of entities at the coarsest level i.e., |F0| or |E0| 02797 *or |V0| 02798 * 02799 * Two types of queries: 02800 * 1) Given an entity, find its children at a particular level. 02801 * 2) Given any entity at any level , find its connectivity (or bounding edges) 02802 * 02803 **/ 02804 02805 data.clear(); 02806 02807 if( listtype == 2 ) // FList 02808 { 02809 // FList = <F, FC, FE> where F = <F0, F1, ..,FL>, FC = <FC0, FC1, .., FCL> and FE = <FE0, 02810 // FE1, .., FEL> 02811 if( datatype == 0 ) // requesting child entities 02812 { 02813 EntityType ftype = mbImpl->type_from_handle( buffer[0] ); 02814 02815 int start, end, toadd, prev; 02816 start = end = entity_index; 02817 toadd = prev = nentities; 02818 for( int i = 0; i < level; i++ ) 02819 { 02820 int d = get_index_from_degree( level_dsequence[i] ); 02821 int nch = refTemplates[ftype - 1][d].total_new_ents; 02822 start = start * nch; 02823 end = end * nch + nch - 1; 02824 if( i < level - 1 ) 02825 { 02826 prev = prev * nch; 02827 toadd += prev; 02828 } 02829 } 02830 02831 start += toadd; 02832 end += toadd; 02833 02834 int num_child = end - start + 1; 02835 data.reserve( num_child ); 02836 02837 for( int i = start; i <= end; i++ ) 02838 { 02839 EntityHandle child = buffer[i]; 02840 data.push_back( child ); 02841 } 02842 } 02843 else if( datatype == 1 ) // requesting connectivity of an entity 02844 { 02845 EntityType ftype = mbImpl->type_from_handle( buffer[0] ); 02846 int nepf = ahf->lConnMap2D[ftype - 2].num_verts_in_face; 02847 02848 int toadd = nentities, prev = nentities; 02849 for( int i = 0; i < nlevels; i++ ) 02850 { 02851 int d = get_index_from_degree( level_dsequence[i] ); 02852 int nch = refTemplates[ftype - 1][d].total_new_ents; 02853 prev = prev * nch; 02854 toadd += prev; 02855 } 02856 02857 for( int i = 0; i < nepf; i++ ) 02858 data.push_back( buffer[toadd + nepf * entity_index + i] ); 02859 } 02860 else if( datatype == 2 ) // requesting bounding edges of an entity 02861 { 02862 EntityType ftype = mbImpl->type_from_handle( buffer[0] ); 02863 int nepf = ahf->lConnMap2D[ftype - 2].num_verts_in_face; 02864 02865 int toadd = nentities, prev = nentities; 02866 for( int i = 0; i < nlevels; i++ ) 02867 { 02868 int d = get_index_from_degree( level_dsequence[i] ); 02869 int nch = refTemplates[ftype - 1][d].total_new_ents; 02870 prev = prev * nch; 02871 toadd += prev; 02872 } 02873 toadd += toadd * nepf; 02874 02875 for( int i = 0; i < nepf; i++ ) 02876 data.push_back( buffer[toadd + nepf * entity_index + i] ); 02877 } 02878 else 02879 MB_SET_ERR( MB_FAILURE, "Requesting invalid info from buffer for faces" ); 02880 } 02881 else if( listtype == 1 ) // EList 02882 { 02883 // EList = <E, EC> where E = <E0, E1, ..,EL> and EC = <EC0, EC1, .., ECL> 02884 if( datatype == 0 ) // requesting child entities 02885 { 02886 int start, end, toadd, prev; 02887 start = end = entity_index; 02888 toadd = prev = nentities; 02889 for( int i = 0; i < level; i++ ) 02890 { 02891 int d = get_index_from_degree( level_dsequence[i] ); 02892 int nch = refTemplates[MBEDGE - 1][d].total_new_ents; 02893 start = start * nch; 02894 end = end * nch + nch - 1; 02895 02896 if( i < level - 1 ) 02897 { 02898 prev = prev * nch; 02899 toadd += prev; 02900 } 02901 } 02902 02903 start += toadd; 02904 end += toadd; 02905 02906 int num_child = end - start + 1; 02907 data.reserve( num_child ); 02908 02909 for( int i = start; i <= end; i++ ) 02910 { 02911 EntityHandle child = buffer[i]; 02912 data.push_back( child ); 02913 } 02914 } 02915 else if( datatype == 1 ) // requesting connectivities of child entities 02916 { 02917 int toadd = nentities, prev = nentities; 02918 for( int i = 0; i < nlevels; i++ ) 02919 { 02920 int d = get_index_from_degree( level_dsequence[i] ); 02921 int nch = refTemplates[MBEDGE - 1][d].total_new_ents; 02922 prev = prev * nch; 02923 toadd += prev; 02924 } 02925 02926 data.push_back( buffer[toadd + 2 * entity_index] ); 02927 data.push_back( buffer[toadd + 2 * entity_index + 1] ); 02928 } 02929 else 02930 MB_SET_ERR( MB_FAILURE, "Requesting invalid info from buffer for edges" ); 02931 } 02932 else if( listtype == 0 ) // VList 02933 { 02934 // VList = <V> where V = <V0, V1, ..,VL> 02935 if( datatype == 0 ) 02936 { 02937 int idx = level * nentities + entity_index; 02938 data.push_back( buffer[idx] ); 02939 } 02940 else 02941 MB_SET_ERR( MB_FAILURE, "Requesting invalid info from buffer for vertices" ); 02942 } 02943 else 02944 MB_SET_ERR( MB_FAILURE, "Requesting invalid info from buffer" ); 02945 02946 return MB_SUCCESS; 02947 } 02948 02949 bool NestedRefine::check_for_parallelinfo( EntityHandle entity, int proc, std::multimap< EntityHandle, int >& remProcs ) 02950 { 02951 bool found = false; 02952 02953 std::pair< std::multimap< EntityHandle, int >::iterator, std::multimap< EntityHandle, int >::iterator > it_hes; 02954 it_hes = remProcs.equal_range( entity ); 02955 02956 for( std::multimap< EntityHandle, int >::iterator it = it_hes.first; it != it_hes.second; ++it ) 02957 { 02958 if( it->second == proc ) 02959 { 02960 found = true; 02961 break; 02962 } 02963 } 02964 02965 return found; 02966 } 02967 02968 ErrorCode NestedRefine::check_for_parallelinfo( EntityHandle entity, 02969 int proc, 02970 std::multimap< EntityHandle, EntityHandle >& remHandles, 02971 std::multimap< EntityHandle, int >& remProcs, 02972 EntityHandle& rhandle ) 02973 { 02974 // shared procs for given entity 02975 std::pair< std::multimap< EntityHandle, int >::iterator, std::multimap< EntityHandle, int >::iterator > it_ps; 02976 it_ps = remProcs.equal_range( entity ); 02977 02978 // shared remote handles for given entity 02979 std::pair< std::multimap< EntityHandle, EntityHandle >::iterator, 02980 std::multimap< EntityHandle, EntityHandle >::iterator > 02981 it_hs; 02982 it_hs = remHandles.equal_range( entity ); 02983 02984 std::multimap< EntityHandle, int >::iterator itp; 02985 std::multimap< EntityHandle, EntityHandle >::iterator ith; 02986 02987 for( itp = it_ps.first, ith = it_hs.first; itp != it_ps.second; ++itp, ++ith ) 02988 { 02989 if( itp->second == proc ) 02990 { 02991 rhandle = ith->second; 02992 break; 02993 } 02994 } 02995 02996 return MB_SUCCESS; 02997 } 02998 02999 #endif 03000 03001 /********************************** 03002 * Update AHF maps * 03003 * ********************************/ 03004 03005 ErrorCode NestedRefine::update_local_ahf( int deg, 03006 EntityType type, 03007 int pat_id, 03008 EntityHandle* vbuffer, 03009 EntityHandle* ent_buffer, 03010 int etotal ) 03011 { 03012 ErrorCode error; 03013 int nhf = 0, nv = 0, total_new_verts = 0; 03014 int d = get_index_from_degree( deg ); 03015 03016 // Get the number of half-facets 03017 if( type == MBEDGE ) 03018 { 03019 nhf = 2; 03020 nv = 2; 03021 total_new_verts = refTemplates[0][d].total_new_verts; 03022 } 03023 else if( type == MBTRI || type == MBQUAD ) 03024 { 03025 nhf = ahf->lConnMap2D[type - 2].num_verts_in_face; 03026 nv = nhf; 03027 total_new_verts = refTemplates[pat_id][d].total_new_verts; 03028 } 03029 else if( type == MBTET || type == MBHEX ) 03030 { 03031 int index = ahf->get_index_in_lmap( *_incells.begin() ); 03032 nhf = ahf->lConnMap3D[index].num_faces_in_cell; 03033 nv = ahf->lConnMap3D[index].num_verts_in_cell; 03034 total_new_verts = refTemplates[pat_id][d].total_new_verts; 03035 } 03036 03037 std::vector< EntityHandle > ent; 03038 std::vector< int > lid; 03039 03040 // Update the vertex to half-facet map 03041 for( int i = 0; i < total_new_verts; i++ ) 03042 { 03043 ent.clear(); 03044 lid.clear(); 03045 EntityHandle vid = vbuffer[i + nv]; 03046 error = ahf->get_incident_map( type, vid, ent, lid );MB_CHK_ERR( error ); 03047 03048 if( ent[0] ) continue; 03049 03050 int id = refTemplates[pat_id][d].v2hf[i + nv][0] - 1; 03051 ent[0] = ent_buffer[id]; 03052 lid[0] = refTemplates[pat_id][d].v2hf[i + nv][1]; 03053 03054 error = ahf->set_incident_map( type, vid, ent, lid );MB_CHK_ERR( error ); 03055 } 03056 03057 // Update the sibling half-facet map 03058 for( int i = 0; i < etotal; i++ ) 03059 { 03060 std::vector< EntityHandle > sib_entids( nhf ); 03061 std::vector< int > sib_lids( nhf ); 03062 03063 error = ahf->get_sibling_map( type, ent_buffer[i], &sib_entids[0], &sib_lids[0], nhf );MB_CHK_ERR( error ); 03064 03065 for( int l = 0; l < nhf; l++ ) 03066 { 03067 if( sib_entids[l] ) continue; 03068 03069 // Fill out the sibling values 03070 int id = refTemplates[pat_id][d].ents_opphfs[i][2 * l]; 03071 if( id ) 03072 { 03073 sib_entids[l] = ent_buffer[id - 1]; 03074 sib_lids[l] = refTemplates[pat_id][d].ents_opphfs[i][2 * l + 1]; 03075 } 03076 else 03077 { 03078 sib_entids[l] = 0; 03079 sib_lids[l] = 0; 03080 } 03081 } 03082 03083 error = ahf->set_sibling_map( type, ent_buffer[i], &sib_entids[0], &sib_lids[0], nhf );MB_CHK_ERR( error ); 03084 03085 for( int l = 0; l < nhf; l++ ) 03086 { 03087 if( sib_entids[l] ) 03088 { 03089 03090 EntityHandle set_entid = ent_buffer[i]; 03091 int set_lid = l; 03092 03093 error = ahf->set_sibling_map( type, sib_entids[l], sib_lids[l], set_entid, set_lid );MB_CHK_ERR( error ); 03094 } 03095 } 03096 } 03097 return MB_SUCCESS; 03098 } 03099 03100 ErrorCode NestedRefine::update_local_ahf( int deg, 03101 EntityType type, 03102 EntityHandle* vbuffer, 03103 EntityHandle* ent_buffer, 03104 int etotal ) 03105 { 03106 ErrorCode error; 03107 assert( type != MBTET ); 03108 error = update_local_ahf( deg, type, type - 1, vbuffer, ent_buffer, etotal );MB_CHK_ERR( error ); 03109 03110 return MB_SUCCESS; 03111 } 03112 03113 ErrorCode NestedRefine::update_global_ahf( EntityType type, int cur_level, int deg, std::vector< int >* pattern_ids ) 03114 { 03115 03116 ErrorCode error; 03117 03118 // Get the number of half-facets and number of children of each type 03119 if( type == MBEDGE ) 03120 { 03121 assert( pattern_ids == NULL ); 03122 error = update_global_ahf_1D( cur_level, deg );MB_CHK_ERR( error ); 03123 } 03124 else if( type == MBTRI || type == MBQUAD ) 03125 { 03126 assert( pattern_ids == NULL ); 03127 error = update_global_ahf_2D( cur_level, deg );MB_CHK_ERR( error ); 03128 } 03129 else if( type == MBHEX ) 03130 { 03131 assert( pattern_ids == NULL ); 03132 error = update_global_ahf_3D( cur_level, deg );MB_CHK_ERR( error ); 03133 } 03134 else if( type == MBTET ) 03135 { 03136 assert( pattern_ids != NULL ); 03137 error = update_global_ahf_3D( cur_level, deg, pattern_ids );MB_CHK_ERR( error ); 03138 } 03139 else 03140 MB_SET_ERR( MB_NOT_IMPLEMENTED, "Requesting AHF update for an unsupported mesh entity type" ); 03141 03142 return MB_SUCCESS; 03143 } 03144 03145 /*ErrorCode NestedRefine::update_global_ahf(int cur_level, int deg, std::vector<int> &pattern_ids) 03146 { 03147 ErrorCode error; 03148 error = update_global_ahf_3D(cur_level, deg, pattern_ids); MB_CHK_ERR(error); 03149 03150 return MB_SUCCESS; 03151 }*/ 03152 03153 ErrorCode NestedRefine::update_global_ahf_1D( int cur_level, int deg ) 03154 { 03155 ErrorCode error; 03156 int d = get_index_from_degree( deg ); 03157 int nhf, nchilds, nverts_prev, nents_prev; 03158 nhf = 2; 03159 nchilds = refTemplates[0][d].total_new_ents; 03160 if( cur_level ) 03161 { 03162 nverts_prev = level_mesh[cur_level - 1].num_verts; 03163 nents_prev = level_mesh[cur_level - 1].num_edges; 03164 } 03165 else 03166 { 03167 nverts_prev = _inverts.size(); 03168 nents_prev = _inedges.size(); 03169 } 03170 03171 std::vector< EntityHandle > inci_ent, child_ents; 03172 std::vector< int > inci_lid, child_lids; 03173 03174 // Update the vertex to half-facet maps for duplicate vertices 03175 for( int i = 0; i < nverts_prev; i++ ) 03176 { 03177 inci_ent.clear(); 03178 inci_lid.clear(); 03179 child_ents.clear(); 03180 child_lids.clear(); 03181 03182 // Vertex id in the previous mesh and the current one 03183 EntityHandle vid; 03184 if( cur_level ) 03185 vid = level_mesh[cur_level - 1].start_vertex + i; 03186 else 03187 vid = _inverts[i]; 03188 EntityHandle cur_vid = level_mesh[cur_level].start_vertex + i; 03189 03190 // Get the incident half-vert in the previous mesh 03191 error = ahf->get_incident_map( MBEDGE, vid, inci_ent, inci_lid );MB_CHK_ERR( error ); 03192 03193 // Obtain the corresponding incident child in the current mesh 03194 int lvid = get_local_vid( vid, inci_ent[0], cur_level - 1 ); 03195 if( lvid < 0 ) MB_SET_ERR( MB_FAILURE, "did not find local vertex ix " ); 03196 int chid = refTemplates[0][d].v2hf[lvid][0] - 1; 03197 03198 int pid; 03199 if( cur_level ) 03200 pid = inci_ent[0] - level_mesh[cur_level - 1].start_edge; 03201 else 03202 pid = inci_ent[0] - *_inedges.begin(); 03203 03204 int ind = nchilds * pid; 03205 03206 child_ents.push_back( level_mesh[cur_level].start_edge + ind + chid ); 03207 child_lids.push_back( refTemplates[0][d].v2hf[lvid][1] ); 03208 03209 error = ahf->set_incident_map( MBEDGE, cur_vid, child_ents, child_lids );MB_CHK_ERR( error ); 03210 } 03211 03212 // Update the sibling half-facet maps across entities 03213 for( int i = 0; i < nents_prev; i++ ) 03214 { 03215 EntityHandle ent; 03216 if( cur_level ) 03217 ent = level_mesh[cur_level - 1].start_edge + i; 03218 else 03219 ent = _inedges[i]; 03220 03221 std::vector< EntityHandle > sib_entids( nhf ); 03222 std::vector< int > sib_lids( nhf ); 03223 03224 error = ahf->get_sibling_map( MBEDGE, ent, &sib_entids[0], &sib_lids[0], nhf );MB_CHK_ERR( error ); 03225 03226 int id, idx; 03227 03228 for( int l = 0; l < nhf; l++ ) 03229 { 03230 if( !sib_entids[l] ) continue; 03231 03232 // Find the child incident on the half-facet 03233 id = refTemplates[0][d].ents_on_pent[l][1] - 1; 03234 idx = nchilds * i; 03235 EntityHandle child_ent = level_mesh[cur_level].start_edge + idx + id; 03236 int ch_lid = l; 03237 03238 // Find the sibling of the child 03239 std::vector< EntityHandle > sib_childs( nhf ); 03240 std::vector< int > sib_chlids( nhf ); 03241 03242 error = ahf->get_sibling_map( MBEDGE, child_ent, &sib_childs[0], &sib_chlids[0], nhf );MB_CHK_ERR( error ); 03243 03244 // If the sibling already exists, dont do anything 03245 if( sib_childs[ch_lid] ) continue; 03246 03247 // Get the correponding child of the sibling of the current parent 03248 int psib; 03249 if( cur_level ) 03250 psib = sib_entids[l] - level_mesh[cur_level - 1].start_edge; 03251 else 03252 psib = sib_entids[l] - *_inedges.begin(); 03253 03254 int plid = sib_lids[l]; 03255 03256 id = refTemplates[0][d].ents_on_pent[plid][1] - 1; 03257 idx = nchilds * psib; 03258 03259 EntityHandle psib_child = level_mesh[cur_level].start_edge + idx + id; 03260 int psib_chlid = plid; 03261 03262 // Set the siblings 03263 sib_childs[ch_lid] = psib_child; 03264 sib_chlids[ch_lid] = psib_chlid; 03265 03266 error = ahf->set_sibling_map( MBEDGE, child_ent, &sib_childs[0], &sib_chlids[0], nhf );MB_CHK_ERR( error ); 03267 } 03268 } 03269 03270 return MB_SUCCESS; 03271 } 03272 03273 ErrorCode NestedRefine::update_global_ahf_1D_sub( int cur_level, int deg ) 03274 { 03275 ErrorCode error; 03276 int d = get_index_from_degree( deg ); 03277 int nhf, nchilds, nents_prev; 03278 nhf = 2; 03279 nchilds = refTemplates[0][d].total_new_ents; 03280 if( cur_level ) 03281 { 03282 nents_prev = level_mesh[cur_level - 1].num_edges; 03283 } 03284 else 03285 { 03286 nents_prev = _inedges.size(); 03287 } 03288 03289 // Update the sibling half-facet maps across entities 03290 03291 std::vector< EntityHandle > conn; 03292 for( int i = 0; i < nents_prev; i++ ) 03293 { 03294 EntityHandle ent; 03295 if( cur_level ) 03296 ent = level_mesh[cur_level - 1].start_edge + i; 03297 else 03298 ent = _inedges[i]; 03299 03300 // Set incident hv maps 03301 conn.clear(); 03302 error = get_connectivity( ent, cur_level, conn );MB_CHK_ERR( error ); 03303 03304 std::vector< EntityHandle > inci_ent, child_ents; 03305 std::vector< int > inci_lid, child_lids; 03306 for( int j = 0; j < 2; j++ ) 03307 { 03308 inci_ent.clear(); 03309 inci_lid.clear(); 03310 child_ents.clear(); 03311 child_lids.clear(); 03312 03313 // Get the entityhandle of the vertex from previous level in the current level 03314 EntityHandle cur_vid; 03315 if( cur_level ) 03316 cur_vid = level_mesh[cur_level].start_vertex + ( conn[j] - level_mesh[cur_level - 1].start_vertex ); 03317 else 03318 cur_vid = level_mesh[cur_level].start_vertex + ( conn[j] - *_inverts.begin() ); 03319 03320 // Obtain the incident half-facet. If exists, then no need to assign another 03321 error = ahf->get_incident_map( MBEDGE, cur_vid, inci_ent, inci_lid );MB_CHK_ERR( error ); 03322 if( inci_ent[0] != 0 ) continue; 03323 03324 // Get the incident half-facet on the old vertex 03325 error = ahf->get_incident_map( MBEDGE, conn[j], inci_ent, inci_lid );MB_CHK_ERR( error ); 03326 03327 // Obtain the corresponding incident child in the current mesh 03328 int lvid = get_local_vid( conn[j], inci_ent[0], cur_level - 1 ); 03329 if( lvid < 0 ) MB_SET_ERR( MB_FAILURE, "did not find local vertex ix " ); 03330 int chid = refTemplates[0][d].v2hf[lvid][0] - 1; 03331 03332 int pid; 03333 if( cur_level ) 03334 pid = inci_ent[0] - level_mesh[cur_level - 1].start_edge; 03335 else 03336 pid = inci_ent[0] - *_inedges.begin(); 03337 03338 int ind = nchilds * pid; 03339 03340 child_ents.push_back( level_mesh[cur_level].start_edge + ind + chid ); 03341 child_lids.push_back( refTemplates[0][d].v2hf[lvid][1] ); 03342 03343 error = ahf->set_incident_map( MBEDGE, cur_vid, child_ents, child_lids );MB_CHK_ERR( error ); 03344 } 03345 03346 std::vector< EntityHandle > sib_entids( nhf ); 03347 std::vector< int > sib_lids( nhf ); 03348 03349 error = ahf->get_sibling_map( MBEDGE, ent, &sib_entids[0], &sib_lids[0], nhf );MB_CHK_ERR( error ); 03350 03351 int id, idx; 03352 03353 for( int l = 0; l < nhf; l++ ) 03354 { 03355 if( !sib_entids[l] ) continue; 03356 03357 // Find the child incident on the half-facet 03358 id = refTemplates[0][d].ents_on_pent[l][1] - 1; 03359 idx = nchilds * i; 03360 EntityHandle child_ent = level_mesh[cur_level].start_edge + idx + id; 03361 int ch_lid = l; 03362 03363 // Find the sibling of the child 03364 std::vector< EntityHandle > sib_childs( nhf ); 03365 std::vector< int > sib_chlids( nhf ); 03366 03367 error = ahf->get_sibling_map( MBEDGE, child_ent, &sib_childs[0], &sib_chlids[0], nhf );MB_CHK_ERR( error ); 03368 03369 // If the sibling already exists, dont do anything 03370 if( sib_childs[ch_lid] ) continue; 03371 03372 // Get the correponding child of the sibling of the current parent 03373 int psib; 03374 if( cur_level ) 03375 psib = sib_entids[l] - level_mesh[cur_level - 1].start_edge; 03376 else 03377 psib = sib_entids[l] - *_inedges.begin(); 03378 03379 int plid = sib_lids[l]; 03380 03381 id = refTemplates[0][d].ents_on_pent[plid][1] - 1; 03382 idx = nchilds * psib; 03383 03384 EntityHandle psib_child = level_mesh[cur_level].start_edge + idx + id; 03385 int psib_chlid = plid; 03386 03387 // Set the siblings 03388 sib_childs[ch_lid] = psib_child; 03389 sib_chlids[ch_lid] = psib_chlid; 03390 03391 error = ahf->set_sibling_map( MBEDGE, child_ent, &sib_childs[0], &sib_chlids[0], nhf );MB_CHK_ERR( error ); 03392 } 03393 } 03394 03395 return MB_SUCCESS; 03396 } 03397 03398 ErrorCode NestedRefine::update_ahf_1D( int cur_level ) 03399 { 03400 ErrorCode error; 03401 error = ahf->determine_sibling_halfverts( level_mesh[cur_level].verts, level_mesh[cur_level].edges );MB_CHK_ERR( error ); 03402 03403 error = ahf->determine_incident_halfverts( level_mesh[cur_level].edges );MB_CHK_ERR( error ); 03404 03405 return MB_SUCCESS; 03406 } 03407 03408 ErrorCode NestedRefine::update_global_ahf_2D( int cur_level, int deg ) 03409 { 03410 ErrorCode error; 03411 03412 EntityType type = mbImpl->type_from_handle( *_infaces.begin() ); 03413 int nhf, nchilds, nverts_prev, nents_prev; 03414 03415 nhf = ahf->lConnMap2D[type - 2].num_verts_in_face; 03416 int d = get_index_from_degree( deg ); 03417 nchilds = refTemplates[type - 1][d].total_new_ents; 03418 03419 if( cur_level ) 03420 { 03421 nverts_prev = level_mesh[cur_level - 1].num_verts; 03422 nents_prev = level_mesh[cur_level - 1].num_faces; 03423 } 03424 else 03425 { 03426 nverts_prev = _inverts.size(); 03427 nents_prev = _infaces.size(); 03428 } 03429 03430 std::vector< EntityHandle > inci_ent, child_ents; 03431 std::vector< int > inci_lid, child_lids; 03432 03433 // Update the vertex to half-edge maps for old/duplicate vertices 03434 for( int i = 0; i < nverts_prev; i++ ) 03435 { 03436 inci_ent.clear(); 03437 inci_lid.clear(); 03438 child_ents.clear(); 03439 child_lids.clear(); 03440 03441 // Vertex id in the previous mesh 03442 EntityHandle vid; 03443 if( cur_level ) 03444 vid = level_mesh[cur_level - 1].start_vertex + i; 03445 else 03446 vid = _inverts[i]; 03447 EntityHandle cur_vid = level_mesh[cur_level].start_vertex + i; 03448 03449 // Get the incident half-vert in the previous mesh 03450 error = ahf->get_incident_map( type, vid, inci_ent, inci_lid );MB_CHK_ERR( error ); 03451 03452 // Obtain the corresponding incident child in the current mesh 03453 for( int j = 0; j < (int)inci_ent.size(); j++ ) 03454 { 03455 int lvid = get_local_vid( vid, inci_ent[j], cur_level - 1 ); 03456 if( lvid < 0 ) MB_SET_ERR( MB_FAILURE, "did not find local vertex ix " ); 03457 int chid = refTemplates[type - 1][d].v2hf[lvid][0] - 1; 03458 03459 int pid; 03460 if( cur_level ) 03461 pid = inci_ent[j] - level_mesh[cur_level - 1].start_face; 03462 else 03463 pid = inci_ent[j] - *_infaces.begin(); 03464 03465 int ind = nchilds * pid; 03466 03467 child_ents.push_back( level_mesh[cur_level].start_face + ind + chid ); 03468 child_lids.push_back( refTemplates[type - 1][d].v2hf[lvid][1] ); 03469 } 03470 error = ahf->set_incident_map( type, cur_vid, child_ents, child_lids );MB_CHK_ERR( error ); 03471 } 03472 03473 EntityHandle fedge[2]; 03474 03475 // Update the sibling half-facet maps across entities 03476 for( int i = 0; i < nents_prev; i++ ) 03477 { 03478 EntityHandle ent; 03479 if( cur_level ) 03480 ent = level_mesh[cur_level - 1].start_face + i; 03481 else 03482 ent = _infaces[i]; 03483 03484 std::vector< EntityHandle > fid_conn; 03485 error = get_connectivity( ent, cur_level, fid_conn ); 03486 if( MB_SUCCESS != error ) return error; 03487 03488 std::vector< EntityHandle > sib_entids( nhf ); 03489 std::vector< int > sib_lids( nhf ); 03490 03491 error = ahf->get_sibling_map( type, ent, &sib_entids[0], &sib_lids[0], nhf );MB_CHK_ERR( error ); 03492 03493 int id, idx; 03494 03495 for( int l = 0; l < nhf; l++ ) 03496 { 03497 if( !sib_entids[l] ) continue; 03498 03499 int nidx = ahf->lConnMap2D[type - 2].next[l]; 03500 fedge[0] = fid_conn[l]; 03501 fedge[1] = fid_conn[nidx]; 03502 03503 EntityHandle sfid = sib_entids[l]; 03504 int slid = sib_lids[l]; 03505 03506 std::vector< EntityHandle > conn; 03507 error = get_connectivity( sfid, cur_level, conn ); 03508 if( MB_SUCCESS != error ) return error; 03509 03510 bool orient = true; 03511 nidx = ahf->lConnMap2D[type - 2].next[slid]; 03512 if( ( fedge[1] == conn[slid] ) && ( fedge[0] == conn[nidx] ) ) orient = false; 03513 03514 if( orient ) assert( ( fedge[0] == conn[slid] ) && ( fedge[1] == conn[nidx] ) ); 03515 03516 // Find the childrens incident on the half-facet 03517 int nch = refTemplates[type - 1][d].ents_on_pent[l][0]; 03518 idx = nchilds * i; 03519 03520 // Loop over all the incident childrens 03521 for( int k = 0; k < nch; k++ ) 03522 { 03523 id = refTemplates[type - 1][d].ents_on_pent[l][k + 1] - 1; 03524 EntityHandle child_ent = level_mesh[cur_level].start_face + idx + id; 03525 int child_lid = l; 03526 03527 // Find the sibling of the child 03528 EntityHandle child_sibent; 03529 int child_siblid; 03530 error = ahf->get_sibling_map( type, child_ent, child_lid, child_sibent, child_siblid );MB_CHK_ERR( error ); 03531 03532 if( child_sibent != 0 ) continue; 03533 03534 // Get the correponding child of the sibling of the current parent 03535 int psib; 03536 if( cur_level ) 03537 psib = sfid - level_mesh[cur_level - 1].start_face; 03538 else 03539 psib = sfid - *_infaces.begin(); 03540 03541 int plid = slid; 03542 03543 if( orient ) 03544 id = refTemplates[type - 1][d].ents_on_pent[plid][k + 1] - 1; 03545 else 03546 id = refTemplates[type - 1][d].ents_on_pent[plid][nch - k] - 1; 03547 03548 int sidx = nchilds * psib; 03549 03550 EntityHandle psib_child = level_mesh[cur_level].start_face + sidx + id; 03551 int psib_chlid = plid; 03552 03553 // Set the siblings 03554 error = ahf->set_sibling_map( type, child_ent, child_lid, psib_child, psib_chlid );MB_CHK_ERR( error ); 03555 } 03556 } 03557 } 03558 03559 return MB_SUCCESS; 03560 } 03561 03562 ErrorCode NestedRefine::update_global_ahf_2D_sub( int cur_level, int deg ) 03563 { 03564 ErrorCode error; 03565 int d = get_index_from_degree( deg ); 03566 EntityType type = mbImpl->type_from_handle( *_infaces.begin() ); 03567 int nhf, nchilds, nents_prev; 03568 nhf = ahf->lConnMap2D[type - 2].num_verts_in_face; 03569 nchilds = refTemplates[type - 1][d].total_new_ents; 03570 03571 if( cur_level ) 03572 nents_prev = level_mesh[cur_level - 1].num_faces; 03573 else 03574 nents_prev = _infaces.size(); 03575 03576 EntityHandle fedge[2]; 03577 03578 // Update the sibling half-facet maps across entities 03579 for( int i = 0; i < nents_prev; i++ ) 03580 { 03581 EntityHandle ent; 03582 if( cur_level ) 03583 ent = level_mesh[cur_level - 1].start_face + i; 03584 else 03585 ent = _infaces[i]; 03586 03587 std::vector< EntityHandle > fid_conn; 03588 error = get_connectivity( ent, cur_level, fid_conn ); 03589 if( MB_SUCCESS != error ) return error; 03590 03591 std::vector< EntityHandle > inci_ent, child_ents; 03592 std::vector< int > inci_lid, child_lids; 03593 03594 // Set incident half-edges 03595 for( int j = 0; j < nhf; j++ ) 03596 { 03597 inci_ent.clear(); 03598 inci_lid.clear(); 03599 child_ents.clear(); 03600 child_lids.clear(); 03601 EntityHandle cur_vid; 03602 if( cur_level ) 03603 cur_vid = level_mesh[cur_level].start_vertex + ( fid_conn[j] - level_mesh[cur_level - 1].start_vertex ); 03604 else 03605 cur_vid = level_mesh[cur_level].start_vertex + ( fid_conn[j] - *_inverts.begin() ); 03606 03607 // Obtain the incident half-facet. If exists, then no need to assign another 03608 error = ahf->get_incident_map( type, cur_vid, inci_ent, inci_lid );MB_CHK_ERR( error ); 03609 if( inci_ent[0] != 0 ) continue; 03610 03611 // Get the incident half-facet on the old vertex 03612 error = ahf->get_incident_map( type, fid_conn[j], inci_ent, inci_lid );MB_CHK_ERR( error ); 03613 03614 // Obtain the corresponding incident child in the current mesh 03615 for( int k = 0; k < (int)inci_ent.size(); k++ ) 03616 { 03617 int lvid = get_local_vid( fid_conn[j], inci_ent[k], cur_level - 1 ); 03618 if( lvid < 0 ) MB_SET_ERR( MB_FAILURE, "did not find local vertex ix " ); 03619 int chid = refTemplates[type - 1][d].v2hf[lvid][0] - 1; 03620 03621 int pid; 03622 if( cur_level ) 03623 pid = inci_ent[k] - level_mesh[cur_level - 1].start_face; 03624 else 03625 pid = inci_ent[k] - *_infaces.begin(); 03626 03627 int ind = nchilds * pid; 03628 03629 child_ents.push_back( level_mesh[cur_level].start_face + ind + chid ); 03630 child_lids.push_back( refTemplates[type - 1][d].v2hf[lvid][1] ); 03631 } 03632 03633 error = ahf->set_incident_map( type, cur_vid, child_ents, child_lids );MB_CHK_ERR( error ); 03634 } 03635 03636 // Set sibling half-edges 03637 std::vector< EntityHandle > sib_entids( nhf ); 03638 std::vector< int > sib_lids( nhf ); 03639 03640 error = ahf->get_sibling_map( type, ent, &sib_entids[0], &sib_lids[0], nhf );MB_CHK_ERR( error ); 03641 03642 int id, idx; 03643 03644 for( int l = 0; l < nhf; l++ ) 03645 { 03646 if( !sib_entids[l] ) continue; 03647 03648 int nidx = ahf->lConnMap2D[type - 2].next[l]; 03649 fedge[0] = fid_conn[l]; 03650 fedge[1] = fid_conn[nidx]; 03651 03652 EntityHandle sfid = sib_entids[l]; 03653 int slid = sib_lids[l]; 03654 03655 std::vector< EntityHandle > conn; 03656 error = get_connectivity( sfid, cur_level, conn );MB_CHK_ERR( error ); 03657 03658 assert( (int)conn.size() > nidx && (int)conn.size() > slid ); 03659 03660 bool orient = true; 03661 nidx = ahf->lConnMap2D[type - 2].next[slid]; 03662 if( ( fedge[1] == conn[slid] ) && ( fedge[0] == conn[nidx] ) ) orient = false; 03663 03664 if( orient ) assert( ( fedge[0] == conn[slid] ) && ( fedge[1] == conn[nidx] ) ); 03665 03666 // Find the childrens incident on the half-facet 03667 int nch = refTemplates[type - 1][d].ents_on_pent[l][0]; 03668 idx = nchilds * i; 03669 03670 // Loop over all the incident childrens 03671 for( int k = 0; k < nch; k++ ) 03672 { 03673 id = refTemplates[type - 1][d].ents_on_pent[l][k + 1] - 1; 03674 EntityHandle child_ent = level_mesh[cur_level].start_face + idx + id; 03675 int child_lid = l; 03676 03677 // Find the sibling of the child 03678 EntityHandle child_sibent; 03679 int child_siblid; 03680 error = ahf->get_sibling_map( type, child_ent, child_lid, child_sibent, child_siblid );MB_CHK_ERR( error ); 03681 03682 if( child_sibent != 0 ) continue; 03683 03684 // Get the correponding child of the sibling of the current parent 03685 int psib; 03686 if( cur_level ) 03687 psib = sfid - level_mesh[cur_level - 1].start_face; 03688 else 03689 psib = sfid - *_infaces.begin(); 03690 03691 int plid = slid; 03692 03693 if( orient ) 03694 id = refTemplates[type - 1][d].ents_on_pent[plid][k + 1] - 1; 03695 else 03696 id = refTemplates[type - 1][d].ents_on_pent[plid][nch - k] - 1; 03697 03698 int sidx = nchilds * psib; 03699 03700 EntityHandle psib_child = level_mesh[cur_level].start_face + sidx + id; 03701 int psib_chlid = plid; 03702 03703 // Set the siblings 03704 error = ahf->set_sibling_map( type, child_ent, child_lid, psib_child, psib_chlid );MB_CHK_ERR( error ); 03705 } 03706 } 03707 } 03708 03709 return MB_SUCCESS; 03710 } 03711 03712 ErrorCode NestedRefine::update_global_ahf_3D( int cur_level, int deg, std::vector< int >* pattern_ids ) 03713 { 03714 ErrorCode error; 03715 int nvpc, ne, nhf, nchilds, nverts_prev, nents_prev; 03716 03717 EntityType type = mbImpl->type_from_handle( *_incells.begin() ); 03718 int index = ahf->get_index_in_lmap( *_incells.begin() ); 03719 int d = get_index_from_degree( deg ); 03720 03721 nhf = ahf->lConnMap3D[index].num_faces_in_cell; 03722 ne = ahf->lConnMap3D[index].num_edges_in_cell; 03723 nvpc = ahf->lConnMap3D[index].num_verts_in_cell; 03724 nchilds = refTemplates[type - 1][d].total_new_ents; 03725 03726 if( cur_level ) 03727 { 03728 nverts_prev = level_mesh[cur_level - 1].num_verts; 03729 nents_prev = level_mesh[cur_level - 1].num_cells; 03730 } 03731 else 03732 { 03733 nverts_prev = _inverts.size(); 03734 nents_prev = _incells.size(); 03735 } 03736 03737 std::vector< EntityHandle > inci_ent, child_ents; 03738 std::vector< int > inci_lid, child_lids; 03739 03740 // Step 1: Update the V2HF maps for old/duplicate vertices 03741 for( int i = 0; i < nverts_prev; i++ ) 03742 { 03743 inci_ent.clear(); 03744 inci_lid.clear(); 03745 child_ents.clear(); 03746 child_lids.clear(); 03747 03748 // Vertex id in the previous mesh 03749 EntityHandle vid; 03750 if( cur_level ) 03751 vid = level_mesh[cur_level - 1].start_vertex + i; 03752 else 03753 vid = _inverts[i]; 03754 EntityHandle cur_vid = level_mesh[cur_level].start_vertex + i; 03755 03756 // Get the incident half-vert in the previous mesh 03757 error = ahf->get_incident_map( type, vid, inci_ent, inci_lid );MB_CHK_ERR( error ); 03758 03759 // Obtain the corresponding incident child in the current mesh 03760 for( int j = 0; j < (int)inci_ent.size(); j++ ) 03761 { 03762 int lvid = get_local_vid( vid, inci_ent[j], cur_level - 1 ); 03763 if( lvid < 0 ) MB_SET_ERR( MB_FAILURE, "did not find local vertex ix " ); 03764 int chid = refTemplates[type - 1][d].v2hf[lvid][0] - 1; 03765 03766 int pid; 03767 if( cur_level ) 03768 pid = inci_ent[j] - level_mesh[cur_level - 1].start_cell; 03769 else 03770 pid = inci_ent[j] - *_incells.begin(); 03771 03772 int ind = nchilds * pid; 03773 03774 // EntityHandle child_ent = level_mesh[cur_level].start_cell + ind+chid ; 03775 // int child_lid = refTemplates[type-1][d].v2hf[lvid][1]; 03776 child_ents.push_back( level_mesh[cur_level].start_cell + ind + chid ); 03777 child_lids.push_back( refTemplates[type - 1][d].v2hf[lvid][1] ); 03778 } 03779 03780 error = ahf->set_incident_map( type, cur_vid, child_ents, child_lids );MB_CHK_ERR( error ); 03781 } 03782 03783 // error = ahf->determine_incident_halffaces( level_mesh[cur_level].cells);MB_CHK_ERR(error); 03784 03785 // Step 2: Update SIBHFS maps 03786 for( int i = 0; i < nents_prev; i++ ) 03787 { 03788 EntityHandle ent; 03789 if( cur_level ) 03790 ent = level_mesh[cur_level - 1].start_cell + i; 03791 else 03792 ent = _incells[i]; 03793 03794 std::vector< EntityHandle > sib_entids( nhf ); 03795 std::vector< int > sib_lids( nhf ); 03796 03797 error = ahf->get_sibling_map( type, ent, &sib_entids[0], &sib_lids[0], nhf );MB_CHK_ERR( error ); 03798 03799 int id, idx; 03800 03801 for( int l = 0; l < nhf; l++ ) 03802 { 03803 03804 if( !sib_entids[l] ) continue; 03805 03806 // Get the number of children incident on this half-face 03807 int pat_id; 03808 if( type == MBTET ) 03809 pat_id = ( *pattern_ids )[i]; 03810 else 03811 pat_id = type - 1; 03812 int nch = refTemplates[pat_id][d].ents_on_pent[l][0]; 03813 03814 // Get the order of children indices incident on this half-face 03815 std::vector< int > id_sib( nch ); 03816 for( int k = 0; k < nch; k++ ) 03817 id_sib[k] = 0; 03818 03819 error = reorder_indices( cur_level, deg, ent, l, sib_entids[l], sib_lids[l], 1, &id_sib[0] );MB_CHK_ERR( error ); 03820 03821 // Get the parent index of the sibling cell 03822 int psib; 03823 if( cur_level ) 03824 psib = sib_entids[l] - level_mesh[cur_level - 1].start_cell; 03825 else 03826 psib = sib_entids[l] - *_incells.begin(); 03827 03828 int plid = sib_lids[l]; 03829 int sidx = nchilds * psib; 03830 int sibpat_id; 03831 if( type == MBTET ) 03832 sibpat_id = ( *pattern_ids )[psib]; 03833 else 03834 sibpat_id = type - 1; 03835 03836 // Loop over all the childs incident on the working half-face 03837 idx = nchilds * i; 03838 03839 for( int k = 0; k < nch; k++ ) 03840 { 03841 id = refTemplates[pat_id][d].ents_on_pent[l][k + 1] - 1; 03842 EntityHandle child_ent = level_mesh[cur_level].start_cell + idx + id; 03843 int child_lid = l; 03844 03845 // Find the sibling of the working child 03846 EntityHandle child_sibent; 03847 int child_siblid; 03848 error = ahf->get_sibling_map( type, child_ent, child_lid, child_sibent, child_siblid );MB_CHK_ERR( error ); 03849 03850 if( child_sibent != 0 ) continue; 03851 03852 // Get the correponding child of the sibling of the current parent 03853 // We have already computed the order the children on incident corresponding to the 03854 // working half-face 03855 id = refTemplates[sibpat_id][d].ents_on_pent[plid][id_sib[k]] - 1; 03856 03857 EntityHandle psib_child = level_mesh[cur_level].start_cell + sidx + id; 03858 int psib_chlid = plid; 03859 03860 // Set the siblings of children incident on current half-face 03861 error = ahf->set_sibling_map( type, child_ent, child_lid, psib_child, psib_chlid );MB_CHK_ERR( error ); 03862 03863 // Set the sibling of the sibling of the children to the children 03864 error = ahf->set_sibling_map( type, psib_child, psib_chlid, child_ent, child_lid );MB_CHK_ERR( error ); 03865 } 03866 } 03867 03868 // Loop over edges to check if there are any non-manifold edges. If there are then the v2hfs 03869 // map should be updated for the new vertices on it. 03870 const EntityHandle* conn; 03871 error = mbImpl->get_connectivity( ent, conn, nvpc );MB_CHK_ERR( error ); 03872 03873 int nv = refTemplates[type - 1][d].nv_edge; //#verts on each edge 03874 for( int l = 0; l < ne; l++ ) 03875 { 03876 id = ahf->lConnMap3D[index].e2v[l][0]; 03877 EntityHandle v_start = conn[id]; 03878 id = ahf->lConnMap3D[index].e2v[l][1]; 03879 EntityHandle v_end = conn[id]; 03880 03881 bool visited = false; 03882 03883 std::vector< EntityHandle > inci_ent1, inci_ent2; 03884 std::vector< int > inci_lid1, inci_lid2; 03885 error = ahf->get_incident_map( type, v_start, inci_ent1, inci_lid1 );MB_CHK_ERR( error ); 03886 error = ahf->get_incident_map( type, v_end, inci_ent2, inci_lid2 );MB_CHK_ERR( error ); 03887 03888 if( inci_ent1.size() > 1 && inci_ent2.size() > 1 ) 03889 { 03890 std::vector< EntityHandle > cell_comps; 03891 std::vector< int > leid_comps; 03892 03893 error = ahf->get_up_adjacencies_edg_3d_comp( ent, l, cell_comps, &leid_comps );MB_CHK_ERR( error ); 03894 03895 int ncomps = cell_comps.size(); 03896 std::vector< EntityHandle > edgverts; 03897 std::vector< EntityHandle > compchildents( nv * ncomps ); 03898 std::vector< int > compchildlfids( nv * ncomps ); 03899 03900 for( int s = 0; s < nv * ncomps; s++ ) 03901 { 03902 compchildents[s] = 0; 03903 compchildlfids[s] = 0; 03904 } 03905 03906 for( int j = 0; j < (int)cell_comps.size(); j++ ) 03907 { 03908 int ind; 03909 if( cur_level ) 03910 ind = level_mesh[cur_level - 1].cells.index( cell_comps[j] ); 03911 else 03912 ind = _incells.index( cell_comps[j] ); 03913 03914 for( int k = 0; k < nv; k++ ) 03915 { 03916 int chid = refTemplates[type - 1][d].ents_on_vedge[leid_comps[j]][3 * k] - 1; 03917 int lfid = refTemplates[type - 1][d].ents_on_vedge[leid_comps[j]][3 * k + 1]; 03918 int lvid = refTemplates[type - 1][d].ents_on_vedge[leid_comps[j]][3 * k + 2]; 03919 03920 EntityHandle childcell = level_mesh[cur_level].start_cell + ind * nchilds + chid; 03921 03922 const EntityHandle* econn; 03923 error = mbImpl->get_connectivity( childcell, econn, nvpc );MB_CHK_ERR( error ); 03924 03925 EntityHandle vert = econn[lvid]; 03926 03927 if( ahf->check_nonmanifold_vertices( type, vert ) ) 03928 { 03929 visited = true; 03930 break; 03931 } 03932 03933 if( edgverts.empty() ) 03934 { 03935 edgverts.push_back( vert ); 03936 compchildents[0] = childcell; 03937 compchildlfids[0] = lfid; 03938 } 03939 else 03940 { 03941 std::vector< EntityHandle >::iterator it; 03942 it = find( edgverts.begin(), edgverts.end(), vert ); 03943 int indx = it - edgverts.begin(); 03944 03945 if( it == edgverts.end() ) 03946 { 03947 edgverts.push_back( vert ); 03948 compchildents[k * ncomps] = childcell; 03949 compchildlfids[k * ncomps] = lfid; 03950 } 03951 else 03952 { 03953 compchildents[indx * ncomps + j] = childcell; 03954 compchildlfids[indx * ncomps + j] = lfid; 03955 } 03956 } 03957 } 03958 } 03959 03960 if( visited ) 03961 { 03962 break; 03963 } 03964 03965 // Set the incident half-facet map 03966 for( int k = 0; k < nv; k++ ) 03967 { 03968 std::vector< EntityHandle > set_childents; 03969 std::vector< int > set_childlfids; 03970 for( int j = 0; j < ncomps; j++ ) 03971 { 03972 set_childents.push_back( compchildents[k * ncomps + j] ); 03973 set_childlfids.push_back( compchildlfids[k * ncomps + j] ); 03974 } 03975 03976 error = ahf->set_incident_map( type, edgverts[k], set_childents, set_childlfids );MB_CHK_ERR( error ); 03977 } 03978 } 03979 } 03980 } 03981 03982 return MB_SUCCESS; 03983 } 03984 03985 ErrorCode NestedRefine::get_lid_inci_child( EntityType type, 03986 int deg, 03987 int lfid, 03988 int leid, 03989 std::vector< int >& child_ids, 03990 std::vector< int >& child_lvids ) 03991 { 03992 int index = ahf->get_index_in_lmap( *_incells.begin() ); 03993 int d = get_index_from_degree( deg ); 03994 03995 // int lv0 = ahf->lConnMap3D[index].e2v[leid][0]; 03996 // int lv1 = ahf->lConnMap3D[index].e2v[leid][1]; 03997 int nvpc = ahf->lConnMap3D[index].num_verts_in_cell; 03998 03999 int nv = refTemplates[type - 1][d].nv_edge; 04000 int nch = refTemplates[type - 1][d].ents_on_pent[lfid][0]; 04001 04002 for( int i = 0; i < nch; i++ ) 04003 { 04004 int id = refTemplates[type - 1][d].ents_on_pent[lfid][i + 1] - 1; 04005 for( int j = 0; j < nvpc; j++ ) 04006 { 04007 int lv = refTemplates[type - 1][d].ents_conn[id][j]; 04008 for( int k = 0; k < nv; k++ ) 04009 { 04010 if( lv == refTemplates[type - 1][d].vert_on_edges[leid][k] ) 04011 { 04012 child_ids.push_back( id ); 04013 child_lvids.push_back( j ); 04014 } 04015 } 04016 } 04017 } 04018 04019 return MB_SUCCESS; 04020 } 04021 04022 /* ********************************** 04023 * * Boundary Functions * 04024 ************************************/ 04025 04026 bool NestedRefine::is_vertex_on_boundary( const EntityHandle& vertex ) 04027 { 04028 ErrorCode error; 04029 EntityHandle sibents[27]; 04030 int siblids[27]; 04031 std::vector< EntityHandle > ent; 04032 std::vector< int > lid; 04033 04034 int nhf; 04035 if( elementype == MBEDGE ) 04036 nhf = 2; 04037 else if( ( elementype == MBTRI ) || ( elementype == MBQUAD ) ) 04038 nhf = ahf->lConnMap2D[elementype - 2].num_verts_in_face; 04039 else if( ( elementype == MBTET ) || ( elementype == MBHEX ) ) 04040 { 04041 int idx = ahf->get_index_in_lmap( *_incells.begin() ); 04042 nhf = ahf->lConnMap3D[idx].num_faces_in_cell; 04043 } 04044 else 04045 MB_SET_ERR( MB_FAILURE, "Requesting vertex boundary information for an unsupported entity type" ); 04046 04047 error = ahf->get_incident_map( elementype, vertex, ent, lid );MB_CHK_ERR( error ); 04048 error = ahf->get_sibling_map( elementype, ent[0], &sibents[0], &siblids[0], nhf );MB_CHK_ERR( error ); 04049 04050 return ( sibents[lid[0]] == 0 ); 04051 } 04052 04053 bool NestedRefine::is_edge_on_boundary( const EntityHandle& entity ) 04054 { 04055 ErrorCode error; 04056 bool is_border = false; 04057 if( meshdim == 1 ) // The edge has a vertex on the boundary in the curve mesh 04058 { 04059 EntityHandle sibents[2]; 04060 int siblids[2]; 04061 error = ahf->get_sibling_map( MBEDGE, entity, &sibents[0], &siblids[0], 2 );MB_CHK_ERR( error ); 04062 for( int i = 0; i < 2; i++ ) 04063 { 04064 if( sibents[i] == 0 ) 04065 { 04066 is_border = true; 04067 break; 04068 } 04069 } 04070 } 04071 else if( meshdim == 2 ) // The edge is on the boundary of the 2d mesh 04072 { 04073 std::vector< EntityHandle > adjents; 04074 error = ahf->get_up_adjacencies_2d( entity, adjents );MB_CHK_ERR( error ); 04075 if( adjents.size() == 1 ) is_border = true; 04076 } 04077 else if( meshdim == 3 ) // The edge is part of a face on the boundary of the 3d mesh 04078 { 04079 std::vector< EntityHandle > adjents; 04080 std::vector< int > leids; 04081 error = ahf->get_up_adjacencies_edg_3d( entity, adjents, &leids );MB_CHK_ERR( error ); 04082 assert( !adjents.empty() ); 04083 04084 int index = ahf->get_index_in_lmap( adjents[0] ); 04085 int nhf = ahf->lConnMap3D[index].num_faces_in_cell; 04086 04087 for( int i = 0; i < (int)adjents.size(); i++ ) 04088 { 04089 EntityHandle sibents[6]; 04090 int siblids[6]; 04091 error = ahf->get_sibling_map( elementype, adjents[0], &sibents[0], &siblids[0], nhf );MB_CHK_ERR( error ); 04092 for( int k = 0; k < 2; k++ ) 04093 { 04094 int hf = ahf->lConnMap3D[index].e2hf[leids[0]][k]; 04095 if( sibents[hf] == 0 ) 04096 { 04097 is_border = true; 04098 break; 04099 } 04100 } 04101 } 04102 } 04103 return is_border; 04104 } 04105 04106 bool NestedRefine::is_face_on_boundary( const EntityHandle& entity ) 04107 { 04108 ErrorCode error; 04109 bool is_border = false; 04110 04111 if( meshdim == 1 ) 04112 MB_SET_ERR( MB_FAILURE, "Requesting boundary information for a face entity type on a curve mesh" ); 04113 else if( meshdim == 2 ) // The face has a local edge on the boundary of the 2d mesh 04114 { 04115 EntityHandle sibents[4]; 04116 int siblids[4]; 04117 int nepf = ahf->lConnMap2D[elementype - 2].num_verts_in_face; 04118 error = ahf->get_sibling_map( elementype, entity, &sibents[0], &siblids[0], nepf );MB_CHK_ERR( error ); 04119 04120 for( int i = 0; i < nepf; i++ ) 04121 { 04122 if( sibents[i] == 0 ) 04123 { 04124 is_border = true; 04125 break; 04126 } 04127 } 04128 } 04129 else if( meshdim == 3 ) // The face lies on the boundary of the 3d mesh 04130 { 04131 std::vector< EntityHandle > adjents; 04132 error = ahf->get_up_adjacencies_face_3d( entity, adjents );MB_CHK_ERR( error ); 04133 if( adjents.size() == 1 ) is_border = true; 04134 } 04135 return is_border; 04136 } 04137 04138 bool NestedRefine::is_cell_on_boundary( const EntityHandle& entity ) 04139 { 04140 if( meshdim != 3 ) 04141 MB_SET_ERR( MB_FAILURE, "Requesting boundary information for a cell entity type on a curve or surface mesh" ); 04142 04143 bool is_border = false; 04144 int index = ahf->get_index_in_lmap( *_incells.begin() ); 04145 int nfpc = ahf->lConnMap3D[index].num_faces_in_cell; 04146 EntityHandle sibents[6]; 04147 int siblids[6]; 04148 04149 ErrorCode error = ahf->get_sibling_map( elementype, entity, &sibents[0], &siblids[0], nfpc );MB_CHK_ERR( error ); 04150 04151 for( int i = 0; i < nfpc; i++ ) 04152 { 04153 if( sibents[i] == 0 ) 04154 { 04155 is_border = true; 04156 break; 04157 } 04158 } 04159 return is_border; 04160 } 04161 04162 /* ********************************** 04163 * Helper Functions * 04164 ************************************/ 04165 ErrorCode NestedRefine::copy_vertices_from_prev_level( int cur_level ) 04166 { 04167 ErrorCode error; 04168 04169 if( cur_level ) 04170 { 04171 int nverts_prev = level_mesh[cur_level - 1].num_verts; 04172 for( int i = 0; i < nverts_prev; i++ ) 04173 { 04174 level_mesh[cur_level].coordinates[0][i] = level_mesh[cur_level - 1].coordinates[0][i]; 04175 level_mesh[cur_level].coordinates[1][i] = level_mesh[cur_level - 1].coordinates[1][i]; 04176 level_mesh[cur_level].coordinates[2][i] = level_mesh[cur_level - 1].coordinates[2][i]; 04177 } 04178 } 04179 else // Copy the vertices from the input mesh 04180 { 04181 int nverts_in = _inverts.size(); 04182 std::vector< double > vcoords( 3 * nverts_in ); 04183 error = mbImpl->get_coords( _inverts, &vcoords[0] );MB_CHK_ERR( error ); 04184 04185 for( int i = 0; i < nverts_in; i++ ) 04186 { 04187 level_mesh[cur_level].coordinates[0][i] = vcoords[3 * i]; 04188 level_mesh[cur_level].coordinates[1][i] = vcoords[3 * i + 1]; 04189 level_mesh[cur_level].coordinates[2][i] = vcoords[3 * i + 2]; 04190 } 04191 } 04192 return MB_SUCCESS; 04193 // To add: Map from old vertices to new duplicates: NOT NEEDED 04194 } 04195 04196 ErrorCode NestedRefine::update_tracking_verts( EntityHandle cid, 04197 int cur_level, 04198 int deg, 04199 std::vector< EntityHandle >& trackvertsC_edg, 04200 std::vector< EntityHandle >& trackvertsC_face, 04201 EntityHandle* vbuffer ) 04202 { 04203 // The vertices in the vbuffer are added to appropriate edges and faces of cells that are 04204 // incident on the working cell. 04205 ErrorCode error; 04206 04207 EntityHandle cstart_prev; 04208 if( cur_level ) 04209 cstart_prev = level_mesh[cur_level - 1].start_cell; 04210 else 04211 cstart_prev = *_incells.begin(); 04212 04213 EntityType cell_type = mbImpl->type_from_handle( cstart_prev ); 04214 int cindex = cell_type - 1; 04215 int d = get_index_from_degree( deg ); 04216 04217 int nve = refTemplates[cindex][d].nv_edge; 04218 int nvf = refTemplates[cindex][d].nv_face; 04219 04220 int index = ahf->get_index_in_lmap( *( _incells.begin() ) ); 04221 int nepc = ahf->lConnMap3D[index].num_edges_in_cell; 04222 int nfpc = ahf->lConnMap3D[index].num_faces_in_cell; 04223 04224 // Step 1: Add the vertices on an edge of the working cell to tracking array of incident cells. 04225 for( int i = 0; i < nepc; i++ ) 04226 { 04227 // Add the vertices to edges of the current cell 04228 for( int j = 0; j < nve; j++ ) 04229 { 04230 int id = refTemplates[cindex][d].vert_on_edges[i][j]; 04231 int idx = cid - cstart_prev; 04232 int aid = idx * nve * nepc + nve * i + j; 04233 04234 if( !trackvertsC_edg[aid] ) trackvertsC_edg[aid] = vbuffer[id]; 04235 } 04236 04237 // Obtain all the incident cells 04238 std::vector< EntityHandle > inc_cids; 04239 std::vector< int > inc_leids, inc_orient; 04240 04241 error = ahf->get_up_adjacencies_edg_3d( cid, i, inc_cids, &inc_leids, &inc_orient );MB_CHK_ERR( error ); 04242 04243 if( inc_cids.size() == 1 ) continue; 04244 04245 // Add the vertices to the edges of the incident cells 04246 for( int k = 0; k < (int)inc_cids.size(); k++ ) 04247 { 04248 if( inc_cids[k] == cid ) continue; 04249 04250 int idx = inc_cids[k] - cstart_prev; 04251 04252 if( inc_orient[k] ) // Same edge direction as the current edge 04253 { 04254 for( int j = 0; j < nve; j++ ) 04255 { 04256 int id = refTemplates[cindex][d].vert_on_edges[i][j]; 04257 int aid = idx * nve * nepc + nve * inc_leids[k] + j; 04258 04259 if( !trackvertsC_edg[aid] ) trackvertsC_edg[aid] = vbuffer[id]; 04260 } 04261 } 04262 else 04263 { 04264 for( int j = 0; j < nve; j++ ) 04265 { 04266 int id = refTemplates[cindex][d].vert_on_edges[i][nve - j - 1]; 04267 int aid = idx * nve * nepc + nve * inc_leids[k] + j; 04268 04269 if( !trackvertsC_edg[aid] ) trackvertsC_edg[aid] = vbuffer[id]; 04270 } 04271 } 04272 } 04273 } 04274 04275 // Step 2: Add the vertices on a face of the working cell to tracking array of incident cells. 04276 if( nvf ) 04277 { 04278 04279 for( int i = 0; i < nfpc; i++ ) 04280 { 04281 // Add vertices to the tracking array of vertices on faces for the current cell 04282 std::vector< EntityHandle > face_vbuf( nvf, 0 ); 04283 for( int j = 0; j < nvf; j++ ) 04284 { 04285 int id = refTemplates[cindex][d].vert_on_faces[i][j]; 04286 int idx = cid - cstart_prev; 04287 int aid = idx * nvf * nfpc + nvf * i + j; 04288 04289 if( !trackvertsC_face[aid] ) trackvertsC_face[aid] = vbuffer[id]; 04290 04291 face_vbuf[j] = vbuffer[id]; 04292 } 04293 04294 // Obtain all the incident cells 04295 std::vector< EntityHandle > sib_cids; 04296 std::vector< int > sib_lfids; 04297 error = ahf->get_up_adjacencies_face_3d( cid, i, sib_cids, &sib_lfids );MB_CHK_ERR( error ); 04298 04299 if( sib_cids.size() == 1 ) continue; 04300 04301 // Reorder the vertex local ids incident on the half-face 04302 std::vector< int > id_sib( nvf ); 04303 for( int k = 0; k < nvf; k++ ) 04304 id_sib[k] = 0; 04305 04306 error = reorder_indices( cur_level, deg, sib_cids[1], sib_lfids[1], cid, i, 0, &id_sib[0] );MB_CHK_ERR( error ); 04307 04308 // Add vertices to the tracking array of vertices on faces for the sibling cell of the 04309 // current cell 04310 for( int j = 0; j < nvf; j++ ) 04311 { 04312 int idx = sib_cids[1] - cstart_prev; 04313 int aid = idx * nvf * nfpc + nvf * sib_lfids[1] + j; 04314 04315 if( !trackvertsC_face[aid] ) trackvertsC_face[aid] = face_vbuf[id_sib[j] - 1]; 04316 } 04317 } 04318 } 04319 return MB_SUCCESS; 04320 } 04321 04322 ErrorCode NestedRefine::reorder_indices( int cur_level, 04323 int deg, 04324 EntityHandle cell, 04325 int lfid, 04326 EntityHandle sib_cell, 04327 int sib_lfid, 04328 int index, 04329 int* id_sib ) 04330 { 04331 // Reorders the indices of either vertices or children cell local ids to match with order of the 04332 // given cell and a local face. index = 0 : vertices, 04333 // = 1 : face 04334 04335 assert( deg == 2 || deg == 3 ); 04336 04337 ErrorCode error; 04338 int idx = ahf->get_index_in_lmap( *_incells.begin() ); 04339 int nvF = ahf->lConnMap3D[idx].hf2v_num[lfid]; 04340 int nco = permutation[nvF - 3].num_comb; 04341 04342 if( !index && ( ( nvF == 3 && deg == 3 ) || ( nvF == 4 && deg == 2 ) ) ) 04343 { 04344 id_sib[0] = 1; 04345 } 04346 else 04347 { 04348 // Get connectivity of the cell and its sibling cell 04349 std::vector< EntityHandle > conn, sib_conn; 04350 error = get_connectivity( cell, cur_level, conn );MB_CHK_ERR( error ); 04351 04352 error = get_connectivity( sib_cell, cur_level, sib_conn );MB_CHK_ERR( error ); 04353 04354 // Get the connectivity of the local face in the cell and its sibling 04355 std::vector< EntityHandle > lface( nvF ); 04356 std::vector< EntityHandle > lface_sib( nvF ); 04357 for( int i = 0; i < nvF; i++ ) 04358 { 04359 int id = ahf->lConnMap3D[idx].hf2v[lfid][i]; 04360 lface[i] = conn[id]; 04361 04362 id = ahf->lConnMap3D[idx].hf2v[sib_lfid][i]; 04363 lface_sib[i] = sib_conn[id]; 04364 } 04365 04366 // Find the combination 04367 int c = 0; 04368 for( int i = 0; i < nco; i++ ) 04369 { 04370 int count = 0; 04371 for( int j = 0; j < nvF; j++ ) 04372 { 04373 int id = permutation[nvF - 3].comb[i][j]; 04374 if( lface[j] == lface_sib[id] ) count += 1; 04375 } 04376 04377 if( count == nvF ) 04378 { 04379 c = i; 04380 break; 04381 } 04382 } 04383 04384 if( c > nco ) MB_SET_ERR( MB_FAILURE, "Getting a combination number more than currently supported" ); 04385 04386 // Get the ordered indices 04387 if( ( ( !index ) && ( nvF == 4 ) && ( deg == 3 ) ) || ( deg == 2 ) ) 04388 { 04389 for( int i = 0; i < 4; i++ ) 04390 id_sib[i] = permutation[nvF - 3].porder2[c][i]; 04391 } 04392 else 04393 { 04394 for( int i = 0; i < 9; i++ ) 04395 id_sib[i] = permutation[nvF - 3].porder3[c][i]; 04396 } 04397 } 04398 04399 return MB_SUCCESS; 04400 } 04401 04402 ErrorCode NestedRefine::reorder_indices( int deg, 04403 EntityHandle* face1_conn, 04404 EntityHandle* face2_conn, 04405 int nvF, 04406 std::vector< int >& lemap, 04407 std::vector< int >& vidx, 04408 int* leorient ) 04409 { 04410 // Given the connectivities of two faces, get the permuted indices w.r.t first face. 04411 // Step 1: First find the orientation 04412 int nco = permutation[nvF - 3].num_comb; 04413 int c = 0; 04414 for( int i = 0; i < nco; i++ ) 04415 { 04416 int count = 0; 04417 for( int j = 0; j < nvF; j++ ) 04418 { 04419 int id = permutation[nvF - 3].comb[i][j]; 04420 if( face1_conn[j] == face2_conn[id] ) count += 1; 04421 } 04422 04423 if( count == nvF ) 04424 { 04425 c = i; 04426 break; 04427 } 04428 } 04429 04430 if( c > nco ) MB_SET_ERR( MB_FAILURE, "Getting a combination number more than currently supported" ); 04431 04432 // Add the corresponding local edges 04433 lemap.reserve( nvF ); 04434 for( int i = 0; i < nvF; i++ ) 04435 { 04436 lemap.push_back( permutation[nvF - 3].lemap[c][i] ); 04437 } 04438 if( leorient ) leorient[0] = permutation[nvF - 3].orient[c]; 04439 04440 if( nvF == 3 && deg == 2 ) return MB_SUCCESS; 04441 04442 if( ( nvF == 3 && deg == 3 ) || ( nvF == 4 && deg == 2 ) ) 04443 { 04444 vidx.push_back( 1 ); 04445 } 04446 else if( nvF == 4 && deg == 3 ) 04447 { 04448 for( int i = 0; i < 4; i++ ) 04449 vidx.push_back( permutation[nvF - 3].porder2[c][i] ); 04450 } 04451 04452 return MB_SUCCESS; 04453 } 04454 04455 ErrorCode NestedRefine::reorder_indices( int deg, int nvF, int comb, int* childfid_map ) 04456 { 04457 // Given connectivities of two faces and a degree, get the permuted indices of the children 04458 // faces w.r.t first face. 04459 04460 assert( deg == 2 || deg == 3 ); 04461 04462 // Get the ordered indices 04463 if( deg == 2 ) 04464 { 04465 for( int i = 0; i < 4; i++ ) 04466 childfid_map[i] = permutation[nvF - 3].porder2[comb][i]; 04467 } 04468 else 04469 { 04470 for( int i = 0; i < 9; i++ ) 04471 childfid_map[i] = permutation[nvF - 3].porder3[comb][i]; 04472 } 04473 04474 return MB_SUCCESS; 04475 } 04476 04477 ErrorCode NestedRefine::reorder_indices( EntityHandle* face1_conn, 04478 EntityHandle* face2_conn, 04479 int nvF, 04480 int* conn_map, 04481 int& comb, 04482 int* orient ) 04483 { 04484 // Given connectivities of two faces and a degree, get the permuted indices of the children 04485 // faces w.r.t first face. 04486 04487 // Step 1: First find the combination 04488 int nco = permutation[nvF - 3].num_comb; 04489 int c = 0; 04490 for( int i = 0; i < nco; i++ ) 04491 { 04492 int count = 0; 04493 for( int j = 0; j < nvF; j++ ) 04494 { 04495 int id = permutation[nvF - 3].comb[i][j]; 04496 if( face1_conn[j] == face2_conn[id] ) count += 1; 04497 } 04498 04499 if( count == nvF ) 04500 { 04501 c = i; 04502 break; 04503 } 04504 } 04505 04506 if( c > nco ) MB_SET_ERR( MB_FAILURE, "Getting a combination number more than currently supported" ); 04507 04508 comb = c; 04509 04510 if( orient ) orient[0] = permutation[nvF - 3].orient[c]; 04511 04512 for( int j = 0; j < nvF; j++ ) 04513 { 04514 conn_map[j] = permutation[nvF - 3].comb[c][j]; 04515 } 04516 04517 return MB_SUCCESS; 04518 } 04519 04520 ErrorCode NestedRefine::count_subentities( EntityHandle set, int cur_level, int* nedges, int* nfaces ) 04521 { 04522 ErrorCode error; 04523 04524 if( cur_level >= 0 ) 04525 { 04526 Range edges, faces, cells; 04527 04528 error = mbImpl->get_entities_by_dimension( set, 1, edges );MB_CHK_ERR( error ); 04529 04530 error = mbImpl->get_entities_by_dimension( set, 2, faces );MB_CHK_ERR( error ); 04531 04532 error = mbImpl->get_entities_by_dimension( set, 3, cells );MB_CHK_ERR( error ); 04533 04534 error = ahf->count_subentities( edges, faces, cells, nedges, nfaces );MB_CHK_ERR( error ); 04535 } 04536 else 04537 { 04538 error = ahf->count_subentities( _inedges, _infaces, _incells, nedges, nfaces );MB_CHK_ERR( error ); 04539 } 04540 04541 return MB_SUCCESS; 04542 } 04543 04544 ErrorCode NestedRefine::get_octahedron_corner_coords( int cur_level, int deg, EntityHandle* vbuffer, double* ocoords ) 04545 { 04546 int lid[6] = { 0, 0, 0, 0, 0, 0 }; 04547 04548 if( deg == 2 ) 04549 { 04550 lid[0] = 5; 04551 lid[1] = 8; 04552 lid[2] = 9; 04553 lid[3] = 6; 04554 lid[4] = 4; 04555 lid[5] = 7; 04556 } 04557 else if( deg == 3 ) 04558 { 04559 lid[0] = 19; 04560 lid[1] = 16; 04561 lid[2] = 18; 04562 lid[3] = 9; 04563 lid[4] = 4; 04564 lid[5] = 10; 04565 } 04566 04567 EntityHandle vstart = level_mesh[cur_level].start_vertex; 04568 04569 for( int i = 0; i < 6; i++ ) 04570 { 04571 EntityHandle vid = vbuffer[lid[i]]; 04572 ocoords[3 * i] = level_mesh[cur_level].coordinates[0][vid - vstart]; 04573 ocoords[3 * i + 1] = level_mesh[cur_level].coordinates[1][vid - vstart]; 04574 ocoords[3 * i + 2] = level_mesh[cur_level].coordinates[2][vid - vstart]; 04575 } 04576 04577 return MB_SUCCESS; 04578 } 04579 04580 int NestedRefine::find_shortest_diagonal_octahedron( int cur_level, int deg, EntityHandle* vbuffer ) 04581 { 04582 ErrorCode error; 04583 double coords[18]; 04584 error = get_octahedron_corner_coords( cur_level, deg, vbuffer, coords ); 04585 if( error != MB_SUCCESS ) MB_SET_ERR( MB_FAILURE, "Error in obtaining octahedron corner coordinates" ); 04586 04587 int diag_map[6] = { 1, 3, 2, 4, 5, 0 }; 04588 double length = std::numeric_limits< double >::max(); 04589 04590 int diag = 0; 04591 double x, y, z; 04592 x = y = z = 0; 04593 04594 for( int d = 0; d < 3; d++ ) 04595 { 04596 int id1 = diag_map[2 * d]; 04597 int id2 = diag_map[2 * d + 1]; 04598 x = coords[3 * id1] - coords[3 * id2]; 04599 y = coords[3 * id1 + 1] - coords[3 * id2 + 1]; 04600 z = coords[3 * id1 + 2] - coords[3 * id2 + 2]; 04601 double dlen = sqrt( x * x + y * y + z * z ); 04602 if( dlen < length ) 04603 { 04604 length = dlen; 04605 diag = d + 1; 04606 } 04607 } 04608 04609 return diag; 04610 } 04611 04612 int NestedRefine::get_local_vid( EntityHandle vid, EntityHandle ent, int level ) 04613 { 04614 ErrorCode error; 04615 // Given a vertex, find its local id in the given entity 04616 std::vector< EntityHandle > conn; 04617 04618 error = get_connectivity( ent, level + 1, conn ); 04619 if( error != MB_SUCCESS ) MB_SET_ERR( MB_FAILURE, "Error in getting connectivity of the requested entity" ); 04620 04621 int lid = -1; 04622 for( int i = 0; i < (int)conn.size(); i++ ) 04623 { 04624 if( conn[i] == vid ) 04625 { 04626 lid = i; 04627 break; 04628 } 04629 } 04630 if( lid < 0 ) MB_SET_ERR( MB_FAILURE, "Error in getting local vertex id in the given entity" ); 04631 return lid; 04632 } 04633 04634 int NestedRefine::get_index_from_degree( int degree ) 04635 { 04636 int d = deg_index.find( degree )->second; 04637 return d; 04638 } 04639 04640 /* 04641 ErrorCode NestedRefine::print_maps_1D(int level) 04642 { 04643 ErrorCode error; 04644 int nv, ne; 04645 nv = level_mesh[level].num_verts; 04646 ne = level_mesh[level].num_edges; 04647 04648 EntityHandle start_edge = level_mesh[level].start_edge; 04649 04650 //V2HV 04651 std::cout<<"<V2HV_EID, V2HV_LVID>"<<std::endl; 04652 for (int i=0; i<nv; i++) 04653 { 04654 EntityHandle eid=0; 04655 int lvid=0; 04656 EntityHandle vid = level_mesh[level].start_vertex+i; 04657 error = ahf->get_incident_map(MBEDGE, vid, eid, lvid); MB_CHK_ERR(error); 04658 04659 std::cout<<"For vertex = "<<vid<<"::Incident halfvertex "<<eid<<" "<<lvid<<std::endl; 04660 } 04661 04662 //SIBHVS 04663 std::cout<<"start_edge = "<<start_edge<<std::endl; 04664 std::cout<<"<SIBHVS_EID,SIBHVS_LVID>"<<std::endl; 04665 for (int i=0; i<ne; i++) 04666 { 04667 EntityHandle ent = start_edge+i; 04668 04669 EntityHandle eid[2]; int lvid[2]; 04670 error = ahf->get_sibling_map(MBEDGE, ent, &eid[0], &lvid[0], 2); MB_CHK_ERR(error); 04671 std::cout<<"<"<<eid[0]<<","<<lvid[0]<<">"<<" "<<"<"<<eid[1]<<","<<lvid[1]<<">"<<std::endl; 04672 } 04673 04674 return MB_SUCCESS; 04675 } 04676 04677 ErrorCode NestedRefine::print_maps_2D(int level, EntityType type) 04678 { 04679 ErrorCode error; 04680 int nv, nf; 04681 nv = level_mesh[level].num_verts; 04682 nf = level_mesh[level].num_faces; 04683 04684 EntityHandle start_face = level_mesh[level].start_face; 04685 04686 //V2HV 04687 std::cout<<"<V2HE_FID, V2HE_LEID>"<<std::endl; 04688 for (int i=0; i<nv; i++) 04689 { 04690 EntityHandle fid=0; 04691 int leid=0; 04692 EntityHandle vid = level_mesh[level].start_vertex+i; 04693 error = ahf->get_incident_map(type, vid, fid, leid); MB_CHK_ERR(error); 04694 04695 std::cout<<"For vertex = "<<vid<<"::Incident halfedge "<<fid<<" "<<leid<<std::endl; 04696 } 04697 04698 //SIBHES 04699 std::cout<<"start_face = "<<start_face<<std::endl; 04700 std::cout<<"<SIBHES_FID,SIBHES_LEID>"<<std::endl; 04701 EntityType ftype = mbImpl->type_from_handle(*_infaces.begin()); 04702 int nepf = ahf->lConnMap2D[ftype-2].num_verts_in_face; 04703 04704 EntityHandle *fid = new EntityHandle[nepf]; 04705 int *leid = new int[nepf]; 04706 04707 for (int i=0; i<nf; i++) 04708 { 04709 for (int j=0; j<nepf; j++) 04710 { 04711 fid[j] = 0; 04712 leid[j] = 0; 04713 } 04714 04715 EntityHandle ent = start_face+i; 04716 error = ahf->get_sibling_map(type, ent, fid, leid, nepf); MB_CHK_ERR(error); 04717 04718 for (int j=0; j<nepf; j++){ 04719 std::cout<<"<"<<fid[j]<<","<<leid[j]<<">"<<" "; 04720 } 04721 std::cout<<std::endl; 04722 } 04723 04724 delete [] fid; 04725 delete [] leid; 04726 04727 return MB_SUCCESS; 04728 } 04729 04730 ErrorCode NestedRefine::print_maps_3D(int level, EntityType type) 04731 { 04732 ErrorCode error; 04733 int nv, nc; 04734 nv = level_mesh[level].num_verts; 04735 nc = level_mesh[level].num_cells; 04736 EntityHandle start_cell = level_mesh[level].start_cell; 04737 04738 //V2HF 04739 std::cout<<"<V2HF_CID, V2HF_LFID>"<<std::endl; 04740 for (int i=0; i<nv; i++) 04741 { 04742 EntityHandle cid=0; 04743 int lfid=0; 04744 EntityHandle vid = level_mesh[level].start_vertex+i; 04745 error = ahf->get_incident_map(type, vid, cid, lfid); MB_CHK_ERR(error); 04746 04747 std::cout<<"For vertex = "<<vid<<"::Incident halfface "<<cid<<" "<<lfid<<std::endl; 04748 } 04749 04750 //SIBHFS 04751 std::cout<<"start_cell = "<<start_cell<<std::endl; 04752 std::cout<<"<SIBHFS_CID,SIBHFS_LFID>"<<std::endl; 04753 int index = ahf->get_index_in_lmap(start_cell); 04754 int nfpc = ahf->lConnMap3D[index].num_faces_in_cell; 04755 04756 EntityHandle *cid = new EntityHandle[nfpc]; 04757 int *lfid = new int[nfpc]; 04758 for (int i=0; i<nc; i++) 04759 { 04760 for (int k=0; k<nfpc; k++) 04761 { 04762 cid[k] = 0; 04763 lfid[k] = 0; 04764 } 04765 04766 EntityHandle ent = start_cell+i; 04767 error = ahf->get_sibling_map(type, ent, cid, lfid, nfpc); MB_CHK_ERR(error); 04768 04769 for (int j=0; j<nfpc; j++){ 04770 std::cout<<"<"<<cid[j]<<","<<lfid[j]<<">"<<" "; 04771 } 04772 std::cout<<std::endl; 04773 } 04774 04775 delete [] cid; 04776 delete [] lfid; 04777 04778 return MB_SUCCESS; 04779 } 04780 04781 */ 04782 } // namespace moab