MOAB: Mesh Oriented datABase
(version 5.4.1)
|
00001 #include "moab/ParallelComm.hpp" 00002 #include "MBParallelConventions.h" 00003 #include "MBTagConventions.hpp" 00004 #include "moab/Core.hpp" 00005 #include "moab/MeshTopoUtil.hpp" 00006 #include "ReadParallel.hpp" 00007 #include "moab/FileOptions.hpp" 00008 #include "TestUtil.hpp" 00009 #include <algorithm> 00010 #include <vector> 00011 #include <set> 00012 #include <sstream> 00013 00014 using namespace moab; 00015 00016 #ifdef MOAB_HAVE_MPI 00017 #include "moab_mpi.h" 00018 #else 00019 #define MPI_COMM_WORLD 0 00020 #endif 00021 00022 /** Test pack/unpack of vertices */ 00023 void test_pack_vertices(); 00024 /** Test pack/unpack of elements */ 00025 void test_pack_elements(); 00026 /** Test pack/unpack of higher-order elements */ 00027 void test_pack_higher_order(); 00028 /** Test pack/unpack of polygons & polyhedra */ 00029 void test_pack_poly(); 00030 /** Test pack/unpack of entity sets */ 00031 void test_pack_sets_simple(); 00032 /** Test pack/unpack of entity sets including implicit packing of set contents */ 00033 void test_pack_set_contents(); 00034 /** Test pack/unpack of entity sets containing entity sets */ 00035 void test_pack_sets_of_sets(); 00036 /** Test pack/unpack of set parent/child relations */ 00037 void test_pack_set_parent_child(); 00038 /** Test pack/unpack tag values*/ 00039 void test_pack_tag_data_sparse(); 00040 void test_pack_tag_data_dense(); 00041 void test_pack_tag_data_default_value(); 00042 /** Test pack/unpack tag values*/ 00043 void test_pack_bit_tag_data(); 00044 /** Test pack/unpack of variable length tag values*/ 00045 void test_pack_variable_length_tag(); 00046 /** Test pack/unpack tag values*/ 00047 void test_pack_tag_handle_data(); 00048 /** Test pack/unpack of shared entities in 2d*/ 00049 void test_pack_shared_entities_2d(); 00050 /** Test pack/unpack of shared entities in 3d*/ 00051 void test_pack_shared_entities_3d(); 00052 /** Test filter_pstatus function*/ 00053 void test_filter_pstatus(); 00054 /** Test creating a new ParallelComm instance in addition to an existing one*/ 00055 void test_new_pcomm_instance(); 00056 00057 int rank = 0; 00058 00059 int main( int argc, char* argv[] ) 00060 { 00061 #ifdef MOAB_HAVE_MPI 00062 MPI_Init( &argc, &argv ); 00063 MPI_Comm_rank( MPI_COMM_WORLD, &rank ); 00064 #endif 00065 00066 int num_err = 0; 00067 num_err += RUN_TEST( test_pack_vertices ); 00068 num_err += RUN_TEST( test_pack_elements ); 00069 num_err += RUN_TEST( test_pack_higher_order ); 00070 num_err += RUN_TEST( test_pack_poly ); 00071 num_err += RUN_TEST( test_pack_sets_simple ); 00072 num_err += RUN_TEST( test_pack_set_contents ); 00073 num_err += RUN_TEST( test_pack_sets_of_sets ); 00074 num_err += RUN_TEST( test_pack_set_parent_child ); 00075 num_err += RUN_TEST( test_pack_tag_data_sparse ); 00076 num_err += RUN_TEST( test_pack_tag_data_dense ); 00077 num_err += RUN_TEST( test_pack_tag_data_default_value ); 00078 // num_err += RUN_TEST( test_pack_bit_tag_data ); 00079 num_err += RUN_TEST( test_pack_variable_length_tag ); 00080 num_err += RUN_TEST( test_pack_tag_handle_data ); 00081 num_err += RUN_TEST( test_pack_shared_entities_2d ); 00082 num_err += RUN_TEST( test_pack_shared_entities_3d ); 00083 num_err += RUN_TEST( test_filter_pstatus ); 00084 num_err += RUN_TEST( test_new_pcomm_instance ); 00085 00086 #ifdef MOAB_HAVE_MPI 00087 MPI_Finalize(); 00088 #endif 00089 return num_err; 00090 } 00091 00092 /* Utility method: pack mesh data, clear moab instance, and unpack */ 00093 void pack_unpack_noremoteh( Core& moab, Range& entities ) 00094 { 00095 ErrorCode rval; 00096 if( entities.empty() ) 00097 { 00098 rval = moab.get_entities_by_handle( 0, entities );CHECK_ERR( rval ); 00099 } 00100 00101 ParallelComm* pcomm = new ParallelComm( &moab, MPI_COMM_WORLD ); 00102 00103 // get the necessary vertices too 00104 Range tmp_range = entities.subset_by_type( MBENTITYSET ); 00105 entities = subtract( entities, tmp_range ); 00106 rval = moab.get_adjacencies( entities, 0, false, entities, Interface::UNION );CHECK_ERR( rval ); 00107 entities.merge( tmp_range ); 00108 00109 ParallelComm::Buffer buff( ParallelComm::INITIAL_BUFF_SIZE ); 00110 buff.reset_ptr( sizeof( int ) ); 00111 rval = pcomm->pack_buffer( entities, false, true, false, -1, &buff );CHECK_ERR( rval ); 00112 buff.set_stored_size(); 00113 00114 delete pcomm; 00115 moab.~Core(); 00116 00117 new( &moab ) Core(); 00118 pcomm = new ParallelComm( &moab, MPI_COMM_WORLD ); 00119 00120 entities.clear(); 00121 std::vector< std::vector< EntityHandle > > L1hloc, L1hrem; 00122 std::vector< std::vector< int > > L1p; 00123 std::vector< EntityHandle > L2hloc, L2hrem; 00124 std::vector< unsigned int > L2p; 00125 buff.reset_ptr( sizeof( int ) ); 00126 std::vector< EntityHandle > entities_vec( entities.size() ); 00127 std::copy( entities.begin(), entities.end(), entities_vec.begin() ); 00128 rval = pcomm->unpack_buffer( buff.buff_ptr, false, -1, -1, L1hloc, L1hrem, L1p, L2hloc, L2hrem, L2p, entities_vec );CHECK_ERR( rval ); 00129 std::copy( entities_vec.begin(), entities_vec.end(), range_inserter( entities ) ); 00130 00131 delete pcomm; 00132 } 00133 void pack_unpack_noremoteh( Core& moab ) 00134 { 00135 Range empty; 00136 pack_unpack_noremoteh( moab, empty ); 00137 } 00138 00139 /* Utility method -- check expected sizes */ 00140 void check_sizes( Interface& moab, 00141 int num_vtx, 00142 int num_edge, 00143 int num_tri, 00144 int num_quad, 00145 int num_polygon, 00146 int num_tet, 00147 int num_pyr, 00148 int num_wedge, 00149 int num_knife, 00150 int num_hex, 00151 int num_polyhedron ) 00152 { 00153 int count; 00154 ErrorCode rval; 00155 00156 rval = moab.get_number_entities_by_type( 0, MBVERTEX, count );CHECK_ERR( rval ); 00157 CHECK_EQUAL( num_vtx, count ); 00158 00159 rval = moab.get_number_entities_by_type( 0, MBEDGE, count );CHECK_ERR( rval ); 00160 CHECK_EQUAL( num_edge, count ); 00161 00162 rval = moab.get_number_entities_by_type( 0, MBTRI, count );CHECK_ERR( rval ); 00163 CHECK_EQUAL( num_tri, count ); 00164 00165 rval = moab.get_number_entities_by_type( 0, MBQUAD, count );CHECK_ERR( rval ); 00166 CHECK_EQUAL( num_quad, count ); 00167 00168 rval = moab.get_number_entities_by_type( 0, MBPOLYGON, count );CHECK_ERR( rval ); 00169 CHECK_EQUAL( num_polygon, count ); 00170 00171 rval = moab.get_number_entities_by_type( 0, MBTET, count );CHECK_ERR( rval ); 00172 CHECK_EQUAL( num_tet, count ); 00173 00174 rval = moab.get_number_entities_by_type( 0, MBPYRAMID, count );CHECK_ERR( rval ); 00175 CHECK_EQUAL( num_pyr, count ); 00176 00177 rval = moab.get_number_entities_by_type( 0, MBPRISM, count );CHECK_ERR( rval ); 00178 CHECK_EQUAL( num_wedge, count ); 00179 00180 rval = moab.get_number_entities_by_type( 0, MBKNIFE, count );CHECK_ERR( rval ); 00181 CHECK_EQUAL( num_knife, count ); 00182 00183 rval = moab.get_number_entities_by_type( 0, MBHEX, count );CHECK_ERR( rval ); 00184 CHECK_EQUAL( num_hex, count ); 00185 00186 rval = moab.get_number_entities_by_type( 0, MBPOLYHEDRON, count );CHECK_ERR( rval ); 00187 CHECK_EQUAL( num_polyhedron, count ); 00188 } 00189 00190 /* Create a simple mesh for use in tests */ 00191 void create_simple_grid( Interface& moab, unsigned x, unsigned y, unsigned z ); 00192 void create_simple_grid( Interface& moab, unsigned xyz = 3 ) 00193 { 00194 create_simple_grid( moab, xyz, xyz, xyz ); 00195 } 00196 void create_simple_grid( Interface& moab, unsigned x, unsigned y, unsigned z ) 00197 { 00198 ErrorCode rval; 00199 EntityHandle* verts = new EntityHandle[x * y * z]; 00200 for( unsigned k = 0; k < z; ++k ) 00201 for( unsigned j = 0; j < y; ++j ) 00202 for( unsigned i = 0; i < x; ++i ) 00203 { 00204 const double coords[3] = { static_cast< double >( i ), static_cast< double >( j ), 00205 static_cast< double >( k ) }; 00206 rval = moab.create_vertex( coords, verts[x * y * k + x * j + i] );CHECK_ERR( rval ); 00207 } 00208 00209 EntityHandle* elems = new EntityHandle[( x - 1 ) * ( y - 1 ) * ( z - 1 )]; 00210 for( unsigned k = 0; k < ( z - 1 ); ++k ) 00211 for( unsigned j = 0; j < ( y - 1 ); ++j ) 00212 for( unsigned i = 0; i < ( x - 1 ); ++i ) 00213 { 00214 const size_t idx = (size_t)i + (size_t)j * x + (size_t)k * x * y; 00215 const EntityHandle conn[8] = { 00216 verts[idx], verts[idx + 1], verts[idx + x + 1], verts[idx + x], 00217 verts[idx + x * y], verts[idx + x * y + 1], verts[idx + x * y + x + 1], verts[idx + x * y + x] }; 00218 rval = moab.create_element( MBHEX, conn, 8, elems[( x - 1 ) * ( y - 1 ) * k + ( x - 1 ) * j + i] );CHECK_ERR( rval ); 00219 } 00220 delete[] verts; 00221 delete[] elems; 00222 } 00223 00224 ErrorCode create_patch( Interface* moab, Range& verts, Range& quads, unsigned int n, double* xyz, int* gids ) 00225 { 00226 // create vertices/quads in square array 00227 ErrorCode result = moab->create_vertices( xyz, n * n, verts ); 00228 if( MB_SUCCESS != result ) return result; 00229 std::vector< EntityHandle > connect; 00230 for( unsigned int j = 0; j < n - 1; j++ ) 00231 { 00232 for( unsigned int i = 0; i < n - 1; i++ ) 00233 { 00234 connect.push_back( verts[n * j + i] ); 00235 connect.push_back( verts[n * j + i + 1] ); 00236 connect.push_back( verts[n * ( j + 1 ) + i + 1] ); 00237 connect.push_back( verts[n * ( j + 1 ) + i] ); 00238 } 00239 } 00240 00241 unsigned int nquads = ( n - 1 ) * ( n - 1 ); 00242 for( unsigned int i = 0; i < nquads; i++ ) 00243 { 00244 EntityHandle dum_quad; 00245 result = moab->create_element( MBQUAD, &connect[4 * i], 4, dum_quad ); 00246 if( MB_SUCCESS != result ) return result; 00247 quads.insert( dum_quad ); 00248 } 00249 00250 // global ids 00251 Tag gid_tag = moab->globalId_tag(); 00252 result = moab->tag_set_data( gid_tag, verts, gids ); 00253 if( MB_SUCCESS != result ) return result; 00254 00255 return result; 00256 } 00257 00258 ErrorCode create_shared_grid_2d( ParallelComm** pc, Range* verts, Range* quads ) 00259 { 00260 // 00261 // P2______ 00262 // /__/__/ /|P1 00263 // y: /__/__/ /|| 00264 // 1 _____ ||/ _____ 1 00265 // | | | |/|-1 | | | 00266 // .5 |__|__| ||/ |__|__| .5 00267 // |P0| | |/-.5 |P3| | 00268 // 0 |__|__| z:0 |__|__| 0 00269 // x:-1 -.5 0 0 .5 1 00270 // 00271 // nodes: P2 00272 // 18 16 14 P1 00273 // 17 15 13 14 00274 // 6 7 8 13 12 00275 // 8 11 10 00276 // 6 7 8 5 9 8 23 24 P3 00277 // 3 4 5 2 5 21 22 00278 // P0 0 1 2 2 19 20 00279 00280 int gids[] = { 00281 0, 1, 2, 3, 4, 5, 6, 7, 8, // P0 00282 2, 9, 10, 5, 11, 12, 8, 13, 14, // P1 00283 6, 7, 8, 17, 15, 13, 18, 16, 14, // P2 00284 2, 19, 20, 5, 21, 22, 8, 23, 24 // P3 00285 }; 00286 double xyz[] = { 00287 -1.0, 0.0, 0.0, -0.5, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.5, 0.0, -0.5, 0.5, 0.0, 0.0, 0.5, 0.0, 00288 -1.0, 1.0, 0.0, -0.5, 1.0, 0.0, 0.0, 1.0, 0.0, // n0-8 00289 0.0, 0.0, -0.5, 0.0, 0.0, -1.0, 0.0, 0.5, -0.5, 0.0, 0.5, -1.0, 0.0, 1.0, -0.5, 0.0, 1.0, -1.0, // n9-14 00290 -0.5, 1.0, -0.5, -0.5, 1.0, -1.0, -1.0, 1.0, -0.5, -1.0, 1.0, -1.0, // n15-18 00291 0.5, 0.0, 0.0, 1.0, 0.0, 0.0, 0.5, 0.5, 0.0, 1.0, 0.5, 0.0, 0.5, 1.0, 0.0, 1.0, 1.0, 0.0, // n19-24 00292 }; 00293 double xyztmp[27]; 00294 00295 // create the test mesh above 00296 for( unsigned int i = 0; i < 4; i++ ) 00297 { 00298 for( unsigned int j = 0; j < 9; j++ ) 00299 { 00300 xyztmp[3 * j] = xyz[3 * gids[9 * i + j]]; 00301 xyztmp[3 * j + 1] = xyz[3 * gids[9 * i + j] + 1]; 00302 xyztmp[3 * j + 2] = xyz[3 * gids[9 * i + j] + 2]; 00303 } 00304 00305 create_patch( pc[i]->get_moab(), verts[i], quads[i], 3, xyztmp, &gids[9 * i] ); 00306 } 00307 00308 ErrorCode rval = ParallelComm::resolve_shared_ents( pc, 4, 0, 2 );CHECK_ERR( rval ); 00309 00310 return rval; 00311 } 00312 00313 ErrorCode create_shared_grid_3d( ParallelComm** pc, Range* verts, Range* hexes ) 00314 { 00315 // 00316 // 4 _____ _____ 00317 // | | | | | | 00318 // 3|__|__| |__|__| GIDS HANDLES 00319 // |P1| | |P2| | 00320 // |__|__| |__|__| 20 21 22 22 23 24 7 8 9 7 8 9 00321 // 2 ___________ 15 16 17 17 18 19 4 5 6 4 5 6 00322 // | | | | | 10 11 12 12 13 14 1 2 3 1 2 3 00323 // / 1|__|__|__|__| 00324 // | | |P0| | | 10 11 12 13 14 10 11 12 13 14 00325 // J 0|__|__|__|__| 5 6 7 8 9 5 6 7 8 9 00326 // I-> 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 00327 // 00328 // P3 - k = 2..4 00329 00330 // create structured meshes 00331 // ijkmin[p][ijk], ijkmax[p][ijk] 00332 #define P 4 00333 int ijkmin[P][3] = { { 0, 0, 0 }, { 0, 2, 0 }, { 2, 2, 0 }, { 0, 0, 2 } }; 00334 int ijkmax[P][3] = { { 4, 2, 2 }, { 2, 4, 2 }, { 4, 4, 2 }, { 4, 4, 4 } }; 00335 00336 int nijk[P][3]; 00337 int NIJK[3] = { 0, 0, 0 }; 00338 #define INDEXG( i, j, k ) ( (k)*NIJK[1] * NIJK[0] + (j)*NIJK[0] + ( i ) ) 00339 #define INDEXL( i, j, k ) \ 00340 ( ( (k)-ijkmin[p][2] ) * nijk[p][1] * nijk[p][0] + ( (j)-ijkmin[p][1] ) * nijk[p][0] + ( (i)-ijkmin[p][0] ) ) 00341 00342 int p, i, j, k; 00343 for( p = 0; p < P; p++ ) 00344 { 00345 for( i = 0; i < 3; i++ ) 00346 { 00347 nijk[p][i] = ijkmax[p][i] - ijkmin[p][i] + 1; 00348 NIJK[i] = std::max( NIJK[i], nijk[p][i] ); 00349 } 00350 } 00351 00352 std::vector< int > gids; 00353 std::vector< double > xyz; 00354 ErrorCode rval; 00355 Tag gid_tag; 00356 00357 for( p = 0; p < P; p++ ) 00358 { 00359 gid_tag = pc[p]->get_moab()->globalId_tag(); 00360 00361 // make vertices 00362 int nverts = nijk[p][0] * nijk[p][1] * nijk[p][2]; 00363 xyz.resize( 3 * nverts ); 00364 gids.resize( nverts ); 00365 00366 // set vertex gids 00367 int nv = 0; 00368 for( k = ijkmin[p][2]; k <= ijkmax[p][2]; k++ ) 00369 for( j = ijkmin[p][1]; j <= ijkmax[p][1]; j++ ) 00370 for( i = ijkmin[p][0]; i <= ijkmax[p][0]; i++ ) 00371 { 00372 // xyz 00373 xyz[3 * nv] = i; 00374 xyz[3 * nv + 1] = j; 00375 xyz[3 * nv + 2] = k; 00376 00377 // gid 00378 gids[nv++] = INDEXG( i, j, k ); 00379 } 00380 00381 rval = pc[p]->get_moab()->create_vertices( &xyz[0], nverts, verts[p] );CHECK_ERR( rval ); 00382 00383 rval = pc[p]->get_moab()->tag_set_data( gid_tag, verts[p], &gids[0] ); 00384 if( MB_SUCCESS != rval ) return rval; 00385 00386 // make elements 00387 nv = 0; 00388 EntityHandle connect[8], dum_hex; 00389 for( k = ijkmin[p][2]; k < ijkmax[p][2]; k++ ) 00390 for( j = ijkmin[p][1]; j < ijkmax[p][1]; j++ ) 00391 for( i = ijkmin[p][0]; i < ijkmax[p][0]; i++ ) 00392 { 00393 // gid 00394 connect[0] = verts[p][INDEXL( i, j, k )]; 00395 connect[1] = verts[p][INDEXL( i + 1, j, k )]; 00396 connect[2] = verts[p][INDEXL( i + 1, j + 1, k )]; 00397 connect[3] = verts[p][INDEXL( i, j + 1, k )]; 00398 connect[4] = verts[p][INDEXL( i, j, k + 1 )]; 00399 connect[5] = verts[p][INDEXL( i + 1, j, k + 1 )]; 00400 connect[6] = verts[p][INDEXL( i + 1, j + 1, k + 1 )]; 00401 connect[7] = verts[p][INDEXL( i, j + 1, k + 1 )]; 00402 rval = pc[p]->get_moab()->create_element( MBHEX, connect, 8, dum_hex ); 00403 hexes[p].insert( dum_hex ); 00404 gids[nv++] = INDEXG( i, j, k ); 00405 } 00406 rval = pc[p]->get_moab()->tag_set_data( gid_tag, hexes[p], &gids[0] ); 00407 if( MB_SUCCESS != rval ) return rval; 00408 00409 std::ostringstream fname; 00410 fname << "tmp" << p << "." << rank << ".h5m"; 00411 rval = pc[p]->get_moab()->write_file( fname.str().c_str() ); 00412 if( MB_SUCCESS != rval ) return rval; 00413 } 00414 rval = ParallelComm::resolve_shared_ents( pc, 4, 0, 3 );CHECK_ERR( rval ); 00415 return rval; 00416 } 00417 00418 void test_pack_vertices() 00419 { 00420 Core moab; 00421 ErrorCode rval; 00422 Range verts; 00423 00424 const size_t num_verts = 4; 00425 const double coords[3 * num_verts] = { -0.5, -1. / 3, 0.0, 0.5, -1. / 3, 0.0, 00426 0.0, 2. / 3, 0.0, 0.0, 0.0, 0.745356 }; 00427 00428 rval = moab.create_vertices( coords, num_verts, verts );CHECK_ERR( rval ); 00429 00430 pack_unpack_noremoteh( moab, verts ); 00431 CHECK_EQUAL( num_verts, verts.size() ); 00432 00433 double coords2[3 * num_verts]; 00434 rval = moab.get_coords( verts, coords2 );CHECK_ERR( rval ); 00435 00436 std::vector< bool > seen( num_verts, false ); 00437 for( unsigned i = 0; i < num_verts; ++i ) 00438 { 00439 unsigned j; 00440 for( j = 0; j < num_verts; ++j ) 00441 if( coords[3 * j] == coords2[3 * i] && coords[3 * j + 1] == coords2[3 * i + 1] && 00442 coords[3 * j + 2] == coords2[3 * i + 2] ) 00443 break; 00444 CHECK( j < num_verts ); 00445 CHECK( !seen[j] ); 00446 seen[j] = true; 00447 } 00448 } 00449 00450 void test_pack_elements() 00451 { 00452 Core moab; 00453 ErrorCode rval; 00454 Range elems; 00455 00456 // define some vertices 00457 const size_t num_verts = 12; 00458 EntityHandle verts[num_verts]; 00459 const double hex_corners[3 * num_verts] = { -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 0, 1, -1, 0, 00460 1, 1, 0, -1, 1, 0, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1 }; 00461 for( size_t i = 0; i < num_verts; ++i ) 00462 { 00463 rval = moab.create_vertex( hex_corners + 3 * i, verts[i] );CHECK_ERR( rval ); 00464 } 00465 00466 // define two adjacent hexes 00467 const size_t num_hex = 2; 00468 EntityHandle hexes[num_hex]; 00469 rval = moab.create_element( MBHEX, verts, 8, hexes[0] );CHECK_ERR( rval ); 00470 elems.insert( hexes[0] ); 00471 rval = moab.create_element( MBHEX, verts + 4, 8, hexes[1] );CHECK_ERR( rval ); 00472 elems.insert( hexes[1] ); 00473 00474 // define a single quad on the adjacent sides of the hexes 00475 const size_t num_quad = 1; 00476 EntityHandle quad; 00477 rval = moab.create_element( MBQUAD, verts + 4, 4, quad );CHECK_ERR( rval ); 00478 elems.insert( quad ); 00479 00480 // define a decomposition of the first hex into 5 tets 00481 const size_t num_tet = 5; 00482 EntityHandle tets[num_tet]; 00483 EntityHandle tet_conn[num_tet][4] = { { verts[0], verts[1], verts[3], verts[4] }, 00484 { verts[1], verts[2], verts[3], verts[6] }, 00485 { verts[1], verts[3], verts[4], verts[6] }, 00486 { verts[4], verts[6], verts[5], verts[1] }, 00487 { verts[7], verts[6], verts[4], verts[3] } }; 00488 rval = moab.create_element( MBTET, tet_conn[0], 4, tets[0] );CHECK_ERR( rval ); 00489 elems.insert( tets[0] ); 00490 rval = moab.create_element( MBTET, tet_conn[1], 4, tets[1] );CHECK_ERR( rval ); 00491 elems.insert( tets[1] ); 00492 rval = moab.create_element( MBTET, tet_conn[2], 4, tets[2] );CHECK_ERR( rval ); 00493 elems.insert( tets[2] ); 00494 rval = moab.create_element( MBTET, tet_conn[3], 4, tets[3] );CHECK_ERR( rval ); 00495 elems.insert( tets[3] ); 00496 rval = moab.create_element( MBTET, tet_conn[4], 4, tets[4] );CHECK_ERR( rval ); 00497 elems.insert( tets[4] ); 00498 00499 // define the 4 shared faces of the above tets as tris 00500 // (the faces of the 3rd tet) 00501 const size_t num_tri = 4; 00502 EntityHandle tris[num_tri]; 00503 EntityHandle tri_conn[num_tri][3] = { { verts[3], verts[1], verts[4] }, 00504 { verts[1], verts[6], verts[4] }, 00505 { verts[1], verts[3], verts[6] }, 00506 { verts[3], verts[4], verts[6] } }; 00507 rval = moab.create_element( MBTRI, tri_conn[0], 3, tris[0] );CHECK_ERR( rval ); 00508 elems.insert( tris[0] ); 00509 rval = moab.create_element( MBTRI, tri_conn[1], 3, tris[1] );CHECK_ERR( rval ); 00510 elems.insert( tris[1] ); 00511 rval = moab.create_element( MBTRI, tri_conn[2], 3, tris[2] );CHECK_ERR( rval ); 00512 elems.insert( tris[2] ); 00513 rval = moab.create_element( MBTRI, tri_conn[3], 3, tris[3] );CHECK_ERR( rval ); 00514 elems.insert( tris[3] ); 00515 00516 // define a decomposition of the second hex into two wedges 00517 const size_t num_wedge = 2; 00518 EntityHandle wedges[num_wedge]; 00519 EntityHandle wedge_conn[num_wedge][6] = { { verts[4], verts[5], verts[7], verts[8], verts[9], verts[11] }, 00520 { verts[5], verts[6], verts[7], verts[9], verts[10], verts[11] } }; 00521 rval = moab.create_element( MBPRISM, wedge_conn[0], 6, wedges[0] );CHECK_ERR( rval ); 00522 elems.insert( wedges[0] ); 00523 rval = moab.create_element( MBPRISM, wedge_conn[1], 6, wedges[1] );CHECK_ERR( rval ); 00524 elems.insert( wedges[1] ); 00525 00526 // define a pyramid 00527 EntityHandle pyr; 00528 rval = moab.create_element( MBPYRAMID, verts, 5, pyr );CHECK_ERR( rval ); 00529 elems.insert( pyr ); 00530 00531 // pack and unpack mesh 00532 pack_unpack_noremoteh( moab, elems ); 00533 00534 // check_counts 00535 check_sizes( moab, num_verts, 0, num_tri, num_quad, 0, num_tet, 1, num_wedge, 0, num_hex, 0 ); 00536 00537 // get connectivity for two hexes and a quad 00538 Range range; 00539 const EntityHandle *conn1, *conn2, *conn3; 00540 int len1, len2, len3; 00541 rval = moab.get_entities_by_type( 0, MBHEX, range );CHECK_ERR( rval ); 00542 CHECK_EQUAL( num_hex, range.size() ); 00543 rval = moab.get_connectivity( range.front(), conn1, len1, true );CHECK_ERR( rval ); 00544 CHECK_EQUAL( 8, len1 ); 00545 rval = moab.get_connectivity( range.back(), conn2, len2, true );CHECK_ERR( rval ); 00546 CHECK_EQUAL( 8, len2 ); 00547 range.clear(); 00548 rval = moab.get_entities_by_type( 0, MBQUAD, range );CHECK_ERR( rval ); 00549 CHECK_EQUAL( num_quad, range.size() ); 00550 rval = moab.get_connectivity( range.front(), conn3, len3, true );CHECK_ERR( rval ); 00551 CHECK_EQUAL( 4, len3 ); 00552 00553 // Check if hexes are reversed 00554 if( conn1[0] == conn2[4] ) 00555 { 00556 std::swap( conn1, conn2 ); 00557 } 00558 00559 // Check consistant connectivity between hexes 00560 CHECK_EQUAL( conn1[4], conn2[0] ); 00561 CHECK_EQUAL( conn1[5], conn2[1] ); 00562 CHECK_EQUAL( conn1[6], conn2[2] ); 00563 CHECK_EQUAL( conn1[7], conn2[3] ); 00564 // Check connectivity of quad on shared face 00565 CHECK_EQUAL( conn1[4], conn3[0] ); 00566 CHECK_EQUAL( conn1[5], conn3[1] ); 00567 CHECK_EQUAL( conn1[6], conn3[2] ); 00568 CHECK_EQUAL( conn1[7], conn3[3] ); 00569 // Check coordinates 00570 const EntityHandle combined[12] = { conn1[0], conn1[1], conn1[2], conn1[3], conn3[0], conn3[1], 00571 conn3[2], conn3[3], conn2[4], conn2[5], conn2[6], conn2[7] }; 00572 double coords[36]; 00573 rval = moab.get_coords( combined, 12, coords );CHECK_ERR( rval ); 00574 for( int i = 0; i < 36; ++i ) 00575 { 00576 CHECK_REAL_EQUAL( hex_corners[i], coords[i], 1e-12 ); 00577 } 00578 } 00579 00580 void test_pack_higher_order() 00581 { 00582 Core moab; 00583 ErrorCode rval; 00584 Range elems; 00585 00586 // define coordinates for a pyramid decomposed 00587 // into two 10-node tets 00588 const size_t num_vert = 14; 00589 const double coords[3 * num_vert] = { -1, -1, 0, 0, -1, 0, 1, -1, 0, 1, 0, 0, 1, 1, 00590 0, 0, 1, 0, -1, 1, 0, -1, 0, 0, 0, 0, 0, 0, 00591 0, 1, -.5, -.5, .5, .5, -.5, .5, .5, .5, .5, -.5, .5, .5 }; 00592 EntityHandle verts[num_vert]; 00593 for( size_t i = 0; i < num_vert; ++i ) 00594 { 00595 rval = moab.create_vertex( coords + 3 * i, verts[i] );CHECK_ERR( rval ); 00596 } 00597 00598 // define two tets 00599 const size_t num_tet = 2; 00600 EntityHandle tet_conn[2][10] = { 00601 { verts[0], verts[4], verts[9], verts[2], verts[8], verts[12], verts[10], verts[1], verts[3], verts[11] }, 00602 { verts[0], verts[9], verts[4], verts[6], verts[10], verts[12], verts[8], verts[7], verts[13], verts[5] } }; 00603 00604 EntityHandle tets[num_tet]; 00605 rval = moab.create_element( MBTET, tet_conn[0], 10, tets[0] );CHECK_ERR( rval ); 00606 elems.insert( tets[0] ); 00607 rval = moab.create_element( MBTET, tet_conn[1], 10, tets[1] );CHECK_ERR( rval ); 00608 elems.insert( tets[1] ); 00609 00610 // define interior tri face 00611 const size_t num_tri = 1; 00612 EntityHandle tri_conn[6] = { verts[0], verts[4], verts[9], verts[8], verts[12], verts[10] }; 00613 EntityHandle tri; 00614 rval = moab.create_element( MBTRI, tri_conn, 6, tri );CHECK_ERR( rval ); 00615 elems.insert( tri ); 00616 00617 // pack and unpack mesh 00618 pack_unpack_noremoteh( moab, elems ); 00619 00620 // check_counts 00621 check_sizes( moab, num_vert, 0, num_tri, 0, 0, num_tet, 0, 0, 0, 0, 0 ); 00622 00623 // get connectivity for two tets and a tri 00624 Range range; 00625 const EntityHandle *conn1, *conn2, *conn3; 00626 int len1, len2, len3; 00627 rval = moab.get_entities_by_type( 0, MBTET, range );CHECK_ERR( rval ); 00628 CHECK_EQUAL( num_tet, range.size() ); 00629 rval = moab.get_connectivity( range.front(), conn1, len1, false );CHECK_ERR( rval ); 00630 CHECK_EQUAL( 10, len1 ); 00631 rval = moab.get_connectivity( range.back(), conn2, len2, false );CHECK_ERR( rval ); 00632 CHECK_EQUAL( 10, len2 ); 00633 range.clear(); 00634 rval = moab.get_entities_by_type( 0, MBTRI, range );CHECK_ERR( rval ); 00635 CHECK_EQUAL( num_tri, range.size() ); 00636 rval = moab.get_connectivity( range.front(), conn3, len3, false );CHECK_ERR( rval ); 00637 CHECK_EQUAL( 6, len3 ); 00638 00639 // The first face of one of the tets is in the 00640 // same order as the tri. 00641 if( conn3[1] != conn1[1] ) std::swap( conn1, conn2 ); 00642 00643 // check consistant connectivity for face shared by tets 00644 CHECK_EQUAL( conn1[0], conn2[0] ); 00645 CHECK_EQUAL( conn1[1], conn2[2] ); 00646 CHECK_EQUAL( conn1[2], conn2[1] ); 00647 CHECK_EQUAL( conn1[4], conn2[6] ); 00648 CHECK_EQUAL( conn1[5], conn2[5] ); 00649 CHECK_EQUAL( conn1[6], conn2[4] ); 00650 // check connsistant connectivity between tet face and tri 00651 CHECK_EQUAL( conn1[0], conn3[0] ); 00652 CHECK_EQUAL( conn1[1], conn3[1] ); 00653 CHECK_EQUAL( conn1[2], conn3[2] ); 00654 CHECK_EQUAL( conn1[4], conn3[3] ); 00655 CHECK_EQUAL( conn1[5], conn3[4] ); 00656 CHECK_EQUAL( conn1[6], conn3[5] ); 00657 00658 // order vertex handles corresponding to original coordinate list 00659 const EntityHandle combined[num_vert] = { conn1[0], conn1[7], conn1[3], conn1[8], conn1[1], conn2[9], conn2[3], 00660 conn2[7], conn1[4], conn1[2], conn1[6], conn1[9], conn1[5], conn2[8] }; 00661 double coords2[3 * num_vert]; 00662 rval = moab.get_coords( combined, num_vert, coords2 );CHECK_ERR( rval ); 00663 00664 // check vertex coordinates 00665 for( int i = 0; i < 36; ++i ) 00666 { 00667 CHECK_REAL_EQUAL( coords[i], coords2[i], 1e-12 ); 00668 } 00669 } 00670 00671 void test_pack_poly() 00672 { 00673 Core moab; 00674 ErrorCode rval; 00675 Range elems; 00676 00677 // define a pyramid w/ a octagonal base 00678 const double a = 0.5; 00679 const double b = 1 + sqrt( 2.0 ) / 2.0; 00680 const size_t num_vert = 9; 00681 const double coords[3 * num_vert] = { -a, -b, 0, a, -b, 0, b, -a, 0, b, a, 0, a, b, 00682 0, -a, b, 0, -b, a, 0, -b, -a, 0, 0, 0, 1 }; 00683 EntityHandle verts[num_vert]; 00684 for( size_t i = 0; i < num_vert; ++i ) 00685 { 00686 rval = moab.create_vertex( coords + 3 * i, verts[i] );CHECK_ERR( rval ); 00687 } 00688 00689 // define octagonal base 00690 const size_t num_polygon = 1; 00691 EntityHandle octagon; 00692 rval = moab.create_element( MBPOLYGON, verts, 8, octagon );CHECK_ERR( rval ); 00693 00694 // define triangular sides 00695 const size_t num_tri = num_vert - 1; 00696 EntityHandle tri[num_tri]; 00697 for( size_t i = 0; i < num_tri; ++i ) 00698 { 00699 const EntityHandle conn[3] = { verts[i], verts[( i + 1 ) % num_tri], verts[num_tri] }; 00700 rval = moab.create_element( MBTRI, conn, 3, tri[i] );CHECK_ERR( rval ); 00701 } 00702 00703 // define the octagon-based pyramid 00704 const size_t num_polyhedron = 1; 00705 EntityHandle polyhedron; 00706 EntityHandle all_faces[num_vert]; 00707 all_faces[0] = octagon; 00708 std::copy( tri, tri + num_tri, all_faces + 1 ); 00709 rval = moab.create_element( MBPOLYHEDRON, all_faces, num_vert, polyhedron );CHECK_ERR( rval ); 00710 00711 // pack and unpack the mesh 00712 elems.clear(); 00713 elems.insert( polyhedron ); 00714 elems.insert( octagon ); 00715 std::copy( tri, tri + num_tri, range_inserter( elems ) ); 00716 pack_unpack_noremoteh( moab, elems ); 00717 00718 // check counts 00719 check_sizes( moab, num_vert, 0, num_tri, 0, num_polygon, 0, 0, 0, 0, 0, num_polyhedron ); 00720 00721 // get entities 00722 Range range; 00723 rval = moab.get_entities_by_type( 0, MBPOLYHEDRON, range );CHECK_ERR( rval ); 00724 CHECK_EQUAL( num_polyhedron, range.size() ); 00725 polyhedron = range.front(); 00726 00727 range.clear(); 00728 rval = moab.get_entities_by_type( 0, MBPOLYGON, range );CHECK_ERR( rval ); 00729 CHECK_EQUAL( num_polygon, range.size() ); 00730 octagon = range.front(); 00731 00732 range.clear(); 00733 rval = moab.get_entities_by_type( 0, MBTRI, range );CHECK_ERR( rval ); 00734 CHECK_EQUAL( num_tri, range.size() ); 00735 00736 // check coords of octagon vertices 00737 const EntityHandle* oct_conn; 00738 int eight = 0; 00739 rval = moab.get_connectivity( octagon, oct_conn, eight );CHECK_ERR( rval ); 00740 CHECK_EQUAL( 8, eight ); 00741 double oct_coords[3 * 8]; 00742 rval = moab.get_coords( oct_conn, 8, oct_coords );CHECK_ERR( rval ); 00743 for( int i = 0; i < 3 * 8; ++i ) 00744 { 00745 CHECK_REAL_EQUAL( coords[i], oct_coords[i], 1e-12 ); 00746 } 00747 00748 // check faces of polyhedron 00749 std::vector< EntityHandle > volconn; 00750 rval = moab.get_connectivity( &polyhedron, 1, volconn );CHECK_ERR( rval ); 00751 CHECK_EQUAL( num_tri + 1, volconn.size() ); 00752 CHECK_EQUAL( volconn[0], octagon ); 00753 for( Range::iterator i = range.begin(); i != range.end(); ++i ) 00754 { 00755 CHECK( std::find( volconn.begin(), volconn.end(), *i ) != volconn.end() ); 00756 } 00757 } 00758 00759 void test_pack_sets_simple() 00760 { 00761 Core moab; 00762 ErrorCode rval; 00763 create_simple_grid( moab, 3 ); 00764 00765 // delete any existing sets 00766 Range sets; 00767 rval = moab.get_entities_by_type( 0, MBENTITYSET, sets );CHECK_ERR( rval ); 00768 if( !sets.empty() ) 00769 { 00770 rval = moab.delete_entities( sets );CHECK_ERR( rval ); 00771 } 00772 00773 // get all entities 00774 Range entities; 00775 rval = moab.get_entities_by_handle( 0, entities );CHECK_ERR( rval ); 00776 // expect 8 elements and 27 vertices 00777 CHECK_EQUAL( 35, (int)entities.size() ); 00778 CHECK_EQUAL( 27u, entities.num_of_type( MBVERTEX ) ); 00779 CHECK_EQUAL( 8u, entities.num_of_type( MBHEX ) ); 00780 00781 // create five sets: 00782 // 1) one with all the elements and vertices, 00783 // 2) one with half of the elements, 00784 // 3) one with the other half of the elements, 00785 // 4) one with a single vertex, 00786 // 5) an empty set, 00787 EntityHandle all_set, half1_set, half2_set, vertex_set, empty_set; 00788 const unsigned int all_opt = MESHSET_SET | MESHSET_TRACK_OWNER, half1_opt = MESHSET_SET, half2_opt = MESHSET_SET, 00789 vertex_opt = MESHSET_ORDERED, empty_opt = MESHSET_ORDERED | MESHSET_TRACK_OWNER; 00790 rval = moab.create_meshset( all_opt, all_set );CHECK_ERR( rval ); 00791 entities.insert( all_set ); 00792 rval = moab.create_meshset( half1_opt, half1_set );CHECK_ERR( rval ); 00793 entities.insert( half1_set ); 00794 rval = moab.create_meshset( half2_opt, half2_set );CHECK_ERR( rval ); 00795 entities.insert( half2_set ); 00796 rval = moab.create_meshset( vertex_opt, vertex_set );CHECK_ERR( rval ); 00797 entities.insert( vertex_set ); 00798 rval = moab.create_meshset( empty_opt, empty_set );CHECK_ERR( rval ); 00799 entities.insert( empty_set ); 00800 00801 Range elems, verts, half; 00802 rval = moab.get_entities_by_type( 0, MBVERTEX, verts );CHECK_ERR( rval ); 00803 rval = moab.get_entities_by_type( 0, MBHEX, elems );CHECK_ERR( rval ); 00804 00805 rval = moab.add_entities( all_set, verts );CHECK_ERR( rval ); 00806 rval = moab.add_entities( all_set, elems );CHECK_ERR( rval ); 00807 half.merge( elems.begin(), elems.begin() += elems.size() / 2 ); 00808 rval = moab.add_entities( half1_set, half );CHECK_ERR( rval ); 00809 half.clear(); 00810 half.merge( elems.begin() += elems.size() / 2, elems.end() ); 00811 rval = moab.add_entities( half2_set, half );CHECK_ERR( rval ); 00812 EntityHandle vert = verts.front(); 00813 rval = moab.add_entities( vertex_set, &vert, 1 );CHECK_ERR( rval ); 00814 00815 // do pack and unpack 00816 pack_unpack_noremoteh( moab, entities ); 00817 00818 // get entities by type 00819 verts.clear(); 00820 rval = moab.get_entities_by_type( 0, MBVERTEX, verts );CHECK_ERR( rval ); 00821 elems.clear(); 00822 rval = moab.get_entities_by_type( 0, MBHEX, elems );CHECK_ERR( rval ); 00823 sets.clear(); 00824 rval = moab.get_entities_by_type( 0, MBENTITYSET, sets );CHECK_ERR( rval ); 00825 00826 CHECK_EQUAL( 27, (int)verts.size() ); 00827 CHECK_EQUAL( 8, (int)elems.size() ); 00828 CHECK_EQUAL( 5, (int)sets.size() ); 00829 00830 // guess which is which 00831 empty_set = all_set = vertex_set = half1_set = half2_set = 0; 00832 for( Range::iterator i = sets.begin(); i != sets.end(); ++i ) 00833 { 00834 int num_vtx, num_elem; 00835 rval = moab.get_number_entities_by_type( *i, MBVERTEX, num_vtx );CHECK_ERR( rval ); 00836 rval = moab.get_number_entities_by_type( *i, MBHEX, num_elem );CHECK_ERR( rval ); 00837 if( num_vtx == 0 ) 00838 { 00839 if( num_elem == 0 ) 00840 { 00841 CHECK_EQUAL( (EntityHandle)0, empty_set ); 00842 empty_set = *i; 00843 } 00844 else if( !half1_set ) 00845 { 00846 half1_set = *i; 00847 } 00848 else 00849 { 00850 CHECK_EQUAL( (EntityHandle)0, half2_set ); 00851 half2_set = *i; 00852 } 00853 } 00854 else if( num_vtx == 1 ) 00855 { 00856 CHECK_EQUAL( 0, num_elem ); 00857 CHECK_EQUAL( (EntityHandle)0, vertex_set ); 00858 vertex_set = *i; 00859 } 00860 else 00861 { 00862 CHECK_EQUAL( 8, num_elem ); 00863 CHECK_EQUAL( 27, num_vtx ); 00864 CHECK_EQUAL( (EntityHandle)0, all_set ); 00865 all_set = *i; 00866 } 00867 } 00868 00869 // check set options 00870 unsigned opt; 00871 rval = moab.get_meshset_options( all_set, opt );CHECK_ERR( rval ); 00872 CHECK_EQUAL( all_opt, opt ); 00873 rval = moab.get_meshset_options( half1_set, opt );CHECK_ERR( rval ); 00874 CHECK_EQUAL( half1_opt, opt ); 00875 rval = moab.get_meshset_options( half2_set, opt );CHECK_ERR( rval ); 00876 CHECK_EQUAL( half2_opt, opt ); 00877 rval = moab.get_meshset_options( vertex_set, opt );CHECK_ERR( rval ); 00878 CHECK_EQUAL( vertex_opt, opt ); 00879 rval = moab.get_meshset_options( empty_set, opt );CHECK_ERR( rval ); 00880 CHECK_EQUAL( empty_opt, opt ); 00881 } 00882 00883 void test_pack_set_contents() 00884 { 00885 Core moab; 00886 ErrorCode rval; 00887 create_simple_grid( moab, 3 ); 00888 00889 // delete any existing sets 00890 Range sets; 00891 rval = moab.get_entities_by_type( 0, MBENTITYSET, sets );CHECK_ERR( rval ); 00892 if( !sets.empty() ) 00893 { 00894 rval = moab.delete_entities( sets );CHECK_ERR( rval ); 00895 } 00896 00897 // get all vertices 00898 Range vertices; 00899 rval = moab.get_entities_by_type( 0, MBVERTEX, vertices );CHECK_ERR( rval ); 00900 CHECK_EQUAL( 27, (int)vertices.size() ); 00901 // create meshset containing vertices 00902 EntityHandle set; 00903 rval = moab.create_meshset( MESHSET_SET, set );CHECK_ERR( rval ); 00904 rval = moab.add_entities( set, vertices );CHECK_ERR( rval ); 00905 00906 // pack and unpack range containing only set handle. 00907 // Will fail unless we also pass in set contents explicitly 00908 Range entities( vertices ); 00909 entities.insert( set ); 00910 pack_unpack_noremoteh( moab, entities ); 00911 00912 // expect single set in mesh 00913 entities.clear(); 00914 rval = moab.get_entities_by_type( 0, MBENTITYSET, entities );CHECK_ERR( rval ); 00915 CHECK_EQUAL( 1, (int)entities.size() ); 00916 set = entities.front(); 00917 00918 // expect 27 vertices in mesh 00919 vertices.clear(); 00920 rval = moab.get_entities_by_type( 0, MBVERTEX, vertices );CHECK_ERR( rval ); 00921 CHECK_EQUAL( 27, (int)vertices.size() ); 00922 00923 // expect set to contain all 27 vertices 00924 vertices.clear(); 00925 rval = moab.get_entities_by_type( set, MBVERTEX, vertices );CHECK_ERR( rval ); 00926 CHECK_EQUAL( 27, (int)vertices.size() ); 00927 } 00928 00929 void test_pack_sets_of_sets() 00930 { 00931 Core moab; 00932 ErrorCode rval; 00933 00934 // delete any existing sets 00935 Range sets; 00936 rval = moab.get_entities_by_type( 0, MBENTITYSET, sets );CHECK_ERR( rval ); 00937 if( !sets.empty() ) 00938 { 00939 rval = moab.delete_entities( sets );CHECK_ERR( rval ); 00940 } 00941 00942 // create three sets such that set2 contains set1, and set3 contains 00943 // both set1 and set2 00944 EntityHandle set1, set2, set3; 00945 sets.clear(); 00946 rval = moab.create_meshset( MESHSET_ORDERED, set1 );CHECK_ERR( rval ); 00947 sets.insert( set1 ); 00948 rval = moab.create_meshset( MESHSET_SET, set2 );CHECK_ERR( rval ); 00949 rval = moab.add_entities( set2, sets );CHECK_ERR( rval ); 00950 sets.insert( set2 ); 00951 rval = moab.create_meshset( MESHSET_SET, set3 );CHECK_ERR( rval ); 00952 rval = moab.add_entities( set3, sets );CHECK_ERR( rval ); 00953 sets.insert( set3 ); 00954 00955 // pack and unpack 00956 pack_unpack_noremoteh( moab, sets ); 00957 00958 // get sets 00959 sets.clear(); 00960 rval = moab.get_entities_by_type( 0, MBENTITYSET, sets );CHECK_ERR( rval ); 00961 CHECK_EQUAL( 3, (int)sets.size() ); 00962 00963 // figure out which is which 00964 set1 = set2 = set3 = 0; 00965 for( Range::iterator i = sets.begin(); i != sets.end(); ++i ) 00966 { 00967 int count; 00968 rval = moab.get_number_entities_by_type( *i, MBENTITYSET, count );CHECK_ERR( rval ); 00969 CHECK( count >= 0 && count <= 2 ); 00970 switch( count ) 00971 { 00972 case 0: 00973 CHECK_EQUAL( (EntityHandle)0, set1 ); 00974 set1 = *i; 00975 break; 00976 case 1: 00977 CHECK_EQUAL( (EntityHandle)0, set2 ); 00978 set2 = *i; 00979 break; 00980 case 2: 00981 CHECK_EQUAL( (EntityHandle)0, set3 ); 00982 set3 = *i; 00983 break; 00984 } 00985 } 00986 00987 // check that set2 contains set1 00988 sets.clear(); 00989 rval = moab.get_entities_by_type( set2, MBENTITYSET, sets );CHECK_ERR( rval ); 00990 CHECK_EQUAL( 1, (int)sets.size() ); 00991 CHECK_EQUAL( set1, sets.front() ); 00992 00993 // check that set3 contains set1 and set2 00994 sets.clear(); 00995 rval = moab.get_entities_by_type( set3, MBENTITYSET, sets );CHECK_ERR( rval ); 00996 CHECK_EQUAL( 2, (int)sets.size() ); 00997 if( sets.front() == set1 ) 00998 { 00999 CHECK_EQUAL( set2, sets.back() ); 01000 } 01001 else 01002 { 01003 CHECK_EQUAL( set2, sets.front() ); 01004 CHECK_EQUAL( set1, sets.back() ); 01005 } 01006 } 01007 01008 void test_pack_set_parent_child() 01009 { 01010 Core moab; 01011 ErrorCode rval; 01012 01013 // delete any existing sets 01014 Range sets; 01015 rval = moab.get_entities_by_type( 0, MBENTITYSET, sets );CHECK_ERR( rval ); 01016 if( !sets.empty() ) 01017 { 01018 rval = moab.delete_entities( sets );CHECK_ERR( rval ); 01019 } 01020 01021 // create three sets such that set3 has a child link to 01022 // set1, set2 has a parent link to set1, and such that set3 and 01023 // set2 are parent and child, respectively. 01024 EntityHandle set1, set2, set3; 01025 sets.clear(); 01026 rval = moab.create_meshset( MESHSET_ORDERED, set1 );CHECK_ERR( rval ); 01027 sets.insert( set1 ); 01028 rval = moab.create_meshset( MESHSET_SET, set2 );CHECK_ERR( rval ); 01029 sets.insert( set2 ); 01030 rval = moab.create_meshset( MESHSET_SET, set3 );CHECK_ERR( rval ); 01031 sets.insert( set3 ); 01032 01033 rval = moab.add_child_meshset( set3, set1 );CHECK_ERR( rval ); 01034 rval = moab.add_parent_meshset( set2, set1 );CHECK_ERR( rval ); 01035 rval = moab.add_parent_child( set3, set2 );CHECK_ERR( rval ); 01036 01037 // make sure everything is valid before doing the pack/unpack 01038 int count; 01039 rval = moab.num_child_meshsets( set1, &count ); 01040 CHECK( MB_SUCCESS == rval && 0 == count ); 01041 rval = moab.num_child_meshsets( set2, &count ); 01042 CHECK( MB_SUCCESS == rval && 0 == count ); 01043 rval = moab.num_child_meshsets( set3, &count ); 01044 CHECK( MB_SUCCESS == rval && 2 == count ); 01045 rval = moab.num_parent_meshsets( set1, &count ); 01046 CHECK( MB_SUCCESS == rval && 0 == count ); 01047 rval = moab.num_parent_meshsets( set2, &count ); 01048 CHECK( MB_SUCCESS == rval && 2 == count ); 01049 rval = moab.num_parent_meshsets( set3, &count ); 01050 CHECK( MB_SUCCESS == rval && 0 == count ); 01051 01052 // pack and unpack 01053 pack_unpack_noremoteh( moab, sets ); 01054 01055 // get sets 01056 sets.clear(); 01057 rval = moab.get_entities_by_type( 0, MBENTITYSET, sets );CHECK_ERR( rval ); 01058 CHECK_EQUAL( 3, (int)sets.size() ); 01059 01060 // look for a set with two child links (set3) 01061 set1 = set2 = set3 = 0; 01062 for( Range::iterator i = sets.begin(); i != sets.end(); ++i ) 01063 { 01064 int mcount; 01065 rval = moab.num_child_meshsets( *i, &mcount );CHECK_ERR( rval ); 01066 if( mcount == 2 ) 01067 { 01068 set3 = *i; 01069 break; 01070 } 01071 } 01072 CHECK( 0 != set3 ); 01073 01074 // check set relations 01075 std::vector< EntityHandle > parents, children; 01076 rval = moab.get_child_meshsets( set3, children );CHECK_ERR( rval ); 01077 CHECK_EQUAL( (std::vector< EntityHandle >::size_type)2, children.size() ); 01078 set1 = children[0]; 01079 set2 = children[1]; 01080 rval = moab.get_parent_meshsets( set1, parents );CHECK_ERR( rval ); 01081 CHECK( parents.empty() ); 01082 children.clear(); 01083 rval = moab.get_parent_meshsets( set1, children );CHECK_ERR( rval ); 01084 CHECK( children.empty() ); 01085 rval = moab.get_parent_meshsets( set2, parents );CHECK_ERR( rval ); 01086 CHECK_EQUAL( (std::vector< EntityHandle >::size_type)2, parents.size() ); 01087 CHECK_EQUAL( set1, parents[0] ); 01088 CHECK_EQUAL( set3, parents[1] ); 01089 } 01090 01091 void test_pack_tag_data_sparse() 01092 { 01093 Range::iterator i; 01094 int size; 01095 DataType type; 01096 TagType storage; 01097 Core moab; 01098 Interface& mb = moab; 01099 ErrorCode rval; 01100 01101 create_simple_grid( mb, 3 ); 01102 Range elems; 01103 rval = mb.get_entities_by_type( 0, MBHEX, elems );CHECK_ERR( rval ); 01104 CHECK( !elems.empty() ); 01105 01106 // Define a sparse tag containing two integers. For every other element 01107 // in the mesh, set the tag value to the floor of the x and y 01108 // coordinates of the first vertex in the elements connectivity list. 01109 const char sparse_2_int_tag_name[] = "test tag 1"; 01110 Tag sparse_2_int_tag; 01111 rval = 01112 mb.tag_get_handle( sparse_2_int_tag_name, 2, MB_TYPE_INTEGER, sparse_2_int_tag, MB_TAG_SPARSE | MB_TAG_CREAT );CHECK_ERR( rval ); 01113 bool skip = false; 01114 for( i = elems.begin(); i != elems.end(); ++i, skip = !skip ) 01115 { 01116 if( skip ) continue; 01117 01118 const EntityHandle* conn = 0; 01119 int len; 01120 rval = mb.get_connectivity( *i, conn, len );CHECK_ERR( rval ); 01121 double coords[3]; 01122 rval = mb.get_coords( conn, 1, coords );CHECK_ERR( rval ); 01123 const int data[2] = { (int)coords[0], (int)coords[1] }; 01124 rval = mb.tag_set_data( sparse_2_int_tag, &*i, 1, data );CHECK_ERR( rval ); 01125 } 01126 01127 // pack and unpack 01128 Range ents; 01129 pack_unpack_noremoteh( moab, ents ); 01130 elems.clear(); 01131 rval = mb.get_entities_by_type( 0, MBHEX, elems );CHECK_ERR( rval ); 01132 01133 // check tag meta for sparse_2_int_tag 01134 rval = mb.tag_get_handle( sparse_2_int_tag_name, 2, MB_TYPE_INTEGER, sparse_2_int_tag );CHECK_ERR( rval ); 01135 rval = mb.tag_get_length( sparse_2_int_tag, size );CHECK_ERR( rval ); 01136 CHECK_EQUAL( 2, size ); 01137 rval = mb.tag_get_type( sparse_2_int_tag, storage );CHECK_ERR( rval ); 01138 CHECK_EQUAL( MB_TAG_SPARSE, storage ); 01139 rval = mb.tag_get_data_type( sparse_2_int_tag, type );CHECK_ERR( rval ); 01140 CHECK_EQUAL( MB_TYPE_INTEGER, type ); 01141 int intdata[2]; 01142 rval = mb.tag_get_default_value( sparse_2_int_tag, intdata ); 01143 CHECK_EQUAL( MB_ENTITY_NOT_FOUND, rval ); 01144 01145 // check tag data for sparse_2_int_tag 01146 Range tagged; 01147 rval = mb.get_entities_by_type_and_tag( 0, MBHEX, &sparse_2_int_tag, 0, 1, tagged );CHECK_ERR( rval ); 01148 CHECK_EQUAL( ( elems.size() + 1 ) / 2, tagged.size() ); 01149 for( i = tagged.begin(); i != tagged.end(); ++i ) 01150 { 01151 rval = mb.tag_get_data( sparse_2_int_tag, &*i, 1, intdata );CHECK_ERR( rval ); 01152 01153 const EntityHandle* conn = 0; 01154 int len; 01155 rval = mb.get_connectivity( *i, conn, len );CHECK_ERR( rval ); 01156 double coords[3]; 01157 rval = mb.get_coords( conn, 1, coords );CHECK_ERR( rval ); 01158 01159 CHECK_EQUAL( (int)( coords[0] ), intdata[0] ); 01160 CHECK_EQUAL( (int)( coords[1] ), intdata[1] ); 01161 } 01162 } 01163 01164 void test_pack_tag_data_dense() 01165 { 01166 Range::iterator i; 01167 int size; 01168 DataType type; 01169 TagType storage; 01170 Core moab; 01171 Interface& mb = moab; 01172 ErrorCode rval; 01173 01174 create_simple_grid( mb, 3 ); 01175 Range verts; 01176 rval = mb.get_entities_by_type( 0, MBVERTEX, verts );CHECK_ERR( rval ); 01177 CHECK( !verts.empty() ); 01178 01179 // Define a dense tag containing a single double-precision floating 01180 // point value. For each vertex, store the distance from the origin 01181 // in this tag. 01182 const char dense_1_double_tag_name[] = "test tag 2"; 01183 Tag dense_1_double_tag; 01184 rval = 01185 mb.tag_get_handle( dense_1_double_tag_name, 1, MB_TYPE_DOUBLE, dense_1_double_tag, MB_TAG_DENSE | MB_TAG_EXCL );CHECK_ERR( rval ); 01186 for( i = verts.begin(); i != verts.end(); ++i ) 01187 { 01188 double coords[3]; 01189 rval = mb.get_coords( &*i, 1, coords );CHECK_ERR( rval ); 01190 double val = sqrt( coords[0] * coords[0] + coords[1] * coords[1] + coords[2] * coords[2] ); 01191 rval = mb.tag_set_data( dense_1_double_tag, &*i, 1, &val );CHECK_ERR( rval ); 01192 } 01193 01194 // pack and unpack 01195 Range ents; 01196 pack_unpack_noremoteh( moab, ents ); 01197 verts.clear(); 01198 rval = mb.get_entities_by_type( 0, MBVERTEX, verts );CHECK_ERR( rval ); 01199 01200 // check tag meta for dense_1_double_tag 01201 rval = mb.tag_get_handle( dense_1_double_tag_name, 1, MB_TYPE_DOUBLE, dense_1_double_tag );CHECK_ERR( rval ); 01202 rval = mb.tag_get_length( dense_1_double_tag, size );CHECK_ERR( rval ); 01203 CHECK_EQUAL( 1, size ); 01204 rval = mb.tag_get_type( dense_1_double_tag, storage );CHECK_ERR( rval ); 01205 CHECK_EQUAL( MB_TAG_DENSE, storage ); 01206 rval = mb.tag_get_data_type( dense_1_double_tag, type );CHECK_ERR( rval ); 01207 CHECK_EQUAL( MB_TYPE_DOUBLE, type ); 01208 double dval; 01209 rval = mb.tag_get_default_value( dense_1_double_tag, &dval ); 01210 CHECK_EQUAL( MB_ENTITY_NOT_FOUND, rval ); 01211 01212 // check tag data for dense_1_double_tag 01213 for( i = verts.begin(); i != verts.end(); ++i ) 01214 { 01215 double coords[3]; 01216 rval = mb.get_coords( &*i, 1, coords );CHECK_ERR( rval ); 01217 01218 const double expected = sqrt( coords[0] * coords[0] + coords[1] * coords[1] + coords[2] * coords[2] ); 01219 rval = mb.tag_get_data( dense_1_double_tag, &*i, 1, &dval );CHECK_ERR( rval ); 01220 CHECK_REAL_EQUAL( expected, dval, 1e-6 ); 01221 } 01222 } 01223 01224 void test_pack_tag_data_default_value() 01225 { 01226 Range::iterator i; 01227 int size; 01228 DataType type; 01229 TagType storage; 01230 Core moab; 01231 Interface& mb = moab; 01232 ErrorCode rval; 01233 01234 create_simple_grid( mb, 3 ); 01235 Range verts, elems, sets; 01236 rval = mb.get_entities_by_type( 0, MBVERTEX, verts );CHECK_ERR( rval ); 01237 CHECK( !verts.empty() ); 01238 rval = mb.get_entities_by_type( 0, MBHEX, elems );CHECK_ERR( rval ); 01239 CHECK( !elems.empty() ); 01240 01241 // Define a dense, opaque tag with a default value of "DEFLT". 01242 // Set the tag on one element, one vertex,and one set to "TAGGD". 01243 const char dense_5_opaque_tag_name[] = 01244 "This is intentionally a very long tag name in an attempt to test for an arbitrary " 01245 "limitations on tag name length."; 01246 Tag dense_5_opaque_tag; 01247 rval = mb.tag_get_handle( dense_5_opaque_tag_name, 5, MB_TYPE_OPAQUE, dense_5_opaque_tag, 01248 MB_TAG_DENSE | MB_TAG_EXCL, "DEFLT" );CHECK_ERR( rval ); 01249 EntityHandle set; 01250 rval = mb.create_meshset( MESHSET_SET, set );CHECK_ERR( rval ); 01251 const EntityHandle handles[3] = { verts.front(), elems.front(), set }; 01252 const char data[] = "TAGGDTAGGDTAGGD"; 01253 rval = mb.tag_set_data( dense_5_opaque_tag, handles, 3, data );CHECK_ERR( rval ); 01254 01255 // pack and unpack 01256 Range ents; 01257 pack_unpack_noremoteh( moab, ents ); 01258 elems.clear(); 01259 verts.clear(); 01260 sets.clear(); 01261 rval = mb.get_entities_by_type( 0, MBVERTEX, verts );CHECK_ERR( rval ); 01262 rval = mb.get_entities_by_type( 0, MBHEX, elems );CHECK_ERR( rval ); 01263 rval = mb.get_entities_by_type( 0, MBENTITYSET, sets );CHECK_ERR( rval ); 01264 01265 // check tag meta for dense_5_opaque_tag 01266 rval = mb.tag_get_handle( dense_5_opaque_tag_name, 5, MB_TYPE_OPAQUE, dense_5_opaque_tag );CHECK_ERR( rval ); 01267 rval = mb.tag_get_length( dense_5_opaque_tag, size );CHECK_ERR( rval ); 01268 CHECK_EQUAL( 5, size ); 01269 rval = mb.tag_get_type( dense_5_opaque_tag, storage );CHECK_ERR( rval ); 01270 CHECK_EQUAL( MB_TAG_DENSE, storage ); 01271 rval = mb.tag_get_data_type( dense_5_opaque_tag, type );CHECK_ERR( rval ); 01272 CHECK_EQUAL( MB_TYPE_OPAQUE, type ); 01273 char odata[6]; 01274 odata[5] = '\0'; 01275 rval = mb.tag_get_default_value( dense_5_opaque_tag, odata );CHECK_ERR( rval ); 01276 CHECK_EQUAL( std::string( "DEFLT" ), std::string( odata ) ); 01277 01278 // count number of each type with tag set to non-default 01279 int vcount = 0, ecount = 0, scount = 0; 01280 for( i = verts.begin(); i != verts.end(); ++i ) 01281 { 01282 rval = mb.tag_get_data( dense_5_opaque_tag, &*i, 1, odata );CHECK_ERR( rval ); 01283 if( strcmp( odata, "DEFLT" ) != 0 ) 01284 { 01285 CHECK_EQUAL( std::string( "TAGGD" ), std::string( odata ) ); 01286 ++vcount; 01287 } 01288 } 01289 CHECK_EQUAL( 1, vcount ); 01290 for( i = elems.begin(); i != elems.end(); ++i ) 01291 { 01292 rval = mb.tag_get_data( dense_5_opaque_tag, &*i, 1, odata );CHECK_ERR( rval ); 01293 if( strcmp( odata, "DEFLT" ) != 0 ) 01294 { 01295 CHECK_EQUAL( "TAGGD", odata ); 01296 ++ecount; 01297 } 01298 } 01299 CHECK_EQUAL( 1, ecount ); 01300 for( i = sets.begin(); i != sets.end(); ++i ) 01301 { 01302 rval = mb.tag_get_data( dense_5_opaque_tag, &*i, 1, odata );CHECK_ERR( rval ); 01303 if( strcmp( odata, "DEFLT" ) != 0 ) 01304 { 01305 CHECK_EQUAL( "TAGGD", odata ); 01306 ++scount; 01307 } 01308 } 01309 CHECK_EQUAL( 1, scount ); 01310 } 01311 01312 void test_pack_bit_tag_data() 01313 { 01314 Range::iterator i; 01315 Core moab; 01316 Interface& mb = moab; 01317 ErrorCode rval; 01318 01319 // create some mesh 01320 create_simple_grid( mb, 3 ); 01321 Range verts; 01322 rval = mb.get_entities_by_type( 0, MBVERTEX, verts );CHECK_ERR( rval ); 01323 CHECK( !verts.empty() ); 01324 01325 // Create a bit tag 01326 const char tag_name[] = "test bit"; 01327 Tag tag; 01328 rval = mb.tag_get_handle( tag_name, 3, MB_TYPE_BIT, tag, MB_TAG_EXCL );CHECK_ERR( rval ); 01329 01330 // Set bits to 1 unless cooresponding coordinate of 01331 // vertex is zero. 01332 for( i = verts.begin(); i != verts.end(); ++i ) 01333 { 01334 double coords[3]; 01335 rval = mb.get_coords( &*i, 1, coords );CHECK_ERR( rval ); 01336 01337 unsigned char data = 0; 01338 for( int j = 0; j < 3; ++j ) 01339 if( fabs( coords[j] ) > 1e-6 ) data |= ( 1 << j ); 01340 rval = mb.tag_set_data( tag, &*i, 1, &data );CHECK_ERR( rval ); 01341 } 01342 01343 // pack and unpack 01344 Range ents; 01345 pack_unpack_noremoteh( moab, ents ); 01346 verts.clear(); 01347 rval = mb.get_entities_by_type( 0, MBVERTEX, verts );CHECK_ERR( rval ); 01348 01349 // check tag meta 01350 rval = mb.tag_get_handle( tag_name, 3, MB_TYPE_BIT, tag );CHECK_ERR( rval ); 01351 01352 int size; 01353 rval = mb.tag_get_length( tag, size );CHECK_ERR( rval ); 01354 CHECK_EQUAL( 3, size ); 01355 01356 TagType storage; 01357 rval = mb.tag_get_type( tag, storage );CHECK_ERR( rval ); 01358 CHECK_EQUAL( MB_TAG_BIT, storage ); 01359 01360 DataType type; 01361 rval = mb.tag_get_data_type( tag, type ); 01362 CHECK_EQUAL( MB_TYPE_BIT, type ); 01363 01364 // check tag values 01365 for( i = verts.begin(); i != verts.end(); ++i ) 01366 { 01367 double coords[3]; 01368 rval = mb.get_coords( &*i, 1, coords );CHECK_ERR( rval ); 01369 01370 unsigned char expected = 0; 01371 for( int j = 0; j < 3; ++j ) 01372 if( fabs( coords[j] ) > 1e-6 ) expected |= ( 1 << j ); 01373 01374 unsigned char data = (unsigned char)0xFF; 01375 rval = mb.tag_get_data( tag, &*i, 1, &data );CHECK_ERR( rval ); 01376 01377 CHECK_EQUAL( (int)expected, (int)data ); 01378 } 01379 } 01380 01381 void test_pack_variable_length_tag() 01382 { 01383 Range::iterator i; 01384 Core moab; 01385 Interface& mb = moab; 01386 ErrorCode rval; 01387 01388 // create some mesh 01389 create_simple_grid( mb, 3 ); 01390 Range verts; 01391 rval = mb.get_entities_by_type( 0, MBVERTEX, verts );CHECK_ERR( rval ); 01392 CHECK( !verts.empty() ); 01393 01394 // create a variable-length tag 01395 const char* tag_name = "var_int_tag"; 01396 const int defval_size = 5; 01397 const int default_val[defval_size] = { 0xBEEF, 0xFEED, 0xDEAD, 0xBAD, 0xBEAD }; 01398 Tag tag; 01399 rval = mb.tag_get_handle( tag_name, defval_size, MB_TYPE_INTEGER, tag, MB_TAG_DENSE | MB_TAG_VARLEN | MB_TAG_EXCL, 01400 default_val );CHECK_ERR( rval ); 01401 01402 // for each vertex, store in the tag an integer between 1 and 3, 01403 // followed by the floor of the cooresponding number of vertex 01404 // coordinates, beginning with x. 01405 for( i = verts.begin(); i != verts.end(); ++i ) 01406 { 01407 double coords[3]; 01408 rval = mb.get_coords( &*i, 1, coords );CHECK_ERR( rval ); 01409 01410 const int num_coord = 1 + *i % 3; 01411 const int data_size = num_coord + 1; 01412 const int data[4] = { num_coord, (int)coords[0], (int)coords[1], (int)coords[2] }; 01413 const void* data_ptrs[1] = { data }; 01414 rval = mb.tag_set_by_ptr( tag, &*i, 1, data_ptrs, &data_size );CHECK_ERR( rval ); 01415 } 01416 01417 // pack and unpack 01418 pack_unpack_noremoteh( moab ); 01419 verts.clear(); 01420 rval = mb.get_entities_by_type( 0, MBVERTEX, verts );CHECK_ERR( rval ); 01421 01422 // check tag meta 01423 rval = mb.tag_get_handle( tag_name, 0, MB_TYPE_INTEGER, tag );CHECK_ERR( rval ); 01424 01425 int size; 01426 rval = mb.tag_get_length( tag, size ); 01427 CHECK_EQUAL( MB_VARIABLE_DATA_LENGTH, rval ); 01428 01429 TagType storage; 01430 rval = mb.tag_get_type( tag, storage );CHECK_ERR( rval ); 01431 CHECK_EQUAL( MB_TAG_DENSE, storage ); 01432 01433 DataType type; 01434 rval = mb.tag_get_data_type( tag, type );CHECK_ERR( rval ); 01435 CHECK_EQUAL( MB_TYPE_INTEGER, type ); 01436 01437 const void* defval_ptr; 01438 rval = mb.tag_get_default_value( tag, defval_ptr, size );CHECK_ERR( rval ); 01439 CHECK_EQUAL( defval_size, size ); 01440 const int* defval_arr = reinterpret_cast< const int* >( defval_ptr ); 01441 for( int j = 0; j < size; ++j ) 01442 CHECK_EQUAL( default_val[j], defval_arr[j] ); 01443 01444 // check tag values 01445 for( i = verts.begin(); i != verts.end(); ++i ) 01446 { 01447 double coords[3]; 01448 rval = mb.get_coords( &*i, 1, coords );CHECK_ERR( rval ); 01449 01450 int tsize; 01451 const void* valptr; 01452 rval = mb.tag_get_by_ptr( tag, &*i, 1, &valptr, &tsize );CHECK_ERR( rval ); 01453 CHECK( tsize > 1 ); 01454 CHECK( tsize <= 4 ); 01455 01456 const int* valarr = reinterpret_cast< const int* >( valptr ); 01457 CHECK( valarr[0] >= 1 ); 01458 CHECK( valarr[0] <= 3 ); 01459 for( int j = 0; j < valarr[0]; ++j ) 01460 { 01461 CHECK_EQUAL( (int)( coords[j] ), valarr[j + 1] ); 01462 } 01463 } 01464 } 01465 01466 void test_pack_tag_handle_data() 01467 { 01468 Range::iterator i; 01469 Core moab; 01470 Interface& mb = moab; 01471 ErrorCode rval; 01472 01473 // create some mesh 01474 create_simple_grid( mb, 3 ); 01475 Range verts, elems; 01476 rval = mb.get_entities_by_type( 0, MBVERTEX, verts );CHECK_ERR( rval ); 01477 CHECK( !verts.empty() ); 01478 rval = mb.get_entities_by_type( 0, MBHEX, elems );CHECK_ERR( rval ); 01479 CHECK( !elems.empty() ); 01480 01481 // create a tag 01482 const char* tag_name = "entity tag"; 01483 EntityHandle default_val[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; 01484 Tag tag; 01485 rval = mb.tag_get_handle( tag_name, 8, MB_TYPE_HANDLE, tag, MB_TAG_SPARSE | MB_TAG_EXCL, &default_val );CHECK_ERR( rval ); 01486 01487 // Store on each vertex the handles of the adjacent hexes, padded 01488 // with NULL handles. 01489 EntityHandle tagdata[8 * 8]; 01490 for( i = elems.begin(); i != elems.end(); ++i ) 01491 { 01492 const EntityHandle* conn; 01493 int len; 01494 rval = mb.get_connectivity( *i, conn, len );CHECK_ERR( rval ); 01495 CHECK_EQUAL( 8, len ); 01496 01497 rval = mb.tag_get_data( tag, conn, len, tagdata );CHECK_ERR( rval ); 01498 01499 for( int j = 0; j < 8; ++j ) 01500 { 01501 EntityHandle* vdata = tagdata + 8 * j; 01502 int idx = 0; 01503 while( vdata[idx] ) 01504 { 01505 ++idx; 01506 CHECK( idx < 8 ); 01507 } 01508 vdata[idx] = *i; 01509 } 01510 01511 rval = mb.tag_set_data( tag, conn, len, tagdata );CHECK_ERR( rval ); 01512 } 01513 01514 // pack and unpack 01515 pack_unpack_noremoteh( moab ); 01516 verts.clear(); 01517 rval = mb.get_entities_by_type( 0, MBVERTEX, verts );CHECK_ERR( rval ); 01518 01519 // check tag meta 01520 rval = mb.tag_get_handle( tag_name, 8, MB_TYPE_HANDLE, tag );CHECK_ERR( rval ); 01521 01522 int size; 01523 rval = mb.tag_get_length( tag, size );CHECK_ERR( rval ); 01524 CHECK_EQUAL( 8, size ); 01525 01526 TagType storage; 01527 rval = mb.tag_get_type( tag, storage );CHECK_ERR( rval ); 01528 CHECK_EQUAL( MB_TAG_SPARSE, storage ); 01529 01530 DataType type; 01531 rval = mb.tag_get_data_type( tag, type );CHECK_ERR( rval ); 01532 CHECK_EQUAL( MB_TYPE_HANDLE, type ); 01533 01534 rval = mb.tag_get_default_value( tag, tagdata );CHECK_ERR( rval ); 01535 for( int j = 0; j < 8; ++j ) 01536 { 01537 CHECK_EQUAL( (EntityHandle)0, tagdata[j] ); 01538 } 01539 01540 // check tag values 01541 for( i = elems.begin(); i != elems.end(); ++i ) 01542 { 01543 const EntityHandle* conn; 01544 int len; 01545 rval = mb.get_connectivity( *i, conn, len );CHECK_ERR( rval ); 01546 CHECK_EQUAL( 8, len ); 01547 01548 rval = mb.tag_get_data( tag, conn, len, tagdata );CHECK_ERR( rval ); 01549 01550 for( int j = 0; j < 8; ++j ) 01551 { 01552 EntityHandle* vdata = tagdata + 8 * j; 01553 int idx = 0; 01554 while( vdata[idx] != *i ) 01555 { 01556 ++idx; 01557 CHECK( idx < 8 ); 01558 } 01559 vdata[idx] = 0; 01560 } 01561 01562 rval = mb.tag_set_data( tag, conn, len, tagdata );CHECK_ERR( rval ); 01563 } 01564 01565 for( i = verts.begin(); i != verts.end(); ++i ) 01566 { 01567 rval = mb.tag_get_data( tag, &*i, 1, tagdata );CHECK_ERR( rval ); 01568 for( int j = 0; j < 8; ++j ) 01569 { 01570 CHECK_EQUAL( (EntityHandle)0, tagdata[j] ); 01571 } 01572 } 01573 } 01574 01575 ErrorCode get_entities( Interface* mb, 01576 std::vector< EntityHandle >& ent_verts, 01577 int verts_per_entity, 01578 int dim, 01579 Range& ents ) 01580 { 01581 assert( !( ent_verts.size() % verts_per_entity ) ); 01582 unsigned int num_ents = ent_verts.size() / verts_per_entity; 01583 Range dum_ents; 01584 ErrorCode result; 01585 for( unsigned int i = 0; i < num_ents; i++ ) 01586 { 01587 result = mb->get_adjacencies( &ent_verts[verts_per_entity * i], verts_per_entity, dim, true, dum_ents );CHECK_ERR( result ); 01588 assert( dum_ents.size() == 1 ); 01589 ents.merge( dum_ents ); 01590 dum_ents.clear(); 01591 } 01592 return MB_SUCCESS; 01593 } 01594 01595 void test_pack_shared_entities_2d() 01596 { 01597 Core moab[4]; 01598 ParallelComm* pc[4]; 01599 for( unsigned int i = 0; i < 4; i++ ) 01600 { 01601 pc[i] = new ParallelComm( &moab[i], MPI_COMM_WORLD ); 01602 pc[i]->set_rank( i ); 01603 } 01604 01605 Range verts[4], quads[4]; 01606 ErrorCode rval = create_shared_grid_2d( pc, verts, quads );CHECK_ERR( rval ); 01607 01608 // moab[0].list_entities(0,1); 01609 01610 // exchange interface cells 01611 rval = ParallelComm::exchange_ghost_cells( pc, 4, -1, -1, 0, 0, true );CHECK_ERR( rval ); 01612 01613 // now 1 layer of hex ghosts 01614 rval = ParallelComm::exchange_ghost_cells( pc, 4, 2, 0, 1, 0, true );CHECK_ERR( rval ); 01615 01616 // now 1 layer of hex ghosts w/ edges 01617 rval = ParallelComm::exchange_ghost_cells( pc, 4, 2, 0, 1, 1, true );CHECK_ERR( rval ); 01618 01619 for( unsigned int i = 0; i < 4; i++ ) 01620 delete pc[i]; 01621 } 01622 01623 void test_pack_shared_entities_3d() 01624 { 01625 Core moab[4]; 01626 ParallelComm* pc[4]; 01627 for( unsigned int i = 0; i < 4; i++ ) 01628 { 01629 pc[i] = new ParallelComm( &moab[i], MPI_COMM_WORLD ); 01630 pc[i]->set_rank( i ); 01631 for( unsigned int j = 0; j < 4; j++ ) 01632 { 01633 if( j == i ) 01634 continue; 01635 else 01636 pc[i]->get_buffers( j ); 01637 } 01638 } 01639 01640 Range verts[4], hexes[4]; 01641 ErrorCode rval = create_shared_grid_3d( pc, verts, hexes );CHECK_ERR( rval ); 01642 01643 // exchange interface cells 01644 rval = ParallelComm::exchange_ghost_cells( pc, 4, -1, -1, 0, 0, true );CHECK_ERR( rval ); 01645 01646 // now 1 layer of hex ghosts 01647 rval = ParallelComm::exchange_ghost_cells( pc, 4, 3, 0, 1, 0, true );CHECK_ERR( rval ); 01648 01649 // now 1 layer of hex ghosts w/ faces, edges 01650 rval = ParallelComm::exchange_ghost_cells( pc, 4, 3, 0, 1, 3, true );CHECK_ERR( rval ); 01651 01652 for( unsigned int i = 0; i < 4; i++ ) 01653 delete pc[i]; 01654 } 01655 01656 void test_filter_pstatus() 01657 { 01658 Range::iterator i; 01659 Core moab; 01660 Interface& mb = moab; 01661 ErrorCode rval; 01662 01663 // create some mesh 01664 create_simple_grid( mb, 3 ); 01665 std::vector< EntityHandle > verts; 01666 Range dum_vertsr, vertsr; 01667 rval = mb.get_entities_by_type( 0, MBVERTEX, dum_vertsr );CHECK_ERR( rval ); 01668 vertsr.insert( dum_vertsr[0], dum_vertsr[8] ); 01669 for( int k = 0; k < 9; k++ ) 01670 verts.push_back( vertsr[k] ); 01671 01672 CHECK( !verts.empty() ); 01673 01674 ParallelComm* pcomm = new ParallelComm( &moab, MPI_COMM_WORLD ); 01675 01676 std::vector< int > procs( 70, -1 ); 01677 for( int k = 0; k < 6; k++ ) 01678 procs[k] = k; 01679 01680 std::vector< unsigned char > pvals( verts.size(), 0 ); 01681 // interface, owned 01682 pvals[0] = ( PSTATUS_INTERFACE | PSTATUS_SHARED ); // p0 01683 rval = moab.tag_set_data( pcomm->sharedp_tag(), &verts[0], 1, &procs[0] );CHECK_ERR( rval ); 01684 // interface, not owned 01685 pvals[1] = ( PSTATUS_NOT_OWNED | PSTATUS_INTERFACE | PSTATUS_SHARED ); // p1 01686 rval = moab.tag_set_data( pcomm->sharedp_tag(), &verts[1], 1, &procs[1] );CHECK_ERR( rval ); 01687 // interface, multi-shared, owned 01688 pvals[2] = ( PSTATUS_INTERFACE | PSTATUS_SHARED | PSTATUS_MULTISHARED ); // p0, p1 01689 rval = moab.tag_set_data( pcomm->sharedps_tag(), &verts[2], 1, &procs[0] );CHECK_ERR( rval ); 01690 // interface, multi-shared, not owned 01691 pvals[3] = ( PSTATUS_INTERFACE | PSTATUS_MULTISHARED | PSTATUS_NOT_OWNED | PSTATUS_SHARED ); // p1, p2 01692 rval = moab.tag_set_data( pcomm->sharedps_tag(), &verts[3], 1, &procs[1] );CHECK_ERR( rval ); 01693 // ghost, shared 01694 pvals[4] = ( PSTATUS_GHOST | PSTATUS_SHARED | PSTATUS_NOT_OWNED ); // p2 01695 rval = moab.tag_set_data( pcomm->sharedp_tag(), &verts[4], 1, &procs[2] );CHECK_ERR( rval ); 01696 // ghost, multi-shared 01697 pvals[5] = ( PSTATUS_GHOST | PSTATUS_MULTISHARED | PSTATUS_NOT_OWNED | PSTATUS_SHARED ); // p2, p3 01698 rval = moab.tag_set_data( pcomm->sharedps_tag(), &verts[5], 1, &procs[2] );CHECK_ERR( rval ); 01699 // owned, shared 01700 pvals[6] = ( PSTATUS_SHARED ); // p4 01701 rval = moab.tag_set_data( pcomm->sharedp_tag(), &verts[6], 1, &procs[4] );CHECK_ERR( rval ); 01702 // owned, multi-shared 01703 pvals[7] = ( PSTATUS_MULTISHARED | PSTATUS_SHARED ); // p4, p5 01704 rval = moab.tag_set_data( pcomm->sharedps_tag(), &verts[7], 1, &procs[4] );CHECK_ERR( rval ); 01705 // not shared, owned 01706 pvals[8] = 0x0; 01707 01708 rval = moab.tag_set_data( pcomm->pstatus_tag(), &verts[0], 9, &pvals[0] );CHECK_ERR( rval ); 01709 01710 Range tmp_range = vertsr; 01711 01712 // interface ents 01713 rval = pcomm->filter_pstatus( tmp_range, PSTATUS_INTERFACE, PSTATUS_AND );CHECK_ERR( rval ); 01714 CHECK( tmp_range.size() == 4 && *tmp_range.begin() == verts[0] && *tmp_range.rbegin() == verts[3] ); 01715 // not interface 01716 tmp_range = vertsr; 01717 rval = pcomm->filter_pstatus( tmp_range, PSTATUS_INTERFACE, PSTATUS_NOT );CHECK_ERR( rval ); 01718 CHECK( tmp_range.size() == 5 && *tmp_range.begin() == verts[4] && *tmp_range.rbegin() == verts[8] ); 01719 // interface not owned 01720 tmp_range = vertsr; 01721 rval = pcomm->filter_pstatus( tmp_range, PSTATUS_INTERFACE | PSTATUS_NOT_OWNED, PSTATUS_AND );CHECK_ERR( rval ); 01722 CHECK( tmp_range.size() == 2 && *tmp_range.begin() == verts[1] && *tmp_range.rbegin() == verts[3] ); 01723 // ghost 01724 tmp_range = vertsr; 01725 rval = pcomm->filter_pstatus( tmp_range, PSTATUS_GHOST, PSTATUS_AND );CHECK_ERR( rval ); 01726 CHECK( tmp_range.size() == 2 && *tmp_range.begin() == verts[4] && *tmp_range.rbegin() == verts[5] ); 01727 // shared not multi-shared 01728 tmp_range = vertsr; 01729 rval = pcomm->filter_pstatus( tmp_range, PSTATUS_SHARED, PSTATUS_AND );CHECK_ERR( rval ); 01730 rval = pcomm->filter_pstatus( tmp_range, PSTATUS_MULTISHARED, PSTATUS_NOT );CHECK_ERR( rval ); 01731 CHECK( tmp_range.size() == 4 && tmp_range[0] == verts[0] && tmp_range[1] == verts[1] && tmp_range[2] == verts[4] && 01732 tmp_range[3] == verts[6] ); 01733 // shared w/ p0 01734 tmp_range = vertsr; 01735 rval = pcomm->filter_pstatus( tmp_range, PSTATUS_SHARED, PSTATUS_AND, 0 );CHECK_ERR( rval ); 01736 CHECK( tmp_range.size() == 2 && tmp_range[1] == verts[2] ); 01737 // shared w/ p2 && not owned 01738 tmp_range = vertsr; 01739 rval = pcomm->filter_pstatus( tmp_range, PSTATUS_SHARED | PSTATUS_NOT_OWNED, PSTATUS_AND, 2 );CHECK_ERR( rval ); 01740 CHECK( tmp_range.size() == 3 && tmp_range[0] == verts[3] && tmp_range[1] == verts[4] && tmp_range[2] == verts[5] ); 01741 01742 delete pcomm; 01743 } 01744 01745 void test_new_pcomm_instance() 01746 { 01747 #if defined( MOAB_HAVE_MPI ) && defined( MOAB_HAVE_HDF5 ) 01748 Core moab; 01749 Interface& mb = moab; 01750 01751 // This parallel read will create a ParallelComm instance implicitly 01752 std::string example = TestDir + "unittest/64bricks_1khex.h5m"; 01753 std::string read_options = "PARALLEL=READ_PART;PARTITION=PARALLEL_PARTITION;PARALLEL_RESOLVE_SHARED_ENTS"; 01754 ErrorCode rval = mb.load_file( example.c_str(), 0, read_options.c_str() );CHECK_ERR( rval ); 01755 01756 // It is highly recommended to reuse existing ParallelComm instance with 01757 // ParallelComm::get_pcomm() Creating a new ParallelComm instance should still be allowed, 01758 // anyway 01759 ParallelComm* pcomm = new moab::ParallelComm( &moab, MPI_COMM_WORLD ); 01760 01761 // Do something with pcomm 01762 // ... 01763 01764 delete pcomm; 01765 #endif 01766 }