MOAB: Mesh Oriented datABase
(version 5.4.1)
|
00001 /** 00002 * MOAB, a Mesh-Oriented datABase, is a software component for creating, 00003 * storing and accessing finite element mesh data. 00004 * 00005 * Copyright 2004 Sandia Corporation. Under the terms of Contract 00006 * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government 00007 * retains certain rights in this software. 00008 * 00009 * This library is free software; you can redistribute it and/or 00010 * modify it under the terms of the GNU Lesser General Public 00011 * License as published by the Free Software Foundation; either 00012 * version 2.1 of the License, or (at your option) any later version. 00013 * 00014 */ 00015 00016 /*! 00017 MBTest.cpp 00018 Test Harness for MB mesh database system 00019 */ 00020 00021 #ifdef WIN32 00022 #ifdef _DEBUG 00023 // turn off warnings that say they debugging identifier has been truncated 00024 // this warning comes up when using some STL containers 00025 #pragma warning( disable : 4786 ) 00026 #endif 00027 #endif 00028 00029 #include <iostream> 00030 #include <fstream> 00031 #include <algorithm> 00032 #include <cstdio> 00033 #include <ctime> 00034 #include <cassert> 00035 #include <cmath> 00036 #include <cstdio> 00037 #include "moab/Interface.hpp" 00038 #include "MBTagConventions.hpp" 00039 #include "moab/Range.hpp" 00040 #include "moab/Skinner.hpp" 00041 #include "moab/MeshTopoUtil.hpp" 00042 #include "moab/CN.hpp" 00043 #include "moab/OrientedBox.hpp" 00044 #include "moab/CartVect.hpp" 00045 #include "moab/WriteUtilIface.hpp" 00046 00047 #ifdef MOAB_HAVE_MPI 00048 #include "moab_mpi.h" 00049 #endif 00050 00051 #ifndef IS_BUILDING_MB 00052 #define IS_BUILDING_MB 00053 #endif 00054 #include "Internals.hpp" 00055 #include "moab/Core.hpp" 00056 #include "SequenceManager.hpp" 00057 #include "EntitySequence.hpp" 00058 #include "RangeSeqIntersectIter.hpp" 00059 #include "moab/Error.hpp" 00060 #include "moab/ScdInterface.hpp" 00061 00062 /* Use the following define to specify that our tests 00063 return an error code and not the default void */ 00064 #define TEST_USES_ERR_CODES 00065 #include "TestUtil.hpp" 00066 00067 using namespace std; 00068 using namespace moab; 00069 00070 #define CHKERR( A ) \ 00071 do \ 00072 { \ 00073 if( MB_SUCCESS != ( A ) ) \ 00074 { \ 00075 std::cerr << "Failure (error code " << ( A ) << ") at " __FILE__ ":" << __LINE__ << std::endl; \ 00076 return A; \ 00077 } \ 00078 } while( false ) 00079 00080 #ifdef MOAB_HAVE_NETCDF 00081 ErrorCode load_file_one( Interface* iface ) 00082 { 00083 std::string file_name = TestDir + "unittest/mbtest1.g"; 00084 ErrorCode error = iface->load_mesh( file_name.c_str() ); 00085 if( MB_SUCCESS != error ) 00086 { 00087 std::cout << "Failed to load input file: " << file_name << std::endl; 00088 std::string error_reason; 00089 iface->get_last_error( error_reason ); 00090 cout << error_reason << std::endl; 00091 } 00092 return error; 00093 } 00094 #endif 00095 00096 /* Create a regular 2x2x2 hex mesh */ 00097 ErrorCode create_some_mesh( Interface* iface ); 00098 00099 ErrorCode check_valid_connectivity( Interface* iface ); 00100 00101 /*! 00102 @test 00103 Vertex Coordinates 00104 @li Get coordinates of vertex 1 correctly 00105 @li Get coordinates of vertex 8 correctly 00106 @li Get coordinates of vertex 6 correctly 00107 */ 00108 ErrorCode mb_vertex_coordinate_test() 00109 { 00110 Core moab; 00111 Interface* MB = &moab; 00112 ErrorCode error = create_some_mesh( MB );MB_CHK_ERR( error ); 00113 00114 Range vertices; 00115 error = MB->get_entities_by_type( 0, MBVERTEX, vertices );MB_CHK_ERR( error ); 00116 00117 std::vector< double > all_coords( 3 * vertices.size() ); 00118 double* coord_iter = &all_coords[0]; 00119 for( Range::iterator iter = vertices.begin(); iter != vertices.end(); ++iter ) 00120 { 00121 error = MB->get_coords( &( *iter ), 1, coord_iter );MB_CHK_ERR( error ); 00122 coord_iter += 3; 00123 } 00124 00125 // check blocked coordinates 00126 const size_t N = vertices.size() + 1; 00127 std::vector< double > x( N ), y( N ), z( N ); 00128 // set last value so we can check later that nothing wrote past the 00129 // intended end of an array 00130 x[vertices.size()] = y[vertices.size()] = z[vertices.size()] = -3.14159; 00131 error = MB->get_coords( vertices, &x[0], &y[0], &z[0] ); 00132 for( size_t i = 0; i < vertices.size(); ++i ) 00133 { 00134 CHECK_REAL_EQUAL( all_coords[3 * i], x[i], 1E-12 ); 00135 CHECK_REAL_EQUAL( all_coords[3 * i + 1], y[i], 1E-12 ); 00136 CHECK_REAL_EQUAL( all_coords[3 * i + 2], z[i], 1E-12 ); 00137 } 00138 // checkthat get_coords did not write past intended end of arrays 00139 CHECK_REAL_EQUAL( -3.14159, x[vertices.size()], 1E-12 ); 00140 CHECK_REAL_EQUAL( -3.14159, y[vertices.size()], 1E-12 ); 00141 CHECK_REAL_EQUAL( -3.14159, z[vertices.size()], 1E-12 ); 00142 00143 // add invalid handle to end of range and try query again 00144 vertices.insert( vertices.back() + 1 ); 00145 error = MB->get_coords( vertices, &x[0], &y[0], &z[0] ); 00146 CHECK_EQUAL( MB_ENTITY_NOT_FOUND, error ); 00147 00148 // Try getting coordinates for a hex (should fail) 00149 Range hexes; 00150 error = MB->get_entities_by_type( 0, MBHEX, hexes );MB_CHK_ERR( error ); 00151 EntityHandle handle = hexes.front(); 00152 error = MB->get_coords( &handle, 1, &x[0] );MB_CHK_ERR( error ); 00153 CHECK_REAL_EQUAL( 0.5, x[0], 1E-12 ); 00154 CHECK_REAL_EQUAL( 0.5, x[1], 1E-12 ); 00155 CHECK_REAL_EQUAL( 0.5, x[2], 1E-12 ); 00156 00157 return MB_SUCCESS; 00158 } 00159 00160 /*! 00161 @test 00162 MB Vertex Tag Test 00163 @li Add, Set and correctly get an int tag 00164 @li Add, Set and correctly get a boolean tag 00165 @li Add, Set and correctly get a double tag 00166 @li Add, Set and correctly get a struct tag 00167 */ 00168 ErrorCode mb_vertex_tag_test() 00169 { 00170 Core moab; 00171 Interface* MB = &moab; 00172 ErrorCode error = create_some_mesh( MB ); 00173 if( MB_SUCCESS != error ) return error; 00174 00175 // Add an int Vertex Tag to the database 00176 00177 Tag tag_id; 00178 00179 // Create a dense tag for all vertices 00180 error = MB->tag_get_handle( "int_tag", 1, MB_TYPE_INTEGER, tag_id, MB_TAG_SPARSE | MB_TAG_EXCL ); 00181 if( error != MB_SUCCESS ) return error; 00182 00183 // put a value in vertex 1 and retrieve 00184 std::vector< EntityHandle > verts; 00185 error = MB->get_entities_by_type( 0, MBVERTEX, verts ); 00186 if( MB_SUCCESS != error ) return error; 00187 EntityHandle handle = verts[0]; 00188 int input_value = 11; 00189 error = MB->tag_set_data( tag_id, &handle, 1, &input_value ); 00190 if( MB_SUCCESS != error ) return error; 00191 00192 int output_value; 00193 error = MB->tag_get_data( tag_id, &handle, 1, &output_value ); 00194 if( MB_SUCCESS != error ) 00195 return error; 00196 else if( output_value != input_value ) 00197 return MB_FAILURE; 00198 00199 // put a value in vertex 5 and retrieve 00200 00201 handle = verts[5]; 00202 input_value = 11; 00203 error = MB->tag_set_data( tag_id, &handle, 1, &input_value ); 00204 if( MB_SUCCESS != error ) return error; 00205 error = MB->tag_get_data( tag_id, &handle, 1, &output_value ); 00206 if( MB_SUCCESS != error ) 00207 return error; 00208 else if( output_value != input_value ) 00209 return MB_FAILURE; 00210 00211 // put a value in vertex 98088234 which doesn't exist 00212 handle = *std::max_element( verts.begin(), verts.end() ) + 1; 00213 input_value = 11; 00214 00215 error = MB->tag_set_data( tag_id, &handle, 1, &input_value ); 00216 if( error == MB_SUCCESS ) return error; 00217 00218 error = MB->tag_get_data( tag_id, &handle, 1, &output_value ); 00219 if( error == MB_SUCCESS ) return error; 00220 00221 if( output_value != input_value ) return MB_FAILURE; 00222 00223 // Add a bool Vertex Tag to the database 00224 00225 error = MB->tag_get_handle( "bool_tag", sizeof( bool ), MB_TYPE_OPAQUE, tag_id, MB_TAG_SPARSE | MB_TAG_EXCL ); 00226 if( error != MB_SUCCESS ) return error; 00227 00228 // put a value in vertex 5 and retrieve 00229 00230 handle = verts[5]; 00231 bool bool_input_value = true; 00232 bool bool_output_value = false; 00233 error = MB->tag_set_data( tag_id, &handle, 1, &bool_input_value ); 00234 if( error != MB_SUCCESS ) return error; 00235 error = MB->tag_get_data( tag_id, &handle, 1, &bool_output_value ); 00236 if( error != MB_SUCCESS ) 00237 return error; 00238 else if( bool_output_value != bool_input_value ) 00239 return MB_FAILURE; 00240 00241 // Add a double Vertex Tag to the database 00242 00243 error = MB->tag_get_handle( "double_tag", 1, MB_TYPE_DOUBLE, tag_id, MB_TAG_SPARSE | MB_TAG_EXCL ); 00244 if( error != MB_SUCCESS ) return error; 00245 00246 // put a value in vertex 8: and retrieve 00247 00248 handle = verts[8]; 00249 double double_input_value = 1.0; 00250 double double_output_value = 0.0; 00251 error = MB->tag_set_data( tag_id, &handle, 1, &double_input_value ); 00252 if( error != MB_SUCCESS ) return error; 00253 00254 error = MB->tag_get_data( tag_id, &handle, 1, &double_output_value ); 00255 if( error != MB_SUCCESS ) 00256 return error; 00257 else if( double_output_value != double_input_value ) 00258 return MB_FAILURE; 00259 00260 // Add a struct Vertex Tag to the database 00261 00262 struct TagStruct 00263 { 00264 int test_int; 00265 double test_double; 00266 }; 00267 error = 00268 MB->tag_get_handle( "struct_tag", sizeof( TagStruct ), MB_TYPE_OPAQUE, tag_id, MB_TAG_SPARSE | MB_TAG_EXCL ); 00269 if( error != MB_SUCCESS ) return error; 00270 00271 // put a value in vertex 7 and retrieve 00272 00273 handle = verts[7]; 00274 TagStruct input_tag_struct; 00275 input_tag_struct.test_int = 55; 00276 input_tag_struct.test_double = -1.2345; 00277 TagStruct output_tag_struct; 00278 error = MB->tag_set_data( tag_id, &handle, 1, &input_tag_struct ); 00279 if( error != MB_SUCCESS ) return error; 00280 error = MB->tag_get_data( tag_id, &handle, 1, &output_tag_struct ); 00281 if( error != MB_SUCCESS ) 00282 return error; 00283 else if( output_tag_struct.test_int != input_tag_struct.test_int || 00284 output_tag_struct.test_double != input_tag_struct.test_double ) 00285 return MB_FAILURE; 00286 00287 // Create sparse tags for 10 random entities including some outside the 00288 // range of allowable entities. 00289 00290 error = MB->tag_get_handle( "sparse_int_tag", 1, MB_TYPE_INTEGER, tag_id, MB_TAG_SPARSE | MB_TAG_EXCL ); 00291 00292 if( error != MB_SUCCESS ) return error; 00293 00294 // print_yes = true; 00295 int i; 00296 for( i = 0; i < 10; i++ ) 00297 { 00298 // use invalid handles for odd values 00299 00300 if( i % 2 ) 00301 handle = verts[i] + *std::max_element( verts.begin(), verts.end() ); 00302 else 00303 handle = verts[i]; 00304 00305 input_value = 11; 00306 error = MB->tag_set_data( tag_id, &handle, 1, &input_value ); 00307 00308 // should fail on odd values of i 00309 if( !( i % 2 ) ) 00310 { 00311 if( error != MB_SUCCESS ) // even case and if failed 00312 return error; 00313 } 00314 else 00315 { 00316 if( error == MB_SUCCESS ) // odd case and it says it worked! 00317 return MB_FAILURE; 00318 } 00319 00320 error = MB->tag_get_data( tag_id, &handle, 1, &output_value ); 00321 if( ( i % 2 ) && error != MB_FAILURE && error != MB_TAG_NOT_FOUND ) return error; 00322 00323 if( ( i % 2 ) && output_value != input_value ) return MB_FAILURE; 00324 } 00325 00326 // get the tag_name of the last tag created above 00327 std::string int_tag_name; 00328 error = MB->tag_get_name( tag_id, int_tag_name ); 00329 if( error != MB_SUCCESS ) return error; 00330 00331 if( int_tag_name != "sparse_int_tag" ) return MB_FAILURE; 00332 00333 // get the tag handle of the last tag created above 00334 Tag int_tag_handle; 00335 error = MB->tag_get_handle( int_tag_name.c_str(), 1, MB_TYPE_INTEGER, int_tag_handle ); 00336 if( MB_SUCCESS != error ) return error; 00337 00338 if( int_tag_handle != tag_id ) return MB_FAILURE; 00339 00340 // test tag_get_tags_on_entity and tag_delete_data 00341 std::vector< Tag > all_tags; 00342 handle = verts[0]; 00343 error = MB->tag_get_tags_on_entity( handle, all_tags ); 00344 if( MB_SUCCESS != error ) return error; 00345 00346 if( !all_tags.empty() ) 00347 { 00348 error = MB->tag_delete_data( all_tags[0], &handle, 1 ); 00349 if( MB_SUCCESS != error ) return error; 00350 00351 error = MB->tag_delete( all_tags[0] ); 00352 if( MB_SUCCESS != error ) return error; 00353 } 00354 // delete tags test 00355 00356 // delete 2 of the sparse tags that were created above. 00357 handle = verts[2]; 00358 error = MB->tag_delete_data( tag_id, &handle, 1 ); 00359 if( error != MB_SUCCESS ) return error; 00360 00361 handle = verts[6]; 00362 error = MB->tag_delete_data( tag_id, &handle, 1 ); 00363 if( error != MB_SUCCESS ) return error; 00364 00365 // delete all the rest of the sparse tags. 00366 00367 error = MB->tag_delete( tag_id ); 00368 if( error != MB_SUCCESS ) return error; 00369 00370 // delete the dense tag named bool_tag 00371 Tag bool_tag_handle; 00372 error = MB->tag_get_handle( "bool_tag", sizeof( bool ), MB_TYPE_OPAQUE, bool_tag_handle ); 00373 if( error != MB_SUCCESS ) return error; 00374 00375 error = MB->tag_delete( bool_tag_handle ); 00376 if( error != MB_SUCCESS ) return error; 00377 00378 return error; 00379 } 00380 00381 ErrorCode mb_temporary_test() 00382 { 00383 Core moab; 00384 Interface* gMB = &moab; 00385 00386 double array[3] = { 0.0, 0.0, 0.0 }; 00387 EntityHandle h_node1; 00388 ErrorCode result = gMB->create_vertex( array, h_node1 ); 00389 if( MB_SUCCESS != result ) return result; 00390 00391 EntityHandle ordered_meshset1; 00392 result = gMB->create_meshset( MESHSET_ORDERED | MESHSET_TRACK_OWNER, ordered_meshset1 ); 00393 if( MB_SUCCESS != result ) return result; 00394 00395 EntityHandle ordered_meshset2; 00396 result = gMB->create_meshset( MESHSET_ORDERED | MESHSET_TRACK_OWNER, ordered_meshset2 ); 00397 if( MB_SUCCESS != result ) return result; 00398 00399 result = gMB->add_entities( ordered_meshset1, &h_node1, 1 ); 00400 if( MB_SUCCESS != result ) return result; 00401 00402 result = gMB->remove_entities( ordered_meshset1, &h_node1, 1 ); 00403 if( MB_SUCCESS != result ) return result; 00404 00405 result = gMB->add_entities( ordered_meshset2, &h_node1, 1 ); 00406 if( MB_SUCCESS != result ) return result; 00407 00408 bool create_if_missing = false; 00409 std::vector< EntityHandle > meshsets; 00410 result = gMB->get_adjacencies( &h_node1, 1, 4, create_if_missing, meshsets ); 00411 if( MB_SUCCESS != result ) return result; 00412 00413 if( 1u != meshsets.size() ) return MB_FAILURE; 00414 00415 return MB_SUCCESS; 00416 } 00417 00418 ErrorCode mb_adjacent_vertex_test() 00419 { 00420 Core moab; 00421 Interface* mb = &moab; 00422 ErrorCode rval = create_some_mesh( mb ); 00423 if( MB_SUCCESS != rval ) return rval; 00424 00425 Range hexes, expt_vert, got_vert, some_hexes; 00426 Range::const_iterator i, j; 00427 int n; 00428 00429 // get all hexes 00430 rval = mb->get_entities_by_type( 0, MBHEX, hexes ); 00431 if( rval != MB_SUCCESS ) return rval; 00432 if( hexes.empty() ) // can't do test if no elements 00433 return MB_FAILURE; 00434 00435 // get every third hex and its vertices 00436 n = 0; 00437 for( i = hexes.begin(); i != hexes.end(); ++i ) 00438 { 00439 if( ++n % 3 ) continue; 00440 some_hexes.insert( *i ); 00441 const EntityHandle* conn; 00442 int len; 00443 rval = mb->get_connectivity( *i, conn, len ); 00444 if( MB_SUCCESS != rval ) return rval; 00445 for( int k = 0; k < len; ++k ) 00446 expt_vert.insert( conn[k] ); 00447 } 00448 00449 // use get_adjacencies to get vertices 00450 rval = mb->get_adjacencies( some_hexes, 0, false, got_vert, Interface::UNION ); 00451 if( MB_SUCCESS != rval ) 00452 { 00453 std::cout << "get_adjacencies failed with error code " << rval << std::endl; 00454 return rval; 00455 } 00456 00457 i = expt_vert.begin(); 00458 j = got_vert.begin(); 00459 while( i != expt_vert.end() && j != got_vert.end() ) 00460 { 00461 if( *i < *j ) 00462 { 00463 std::cout << "Result missing vertex: " << *i << std::endl; 00464 return MB_FAILURE; 00465 } 00466 else if( *j < *i ) 00467 { 00468 std::cout << "Result contains extra vertex: " << *j << std::endl; 00469 return MB_FAILURE; 00470 } 00471 ++i; 00472 ++j; 00473 } 00474 00475 if( i != expt_vert.end() ) 00476 { 00477 std::cout << "Result missing vertex: " << *i << std::endl; 00478 return MB_FAILURE; 00479 } 00480 else if( j != got_vert.end() ) 00481 { 00482 std::cout << "Result contains extra vertex: " << *j << std::endl; 00483 return MB_FAILURE; 00484 } 00485 00486 return MB_SUCCESS; 00487 } 00488 #ifdef MOAB_HAVE_NETCDF 00489 ErrorCode mb_adjacencies_test() 00490 { 00491 Core moab; 00492 Interface* mb = &moab; 00493 ErrorCode result = load_file_one( mb ); 00494 if( MB_SUCCESS != result ) return result; 00495 00496 // this test does the following: 00497 // 1. For each element, creates vertex-element adjacencies (only for 00498 // lowest-id vertex) 00499 // 2. Creates all lower-order ancillary entities 00500 // 3. Checks for proper number of same 00501 // 00502 // assume mesh has already been read 00503 00504 EntityType seq_type; 00505 Range handle_range; 00506 00507 // lets create a skin of the hexes 00508 // this may be far from being the most efficient, but 00509 // it certainly does exercise the adjacency routines 00510 00511 Range::iterator iter; 00512 Range::reverse_iterator riter; 00513 00514 // first get the hexes 00515 Range hexes; 00516 result = mb->get_entities_by_type( 0, MBHEX, hexes ); 00517 if( MB_SUCCESS != result ) return result; 00518 00519 unsigned int num_hexes = hexes.size(); 00520 00521 // make sure we got hexes 00522 for( riter = hexes.rbegin(); riter != hexes.rend(); ++riter ) 00523 { 00524 if( TYPE_FROM_HANDLE( *riter ) != MBHEX ) return MB_FAILURE; 00525 } 00526 00527 // get all the nodes that these hexes are connected to 00528 Range nodes; 00529 result = mb->get_adjacencies( hexes, 0, false, nodes, Interface::UNION ); 00530 if( MB_SUCCESS != result ) return result; 00531 00532 // make sure we got nodes 00533 for( iter = nodes.begin(); iter != nodes.end(); ++iter ) 00534 { 00535 if( TYPE_FROM_HANDLE( *iter ) != MBVERTEX ) return MB_FAILURE; 00536 } 00537 00538 // find the interior nodes; assume a structured mesh 00539 Range interior_nodes; 00540 std::vector< EntityHandle > attached_hexes; 00541 for( iter = nodes.begin(); iter != nodes.end(); ) 00542 { 00543 attached_hexes.clear(); 00544 result = mb->get_adjacencies( &( *iter ), 1, 3, false, attached_hexes ); 00545 if( MB_SUCCESS != result ) return result; 00546 attached_hexes.erase( std::remove_if( attached_hexes.begin(), attached_hexes.end(), 00547 type_not_equals( mb, MBHEX ) ), 00548 attached_hexes.end() ); 00549 00550 // if this node has less than 8 hexes attached to it, it is not 00551 // an interior node 00552 if( attached_hexes.size() == 8 ) 00553 { 00554 // add to the interior nodes list and remove from the nodes list 00555 interior_nodes.insert( *iter ); 00556 iter = nodes.erase( iter ); 00557 } 00558 else 00559 ++iter; 00560 } 00561 00562 // get interior quads from interior nodes 00563 Range interior_quads; 00564 result = mb->get_adjacencies( interior_nodes, 2, true, interior_quads, Interface::UNION ); 00565 if( MB_SUCCESS != result ) return result; 00566 00567 // get a list of quads generated adjacent to the exterior nodes 00568 Range temp_quads, exterior_quads; 00569 result = mb->get_adjacencies( nodes, 2, true, temp_quads, Interface::UNION ); 00570 if( MB_SUCCESS != result ) return result; 00571 00572 // now remove any interior quads from the previous quads list 00573 // and we should be left with exterior quads 00574 std::set_difference( temp_quads.begin(), temp_quads.end(), interior_quads.begin(), interior_quads.end(), 00575 range_inserter( exterior_quads ) ); 00576 00577 // check to make sure we have the right number of quads; for hexes, should be 00578 // .5(6*num_hexes - num_exterior_quads) 00579 unsigned int num_expected_int_quads = ( 6 * num_hexes - exterior_quads.size() ) / 2; 00580 if( num_expected_int_quads != interior_quads.size() ) return MB_FAILURE; 00581 00582 // delete the interior quads 00583 result = mb->delete_entities( interior_quads ); 00584 if( MB_SUCCESS != result ) return result; 00585 00586 Range remaining_quads; 00587 result = mb->get_entities_by_type( 0, MBQUAD, remaining_quads ); 00588 if( MB_SUCCESS != result ) return result; 00589 00590 if( remaining_quads.size() != exterior_quads.size() ) return MB_FAILURE; 00591 00592 // 3. Checks for proper number of same 00593 // re-retrieve and store the handle ranges for all element types 00594 00595 int num_ents; 00596 00597 for( seq_type = MBEDGE; seq_type != MBENTITYSET; seq_type++ ) 00598 { 00599 handle_range.clear(); 00600 00601 result = mb->get_entities_by_type( 0, seq_type, handle_range ); 00602 if( MB_SUCCESS != result ) return result; 00603 00604 result = mb->get_number_entities_by_type( 0, seq_type, num_ents ); 00605 if( MB_SUCCESS != result ) return result; 00606 00607 if( handle_range.size() != (unsigned int)num_ents ) return MB_FAILURE; 00608 } 00609 00610 return result; 00611 } 00612 00613 #endif 00614 00615 ErrorCode mb_adjacencies_create_delete_test() 00616 { 00617 Core moab; 00618 Interface* mb = &moab; 00619 ErrorCode rval; 00620 00621 double coords[] = { 0, 0, 0, 2, 0, 0, 1, 2, 0 }; 00622 Range verts; 00623 rval = mb->create_vertices( coords, 3, verts ); 00624 if( MB_SUCCESS != rval ) return rval; 00625 if( verts.size() != 3 ) return MB_FAILURE; 00626 EntityHandle vert_arr[3]; 00627 00628 EntityHandle tri; 00629 std::copy( verts.begin(), verts.end(), vert_arr ); 00630 rval = mb->create_element( MBTRI, vert_arr, 3, tri ); 00631 if( MB_SUCCESS != rval ) return rval; 00632 00633 vert_arr[2] = vert_arr[0]; 00634 EntityHandle forward_edge, reverse_edge; 00635 rval = mb->create_element( MBEDGE, vert_arr, 2, forward_edge ); 00636 if( MB_SUCCESS != rval ) return rval; 00637 00638 std::vector< EntityHandle > results; 00639 rval = mb->get_adjacencies( &forward_edge, 1, 2, false, results ); 00640 if( results.size() != 1 || results.front() != tri ) 00641 { 00642 std::cerr << "Adjacency query from forward edge to tri failed at " << __FILE__ << ":" << __LINE__ << std::endl; 00643 return MB_FAILURE; 00644 } 00645 results.clear(); 00646 rval = mb->get_adjacencies( &tri, 1, 1, false, results ); 00647 if( results.size() != 1 || results.front() != forward_edge ) 00648 { 00649 std::cerr << "Adjacency query from tri to forward edge failed at " << __FILE__ << ":" << __LINE__ << std::endl; 00650 return MB_FAILURE; 00651 } 00652 00653 rval = mb->delete_entities( &forward_edge, 1 ); 00654 if( MB_SUCCESS != rval ) return rval; 00655 00656 results.clear(); 00657 rval = mb->get_adjacencies( &tri, 1, 1, false, results ); 00658 if( !results.empty() ) 00659 { 00660 std::cerr << "Adjacency query from tri returned non-existent edge at " << __FILE__ << ":" << __LINE__ 00661 << std::endl; 00662 return MB_FAILURE; 00663 } 00664 00665 rval = mb->create_element( MBEDGE, vert_arr + 1, 2, reverse_edge ); 00666 if( MB_SUCCESS != rval ) return rval; 00667 00668 results.clear(); 00669 rval = mb->get_adjacencies( &reverse_edge, 1, 2, false, results ); 00670 if( results.size() != 1 || results.front() != tri ) 00671 { 00672 std::cerr << "Adjacency query from reverse edge to tri failed at " << __FILE__ << ":" << __LINE__ << std::endl; 00673 return MB_FAILURE; 00674 } 00675 results.clear(); 00676 rval = mb->get_adjacencies( &tri, 1, 1, false, results ); 00677 if( results.size() != 1 || results.front() != reverse_edge ) 00678 { 00679 std::cerr << "Adjacency query from tri to reverse edge failed at " << __FILE__ << ":" << __LINE__ << std::endl; 00680 return MB_FAILURE; 00681 } 00682 00683 return MB_SUCCESS; 00684 } 00685 00686 static ErrorCode create_two_hex_full_mesh( Interface* mb, 00687 EntityHandle vertices[12], 00688 EntityHandle hexes[2], 00689 EntityHandle hex1_faces[6], 00690 EntityHandle hex2_faces[6], 00691 EntityHandle hex1_edges[12], 00692 EntityHandle hex2_edges[12] ) 00693 { 00694 ErrorCode rval; 00695 // create a simple mesh containing 2 hexes 00696 const double coords[] = { 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 1, 0, 1, 1, 0, 2, 1, 0, 00697 0, 0, 1, 1, 0, 1, 2, 0, 1, 0, 1, 1, 1, 1, 1, 2, 1, 1 }; 00698 for( int i = 0; i < 12; ++i ) 00699 if( MB_SUCCESS != mb->create_vertex( coords + 3 * i, vertices[i] ) ) return MB_FAILURE; 00700 EntityHandle hex1_conn[] = { vertices[6], vertices[7], vertices[1], vertices[0], 00701 vertices[9], vertices[10], vertices[4], vertices[3] }; 00702 EntityHandle hex2_conn[] = { vertices[7], vertices[8], vertices[2], vertices[1], 00703 vertices[10], vertices[11], vertices[5], vertices[4] }; 00704 EntityHandle shared_quad_conn[] = { vertices[7], vertices[1], vertices[4], vertices[10] }; 00705 EntityHandle hex1_face_conn[][4] = { { vertices[6], vertices[7], vertices[10], vertices[9] }, 00706 { vertices[7], vertices[6], vertices[0], vertices[1] }, 00707 { vertices[1], vertices[0], vertices[3], vertices[4] }, 00708 { vertices[9], vertices[10], vertices[4], vertices[3] }, 00709 { vertices[3], vertices[0], vertices[6], vertices[9] } }; 00710 EntityHandle hex2_face_conn[][4] = { { vertices[7], vertices[8], vertices[11], vertices[10] }, 00711 { vertices[8], vertices[7], vertices[1], vertices[2] }, 00712 { vertices[2], vertices[1], vertices[4], vertices[5] }, 00713 { vertices[10], vertices[11], vertices[5], vertices[4] }, 00714 { vertices[5], vertices[2], vertices[8], vertices[11] } }; 00715 EntityHandle shared_edge_conn[][2] = { { vertices[1], vertices[7] }, 00716 { vertices[7], vertices[10] }, 00717 { vertices[10], vertices[4] }, 00718 { vertices[4], vertices[1] } }; 00719 EntityHandle hex1_edge_conn[][2] = { { vertices[6], vertices[7] }, { vertices[9], vertices[10] }, 00720 { vertices[3], vertices[4] }, { vertices[0], vertices[1] }, 00721 { vertices[6], vertices[9] }, { vertices[9], vertices[3] }, 00722 { vertices[3], vertices[0] }, { vertices[0], vertices[6] } }; 00723 EntityHandle hex2_edge_conn[][2] = { { vertices[7], vertices[8] }, { vertices[10], vertices[11] }, 00724 { vertices[4], vertices[5] }, { vertices[1], vertices[2] }, 00725 { vertices[8], vertices[11] }, { vertices[11], vertices[5] }, 00726 { vertices[5], vertices[2] }, { vertices[2], vertices[8] } }; 00727 rval = mb->create_element( MBHEX, hex1_conn, 8, hexes[0] ); 00728 if( MB_SUCCESS != rval ) return rval; 00729 rval = mb->create_element( MBHEX, hex2_conn, 8, hexes[1] ); 00730 if( MB_SUCCESS != rval ) return rval; 00731 rval = mb->create_element( MBQUAD, shared_quad_conn, 4, hex1_faces[0] ); 00732 if( MB_SUCCESS != rval ) return rval; 00733 hex2_faces[0] = hex1_faces[0]; 00734 for( int i = 0; i < 5; ++i ) 00735 { 00736 rval = mb->create_element( MBQUAD, hex1_face_conn[i], 4, hex1_faces[i + 1] ); 00737 if( MB_SUCCESS != rval ) return rval; 00738 rval = mb->create_element( MBQUAD, hex2_face_conn[i], 4, hex2_faces[i + 1] ); 00739 if( MB_SUCCESS != rval ) return rval; 00740 } 00741 for( int i = 0; i < 4; ++i ) 00742 { 00743 rval = mb->create_element( MBEDGE, shared_edge_conn[i], 2, hex1_edges[i] ); 00744 if( MB_SUCCESS != rval ) return rval; 00745 hex2_edges[i] = hex1_edges[i]; 00746 } 00747 for( int i = 0; i < 8; ++i ) 00748 { 00749 rval = mb->create_element( MBEDGE, hex1_edge_conn[i], 2, hex1_edges[i + 4] ); 00750 if( MB_SUCCESS != rval ) return rval; 00751 rval = mb->create_element( MBEDGE, hex2_edge_conn[i], 2, hex2_edges[i + 4] ); 00752 if( MB_SUCCESS != rval ) return rval; 00753 } 00754 return MB_SUCCESS; 00755 } 00756 00757 ErrorCode mb_upward_adjacencies_test() 00758 { 00759 ErrorCode rval; 00760 Core moab; 00761 Interface* mb = &moab; 00762 00763 // create a simple mesh containing 2 hexes 00764 EntityHandle vertices[12], hexes[2], hex1_faces[6], hex2_faces[6], hex1_edges[12], hex2_edges[12]; 00765 rval = create_two_hex_full_mesh( mb, vertices, hexes, hex1_faces, hex2_faces, hex1_edges, hex2_edges );MB_CHK_ERR( rval ); 00766 00767 // test adjacences from dim to 3 00768 for( int dim = 0; dim < 3; ++dim ) 00769 { 00770 std::vector< EntityHandle > hex1_ent, hex2_ent, shared; 00771 const EntityHandle *list1, *list2; 00772 int n; 00773 switch( dim ) 00774 { 00775 case 0: 00776 rval = mb->get_connectivity( hexes[0], list1, n );MB_CHK_ERR( rval ); 00777 rval = mb->get_connectivity( hexes[1], list2, n );MB_CHK_ERR( rval ); 00778 break; 00779 case 1: 00780 list1 = hex1_edges; 00781 list2 = hex2_edges; 00782 n = 12; 00783 break; 00784 case 2: 00785 list1 = hex1_faces; 00786 list2 = hex2_faces; 00787 n = 6; 00788 break; 00789 } 00790 // split entities into those uniquely in hex1, those uniquely in hex2 00791 // and those shared between the two 00792 for( int i = 0; i < n; ++i ) 00793 { 00794 if( std::find( list2, list2 + n, list1[i] ) - list2 == n ) 00795 hex1_ent.push_back( list1[i] ); 00796 else 00797 shared.push_back( list1[i] ); 00798 if( std::find( list1, list1 + n, list2[i] ) - list1 == n ) hex2_ent.push_back( list2[i] ); 00799 } 00800 // for each shared entity check that get_adjacencies returns both hexes 00801 for( size_t j = 0; j < shared.size(); ++j ) 00802 { 00803 std::vector< EntityHandle > adj; 00804 rval = mb->get_adjacencies( &shared[j], 1, 3, false, adj );MB_CHK_ERR( rval ); 00805 if( adj.size() != 2 ) 00806 { 00807 std::cout << "Expected 2 hexes adjacent to " << dim << "D entity " << j << ". Got " << adj.size() 00808 << " hexes." << std::endl; 00809 return MB_FAILURE; 00810 } 00811 if( !( adj[0] == hexes[0] && adj[1] == hexes[1] ) && !( adj[0] == hexes[1] && adj[1] == hexes[0] ) ) 00812 { 00813 std::cout << "Got incorrect hexes adjacent to " << dim << "D entity " << j << std::endl; 00814 return MB_FAILURE; 00815 } 00816 } 00817 00818 for( size_t j = 0; j < hex1_ent.size(); ++j ) 00819 { 00820 std::vector< EntityHandle > adj; 00821 rval = mb->get_adjacencies( &hex1_ent[j], 1, 3, false, adj );MB_CHK_ERR( rval ); 00822 CHECK( adj.size() == 1 && adj[0] == hexes[0] ); 00823 } 00824 00825 for( size_t j = 0; j < hex2_ent.size(); ++j ) 00826 { 00827 std::vector< EntityHandle > adj; 00828 rval = mb->get_adjacencies( &hex2_ent[j], 1, 3, false, adj );MB_CHK_ERR( rval ); 00829 CHECK( adj.size() == 1 && adj[0] == hexes[1] ); 00830 } 00831 } 00832 00833 // For each edge, get adjacent faces, and for each face 00834 // get adjacent hexes. Result should be the same as 00835 // direct query from edges to hexes 00836 std::vector< EntityHandle > all_edges( 24 ); 00837 std::copy( hex1_edges, hex1_edges + 12, all_edges.begin() ); 00838 std::copy( hex2_edges, hex2_edges + 12, all_edges.begin() + 12 ); 00839 std::sort( all_edges.begin(), all_edges.end() ); 00840 all_edges.erase( std::unique( all_edges.begin(), all_edges.end() ), all_edges.end() ); 00841 for( size_t j = 0; j < all_edges.size(); ++j ) 00842 { 00843 std::vector< EntityHandle > edge_hexes, edge_faces, face_hexes; 00844 rval = mb->get_adjacencies( &all_edges[j], 1, 3, false, edge_hexes );MB_CHK_ERR( rval ); 00845 rval = mb->get_adjacencies( &all_edges[j], 1, 2, false, edge_faces );MB_CHK_ERR( rval ); 00846 rval = mb->get_adjacencies( &edge_faces[0], edge_faces.size(), 3, false, face_hexes, Interface::UNION );MB_CHK_ERR( rval ); 00847 if( edge_hexes.size() != face_hexes.size() ) 00848 { 00849 std::cout << "Inconsistent adjacency data for edge " << j << ". edge->face->hex resulted in " 00850 << face_hexes.size() << "hexes while edge->hex resulted in " << edge_hexes.size() << std::endl; 00851 return MB_FAILURE; 00852 } 00853 switch( edge_hexes.size() ) 00854 { 00855 case 1: 00856 CHECK( edge_hexes[0] == face_hexes[0] ); 00857 break; 00858 case 2: 00859 CHECK( ( edge_hexes[0] == face_hexes[0] && edge_hexes[1] == face_hexes[1] ) || 00860 ( edge_hexes[0] == face_hexes[1] && edge_hexes[1] == face_hexes[0] ) ); 00861 break; 00862 default: 00863 std::cout << "Got " << edge_hexes.size() << " hexes adjacent to edge " << j << std::endl; 00864 return MB_FAILURE; 00865 } 00866 } 00867 return MB_SUCCESS; 00868 } 00869 00870 ErrorCode mb_adjacent_create_test() 00871 { 00872 Core moab; 00873 Interface& mb = moab; 00874 ErrorCode rval; 00875 00876 // create vertices 00877 const double coords[][3] = { { -0.5, -0.5, 0.5 }, { -0.5, -0.5, -0.5 }, { -0.5, 0.5, -0.5 }, { -0.5, 0.5, 0.5 }, 00878 { 0.5, -0.5, 0.5 }, { 0.5, -0.5, -0.5 }, { 0.5, 0.5, -0.5 }, { 0.5, 0.5, 0.5 } }; 00879 EntityHandle verts[8] = { 0 }; 00880 for( int i = 0; i < 8; ++i ) 00881 { 00882 rval = mb.create_vertex( coords[i], verts[i] );MB_CHK_ERR( rval ); 00883 } 00884 // create a single hex 00885 const EntityHandle hconn[8] = { verts[0], verts[1], verts[2], verts[3], verts[4], verts[5], verts[6], verts[7] }; 00886 EntityHandle hex; 00887 rval = mb.create_element( MBHEX, hconn, 8, hex );MB_CHK_ERR( rval ); 00888 // create hex faces 00889 std::vector< EntityHandle > quads; 00890 rval = mb.get_adjacencies( &hex, 1, 2, true, quads, Interface::UNION );MB_CHK_ERR( rval ); 00891 CHECK_EQUAL( (size_t)6, quads.size() ); 00892 // check that we got each of the 6 expected faces, with outwards 00893 // normals assuming CCW order and correct connectivity 00894 const EntityHandle faces[6][4] = { 00895 { verts[0], verts[1], verts[5], verts[4] }, { verts[1], verts[2], verts[6], verts[5] }, 00896 { verts[2], verts[3], verts[7], verts[6] }, { verts[3], verts[0], verts[4], verts[7] }, 00897 { verts[3], verts[2], verts[1], verts[0] }, { verts[4], verts[5], verts[6], verts[7] } }; 00898 for( int i = 0; i < 6; ++i ) 00899 { // for each expected face 00900 // get sorted list of verts first for easy comparison 00901 std::vector< EntityHandle > exp_sorted( 4 ); 00902 std::copy( faces[i], faces[i] + 4, exp_sorted.begin() ); 00903 std::sort( exp_sorted.begin(), exp_sorted.end() ); 00904 // search for matching face in output 00905 int j = 0; 00906 std::vector< EntityHandle > conn; 00907 for( ; j < 6; ++j ) 00908 { 00909 conn.clear(); 00910 rval = mb.get_connectivity( &quads[j], 1, conn );MB_CHK_ERR( rval ); 00911 CHECK_EQUAL( (size_t)4, conn.size() ); 00912 std::vector< EntityHandle > sorted( conn ); 00913 std::sort( sorted.begin(), sorted.end() ); 00914 if( sorted == exp_sorted ) break; 00915 } 00916 if( j == 6 ) 00917 { 00918 std::cerr << "No adjacent face matching hex face " << i << std::endl; 00919 CHECK( j < 6 ); 00920 } 00921 // check order 00922 int k = std::find( conn.begin(), conn.end(), faces[i][0] ) - conn.begin(); 00923 for( j = 1; j < 4; ++j ) 00924 if( faces[i][j] != conn[( j + k ) % 4] ) break; 00925 if( j != 4 ) 00926 { 00927 std::cerr << "Incorrect vertex order for hex face " << i << std::endl; 00928 std::cerr << "Expected: " << faces[i][0] << ", " << faces[i][1] << ", " << faces[i][2] << ", " 00929 << faces[i][3] << std::endl; 00930 std::cerr << "Actual: " << conn[0] << ", " << conn[1] << ", " << conn[2] << ", " << conn[3] << std::endl; 00931 CHECK( false ); 00932 } 00933 } 00934 return MB_SUCCESS; 00935 } 00936 00937 ErrorCode nothing_but_type( Range& range, EntityType type ) 00938 { 00939 00940 // make sure there's nothing but hexes in hex_ms 00941 Range::iterator iter, end_iter; 00942 iter = range.begin(); 00943 end_iter = range.end(); 00944 00945 for( ; iter != end_iter; ++iter ) 00946 { 00947 if( TYPE_FROM_HANDLE( *iter ) != type ) 00948 { 00949 return MB_FAILURE; 00950 } 00951 } 00952 return MB_SUCCESS; 00953 } 00954 00955 ErrorCode check_esets( Interface* MB, const int num_sets ) 00956 { 00957 int entity_sets_size; 00958 ErrorCode result = MB->get_number_entities_by_type( 0, MBENTITYSET, entity_sets_size ); 00959 if( MB_SUCCESS != result || entity_sets_size != num_sets ) return MB_FAILURE; 00960 00961 return MB_SUCCESS; 00962 } 00963 00964 ErrorCode mb_mesh_sets_test( int flags ) 00965 { 00966 Core moab; 00967 Interface* MB = &moab; 00968 ErrorCode result = create_some_mesh( MB ); 00969 if( MB_SUCCESS != result ) return result; 00970 00971 Range temp_range; 00972 std::vector< EntityHandle > temp_vector; 00973 EntityType ent_type; 00974 00975 EntityHandle ms_array[MBENTITYSET] = { 0 }; 00976 unsigned int number_array[MBENTITYSET] = { 0 }; 00977 unsigned int num_dim_array[4] = { 0, 0, 0, 0 }; 00978 int count, start_num_sets; 00979 00980 result = MB->get_number_entities_by_type( 0, MBENTITYSET, start_num_sets ); 00981 if( MB_SUCCESS != result ) return result; 00982 00983 // add entities to meshsets 00984 for( ent_type = MBEDGE; ent_type != MBENTITYSET; ent_type++ ) 00985 { 00986 result = MB->create_meshset( flags, ms_array[ent_type] ); 00987 if( result != MB_SUCCESS ) return result; 00988 00989 temp_range.clear(); 00990 result = MB->get_entities_by_type( 0, ent_type, temp_range ); 00991 if( result != MB_SUCCESS ) return result; 00992 result = MB->get_number_entities_by_type( 0, ent_type, count ); 00993 if( result != MB_SUCCESS ) return result; 00994 if( (unsigned)count != temp_range.size() ) return MB_FAILURE; 00995 result = MB->add_entities( ms_array[ent_type], temp_range ); 00996 if( result != MB_SUCCESS ) return result; 00997 00998 number_array[ent_type] = temp_range.size(); // KGM 00999 num_dim_array[CN::Dimension( ent_type )] += count; 01000 01001 // Check to make sure mesh set really has correct number of entities in it 01002 temp_range.clear(); 01003 temp_vector.clear(); 01004 result = MB->get_entities_by_handle( ms_array[ent_type], temp_range ); 01005 if( result != MB_SUCCESS ) return result; 01006 if( number_array[ent_type] != temp_range.size() ) 01007 { 01008 cout << "Number of entities in meshset test is not correct" << endl; 01009 return MB_FAILURE; 01010 } 01011 if( !temp_range.all_of_type( ent_type ) ) return MB_FAILURE; 01012 01013 result = MB->get_entities_by_handle( ms_array[ent_type], temp_vector ); 01014 if( result != MB_SUCCESS ) return result; 01015 if( number_array[ent_type] != temp_vector.size() ) 01016 { 01017 cout << "Number of entities in meshset test is not correct" << endl; 01018 return MB_FAILURE; 01019 } 01020 01021 temp_range.clear(); 01022 result = MB->get_entities_by_type( ms_array[ent_type], ent_type, temp_range ); 01023 if( result != MB_SUCCESS ) return result; 01024 if( number_array[ent_type] != temp_range.size() ) 01025 { 01026 cout << "Number of entities by type in meshset test is not correct" << endl; 01027 return MB_FAILURE; 01028 } 01029 if( !temp_range.all_of_type( ent_type ) ) return MB_FAILURE; 01030 01031 temp_range.clear(); 01032 result = MB->get_entities_by_type( ms_array[ent_type], MBVERTEX, temp_range ); 01033 if( result != MB_SUCCESS ) return result; 01034 if( 0 != temp_range.size() ) return MB_FAILURE; 01035 01036 temp_range.clear(); 01037 result = MB->get_entities_by_dimension( ms_array[ent_type], CN::Dimension( ent_type ), temp_range ); 01038 if( result != MB_SUCCESS ) return result; 01039 if( number_array[ent_type] != temp_range.size() ) 01040 { 01041 cout << "Number of entities by dimension in meshset test is not correct" << endl; 01042 return MB_FAILURE; 01043 } 01044 if( !temp_range.all_of_type( ent_type ) ) return MB_FAILURE; 01045 01046 temp_range.clear(); 01047 result = MB->get_entities_by_dimension( ms_array[ent_type], 0, temp_range ); 01048 if( result != MB_SUCCESS ) return result; 01049 if( 0 != temp_range.size() ) 01050 { 01051 cout << "Number of entities by dimension in meshset test is not correct" << endl; 01052 return MB_FAILURE; 01053 } 01054 01055 result = MB->get_number_entities_by_handle( ms_array[ent_type], count ); 01056 if( result != MB_SUCCESS ) return result; 01057 if( (unsigned)count != number_array[ent_type] ) return MB_FAILURE; 01058 01059 result = MB->get_number_entities_by_type( ms_array[ent_type], ent_type, count ); 01060 if( result != MB_SUCCESS ) return result; 01061 if( (unsigned)count != number_array[ent_type] ) return MB_FAILURE; 01062 01063 result = MB->get_number_entities_by_type( ms_array[ent_type], MBVERTEX, count ); 01064 if( result != MB_SUCCESS ) return result; 01065 if( count != 0 ) return MB_FAILURE; 01066 01067 result = MB->get_number_entities_by_dimension( ms_array[ent_type], CN::Dimension( ent_type ), count ); 01068 if( result != MB_SUCCESS ) return result; 01069 if( (unsigned)count != number_array[ent_type] ) return MB_FAILURE; 01070 01071 result = MB->get_number_entities_by_dimension( ms_array[ent_type], 0, count ); 01072 if( result != MB_SUCCESS ) return result; 01073 if( count != 0 ) return MB_FAILURE; 01074 } 01075 01076 result = check_esets( MB, start_num_sets + MBENTITYSET - MBEDGE ); 01077 if( MB_SUCCESS != result ) return result; 01078 01079 for( int dim = 1; dim < 4; ++dim ) 01080 { 01081 result = MB->get_number_entities_by_dimension( 0, dim, count ); 01082 if( MB_SUCCESS != result ) return MB_FAILURE; 01083 if( (unsigned)count != num_dim_array[dim] ) return MB_FAILURE; 01084 } 01085 01086 //----------TEST RECURSIVE OPERATIONS----------------// 01087 EntityHandle recursive1, recursive2; 01088 result = MB->create_meshset( MESHSET_SET, recursive1 ); 01089 if( result != MB_SUCCESS ) return result; 01090 result = MB->create_meshset( 0, recursive2 ); 01091 if( result != MB_SUCCESS ) return result; 01092 unsigned num_sets = MBENTITYSET - MBEDGE; 01093 result = MB->add_entities( recursive2, ms_array + MBEDGE, num_sets ); 01094 if( MB_SUCCESS != result ) return result; 01095 result = MB->add_entities( recursive1, &recursive2, 1 ); 01096 if( MB_SUCCESS != result ) return result; 01097 01098 temp_range.clear(); 01099 result = MB->get_entities_by_type( recursive1, MBENTITYSET, temp_range ); 01100 if( MB_SUCCESS != result ) return result; 01101 if( temp_range.size() != 1 || *( temp_range.begin() ) != recursive2 ) return MB_FAILURE; 01102 01103 temp_range.clear(); 01104 result = MB->get_entities_by_type( recursive2, MBENTITYSET, temp_range ); 01105 if( MB_SUCCESS != result ) return result; 01106 if( temp_range.size() != num_sets || !temp_range.all_of_type( MBENTITYSET ) ) return MB_FAILURE; 01107 01108 temp_range.clear(); 01109 result = MB->get_entities_by_handle( recursive1, temp_range ); 01110 if( MB_SUCCESS != result ) return result; 01111 if( temp_range.size() != 1 || *( temp_range.begin() ) != recursive2 ) return MB_FAILURE; 01112 01113 temp_range.clear(); 01114 result = MB->get_entities_by_handle( recursive2, temp_range ); 01115 if( MB_SUCCESS != result ) return result; 01116 if( temp_range.size() != num_sets || !temp_range.all_of_type( MBENTITYSET ) ) return MB_FAILURE; 01117 01118 unsigned total = 0; 01119 for( ent_type = MBEDGE; ent_type != MBENTITYSET; ent_type++ ) 01120 { 01121 total += number_array[ent_type]; 01122 temp_range.clear(); 01123 result = MB->get_entities_by_type( recursive1, ent_type, temp_range, true ); 01124 if( result != MB_SUCCESS ) return result; 01125 if( number_array[ent_type] != temp_range.size() ) 01126 { 01127 cout << "Recursive number of entities by type in meshset test is not correct" << endl; 01128 return MB_FAILURE; 01129 } 01130 if( !temp_range.all_of_type( ent_type ) ) return MB_FAILURE; 01131 result = MB->get_number_entities_by_type( recursive1, ent_type, count, true ); 01132 if( result != MB_SUCCESS ) return result; 01133 if( number_array[ent_type] != (unsigned)count ) 01134 { 01135 cout << "Recursive number of entities by type in meshset test is not correct" << endl; 01136 return MB_FAILURE; 01137 } 01138 if( !temp_range.all_of_type( ent_type ) ) return MB_FAILURE; 01139 } 01140 if( 0 == total ) 01141 { 01142 cout << "Invalid test input. No entities!" << endl; 01143 return MB_FAILURE; 01144 } 01145 01146 for( int dim = 1; dim < 4; ++dim ) 01147 { 01148 temp_range.clear(); 01149 result = MB->get_entities_by_dimension( recursive1, dim, temp_range, true ); 01150 if( MB_SUCCESS != result ) return MB_FAILURE; 01151 if( temp_range.size() != num_dim_array[dim] ) return MB_FAILURE; 01152 if( !temp_range.all_of_dimension( dim ) ) return MB_FAILURE; 01153 result = MB->get_number_entities_by_dimension( recursive1, dim, count, true ); 01154 if( MB_SUCCESS != result ) return MB_FAILURE; 01155 if( (unsigned)count != num_dim_array[dim] ) return MB_FAILURE; 01156 } 01157 01158 temp_range.clear(); 01159 result = MB->get_entities_by_handle( recursive1, temp_range, true ); 01160 if( result != MB_SUCCESS ) return result; 01161 if( total != temp_range.size() ) 01162 { 01163 cout << "Recursive number of entities in meshset test is not correct" << endl; 01164 return MB_FAILURE; 01165 } 01166 01167 // try circular relation 01168 result = MB->add_entities( recursive2, &recursive1, 1 ); 01169 if( MB_SUCCESS != result ) 01170 { 01171 std::cout << "Failed to create circular set containment" << std::endl; 01172 return result; 01173 } 01174 temp_range.clear(); 01175 result = MB->get_entities_by_handle( recursive1, temp_range, true ); 01176 if( result != MB_SUCCESS ) return result; 01177 if( total != temp_range.size() ) 01178 { 01179 cout << "Recursive number of entities in meshset test is not correct" << endl; 01180 return MB_FAILURE; 01181 } 01182 01183 result = check_esets( MB, start_num_sets + MBENTITYSET - MBEDGE + 2 ); 01184 if( MB_SUCCESS != result ) return result; 01185 01186 //----------TEST BOOLEAN OPERATIONS----------------// 01187 01188 EntityHandle temp_ms1, temp_ms2; 01189 result = MB->create_meshset( flags, temp_ms1 ); 01190 if( result != MB_SUCCESS ) return result; 01191 result = MB->create_meshset( flags, temp_ms2 ); 01192 if( result != MB_SUCCESS ) return result; 01193 01194 // Subtract 01195 // add all edges and hexes of ms_array[MBHEX] and ms_array[MBEDGE] to temp_ms1 01196 // get all Edge entities 01197 temp_range.clear(); 01198 result = MB->get_entities_by_handle( ms_array[MBEDGE], temp_range ); 01199 if( result != MB_SUCCESS ) return result; 01200 01201 // add Edges to ms1 01202 result = MB->add_entities( temp_ms1, temp_range ); 01203 if( result != MB_SUCCESS ) return result; 01204 01205 temp_range.clear(); 01206 result = MB->get_entities_by_handle( ms_array[MBHEX], temp_range ); 01207 if( result != MB_SUCCESS ) return result; 01208 01209 // add Hexes to ms1 01210 result = MB->add_entities( temp_ms1, temp_range ); 01211 if( result != MB_SUCCESS ) return result; 01212 01213 // subtract bars meshset out of hex meshset 01214 result = MB->subtract_meshset( temp_ms1, ms_array[MBEDGE] ); 01215 if( result != MB_SUCCESS ) return result; 01216 01217 // Perform the check 01218 temp_range.clear(); 01219 result = MB->get_entities_by_handle( temp_ms1, temp_range ); 01220 if( result != MB_SUCCESS ) return result; 01221 01222 if( number_array[MBHEX] != temp_range.size() ) 01223 { 01224 cout << "MBset subtraction is bad" << endl; 01225 return MB_FAILURE; 01226 } 01227 // make sure there's nothing but hexes in hex_ms 01228 if( nothing_but_type( temp_range, MBHEX ) != MB_SUCCESS ) return MB_FAILURE; 01229 01230 result = check_esets( MB, start_num_sets + MBENTITYSET - MBEDGE + 4 ); 01231 if( MB_SUCCESS != result ) return result; 01232 01233 //------------Intersect------------ 01234 // 01235 // clean out the temp_ms1 01236 MB->clear_meshset( &temp_ms1, 1 ); 01237 01238 temp_range.clear(); 01239 // get all quad entities 01240 temp_range.clear(); 01241 result = MB->get_entities_by_handle( ms_array[MBQUAD], temp_range ); 01242 if( result != MB_SUCCESS ) return result; 01243 01244 // add tets them to ms1 01245 result = MB->add_entities( temp_ms1, temp_range ); 01246 if( result != MB_SUCCESS ) return result; 01247 01248 // get all tet entities 01249 temp_range.clear(); 01250 result = MB->get_entities_by_handle( ms_array[MBTET], temp_range ); 01251 if( result != MB_SUCCESS ) return result; 01252 01253 // add tets them to ms1 01254 result = MB->add_entities( temp_ms1, temp_range ); 01255 if( result != MB_SUCCESS ) return result; 01256 01257 // intersect temp_ms1 (which contains all quads and tets) with tet meshset 01258 // temp_ms1 meshset is altered 01259 result = MB->intersect_meshset( temp_ms1, ms_array[MBTET] ); 01260 if( result != MB_SUCCESS ) return result; 01261 01262 // Perform the check, only tets should be in temp_ms1 01263 temp_range.clear(); 01264 result = MB->get_entities_by_handle( temp_ms1, temp_range ); 01265 if( result != MB_SUCCESS ) return result; 01266 if( number_array[MBTET] != temp_range.size() ) 01267 { 01268 cout << "MBset intersection is bad" << endl; 01269 return MB_FAILURE; 01270 } 01271 01272 // make sure there's nothing but tet in range 01273 if( nothing_but_type( temp_range, MBTET ) != MB_SUCCESS ) return MB_FAILURE; 01274 01275 result = check_esets( MB, start_num_sets + MBENTITYSET - MBEDGE + 4 ); 01276 if( MB_SUCCESS != result ) return result; 01277 01278 //-------------Unite-------------- 01279 // fill temp_ms1 with tets and tris 01280 // get all tris 01281 temp_range.clear(); 01282 result = MB->get_entities_by_handle( ms_array[MBTRI], temp_range ); 01283 if( result != MB_SUCCESS ) return result; 01284 01285 // add tets them to ms1 01286 result = MB->add_entities( temp_ms1, temp_range ); 01287 if( result != MB_SUCCESS ) return result; 01288 01289 temp_range.clear(); 01290 result = MB->get_entities_by_handle( ms_array[MBTET], temp_range ); 01291 if( result != MB_SUCCESS ) return result; 01292 01293 // add tets them to ms1 01294 result = MB->add_entities( temp_ms1, temp_range ); 01295 if( result != MB_SUCCESS ) return result; 01296 01297 // fill temp_ms2 with tris and hexes 01298 temp_range.clear(); 01299 result = MB->get_entities_by_handle( ms_array[MBTRI], temp_range ); 01300 if( result != MB_SUCCESS ) return result; 01301 01302 // add tets them to ms1 01303 result = MB->add_entities( temp_ms2, temp_range ); 01304 if( result != MB_SUCCESS ) return result; 01305 01306 temp_range.clear(); 01307 result = MB->get_entities_by_handle( ms_array[MBQUAD], temp_range ); 01308 if( result != MB_SUCCESS ) return result; 01309 01310 // add tets them to ms1 01311 result = MB->add_entities( temp_ms2, temp_range ); 01312 if( result != MB_SUCCESS ) return result; 01313 01314 // temp_ms1 is now filled with tets and tris 01315 // temp_ms2 is now filled with quads and tris 01316 int size1 = 0, size2 = 0; 01317 result = MB->get_number_entities_by_handle( ms_array[MBTRI], size1 ); 01318 if( result != MB_SUCCESS ) return result; 01319 01320 result = MB->intersect_meshset( temp_ms1, temp_ms2 ); 01321 if( result != MB_SUCCESS ) return result; 01322 result = MB->get_number_entities_by_handle( temp_ms1, size2 ); 01323 if( result != MB_SUCCESS ) return result; 01324 01325 if( size1 != size2 ) 01326 { 01327 return MB_FAILURE; 01328 } 01329 01330 temp_range.clear(); 01331 result = MB->get_entities_by_handle( temp_ms1, temp_range ); 01332 if( result != MB_SUCCESS ) return result; 01333 01334 // make sure there's nothing but tris in temp_range 01335 if( nothing_but_type( temp_range, MBTRI ) != MB_SUCCESS ) return MB_FAILURE; 01336 01337 result = check_esets( MB, start_num_sets + MBENTITYSET - MBEDGE + 4 ); 01338 if( MB_SUCCESS != result ) return result; 01339 01340 //-------------Misc tests-------------- 01341 EntityHandle temp_ms3; 01342 result = MB->create_meshset( flags, temp_ms3 ); 01343 if( result != MB_SUCCESS ) return result; 01344 01345 EntityHandle handle_array[] = { 1, 2, 3, 4, 5, 7, 8, 9, 10 }; 01346 const int num_handle = sizeof( handle_array ) / sizeof( handle_array[0] ); 01347 // add ents to set 01348 result = MB->add_entities( temp_ms3, handle_array, num_handle ); 01349 if( result != MB_SUCCESS ) return result; 01350 01351 // try adding again 01352 result = MB->add_entities( temp_ms3, handle_array, num_handle ); 01353 if( result != MB_SUCCESS ) return result; 01354 01355 int num_ents; 01356 result = MB->get_number_entities_by_handle( temp_ms3, num_ents ); 01357 if( result != MB_SUCCESS ) return result; 01358 01359 int num_expected = ( flags & MESHSET_SET ) ? num_handle : 2 * num_handle; 01360 if( num_ents != num_expected ) return MB_FAILURE; 01361 01362 return MB_SUCCESS; 01363 } 01364 01365 static bool compare_lists( std::vector< EntityHandle > vect, const EntityHandle* array, int count, bool ordered = true ) 01366 { 01367 if( vect.size() != (size_t)count ) return false; 01368 for( int i = 0; i < count; ++i ) 01369 { 01370 if( ordered ) 01371 { 01372 if( vect[i] != array[i] ) return false; 01373 } 01374 else if( std::find( vect.begin(), vect.end(), array[i] ) == vect.end() ) 01375 return false; 01376 } 01377 return true; 01378 } 01379 01380 // Test parent/child stuff in meshsets 01381 ErrorCode mb_mesh_set_parent_child_test() 01382 { 01383 Core moab; 01384 Interface* MB = &moab; 01385 01386 ErrorCode rval; 01387 std::vector< EntityHandle > list; 01388 Range range; 01389 Range::iterator iter; 01390 int count; 01391 01392 // create a few mesh sets 01393 const int num_sets = 10; 01394 EntityHandle sets[num_sets]; 01395 for( int i = 0; i < num_sets; ++i ) 01396 { 01397 rval = MB->create_meshset( i % 2 ? MESHSET_SET : 0, sets[i] ); 01398 if( MB_SUCCESS != rval ) return rval; 01399 } 01400 01401 // test adding child meshsets 01402 01403 // add first child 01404 rval = MB->add_child_meshset( sets[0], sets[1] ); 01405 if( MB_SUCCESS != rval ) return rval; 01406 list.clear(); 01407 rval = MB->get_child_meshsets( sets[0], list ); 01408 if( MB_SUCCESS != rval ) return rval; 01409 if( !compare_lists( list, sets + 1, 1 ) ) return MB_FAILURE; 01410 // try to add child again 01411 rval = MB->add_child_meshset( sets[0], sets[1] ); 01412 if( MB_SUCCESS != rval ) return rval; 01413 list.clear(); 01414 rval = MB->get_child_meshsets( sets[0], list ); 01415 if( MB_SUCCESS != rval ) return rval; 01416 if( !compare_lists( list, sets + 1, 1 ) ) return MB_FAILURE; 01417 01418 // add second child 01419 rval = MB->add_child_meshset( sets[0], sets[2] ); 01420 if( MB_SUCCESS != rval ) return rval; 01421 list.clear(); 01422 rval = MB->get_child_meshsets( sets[0], list ); 01423 if( MB_SUCCESS != rval ) return rval; 01424 if( !compare_lists( list, sets + 1, 2 ) ) return MB_FAILURE; 01425 // try adding child again 01426 rval = MB->add_child_meshset( sets[0], sets[1] ); 01427 if( MB_SUCCESS != rval ) return rval; 01428 list.clear(); 01429 rval = MB->get_child_meshsets( sets[0], list ); 01430 if( MB_SUCCESS != rval ) return rval; 01431 if( !compare_lists( list, sets + 1, 2 ) ) return MB_FAILURE; 01432 01433 // add third child 01434 rval = MB->add_child_meshset( sets[0], sets[3] ); 01435 if( MB_SUCCESS != rval ) return rval; 01436 list.clear(); 01437 rval = MB->get_child_meshsets( sets[0], list ); 01438 if( MB_SUCCESS != rval ) return rval; 01439 if( !compare_lists( list, sets + 1, 3 ) ) return MB_FAILURE; 01440 // try adding child again 01441 rval = MB->add_child_meshset( sets[0], sets[1] ); 01442 if( MB_SUCCESS != rval ) return rval; 01443 list.clear(); 01444 rval = MB->get_child_meshsets( sets[0], list ); 01445 if( MB_SUCCESS != rval ) return rval; 01446 if( !compare_lists( list, sets + 1, 3 ) ) return MB_FAILURE; 01447 01448 // add fourth child 01449 rval = MB->add_child_meshset( sets[0], sets[4] ); 01450 if( MB_SUCCESS != rval ) return rval; 01451 list.clear(); 01452 rval = MB->get_child_meshsets( sets[0], list ); 01453 if( MB_SUCCESS != rval ) return rval; 01454 if( !compare_lists( list, sets + 1, 4 ) ) return MB_FAILURE; 01455 01456 // make sure range query returns same result 01457 std::sort( list.begin(), list.end() ); 01458 rval = MB->get_child_meshsets( sets[0], range ); 01459 iter = range.begin(); 01460 for( unsigned i = 0; i < 4; ++i, ++iter ) 01461 if( *iter != list[i] ) return MB_FAILURE; 01462 01463 // remove first child 01464 rval = MB->remove_child_meshset( sets[0], sets[1] ); 01465 if( MB_SUCCESS != rval ) return rval; 01466 list.clear(); 01467 rval = MB->get_child_meshsets( sets[0], list ); 01468 if( MB_SUCCESS != rval ) return rval; 01469 if( !compare_lists( list, sets + 2, 3 ) ) return MB_FAILURE; 01470 // try removing child again 01471 rval = MB->remove_child_meshset( sets[0], sets[1] ); 01472 if( MB_SUCCESS != rval ) return rval; 01473 01474 // remove second child 01475 rval = MB->remove_child_meshset( sets[0], sets[2] ); 01476 if( MB_SUCCESS != rval ) return rval; 01477 list.clear(); 01478 rval = MB->get_child_meshsets( sets[0], list ); 01479 if( !compare_lists( list, sets + 3, 2 ) ) return MB_FAILURE; 01480 // try removing child again 01481 rval = MB->remove_child_meshset( sets[0], sets[2] ); 01482 if( MB_SUCCESS != rval ) return rval; 01483 01484 // remove third child 01485 rval = MB->remove_child_meshset( sets[0], sets[3] ); 01486 if( MB_SUCCESS != rval ) return rval; 01487 list.clear(); 01488 rval = MB->get_child_meshsets( sets[0], list ); 01489 if( list.size() != 1 || list[0] != sets[4] ) return MB_FAILURE; 01490 01491 // remove fourth child 01492 rval = MB->remove_child_meshset( sets[0], sets[4] ); 01493 if( MB_SUCCESS != rval ) return rval; 01494 list.clear(); 01495 rval = MB->get_child_meshsets( sets[0], list ); 01496 if( !list.empty() ) return MB_FAILURE; 01497 01498 // test adding parent meshsets 01499 01500 // add first parent 01501 rval = MB->add_parent_meshset( sets[0], sets[1] ); 01502 if( MB_SUCCESS != rval ) return rval; 01503 list.clear(); 01504 rval = MB->get_parent_meshsets( sets[0], list ); 01505 if( MB_SUCCESS != rval ) return rval; 01506 if( !compare_lists( list, sets + 1, 1 ) ) return MB_FAILURE; 01507 // try to add parent again 01508 rval = MB->add_parent_meshset( sets[0], sets[1] ); 01509 if( MB_SUCCESS != rval ) return rval; 01510 list.clear(); 01511 rval = MB->get_parent_meshsets( sets[0], list ); 01512 if( MB_SUCCESS != rval ) return rval; 01513 if( !compare_lists( list, sets + 1, 1 ) ) return MB_FAILURE; 01514 01515 // add second parent 01516 rval = MB->add_parent_meshset( sets[0], sets[2] ); 01517 if( MB_SUCCESS != rval ) return rval; 01518 list.clear(); 01519 rval = MB->get_parent_meshsets( sets[0], list ); 01520 if( MB_SUCCESS != rval ) return rval; 01521 if( !compare_lists( list, sets + 1, 2 ) ) return MB_FAILURE; 01522 // try adding parent again 01523 rval = MB->add_parent_meshset( sets[0], sets[1] ); 01524 if( MB_SUCCESS != rval ) return rval; 01525 list.clear(); 01526 rval = MB->get_parent_meshsets( sets[0], list ); 01527 if( MB_SUCCESS != rval ) return rval; 01528 if( !compare_lists( list, sets + 1, 2 ) ) return MB_FAILURE; 01529 01530 // add third parent 01531 rval = MB->add_parent_meshset( sets[0], sets[3] ); 01532 if( MB_SUCCESS != rval ) return rval; 01533 list.clear(); 01534 rval = MB->get_parent_meshsets( sets[0], list ); 01535 if( MB_SUCCESS != rval ) return rval; 01536 if( !compare_lists( list, sets + 1, 3 ) ) return MB_FAILURE; 01537 // try adding parent again 01538 rval = MB->add_parent_meshset( sets[0], sets[1] ); 01539 if( MB_SUCCESS != rval ) return rval; 01540 list.clear(); 01541 rval = MB->get_parent_meshsets( sets[0], list ); 01542 if( MB_SUCCESS != rval ) return rval; 01543 if( !compare_lists( list, sets + 1, 3 ) ) return MB_FAILURE; 01544 01545 // add fourth parent 01546 rval = MB->add_parent_meshset( sets[0], sets[4] ); 01547 if( MB_SUCCESS != rval ) return rval; 01548 list.clear(); 01549 rval = MB->get_parent_meshsets( sets[0], list ); 01550 if( MB_SUCCESS != rval ) return rval; 01551 if( !compare_lists( list, sets + 1, 4 ) ) return MB_FAILURE; 01552 01553 // make sure range query returns same result 01554 std::sort( list.begin(), list.end() ); 01555 rval = MB->get_parent_meshsets( sets[0], range ); 01556 iter = range.begin(); 01557 for( unsigned i = 0; i < 4; ++i, ++iter ) 01558 if( *iter != list[i] ) return MB_FAILURE; 01559 01560 // remove first parent 01561 rval = MB->remove_parent_meshset( sets[0], sets[1] ); 01562 if( MB_SUCCESS != rval ) return rval; 01563 list.clear(); 01564 rval = MB->get_parent_meshsets( sets[0], list ); 01565 if( MB_SUCCESS != rval ) return rval; 01566 if( !compare_lists( list, sets + 2, 3 ) ) return MB_FAILURE; 01567 // try removing parent again 01568 rval = MB->remove_parent_meshset( sets[0], sets[1] ); 01569 if( MB_SUCCESS != rval ) return rval; 01570 01571 // remove second parent 01572 rval = MB->remove_parent_meshset( sets[0], sets[2] ); 01573 if( MB_SUCCESS != rval ) return rval; 01574 list.clear(); 01575 rval = MB->get_parent_meshsets( sets[0], list ); 01576 if( !compare_lists( list, sets + 3, 2 ) ) return MB_FAILURE; 01577 // try removing parent again 01578 rval = MB->remove_parent_meshset( sets[0], sets[2] ); 01579 if( MB_SUCCESS != rval ) return rval; 01580 01581 // remove third parent 01582 rval = MB->remove_parent_meshset( sets[0], sets[3] ); 01583 if( MB_SUCCESS != rval ) return rval; 01584 list.clear(); 01585 rval = MB->get_parent_meshsets( sets[0], list ); 01586 if( list.size() != 1 || list[0] != sets[4] ) return MB_FAILURE; 01587 01588 // remove fourth parent 01589 rval = MB->remove_parent_meshset( sets[0], sets[4] ); 01590 if( MB_SUCCESS != rval ) return rval; 01591 list.clear(); 01592 rval = MB->get_parent_meshsets( sets[0], list ); 01593 if( !list.empty() ) return MB_FAILURE; 01594 01595 // setup tests of recursive child query 01596 // 0 01597 // / \ . 01598 // 1 2 01599 // / \ / \ . 01600 // 3 4 5 01601 // \ / \ / 01602 // 6 7 01603 rval = MB->add_child_meshset( sets[0], sets[1] ); 01604 if( MB_SUCCESS != rval ) return rval; 01605 rval = MB->add_child_meshset( sets[0], sets[2] ); 01606 if( MB_SUCCESS != rval ) return rval; 01607 rval = MB->add_child_meshset( sets[1], sets[3] ); 01608 if( MB_SUCCESS != rval ) return rval; 01609 rval = MB->add_child_meshset( sets[1], sets[4] ); 01610 if( MB_SUCCESS != rval ) return rval; 01611 rval = MB->add_child_meshset( sets[2], sets[4] ); 01612 if( MB_SUCCESS != rval ) return rval; 01613 rval = MB->add_child_meshset( sets[2], sets[5] ); 01614 if( MB_SUCCESS != rval ) return rval; 01615 rval = MB->add_child_meshset( sets[3], sets[6] ); 01616 if( MB_SUCCESS != rval ) return rval; 01617 rval = MB->add_child_meshset( sets[4], sets[6] ); 01618 if( MB_SUCCESS != rval ) return rval; 01619 rval = MB->add_child_meshset( sets[4], sets[7] ); 01620 if( MB_SUCCESS != rval ) return rval; 01621 rval = MB->add_child_meshset( sets[5], sets[7] ); 01622 if( MB_SUCCESS != rval ) return rval; 01623 01624 // test query at depth of 1 01625 list.clear(); 01626 rval = MB->get_child_meshsets( sets[0], list, 1 ); 01627 if( MB_SUCCESS != rval ) return rval; 01628 if( list.size() != 2 || list[0] != sets[1] || list[1] != sets[2] ) return MB_FAILURE; 01629 rval = MB->num_child_meshsets( sets[0], &count, 1 ); 01630 if( MB_SUCCESS != rval ) return rval; 01631 if( count != 2 ) return MB_FAILURE; 01632 01633 // test query at depth of 2 01634 list.clear(); 01635 rval = MB->get_child_meshsets( sets[0], list, 2 ); 01636 if( MB_SUCCESS != rval ) return rval; 01637 if( !compare_lists( list, sets + 1, 5, false ) ) return MB_FAILURE; 01638 rval = MB->num_child_meshsets( sets[0], &count, 2 ); 01639 if( MB_SUCCESS != rval ) return rval; 01640 if( count != 5 ) return MB_FAILURE; 01641 01642 // test query at depth of 3 01643 list.clear(); 01644 rval = MB->get_child_meshsets( sets[0], list, 3 ); 01645 if( MB_SUCCESS != rval ) return rval; 01646 if( !compare_lists( list, sets + 1, 7, false ) ) return MB_FAILURE; 01647 rval = MB->num_child_meshsets( sets[0], &count, 3 ); 01648 if( MB_SUCCESS != rval ) return rval; 01649 if( count != 7 ) return MB_FAILURE; 01650 01651 // test query at depth of 4 01652 list.clear(); 01653 rval = MB->get_child_meshsets( sets[0], list, 4 ); 01654 if( MB_SUCCESS != rval ) return rval; 01655 if( !compare_lists( list, sets + 1, 7, false ) ) return MB_FAILURE; 01656 rval = MB->num_child_meshsets( sets[0], &count, 4 ); 01657 if( MB_SUCCESS != rval ) return rval; 01658 if( count != 7 ) return MB_FAILURE; 01659 01660 // test query at all 01661 list.clear(); 01662 rval = MB->get_child_meshsets( sets[0], list, 0 ); 01663 if( MB_SUCCESS != rval ) return rval; 01664 if( !compare_lists( list, sets + 1, 7, false ) ) return MB_FAILURE; 01665 rval = MB->num_child_meshsets( sets[0], &count, 0 ); 01666 if( MB_SUCCESS != rval ) return rval; 01667 if( count != 7 ) return MB_FAILURE; 01668 01669 // clean up child links 01670 rval = MB->remove_child_meshset( sets[0], sets[1] ); 01671 if( MB_SUCCESS != rval ) return rval; 01672 rval = MB->remove_child_meshset( sets[0], sets[2] ); 01673 if( MB_SUCCESS != rval ) return rval; 01674 rval = MB->remove_child_meshset( sets[1], sets[3] ); 01675 if( MB_SUCCESS != rval ) return rval; 01676 rval = MB->remove_child_meshset( sets[1], sets[4] ); 01677 if( MB_SUCCESS != rval ) return rval; 01678 rval = MB->remove_child_meshset( sets[2], sets[4] ); 01679 if( MB_SUCCESS != rval ) return rval; 01680 rval = MB->remove_child_meshset( sets[2], sets[5] ); 01681 if( MB_SUCCESS != rval ) return rval; 01682 rval = MB->remove_child_meshset( sets[3], sets[6] ); 01683 if( MB_SUCCESS != rval ) return rval; 01684 rval = MB->remove_child_meshset( sets[4], sets[6] ); 01685 if( MB_SUCCESS != rval ) return rval; 01686 rval = MB->remove_child_meshset( sets[4], sets[7] ); 01687 if( MB_SUCCESS != rval ) return rval; 01688 rval = MB->remove_child_meshset( sets[5], sets[7] ); 01689 if( MB_SUCCESS != rval ) return rval; 01690 for( int i = 0; i < 5; ++i ) 01691 if( MB_SUCCESS != MB->num_child_meshsets( sets[i], &count ) || count ) return MB_FAILURE; 01692 01693 // setup tests of recursive parent query 01694 // 6 7 01695 // / \ / \ . 01696 // 3 4 5 01697 // \ / \ / 01698 // 1 2 01699 // \ / 01700 // 0 01701 rval = MB->add_parent_meshset( sets[0], sets[1] ); 01702 if( MB_SUCCESS != rval ) return rval; 01703 rval = MB->add_parent_meshset( sets[0], sets[2] ); 01704 if( MB_SUCCESS != rval ) return rval; 01705 rval = MB->add_parent_meshset( sets[1], sets[3] ); 01706 if( MB_SUCCESS != rval ) return rval; 01707 rval = MB->add_parent_meshset( sets[1], sets[4] ); 01708 if( MB_SUCCESS != rval ) return rval; 01709 rval = MB->add_parent_meshset( sets[2], sets[4] ); 01710 if( MB_SUCCESS != rval ) return rval; 01711 rval = MB->add_parent_meshset( sets[2], sets[5] ); 01712 if( MB_SUCCESS != rval ) return rval; 01713 rval = MB->add_parent_meshset( sets[3], sets[6] ); 01714 if( MB_SUCCESS != rval ) return rval; 01715 rval = MB->add_parent_meshset( sets[4], sets[6] ); 01716 if( MB_SUCCESS != rval ) return rval; 01717 rval = MB->add_parent_meshset( sets[4], sets[7] ); 01718 if( MB_SUCCESS != rval ) return rval; 01719 rval = MB->add_parent_meshset( sets[5], sets[7] ); 01720 if( MB_SUCCESS != rval ) return rval; 01721 01722 // test query at depth of 1 01723 list.clear(); 01724 rval = MB->get_parent_meshsets( sets[0], list, 1 ); 01725 if( MB_SUCCESS != rval ) return rval; 01726 if( list.size() != 2 || list[0] != sets[1] || list[1] != sets[2] ) return MB_FAILURE; 01727 rval = MB->num_parent_meshsets( sets[0], &count, 1 ); 01728 if( MB_SUCCESS != rval ) return rval; 01729 if( count != 2 ) return MB_FAILURE; 01730 01731 // test query at depth of 2 01732 list.clear(); 01733 rval = MB->get_parent_meshsets( sets[0], list, 2 ); 01734 if( MB_SUCCESS != rval ) return rval; 01735 if( !compare_lists( list, sets + 1, 5, false ) ) return MB_FAILURE; 01736 rval = MB->num_parent_meshsets( sets[0], &count, 2 ); 01737 if( MB_SUCCESS != rval ) return rval; 01738 if( count != 5 ) return MB_FAILURE; 01739 01740 // test query at depth of 3 01741 list.clear(); 01742 rval = MB->get_parent_meshsets( sets[0], list, 3 ); 01743 if( MB_SUCCESS != rval ) return rval; 01744 if( !compare_lists( list, sets + 1, 7, false ) ) return MB_FAILURE; 01745 rval = MB->num_parent_meshsets( sets[0], &count, 3 ); 01746 if( MB_SUCCESS != rval ) return rval; 01747 if( count != 7 ) return MB_FAILURE; 01748 01749 // test query at depth of 4 01750 list.clear(); 01751 rval = MB->get_parent_meshsets( sets[0], list, 4 ); 01752 if( MB_SUCCESS != rval ) return rval; 01753 if( !compare_lists( list, sets + 1, 7, false ) ) return MB_FAILURE; 01754 rval = MB->num_parent_meshsets( sets[0], &count, 4 ); 01755 if( MB_SUCCESS != rval ) return rval; 01756 if( count != 7 ) return MB_FAILURE; 01757 01758 // test query at all 01759 list.clear(); 01760 rval = MB->get_parent_meshsets( sets[0], list, 0 ); 01761 if( MB_SUCCESS != rval ) return rval; 01762 if( !compare_lists( list, sets + 1, 7, false ) ) return MB_FAILURE; 01763 rval = MB->num_parent_meshsets( sets[0], &count, 0 ); 01764 if( MB_SUCCESS != rval ) return rval; 01765 if( count != 7 ) return MB_FAILURE; 01766 01767 // clean up parent links 01768 rval = MB->remove_parent_meshset( sets[0], sets[1] ); 01769 if( MB_SUCCESS != rval ) return rval; 01770 rval = MB->remove_parent_meshset( sets[0], sets[2] ); 01771 if( MB_SUCCESS != rval ) return rval; 01772 rval = MB->remove_parent_meshset( sets[1], sets[3] ); 01773 if( MB_SUCCESS != rval ) return rval; 01774 rval = MB->remove_parent_meshset( sets[1], sets[4] ); 01775 if( MB_SUCCESS != rval ) return rval; 01776 rval = MB->remove_parent_meshset( sets[2], sets[4] ); 01777 if( MB_SUCCESS != rval ) return rval; 01778 rval = MB->remove_parent_meshset( sets[2], sets[5] ); 01779 if( MB_SUCCESS != rval ) return rval; 01780 rval = MB->remove_parent_meshset( sets[3], sets[6] ); 01781 if( MB_SUCCESS != rval ) return rval; 01782 rval = MB->remove_parent_meshset( sets[4], sets[6] ); 01783 if( MB_SUCCESS != rval ) return rval; 01784 rval = MB->remove_parent_meshset( sets[4], sets[7] ); 01785 if( MB_SUCCESS != rval ) return rval; 01786 rval = MB->remove_parent_meshset( sets[5], sets[7] ); 01787 if( MB_SUCCESS != rval ) return rval; 01788 for( int i = 0; i < 5; ++i ) 01789 if( MB_SUCCESS != MB->num_parent_meshsets( sets[i], &count ) || count ) return MB_FAILURE; 01790 01791 // test combined parent/child links 01792 01793 // test creation 01794 rval = MB->add_parent_child( sets[9], sets[8] ); 01795 if( MB_SUCCESS != rval ) return rval; 01796 list.clear(); 01797 rval = MB->get_child_meshsets( sets[9], list ); 01798 if( MB_SUCCESS != rval ) return rval; 01799 if( list.size() != 1 || list[0] != sets[8] ) return MB_FAILURE; 01800 list.clear(); 01801 rval = MB->get_parent_meshsets( sets[8], list ); 01802 if( MB_SUCCESS != rval ) return rval; 01803 if( list.size() != 1 || list[0] != sets[9] ) return MB_FAILURE; 01804 01805 // test deletion of parent/child 01806 rval = MB->add_parent_child( sets[7], sets[9] ); 01807 if( MB_SUCCESS != rval ) return rval; 01808 rval = MB->delete_entities( &sets[9], 1 ); 01809 if( MB_SUCCESS != rval ) return rval; 01810 list.clear(); 01811 rval = MB->get_parent_meshsets( sets[8], list ); 01812 if( !list.empty() ) return MB_FAILURE; 01813 list.clear(); 01814 rval = MB->get_child_meshsets( sets[7], list ); 01815 if( !list.empty() ) return MB_FAILURE; 01816 01817 // clean up remaining sets 01818 return MB->delete_entities( sets, 9 ); 01819 } 01820 01821 ErrorCode mb_mesh_sets_set_test() 01822 { 01823 return mb_mesh_sets_test( MESHSET_SET ); 01824 } 01825 01826 ErrorCode mb_mesh_sets_list_test() 01827 { 01828 return mb_mesh_sets_test( MESHSET_ORDERED ); 01829 } 01830 01831 // Verify that all query functions *append* to output Range 01832 ErrorCode mb_mesh_set_appends( int flags ) 01833 { 01834 Core moab; 01835 Interface* mb = &moab; 01836 ErrorCode rval = create_some_mesh( mb ); 01837 if( MB_SUCCESS != rval ) return rval; 01838 01839 // get all handles and subdivide into vertex and non-vertex ents 01840 Range all_ents, verts, elems, results; 01841 rval = mb->get_entities_by_handle( 0, all_ents ); 01842 if( MB_SUCCESS != rval ) return rval; 01843 Range::iterator ve = all_ents.upper_bound( MBVERTEX ); 01844 verts.merge( all_ents.begin(), ve ); 01845 elems.merge( ve, all_ents.end() ); 01846 01847 // If we're not testing queries from the root set, 01848 // create a set containing all the vertices 01849 EntityHandle set = 0; 01850 if( flags != -1 ) 01851 { 01852 rval = mb->create_meshset( flags, set ); 01853 if( MB_SUCCESS != rval ) return rval; 01854 rval = mb->add_entities( set, verts ); 01855 if( MB_SUCCESS != rval ) return rval; 01856 } 01857 01858 // Test get_entities_by_handle. This one doesn't make 01859 // much sense if we're testing the root set, but it doesn't 01860 // hurt to test it anyway. 01861 results = elems; 01862 rval = mb->get_entities_by_handle( set, results ); 01863 if( MB_SUCCESS != rval ) return rval; 01864 if( results != all_ents ) return MB_FAILURE; 01865 01866 // Test get_entities_by_dimension 01867 results = elems; 01868 rval = mb->get_entities_by_dimension( set, 0, results ); 01869 if( MB_SUCCESS != rval ) return rval; 01870 if( results != all_ents ) return MB_FAILURE; 01871 01872 // Test get_entities_by_type 01873 results = elems; 01874 rval = mb->get_entities_by_type( set, MBVERTEX, results ); 01875 if( MB_SUCCESS != rval ) return rval; 01876 if( results != all_ents ) return MB_FAILURE; 01877 01878 // choose a single entity for testing tag queries 01879 EntityHandle entity = verts.front(); 01880 Range expected( elems ); 01881 expected.insert( entity ); 01882 01883 Tag sparse, dense; 01884 const int zero = 0, one = 1; 01885 const void* vals[] = { &one }; 01886 01887 // Test get_entities_by_type_and_tag w/ sparse tag and no value 01888 rval = mb->tag_get_handle( "mb_mesh_set_appends_sparse", 1, MB_TYPE_INTEGER, sparse, MB_TAG_SPARSE | MB_TAG_EXCL ); 01889 if( MB_SUCCESS != rval ) return rval; 01890 rval = mb->tag_set_data( sparse, &entity, 1, &one ); 01891 if( MB_SUCCESS != rval ) return rval; 01892 results = elems; 01893 rval = 01894 mb->get_entities_by_type_and_tag( set, TYPE_FROM_HANDLE( entity ), &sparse, 0, 1, results, Interface::UNION ); 01895 if( MB_SUCCESS != rval ) return rval; 01896 if( results != expected ) return MB_FAILURE; 01897 // Test again, but specify tag value 01898 results = elems; 01899 rval = mb->get_entities_by_type_and_tag( set, TYPE_FROM_HANDLE( entity ), &sparse, vals, 1, results, 01900 Interface::UNION ); 01901 if( MB_SUCCESS != rval ) return rval; 01902 if( results != expected ) return MB_FAILURE; 01903 01904 // Test get_entities_by_type_and_tag w/ dense tag 01905 rval = 01906 mb->tag_get_handle( "mb_mesh_set_appends_dense", 1, MB_TYPE_INTEGER, dense, MB_TAG_DENSE | MB_TAG_EXCL, &zero ); 01907 if( MB_SUCCESS != rval ) return rval; 01908 rval = mb->tag_set_data( dense, &entity, 1, &one ); 01909 if( MB_SUCCESS != rval ) return rval; 01910 results = elems; 01911 rval = 01912 mb->get_entities_by_type_and_tag( set, TYPE_FROM_HANDLE( entity ), &dense, vals, 1, results, Interface::UNION ); 01913 if( MB_SUCCESS != rval ) return rval; 01914 if( results != expected ) return MB_FAILURE; 01915 01916 return MB_SUCCESS; 01917 } 01918 01919 ErrorCode mb_mesh_set_set_appends() 01920 { 01921 return mb_mesh_set_appends( MESHSET_SET ); 01922 } 01923 01924 ErrorCode mb_mesh_set_list_appends() 01925 { 01926 return mb_mesh_set_appends( MESHSET_ORDERED ); 01927 } 01928 01929 ErrorCode mb_mesh_set_root_appends() 01930 { 01931 return mb_mesh_set_appends( -1 ); 01932 } 01933 01934 ErrorCode mb_mesh_set_set_replace_test() 01935 { 01936 Core moab; 01937 Interface* mb = &moab; 01938 ErrorCode rval; 01939 Range r; 01940 // create 10 vertices to put in set 01941 std::vector< double > coords( 30 ); 01942 rval = mb->create_vertices( &coords[0], 10, r );MB_CHK_ERR( rval ); 01943 std::vector< EntityHandle > verts( r.size() ); 01944 std::copy( r.begin(), r.end(), verts.begin() ); 01945 r.clear(); 01946 // create a set 01947 EntityHandle set; 01948 rval = mb->create_meshset( MESHSET_SET, set );MB_CHK_ERR( rval ); 01949 // put every other vertex in set 01950 for( size_t i = 0; i < 10; i += 2 ) 01951 r.insert( verts[i] ); 01952 rval = mb->add_entities( set, r );MB_CHK_ERR( rval ); 01953 r.clear(); 01954 // swap 3 of the vertices 01955 EntityHandle old_ents[3] = { verts[2], verts[4], verts[6] }; 01956 EntityHandle new_ents[3] = { verts[1], verts[9], verts[5] }; 01957 rval = mb->replace_entities( set, old_ents, new_ents, 3 );MB_CHK_ERR( rval ); 01958 // check new set contents 01959 rval = mb->get_entities_by_handle( set, r );MB_CHK_ERR( rval ); 01960 Range r2; 01961 r2.insert( verts[0] ); 01962 r2.insert( verts[1] ); 01963 r2.insert( verts[9] ); 01964 r2.insert( verts[5] ); 01965 r2.insert( verts[8] ); 01966 if( r != r2 ) 01967 { 01968 std::cerr << "Range does not contain expected values." << std::endl 01969 << " Expected: " << r2 << std::endl 01970 << " Actual : " << r << std::endl; 01971 return MB_FAILURE; 01972 } 01973 01974 return MB_SUCCESS; 01975 } 01976 01977 ErrorCode mb_mesh_set_list_replace_test() 01978 { 01979 Core moab; 01980 Interface* mb = &moab; 01981 ErrorCode rval; 01982 // create 10 vertices to put in set 01983 Range r; 01984 std::vector< double > coords( 30 ); 01985 rval = mb->create_vertices( &coords[0], 10, r );MB_CHK_ERR( rval ); 01986 std::vector< EntityHandle > verts( r.size() ); 01987 std::copy( r.begin(), r.end(), verts.begin() ); 01988 r.clear(); 01989 // create a set 01990 EntityHandle set; 01991 rval = mb->create_meshset( MESHSET_ORDERED, set );MB_CHK_ERR( rval ); 01992 // put all vertices in set, but add the first one a second time 01993 std::vector< EntityHandle > list( verts ); 01994 list.push_back( verts.front() ); 01995 rval = mb->add_entities( set, &list[0], list.size() );MB_CHK_ERR( rval ); 01996 // swap 3 of the vertices 01997 EntityHandle old_ents[3] = { verts[2], verts[4], verts[6] }; 01998 EntityHandle new_ents[3] = { verts[1], verts[9], verts[5] }; 01999 rval = mb->replace_entities( set, old_ents, new_ents, 3 );MB_CHK_ERR( rval ); 02000 // check new set contents 02001 std::vector< EntityHandle > list2; 02002 rval = mb->get_entities_by_handle( set, list2 );MB_CHK_ERR( rval ); 02003 list[2] = verts[1]; 02004 list[4] = verts[9]; 02005 list[6] = verts[5]; 02006 if( list != list2 ) 02007 { 02008 std::cerr << "Range does not contain expected values." << std::endl; 02009 std::cerr << " Expected: "; 02010 std::copy( list.begin(), list.end(), std::ostream_iterator< EntityHandle >( std::cerr, " " ) ); 02011 std::cerr << std::endl << " Actual : "; 02012 std::copy( list2.begin(), list2.end(), std::ostream_iterator< EntityHandle >( std::cerr, " " ) ); 02013 std::cerr << std::endl; 02014 return MB_FAILURE; 02015 } 02016 // now try replacing a repeated value 02017 rval = mb->replace_entities( set, &verts[0], &verts[3], 1 );MB_CHK_ERR( rval ); 02018 list[0] = list[10] = verts[3]; 02019 list2.clear(); 02020 rval = mb->get_entities_by_handle( set, list2 );MB_CHK_ERR( rval ); 02021 if( list != list2 ) 02022 { 02023 std::cerr << "Range does not contain expected values." << std::endl; 02024 std::cerr << " Expected: "; 02025 std::copy( list.begin(), list.end(), std::ostream_iterator< EntityHandle >( std::cerr, " " ) ); 02026 std::cerr << std::endl << " Actual : "; 02027 std::copy( list2.begin(), list2.end(), std::ostream_iterator< EntityHandle >( std::cerr, " " ) ); 02028 std::cerr << std::endl; 02029 return MB_FAILURE; 02030 } 02031 02032 return MB_SUCCESS; 02033 } 02034 02035 /* Test the following changes to a meshset: 02036 set MB-> tracking 02037 tracking MB-> set 02038 unordered MB-> ordered 02039 ordered MB-> unordered 02040 */ 02041 ErrorCode mb_mesh_set_flag_test() 02042 { 02043 Core moab; 02044 Interface* mb = &moab; 02045 02046 ErrorCode rval; 02047 // create 10 vertices to put in set 02048 Range verts; 02049 std::vector< double > coords( 30 ); 02050 rval = mb->create_vertices( &coords[0], 10, verts );MB_CHK_ERR( rval ); 02051 02052 // CHECK SET->TRACKING 02053 // create a set and add the verts 02054 EntityHandle set; 02055 rval = mb->create_meshset( MESHSET_SET, set );MB_CHK_ERR( rval ); 02056 rval = mb->add_entities( set, verts );MB_CHK_ERR( rval ); 02057 // the verts should not be tracking adjacencies 02058 Range adj_sets; 02059 rval = mb->get_adjacencies( verts, 4, false, adj_sets );MB_CHK_ERR( rval ); 02060 if( !adj_sets.empty() ) 02061 { 02062 std::cerr << "range should be empty but contains:" << std::endl; 02063 rval = mb->list_entities( adj_sets ); 02064 return MB_FAILURE; 02065 } 02066 // check to make sure the flags on MESHSET_SET 02067 unsigned int flags; 02068 rval = mb->get_meshset_options( set, flags );MB_CHK_ERR( rval ); 02069 if( !( MESHSET_SET & flags ) || ( MESHSET_TRACK_OWNER & flags ) || ( MESHSET_ORDERED & flags ) ) 02070 { 02071 std::cerr << "set should be MESHSET_SET only, flags=" << flags << std::endl; 02072 return MB_FAILURE; 02073 } 02074 // change to a tracking set and check flags 02075 rval = mb->set_meshset_options( set, MESHSET_TRACK_OWNER );MB_CHK_ERR( rval ); 02076 rval = mb->get_meshset_options( set, flags );MB_CHK_ERR( rval ); 02077 if( ( MESHSET_SET & flags ) || !( MESHSET_TRACK_OWNER & flags ) || ( MESHSET_ORDERED & flags ) ) 02078 { 02079 std::cerr << "set should be MESHSET_TRACK_OWNER only, flags=" << flags << std::endl; 02080 return MB_FAILURE; 02081 } 02082 // check adjacencies 02083 rval = mb->get_adjacencies( verts, 4, false, adj_sets );MB_CHK_ERR( rval ); 02084 if( 1 != adj_sets.size() ) 02085 { 02086 std::cerr << "range should contain a set, adj_sets.size()=" << adj_sets.size() << std::endl; 02087 rval = mb->list_entities( adj_sets ); 02088 return MB_FAILURE; 02089 } 02090 02091 // CHECK TRACKING->SET 02092 // change to a standard set and check flags 02093 rval = mb->set_meshset_options( set, MESHSET_SET );MB_CHK_ERR( rval ); 02094 rval = mb->get_meshset_options( set, flags );MB_CHK_ERR( rval ); 02095 if( !( MESHSET_SET & flags ) || ( MESHSET_TRACK_OWNER & flags ) || ( MESHSET_ORDERED & flags ) ) 02096 { 02097 std::cerr << "set should be MESHSET_SET only, flags=" << flags << std::endl; 02098 return MB_FAILURE; 02099 } 02100 // the set should no longer be adjacent to the vertices 02101 adj_sets.clear(); 02102 rval = mb->get_adjacencies( verts, 4, false, adj_sets );MB_CHK_ERR( rval ); 02103 if( !adj_sets.empty() ) 02104 { 02105 std::cerr << "range should be empty but contains:" << std::endl; 02106 rval = mb->list_entities( adj_sets ); 02107 return MB_FAILURE; 02108 } 02109 // CHECK UNORDERED->ORDERED 02110 // add a duplicate vert 02111 rval = mb->add_entities( set, &verts.front(), 1 );MB_CHK_ERR( rval ); 02112 // unordered sets cannot hold duplicates so size shouldn't change 02113 std::vector< EntityHandle > entities; 02114 rval = mb->get_entities_by_handle( set, entities ); 02115 if( 10 != entities.size() ) 02116 { 02117 std::cerr << "set should not hold duplicate entities" << std::endl; 02118 return MB_FAILURE; 02119 } 02120 // change to an ordered set and check flags 02121 rval = mb->set_meshset_options( set, MESHSET_ORDERED );MB_CHK_ERR( rval ); 02122 rval = mb->get_meshset_options( set, flags );MB_CHK_ERR( rval ); 02123 if( ( MESHSET_SET & flags ) || ( MESHSET_TRACK_OWNER & flags ) || !( MESHSET_ORDERED & flags ) ) 02124 { 02125 std::cerr << "set should be MESHSET_ORDERED only, flags=" << flags << std::endl; 02126 return MB_FAILURE; 02127 } 02128 // swap the order with some entities to that the handles aren't ordered 02129 rval = mb->clear_meshset( &set, 1 );MB_CHK_ERR( rval ); 02130 entities.clear(); 02131 entities.resize( 2 ); 02132 entities[0] = verts[1]; 02133 entities[1] = verts[0]; 02134 rval = mb->add_entities( set, &entities[0], 2 );MB_CHK_ERR( rval ); 02135 // check to ensure the entities keep their order 02136 entities.clear(); 02137 rval = mb->get_entities_by_handle( set, entities ); 02138 if( verts[0] != entities[1] || verts[1] != entities[0] ) 02139 { 02140 std::cerr << "ordered set did not keep its order" << std::endl; 02141 return MB_FAILURE; 02142 } 02143 02144 // CHECK ORDERED->UNORDERED 02145 // change to an unordered set and check flags 02146 rval = mb->set_meshset_options( set, MESHSET_SET );MB_CHK_ERR( rval ); 02147 rval = mb->get_meshset_options( set, flags );MB_CHK_ERR( rval ); 02148 if( !( MESHSET_SET & flags ) || ( MESHSET_TRACK_OWNER & flags ) || MESHSET_ORDERED & flags ) 02149 { 02150 std::cerr << "set should be MESHSET_SET only, flags=" << flags << std::endl; 02151 return MB_FAILURE; 02152 } 02153 // the entities in the set should now be ordered by handle 02154 entities.clear(); 02155 rval = mb->get_entities_by_handle( set, entities ); 02156 if( verts[0] != entities[0] || verts[1] != entities[1] ) 02157 { 02158 std::cerr << "unordered set is still ordered" << std::endl; 02159 return MB_FAILURE; 02160 } 02161 return MB_SUCCESS; 02162 } 02163 02164 #ifdef MOAB_HAVE_NETCDF 02165 // number of entities of type MBVERTEX, MBEDGE, MBDTri, MBQUAD, MBTET, and MBHEX 02166 // in mbtest1.g (all other values are 0. 02167 static const EntityType types[] = { MBVERTEX, MBEDGE, MBTRI, MBQUAD, MBTET, MBHEX }; 02168 const int num_types = sizeof( types ) / sizeof( types[0] ); 02169 static const unsigned int num_entities[num_types + 1] = { 47, 12, 18, 8, 22, 8, 0 }; 02170 02171 ErrorCode mb_delete_mesh_test() 02172 { 02173 Core moab; 02174 Interface* gMB = &moab; 02175 ErrorCode error = load_file_one( gMB ); 02176 if( MB_SUCCESS != error ) return error; 02177 02178 // Lets also test the global MB pointer (gMB) here. 02179 error = gMB->delete_mesh(); 02180 if( error != MB_SUCCESS ) return error; 02181 02182 // load the mesh again 02183 error = load_file_one( gMB ); 02184 if( error != MB_SUCCESS ) return error; 02185 02186 // step through each element type 02187 for( EntityType type = MBVERTEX; type != MBENTITYSET; type++ ) 02188 { 02189 // There should be entities 02190 Range entities; 02191 error = gMB->get_entities_by_type( 0, type, entities ); 02192 if( error != MB_SUCCESS ) return error; 02193 02194 size_t idx = std::find( types, types + num_types, type ) - types; 02195 if( entities.size() != num_entities[idx] ) return MB_FAILURE; 02196 } 02197 02198 return MB_SUCCESS; 02199 } 02200 02201 ErrorCode mb_mesh_set_tracking_test() 02202 { 02203 Core moab; 02204 Interface* MB = &moab; 02205 02206 // read in a file so you have some data in the database 02207 02208 ErrorCode error = load_file_one( MB ); 02209 if( error != MB_SUCCESS ) return error; 02210 02211 EntityHandle ms1, ms2, ms3; 02212 02213 // create meshsets 02214 ErrorCode result = MB->create_meshset( MESHSET_TRACK_OWNER | MESHSET_ORDERED, ms1 ); 02215 if( result != MB_SUCCESS ) return result; 02216 result = MB->create_meshset( MESHSET_SET | MESHSET_TRACK_OWNER, ms2 ); 02217 if( result != MB_SUCCESS ) return result; 02218 result = MB->create_meshset( MESHSET_SET | MESHSET_TRACK_OWNER, ms3 ); 02219 if( result != MB_SUCCESS ) return result; 02220 02221 // get all hexes 02222 Range hexes; 02223 result = MB->get_entities_by_type( 0, MBHEX, hexes ); 02224 if( result != MB_SUCCESS ) return result; 02225 02226 // get all tris 02227 Range tris; 02228 result = MB->get_entities_by_type( 0, MBTRI, tris ); 02229 if( result != MB_SUCCESS ) return result; 02230 02231 // get all tets 02232 Range temp_range; 02233 result = MB->get_entities_by_type( 0, MBTET, temp_range ); 02234 if( result != MB_SUCCESS ) return result; 02235 02236 // copy all the tets from the range into a vector 'tets' 02237 std::vector< EntityHandle > tets( temp_range.size() ); 02238 std::copy( temp_range.begin(), temp_range.end(), tets.begin() ); 02239 02240 // Quick check on 'get_entities_by_dimension()' 02241 Range dim_3_range; 02242 result = MB->get_entities_by_dimension( 0, 3, dim_3_range ); 02243 if( result != MB_SUCCESS ) return result; 02244 02245 // hexes and tets should be only dimension 3 entities 02246 if( hexes.size() + tets.size() != dim_3_range.size() ) return MB_FAILURE; 02247 02248 // put all hexes in ms1, ms2, ms3 02249 result = MB->add_entities( ms1, hexes ); // add ents in a range 02250 if( result != MB_SUCCESS ) return result; 02251 // to ordered meshset 02252 02253 result = MB->add_entities( ms2, hexes ); // add ents in a range 02254 if( result != MB_SUCCESS ) return result; 02255 // to unordered meshset 02256 02257 result = MB->add_entities( ms3, hexes ); 02258 if( result != MB_SUCCESS ) return result; 02259 02260 // put all tets in ms1, ms2 02261 if( MB->add_entities( ms1, &tets[0], tets.size() ) != MB_SUCCESS ) // add ents in a vector 02262 return MB_FAILURE; // to ordered meshset 02263 02264 if( MB->add_entities( ms2, &tets[0], tets.size() ) != MB_SUCCESS ) // add ents in a vector 02265 return MB_FAILURE; // to unordered meshset 02266 02267 // put all tris in ms1 02268 result = MB->add_entities( ms1, tris ); 02269 if( result != MB_SUCCESS ) return result; 02270 02271 Range::iterator iter; 02272 iter = tris.begin(); 02273 02274 std::vector< EntityHandle > temp_vec; 02275 02276 // ask a tri which meshsets it is in 02277 result = MB->get_adjacencies( &( *iter ), 1, 4, false, temp_vec ); 02278 if( result != MB_SUCCESS ) return result; 02279 02280 // cout<<"tris temp_vec.size() = "<<temp_vec.size()<<endl; 02281 if( temp_vec.size() != 2 ) return MB_FAILURE; 02282 02283 // ask a tet which meshsets it is in 02284 temp_vec.clear(); 02285 std::vector< EntityHandle >::iterator vec_iter = tets.begin(); 02286 result = MB->get_adjacencies( &( *vec_iter ), 1, 4, false, temp_vec ); 02287 if( result != MB_SUCCESS ) return result; 02288 02289 // cout<<"tet temp_vec.size() = "<<temp_vec.size()<<endl; 02290 if( temp_vec.size() != 3 ) return MB_FAILURE; 02291 02292 // ask a hex which meshsets it is in 02293 temp_vec.clear(); 02294 iter = hexes.begin(); 02295 result = MB->get_adjacencies( &( *iter ), 1, 4, false, temp_vec ); 02296 if( result != MB_SUCCESS ) return result; 02297 02298 // should be in 4 temp_vec 02299 if( temp_vec.size() != 4 ) return MB_FAILURE; 02300 02301 // take this hex out of the ms1, ms2, ms3 02302 if( MB->remove_entities( ms1, &( *iter ), 1 ) != MB_SUCCESS ) // remove ents in a vector 02303 return MB_FAILURE; // from ordered meshset 02304 02305 if( MB->remove_entities( ms2, &( *iter ), 1 ) != MB_SUCCESS ) // remove ents in a vector 02306 return MB_FAILURE; // from unordered meshset 02307 02308 temp_range.clear(); 02309 temp_range.insert( *iter ); 02310 if( MB->remove_entities( ms3, temp_range ) != MB_SUCCESS ) // remove ents in a range 02311 return MB_FAILURE; // from unordered meshset 02312 02313 // ask the hex how many meshsets it is in 02314 temp_vec.clear(); 02315 result = MB->get_adjacencies( &( *iter ), 1, 4, false, temp_vec ); 02316 if( result != MB_SUCCESS ) return result; 02317 if( temp_vec.size() != 1 ) return MB_FAILURE; 02318 02319 // add the hex back into ms1 02320 result = MB->add_entities( ms1, temp_range ); 02321 if( result != MB_SUCCESS ) return result; 02322 02323 // ask the hex how many meshsets it is in 02324 temp_vec.clear(); 02325 result = MB->get_adjacencies( &( *iter ), 1, 4, false, temp_vec ); 02326 if( result != MB_SUCCESS ) return result; 02327 if( temp_vec.size() != 2 ) return MB_FAILURE; 02328 02329 temp_range.clear(); 02330 temp_range.insert( *iter ); 02331 if( MB->remove_entities( ms1, temp_range ) != MB_SUCCESS ) // remove ents in a range 02332 return MB_FAILURE; // from an ordered meshset 02333 02334 // ask the hex how many meshsets it is in 02335 temp_vec.clear(); 02336 result = MB->get_adjacencies( &( *iter ), 1, 4, false, temp_vec ); 02337 if( result != MB_SUCCESS ) return result; 02338 if( temp_vec.size() != 1 ) return MB_FAILURE; 02339 02340 // Deleting a meshset 02341 02342 iter = tris.begin(); 02343 temp_vec.clear(); 02344 // ask a tri which meshsets it is in 02345 result = MB->get_adjacencies( &( *iter ), 1, 4, false, temp_vec ); 02346 if( result != MB_SUCCESS ) return result; 02347 02348 if( temp_vec.size() != 2 ) return MB_FAILURE; 02349 02350 // Try deleting a meshset 02351 result = MB->delete_entities( &ms1, 1 ); 02352 if( result != MB_SUCCESS ) return result; 02353 02354 temp_vec.clear(); 02355 // Query tri again for meshsets it's in 02356 result = MB->get_adjacencies( &( *iter ), 1, 4, false, temp_vec ); 02357 if( result != MB_SUCCESS ) return result; 02358 02359 if( temp_vec.size() != 1 ) return MB_FAILURE; 02360 02361 // Delete an entitiy from ms2....make sure it's removed out of ms2 02362 int num_before = 0; 02363 MB->get_number_entities_by_handle( ms2, num_before ); 02364 vec_iter = tets.begin(); 02365 result = MB->delete_entities( &( *vec_iter ), 1 ); 02366 if( result != MB_SUCCESS ) return result; 02367 02368 int num_after = 0; 02369 MB->get_number_entities_by_handle( ms2, num_after ); 02370 if( num_before != num_after + 1 ) return MB_FAILURE; 02371 02372 return MB_SUCCESS; 02373 } 02374 #endif 02375 02376 // Compare internal representation of contents for a list (MESHSET_ORDERED) 02377 // set to expected contents. Assumes expected contents are correctly 02378 // ordered. 02379 static ErrorCode check_list_meshset_internal( const EntityHandle* expected, 02380 int num_expected, 02381 const EntityHandle* contents, 02382 int length ) 02383 { 02384 bool okay = true; 02385 for( int i = 0; i < std::min( num_expected, length ); ++i ) 02386 { 02387 if( expected[i] != contents[i] ) 02388 { 02389 std::cerr << "List set contents differ at index " << i << ": expected " << expected[i] << " but got " 02390 << contents[i] << std::endl; 02391 okay = false; 02392 } 02393 } 02394 if( num_expected > length ) 02395 { 02396 std::cerr << "List set is missing " << num_expected - length << "handles" << std::endl; 02397 okay = false; 02398 } 02399 else if( length > num_expected ) 02400 { 02401 std::cerr << "List set has " << num_expected - length << " extra handles" << std::endl; 02402 okay = false; 02403 } 02404 02405 if( okay ) return MB_SUCCESS; 02406 02407 std::cerr << "Expected contents: "; 02408 if( !num_expected ) 02409 std::cerr << "(empty)"; 02410 else 02411 std::cerr << expected[0]; 02412 for( int i = 1; i < num_expected; ++i ) 02413 std::cerr << ", " << expected[i]; 02414 std::cerr << std::endl; 02415 02416 std::cerr << "Actual contents: "; 02417 if( !length ) 02418 std::cerr << "(empty)"; 02419 else 02420 std::cerr << contents[0]; 02421 for( int i = 1; i < length; ++i ) 02422 std::cerr << ", " << contents[i]; 02423 std::cerr << std::endl; 02424 02425 return MB_FAILURE; 02426 } 02427 02428 // Compare internal representation of contents for a ranged (MESHSET_SET) 02429 // set to expected contents. Assumes expected contents are correctly 02430 // ordered. 02431 static ErrorCode check_ranged_meshset_internal( const EntityHandle* expected, 02432 int num_expected, 02433 const EntityHandle* contents, 02434 int length ) 02435 { 02436 if( length % 2 ) 02437 { 02438 std::cerr << "Range set is corrupt. Odd number of handles in content list" << std::endl; 02439 std::cerr << "Actual contents: " << contents[0]; 02440 for( int i = 1; i < length; ++i ) 02441 std::cerr << ", " << contents[i]; 02442 std::cerr << std::endl; 02443 return MB_FAILURE; 02444 } 02445 bool okay = true; 02446 // check that all range pairs are valid (first handle less than or 02447 // equal to second) 02448 for( int i = 0; i < length; i += 2 ) 02449 { 02450 if( contents[i] > contents[i + 1] ) 02451 { 02452 std::cerr << "Range set has invalid range pair at index " << i << ": [" << contents[i] << ',' 02453 << contents[i + 1] << ']' << std::endl; 02454 okay = false; 02455 } 02456 } 02457 // check that all range pairs are sorted and non-overlapping 02458 // (start of a range must be greater than end of previous range) 02459 for( int i = 2; i < length; i += 2 ) 02460 { 02461 if( contents[i] < contents[i - 1] ) 02462 { 02463 std::cerr << "Range set has incorrectly ordered ranges at index " << i << ": [...," << contents[i - 1] 02464 << "], [" << contents[i] << ",...]" << std::endl; 02465 okay = false; 02466 } 02467 if( contents[i] == contents[i - 1] + 1 ) 02468 { 02469 std::cerr << "Range set has pairs that should have been merged at index " << i << ": [...," 02470 << contents[i - 1] << "], [" << contents[i] << ",...]" << std::endl; 02471 okay = false; 02472 } 02473 } 02474 if( !okay ) 02475 { 02476 std::cerr << "Actual contents: "; 02477 if( !length ) 02478 std::cerr << "(empty)"; 02479 else 02480 std::cerr << '[' << contents[0] << ',' << contents[1] << ']'; 02481 for( int i = 2; i < length; i += 2 ) 02482 std::cerr << ", [" << contents[i] << ',' << contents[i + 1] << ']'; 02483 std::cerr << std::endl; 02484 return MB_FAILURE; 02485 } 02486 02487 int j = 0; 02488 for( int i = 0; i < length; i += 2 ) 02489 { 02490 for( ; j < num_expected && expected[j] < contents[i]; ++j ) 02491 { 02492 std::cerr << "Range set missing expected handle: " << expected[j] << std::endl; 02493 okay = false; 02494 } 02495 int k = j; 02496 while( k < num_expected && expected[k] <= contents[i + 1] ) 02497 ++k; 02498 if( (EntityHandle)( k - j ) <= ( contents[i + 1] - contents[i] ) ) 02499 { 02500 std::cerr << "Handle range [" << contents[i] << ',' << contents[i + 1] 02501 << "] contains unexpected handles. Expected handles: "; 02502 if( k == j ) 02503 std::cerr << "(none)" << std::endl; 02504 else 02505 { 02506 std::cerr << expected[j]; 02507 for( ++j; j < k; ++j ) 02508 std::cerr << ", " << expected[j]; 02509 std::cerr << std::endl; 02510 } 02511 okay = false; 02512 } 02513 j = k; 02514 } 02515 02516 if( okay ) return MB_SUCCESS; 02517 02518 std::cerr << "Expected contents: "; 02519 if( !num_expected ) 02520 std::cerr << "(empty)"; 02521 else 02522 std::cerr << expected[0]; 02523 for( int i = 1; i < num_expected; ++i ) 02524 std::cerr << ", " << expected[i]; 02525 std::cerr << std::endl; 02526 02527 std::cerr << "Actual contents: "; 02528 if( !length ) 02529 std::cerr << "(empty)"; 02530 else 02531 std::cerr << '[' << contents[0] << ',' << contents[1] << ']'; 02532 for( int i = 2; i < length; i += 2 ) 02533 std::cerr << ", [" << contents[i] << ',' << contents[i + 1] << ']'; 02534 std::cerr << std::endl; 02535 02536 return MB_FAILURE; 02537 } 02538 02539 // Check the internal representation of a meshset 02540 // to verify that it is correct. 02541 static ErrorCode check_meshset_internal( Interface& mb, 02542 EntityHandle set, 02543 const EntityHandle* expected, 02544 int num_expected ) 02545 { 02546 ErrorCode rval; 02547 WriteUtilIface* tool = 0; 02548 rval = mb.query_interface( tool );MB_CHK_ERR( rval ); 02549 02550 const EntityHandle* contents; 02551 int length; 02552 unsigned char flags; 02553 rval = tool->get_entity_list_pointers( &set, 1, &contents, WriteUtilIface::CONTENTS, &length, &flags );MB_CHK_ERR( rval ); 02554 ErrorCode rval1 = mb.release_interface( tool );MB_CHK_ERR( rval1 ); 02555 02556 if( flags & MESHSET_ORDERED ) 02557 rval = check_list_meshset_internal( expected, num_expected, contents, length ); 02558 else 02559 rval = check_ranged_meshset_internal( expected, num_expected, contents, length );MB_CHK_ERR( rval ); 02560 return MB_SUCCESS; 02561 } 02562 02563 ErrorCode mb_mesh_set_set_add_remove_test() 02564 { 02565 Core core; 02566 Interface& mb = core; 02567 EntityHandle set; 02568 ErrorCode rval = mb.create_meshset( MESHSET_SET, set );MB_CHK_ERR( rval ); 02569 02570 EntityHandle list1[] = { 10, 16, 18, 20, 24, 27 }; 02571 size_t len1 = sizeof( list1 ) / sizeof( list1[0] ); 02572 EntityHandle list2[] = { 10, 16, 17, 18, 19, 20, 24, 27 }; 02573 size_t len2 = sizeof( list2 ) / sizeof( list2[0] ); 02574 rval = mb.add_entities( set, list1, len1 );MB_CHK_ERR( rval ); 02575 rval = check_meshset_internal( mb, set, list1, len1 );MB_CHK_ERR( rval ); 02576 rval = mb.add_entities( set, list2, len2 );MB_CHK_ERR( rval ); 02577 EntityHandle exp12[] = { 10, 16, 17, 18, 19, 20, 24, 27 }; 02578 size_t len12 = sizeof( exp12 ) / sizeof( exp12[0] ); 02579 rval = check_meshset_internal( mb, set, exp12, len12 );MB_CHK_ERR( rval ); 02580 02581 EntityHandle list3[] = { 15, 16, 18, 20, 21, 24, 28 }; 02582 size_t len3 = sizeof( list3 ) / sizeof( list3[0] ); 02583 rval = mb.remove_entities( set, list3, len3 );MB_CHK_ERR( rval ); 02584 EntityHandle exp123[] = { 10, 17, 19, 27 }; 02585 size_t len123 = sizeof( exp123 ) / sizeof( exp123[0] ); 02586 rval = check_meshset_internal( mb, set, exp123, len123 );MB_CHK_ERR( rval ); 02587 02588 EntityHandle list4[] = { 18, 10, 11, 12, 13, 14, 15, 16 }; 02589 size_t len4 = sizeof( list4 ) / sizeof( list4[0] ); 02590 rval = mb.add_entities( set, list4, len4 );MB_CHK_ERR( rval ); 02591 EntityHandle exp14[] = { 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 27 }; 02592 size_t len14 = sizeof( exp14 ) / sizeof( exp14[0] ); 02593 rval = check_meshset_internal( mb, set, exp14, len14 );MB_CHK_ERR( rval ); 02594 02595 EntityHandle list5[] = { 9, 10, 12, 13, 14, 15, 19, 20 }; 02596 rval = mb.remove_entities( set, list5, sizeof( list5 ) / sizeof( list5[0] ) );MB_CHK_ERR( rval ); 02597 EntityHandle exp5[] = { 11, 16, 17, 18, 27 }; 02598 rval = check_meshset_internal( mb, set, exp5, sizeof( exp5 ) / sizeof( exp5[0] ) );MB_CHK_ERR( rval ); 02599 02600 EntityHandle list6[] = { 9, 10, 15, 16, 18, 19, 28 }; 02601 rval = mb.add_entities( set, list6, sizeof( list6 ) / sizeof( list6[0] ) );MB_CHK_ERR( rval ); 02602 EntityHandle exp6[] = { 9, 10, 11, 15, 16, 17, 18, 19, 27, 28 }; 02603 rval = check_meshset_internal( mb, set, exp6, sizeof( exp6 ) / sizeof( exp6[0] ) );MB_CHK_ERR( rval ); 02604 02605 EntityHandle list7[] = { 13, 19, 27, 28 }; 02606 rval = mb.add_entities( set, list7, sizeof( list7 ) / sizeof( list7[0] ) );MB_CHK_ERR( rval ); 02607 EntityHandle exp7[] = { 9, 10, 11, 13, 15, 16, 17, 18, 19, 27, 28 }; 02608 rval = check_meshset_internal( mb, set, exp7, sizeof( exp7 ) / sizeof( exp7[0] ) );MB_CHK_ERR( rval ); 02609 02610 EntityHandle list8[] = { 12, 14, 33 }; 02611 rval = mb.add_entities( set, list8, sizeof( list8 ) / sizeof( list8[0] ) );MB_CHK_ERR( rval ); 02612 EntityHandle exp8[] = { 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 27, 28, 33 }; 02613 rval = check_meshset_internal( mb, set, exp8, sizeof( exp8 ) / sizeof( exp8[0] ) );MB_CHK_ERR( rval ); 02614 02615 EntityHandle list9[] = { 29, 30, 31, 32, 34 }; 02616 rval = mb.remove_entities( set, list9, sizeof( list9 ) / sizeof( list9[0] ) );MB_CHK_ERR( rval ); 02617 rval = check_meshset_internal( mb, set, exp8, sizeof( exp8 ) / sizeof( exp8[0] ) );MB_CHK_ERR( rval ); 02618 02619 EntityHandle list10[] = { 9, 11, 13, 17, 18, 19, 28, 33, 100 }; 02620 rval = mb.remove_entities( set, list10, sizeof( list10 ) / sizeof( list10[0] ) );MB_CHK_ERR( rval ); 02621 EntityHandle exp10[] = { 10, 12, 14, 15, 16, 27 }; 02622 rval = check_meshset_internal( mb, set, exp10, sizeof( exp10 ) / sizeof( exp10[0] ) );MB_CHK_ERR( rval ); 02623 02624 EntityHandle list11[] = { 11, 12, 13, 14, 27, 28 }; 02625 rval = mb.remove_entities( set, list11, sizeof( list11 ) / sizeof( list11[0] ) );MB_CHK_ERR( rval ); 02626 EntityHandle exp11[] = { 10, 15, 16 }; 02627 rval = check_meshset_internal( mb, set, exp11, sizeof( exp11 ) / sizeof( exp11[0] ) );MB_CHK_ERR( rval ); 02628 02629 EntityHandle list12[] = { 1, 10, 15, 16 }; 02630 rval = mb.remove_entities( set, list12, sizeof( list12 ) / sizeof( list12[0] ) );MB_CHK_ERR( rval ); 02631 rval = check_meshset_internal( mb, set, 0, 0 );MB_CHK_ERR( rval ); 02632 02633 return MB_SUCCESS; 02634 } 02635 02636 ErrorCode mb_higher_order_test() 02637 { 02638 Core moab; 02639 Interface* MB = &moab; 02640 02641 double nodes_array[7][3]; 02642 02643 nodes_array[0][0] = 0; 02644 nodes_array[0][1] = 0; 02645 nodes_array[0][2] = 0; 02646 nodes_array[1][0] = 2; 02647 nodes_array[1][1] = 0; 02648 nodes_array[1][2] = 0; 02649 nodes_array[2][0] = 1; 02650 nodes_array[2][1] = 2; 02651 nodes_array[2][2] = 1; 02652 nodes_array[3][0] = 1; 02653 nodes_array[3][1] = 0; 02654 nodes_array[3][2] = 0; 02655 nodes_array[4][0] = 1.5; 02656 nodes_array[4][1] = 0.5; 02657 nodes_array[4][2] = 0.5; 02658 nodes_array[5][0] = 0.5; 02659 nodes_array[5][1] = 0.5; 02660 nodes_array[5][2] = 0.5; 02661 nodes_array[6][0] = 1; 02662 nodes_array[6][1] = 1; 02663 nodes_array[6][2] = 0.5; 02664 02665 // create the nodes 02666 std::vector< EntityHandle > connectivity( 8 ); 02667 EntityHandle node_handle; 02668 int i; 02669 for( i = 0; i < 7; i++ ) 02670 { 02671 if( MB->create_vertex( nodes_array[i], node_handle ) != MB_SUCCESS ) return MB_FAILURE; 02672 connectivity[i] = node_handle; 02673 } 02674 02675 // create the higher order tri 02676 EntityHandle tri_handle; 02677 ErrorCode result = MB->create_element( MBTRI, &connectivity[0], 6, tri_handle ); 02678 if( result != MB_SUCCESS ) return result; 02679 02680 // create the higher order tri 02681 std::vector< EntityHandle > other_conn( 3 ); 02682 02683 double other_nodes[3][3]; 02684 other_nodes[0][0] = 1.999; 02685 other_nodes[0][1] = 1.999; 02686 other_nodes[0][2] = 1.999; 02687 other_nodes[1][0] = 2.999; 02688 other_nodes[1][1] = 2.999; 02689 other_nodes[1][2] = 2.999; 02690 other_nodes[2][0] = 3.999; 02691 other_nodes[2][1] = 3.999; 02692 other_nodes[2][2] = 3.999; 02693 02694 for( i = 0; i < 3; i++ ) 02695 { 02696 if( MB->create_vertex( other_nodes[i], node_handle ) != MB_SUCCESS ) return MB_FAILURE; 02697 other_conn[i] = node_handle; 02698 } 02699 02700 EntityHandle other_tri_handle; 02701 result = MB->create_element( MBTRI, &other_conn[0], 3, other_tri_handle ); 02702 if( result != MB_SUCCESS ) return result; 02703 02704 // get the connectivity now 02705 std::vector< EntityHandle > retrieved_conn; 02706 02707 result = MB->get_connectivity( &tri_handle, 1, retrieved_conn ); 02708 if( result != MB_SUCCESS ) return result; 02709 02710 unsigned int k; 02711 for( k = 0; k < retrieved_conn.size(); k++ ) 02712 if( connectivity[k] != retrieved_conn[k] ) return MB_FAILURE; 02713 02714 result = MB->get_connectivity( &other_tri_handle, 1, retrieved_conn ); 02715 if( result != MB_SUCCESS ) return result; 02716 02717 for( k = 0; k < other_conn.size(); k++ ) 02718 if( other_conn[k] != retrieved_conn[k] ) return MB_FAILURE; 02719 02720 // now let's just try getting the topological connectivity (the 3 corner vertices) 02721 std::vector< EntityHandle > topo_conn; 02722 result = MB->get_connectivity( &other_tri_handle, 1, topo_conn, true ); 02723 if( result != MB_SUCCESS ) return result; 02724 02725 if( topo_conn.size() != 3 ) return MB_FAILURE; 02726 02727 for( k = 0; k < 3; k++ ) 02728 if( topo_conn[k] != retrieved_conn[k] ) return MB_FAILURE; 02729 02730 // short check to make sure that Core::handle_from_id() works 02731 unsigned long handle_id = MB->id_from_handle( node_handle ); 02732 02733 EntityHandle test_handle; 02734 result = MB->handle_from_id( MBVERTEX, handle_id, test_handle ); 02735 if( result != MB_SUCCESS ) return result; 02736 02737 if( test_handle != node_handle ) return MB_FAILURE; 02738 02739 handle_id = MB->id_from_handle( tri_handle ); 02740 02741 result = MB->handle_from_id( MBTRI, handle_id, test_handle ); 02742 if( result != MB_SUCCESS ) return result; 02743 02744 if( test_handle != tri_handle ) return MB_FAILURE; 02745 02746 // make up some bogus id 02747 handle_id = 2140824; 02748 02749 result = MB->handle_from_id( MBTRI, handle_id, test_handle ); 02750 if( result != MB_ENTITY_NOT_FOUND ) return MB_FAILURE; 02751 02752 result = MB->handle_from_id( MBVERTEX, handle_id, test_handle ); 02753 if( result != MB_ENTITY_NOT_FOUND ) return MB_FAILURE; 02754 02755 return MB_SUCCESS; 02756 } 02757 02758 ErrorCode mb_bit_tags_test() 02759 { 02760 Core moab; 02761 Interface* MB = &moab; 02762 ErrorCode success = create_some_mesh( MB ); 02763 if( MB_SUCCESS != success ) return success; 02764 02765 Tag bit_tag; 02766 Range entities; 02767 MB->get_entities_by_type( 0, MBVERTEX, entities ); 02768 02769 if( MB->tag_get_handle( "bit on vertex", 3, MB_TYPE_BIT, bit_tag, MB_TAG_CREAT ) != MB_SUCCESS ) 02770 { 02771 cout << "couldn't create bit tag" << endl; 02772 return MB_FAILURE; 02773 } 02774 02775 Range::iterator iter; 02776 unsigned char bits; 02777 for( iter = entities.begin(); iter != entities.end(); ++iter ) 02778 { 02779 // tag each vertex with the low 3 bits of the entity handle 02780 bits = ( ( *iter ) & 0x7 ); 02781 success = MB->tag_set_data( bit_tag, &( *iter ), 1, &bits ); 02782 if( success != MB_SUCCESS ) return MB_FAILURE; 02783 } 02784 02785 bits = 0; 02786 for( iter = entities.begin(); iter != entities.end(); ++iter ) 02787 { 02788 // tag each vertex with the low 3 bits of the entity handle 02789 success = MB->tag_get_data( bit_tag, &( *iter ), 1, &bits ); 02790 if( success != MB_SUCCESS ) return MB_FAILURE; 02791 02792 if( bits != ( ( *iter ) & 0x7 ) ) return MB_FAILURE; 02793 } 02794 02795 // test range-based query for all vertices 02796 std::vector< unsigned char > data( entities.size() ); 02797 success = MB->tag_get_data( bit_tag, entities, &data[0] ); 02798 if( MB_SUCCESS != success ) return success; 02799 std::vector< unsigned char >::iterator i = data.begin(); 02800 for( iter = entities.begin(); iter != entities.end(); ++iter, ++i ) 02801 if( *i != ( ( *iter ) & 0x7 ) ) return MB_FAILURE; 02802 02803 // test vector-based query for all vertices 02804 std::vector< EntityHandle > verts( entities.begin(), entities.end() ); 02805 success = MB->tag_get_data( bit_tag, &verts[0], verts.size(), &data[0] ); 02806 if( MB_SUCCESS != success ) return success; 02807 i = data.begin(); 02808 for( iter = entities.begin(); iter != entities.end(); ++iter, ++i ) 02809 if( *i != ( ( *iter ) & 0x7 ) ) return MB_FAILURE; 02810 02811 // test default value 02812 const unsigned char default_bits = '\005'; // 0000 0101 02813 Tag tag2; 02814 success = MB->tag_get_handle( "bit with default", 4, MB_TYPE_BIT, tag2, MB_TAG_CREAT, &default_bits ); 02815 if( MB_SUCCESS != success ) 02816 { 02817 cout << "Failed to create bit tag with default value" << std::endl; 02818 return success; 02819 } 02820 02821 // set value to zero on a single vertex 02822 bits = 0; 02823 EntityHandle zh = verts[verts.size() / 2]; 02824 success = MB->tag_set_data( tag2, &zh, 1, &bits ); 02825 if( MB_SUCCESS != success ) return success; 02826 02827 // get tag values for all entities 02828 data.clear(); 02829 data.resize( verts.size(), 0x7A ); // initialize with 0111 1010 02830 success = MB->tag_get_data( tag2, entities, &data[0] ); 02831 if( MB_SUCCESS != success ) return success; 02832 02833 // check values 02834 i = data.begin(); 02835 for( iter = entities.begin(); iter != entities.end(); ++iter, ++i ) 02836 if( *iter == zh && *i ) // the one we set to zero 02837 return MB_FAILURE; 02838 else if( *iter != zh && *i != default_bits ) 02839 return MB_FAILURE; 02840 02841 return MB_SUCCESS; 02842 } 02843 02844 #ifdef MOAB_HAVE_NETCDF 02845 ErrorCode mb_tags_test() 02846 { 02847 Core moab; 02848 Interface* MB = &moab; 02849 ErrorCode result = load_file_one( MB ); 02850 if( MB_SUCCESS != result ) return result; 02851 02852 Tag stale_bits, stale_dense, stale_sparse; 02853 result = MB->tag_get_handle( "stale data", 5, MB_TYPE_BIT, stale_bits, MB_TAG_CREAT ); 02854 if( MB_SUCCESS != result ) return result; 02855 02856 int def_data = 9; 02857 result = MB->tag_get_handle( "dense stale_data", 1, MB_TYPE_INTEGER, stale_dense, MB_TAG_DENSE | MB_TAG_EXCL, 02858 &def_data ); 02859 if( MB_SUCCESS != result ) return result; 02860 result = MB->tag_get_handle( "sparse stale data", 1, MB_TYPE_INTEGER, stale_sparse, MB_TAG_SPARSE | MB_TAG_EXCL ); 02861 if( MB_SUCCESS != result ) return result; 02862 02863 double coords[3] = { 0, 0, 0 }; 02864 EntityHandle stale_handle1, stale_handle2; 02865 result = MB->create_vertex( coords, stale_handle1 ); 02866 if( MB_SUCCESS != result ) return result; 02867 02868 unsigned char bits = 0x5; 02869 result = MB->tag_set_data( stale_bits, &stale_handle1, 1, &bits ); 02870 if( MB_SUCCESS != result ) return result; 02871 bits = 0; 02872 result = MB->tag_get_data( stale_bits, &stale_handle1, 1, &bits ); 02873 if( MB_SUCCESS != result ) return result; 02874 if( bits != 0x5 ) return MB_FAILURE; 02875 02876 def_data = 1; 02877 result = MB->tag_set_data( stale_dense, &stale_handle1, 1, &def_data ); 02878 if( MB_SUCCESS != result ) return result; 02879 def_data = 0; 02880 result = MB->tag_get_data( stale_dense, &stale_handle1, 1, &def_data ); 02881 if( MB_SUCCESS != result ) return result; 02882 if( def_data != 1 ) return MB_FAILURE; 02883 02884 def_data = 100; 02885 result = MB->tag_set_data( stale_sparse, &stale_handle1, 1, &def_data ); 02886 if( MB_SUCCESS != result ) return result; 02887 def_data = 0; 02888 result = MB->tag_get_data( stale_sparse, &stale_handle1, 1, &def_data ); 02889 if( MB_SUCCESS != result ) return result; 02890 if( def_data != 100 ) return MB_FAILURE; 02891 02892 result = MB->delete_entities( &stale_handle1, 1 ); 02893 if( MB_SUCCESS != result ) return result; 02894 result = MB->create_vertex( coords, stale_handle2 ); 02895 if( MB_SUCCESS != result ) return result; 02896 02897 if( stale_handle1 != stale_handle2 ) 02898 cout << "Tag test could test stale data" << endl; 02899 else 02900 { 02901 bits = 0; 02902 result = MB->tag_get_data( stale_bits, &stale_handle2, 1, &bits ); 02903 if( MB_SUCCESS != result ) return result; 02904 if( bits != 0 ) return MB_FAILURE; 02905 02906 def_data = 3; 02907 result = MB->tag_get_data( stale_dense, &stale_handle2, 1, &def_data ); 02908 if( MB_SUCCESS != result ) return result; 02909 if( def_data != 9 ) return MB_FAILURE; 02910 02911 def_data = 3; 02912 ErrorCode stale_result = MB->tag_get_data( stale_sparse, &stale_handle2, 1, &def_data ); 02913 // we are supposed to fail here 02914 if( stale_result != MB_TAG_NOT_FOUND ) return MB_FAILURE; 02915 } 02916 02917 result = MB->tag_delete( stale_dense ); 02918 if( MB_SUCCESS != result ) return result; 02919 02920 result = MB->delete_entities( &stale_handle2, 1 ); 02921 if( MB_SUCCESS != result ) return result; 02922 02923 // get all blocks with material tag and with tag_value of 1 (should only be 1) 02924 Range entities; 02925 int value = 1; 02926 const void* dum_ptr = &value; 02927 Tag material_tag; 02928 result = MB->tag_get_handle( MATERIAL_SET_TAG_NAME, 1, MB_TYPE_INTEGER, material_tag ); 02929 if( MB_SUCCESS != result ) return result; 02930 if( MB->get_entities_by_type_and_tag( 0, MBENTITYSET, &material_tag, &dum_ptr, 1, entities ) != MB_SUCCESS ) 02931 return MB_FAILURE; 02932 02933 if( entities.size() != 1 ) return MB_FAILURE; 02934 02935 // add a dense tag to hexes 02936 Tag junk_tag; 02937 if( MB->tag_get_handle( "junk_tag", 1, MB_TYPE_INTEGER, junk_tag, MB_TAG_DENSE | MB_TAG_EXCL ) != MB_SUCCESS ) 02938 return MB_FAILURE; 02939 02940 // Set the dense tag on 5 hexes to 3489 02941 Range test_range; 02942 result = MB->get_entities_by_type( 0, MBHEX, test_range ); 02943 if( result != MB_SUCCESS ) return result; 02944 02945 Range::iterator iter, end_iter; 02946 iter = test_range.begin(); 02947 end_iter = test_range.end(); 02948 02949 int data = 3489; 02950 const void* ptr_data = &data; 02951 02952 // mark approxiamtely the first 20% of the hex entities; also put a bit tag on them 02953 unsigned int times = test_range.size() / 5; 02954 bits = 0x5; 02955 const void* ptr_bits = &bits; 02956 02957 for( unsigned int i = 0; i < times; i++ ) 02958 { 02959 if( MB->tag_set_data( junk_tag, &( *iter ), 1, &data ) != MB_SUCCESS ) return MB_FAILURE; 02960 if( MB->tag_set_data( stale_bits, &( *iter ), 1, &bits ) != MB_SUCCESS ) return MB_FAILURE; 02961 ++iter; 02962 } 02963 02964 entities.clear(); 02965 // fetch the hex entities of type--MBHEX, tag-"junk_tag", and tag value -- 3489 02966 if( MB->get_entities_by_type_and_tag( 0, MBHEX, &junk_tag, &ptr_data, 1, entities ) != MB_SUCCESS ) 02967 return MB_FAILURE; 02968 02969 if( entities.size() != times ) // should get as many hexes as you perviously marked 02970 return MB_FAILURE; 02971 02972 // fetch the hex entities of type--MBHEX, tag-"junk_tag", and tag value -- 3489 02973 entities.clear(); 02974 if( MB->get_entities_by_type_and_tag( 0, MBHEX, &stale_bits, &ptr_bits, 1, entities ) != MB_SUCCESS ) 02975 return MB_FAILURE; 02976 02977 if( entities.size() != times ) // should get as many hexes as you perviously marked 02978 return MB_FAILURE; 02979 02980 // test fetch by tag value again, this time limiting the results 02981 // to the contents of an entity set 02982 EntityHandle meshset; 02983 result = MB->create_meshset( MESHSET_SET, meshset ); 02984 if( MB_SUCCESS != result ) return result; 02985 result = MB->add_entities( meshset, test_range ); 02986 if( MB_SUCCESS != result ) return result; 02987 02988 // fetch the hex entities of type--MBHEX, tag-"junk_tag", and tag value -- 3489 02989 entities.clear(); 02990 result = MB->get_entities_by_type_and_tag( meshset, MBHEX, &junk_tag, &ptr_data, 1, entities ); 02991 if( MB_SUCCESS != result ) return result; 02992 02993 if( entities.size() != times ) // should get as many hexes as you perviously marked 02994 return MB_FAILURE; 02995 02996 // fetch the hex entities of type--MBHEX, tag-"stale_bits", and tag value -- 0x5 02997 entities.clear(); 02998 result = MB->get_entities_by_type_and_tag( meshset, MBHEX, &stale_bits, &ptr_bits, 1, entities ); 02999 if( MB_SUCCESS != result ) return result; 03000 03001 if( entities.size() != times ) // should get as many hexes as you perviously marked 03002 return MB_FAILURE; 03003 03004 // now try the query with an empty meshset, expecting to get back 03005 // an empty Range 03006 03007 result = MB->create_meshset( MESHSET_SET, meshset ); 03008 if( MB_SUCCESS != result ) return result; 03009 03010 entities.clear(); 03011 result = MB->get_entities_by_type_and_tag( meshset, MBHEX, &junk_tag, &ptr_data, 1, entities ); 03012 if( MB_SUCCESS != result ) return result; 03013 03014 if( !entities.empty() ) return MB_FAILURE; 03015 03016 result = MB->tag_delete( stale_bits ); 03017 if( MB_SUCCESS != result ) return result; 03018 03019 return MB_SUCCESS; 03020 } 03021 #endif 03022 ErrorCode mb_common_tag_test( TagType storage ) 03023 { 03024 Core moab; 03025 Interface* mb = &moab; 03026 ErrorCode result = create_some_mesh( mb ); 03027 if( MB_SUCCESS != result ) return result; 03028 03029 char tagname[64]; 03030 sprintf( tagname, "t%d", rand() ); 03031 03032 Tag tag; 03033 const EntityHandle def_val = ~(EntityHandle)0; 03034 ErrorCode rval = mb->tag_get_handle( tagname, 1, MB_TYPE_HANDLE, tag, storage | MB_TAG_EXCL, &def_val ); 03035 if( MB_SUCCESS != rval ) return rval; 03036 03037 Range entities; 03038 mb->get_entities_by_handle( 0, entities ); 03039 if( entities.empty() ) return MB_FAILURE; 03040 03041 // set tag on every other entity to be the entities handle 03042 Range::const_iterator i; 03043 bool odd = true; 03044 for( i = entities.begin(); i != entities.end(); ++i, odd = !odd ) 03045 { 03046 if( odd ) 03047 { 03048 const EntityHandle h = *i; 03049 rval = mb->tag_set_data( tag, &h, 1, &h ); 03050 if( MB_SUCCESS != rval ) return rval; 03051 } 03052 } 03053 03054 // check values on every entity -- expect default for every other entity 03055 odd = true; 03056 for( i = entities.begin(); i != entities.end(); ++i, odd = !odd ) 03057 { 03058 EntityHandle val = 0; 03059 rval = mb->tag_get_data( tag, &*i, 1, &val ); 03060 if( MB_SUCCESS != rval ) return rval; 03061 03062 if( odd ) 03063 { 03064 if( val != *i ) return MB_FAILURE; 03065 } 03066 else 03067 { 03068 if( val != def_val ) return MB_FAILURE; 03069 } 03070 } 03071 03072 // set tag values on all entities 03073 std::vector< EntityHandle > values( entities.size() ); 03074 std::copy( entities.begin(), entities.end(), values.begin() ); 03075 rval = mb->tag_set_data( tag, entities, &values[0] ); 03076 if( MB_SUCCESS != rval ) return rval; 03077 03078 // check values on every entity -- expect default for every other entity 03079 for( i = entities.begin(); i != entities.end(); ++i ) 03080 { 03081 EntityHandle val = 0; 03082 rval = mb->tag_get_data( tag, &*i, 1, &val ); 03083 if( MB_SUCCESS != rval ) return rval; 03084 if( val != *i ) return MB_FAILURE; 03085 } 03086 03087 // find each entity by tag value 03088 for( i = entities.begin(); i != entities.end(); ++i ) 03089 { 03090 const EntityHandle h = *i; 03091 const EntityType type = mb->type_from_handle( h ); 03092 const void* const tag_vals[] = { &h }; 03093 Range range; 03094 rval = mb->get_entities_by_type_and_tag( 0, type, &tag, tag_vals, 1, range ); 03095 if( MB_SUCCESS != rval ) return rval; 03096 if( range.size() != 1 ) return MB_FAILURE; 03097 if( range.front() != h ) return MB_FAILURE; 03098 } 03099 03100 return MB_SUCCESS; 03101 } 03102 03103 ErrorCode mb_dense_tag_test() 03104 { 03105 return mb_common_tag_test( MB_TAG_DENSE ); 03106 } 03107 03108 ErrorCode mb_sparse_tag_test() 03109 { 03110 return mb_common_tag_test( MB_TAG_SPARSE ); 03111 } 03112 03113 // class to offset hex center nodes 03114 class OffsetHexCenterNodes : public Interface::HONodeAddedRemoved 03115 { 03116 public: 03117 OffsetHexCenterNodes( Interface* mb, double x, double y, double z ) : gMB( mb ) 03118 { 03119 mCoords[0] = 0.0; 03120 mCoords[1] = 0.0; 03121 mCoords[2] = 0.0; 03122 mOffset[0] = x; 03123 mOffset[1] = y; 03124 mOffset[2] = z; 03125 } 03126 03127 ~OffsetHexCenterNodes() {} 03128 03129 void node_added( EntityHandle node, EntityHandle ) 03130 { 03131 gMB->get_coords( &node, 1, mCoords ); 03132 mCoords[0] += mOffset[0]; 03133 mCoords[1] += mOffset[1]; 03134 mCoords[2] += mOffset[2]; 03135 gMB->set_coords( &node, 1, mCoords ); 03136 } 03137 03138 // do nothing 03139 void node_removed( EntityHandle /*node*/ ) {} 03140 03141 private: 03142 Interface* gMB; 03143 double mCoords[3]; 03144 double mOffset[3]; 03145 }; 03146 #ifdef MOAB_HAVE_NETCDF 03147 ErrorCode mb_entity_conversion_test() 03148 { 03149 ErrorCode error; 03150 Core moab; 03151 Interface* MB = &moab; 03152 03153 // read in a file so you have some data in the database 03154 std::string file_name = TestDir + "unittest/mbtest3.g"; 03155 error = MB->load_mesh( file_name.c_str(), NULL, 0 ); 03156 if( error != MB_SUCCESS ) return error; 03157 03158 Range entities; 03159 EntityHandle meshset; 03160 MB->create_meshset( MESHSET_SET, meshset ); 03161 03162 MB->get_entities_by_type( 0, MBHEX, entities ); 03163 MB->add_entities( meshset, entities ); 03164 03165 OffsetHexCenterNodes function_object( MB, 0.07, 0.15, 0 ); 03166 03167 MB->convert_entities( meshset, false, false, true, &function_object ); 03168 if( MB_SUCCESS != check_valid_connectivity( MB ) ) return MB_FAILURE; 03169 03170 file_name = "hex_mid_volume_nodes.g"; 03171 error = MB->write_mesh( file_name.c_str() ); 03172 if( error != MB_SUCCESS ) return error; 03173 03174 error = MB->delete_mesh(); 03175 if( error != MB_SUCCESS ) return error; 03176 03177 error = MB->load_mesh( file_name.c_str(), NULL, 0 ); 03178 if( error != MB_SUCCESS ) return error; 03179 03180 error = MB->delete_mesh(); 03181 if( error != MB_SUCCESS ) return error; 03182 03183 file_name = TestDir + "unittest/mbtest3.g"; 03184 error = MB->load_mesh( file_name.c_str(), NULL, 0 ); 03185 if( error != MB_SUCCESS ) return error; 03186 03187 entities.clear(); 03188 MB->get_entities_by_type( 0, MBHEX, entities ); 03189 03190 MB->create_meshset( MESHSET_SET, meshset ); 03191 MB->add_entities( meshset, entities ); 03192 MB->convert_entities( meshset, true, true, true ); 03193 if( MB_SUCCESS != check_valid_connectivity( MB ) ) return MB_FAILURE; 03194 03195 file_name = "hex_mid_edge_face_vol_nodes.g"; 03196 error = MB->write_mesh( file_name.c_str() ); 03197 if( error != MB_SUCCESS ) return error; 03198 03199 error = MB->delete_mesh(); 03200 if( error != MB_SUCCESS ) return error; 03201 03202 error = MB->load_mesh( file_name.c_str(), NULL, 0 ); 03203 if( error != MB_SUCCESS ) return error; 03204 03205 error = MB->delete_mesh(); 03206 if( error != MB_SUCCESS ) return error; 03207 03208 file_name = TestDir + "unittest/mbtest3.g"; 03209 error = MB->load_mesh( file_name.c_str(), NULL, 0 ); 03210 if( error != MB_SUCCESS ) return error; 03211 03212 entities.clear(); 03213 MB->get_entities_by_type( 0, MBVERTEX, entities ); 03214 unsigned int original_num_nodes = entities.size(); 03215 entities.clear(); 03216 MB->get_entities_by_type( 0, MBHEX, entities ); 03217 03218 MB->create_meshset( MESHSET_SET, meshset ); 03219 MB->add_entities( meshset, entities ); 03220 MB->convert_entities( meshset, true, false, false ); 03221 if( MB_SUCCESS != check_valid_connectivity( MB ) ) return MB_FAILURE; 03222 03223 file_name = "hex_mid_edge_nodes.g"; 03224 error = MB->write_mesh( file_name.c_str() ); 03225 if( error != MB_SUCCESS ) return error; 03226 03227 // convert them back to hex8's 03228 MB->convert_entities( meshset, false, false, false ); 03229 if( MB_SUCCESS != check_valid_connectivity( MB ) ) return MB_FAILURE; 03230 03231 entities.clear(); 03232 MB->get_entities_by_type( 0, MBVERTEX, entities ); 03233 // make sure the higher order nodes really were deleted 03234 if( entities.size() != original_num_nodes ) return MB_FAILURE; 03235 03236 error = MB->delete_mesh(); 03237 if( error != MB_SUCCESS ) return error; 03238 03239 error = MB->load_mesh( file_name.c_str(), NULL, 0 ); 03240 if( error != MB_SUCCESS ) return error; 03241 03242 error = MB->delete_mesh(); 03243 if( error != MB_SUCCESS ) return error; 03244 03245 file_name = TestDir + "unittest/mbtest1.g"; 03246 error = MB->load_mesh( file_name.c_str(), NULL, 0 ); 03247 if( error != MB_SUCCESS ) return error; 03248 03249 entities.clear(); 03250 MB->get_entities_by_type( 0, MBTET, entities ); 03251 03252 MB->create_meshset( MESHSET_SET, meshset ); 03253 MB->add_entities( meshset, entities ); 03254 MB->convert_entities( meshset, true, false, false ); 03255 if( MB_SUCCESS != check_valid_connectivity( MB ) ) return MB_FAILURE; 03256 03257 file_name = "tet_mid_edge_nodes.g"; 03258 error = MB->write_mesh( file_name.c_str() ); 03259 if( error != MB_SUCCESS ) return error; 03260 03261 error = MB->delete_mesh(); 03262 if( error != MB_SUCCESS ) return error; 03263 03264 error = MB->load_mesh( file_name.c_str(), NULL, 0 ); 03265 if( error != MB_SUCCESS ) return error; 03266 03267 error = MB->delete_mesh(); 03268 if( error != MB_SUCCESS ) return error; 03269 03270 file_name = TestDir + "unittest/mbtest1.g"; 03271 error = MB->load_mesh( file_name.c_str(), NULL, 0 ); 03272 if( error != MB_SUCCESS ) return error; 03273 03274 entities.clear(); 03275 MB->get_entities_by_type( 0, MBTET, entities ); 03276 03277 MB->create_meshset( MESHSET_SET, meshset ); 03278 MB->add_entities( meshset, entities ); 03279 MB->convert_entities( meshset, false, true, false ); 03280 if( MB_SUCCESS != check_valid_connectivity( MB ) ) return MB_FAILURE; 03281 03282 file_name = "tet_mid_face_nodes.g"; 03283 error = MB->write_mesh( file_name.c_str() ); 03284 if( error != MB_SUCCESS ) return error; 03285 03286 error = MB->delete_mesh(); 03287 if( error != MB_SUCCESS ) return error; 03288 03289 error = MB->load_mesh( file_name.c_str(), NULL, 0 ); 03290 if( error != MB_SUCCESS ) return error; 03291 03292 error = MB->delete_mesh(); 03293 if( error != MB_SUCCESS ) return error; 03294 03295 file_name = TestDir + "unittest/mbtest1.g"; 03296 error = MB->load_mesh( file_name.c_str(), NULL, 0 ); 03297 if( error != MB_SUCCESS ) return error; 03298 03299 entities.clear(); 03300 MB->get_entities_by_type( 0, MBTET, entities ); 03301 03302 MB->create_meshset( MESHSET_SET, meshset ); 03303 MB->add_entities( meshset, entities ); 03304 MB->convert_entities( meshset, true, true, false ); 03305 if( MB_SUCCESS != check_valid_connectivity( MB ) ) return MB_FAILURE; 03306 03307 file_name = "tet_mid_edge_face_nodes.g"; 03308 error = MB->write_mesh( file_name.c_str() ); 03309 if( error != MB_SUCCESS ) return error; 03310 03311 error = MB->delete_mesh(); 03312 if( error != MB_SUCCESS ) return error; 03313 03314 error = MB->load_mesh( file_name.c_str(), NULL, 0 ); 03315 if( error != MB_SUCCESS ) return error; 03316 03317 error = MB->delete_mesh(); 03318 if( error != MB_SUCCESS ) return error; 03319 03320 file_name = TestDir + "unittest/mbtest1.g"; 03321 error = MB->load_mesh( file_name.c_str(), NULL, 0 ); 03322 if( error != MB_SUCCESS ) return error; 03323 03324 // delete all MBTRI's 03325 entities.clear(); 03326 error = MB->get_entities_by_type( 0, MBTRI, entities ); 03327 if( MB_SUCCESS != error ) return error; 03328 error = MB->delete_entities( entities ); 03329 if( MB_SUCCESS != error ) return error; 03330 03331 entities.clear(); 03332 error = MB->get_entities_by_type( 0, MBTET, entities ); 03333 if( MB_SUCCESS != error ) return error; 03334 03335 // skin the model 03336 for( Range::iterator tet_iter = entities.begin(); tet_iter != entities.end(); ++tet_iter ) 03337 { 03338 std::vector< EntityHandle > adj; 03339 error = MB->get_adjacencies( &( *tet_iter ), 1, 2, true, adj ); 03340 if( MB_SUCCESS != error ) return error; 03341 for( std::vector< EntityHandle >::iterator tri_iter = adj.begin(); tri_iter != adj.end(); ++tri_iter ) 03342 { 03343 std::vector< EntityHandle > up_adj; 03344 MB->get_adjacencies( &( *tri_iter ), 1, 3, false, up_adj ); 03345 if( up_adj.size() > 1 ) 03346 { 03347 error = MB->delete_entities( &( *tri_iter ), 1 ); 03348 if( MB_SUCCESS != error ) return error; 03349 } 03350 } 03351 } 03352 03353 // create a meshset of the skin 03354 EntityHandle export_meshset; 03355 MB->create_meshset( MESHSET_SET, export_meshset ); 03356 Tag material_tag; 03357 MB->tag_get_handle( MATERIAL_SET_TAG_NAME, 1, MB_TYPE_INTEGER, material_tag ); 03358 int block_id = 100; 03359 MB->tag_set_data( material_tag, &export_meshset, 1, &block_id ); 03360 entities.clear(); 03361 MB->get_entities_by_type( 0, MBTRI, entities ); 03362 // remove the first few tri's for fun 03363 Range tmp_ents; 03364 tmp_ents.insert( *entities.begin() ); 03365 entities.erase( entities.begin() ); 03366 tmp_ents.insert( *entities.begin() ); 03367 entities.erase( entities.begin() ); 03368 tmp_ents.insert( *entities.begin() ); 03369 entities.erase( entities.begin() ); 03370 tmp_ents.insert( *entities.begin() ); 03371 entities.erase( entities.begin() ); 03372 03373 MB->add_entities( export_meshset, entities ); 03374 03375 // convert the skin 03376 MB->convert_entities( export_meshset, true, true, false ); 03377 if( MB_SUCCESS != check_valid_connectivity( MB ) ) return MB_FAILURE; 03378 03379 // make sure our first few tri's were untouched 03380 std::vector< EntityHandle > conn( 3 ); 03381 for( Range::iterator kter = tmp_ents.begin(); kter != tmp_ents.end(); ++kter ) 03382 { 03383 MB->get_connectivity( &( *kter ), 1, conn ); 03384 if( conn.size() != 3 ) return MB_FAILURE; 03385 } 03386 03387 // output the skin 03388 file_name = "tri_mid_edge_face_nodes.g"; 03389 error = MB->write_mesh( file_name.c_str(), &export_meshset, 1 ); 03390 if( error != MB_SUCCESS ) return error; 03391 03392 MB->delete_entities( &export_meshset, 1 ); 03393 03394 error = MB->delete_mesh(); 03395 if( error != MB_SUCCESS ) return error; 03396 03397 // read the skin back in 03398 error = MB->load_mesh( file_name.c_str(), NULL, 0 ); 03399 if( error != MB_SUCCESS ) return error; 03400 03401 entities.clear(); 03402 MB->get_entities_by_type( 0, MBVERTEX, entities ); 03403 // must have 101 nodes 03404 if( entities.size() != 101 ) return MB_FAILURE; 03405 03406 error = MB->delete_mesh(); 03407 if( error != MB_SUCCESS ) return error; 03408 03409 return MB_SUCCESS; 03410 } 03411 #endif 03412 //! Build two Quads with two edges shared between them. The 03413 //! edges share the same nodes. We should be able to get 03414 //! adjacencies on the edges and get one (correct) quad. We 03415 //! should be able to get the edge adjacencies of the quads 03416 //! and only get 4 (not 5) edges. 03417 //! 03418 03419 ErrorCode mb_forced_adjacencies_test() 03420 { 03421 //! first clean up any existing mesh. 03422 ErrorCode error; 03423 Core moab; 03424 Interface* MB = &moab; 03425 03426 //! create 6 nodes, 2 quads and 8 edges. Edge 4 is adjacent 03427 //! to quad 1 and edge 5 is adjacent to quad 2. 03428 //! 03429 //! 4 5 6 03430 //! o--e7---o--e8---o 03431 //! | | | 03432 //! e3 q1 e4 e5 q2 e6 03433 //! | | | 03434 //! o--e1---o--e2---o 03435 //! 1 2 3 03436 //! 03437 double node_coord1[3] = { 0., 0., 0. }; 03438 double node_coord2[3] = { 1., 0., 0. }; 03439 double node_coord3[3] = { 2., 0., 0. }; 03440 double node_coord4[3] = { 0., 1., 0. }; 03441 double node_coord5[3] = { 1., 1., 0. }; 03442 double node_coord6[3] = { 2., 1., 0. }; 03443 03444 EntityHandle node1, node2, node3, node4, node5, node6; 03445 error = MB->create_vertex( node_coord1, node1 ); 03446 if( error != MB_SUCCESS ) return error; 03447 03448 error = MB->create_vertex( node_coord2, node2 ); 03449 if( error != MB_SUCCESS ) return error; 03450 03451 error = MB->create_vertex( node_coord3, node3 ); 03452 if( error != MB_SUCCESS ) return error; 03453 03454 error = MB->create_vertex( node_coord4, node4 ); 03455 if( error != MB_SUCCESS ) return error; 03456 03457 error = MB->create_vertex( node_coord5, node5 ); 03458 if( error != MB_SUCCESS ) return error; 03459 03460 error = MB->create_vertex( node_coord6, node6 ); 03461 if( error != MB_SUCCESS ) return error; 03462 03463 std::vector< EntityHandle > conn( 4 ); 03464 //! create the first quad 03465 EntityHandle quad1; 03466 conn[0] = node1; 03467 conn[1] = node2; 03468 conn[2] = node5; 03469 conn[3] = node4; 03470 error = MB->create_element( MBQUAD, &conn[0], 4, quad1 ); 03471 if( error != MB_SUCCESS ) return error; 03472 03473 //! create the second quad 03474 EntityHandle quad2; 03475 conn[0] = node2; 03476 conn[1] = node3; 03477 conn[2] = node6; 03478 conn[3] = node5; 03479 error = MB->create_element( MBQUAD, &conn[0], 4, quad2 ); 03480 if( error != MB_SUCCESS ) return error; 03481 03482 //! create the edges 03483 EntityHandle edge1; 03484 conn.resize( 2 ); 03485 conn[0] = node1; 03486 conn[1] = node2; 03487 error = MB->create_element( MBEDGE, &conn[0], 2, edge1 ); 03488 if( error != MB_SUCCESS ) return error; 03489 03490 EntityHandle edge2; 03491 conn[0] = node2; 03492 conn[1] = node3; 03493 error = MB->create_element( MBEDGE, &conn[0], 2, edge2 ); 03494 if( error != MB_SUCCESS ) return error; 03495 03496 EntityHandle edge3; 03497 conn[0] = node1; 03498 conn[1] = node4; 03499 error = MB->create_element( MBEDGE, &conn[0], 2, edge3 ); 03500 if( error != MB_SUCCESS ) return error; 03501 03502 EntityHandle edge4; 03503 conn[0] = node2; 03504 conn[1] = node5; 03505 error = MB->create_element( MBEDGE, &conn[0], 2, edge4 ); 03506 if( error != MB_SUCCESS ) return error; 03507 03508 EntityHandle edge5; 03509 conn[0] = node2; 03510 conn[1] = node5; 03511 error = MB->create_element( MBEDGE, &conn[0], 2, edge5 ); 03512 if( error != MB_SUCCESS ) return error; 03513 03514 EntityHandle edge6; 03515 conn[0] = node3; 03516 conn[1] = node6; 03517 error = MB->create_element( MBEDGE, &conn[0], 2, edge6 ); 03518 if( error != MB_SUCCESS ) return error; 03519 03520 EntityHandle edge7; 03521 conn[0] = node4; 03522 conn[1] = node5; 03523 error = MB->create_element( MBEDGE, &conn[0], 2, edge7 ); 03524 if( error != MB_SUCCESS ) return error; 03525 03526 EntityHandle edge8; 03527 conn[0] = node5; 03528 conn[1] = node6; 03529 error = MB->create_element( MBEDGE, &conn[0], 2, edge8 ); 03530 if( error != MB_SUCCESS ) return error; 03531 03532 //! Edge 4 and 5 share the same nodes, but should be different entities 03533 if( edge4 == edge5 ) return MB_FAILURE; 03534 03535 //! Now that the geometry is created start adding the adjacency information 03536 std::vector< EntityHandle > edge_adjacencies1( 4 ); 03537 edge_adjacencies1[0] = edge1; 03538 edge_adjacencies1[1] = edge4; 03539 edge_adjacencies1[2] = edge7; 03540 edge_adjacencies1[3] = edge3; 03541 03542 //! does this (should this) say anything about order of the edges around the 03543 //! quad? Also, does this also build the edge->quad adjacency, or is that 03544 //! does with a separate call? 03545 error = MB->add_adjacencies( quad1, &edge_adjacencies1[0], edge_adjacencies1.size(), true ); 03546 if( error != MB_SUCCESS ) return error; 03547 03548 std::vector< EntityHandle > edge_adjacencies2( 4 ); 03549 edge_adjacencies2[0] = edge2; 03550 edge_adjacencies2[1] = edge6; 03551 edge_adjacencies2[2] = edge8; 03552 edge_adjacencies2[3] = edge5; 03553 error = MB->add_adjacencies( quad2, &edge_adjacencies2[0], edge_adjacencies2.size(), true ); 03554 if( error != MB_SUCCESS ) return error; 03555 03556 //! now get the adjacencies of each quad. 03557 std::vector< EntityHandle > quad1_adjacencies; 03558 error = MB->get_adjacencies( &( quad1 ), 1, 1, false, quad1_adjacencies ); 03559 if( error != MB_SUCCESS ) return error; 03560 03561 std::sort( quad1_adjacencies.begin(), quad1_adjacencies.end() ); 03562 std::sort( edge_adjacencies1.begin(), edge_adjacencies1.end() ); 03563 03564 if( quad1_adjacencies != edge_adjacencies1 ) return MB_FAILURE; 03565 03566 std::vector< EntityHandle > quad2_adjacencies; 03567 error = MB->get_adjacencies( &( quad2 ), 1, 1, false, quad2_adjacencies ); 03568 if( error != MB_SUCCESS ) return error; 03569 03570 std::sort( quad2_adjacencies.begin(), quad2_adjacencies.end() ); 03571 std::sort( edge_adjacencies2.begin(), edge_adjacencies2.end() ); 03572 03573 if( quad2_adjacencies != edge_adjacencies2 ) return MB_FAILURE; 03574 03575 //! try getting the adjacency of edge1 (should be quad1) 03576 std::vector< EntityHandle > edge1_adjacencies; 03577 error = MB->get_adjacencies( &( edge1 ), 1, 2, false, edge1_adjacencies ); 03578 if( error != MB_SUCCESS ) return error; 03579 03580 //! there should be only 1 entity adjacent to edge1 03581 if( edge1_adjacencies.size() != 1 ) return MB_FAILURE; 03582 03583 //! and that entity should be quad1 03584 if( edge1_adjacencies[0] != quad1 ) return MB_FAILURE; 03585 03586 //! try getting the adjacency of edge6 (should be one) 03587 std::vector< EntityHandle > edge6_adjacencies; 03588 error = MB->get_adjacencies( &( edge6 ), 1, 2, false, edge6_adjacencies ); 03589 if( error != MB_SUCCESS ) return error; 03590 03591 //! there should be only 1 entity adjacent to edge6 03592 if( edge6_adjacencies.size() != 1 ) return MB_FAILURE; 03593 03594 //! Now seal up the "gap" caused by edges 4 and 5. Remove edge5 03595 //! from the adjacencies of quad2 and add edge 4 to quad2. 03596 03597 std::vector< EntityHandle > edge5_adjacencies( 1, edge5 ); 03598 error = MB->remove_adjacencies( quad2, &edge5_adjacencies[0], edge5_adjacencies.size() ); 03599 if( error != MB_SUCCESS ) return error; 03600 03601 std::vector< EntityHandle > edge4_adjacencies( 1, edge4 ); 03602 error = MB->add_adjacencies( quad2, &edge4_adjacencies[0], edge4_adjacencies.size(), true ); 03603 if( error != MB_SUCCESS ) return error; 03604 03605 //! get the adjacencies of edge4 and it should return both quads. 03606 std::vector< EntityHandle > quad_adjacencies; 03607 error = MB->get_adjacencies( &( edge4 ), 1, 2, false, quad_adjacencies ); 03608 if( error != MB_SUCCESS ) return error; 03609 03610 //! there should be 2 entities adjacent to edge4 03611 if( quad_adjacencies.size() != 2 ) return MB_FAILURE; 03612 03613 //! and they should be quad1 and quad2. Note that we are not saying anything 03614 //! about order in the array. 03615 if( ( quad_adjacencies[0] != quad1 || quad_adjacencies[1] != quad2 ) && 03616 ( quad_adjacencies[0] != quad2 || quad_adjacencies[1] != quad1 ) ) 03617 return MB_FAILURE; 03618 03619 //! clean up on exit 03620 error = MB->delete_mesh(); 03621 if( error != MB_SUCCESS ) return error; 03622 03623 return MB_SUCCESS; 03624 } 03625 03626 /*bool lessnodesZ(const EntityHandle entity_handle1, const EntityHandle entity_handle2) 03627 { 03628 double coords1[3], coords2[3]; 03629 gMB->get_coords(entity_handle1, coords1); 03630 gMB->get_coords(entity_handle2, coords2); 03631 03632 return coords2[2] < coords1[2]; 03633 }*/ 03634 03635 /*void sort_verts(Range vertices) 03636 { 03637 std::vector<EntityHandle> vert_vec(vertices.size()); 03638 Range::const_iterator iter; 03639 for (iter = vertices.begin(); iter != vertices.end(); ++iter) 03640 vert_vec.push_back(*iter); 03641 vert_vec.sort(lessnodesZ); 03642 }*/ 03643 bool points_are_coincident( const double* first, const double* second ) 03644 { 03645 double diff[3]; 03646 diff[2] = first[2] - second[2]; 03647 // if (diff[2] > 0.001) return false; 03648 03649 diff[0] = first[0] - second[0]; 03650 diff[1] = first[1] - second[1]; 03651 03652 double length = diff[0] * diff[0] + diff[1] * diff[1] + diff[2] * diff[2]; 03653 if( fabs( length ) < .001 ) return true; 03654 03655 return false; 03656 } 03657 ErrorCode find_coincident_nodes( Interface* gMB, 03658 const Range& vertices, 03659 std::vector< std::pair< EntityHandle, EntityHandle > >& coin_nodes ) 03660 { 03661 double first_coords[3], second_coords[3]; 03662 Range::const_iterator iter, jter; 03663 std::pair< EntityHandle, EntityHandle > coincident_pair; 03664 ErrorCode result; 03665 03666 for( iter = vertices.begin(); iter != vertices.end(); ++iter ) 03667 { 03668 result = gMB->get_coords( &( *iter ), 1, first_coords ); 03669 if( result != MB_SUCCESS ) return result; 03670 03671 for( jter = iter; jter != vertices.end(); ++jter ) 03672 { 03673 if( *iter != *jter ) 03674 { 03675 result = gMB->get_coords( &( *jter ), 1, second_coords ); 03676 if( result != MB_SUCCESS ) return result; 03677 03678 if( points_are_coincident( first_coords, second_coords ) ) 03679 { 03680 coincident_pair.first = *iter; 03681 coincident_pair.second = *jter; 03682 coin_nodes.push_back( coincident_pair ); 03683 } 03684 } 03685 } 03686 } 03687 return MB_SUCCESS; 03688 } 03689 03690 ErrorCode find_coincident_elements( Interface* gMB, 03691 const Range& entities, 03692 int num_nodes, 03693 std::vector< std::pair< EntityHandle, EntityHandle > >& coin ) 03694 { 03695 double coords1[8][3], coords2[8][3]; 03696 Range::iterator iter, jter; 03697 std::vector< EntityHandle > conn( 8 ); 03698 std::pair< EntityHandle, EntityHandle > coincident_pair; 03699 int i = 0, /* j = 0,*/ ii = 0; 03700 03701 for( iter = entities.begin(); iter != entities.end(); ++iter ) 03702 { 03703 // Get the coordinates for the element corners. 03704 if( gMB->get_connectivity( &( *iter ), 1, conn ) != MB_SUCCESS ) return MB_FAILURE; 03705 for( ii = 0; ii < num_nodes; ii++ ) 03706 { 03707 if( gMB->get_coords( &( conn[ii] ), 1, coords1[ii] ) != MB_SUCCESS ) return MB_FAILURE; 03708 } 03709 03710 for( jter = iter; jter != entities.end(); ++jter ) 03711 { 03712 if( *iter != *jter ) 03713 { 03714 // Elements should be the same sense to merge. 03715 if( gMB->get_connectivity( &( *jter ), 1, conn ) != MB_SUCCESS ) return MB_FAILURE; 03716 03717 for( int tq = 0; tq < num_nodes; tq++ ) 03718 if( gMB->get_coords( &( conn[tq] ), 1, coords2[tq] ) != MB_SUCCESS ) return MB_FAILURE; 03719 // if(gMB->get_coords(&(conn[0]), 1, coords2[0]) != MB_SUCCESS) 03720 // return MB_FAILURE; 03721 03722 // Find if first node is coincident before testing the rest. 03723 bool first = false; 03724 for( i = 0; i < num_nodes; i++ ) 03725 { 03726 if( points_are_coincident( coords1[i], coords2[0] ) ) 03727 { 03728 /* cout <<"first("<<i<<",0) - "; 03729 cout <<" coords1["<<i<<"] = (" 03730 <<coords1[i][0]<<"," 03731 <<coords1[i][1]<<"," 03732 <<coords1[i][2]<<") "; 03733 cout <<" coords2["<<0<<"] = (" 03734 <<coords2[0][0]<<"," 03735 <<coords2[0][1]<<"," 03736 <<coords2[0][2]<<")\n";*/ 03737 first = true; 03738 break; 03739 } 03740 } 03741 // TEST -- Find if second node is coincident before testing the rest. 03742 bool second = false; 03743 for( int t2 = 0; t2 < num_nodes; t2++ ) 03744 { 03745 if( points_are_coincident( coords1[t2], coords2[1] ) ) 03746 { 03747 /* cout <<"second("<<t2<<",1) - "; 03748 cout <<" coords1["<<t2<<"] = (" 03749 <<coords1[t2][0]<<"," 03750 <<coords1[t2][1]<<"," 03751 <<coords1[t2][2]<<") "; 03752 cout <<" coords2["<<1<<"] = (" 03753 <<coords2[1][0]<<"," 03754 <<coords2[1][1]<<"," 03755 <<coords2[1][2]<<")\n";*/ 03756 second = true; 03757 break; 03758 } 03759 } 03760 // TEST -- Find if second node is coincident before testing the rest. 03761 bool third = false; 03762 for( int ti = 0; ti < num_nodes; ti++ ) 03763 { 03764 if( points_are_coincident( coords1[ti], coords2[2] ) ) 03765 { 03766 /* cout <<"third("<<ti<<",2) - "; 03767 cout <<" coords1["<<ti<<"] = (" 03768 <<coords1[ti][0]<<"," 03769 <<coords1[ti][1]<<"," 03770 <<coords1[ti][2]<<") "; 03771 cout <<" coords2["<<1<<"] = (" 03772 <<coords2[2][0]<<"," 03773 <<coords2[2][1]<<"," 03774 <<coords2[2][2]<<")\n";*/ 03775 third = true; 03776 break; 03777 } 03778 } 03779 if( ( first ) && ( second ) && ( third ) ) 03780 { 03781 cout << "i = " << i << "\n"; 03782 for( int tii = 0; tii < num_nodes; tii++ ) 03783 { 03784 cout << " coords1[" << tii << "] = (" << coords1[tii][0] << "," << coords1[tii][1] << "," 03785 << coords1[tii][2] << ") "; 03786 cout << " coords2[" << tii << "] = (" << coords2[tii][0] << "," << coords2[tii][1] << "," 03787 << coords2[tii][2] << ")\n"; 03788 } 03789 } 03790 03791 if( i < num_nodes ) 03792 { 03793 for( ii = 1; ii < num_nodes; ii++ ) 03794 { 03795 if( gMB->get_coords( &( conn[ii] ), 1, coords2[ii] ) != MB_SUCCESS ) return MB_FAILURE; 03796 } 03797 /* 03798 for(j=1; j<num_nodes; j++) 03799 { 03800 03801 if(!points_are_coincident(coords1[j], coords2[(j+i)%num_nodes])) 03802 break; 03803 } 03804 if(j == num_nodes)*/ 03805 if( ( first ) && ( second ) && ( third ) ) 03806 { 03807 coincident_pair.first = *iter; 03808 coincident_pair.second = *jter; 03809 coin.push_back( coincident_pair ); 03810 } 03811 } 03812 } 03813 } 03814 } 03815 03816 return MB_SUCCESS; 03817 } 03818 03819 #ifdef MOAB_HAVE_NETCDF 03820 ErrorCode mb_merge_test() 03821 { 03822 Core moab; 03823 Interface* MB = &moab; 03824 03825 time_t begin_time = clock(); 03826 unsigned int i; 03827 ErrorCode result; 03828 Skinner Skinner_Obj( MB ); 03829 03830 std::string test_files[] = { std::string( "cell1.gen" ), std::string( "cell2.gen" ) }; 03831 /* std::string("cell3.gen"), 03832 std::string("cell4.gen"), 03833 std::string("cell5.gen"), 03834 std::string("cell6.gen"), 03835 std::string("cell7.gen"), 03836 std::string("cell8.gen"), 03837 std::string("cell9.gen"), 03838 std::string("cell10.gen"), 03839 std::string("cell11.gen"), 03840 std::string("cell12.gen"), 03841 std::string("cell13.gen"), 03842 std::string("cell14.gen"), 03843 std::string("cell15.gen"), 03844 std::string("cell16.gen"), 03845 std::string("cell17.gen"), 03846 std::string("cell18.gen"), 03847 std::string("cell19.gen"), 03848 std::string("cell20.gen"), 03849 std::string("cell21.gen"), 03850 std::string("cell22.gen"), 03851 std::string("cell23.gen"), 03852 std::string("cell24.gen")};*/ 03853 03854 /*std::vector<Range> entities(sizeof(test_files)); 03855 std::vector<Range> forward_lower(sizeof(test_files)); 03856 std::vector<Range> reverse_lower(sizeof(test_files)); 03857 std::vector<Range> nodes(sizeof(test_files));*/ 03858 Range entities; 03859 Range forward_lower; 03860 Range reverse_lower; 03861 Range faces; 03862 Range nodes; 03863 03864 cout << "---Starting Merge Tests---" << endl << endl; 03865 for( i = 0; i < ( sizeof( test_files ) / sizeof( std::string ) ); i++ ) 03866 { 03867 03868 cout << "---Testing:\"" << test_files[i] << "\"---" << endl; 03869 result = MB->load_mesh( test_files[i].c_str(), NULL, 0 ); 03870 if( result == MB_SUCCESS ) cout << "Loaded " << test_files[i] << "\n"; 03871 // get Hexes from model 03872 } 03873 result = MB->get_entities_by_type( 0, MBHEX, entities ); 03874 if( MB_SUCCESS != result ) return result; 03875 Skinner_Obj.find_skin( 0, entities, false, forward_lower, &reverse_lower ); 03876 // cout <<"num hexes = "<<entities.size()<<"\n"; 03877 // cout <<"fl = "<<forward_lower.size()<<" rl = "<<reverse_lower.size()<<"\n"; 03878 03879 // Range::const_iterator iter; 03880 int dim = 0; 03881 // int num_ents = 1; 03882 result = MB->get_adjacencies( forward_lower, dim, true, nodes, Interface::UNION ); 03883 // cout <<"nodes.size() = "<<nodes.size() <<"\n"; 03884 03885 // result = MB->get_entities_by_type(0, MBQUAD, faces); 03886 // cout <<"num faces = "<<faces.size() <<"\n"; 03887 03888 std::vector< std::pair< EntityHandle, EntityHandle > > coin_nodes; 03889 // cout <<"Begining sort...\n"; 03890 // std::sort(nodes.begin(),nodes.end(),lessnodesZ); 03891 // cout <<"Ending sort...\n"; 03892 result = find_coincident_nodes( MB, nodes, coin_nodes ); 03893 cout << "coin_nodes.size() = " << coin_nodes.size() << "\n"; 03894 std::vector< std::pair< EntityHandle, EntityHandle > >::iterator n_iter; 03895 for( n_iter = coin_nodes.begin(); n_iter != coin_nodes.end(); ++n_iter ) 03896 { 03897 result = MB->merge_entities( ( *n_iter ).first, ( *n_iter ).second, false, true ); 03898 if( MB_SUCCESS != result ) return result; 03899 } 03900 /* std::vector<std::pair<EntityHandle, EntityHandle> > coin_faces; 03901 int nodes_per_elt = 4; 03902 result = find_coincident_elements(forward_lower, nodes_per_elt, coin_faces); 03903 if (result != MB_SUCCESS) cout <<"find_coincident_elements fail!\n"; 03904 cout <<"coin_faces.size() = "<<coin_faces.size() <<"\n"; 03905 std::vector< std::pair<EntityHandle, EntityHandle> >::iterator f_iter; 03906 for (f_iter=coin_faces.begin(); f_iter != coin_faces.end(); ++f_iter) 03907 MB->merge_entities((*f_iter).first, (*f_iter).second, true, true);*/ 03908 /* 03909 std::vector<std::pair<EntityHandle, EntityHandle> > coin_fl; 03910 nodes_per_elt = 4; 03911 result = find_coincident_elements(entities, nodes_per_elt, coin_fl); 03912 cout <<"coin_fl.size() = "<<coin_fl.size() <<"\n"; 03913 */ 03914 int num_ents; 03915 if( ( MB_SUCCESS == MB->get_number_entities_by_dimension( 0, 3, num_ents ) && 0 != num_ents ) || 03916 ( MB_SUCCESS == MB->get_number_entities_by_dimension( 0, 2, num_ents ) && 0 != num_ents ) ) 03917 result = MB->write_mesh( "merge_test.g" ); 03918 ; 03919 03920 double clocks_per_sec = (double)CLOCKS_PER_SEC; 03921 double real_time = difftime( time( NULL ), begin_time ); 03922 cout << "TIME: " << ( real_time / clocks_per_sec ) << " seconds.\n"; 03923 return result; 03924 } 03925 #endif 03926 03927 ErrorCode mb_merge_update_test() 03928 { 03929 Core moab; 03930 Interface* mb = &moab; 03931 ErrorCode rval; 03932 03933 // create two quads with a coincident edge pair 03934 double coords[] = { 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 2, 0, 0, 2, 1, 0 }; 03935 EntityHandle verts[8]; 03936 for( int i = 0; i < 8; ++i ) 03937 mb->create_vertex( coords + 3 * i, verts[i] ); 03938 EntityHandle quad1, quad2, edge1, edge2; 03939 mb->create_element( MBQUAD, verts, 4, quad1 ); 03940 mb->create_element( MBQUAD, verts + 4, 4, quad2 ); 03941 mb->create_element( MBEDGE, verts + 1, 2, edge1 ); 03942 mb->create_element( MBEDGE, verts + 4, 2, edge2 ); 03943 03944 // create two tracking sets containing the vertices 03945 // and edge of each quad 03946 EntityHandle set1, set2; 03947 mb->create_meshset( MESHSET_TRACK_OWNER | MESHSET_SET, set1 ); 03948 mb->create_meshset( MESHSET_TRACK_OWNER | MESHSET_ORDERED, set2 ); 03949 mb->add_entities( set1, verts, 4 ); 03950 mb->add_entities( set2, verts + 4, 4 ); 03951 mb->add_entities( set1, &edge1, 1 ); 03952 mb->add_entities( set2, &edge2, 1 ); 03953 03954 // now merge the coincident edges 03955 rval = mb->merge_entities( verts[1], verts[5], false, true ); 03956 if( MB_SUCCESS != rval ) 03957 { 03958 std::cerr << "Merge failed at " << __FILE__ << ":" << __LINE__ << std::endl; 03959 return rval; 03960 } 03961 rval = mb->merge_entities( verts[2], verts[4], false, true ); 03962 if( MB_SUCCESS != rval ) 03963 { 03964 std::cerr << "Merge failed at " << __FILE__ << ":" << __LINE__ << std::endl; 03965 return rval; 03966 } 03967 rval = mb->merge_entities( edge1, edge2, false, true ); 03968 if( MB_SUCCESS != rval ) 03969 { 03970 std::cerr << "Merge failed at " << __FILE__ << ":" << __LINE__ << std::endl; 03971 return rval; 03972 } 03973 03974 // check that there is only one edge and that it has the correct connectivity 03975 Range r; 03976 mb->get_entities_by_type( 0, MBEDGE, r ); 03977 if( r.size() != 1 || r.front() != edge1 ) 03978 { 03979 std::cerr << "Edge merge failed at " << __FILE__ << ":" << __LINE__ << std::endl; 03980 return MB_FAILURE; 03981 } 03982 std::vector< EntityHandle > exp( verts + 1, verts + 3 ), act; 03983 mb->get_connectivity( &edge1, 1, act ); 03984 if( exp != act ) 03985 { 03986 std::cerr << "Incorrect conn for edge at " << __FILE__ << ":" << __LINE__ << std::endl; 03987 return MB_FAILURE; 03988 } 03989 03990 // check that quad connectivity is as expected 03991 exp = std::vector< EntityHandle >( verts, verts + 4 ); 03992 act.clear(); 03993 mb->get_connectivity( &quad1, 1, act ); 03994 if( exp != act ) 03995 { 03996 std::cerr << "Incorrect conn for quad at " << __FILE__ << ":" << __LINE__ << std::endl; 03997 return MB_FAILURE; 03998 } 03999 exp.resize( 4 ); 04000 exp[0] = verts[2]; 04001 exp[1] = verts[1]; 04002 exp[2] = verts[6]; 04003 exp[3] = verts[7]; 04004 act.clear(); 04005 mb->get_connectivity( &quad2, 1, act ); 04006 if( exp != act ) 04007 { 04008 std::cerr << "Incorrect conn for quad at " << __FILE__ << ":" << __LINE__ << std::endl; 04009 return MB_FAILURE; 04010 } 04011 04012 // check that set contents are correctly updated 04013 exp = std::vector< EntityHandle >( verts, verts + 4 ); 04014 exp.push_back( edge1 ); 04015 act.clear(); 04016 mb->get_entities_by_handle( set1, act ); 04017 std::sort( exp.begin(), exp.end() ); 04018 std::sort( act.begin(), act.end() ); 04019 if( exp != act ) 04020 { 04021 std::cerr << "Incorrect set contents at " << __FILE__ << ":" << __LINE__ << std::endl; 04022 std::cerr << " Expected: "; 04023 std::copy( exp.begin(), exp.end(), std::ostream_iterator< EntityHandle >( std::cerr, " " ) ); 04024 std::cerr << std::endl << " Actual : "; 04025 std::copy( act.begin(), act.end(), std::ostream_iterator< EntityHandle >( std::cerr, " " ) ); 04026 std::cerr << std::endl; 04027 return MB_FAILURE; 04028 } 04029 04030 exp.resize( 5 ); 04031 exp[0] = verts[2]; 04032 exp[1] = verts[1]; 04033 exp[2] = verts[6]; 04034 exp[3] = verts[7]; 04035 exp[4] = edge1; 04036 act.clear(); 04037 mb->get_entities_by_handle( set2, act ); 04038 if( exp != act ) 04039 { 04040 std::cerr << "Incorrect set contents at " << __FILE__ << ":" << __LINE__ << std::endl; 04041 std::cerr << " Expected: "; 04042 std::copy( exp.begin(), exp.end(), std::ostream_iterator< EntityHandle >( std::cerr, " " ) ); 04043 std::cerr << std::endl << " Actual : "; 04044 std::copy( act.begin(), act.end(), std::ostream_iterator< EntityHandle >( std::cerr, " " ) ); 04045 std::cerr << std::endl; 04046 return MB_FAILURE; 04047 } 04048 04049 return MB_SUCCESS; 04050 } 04051 #ifdef MOAB_HAVE_NETCDF 04052 ErrorCode mb_stress_test() 04053 { 04054 ErrorCode error; 04055 Core moab; 04056 Interface* MB = &moab; 04057 04058 cout << " Beginning Stress Test . . ." << endl; 04059 cout << "\n Reading elements" << endl; 04060 clock_t start = clock(); 04061 clock_t total_start = clock(); 04062 04063 // read in a file so you have some data in the database 04064 std::string file_name = "mb_big_test.g"; 04065 error = MB->load_mesh( file_name.c_str(), NULL, 0 ); 04066 if( error != MB_SUCCESS ) return error; 04067 04068 clock_t stop = clock(); 04069 04070 int num_entities_local; 04071 error = MB->get_number_entities_by_type( 0, MBHEX, num_entities_local ); 04072 if( error != MB_SUCCESS ) return error; 04073 04074 if( num_entities_local != 256000 ) return error; 04075 04076 float time = static_cast< float >( stop - start ) / CLOCKS_PER_SEC; 04077 float speed = num_entities_local / time; 04078 cout << " Read " << num_entities_local << " entities" 04079 << " in " << time << " seconds" << endl; 04080 cout << " at " << speed << " elements per second." << endl; 04081 04082 cout << "\n Transforming and copying elements" << endl; 04083 start = clock(); 04084 04085 Range hexes; 04086 error = MB->get_entities_by_type( 0, MBHEX, hexes ); 04087 if( error != MB_SUCCESS ) return error; 04088 04089 std::vector< EntityHandle > conn; 04090 Range::iterator iter; 04091 for( iter = hexes.begin(); iter != hexes.end(); ++iter ) 04092 { 04093 error = MB->get_connectivity( &( *iter ), 1, conn ); 04094 if( error != MB_SUCCESS ) return error; 04095 04096 double coords[3]; 04097 int i = 0; 04098 std::vector< EntityHandle > vertex_handle( 8 ); 04099 EntityHandle element_handle; 04100 std::vector< EntityHandle >::iterator jter; 04101 04102 for( jter = conn.begin(); jter != conn.end(); ++jter ) 04103 { 04104 error = MB->get_coords( &( *jter ), 1, coords ); 04105 if( error != MB_SUCCESS ) return error; 04106 coords[2] += 20.0; 04107 error = MB->create_vertex( coords, vertex_handle[i++] ); 04108 if( error != MB_SUCCESS ) return error; 04109 } 04110 error = MB->create_element( MBHEX, &vertex_handle[0], 8, element_handle ); 04111 if( error != MB_SUCCESS ) return error; 04112 } 04113 04114 stop = clock(); 04115 time = static_cast< float >( stop - start ) / CLOCKS_PER_SEC; 04116 04117 cout << " Transformed and created " << num_entities_local << " entities" 04118 << " in " << time << " seconds" << endl; 04119 04120 // Create mesh set 04121 cout << "\n Creating meshset" << endl; 04122 start = clock(); 04123 error = MB->get_entities_by_type( 0, MBHEX, hexes ); 04124 if( error != MB_SUCCESS ) return error; 04125 04126 if( hexes.size() != 512000 ) return MB_FAILURE; 04127 04128 EntityHandle mesh_set; 04129 error = MB->create_meshset( MESHSET_SET, mesh_set ); 04130 if( error != MB_SUCCESS ) return error; 04131 04132 error = MB->add_entities( mesh_set, hexes ); 04133 if( error != MB_SUCCESS ) return error; 04134 04135 stop = clock(); 04136 time = static_cast< float >( stop - start ) / CLOCKS_PER_SEC; 04137 04138 cout << " Created meshset with " << hexes.size() << " entities" 04139 << " in " << time << " seconds" << endl; 04140 04141 cout << "\n Writing 512K element file . . ." << endl; 04142 start = clock(); 04143 04144 // set the block tag 04145 Tag tag_handle; 04146 ErrorCode result = MB->tag_get_handle( MATERIAL_SET_TAG_NAME, 1, MB_TYPE_INTEGER, tag_handle ); 04147 if( result != MB_SUCCESS ) return result; 04148 04149 int id = 1; 04150 result = MB->tag_set_data( tag_handle, &mesh_set, 1, &id ); 04151 if( result != MB_SUCCESS ) return result; 04152 04153 std::vector< EntityHandle > output_list; 04154 output_list.push_back( mesh_set ); 04155 04156 file_name = "mb_stress_out.g"; 04157 error = MB->write_mesh( file_name.c_str(), &output_list[0], output_list.size() ); 04158 if( error != MB_SUCCESS ) return error; 04159 04160 stop = clock(); 04161 time = static_cast< float >( stop - start ) / CLOCKS_PER_SEC; 04162 04163 cout << " Wrote file with " << hexes.size() << " entities" 04164 << " in " << time << " seconds" << endl; 04165 04166 clock_t total_stop = clock(); 04167 time = static_cast< float >( total_stop - total_start ) / CLOCKS_PER_SEC; 04168 04169 cout << " Total time: " << time << " seconds." << endl; 04170 04171 MB->delete_mesh(); 04172 04173 return MB_SUCCESS; 04174 } 04175 #endif 04176 04177 ErrorCode mb_canon_number_test() 04178 { 04179 Core moab; 04180 Interface* MB = &moab; 04181 04182 // various tests for canonical ordering 04183 04184 // CN::AdjacentSubEntities 04185 std::vector< int > vec1, vec2; 04186 ErrorCode result; 04187 04188 EntityType this_type; 04189 04190 for( this_type = MBEDGE; this_type != MBKNIFE; this_type++ ) 04191 { 04192 04193 for( int i = 0; i < CN::VerticesPerEntity( this_type ); i++ ) 04194 { 04195 // test for edges and faces 04196 for( int dim = 1; dim <= CN::Dimension( this_type ); dim++ ) 04197 { 04198 // get the sides adjacent to this vertex 04199 vec1.clear(); 04200 int temp_result = CN::AdjacentSubEntities( this_type, &i, 1, 0, dim, vec1 ); 04201 04202 if( 0 != temp_result || vec1.size() > (unsigned int)CN::NumSubEntities( this_type, dim ) ) 04203 { 04204 cout << "failed getting sides for type " << CN::EntityTypeName( this_type ) << " dimension" << dim 04205 << endl; 04206 return MB_FAILURE; 04207 } 04208 04209 // now get the vertices shared by these sides 04210 vec2.clear(); 04211 temp_result = CN::AdjacentSubEntities( this_type, &vec1[0], vec1.size(), dim, 0, vec2 ); 04212 04213 // vertex side recovered should be i 04214 if( 0 != temp_result || 04215 // if dimension is same as DIMENSION(this_type), will get back all the 04216 // vertices in the entity 04217 ( dim == CN::Dimension( this_type ) && 04218 vec2.size() != (unsigned int)CN::VerticesPerEntity( this_type ) ) || 04219 // otherwise, we should get back only one vertex, and it should be the one 04220 // we started with 04221 ( dim != CN::Dimension( this_type ) && ( vec2.size() != 1 || vec2[0] != i ) ) ) 04222 { 04223 cout << "traversal from verts to sides to verts failed for " << endl 04224 << "vertex " << i << " type " << CN::EntityTypeName( this_type ) << " dimension " << dim 04225 << endl; 04226 return MB_FAILURE; 04227 } 04228 } 04229 } 04230 } 04231 04232 // CN::side_number 04233 04234 // create vertices to use later 04235 double xyz[3] = { 0.0, 0.0, 0.0 }; 04236 EntityHandle vertex_handles[8]; 04237 for( int i = 0; i < 8; i++ ) 04238 { 04239 result = MB->create_vertex( xyz, vertex_handles[i] ); 04240 assert( result == MB_SUCCESS ); 04241 } 04242 int side, sense, offset; 04243 04244 EntityHandle this_entity; 04245 04246 for( this_type = MBEDGE; this_type != MBKNIFE; this_type++ ) 04247 { 04248 04249 // skip remainder of the loop for MBPOLYGONS and POLYHEDRA, which don't follow 04250 // the standard canonical ordering 04251 if( this_type == MBPOLYGON || this_type == MBPOLYHEDRON ) continue; 04252 04253 // make an entity of this type 04254 result = MB->create_element( this_type, vertex_handles, CN::VerticesPerEntity( this_type ), this_entity ); 04255 if( MB_SUCCESS != result || 0 == this_entity ) 04256 { 04257 cout << "failed to create entity of type " << CN::EntityTypeName( this_type ) << endl; 04258 return MB_FAILURE; 04259 } 04260 04261 // now get the connectivity vector * 04262 const EntityHandle* entity_vertices; 04263 int num_verts; 04264 result = MB->get_connectivity( this_entity, entity_vertices, num_verts ); 04265 if( MB_SUCCESS != result || num_verts != CN::VerticesPerEntity( this_type ) ) 04266 { 04267 cout << "failed to get connectivity for entity type " << CN::EntityTypeName( this_type ) << endl; 04268 return MB_FAILURE; 04269 } 04270 04271 // for each dimension 04272 for( int dim = 1; dim <= CN::Dimension( this_type ); dim++ ) 04273 { 04274 // for each side of this dimension 04275 const CN::ConnMap& cm = CN::mConnectivityMap[this_type][dim - 1]; 04276 int tmp_conn[moab::MAX_SUB_ENTITY_VERTICES]; 04277 04278 for( int side_no = 0; side_no < CN::NumSubEntities( this_type, dim ); side_no++ ) 04279 { 04280 04281 for( int j = 0; j < moab::MAX_SUB_ENTITY_VERTICES; j++ ) 04282 tmp_conn[j] = cm.conn[side_no][j]; 04283 int temp_result = CN::SideNumber( this_type, tmp_conn, 04284 CN::VerticesPerEntity( CN::SubEntityType( this_type, dim, side_no ) ), 04285 dim, side, sense, offset ); 04286 if( 0 != temp_result ) 04287 { 04288 cout << "call to CN::side_number failed with non-success result" 04289 << " for type " << CN::EntityTypeName( this_type ) << " dimension " << dim << " side no " 04290 << side_no << endl; 04291 return MB_FAILURE; 04292 } 04293 04294 // side number should be the same as side_no, sense should be forward, offset should 04295 // be zero 04296 if( side != side_no || sense != 1 || offset != 0 ) 04297 { 04298 cout << "call to CN::side_number failed for type " << CN::EntityTypeName( this_type ) 04299 << " dimension " << dim << " side no " << side_no << endl 04300 << "side, sense, offset = " << side << " " << sense << " " << offset << endl; 04301 return MB_FAILURE; 04302 } 04303 } 04304 } 04305 04306 // destroy the entity of this_type 04307 result = MB->delete_entities( &this_entity, 1 ); 04308 if( MB_SUCCESS != result ) return result; 04309 } 04310 04311 return MB_SUCCESS; 04312 } 04313 ErrorCode mb_side_number_test() 04314 { 04315 ErrorCode rval; 04316 Core moab; 04317 Interface* mb = &moab; 04318 04319 /* Create faces of a wedge: */ 04320 /* 04321 4 04322 /|\ 04323 / | \ 04324 / | \ 04325 / 2 \ 04326 3.../.\...5 04327 | / \ | 04328 | / \ | 04329 |/ \| 6 // off vertex 04330 0_________1 04331 */ 04332 04333 const double coords[][3] = { 04334 { 0, 0, 0 }, { 2, 0, 0 }, { 1, 0, 1 }, { 0, 2, 0 }, { 2, 2, 0 }, { 1, 2, 1 }, { 3, 1, 0 }, 04335 }; 04336 EntityHandle verts[7]; 04337 for( unsigned i = 0; i < 7; ++i ) 04338 mb->create_vertex( coords[i], verts[i] ); 04339 04340 EntityHandle faces[6]; 04341 EntityHandle tri[] = { verts[0], verts[1], verts[2] }; 04342 EntityHandle tri2[] = { verts[3], verts[4], verts[5] }; 04343 EntityHandle quad1[] = { verts[0], verts[1], verts[5], verts[3] }; 04344 EntityHandle quad2[] = { verts[1], verts[5], verts[4], verts[2] }; 04345 EntityHandle quad3[] = { verts[2], verts[4], verts[3], verts[0] }; 04346 rval = mb->create_element( MBTRI, tri, 3, faces[0] );MB_CHK_ERR( rval ); 04347 rval = mb->create_element( MBQUAD, quad1, 4, faces[1] );MB_CHK_ERR( rval ); 04348 rval = mb->create_element( MBQUAD, quad2, 4, faces[2] );MB_CHK_ERR( rval ); 04349 rval = mb->create_element( MBQUAD, quad3, 4, faces[3] );MB_CHK_ERR( rval ); 04350 rval = mb->create_element( MBTRI, tri2, 3, faces[4] );MB_CHK_ERR( rval ); 04351 04352 EntityHandle prism; 04353 rval = mb->create_element( MBPRISM, verts, 6, prism );MB_CHK_ERR( rval ); 04354 04355 /* 04356 * side_number(const EntityHandle parent, 04357 const EntityHandle child, 04358 int &side_number, 04359 int &sense, 04360 int &offset) 04361 */ 04362 int side_n, sen, ofs; 04363 rval = mb->side_number( prism, faces[0], side_n, sen, ofs );MB_CHK_ERR( rval ); 04364 CHECK_EQUAL( side_n, 3 ); 04365 CHECK_EQUAL( sen, -1 ); 04366 CHECK_EQUAL( ofs, 0 ); 04367 04368 // this diagonal should not be on the prism (not an edge of the prism) 04369 EntityHandle diagonal1; 04370 EntityHandle diag[] = { verts[2], verts[3] }; 04371 rval = mb->create_element( MBEDGE, diag, 2, diagonal1 );MB_CHK_ERR( rval ); 04372 rval = mb->side_number( prism, diagonal1, side_n, sen, ofs ); 04373 // expected fail 04374 if( rval != MB_FAILURE ) return MB_FAILURE; 04375 04376 // create another triangle, connected to the prism, but not on the side 04377 EntityHandle tri3[] = { verts[3], verts[4], verts[6] }; 04378 rval = mb->create_element( MBTRI, tri3, 3, faces[5] );MB_CHK_ERR( rval ); 04379 rval = mb->side_number( prism, faces[5], side_n, sen, ofs ); 04380 // expected fail 04381 if( rval != MB_FAILURE ) return MB_FAILURE; 04382 04383 return MB_SUCCESS; 04384 } 04385 04386 ErrorCode mb_poly_test() 04387 { 04388 Core moab; 04389 Interface* mb = &moab; 04390 04391 // test polygon and polyhedron representation 04392 // create a couple of polygons; vertices first 04393 const double vert_pos[48] = { -1, 0, 0, 1, 0, 0, 2, 0, 0, 2, 1, 0, 1, 1, 0, 0, 04394 2, 0, -1, 1, 0, -2, 1, 0, -2, 0, 0, -2, -1, 0, -1, -1, 04395 0, -1, -2, 0, 1, -2, 0, 1, -1, 0, 2, -1, 0, 1.5, .5, 1 }; 04396 04397 EntityHandle verts[16]; 04398 ErrorCode result; 04399 int i; 04400 for( i = 0; i < 16; i++ ) 04401 { 04402 result = mb->create_vertex( &vert_pos[3 * i], verts[i] ); 04403 if( MB_SUCCESS != result ) 04404 { 04405 std::cout << "Failed to create vertex " << i << " in mb_poly_test." << std::endl; 04406 return result; 04407 } 04408 } 04409 04410 // then polygons 04411 const int connect_idx[] = { 1, 2, 5, 6, 7, 2, 3, 4, 5, 5, 4, 6, 7, 6, 8, 0, 1, 7, 8, 0, 1, 2, 3, 14, 04412 13, 12, 11, 10, 9, 0, 9, 10, 11, 12, 13, 14, 3, 4, 6, 8, 2, 3, 15, 5, 3, 4, 5, 15 }; 04413 04414 int num_connect_idx[] = { 5, 4, 3, 3, 4, 10, 11, 4, 4 }; 04415 04416 EntityHandle polygons[9], temp_connect[12]; 04417 int idx = 0, nump = 0; 04418 ErrorCode tmp_result; 04419 while( nump < 9 ) 04420 { 04421 for( i = 0; i < num_connect_idx[nump]; i++ ) 04422 temp_connect[i] = verts[connect_idx[idx + i]]; 04423 04424 tmp_result = mb->create_element( MBPOLYGON, temp_connect, num_connect_idx[nump], polygons[nump] ); 04425 if( MB_SUCCESS != tmp_result ) 04426 { 04427 std::cout << "mb_poly_test: create_element failed for polygon " << i << "." << std::endl; 04428 result = tmp_result; 04429 nump++; 04430 continue; 04431 } 04432 04433 idx += num_connect_idx[nump]; 04434 nump++; 04435 } 04436 04437 if( MB_SUCCESS != result ) return result; 04438 04439 // ok, made 'em; now get all the vertices and make sure they're the same 04440 const EntityHandle* connect; 04441 int num_connect; 04442 idx = 0; 04443 int j; 04444 for( i = 0; i < 9; i++ ) 04445 { 04446 tmp_result = mb->get_connectivity( polygons[i], connect, num_connect ); 04447 if( MB_SUCCESS != tmp_result || num_connect != num_connect_idx[i] ) 04448 { 04449 std::cout << "mb_poly_test: get_connectivity test failed for polygon " << i << "." << std::endl; 04450 result = ( tmp_result != MB_SUCCESS ? tmp_result : MB_FAILURE ); 04451 continue; 04452 } 04453 04454 for( j = 0; j < num_connect; j++ ) 04455 { 04456 if( connect[j] != verts[connect_idx[idx + j]] ) 04457 { 04458 std::cout << "mb_poly_test: get_connectivity test returned wrong vertices for polygon " << i << "." 04459 << std::endl; 04460 result = MB_FAILURE; 04461 continue; 04462 } 04463 } 04464 04465 idx += num_connect; 04466 } 04467 04468 if( MB_SUCCESS != result ) return result; 04469 04470 // check a different way, with ranges 04471 Range vert_range, poly_range; 04472 for( i = 0; i < 9; i++ ) 04473 poly_range.insert( polygons[i] ); 04474 result = mb->get_adjacencies( poly_range, 0, false, vert_range, Interface::UNION ); 04475 if( MB_SUCCESS != result ) 04476 { 04477 std::cout << "mb_poly_test: get_adjacencies failed for polygon " << i << "." << std::endl; 04478 return result; 04479 } 04480 04481 else if( vert_range.size() != 16 ) 04482 { 04483 std::cout << "mb_poly_test: get_adjacencies returned wrong # of vertices for polygon " << i << "." << std::endl; 04484 return MB_FAILURE; 04485 } 04486 04487 // make a couple polyhedra 04488 EntityHandle polyhedra[2]; 04489 result = mb->create_element( MBPOLYHEDRON, polygons, 7, polyhedra[0] ); 04490 if( MB_SUCCESS != result ) 04491 { 04492 std::cout << "mb_poly_test: create_element failed for polyhedron 1." << std::endl; 04493 return result; 04494 } 04495 04496 temp_connect[0] = polygons[1]; 04497 temp_connect[1] = polygons[7]; 04498 temp_connect[2] = polygons[8]; 04499 result = mb->create_element( MBPOLYHEDRON, temp_connect, 3, polyhedra[1] ); 04500 if( MB_SUCCESS != result ) 04501 { 04502 std::cout << "mb_poly_test: create_element failed for polyhedron 2." << std::endl; 04503 return result; 04504 } 04505 04506 // now look for vertices common to both 04507 std::vector< EntityHandle > temp_verts; 04508 result = mb->get_adjacencies( polyhedra, 2, 0, false, temp_verts ); 04509 if( MB_SUCCESS != result ) 04510 { 04511 std::cout << "mb_poly_test: get_adjacencies failed for polyhedra." << std::endl; 04512 return result; 04513 } 04514 04515 if( 4 != temp_verts.size() ) 04516 { 04517 std::cout << "mb_poly_test: get_adjacencies for polyhedra returned " << temp_verts.size() 04518 << " vertices, should be 4." << std::endl; 04519 return MB_FAILURE; 04520 } 04521 04522 // ok, we're probably fine 04523 return MB_SUCCESS; 04524 } 04525 04526 ErrorCode mb_topo_util_test() 04527 { 04528 Core moab; 04529 Interface* gMB = &moab; 04530 MeshTopoUtil mtu( gMB ); 04531 04532 // construct a four-hex mesh for testing purposes 04533 double grid_vert_pos[] = { 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 2.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 2.0, 1.0, 0.0, 04534 0.0, 2.0, 0.0, 1.0, 2.0, 0.0, 2.0, 2.0, 0.0, 04535 // 04536 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 2.0, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, 1.0, 1.0, 04537 0.0, 2.0, 1.0, 1.0, 2.0, 1.0, 2.0, 2.0, 1.0 }; 04538 04539 EntityHandle grid_verts[18], grid_elems[4]; 04540 ErrorCode result; 04541 #define RR \ 04542 if( result != MB_SUCCESS ) return result 04543 int init_edges, init_faces; 04544 result = gMB->get_number_entities_by_dimension( 0, 1, init_edges );RR; 04545 result = gMB->get_number_entities_by_dimension( 0, 2, init_faces );RR; 04546 04547 // make vertices 04548 for( int i = 0; i < 18; i++ ) 04549 { 04550 result = gMB->create_vertex( &grid_vert_pos[3 * i], grid_verts[i] );RR; 04551 } 04552 04553 // make hexes 04554 int numv = 3, numv_sq = 9; 04555 #define VINDEX( i, j, k ) ( ( i ) + ( (j)*numv ) + ( (k)*numv_sq ) ) 04556 EntityHandle connect[8]; 04557 for( int j = 0; j < 2; j++ ) 04558 { 04559 for( int i = 0; i < 2; i++ ) 04560 { 04561 int vijk = VINDEX( i, j, 0 ); 04562 connect[0] = grid_verts[vijk]; 04563 connect[1] = grid_verts[vijk + 1]; 04564 connect[2] = grid_verts[vijk + 1 + numv]; 04565 connect[3] = grid_verts[vijk + numv]; 04566 connect[4] = grid_verts[vijk + numv * numv]; 04567 connect[5] = grid_verts[vijk + 1 + numv * numv]; 04568 connect[6] = grid_verts[vijk + 1 + numv + numv * numv]; 04569 connect[7] = grid_verts[vijk + numv + numv * numv]; 04570 result = gMB->create_element( MBHEX, connect, 8, grid_elems[2 * j + i] );RR; 04571 } 04572 } 04573 04574 Range vert_range; 04575 std::copy( grid_verts, grid_verts + 18, range_inserter( vert_range ) ); 04576 04577 // generate aentities 04578 result = mtu.construct_aentities( vert_range );RR; 04579 04580 int this_edges, this_faces; 04581 result = gMB->get_number_entities_by_dimension( 0, 1, this_edges );RR; 04582 result = gMB->get_number_entities_by_dimension( 0, 2, this_faces );RR; 04583 04584 if( this_edges != init_edges + 33 || this_faces != init_faces + 20 ) 04585 { 04586 std::cout << "Wrong number of edges or faces in mb_topo_util test." << std::endl; 04587 // return MB_FAILURE; 04588 } 04589 04590 // get average position 04591 double pos[3]; 04592 for( int j = 0; j < 2; j++ ) 04593 { 04594 for( int i = 0; i < 2; i++ ) 04595 { 04596 result = mtu.get_average_position( grid_elems[2 * j + i], pos );RR; 04597 if( pos[0] != .5 + i || pos[1] != .5 + j || pos[2] != .5 ) 04598 { 04599 std::cout << "Wrong position at i = " << i << ", j = " << j << std::endl; 04600 result = MB_FAILURE; 04601 } 04602 } 04603 } 04604 RR; 04605 04606 // get star faces 04607 Range all_hexes, middle_edge; 04608 std::copy( grid_elems, grid_elems + 4, range_inserter( all_hexes ) ); 04609 // get the shared edge 04610 result = gMB->get_adjacencies( all_hexes, 1, false, middle_edge ); 04611 if( MB_SUCCESS != result || 1 != middle_edge.size() ) 04612 { 04613 std::cout << "Bad result getting single shared edge." << std::endl; 04614 return MB_FAILURE; 04615 } 04616 04617 std::vector< EntityHandle > star_faces, star_hexes; 04618 bool bdy_edge; 04619 result = mtu.star_entities( *middle_edge.begin(), star_faces, bdy_edge, 0, &star_hexes ); 04620 if( MB_SUCCESS != result || bdy_edge || star_faces.size() != 4 || star_hexes.size() != 4 ) 04621 { 04622 std::cout << "Bad result from star_faces for non-bdy edge." << std::endl; 04623 return MB_FAILURE; 04624 } 04625 04626 // now try for a different edge, which has to be on the bdy 04627 Range other_edges; 04628 all_hexes.clear(); 04629 all_hexes.insert( grid_elems[0] ); 04630 result = gMB->get_adjacencies( all_hexes, 1, false, other_edges );RR; 04631 other_edges.erase( *middle_edge.begin() ); 04632 if( 11 != other_edges.size() ) 04633 { 04634 std::cout << "Wrong number of edges in hex." << std::endl; 04635 return MB_FAILURE; 04636 } 04637 star_faces.clear(); 04638 star_hexes.clear(); 04639 result = mtu.star_entities( *other_edges.begin(), star_faces, bdy_edge, 0, &star_hexes ); 04640 if( MB_SUCCESS != result || !bdy_edge || ( star_faces.size() != 2 && star_faces.size() != 3 ) || 04641 ( star_hexes.size() != 1 && star_hexes.size() != 2 ) ) 04642 { 04643 std::cout << "Bad result from star_faces for bdy edge." << std::endl; 04644 return MB_FAILURE; 04645 } 04646 04647 return MB_SUCCESS; 04648 } 04649 04650 ErrorCode mb_split_test() 04651 { 04652 Core moab; 04653 Interface* gMB = &moab; 04654 MeshTopoUtil mtu( gMB ); 04655 04656 // construct a four-hex mesh for testing purposes 04657 double grid_vert_pos[] = { 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 2.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 2.0, 1.0, 0.0, 04658 0.0, 2.0, 0.0, 1.0, 2.0, 0.0, 2.0, 2.0, 0.0, 04659 // 04660 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 2.0, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, 1.0, 1.0, 04661 0.0, 2.0, 1.0, 1.0, 2.0, 1.0, 2.0, 2.0, 1.0, 04662 // 04663 0.0, 0.0, 2.0, 1.0, 0.0, 2.0, 2.0, 0.0, 2.0, 0.0, 1.0, 2.0, 1.0, 1.0, 2.0, 2.0, 1.0, 2.0, 04664 0.0, 2.0, 2.0, 1.0, 2.0, 2.0, 2.0, 2.0, 2.0 }; 04665 04666 EntityHandle grid_verts[27], grid_elems[8]; 04667 ErrorCode result; 04668 #define RR \ 04669 if( result != MB_SUCCESS ) return result 04670 int init_edges, init_faces, init_regions; 04671 result = gMB->get_number_entities_by_dimension( 0, 1, init_edges );RR; 04672 result = gMB->get_number_entities_by_dimension( 0, 2, init_faces );RR; 04673 result = gMB->get_number_entities_by_dimension( 0, 3, init_regions );RR; 04674 04675 // make vertices 04676 for( int i = 0; i < 27; i++ ) 04677 { 04678 result = gMB->create_vertex( &grid_vert_pos[3 * i], grid_verts[i] );RR; 04679 } 04680 04681 // make hexes 04682 int numv = 3, numv_sq = 9; 04683 #define VINDEX( i, j, k ) ( ( i ) + ( (j)*numv ) + ( (k)*numv_sq ) ) 04684 EntityHandle connect[8]; 04685 for( int k = 0; k < 2; k++ ) 04686 { 04687 for( int j = 0; j < 2; j++ ) 04688 { 04689 for( int i = 0; i < 2; i++ ) 04690 { 04691 int vijk = VINDEX( i, j, k ); 04692 connect[0] = grid_verts[vijk]; 04693 connect[1] = grid_verts[vijk + 1]; 04694 connect[2] = grid_verts[vijk + 1 + numv]; 04695 connect[3] = grid_verts[vijk + numv]; 04696 connect[4] = grid_verts[vijk + numv * numv]; 04697 connect[5] = grid_verts[vijk + 1 + numv * numv]; 04698 connect[6] = grid_verts[vijk + 1 + numv + numv * numv]; 04699 connect[7] = grid_verts[vijk + numv + numv * numv]; 04700 result = gMB->create_element( MBHEX, connect, 8, grid_elems[4 * k + 2 * j + i] );RR; 04701 } 04702 } 04703 } 04704 04705 Range vert_range; 04706 std::copy( grid_verts, grid_verts + 27, range_inserter( vert_range ) ); 04707 04708 // generate aentities 04709 result = mtu.construct_aentities( vert_range );RR; 04710 04711 int this_edges, this_faces; 04712 result = gMB->get_number_entities_by_dimension( 0, 1, this_edges );RR; 04713 result = gMB->get_number_entities_by_dimension( 0, 2, this_faces );RR; 04714 04715 if( this_edges != init_edges + 54 || this_faces != init_faces + 36 ) 04716 { 04717 std::cout << "Wrong number of edges or faces in mb_topo_util test." << std::endl; 04718 return MB_FAILURE; 04719 } 04720 04721 // split the faces between the 2 layers 04722 // first get the faces 04723 Range split_faces, tmp_ents, tmp_faces; 04724 for( int i = 0; i < 4; i++ ) 04725 { 04726 tmp_ents.clear(); 04727 tmp_ents.insert( grid_elems[i] ); 04728 tmp_ents.insert( grid_elems[i + 4] ); 04729 tmp_faces.clear(); 04730 result = gMB->get_adjacencies( tmp_ents, 2, false, tmp_faces ); 04731 if( MB_SUCCESS != result || tmp_faces.size() != 1 ) 04732 { 04733 std::cout << "mb_split_test failed to get shared quad." << std::endl; 04734 return MB_FAILURE; 04735 } 04736 split_faces.insert( *tmp_faces.begin() ); 04737 } 04738 04739 Range new_faces, new_regions; 04740 04741 // NOTE: passing in non-NULL pointer for new_regions requests that region between the 04742 // split entities be filled with an element; in this case, since we're splitting faces, 04743 // the new entities are polyhedra 04744 result = mtu.split_entities_manifold( split_faces, new_faces, &new_regions ); 04745 if( MB_SUCCESS != result || new_faces.size() != 4 || new_regions.size() != 4 ) 04746 { 04747 std::cout << "mb_split_test failed to split quads." << std::endl; 04748 return MB_FAILURE; 04749 } 04750 04751 int this_regions; 04752 result = gMB->get_number_entities_by_dimension( 0, 1, this_edges );RR; 04753 result = gMB->get_number_entities_by_dimension( 0, 2, this_faces );RR; 04754 result = gMB->get_number_entities_by_dimension( 0, 3, this_regions );RR; 04755 04756 if( this_edges != init_edges + 54 || this_faces != init_faces + 40 || this_regions != init_regions + 12 ) 04757 { 04758 std::cout << "Wrong number of edges or faces or regions after splitting in mb_topo_util test." << std::endl; 04759 return MB_FAILURE; 04760 } 04761 04762 return MB_SUCCESS; 04763 } 04764 04765 ErrorCode mb_range_seq_intersect_test() 04766 { 04767 ErrorCode rval; 04768 SequenceManager sequences; 04769 RangeSeqIntersectIter iter( &sequences ); 04770 Range range; 04771 04772 // create some entity sequences 04773 EntitySequence *ts1, *ts2, *ts3, *qs1; 04774 EntityHandle th1, th2, th3, qh1; 04775 const int nt1 = 100, nt2 = 10, nt3 = 1, nq1 = 20; 04776 rval = sequences.create_entity_sequence( MBTRI, nt1, 3, 5, th1, ts1, -1 ); 04777 if( MB_SUCCESS != rval ) return rval; 04778 rval = sequences.create_entity_sequence( MBTRI, nt2, 6, 0, th2, ts2, -1 ); 04779 if( MB_SUCCESS != rval ) return rval; 04780 rval = sequences.create_entity_sequence( MBTRI, nt3, 3, MB_END_ID, th3, ts3, -1 ); 04781 if( MB_SUCCESS != rval ) return rval; 04782 rval = sequences.create_entity_sequence( MBQUAD, nq1, 4, 0, qh1, qs1, -1 ); 04783 if( MB_SUCCESS != rval ) return rval; 04784 04785 // we're going to assume this below, so verify it now 04786 if( th1 > th2 || th2 > th3 || th3 > qh1 ) return MB_FAILURE; 04787 04788 // construct an Range containing all valid handles; 04789 range.clear(); 04790 range.insert( ts1->start_handle(), ts1->end_handle() ); 04791 range.insert( ts2->start_handle(), ts2->end_handle() ); 04792 range.insert( ts3->start_handle(), ts3->end_handle() ); 04793 range.insert( qs1->start_handle(), qs1->end_handle() ); 04794 04795 // iterate over all and check results 04796 04797 rval = iter.init( range.begin(), range.end() ); 04798 if( MB_SUCCESS != rval ) return rval; 04799 if( ts1 != iter.get_sequence() ) return MB_FAILURE; 04800 if( iter.get_start_handle() != ts1->start_handle() ) return MB_FAILURE; 04801 if( iter.get_end_handle() != ts1->end_handle() ) return MB_FAILURE; 04802 04803 rval = iter.step(); 04804 if( MB_SUCCESS != rval ) return rval; 04805 if( ts2 != iter.get_sequence() ) return MB_FAILURE; 04806 if( iter.get_start_handle() != ts2->start_handle() ) return MB_FAILURE; 04807 if( iter.get_end_handle() != ts2->end_handle() ) return MB_FAILURE; 04808 04809 rval = iter.step(); 04810 if( MB_SUCCESS != rval ) return rval; 04811 if( ts3 != iter.get_sequence() ) return MB_FAILURE; 04812 if( iter.get_start_handle() != ts3->start_handle() ) return MB_FAILURE; 04813 if( iter.get_end_handle() != ts3->end_handle() ) return MB_FAILURE; 04814 04815 rval = iter.step(); 04816 if( MB_SUCCESS != rval ) return rval; 04817 if( qs1 != iter.get_sequence() ) return MB_FAILURE; 04818 if( iter.get_start_handle() != qs1->start_handle() ) return MB_FAILURE; 04819 if( iter.get_end_handle() != qs1->end_handle() ) return MB_FAILURE; 04820 04821 if( !iter.is_at_end() ) return MB_FAILURE; 04822 rval = iter.step(); 04823 if( MB_FAILURE != rval ) return MB_FAILURE; 04824 04825 // iterate over just the quads 04826 04827 rval = iter.init( range.lower_bound( MBQUAD ), range.end() ); 04828 if( MB_SUCCESS != rval ) return rval; 04829 if( qs1 != iter.get_sequence() ) return MB_FAILURE; 04830 if( iter.get_start_handle() != qs1->start_handle() ) return MB_FAILURE; 04831 if( iter.get_end_handle() != qs1->end_handle() ) return MB_FAILURE; 04832 04833 if( !iter.is_at_end() ) return MB_FAILURE; 04834 rval = iter.step(); 04835 if( MB_FAILURE != rval ) return MB_FAILURE; 04836 04837 // iterate starting one past the beginning of the 04838 // triangles and stopping one before the end. The last 04839 // sequence contains only one tri, so should stop and end 04840 // of second-to-last sequence 04841 04842 rval = iter.init( ++( range.begin() ), --( range.lower_bound( MBQUAD ) ) ); 04843 if( MB_SUCCESS != rval ) return rval; 04844 if( ts1 != iter.get_sequence() ) return MB_FAILURE; 04845 if( iter.get_start_handle() != ts1->start_handle() + 1 ) return MB_FAILURE; 04846 if( iter.get_end_handle() != ts1->end_handle() ) return MB_FAILURE; 04847 04848 rval = iter.step(); 04849 if( MB_SUCCESS != rval ) return rval; 04850 if( ts2 != iter.get_sequence() ) return MB_FAILURE; 04851 if( iter.get_start_handle() != ts2->start_handle() ) return MB_FAILURE; 04852 if( iter.get_end_handle() != ts2->end_handle() ) return MB_FAILURE; 04853 04854 if( !iter.is_at_end() ) return MB_FAILURE; 04855 rval = iter.step(); 04856 if( MB_FAILURE != rval ) return MB_FAILURE; 04857 04858 // Iterate over the quad sequence, starting two past the 04859 // beginning and stopping one before the end 04860 04861 rval = iter.init( ++( range.lower_bound( MBQUAD ) ), --( range.end() ) ); 04862 if( MB_SUCCESS != rval ) return rval; 04863 if( qs1 != iter.get_sequence() ) return MB_FAILURE; 04864 if( iter.get_start_handle() != qs1->start_handle() + 1 ) return MB_FAILURE; 04865 if( iter.get_end_handle() != qs1->end_handle() - 1 ) return MB_FAILURE; 04866 04867 if( !iter.is_at_end() ) return MB_FAILURE; 04868 rval = iter.step(); 04869 if( MB_FAILURE != rval ) return MB_FAILURE; 04870 04871 // Iterate over two subsets of the quad sequence 04872 04873 Range quads = range.subset_by_type( MBQUAD ); 04874 EntityHandle removed = qs1->start_handle() + nq1 / 2; 04875 if( quads.erase( removed ) == quads.end() ) return MB_FAILURE; 04876 04877 rval = iter.init( quads.begin(), quads.end() ); 04878 if( MB_SUCCESS != rval ) return rval; 04879 if( qs1 != iter.get_sequence() ) return MB_FAILURE; 04880 if( iter.get_start_handle() != qs1->start_handle() ) return MB_FAILURE; 04881 if( iter.get_end_handle() != removed - 1 ) return MB_FAILURE; 04882 04883 rval = iter.step(); 04884 if( MB_SUCCESS != rval ) return rval; 04885 if( qs1 != iter.get_sequence() ) return MB_FAILURE; 04886 if( iter.get_start_handle() != removed + 1 ) return MB_FAILURE; 04887 if( iter.get_end_handle() != qs1->end_handle() ) return MB_FAILURE; 04888 04889 if( !iter.is_at_end() ) return MB_FAILURE; 04890 rval = iter.step(); 04891 if( MB_FAILURE != rval ) return MB_FAILURE; 04892 04893 // Iterate over everything, including a bunch of 04894 // invalid handles 04895 04896 Range big; 04897 int junk; 04898 EntityHandle last = CREATE_HANDLE( MBQUAD + 1, 0, junk ); 04899 big.insert( ts1->start_handle() - 1, last ); 04900 04901 // first some invalid handles in the beginning of the range 04902 rval = iter.init( big.begin(), big.end() ); 04903 if( MB_ENTITY_NOT_FOUND != rval ) return MB_FAILURE; 04904 if( NULL != iter.get_sequence() ) return MB_FAILURE; 04905 if( iter.get_start_handle() != *big.begin() ) return MB_FAILURE; 04906 if( iter.get_end_handle() != ts1->start_handle() - 1 ) return MB_FAILURE; 04907 04908 // next the first triangle sequence 04909 rval = iter.step(); 04910 if( MB_SUCCESS != rval ) return rval; 04911 if( ts1 != iter.get_sequence() ) return MB_FAILURE; 04912 if( iter.get_start_handle() != ts1->start_handle() ) return MB_FAILURE; 04913 if( iter.get_end_handle() != ts1->end_handle() ) return MB_FAILURE; 04914 04915 // next the the invalid handles between the first two tri sequences 04916 if( ts1->end_handle() + 1 != ts2->start_handle() ) 04917 { 04918 rval = iter.step(); 04919 if( MB_ENTITY_NOT_FOUND != rval ) return MB_FAILURE; 04920 if( NULL != iter.get_sequence() ) return MB_FAILURE; 04921 if( iter.get_start_handle() != ts1->end_handle() + 1 ) return MB_FAILURE; 04922 if( iter.get_end_handle() != ts2->start_handle() - 1 ) return MB_FAILURE; 04923 } 04924 04925 // next the second triangle sequence 04926 rval = iter.step(); 04927 if( MB_SUCCESS != rval ) return rval; 04928 if( ts2 != iter.get_sequence() ) return MB_FAILURE; 04929 if( iter.get_start_handle() != ts2->start_handle() ) return MB_FAILURE; 04930 if( iter.get_end_handle() != ts2->end_handle() ) return MB_FAILURE; 04931 04932 // next the the invalid handles between the 2nd and 3rd tri sequences 04933 if( ts2->end_handle() + 1 != ts3->start_handle() ) 04934 { 04935 rval = iter.step(); 04936 if( MB_ENTITY_NOT_FOUND != rval ) return MB_FAILURE; 04937 if( NULL != iter.get_sequence() ) return MB_FAILURE; 04938 if( iter.get_start_handle() != ts2->end_handle() + 1 ) return MB_FAILURE; 04939 if( iter.get_end_handle() != ts3->start_handle() - 1 ) return MB_FAILURE; 04940 } 04941 04942 // next the third triangle sequence 04943 rval = iter.step(); 04944 if( MB_SUCCESS != rval ) return rval; 04945 if( ts3 != iter.get_sequence() ) return MB_FAILURE; 04946 if( iter.get_start_handle() != ts3->start_handle() ) return MB_FAILURE; 04947 if( iter.get_end_handle() != ts3->end_handle() ) return MB_FAILURE; 04948 04949 // third tri sequence contains the MAX tri handle, so no more 04950 // invalid triangles. 04951 // next 1 invalid quad at the before MB_START_ID 04952 if( ts3->end_handle() + 1 != qs1->start_handle() ) 04953 { 04954 rval = iter.step(); 04955 if( MB_ENTITY_NOT_FOUND != rval ) return MB_FAILURE; 04956 if( NULL != iter.get_sequence() ) return MB_FAILURE; 04957 if( iter.get_start_handle() != ts3->end_handle() + 1 ) return MB_FAILURE; 04958 if( iter.get_end_handle() != qs1->start_handle() - 1 ) return MB_FAILURE; 04959 } 04960 04961 // next the quad sequence 04962 rval = iter.step(); 04963 if( MB_SUCCESS != rval ) return rval; 04964 if( qs1 != iter.get_sequence() ) return MB_FAILURE; 04965 if( iter.get_start_handle() != qs1->start_handle() ) return MB_FAILURE; 04966 if( iter.get_end_handle() != qs1->end_handle() ) return MB_FAILURE; 04967 04968 // next remaining invalid quad handles in the range 04969 rval = iter.step(); 04970 if( MB_ENTITY_NOT_FOUND != rval ) return MB_FAILURE; 04971 if( 0 != iter.get_sequence() ) return MB_FAILURE; 04972 if( iter.get_start_handle() != qs1->end_handle() + 1 ) return MB_FAILURE; 04973 if( iter.get_end_handle() != last - 1 ) return MB_FAILURE; 04974 04975 // next invalid entity after the last quad in the range 04976 rval = iter.step(); 04977 if( MB_ENTITY_NOT_FOUND != rval ) return MB_FAILURE; 04978 if( 0 != iter.get_sequence() ) return MB_FAILURE; 04979 if( iter.get_start_handle() != last ) return MB_FAILURE; 04980 if( iter.get_end_handle() != last ) return MB_FAILURE; 04981 04982 // now at the end 04983 if( !iter.is_at_end() ) return MB_FAILURE; 04984 rval = iter.step(); 04985 if( MB_FAILURE != rval ) return MB_FAILURE; 04986 04987 // Create some holes 04988 Error eh; 04989 EntityHandle ts1s = ts1->start_handle(); 04990 EntityHandle dead1 = ts1->start_handle() + 1; 04991 EntityHandle dead2 = ts1->start_handle() + 2; 04992 EntityHandle ts1e = ts1->end_handle(); 04993 EntityHandle dead3 = ts2->start_handle(); 04994 EntityHandle dead4 = ts2->end_handle(); 04995 EntityHandle qs1s = qs1->start_handle(); 04996 EntityHandle qs1e = qs1->end_handle(); 04997 EntityHandle dead5 = qs1->start_handle() + nq1 / 2; 04998 EntityHandle dead6 = dead5 + 1; 04999 rval = sequences.delete_entity( &eh, dead1 ); 05000 if( MB_SUCCESS != rval ) return rval; 05001 rval = sequences.delete_entity( &eh, dead2 ); 05002 if( MB_SUCCESS != rval ) return rval; 05003 rval = sequences.delete_entity( &eh, dead3 ); 05004 if( MB_SUCCESS != rval ) return rval; 05005 rval = sequences.delete_entity( &eh, dead4 ); 05006 if( MB_SUCCESS != rval ) return rval; 05007 rval = sequences.delete_entity( &eh, dead5 ); 05008 if( MB_SUCCESS != rval ) return rval; 05009 rval = sequences.delete_entity( &eh, dead6 ); 05010 if( MB_SUCCESS != rval ) return rval; 05011 05012 // Iterate over sequences w/out removing deleted entities 05013 // from range. 05014 05015 // first sequence should have one valid handle at beginning 05016 rval = iter.init( range.begin(), range.end() ); 05017 if( MB_SUCCESS != rval ) return rval; 05018 if( 0 == iter.get_sequence() || ts1s != iter.get_sequence()->start_handle() || 05019 dead1 - 1 != iter.get_sequence()->end_handle() ) 05020 return MB_FAILURE; 05021 if( iter.get_start_handle() != ts1->start_handle() ) return MB_FAILURE; 05022 if( iter.get_end_handle() != dead1 - 1 ) return MB_FAILURE; 05023 05024 // next two invalid handles in sequence in first sequence 05025 rval = iter.step(); 05026 if( MB_ENTITY_NOT_FOUND != rval ) return MB_FAILURE; 05027 if( 0 != iter.get_sequence() ) return MB_FAILURE; 05028 if( iter.get_start_handle() != dead1 ) return MB_FAILURE; 05029 if( iter.get_end_handle() != dead2 ) return MB_FAILURE; 05030 05031 // next the remainder of the fist sequence 05032 rval = iter.step(); 05033 if( MB_SUCCESS != rval ) return rval; 05034 if( 0 == iter.get_sequence() || dead2 + 1 != iter.get_sequence()->start_handle() || 05035 ts1e != iter.get_sequence()->end_handle() ) 05036 return MB_FAILURE; 05037 if( iter.get_start_handle() != dead2 + 1 ) return MB_FAILURE; 05038 if( iter.get_end_handle() != ts1e ) return MB_FAILURE; 05039 05040 // next an invalid handle at the start of the second sequence 05041 rval = iter.step(); 05042 if( MB_ENTITY_NOT_FOUND != rval ) return MB_FAILURE; 05043 if( 0 != iter.get_sequence() ) return MB_FAILURE; 05044 if( iter.get_start_handle() != dead3 ) return MB_FAILURE; 05045 if( iter.get_end_handle() != dead3 ) return MB_FAILURE; 05046 05047 // next the second sequence up to the invalid handle at the end 05048 rval = iter.step(); 05049 if( MB_SUCCESS != rval ) return rval; 05050 if( 0 == iter.get_sequence() || dead3 + 1 != iter.get_sequence()->start_handle() || 05051 dead4 - 1 != iter.get_sequence()->end_handle() ) 05052 return MB_FAILURE; 05053 if( ts2 != iter.get_sequence() ) return MB_FAILURE; 05054 if( iter.get_start_handle() != dead3 + 1 ) return MB_FAILURE; 05055 if( iter.get_end_handle() != dead4 - 1 ) return MB_FAILURE; 05056 05057 // next invaild handle at the end of the second sequence 05058 rval = iter.step(); 05059 if( MB_ENTITY_NOT_FOUND != rval ) return MB_FAILURE; 05060 if( 0 != iter.get_sequence() ) return MB_FAILURE; 05061 if( iter.get_start_handle() != dead4 ) return MB_FAILURE; 05062 if( iter.get_end_handle() != dead4 ) return MB_FAILURE; 05063 05064 // next the third sequence 05065 rval = iter.step(); 05066 if( MB_SUCCESS != rval ) return rval; 05067 if( ts3 != iter.get_sequence() ) return MB_FAILURE; 05068 if( iter.get_start_handle() != ts3->start_handle() ) return MB_FAILURE; 05069 if( iter.get_end_handle() != ts3->end_handle() ) return MB_FAILURE; 05070 05071 // next the quad sequence up to the invalid handle in the middle 05072 rval = iter.step(); 05073 if( MB_SUCCESS != rval ) return rval; 05074 if( 0 == iter.get_sequence() || qs1s != iter.get_sequence()->start_handle() || 05075 dead5 - 1 != iter.get_sequence()->end_handle() ) 05076 return MB_FAILURE; 05077 if( qs1 != iter.get_sequence() ) return MB_FAILURE; 05078 if( iter.get_start_handle() != qs1s ) return MB_FAILURE; 05079 if( iter.get_end_handle() != dead5 - 1 ) return MB_FAILURE; 05080 05081 // next the two invalid handles in the middle 05082 rval = iter.step(); 05083 if( MB_ENTITY_NOT_FOUND != rval ) return MB_FAILURE; 05084 if( 0 != iter.get_sequence() ) return MB_FAILURE; 05085 if( iter.get_start_handle() != dead5 ) return MB_FAILURE; 05086 if( iter.get_end_handle() != dead6 ) return MB_FAILURE; 05087 05088 // next the remainder of the quad sequence 05089 rval = iter.step(); 05090 if( MB_SUCCESS != rval ) return rval; 05091 if( 0 == iter.get_sequence() || dead6 + 1 != iter.get_sequence()->start_handle() || 05092 qs1e != iter.get_sequence()->end_handle() ) 05093 return MB_FAILURE; 05094 if( iter.get_start_handle() != dead6 + 1 ) return MB_FAILURE; 05095 if( iter.get_end_handle() != qs1e ) return MB_FAILURE; 05096 05097 // now at the end 05098 if( !iter.is_at_end() ) return MB_FAILURE; 05099 rval = iter.step(); 05100 if( MB_FAILURE != rval ) return MB_FAILURE; 05101 05102 // now remove the dead entities from the range and iterate again 05103 05104 if( range.erase( dead1 ) == quads.end() ) return MB_FAILURE; 05105 if( range.erase( dead2 ) == quads.end() ) return MB_FAILURE; 05106 if( range.erase( dead3 ) == quads.end() ) return MB_FAILURE; 05107 if( range.erase( dead4 ) == quads.end() ) return MB_FAILURE; 05108 if( range.erase( dead5 ) == quads.end() ) return MB_FAILURE; 05109 if( range.erase( dead6 ) == quads.end() ) return MB_FAILURE; 05110 05111 // first sequence should have one valid handle at beginning 05112 rval = iter.init( range.begin(), range.end() ); 05113 if( MB_SUCCESS != rval ) return rval; 05114 if( 0 == iter.get_sequence() || ts1s != iter.get_sequence()->start_handle() || 05115 dead1 - 1 != iter.get_sequence()->end_handle() ) 05116 return MB_FAILURE; 05117 if( iter.get_start_handle() != ts1s ) return MB_FAILURE; 05118 if( iter.get_end_handle() != dead1 - 1 ) return MB_FAILURE; 05119 05120 // next the remainder of the fist sequence after the hole 05121 rval = iter.step(); 05122 if( MB_SUCCESS != rval ) return rval; 05123 if( 0 == iter.get_sequence() || dead2 + 1 != iter.get_sequence()->start_handle() || 05124 ts1e != iter.get_sequence()->end_handle() ) 05125 return MB_FAILURE; 05126 if( iter.get_start_handle() != dead2 + 1 ) return MB_FAILURE; 05127 if( iter.get_end_handle() != ts1e ) return MB_FAILURE; 05128 05129 // next the second sequence between deleted start and end handles 05130 rval = iter.step(); 05131 if( MB_SUCCESS != rval ) return rval; 05132 if( 0 == iter.get_sequence() || dead3 + 1 != iter.get_sequence()->start_handle() || 05133 dead4 - 1 != iter.get_sequence()->end_handle() ) 05134 return MB_FAILURE; 05135 if( iter.get_start_handle() != dead3 + 1 ) return MB_FAILURE; 05136 if( iter.get_end_handle() != dead4 - 1 ) return MB_FAILURE; 05137 05138 // next the third sequence 05139 rval = iter.step(); 05140 if( MB_SUCCESS != rval ) return rval; 05141 if( ts3 != iter.get_sequence() ) return MB_FAILURE; 05142 if( iter.get_start_handle() != ts3->start_handle() ) return MB_FAILURE; 05143 if( iter.get_end_handle() != ts3->end_handle() ) return MB_FAILURE; 05144 05145 // next the quad sequence up to the hole in the middle 05146 rval = iter.step(); 05147 if( MB_SUCCESS != rval ) return rval; 05148 if( 0 == iter.get_sequence() || qs1s != iter.get_sequence()->start_handle() || 05149 dead5 - 1 != iter.get_sequence()->end_handle() ) 05150 return MB_FAILURE; 05151 if( iter.get_start_handle() != qs1s ) return MB_FAILURE; 05152 if( iter.get_end_handle() != dead5 - 1 ) return MB_FAILURE; 05153 05154 // next the remainder of the quad sequence after the hole 05155 rval = iter.step(); 05156 if( MB_SUCCESS != rval ) return rval; 05157 if( 0 == iter.get_sequence() || dead6 + 1 != iter.get_sequence()->start_handle() || 05158 qs1e != iter.get_sequence()->end_handle() ) 05159 return MB_FAILURE; 05160 if( iter.get_start_handle() != dead6 + 1 ) return MB_FAILURE; 05161 if( iter.get_end_handle() != qs1e ) return MB_FAILURE; 05162 05163 // now at the end 05164 if( !iter.is_at_end() ) return MB_FAILURE; 05165 rval = iter.step(); 05166 if( MB_FAILURE != rval ) return MB_FAILURE; 05167 05168 return MB_SUCCESS; 05169 } 05170 05171 #define ASSERT_EQUAL( A, B ) \ 05172 do \ 05173 { \ 05174 if( !_assert_equal( ( A ), ( B ), #A, #B, __LINE__ ) ) return MB_FAILURE; \ 05175 } while( false ) 05176 05177 #define ASSERT_NOT_EQUAL( A, B ) \ 05178 do \ 05179 { \ 05180 if( !_assert_not_equal( ( A ), ( B ), #A, #B, __LINE__ ) ) return MB_FAILURE; \ 05181 } while( false ) 05182 05183 template < typename T1, typename T2 > 05184 bool _assert_equal( T1 a, T2 b, const char* as, const char* bs, int line ) 05185 { 05186 if( a == b ) return true; 05187 05188 std::cout << "Assertion failed at line " << line << std::endl 05189 << "\t" << as << " == " << bs << std::endl 05190 << "\t" << as << " = " << a << std::endl 05191 << "\t" << bs << " = " << b << std::endl; 05192 return false; 05193 } 05194 05195 template < typename T1, typename T2 > 05196 bool _assert_not_equal( T1 a, T2 b, const char* as, const char* bs, int line ) 05197 { 05198 if( a != b ) return true; 05199 05200 std::cout << "Assertion failed at line " << line << std::endl 05201 << "\t" << as << " != " << bs << std::endl 05202 << "\t" << as << " = " << a << std::endl 05203 << "\t" << bs << " = " << b << std::endl; 05204 return false; 05205 } 05206 05207 std::ostream& operator<<( std::ostream& s, Range::const_iterator i ) 05208 { 05209 return s << *i; 05210 } 05211 05212 ErrorCode mb_poly_adjacency_test() 05213 { 05214 ErrorCode rval; 05215 Core moab; 05216 Interface* mbImpl = &moab; 05217 05218 // make a couple polygons and a polyhedron 05219 double coords[3] = { 0, 1, 2 }; 05220 EntityHandle verts[10], polygons[2], polyhedron; 05221 05222 for( int i = 0; i < 10; i++ ) 05223 { 05224 rval = mbImpl->create_vertex( coords, verts[i] ); 05225 if( MB_SUCCESS != rval ) return rval; 05226 } 05227 05228 for( int i = 0; i < 2; i++ ) 05229 { 05230 rval = mbImpl->create_element( MBPOLYGON, verts, 5, polygons[i] ); 05231 if( MB_SUCCESS != rval ) return rval; 05232 } 05233 rval = mbImpl->create_element( MBPOLYHEDRON, polygons, 2, polyhedron ); 05234 if( MB_SUCCESS != rval ) return rval; 05235 05236 // create the aentities 05237 Range dum_range; 05238 for( int dim = 0; dim < 3; dim++ ) 05239 { 05240 dum_range.clear(); 05241 rval = mbImpl->get_adjacencies( &polyhedron, 1, dim, true, dum_range ); 05242 if( MB_SUCCESS != rval ) return rval; 05243 } 05244 05245 // delete the polyhedron 05246 rval = mbImpl->delete_entities( &polyhedron, 1 ); 05247 if( MB_SUCCESS != rval ) return rval; 05248 05249 // check adjacencies 05250 return moab.check_adjacencies(); 05251 } 05252 05253 ErrorCode mb_poly_adjacency_test2() 05254 { 05255 ErrorCode rval; 05256 Core moab; 05257 Interface* mbImpl = &moab; 05258 05259 // make a polyhedra in shape of a cube with a corner cut 05260 05261 /* 05262 * 05263 * 7 ------------- 8 05264 * . | . | 05265 * . . | initial cube had 8 vertices; box [000 - 222] 05266 * 5 ------------- 6 | cut a triangle 123 on lower corner 05267 * | | | | 05268 * | | | faces of the polyhedra (pointing outward) 05269 * | | | | (123) (24653) (4 10 8 6) 05270 * 3 | | (9 10 4 2 1) (7 8 10 9) (5687) 05271 * \ | | | (1 3 5 7 9) 05272 * 9 - - -| - 10 05273 * \ . | . 05274 * 1, | . 05275 * (000) '2 ---- 4 05276 * 05277 */ 05278 double coords[] = { 05279 0, 1, 0, // vertex 1 05280 1, 0, 0, // vertex 2 05281 0, 0, 1, // vertex 3 05282 2, 0, 0, 0, 0, 2, 2, 0, 2, // vertex 6 05283 0, 2, 2, 2, 2, 2, // vertex 8 05284 0, 2, 0, // vertex 9 05285 2, 2, 0 // vertex 9 05286 05287 }; 05288 EntityHandle verts[10], polygons[7], polyhedron; 05289 05290 for( int i = 0; i < 10; i++ ) 05291 { 05292 rval = mbImpl->create_vertex( &coords[3 * i], verts[i] ); 05293 if( MB_SUCCESS != rval ) return rval; 05294 } 05295 05296 EntityHandle connect[] = { 05297 1, 2, 3, // poly 1 05298 2, 4, 6, 5, 3, // poly 2 05299 4, 10, 8, 6, // polygon 3... 05300 9, 10, 4, 2, 1, 7, 8, 10, 9, 5, 6, 8, 7, 1, 3, 5, 7, 9 // polygon 7 05301 }; // we know the handles directly 05302 05303 int num_verts[7] = { 3, 5, 4, 5, 4, 4, 5 }; 05304 int start_indx[7]; 05305 start_indx[0] = 0; 05306 for( int i = 0; i < 6; i++ ) 05307 start_indx[i + 1] = start_indx[i] + num_verts[i]; 05308 for( int j = 0; j < 7; j++ ) 05309 { 05310 rval = mbImpl->create_element( MBPOLYGON, &connect[start_indx[j]], num_verts[j], polygons[j] ); 05311 if( MB_SUCCESS != rval ) return rval; 05312 } 05313 rval = mbImpl->create_element( MBPOLYHEDRON, polygons, 7, polyhedron ); 05314 if( MB_SUCCESS != rval ) return rval; 05315 05316 // create the aentities 05317 Range dum_range; 05318 for( int dim = 0; dim < 3; dim++ ) 05319 { 05320 dum_range.clear(); 05321 rval = mbImpl->get_adjacencies( &polyhedron, 1, dim, true, dum_range, Interface::UNION ); 05322 if( MB_SUCCESS != rval ) return rval; 05323 // std::cout << "\n dimension:" << dim << " " << dum_range.size() << " entities"; 05324 } 05325 // std::cout << "\n"; 05326 /*rval=mbImpl->write_mesh("polyhedra.vtk"); 05327 if (MB_SUCCESS != rval) 05328 return rval;*/ 05329 // delete the polyhedron 05330 rval = mbImpl->delete_entities( &polyhedron, 1 ); 05331 if( MB_SUCCESS != rval ) return rval; 05332 05333 // check adjacencies 05334 return moab.check_adjacencies(); 05335 } 05336 05337 ErrorCode mb_memory_use_test() 05338 { 05339 Core mb; 05340 unsigned long long init_total, total_with_elem, total_with_tag, total_with_tag_data; 05341 mb.estimated_memory_use( 0, 0, 0, &init_total ); 05342 05343 double coords[12] = { 1, 2, 0, 3, 4, 0, 5, 6, 0, 7, 8, 0 }; 05344 EntityHandle verts[4]; 05345 for( int i = 0; i < 4; ++i ) 05346 if( MB_SUCCESS != mb.create_vertex( coords + 3 * i, verts[i] ) ) return MB_FAILURE; 05347 05348 EntityHandle elem; 05349 mb.create_element( MBQUAD, verts, 4, elem ); 05350 05351 mb.estimated_memory_use( 0, 0, 0, &total_with_elem ); 05352 if( total_with_elem <= init_total ) return MB_FAILURE; 05353 05354 unsigned long long min, am; 05355 Range r; 05356 r.insert( elem ); 05357 mb.estimated_memory_use( r, &min, &am ); 05358 if( min != 4 * sizeof( EntityHandle ) ) return MB_FAILURE; 05359 05360 r.clear(); 05361 r.insert( verts[0] ); 05362 r.insert( verts[1] ); 05363 mb.estimated_memory_use( r, &min, &am ); 05364 if( min != 6 * sizeof( double ) ) return MB_FAILURE; 05365 05366 Tag tag; 05367 if( MB_SUCCESS != mb.tag_get_handle( "TMP_TAG", 1, MB_TYPE_INTEGER, tag, MB_TAG_SPARSE | MB_TAG_EXCL ) ) 05368 return MB_FAILURE; 05369 mb.estimated_memory_use( r, &min, &am ); 05370 if( min != 6 * sizeof( double ) ) return MB_FAILURE; 05371 05372 mb.estimated_memory_use( 0, 0, 0, &total_with_tag ); 05373 if( total_with_tag <= total_with_elem ) return MB_FAILURE; 05374 05375 int tag_data[] = { 0xA, 0xB }; 05376 if( MB_SUCCESS != mb.tag_set_data( tag, r, &tag_data ) ) return MB_FAILURE; 05377 mb.estimated_memory_use( r, &min, &am ); 05378 if( min <= 6 * sizeof( double ) ) return MB_FAILURE; 05379 05380 mb.estimated_memory_use( 0, 0, 0, &total_with_tag_data ); 05381 if( total_with_tag_data <= total_with_tag ) return MB_FAILURE; 05382 05383 return MB_SUCCESS; 05384 } 05385 05386 ErrorCode mb_skin_curve_test_common( bool use_adj ); 05387 05388 ErrorCode mb_skin_curve_test() 05389 { 05390 return mb_skin_curve_test_common( false ); 05391 } 05392 05393 ErrorCode mb_skin_curve_adj_test() 05394 { 05395 return mb_skin_curve_test_common( true ); 05396 } 05397 05398 ErrorCode mb_skin_surface_test_common( bool use_adj ); 05399 05400 ErrorCode mb_skin_surface_test() 05401 { 05402 return mb_skin_surface_test_common( false ); 05403 } 05404 05405 ErrorCode mb_skin_surface_adj_test() 05406 { 05407 return mb_skin_surface_test_common( true ); 05408 } 05409 05410 ErrorCode mb_skin_volume_test_common( bool use_adj ); 05411 05412 ErrorCode mb_skin_volume_test() 05413 { 05414 return mb_skin_volume_test_common( false ); 05415 } 05416 05417 ErrorCode mb_skin_volume_adj_test() 05418 { 05419 return mb_skin_volume_test_common( true ); 05420 } 05421 05422 ErrorCode mb_skin_curve_test_common( bool use_adj ) 05423 { 05424 ErrorCode rval; 05425 Core moab; 05426 Interface* mb = &moab; 05427 05428 std::vector< EntityHandle > verts; 05429 for( unsigned i = 0; i < 10; ++i ) 05430 { 05431 double coords[] = { static_cast< double >( i ), 0, 0 }; 05432 EntityHandle h; 05433 mb->create_vertex( coords, h ); 05434 verts.push_back( h ); 05435 } 05436 Range edges; 05437 for( unsigned i = 1; i < verts.size(); ++i ) 05438 { 05439 EntityHandle conn[] = { verts[i - 1], verts[i] }; 05440 EntityHandle h; 05441 mb->create_element( MBEDGE, conn, 2, h ); 05442 edges.insert( h ); 05443 } 05444 05445 Range skin; 05446 Skinner tool( mb ); 05447 rval = tool.find_skin( 0, edges, 0, skin, use_adj ); 05448 if( MB_SUCCESS != rval ) 05449 { 05450 std::cerr << "Skinner failure at " __FILE__ ":" << __LINE__ << std::endl; 05451 return MB_FAILURE; 05452 } 05453 if( skin.size() != 2 ) 05454 { 05455 std::cerr << "Skinner bad result at " __FILE__ ":" << __LINE__ << std::endl; 05456 return MB_FAILURE; 05457 } 05458 05459 if( verts.front() > verts.back() ) std::swap( verts.front(), verts.back() ); 05460 if( skin.front() != verts.front() || skin.back() != verts.back() ) 05461 { 05462 std::cerr << "Skinner bad result at " __FILE__ ":" << __LINE__ << std::endl; 05463 return MB_FAILURE; 05464 } 05465 05466 // now test again with only one edge 05467 EntityHandle edge = edges.front(); 05468 Range range( edge, edge ); 05469 skin.clear(); 05470 rval = tool.find_skin( 0, range, 0, skin, use_adj ); 05471 if( MB_SUCCESS != rval ) 05472 { 05473 std::cerr << "Skinner failure at " __FILE__ ":" << __LINE__ << std::endl; 05474 return MB_FAILURE; 05475 } 05476 if( skin.size() != 2 ) 05477 { 05478 std::cerr << "Skinner bad result at " __FILE__ ":" << __LINE__ << std::endl; 05479 return MB_FAILURE; 05480 } 05481 05482 Range verts2; 05483 mb->get_connectivity( &edge, 1, verts2 ); 05484 if( skin.front() != verts2.front() || skin.back() != verts2.back() ) 05485 { 05486 std::cerr << "Skinner bad result at " __FILE__ ":" << __LINE__ << std::endl; 05487 return MB_FAILURE; 05488 } 05489 05490 return MB_SUCCESS; 05491 } 05492 05493 ErrorCode mb_skin_surface_test_common( bool use_adj ) 05494 { 05495 ErrorCode rval; 05496 Core moab; 05497 Interface* mb = &moab; 05498 05499 /* Create 4 of 5 faces of a wedge: */ 05500 /* 05501 4 05502 /|\ 05503 / | \ 05504 / | \ 05505 / 2 \ 05506 3.../.\...5 05507 | / \ | 05508 | / \ | 05509 |/ \| 05510 0_________1 05511 */ 05512 05513 const double coords[][3] = { { 0, 0, 0 }, { 2, 0, 0 }, { 1, 0, 1 }, { 0, 2, 0 }, { 2, 2, 0 }, { 1, 2, 1 } }; 05514 EntityHandle verts[6]; 05515 for( unsigned i = 0; i < 6; ++i ) 05516 mb->create_vertex( coords[i], verts[i] ); 05517 05518 EntityHandle faces[4]; 05519 EntityHandle tri[] = { verts[0], verts[1], verts[2] }; 05520 EntityHandle quad1[] = { verts[0], verts[1], verts[5], verts[3] }; 05521 EntityHandle quad2[] = { verts[1], verts[5], verts[4], verts[2] }; 05522 EntityHandle quad3[] = { verts[2], verts[4], verts[3], verts[0] }; 05523 mb->create_element( MBTRI, tri, 3, faces[0] ); 05524 mb->create_element( MBQUAD, quad1, 4, faces[1] ); 05525 mb->create_element( MBQUAD, quad2, 4, faces[2] ); 05526 mb->create_element( MBQUAD, quad3, 4, faces[3] ); 05527 Range source; 05528 std::copy( faces, faces + 4, range_inserter( source ) ); 05529 05530 // Now skin the mesh. The only missing face is the 05531 // back triangle (verts 3, 4, & 5) so the skin should 05532 // be the edges bordering that face. 05533 05534 Range skin; 05535 Skinner tool( mb ); 05536 rval = tool.find_skin( 0, source, 1, skin, use_adj ); 05537 if( MB_SUCCESS != rval ) 05538 { 05539 std::cerr << "Skinner failure at " __FILE__ ":" << __LINE__ << std::endl; 05540 return MB_FAILURE; 05541 } 05542 if( skin.size() != 3 || !skin.all_of_type( MBEDGE ) ) 05543 { 05544 std::cerr << "Skinner bad result at " __FILE__ ":" << __LINE__ << std::endl; 05545 return MB_FAILURE; 05546 } 05547 05548 // Check each edge 05549 std::vector< EntityHandle > conn[3]; 05550 rval = mb->get_connectivity( &skin.front(), 1, conn[0] ); 05551 if( MB_SUCCESS != rval ) return rval; 05552 rval = mb->get_connectivity( &*++skin.begin(), 1, conn[1] ); 05553 if( MB_SUCCESS != rval ) return rval; 05554 rval = mb->get_connectivity( &skin.back(), 1, conn[2] ); 05555 if( MB_SUCCESS != rval ) return rval; 05556 for( int i = 0; i < 3; ++i ) 05557 if( conn[i][0] > conn[i][1] ) std::swap( conn[i][0], conn[i][1] ); 05558 05559 for( int i = 0; i < 3; ++i ) 05560 { 05561 EntityHandle s = verts[i + 3], e = verts[( i + 1 ) % 3 + 3]; 05562 if( s > e ) std::swap( s, e ); 05563 int j = 0; 05564 for( j = 0; j < 3; ++j ) 05565 if( conn[j][0] == s && conn[j][1] == e ) break; 05566 05567 if( j == 3 ) 05568 { 05569 std::cerr << "Skin does not contain edge [" << s << "," << e << "] at " << __FILE__ ":" << __LINE__ 05570 << std::endl; 05571 return MB_FAILURE; 05572 } 05573 } 05574 05575 return MB_SUCCESS; 05576 } 05577 05578 ErrorCode mb_skin_volume_test_common( bool use_adj ) 05579 { 05580 ErrorCode rval; 05581 Core moab; 05582 Interface* mb = &moab; 05583 05584 /* A 2 adjacent hexes hexes */ 05585 /* 05586 9-----10----11 05587 / / /| 05588 / / / | 05589 6-----7-----8..5 05590 | . | . | / 05591 |. |. |/ 05592 0-----1-----2 05593 */ 05594 05595 const double coords[][3] = { { 0, 0, 0 }, { 1, 0, 0 }, { 2, 0, 0 }, { 0, 1, 0 }, { 1, 1, 0 }, { 2, 1, 0 }, 05596 { 0, 0, 1 }, { 1, 0, 1 }, { 2, 0, 1 }, { 0, 1, 1 }, { 1, 1, 1 }, { 2, 1, 1 } }; 05597 EntityHandle verts[12]; 05598 for( unsigned i = 0; i < 12; ++i ) 05599 mb->create_vertex( coords[i], verts[i] ); 05600 05601 EntityHandle hex1c[] = { verts[0], verts[1], verts[4], verts[3], verts[6], verts[7], verts[10], verts[9] }; 05602 EntityHandle hex2c[] = { verts[1], verts[2], verts[5], verts[4], verts[7], verts[8], verts[11], verts[10] }; 05603 EntityHandle hex1, hex2; 05604 mb->create_element( MBHEX, hex1c, 8, hex1 ); 05605 mb->create_element( MBHEX, hex2c, 8, hex2 ); 05606 Range source; 05607 source.insert( hex1 ); 05608 source.insert( hex2 ); 05609 05610 // get all quads and shared face 05611 Range tmp, all_faces; 05612 mb->get_adjacencies( source, 2, true, all_faces, Interface::UNION ); 05613 mb->get_adjacencies( source, 2, true, tmp, Interface::INTERSECT ); 05614 assert( tmp.size() == 1 ); 05615 Range non_shared = subtract( all_faces, tmp ); 05616 05617 // Now skin the mesh. 05618 05619 Range skin; 05620 Skinner tool( mb ); 05621 rval = tool.find_skin( 0, source, 2, skin, use_adj ); 05622 if( MB_SUCCESS != rval ) 05623 { 05624 std::cerr << "Skinner failure at " __FILE__ ":" << __LINE__ << std::endl; 05625 return MB_FAILURE; 05626 } 05627 if( skin != non_shared ) 05628 { 05629 std::cerr << "Skinner bad result at " __FILE__ ":" << __LINE__ << std::endl; 05630 return MB_FAILURE; 05631 } 05632 05633 return MB_SUCCESS; 05634 } 05635 05636 ErrorCode mb_skin_scd_test() 05637 { 05638 // make a 10x10x5 scd mesh 05639 Core moab; 05640 Interface* mb = &moab; 05641 ScdInterface* scdi; 05642 ErrorCode rval = mb->query_interface( scdi ); 05643 if( MB_SUCCESS != rval ) return rval; 05644 HomCoord low( 0, 0, 0 ), high( 10, 10, 5 ); 05645 ScdBox* this_box; 05646 rval = scdi->construct_box( low, high, NULL, 0, this_box ); 05647 if( MB_SUCCESS != rval ) return rval; 05648 05649 // now skin it with the structured and original method, and compare results 05650 Skinner tool( mb ); 05651 Range ents( this_box->start_element(), this_box->start_element() + this_box->num_elements() - 1 ), scd_skin_ents, 05652 skin_ents; 05653 rval = tool.find_skin( 0, ents, false, scd_skin_ents, NULL, true, true, true ); 05654 if( MB_SUCCESS != rval ) return rval; 05655 05656 rval = tool.find_skin( 0, ents, false, skin_ents, NULL, true, true, false ); 05657 if( MB_SUCCESS != rval ) return rval; 05658 05659 // should be same number of entities 05660 if( scd_skin_ents.size() != skin_ents.size() ) return MB_FAILURE; 05661 05662 skin_ents.clear(); 05663 scd_skin_ents.clear(); 05664 05665 // now test getting faces and vertices, also with existing faces now 05666 rval = tool.find_skin( 0, ents, true, scd_skin_ents, NULL, true, true, true ); 05667 if( MB_SUCCESS != rval ) return rval; 05668 05669 rval = tool.find_skin( 0, ents, true, skin_ents, NULL, true, true, false ); 05670 if( MB_SUCCESS != rval ) return rval; 05671 05672 // again, should have same numbers 05673 if( skin_ents.subset_by_type( MBVERTEX ).size() != scd_skin_ents.subset_by_type( MBVERTEX ).size() ) 05674 return MB_FAILURE; 05675 05676 return MB_SUCCESS; 05677 } 05678 05679 ErrorCode mb_skin_fileset_test() 05680 { 05681 Core moab; 05682 Interface* mb = &moab; 05683 ErrorCode error; 05684 const double coords[] = { 0, 0, 0, 1, 0, 0, 2, 0, 0, 2, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 2, 0, 1, 05685 2, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 2, 1, 0, 2, 2, 0, 2, 2, 1, 2, 1, 1, 2, 0, 1, 2 }; 05686 const size_t num_vtx = sizeof( coords ) / sizeof( double ) / 3; 05687 05688 const int conn[] = { 0, 1, 4, 5, 6, 7, 10, 11, 1, 2, 3, 4, 7, 8, 9, 10, 05689 6, 7, 10, 11, 12, 13, 16, 17, 7, 8, 9, 10, 13, 14, 15, 16 }; 05690 const size_t num_elems = sizeof( conn ) / sizeof( int ) / 8; 05691 05692 EntityHandle verts[num_vtx], cells[num_elems]; 05693 for( size_t i = 0; i < num_vtx; ++i ) 05694 { 05695 error = mb->create_vertex( coords + 3 * i, verts[i] );MB_CHK_ERR( error ); 05696 } 05697 05698 for( size_t i = 0; i < num_elems; ++i ) 05699 { 05700 EntityHandle c[8]; 05701 for( int j = 0; j < 8; j++ ) 05702 c[j] = verts[conn[8 * i + j]]; 05703 05704 error = mb->create_element( MBHEX, c, 8, cells[i] );MB_CHK_ERR( error ); 05705 } 05706 05707 EntityHandle fileset; 05708 error = mb->create_meshset( MESHSET_SET, fileset );MB_CHK_ERR( error ); 05709 error = mb->add_entities( fileset, &verts[0], num_vtx );MB_CHK_ERR( error ); 05710 error = mb->add_entities( fileset, &cells[0], num_elems );MB_CHK_ERR( error ); 05711 05712 Range fverts, fedges, ffaces, fcells; 05713 error = mb->get_entities_by_dimension( fileset, 0, fverts );MB_CHK_ERR( error ); 05714 error = mb->get_entities_by_dimension( fileset, 1, fedges );MB_CHK_ERR( error ); 05715 error = mb->get_entities_by_dimension( fileset, 2, ffaces );MB_CHK_ERR( error ); 05716 error = mb->get_entities_by_dimension( fileset, 3, fcells );MB_CHK_ERR( error ); 05717 05718 assert( fverts.size() == 18 && fedges.size() == 0 && ffaces.size() == 0 && fcells.size() == 4 ); 05719 05720 Skinner sk( mb ); 05721 Range skin_ents; 05722 error = sk.find_skin( fileset, fcells, 2, skin_ents, false, true );MB_CHK_ERR( error ); 05723 error = mb->get_entities_by_dimension( fileset, 2, ffaces );MB_CHK_ERR( error ); 05724 assert( ffaces.size() == 16 ); 05725 error = sk.find_skin( fileset, fcells, 1, skin_ents, false, true );MB_CHK_ERR( error ); 05726 error = mb->get_entities_by_dimension( fileset, 1, fedges );MB_CHK_ERR( error ); 05727 assert( fedges.size() == 32 ); 05728 05729 const double fcoords[] = { 0, 0, 3, 1, 0, 3, 2, 0, 3, 2, 1, 3, 1, 1, 3, 0, 1, 3 }; 05730 const size_t num_fvtx = sizeof( fcoords ) / sizeof( double ) / 3; 05731 05732 const int fconn[] = { 0, 1, 4, 5, 1, 2, 3, 4 }; 05733 const size_t num_faces = sizeof( fconn ) / sizeof( int ) / 4; 05734 EntityHandle nwverts[num_fvtx], faces[num_faces]; 05735 for( size_t i = 0; i < num_fvtx; ++i ) 05736 { 05737 error = mb->create_vertex( fcoords + 3 * i, nwverts[i] );MB_CHK_ERR( error ); 05738 } 05739 05740 for( size_t i = 0; i < num_faces; ++i ) 05741 { 05742 EntityHandle c[4]; 05743 for( int j = 0; j < 4; j++ ) 05744 c[j] = nwverts[fconn[4 * i + j]]; 05745 05746 error = mb->create_element( MBQUAD, c, 4, faces[i] );MB_CHK_ERR( error ); 05747 } 05748 EntityHandle fileset1; 05749 error = mb->create_meshset( MESHSET_SET, fileset1 );MB_CHK_ERR( error ); 05750 error = mb->add_entities( fileset1, &nwverts[0], num_fvtx );MB_CHK_ERR( error ); 05751 error = mb->add_entities( fileset1, &faces[0], num_faces );MB_CHK_ERR( error ); 05752 05753 Range verts1, edges1, faces1; 05754 error = mb->get_entities_by_dimension( fileset1, 0, verts1 );MB_CHK_ERR( error ); 05755 error = mb->get_entities_by_dimension( fileset1, 1, edges1 );MB_CHK_ERR( error ); 05756 error = mb->get_entities_by_dimension( fileset1, 2, faces1 );MB_CHK_ERR( error ); 05757 05758 assert( verts1.size() == 6 && edges1.size() == 0 && faces1.size() == 2 ); 05759 05760 // error = sk.find_skin(fileset1, faces1, 1, skin_ents, false, true);MB_CHK_ERR(error); 05761 error = sk.find_skin( fileset1, faces1, false, skin_ents, NULL, true, true, false );MB_CHK_ERR( error ); 05762 error = mb->get_entities_by_dimension( fileset1, 1, edges1 );MB_CHK_ERR( error ); 05763 assert( edges1.size() == 6 ); 05764 05765 return MB_SUCCESS; 05766 } 05767 05768 // It is a common problem for readers to incorrectly 05769 // handle invalid/unknown file types and non-existant 05770 // files. For either case, MOAB will try all readers 05771 // (assuming it doesn't recongnize the file extension), 05772 // so we can test all the readers w/out knowing which 05773 // readers we have. 05774 const char* argv0 = 0; 05775 ErrorCode mb_read_fail_test() 05776 { 05777 Core moab; 05778 Interface* mb = &moab; 05779 05780 const char BAD_FILE_NAME[] = "non-existant-file.txt"; 05781 ErrorCode rval; 05782 05783 FILE* fptr = fopen( BAD_FILE_NAME, "r" ); 05784 if( fptr ) 05785 { 05786 fclose( fptr ); 05787 std::cout << "Test cannot proceed while file exists: " << BAD_FILE_NAME << std::endl; 05788 return MB_FAILURE; 05789 } 05790 05791 // try reading a non-existant file 05792 05793 rval = mb->load_file( BAD_FILE_NAME ); 05794 if( MB_FILE_DOES_NOT_EXIST != rval ) return MB_FAILURE; 05795 05796 // try reading an invalid file 05797 if( !argv0 ) // not set by main, oops! 05798 return MB_FAILURE; 05799 rval = mb->load_file( argv0 ); 05800 if( MB_SUCCESS == rval ) return MB_FAILURE; 05801 05802 return MB_SUCCESS; 05803 } 05804 05805 #define TEST_ERROR_CODE( E ) \ 05806 if( mb->get_error_string( E ) != #E ) \ 05807 { \ 05808 std::cerr << "Invalid error string from get_error_string for " << #E << ": " << mb->get_error_string( E ) \ 05809 << std::endl; \ 05810 return MB_FAILURE; \ 05811 } 05812 05813 ErrorCode mb_enum_string_test() 05814 { 05815 Core moab; 05816 Interface* mb = &moab; 05817 05818 TEST_ERROR_CODE( MB_SUCCESS ); 05819 TEST_ERROR_CODE( MB_INDEX_OUT_OF_RANGE ); 05820 TEST_ERROR_CODE( MB_TYPE_OUT_OF_RANGE ); 05821 TEST_ERROR_CODE( MB_MEMORY_ALLOCATION_FAILED ); 05822 TEST_ERROR_CODE( MB_ENTITY_NOT_FOUND ); 05823 TEST_ERROR_CODE( MB_MULTIPLE_ENTITIES_FOUND ); 05824 TEST_ERROR_CODE( MB_TAG_NOT_FOUND ); 05825 TEST_ERROR_CODE( MB_FILE_DOES_NOT_EXIST ); 05826 TEST_ERROR_CODE( MB_FILE_WRITE_ERROR ); 05827 TEST_ERROR_CODE( MB_NOT_IMPLEMENTED ); 05828 TEST_ERROR_CODE( MB_ALREADY_ALLOCATED ); 05829 TEST_ERROR_CODE( MB_VARIABLE_DATA_LENGTH ); 05830 TEST_ERROR_CODE( MB_INVALID_SIZE ); 05831 TEST_ERROR_CODE( MB_UNSUPPORTED_OPERATION ); 05832 TEST_ERROR_CODE( MB_UNHANDLED_OPTION ); 05833 TEST_ERROR_CODE( MB_STRUCTURED_MESH ); 05834 TEST_ERROR_CODE( MB_FAILURE ); 05835 05836 return MB_SUCCESS; 05837 } 05838 05839 // Test basic skinning using vert-to-elem adjacencies 05840 ErrorCode mb_skin_verts_common( unsigned dim, bool skin_elems ); 05841 05842 ErrorCode mb_skin_surf_verts_test() 05843 { 05844 return mb_skin_verts_common( 2, false ); 05845 } 05846 05847 ErrorCode mb_skin_vol_verts_test() 05848 { 05849 return mb_skin_verts_common( 3, false ); 05850 } 05851 05852 ErrorCode mb_skin_surf_verts_elems_test() 05853 { 05854 return mb_skin_verts_common( 2, true ); 05855 } 05856 05857 ErrorCode mb_skin_vol_verts_elems_test() 05858 { 05859 return mb_skin_verts_common( 3, true ); 05860 } 05861 05862 ErrorCode mb_skin_verts_common( unsigned dim, bool skin_elems ) 05863 { 05864 const int INT = 10; // intervals+1 05865 const char* tmp_file = "structured.vtk"; 05866 std::ofstream str( tmp_file ); 05867 if( !str ) 05868 { 05869 std::cerr << tmp_file << ": filed to create temp file" << std::endl; 05870 return MB_FAILURE; 05871 } 05872 str << "#vtk DataFile Version 2.0" << std::endl 05873 << "mb_skin_verts_common temp file" << std::endl 05874 << "ASCII" << std::endl 05875 << "DATASET STRUCTURED_POINTS" << std::endl 05876 << "DIMENSIONS " << INT << " " << ( dim > 1 ? INT : 1 ) << " " << ( dim > 2 ? INT : 1 ) << std::endl 05877 << "ORIGIN 0 0 0" << std::endl 05878 << "SPACING 1 1 1" << std::endl; 05879 str.close(); 05880 05881 Core moab; 05882 Interface& mb = moab; 05883 ErrorCode rval; 05884 05885 rval = mb.load_file( tmp_file ); 05886 remove( tmp_file ); 05887 if( MB_SUCCESS != rval ) return rval; 05888 05889 Range ents; 05890 rval = mb.get_entities_by_dimension( 0, dim, ents ); 05891 if( MB_SUCCESS != rval ) return rval; 05892 if( ents.empty() ) return MB_FAILURE; 05893 05894 Skinner tool( &mb ); 05895 05896 // mesh is a structured quad/hex mesh, so we can 05897 // determine skin vertices from the number of 05898 // adjacent elements. 05899 unsigned interior_adj = 1; 05900 for( unsigned i = 0; i < dim; ++i ) 05901 interior_adj *= 2; 05902 Range expected, verts; 05903 rval = mb.get_entities_by_dimension( 0, 0, verts ); 05904 if( MB_SUCCESS != rval ) return rval; 05905 Range::iterator h = expected.begin(); 05906 std::vector< EntityHandle > adj; 05907 for( Range::iterator v = verts.begin(); v != verts.end(); ++v ) 05908 { 05909 adj.clear(); 05910 rval = mb.get_adjacencies( &*v, 1, dim, false, adj ); 05911 if( MB_SUCCESS != rval ) return rval; 05912 if( adj.size() < interior_adj ) h = expected.insert( h, *v ); 05913 } 05914 05915 // Get skin vertices using skinner 05916 Range actual; 05917 rval = tool.find_skin( 0, ents, !skin_elems, actual ); 05918 if( MB_SUCCESS != rval ) return rval; 05919 05920 Range extra, missing; 05921 if( !skin_elems ) 05922 { 05923 // Check that we got expected result 05924 extra = subtract( actual, expected ); 05925 missing = subtract( expected, actual ); 05926 if( !extra.empty() || !missing.empty() ) 05927 { 05928 std::cout << "Extra vertices returned: " << extra << std::endl 05929 << "Missing vertices: " << missing << std::endl; 05930 return MB_FAILURE; 05931 } 05932 return MB_SUCCESS; 05933 } 05934 05935 // test that no extra elements we're created 05936 extra.clear(); 05937 rval = mb.get_entities_by_dimension( 0, dim - 1, extra ); 05938 if( MB_SUCCESS != rval ) return rval; 05939 extra = subtract( extra, actual ); 05940 if( !extra.empty() ) 05941 { 05942 std::cout << "Extra/non-returned elements created: " << extra << std::endl; 05943 return MB_FAILURE; 05944 } 05945 05946 // check that each skin vertex has the correct number of adjacent quads 05947 missing.clear(); 05948 extra.clear(); 05949 for( Range::iterator i = expected.begin(); i != expected.end(); ++i ) 05950 { 05951 std::vector< EntityHandle > elem, side; 05952 rval = mb.get_adjacencies( &*i, 1, dim, false, elem ); 05953 if( MB_SUCCESS != rval ) return rval; 05954 rval = mb.get_adjacencies( &*i, 1, dim - 1, false, side ); 05955 if( MB_SUCCESS != rval ) return rval; 05956 if( elem.size() == 1 ) 05957 { 05958 if( side.size() < dim ) 05959 missing.insert( *i ); 05960 else if( side.size() > dim ) 05961 extra.insert( *i ); 05962 } 05963 else if( elem.size() == interior_adj ) 05964 { 05965 if( !side.empty() ) extra.insert( *i ); 05966 } 05967 else 05968 { 05969 if( side.size() < interior_adj / 2 ) 05970 missing.insert( *i ); 05971 else if( side.size() > interior_adj / 2 ) 05972 extra.insert( *i ); 05973 } 05974 } 05975 if( !missing.empty() || !extra.empty() ) 05976 { 05977 std::cout << "Skin elements missing at vertices: " << missing << std::endl 05978 << "Extra skin elements at vertices: " << extra << std::endl; 05979 return MB_FAILURE; 05980 } 05981 05982 // check that all returned elements are actually on the skin 05983 extra.clear(); 05984 for( Range::iterator i = actual.begin(); i != actual.end(); ++i ) 05985 { 05986 Range verts2; 05987 rval = mb.get_adjacencies( &*i, 1, 0, false, verts2 ); 05988 if( MB_SUCCESS != rval ) return rval; 05989 verts2 = subtract( verts2, expected ); 05990 if( !verts2.empty() ) extra.insert( *i ); 05991 } 05992 if( !extra.empty() ) 05993 { 05994 std::cout << "Skinner returned elements not on skin: " << extra << std::endl; 05995 return MB_FAILURE; 05996 } 05997 05998 return MB_SUCCESS; 05999 } 06000 06001 // Test that skinning of polyhedra works 06002 ErrorCode mb_skin_poly_test() 06003 { 06004 /* Create a mesh composed of 8 hexagonal prisms and 06005 two hexahedra by extruding the following cross section 06006 two steps in the Z direction. 06007 06008 0-----1 06009 / (0) \ 06010 (11)/ \(1) 06011 / \ 06012 11 2 06013 / \ Y / \ 06014 (10)/ \(12)^(13)/ \(2) 06015 / \ | / \ 06016 10 12-----13 3 06017 | | | | | 06018 (9)| | +--|-->X |(3) 06019 | | | | 06020 9 15-----14 4 06021 \ / \ / 06022 (8)\ /(15) (14)\ /(4) 06023 \ / \ / 06024 8 5 06025 \ / 06026 (7)\ /(5) 06027 \ (6) / 06028 7-----6 06029 */ 06030 06031 const double coords2D[][2] = { 06032 { -1, 5 }, // 0 06033 { 1, 5 }, { 3, 3 }, { 5, 1 }, { 5, -1 }, { 3, -3 }, // 5 06034 { 1, -5 }, { -1, -5 }, { -3, -3 }, { -5, -1 }, { -5, 1 }, // 10 06035 { -3, 3 }, { -1, 1 }, { 1, 1 }, { 1, -1 }, { -1, -1 } // 15 06036 }; 06037 const int polyconn[4][6] = { 06038 { 0, 1, 2, 13, 12, 11 }, { 2, 3, 4, 5, 14, 13 }, { 5, 6, 7, 8, 15, 14 }, { 8, 9, 10, 11, 12, 15 } }; 06039 const int polyside[4][6] = { 06040 { 0, 1, 13, 16, 12, 11 }, { 2, 3, 4, 14, 17, 13 }, { 5, 6, 7, 15, 18, 14 }, { 8, 9, 10, 12, 19, 15 } }; 06041 06042 ErrorCode rval; 06043 Core moab; 06044 Interface& mb = moab; 06045 Range regions, faces, interior_faces; 06046 06047 // create 48 vertices 06048 EntityHandle verts[3][16]; 06049 for( int i = 0; i < 3; ++i ) 06050 { 06051 for( int j = 0; j < 16; ++j ) 06052 { 06053 double coords[3] = { coords2D[j][0], coords2D[j][1], static_cast< double >( 2 * i ) }; 06054 rval = mb.create_vertex( coords, verts[i][j] ); 06055 if( MB_SUCCESS != rval ) return rval; 06056 } 06057 } 06058 06059 // create two hexahedra 06060 EntityHandle hexes[2]; 06061 for( int i = 0; i < 2; ++i ) 06062 { 06063 EntityHandle conn[8] = { verts[i][15], verts[i][14], verts[i][13], verts[i][12], 06064 verts[i + 1][15], verts[i + 1][14], verts[i + 1][13], verts[i + 1][12] }; 06065 rval = mb.create_element( MBHEX, conn, 8, hexes[i] ); 06066 if( MB_SUCCESS != rval ) return rval; 06067 regions.insert( hexes[i] ); 06068 } 06069 06070 // create hexagonal faces 06071 EntityHandle hexagons[3][4]; 06072 for( int i = 0; i < 3; ++i ) 06073 { 06074 for( int j = 0; j < 4; ++j ) 06075 { 06076 EntityHandle conn[6]; 06077 for( int k = 0; k < 6; ++k ) 06078 conn[k] = verts[i][polyconn[j][k]]; 06079 rval = mb.create_element( MBPOLYGON, conn, 6, hexagons[i][j] ); 06080 if( MB_SUCCESS != rval ) return rval; 06081 faces.insert( hexagons[i][j] ); 06082 if( i == 1 ) interior_faces.insert( hexagons[i][j] ); 06083 } 06084 } 06085 06086 // create quadrilateral faces 06087 EntityHandle quads[2][20]; 06088 for( int i = 0; i < 2; ++i ) 06089 { 06090 for( int j = 0; j < 20; ++j ) 06091 { 06092 int c1, c2; 06093 if( j < 12 ) 06094 { 06095 c1 = j; 06096 c2 = ( j + 1 ) % 12; 06097 } 06098 else if( j < 16 ) 06099 { 06100 c1 = j; 06101 c2 = 2 + 3 * ( ( j - 9 ) % 4 ); 06102 } 06103 else 06104 { 06105 c1 = j - 4; 06106 c2 = 12 + ( j - 15 ) % 4; 06107 } 06108 EntityHandle conn[4] = { verts[i][c1], verts[i][c2], verts[i + 1][c2], verts[i + 1][c1] }; 06109 rval = mb.create_element( MBQUAD, conn, 4, quads[i][j] ); 06110 if( MB_SUCCESS != rval ) return rval; 06111 faces.insert( quads[i][j] ); 06112 if( j > 11 ) interior_faces.insert( quads[i][j] ); 06113 } 06114 } 06115 06116 // create polyhedra 06117 EntityHandle poly[2][4]; 06118 for( int i = 0; i < 2; ++i ) 06119 { 06120 for( int j = 0; j < 4; ++j ) 06121 { 06122 EntityHandle conn[8]; 06123 for( int k = 0; k < 6; ++k ) 06124 conn[k] = quads[i][polyside[j][k]]; 06125 conn[6] = hexagons[i][j]; 06126 conn[7] = hexagons[i + 1][j]; 06127 rval = mb.create_element( MBPOLYHEDRON, conn, 8, poly[i][j] ); 06128 if( MB_SUCCESS != rval ) return rval; 06129 regions.insert( poly[i][j] ); 06130 } 06131 } 06132 06133 Range interior_verts; 06134 interior_verts.insert( verts[1][12] ); 06135 interior_verts.insert( verts[1][13] ); 06136 interior_verts.insert( verts[1][14] ); 06137 interior_verts.insert( verts[1][15] ); 06138 06139 Skinner tool( &mb ); 06140 Range skin; 06141 rval = tool.find_skin( 0, regions, true, skin, 0, true, false ); 06142 if( MB_SUCCESS != rval ) 06143 { 06144 std::cout << "Vertex skinning failed with: " << mb.get_error_string( rval ) << std::endl; 06145 return rval; 06146 } 06147 06148 Range all_verts, all_faces; 06149 rval = mb.get_entities_by_dimension( 0, 0, all_verts ); 06150 if( MB_SUCCESS != rval ) return rval; 06151 rval = mb.get_entities_by_dimension( 0, 2, all_faces ); 06152 if( MB_SUCCESS != rval ) return rval; 06153 06154 Range expected = subtract( all_verts, interior_verts ); 06155 if( expected != skin ) 06156 { 06157 std::cout << "Skinner returned incorrect vertices." << std::endl; 06158 return MB_FAILURE; 06159 } 06160 if( all_faces != faces ) 06161 { 06162 std::cout << "Skinner created/deleted faces for vertex-only skinning" << std::endl; 06163 return MB_FAILURE; 06164 } 06165 06166 skin.clear(); 06167 rval = tool.find_skin( 0, regions, false, skin, 0, true, false ); 06168 if( MB_SUCCESS != rval ) 06169 { 06170 std::cout << "Non-create face skinning failed with: " << mb.get_error_string( rval ) << std::endl; 06171 return rval; 06172 } 06173 expected = subtract( all_faces, interior_faces ); 06174 if( expected != skin ) 06175 { 06176 std::cout << "Skinner returned incorrect faces." << std::endl; 06177 return MB_FAILURE; 06178 } 06179 if( all_faces != faces ) 06180 { 06181 std::cout << "Skinner created/deleted faces for no-create skinning" << std::endl; 06182 return MB_FAILURE; 06183 } 06184 06185 skin.clear(); 06186 rval = tool.find_skin( 0, regions, false, skin, 0, true, true ); 06187 if( MB_SUCCESS != rval ) 06188 { 06189 std::cout << "Create face skinning failed with: " << mb.get_error_string( rval ) << std::endl; 06190 return rval; 06191 } 06192 Range all_faces2; 06193 rval = mb.get_entities_by_dimension( 0, 2, all_faces2 ); 06194 if( MB_SUCCESS != rval ) return rval; 06195 Range difference = subtract( all_faces2, all_faces ); 06196 if( difference.size() != 2 ) 06197 { // should have created two quads for hex top/bottom 06198 std::cout << "Skinner failed to create new quads or created to many." << std::endl; 06199 return MB_FAILURE; 06200 } 06201 expected.merge( difference ); 06202 if( expected != skin ) 06203 { 06204 std::cout << "Skinner returned incorrect faces." << std::endl; 06205 return MB_FAILURE; 06206 } 06207 // check that new faces are correct 06208 EntityHandle expected_conn[2][4] = { { verts[0][12], verts[0][13], verts[0][14], verts[0][15] }, 06209 { verts[2][12], verts[2][13], verts[2][14], verts[2][15] } }; 06210 EntityHandle nq[2] = { difference.front(), difference.back() }; 06211 for( int i = 0; i < 2; ++i ) 06212 { 06213 const EntityHandle* conn; 06214 int len; 06215 bool found = false; 06216 for( int j = 0; !found && j < 2; ++j ) 06217 { 06218 rval = mb.get_connectivity( nq[j], conn, len ); 06219 if( MB_SUCCESS != rval ) return rval; 06220 int idx1 = std::find( conn, conn + len, expected_conn[i][0] ) - conn; 06221 if( idx1 == len ) continue; 06222 found = true; 06223 for( int k = 1; k < 4; ++k ) 06224 if( conn[( idx1 + k ) % 4] != expected_conn[i][k] ) found = false; 06225 if( !found ) 06226 { 06227 found = true; 06228 for( int k = 1; k < 4; ++k ) 06229 if( conn[( idx1 + 4 - k ) % 4] != expected_conn[i][k] ) found = false; 06230 } 06231 } 06232 if( !found ) 06233 { 06234 std::cerr << "Skinner did not create & return expected quad " << i << std::endl; 06235 return MB_FAILURE; 06236 } 06237 } 06238 06239 return MB_SUCCESS; 06240 } 06241 06242 // Test that skinning of higher-order elements works 06243 ErrorCode mb_skin_higher_order_faces_common( bool use_adj ) 06244 { 06245 /* Create mesh: 06246 06247 0---1---2---3---4 06248 | | / 06249 | | / 06250 5 6 7 8 9 06251 | | / 06252 | | / 06253 10--11--12 06254 */ 06255 06256 ErrorCode rval; 06257 Core moab; 06258 Interface& mb = moab; 06259 06260 double coords[13][3] = { { 0, 4, 0 }, { 2, 4, 0 }, { 4, 4, 0 }, { 6, 4, 0 }, { 8, 4, 0 }, { 0, 2, 0 }, { 2, 2, 0 }, 06261 { 4, 2, 0 }, { 5, 2, 0 }, { 6, 2, 0 }, { 0, 0, 0 }, { 2, 0, 0 }, { 4, 0, 0 } }; 06262 EntityHandle verts[13]; 06263 for( int i = 0; i < 13; ++i ) 06264 { 06265 rval = mb.create_vertex( coords[i], verts[i] ); 06266 if( MB_SUCCESS != rval ) return rval; 06267 } 06268 06269 EntityHandle qconn[9] = { verts[0], verts[2], verts[12], verts[10], verts[1], 06270 verts[7], verts[11], verts[5], verts[6] }; 06271 EntityHandle tconn[7] = { verts[2], verts[4], verts[12], verts[3], verts[9], verts[7], verts[8] }; 06272 EntityHandle quad, tri; 06273 rval = mb.create_element( MBQUAD, qconn, 9, quad ); 06274 if( MB_SUCCESS != rval ) return rval; 06275 rval = mb.create_element( MBTRI, tconn, 7, tri ); 06276 if( MB_SUCCESS != rval ) return rval; 06277 06278 Range faces; 06279 faces.insert( quad ); 06280 faces.insert( tri ); 06281 06282 Range skin_verts; 06283 const int skin_vert_idx[] = { 0, 1, 2, 3, 4, 5, 9, 10, 11, 12 }; 06284 for( size_t i = 0; i < sizeof( skin_vert_idx ) / sizeof( skin_vert_idx[0] ); ++i ) 06285 skin_verts.insert( verts[skin_vert_idx[i]] ); 06286 06287 Skinner tool( &mb ); 06288 Range skin; 06289 06290 rval = tool.find_skin( 0, faces, true, skin, 0, use_adj, false ); 06291 if( MB_SUCCESS != rval ) 06292 { 06293 std::cout << "Vertex skinning failed with: " << mb.get_error_string( rval ) << std::endl; 06294 return rval; 06295 } 06296 if( skin != skin_verts ) 06297 { 06298 std::cout << "Skinner returned incorrect vertices." << std::endl; 06299 return MB_FAILURE; 06300 } 06301 06302 const int skin_edges[5][3] = { { 0, 1, 2 }, { 2, 3, 4 }, { 4, 9, 12 }, { 12, 11, 10 }, { 10, 5, 0 } }; 06303 skin.clear(); 06304 rval = tool.find_skin( 0, faces, false, skin, 0, use_adj, true ); 06305 if( MB_SUCCESS != rval ) 06306 { 06307 std::cout << "Edge skinning failed with: " << mb.get_error_string( rval ) << std::endl; 06308 return rval; 06309 } 06310 if( skin.size() != 5u ) 06311 { 06312 std::cout << "Skinner returned " << skin.size() << " vertices. Expected 5" << std::endl; 06313 return MB_FAILURE; 06314 } 06315 int num_quadratic = 0; 06316 const EntityHandle* conn; 06317 int len; 06318 for( Range::iterator i = skin.begin(); i != skin.end(); ++i ) 06319 { 06320 rval = mb.get_connectivity( *i, conn, len, false ); 06321 if( MB_SUCCESS != rval ) return rval; 06322 if( len == 3 ) 06323 num_quadratic++; 06324 else if( len != 2 ) 06325 { 06326 std::cerr << "Skinner created edge with " << len << " vertices" << std::endl; 06327 return MB_FAILURE; 06328 } 06329 } 06330 if( num_quadratic != 5 ) 06331 { 06332 std::cerr << num_quadratic << " of 5 created edges were quadratic" << std::endl; 06333 return MB_FAILURE; 06334 } 06335 06336 for( int i = 0; i < 5; ++i ) 06337 { 06338 bool found = false; 06339 for( Range::iterator j = skin.begin(); j != skin.end(); ++j ) 06340 { 06341 mb.get_connectivity( *j, conn, len, false ); 06342 if( conn[2] == verts[skin_edges[i][1]] ) 06343 { 06344 found = true; 06345 break; 06346 } 06347 } 06348 if( !found ) 06349 { 06350 std::cerr << "One or more skin edges is incorrect" << std::endl; 06351 return MB_FAILURE; 06352 } 06353 if( ( conn[0] != verts[skin_edges[i][0]] || conn[1] != verts[skin_edges[i][2]] ) && 06354 ( conn[0] != verts[skin_edges[i][2]] || conn[1] != verts[skin_edges[i][0]] ) ) 06355 { 06356 std::cerr << "Invalid skin edge connectivity" << std::endl; 06357 return MB_FAILURE; 06358 } 06359 } 06360 06361 return MB_SUCCESS; 06362 } 06363 ErrorCode mb_skin_higher_order_faces_test() 06364 { 06365 return mb_skin_higher_order_faces_common( false ); 06366 } 06367 ErrorCode mb_skin_adj_higher_order_faces_test() 06368 { 06369 return mb_skin_higher_order_faces_common( true ); 06370 } 06371 06372 // Test that skinning of higher-order elements works 06373 ErrorCode mb_skin_higher_order_regions_common( bool use_adj ) 06374 { 06375 // create mesh containing two 27-node hexes 06376 /* 06377 0,2---1,2---2,2---3,2---4,2 06378 | | | 06379 | | | 06380 0,1 1,1 2,1 3,1 4,1 06381 | | | 06382 | | | 06383 0,0---1,0---2,0---3,0---4,0 06384 */ 06385 06386 ErrorCode rval; 06387 Core moab; 06388 Interface& mb = moab; 06389 Range hexes; 06390 06391 EntityHandle verts[5][3][3]; 06392 for( int i = 0; i < 5; ++i ) 06393 for( int j = 0; j < 3; ++j ) 06394 for( int k = 0; k < 3; ++k ) 06395 { 06396 double coords[] = { static_cast< double >( i ), static_cast< double >( j ), 06397 static_cast< double >( k ) }; 06398 rval = mb.create_vertex( coords, verts[i][j][k] ); 06399 if( MB_SUCCESS != rval ) return rval; 06400 } 06401 06402 int hex_conn[][3] = { // corners 06403 { 0, 0, 0 }, 06404 { 2, 0, 0 }, 06405 { 2, 2, 0 }, 06406 { 0, 2, 0 }, 06407 { 0, 0, 2 }, 06408 { 2, 0, 2 }, 06409 { 2, 2, 2 }, 06410 { 0, 2, 2 }, 06411 // mid-edge 06412 { 1, 0, 0 }, 06413 { 2, 1, 0 }, 06414 { 1, 2, 0 }, 06415 { 0, 1, 0 }, 06416 { 0, 0, 1 }, 06417 { 2, 0, 1 }, 06418 { 2, 2, 1 }, 06419 { 0, 2, 1 }, 06420 { 1, 0, 2 }, 06421 { 2, 1, 2 }, 06422 { 1, 2, 2 }, 06423 { 0, 1, 2 }, 06424 // mid-face 06425 { 1, 0, 1 }, 06426 { 2, 1, 1 }, 06427 { 1, 2, 1 }, 06428 { 0, 1, 1 }, 06429 { 1, 1, 0 }, 06430 { 1, 1, 2 }, 06431 // mid-volume 06432 { 1, 1, 1 } }; 06433 06434 EntityHandle hexverts[2][27]; 06435 for( int i = 0; i < 2; ++i ) 06436 { 06437 EntityHandle h; 06438 for( int j = 0; j < 27; ++j ) 06439 hexverts[i][j] = verts[2 * i + hex_conn[j][0]][hex_conn[j][1]][hex_conn[j][2]]; 06440 rval = mb.create_element( MBHEX, hexverts[i], 27, h ); 06441 if( MB_SUCCESS != rval ) return rval; 06442 hexes.insert( h ); 06443 } 06444 06445 Range interior_verts; 06446 interior_verts.insert( verts[1][1][1] ); // mid-node of hex 1 06447 interior_verts.insert( verts[3][1][1] ); // mid-node of hex 2 06448 interior_verts.insert( verts[2][1][1] ); // mid-node of shared face 06449 06450 Skinner tool( &mb ); 06451 Range skin; 06452 06453 rval = tool.find_skin( 0, hexes, true, skin, 0, use_adj, false ); 06454 if( MB_SUCCESS != rval ) 06455 { 06456 std::cout << "Vertex skinning failed with: " << mb.get_error_string( rval ) << std::endl; 06457 return rval; 06458 } 06459 Range extra = intersect( skin, interior_verts ); 06460 if( !extra.empty() ) 06461 { 06462 std::cout << "Skinner returned " << extra.size() << " interior vertices" << std::endl; 06463 std::cout << extra << std::endl; 06464 return MB_FAILURE; 06465 } 06466 int num_vtx; 06467 mb.get_number_entities_by_dimension( 0, 0, num_vtx ); 06468 size_t num_skin = num_vtx - interior_verts.size(); 06469 if( skin.size() != num_skin ) 06470 { 06471 std::cout << "Skinner returned " << skin.size() << " of " << num_skin << " skin vertices" << std::endl; 06472 return MB_FAILURE; 06473 } 06474 06475 skin.clear(); 06476 rval = tool.find_skin( 0, hexes, false, skin, 0, use_adj, true ); 06477 if( MB_SUCCESS != rval ) 06478 { 06479 std::cout << "Element skinning failed with: " << mb.get_error_string( rval ) << std::endl; 06480 return rval; 06481 } 06482 06483 if( skin.size() > 10u ) 06484 { 06485 std::cout << "Skinner created too many faces" << std::endl; 06486 return MB_FAILURE; 06487 } 06488 06489 bool all_okay = true; 06490 bool faces[2][6] = { { false, false, false, false, false, false }, { false, false, false, false, false, false } }; 06491 const EntityHandle* conn; 06492 int len; 06493 for( Range::iterator it = skin.begin(); it != skin.end(); ++it ) 06494 { 06495 rval = mb.get_connectivity( *it, conn, len ); 06496 if( MB_SUCCESS != rval ) return rval; 06497 if( len != 9 ) 06498 { 06499 std::cout << "Skinner created face with " << len << " nodes" << std::endl; 06500 all_okay = false; 06501 continue; 06502 } 06503 06504 int valid, side, sense, offset; 06505 for( int h = 0; h < 2; ++h ) 06506 { 06507 valid = CN::SideNumber( MBHEX, hexverts[h], conn, 4, 2, side, sense, offset ); 06508 if( valid != 0 ) continue; 06509 if( sense != 1 ) 06510 { 06511 std::cout << "Skinner created reversed face for hex " << h << " side " << side << std::endl; 06512 all_okay = false; 06513 continue; 06514 } 06515 06516 int idx[9], len2; 06517 EntityType sidetype; 06518 CN::SubEntityNodeIndices( MBHEX, 27, 2, side, sidetype, len2, idx ); 06519 assert( sidetype == MBQUAD ); 06520 assert( len2 == 9 ); 06521 if( conn[offset] != hexverts[h][idx[0]] || conn[( offset + 1 ) % 4] != hexverts[h][idx[1]] || 06522 conn[( offset + 2 ) % 4] != hexverts[h][idx[2]] || conn[( offset + 3 ) % 4] != hexverts[h][idx[3]] || 06523 conn[4 + offset] != hexverts[h][idx[4]] || conn[4 + ( offset + 1 ) % 4] != hexverts[h][idx[5]] || 06524 conn[4 + ( offset + 2 ) % 4] != hexverts[h][idx[6]] || 06525 conn[4 + ( offset + 3 ) % 4] != hexverts[h][idx[7]] || conn[8] != hexverts[h][idx[8]] ) 06526 { 06527 std::cout << "Side " << side << " of hex " << h << " has invalid connectivity" << std::endl; 06528 all_okay = false; 06529 } 06530 06531 faces[h][side] = true; 06532 } 06533 } 06534 06535 for( int h = 0; h < 2; ++h ) 06536 { 06537 for( int i = 0; i < 6; ++i ) 06538 { 06539 if( ( h == 0 && i == 1 ) || ( h == 1 && i == 3 ) ) 06540 { 06541 if( faces[h][i] ) 06542 { 06543 std::cout << "Skinner created interior face for side " << i << " of hex " << h << std::endl; 06544 all_okay = false; 06545 } 06546 } 06547 else if( !faces[h][i] ) 06548 { 06549 std::cout << "Skinner failed to create side " << i << " of hex " << h << std::endl; 06550 all_okay = false; 06551 } 06552 } 06553 } 06554 06555 return all_okay ? MB_SUCCESS : MB_FAILURE; 06556 } 06557 06558 // Test that skinning of higher-order elements works 06559 ErrorCode mb_skin_higher_order_pyramids() 06560 { 06561 // create mesh containing 13-node pyramid 06562 /* 06563 06564 */ 06565 06566 ErrorCode rval; 06567 Core moab; 06568 Interface& mb = moab; 06569 Range pyramids; 06570 06571 // easier to create a 27 node grid, and then pick a 13-node pyramid 06572 EntityHandle verts[3][3][3]; 06573 for( int i = 0; i < 3; ++i ) 06574 for( int j = 0; j < 3; ++j ) 06575 for( int k = 0; k < 3; ++k ) 06576 { 06577 double coords[] = { static_cast< double >( i ), static_cast< double >( j ), 06578 static_cast< double >( k ) }; 06579 rval = mb.create_vertex( coords, verts[i][j][k] ); 06580 if( MB_SUCCESS != rval ) return rval; 06581 } 06582 06583 EntityHandle piramid1[13] = { 19, 25, 27, 21, 1, 22, 26, 24, 20, 10, 13, 14, 11 }; 06584 06585 EntityHandle h; 06586 06587 rval = mb.create_element( MBPYRAMID, piramid1, 13, h ); 06588 if( MB_SUCCESS != rval ) return rval; 06589 pyramids.insert( h ); 06590 06591 Range faces; 06592 rval = mb.get_adjacencies( pyramids, 2, true, faces, Interface::UNION ); 06593 // triangles should have 6 nodes, quads 8 nodes 06594 06595 if( MB_SUCCESS != rval ) return rval; 06596 06597 Range tris = faces.subset_by_type( MBTRI ); 06598 Range quads = faces.subset_by_type( MBQUAD ); 06599 06600 for( Range::iterator tit = tris.begin(); tit != tris.end(); tit++ ) 06601 { 06602 EntityHandle triangle = *tit; 06603 const EntityHandle* conn; 06604 int num_verts; 06605 rval = mb.get_connectivity( triangle, conn, num_verts ); 06606 if( MB_SUCCESS != rval ) return rval; 06607 if( 6 != num_verts ) return MB_FAILURE; 06608 } 06609 for( Range::iterator qit = quads.begin(); qit != quads.end(); qit++ ) 06610 { 06611 EntityHandle quad = *qit; 06612 const EntityHandle* conn; 06613 int num_verts; 06614 rval = mb.get_connectivity( quad, conn, num_verts ); 06615 if( MB_SUCCESS != rval ) return rval; 06616 if( 8 != num_verts ) return MB_FAILURE; 06617 } 06618 06619 return MB_SUCCESS; 06620 } 06621 ErrorCode mb_skin_higher_order_regions_test() 06622 { 06623 return mb_skin_higher_order_regions_common( false ); 06624 } 06625 ErrorCode mb_skin_adj_higher_order_regions_test() 06626 { 06627 return mb_skin_higher_order_regions_common( true ); 06628 } 06629 06630 ErrorCode mb_skin_reversed_common( int dim, bool use_adj ) 06631 { 06632 EntityType type, subtype; 06633 switch( dim ) 06634 { 06635 case 2: 06636 type = MBTRI; 06637 subtype = MBEDGE; 06638 break; 06639 case 3: 06640 type = MBTET; 06641 subtype = MBTRI; 06642 break; 06643 default: 06644 assert( false ); 06645 return MB_FAILURE; 06646 } 06647 06648 /* 3 06649 /|\ 06650 / | \ 06651 / | \ 06652 / | \ 06653 0----1----2 06654 */ 06655 06656 ErrorCode rval; 06657 Core moab; 06658 Interface& mb = moab; 06659 Range hexes; 06660 06661 double coords[][3] = { { 0, 0, 0 }, { 1, 0, 0 }, { 2, 0, 0 }, { 1, 2, 0 }, { 1, 2, 2 } }; 06662 EntityHandle verts[5]; 06663 const int nvtx = 2 + dim; 06664 for( int i = 0; i < nvtx; ++i ) 06665 { 06666 rval = mb.create_vertex( coords[i], verts[i] ); 06667 if( MB_SUCCESS != rval ) return rval; 06668 } 06669 // NOTE: order connectivity such that side 1 is shared! 06670 EntityHandle conn[2][4] = { { verts[0], verts[1], verts[3], verts[4] }, 06671 { verts[2], verts[3], verts[1], verts[4] } }; 06672 const int conn_len = dim + 1; 06673 Range elems; 06674 for( int i = 0; i < 2; ++i ) 06675 { 06676 EntityHandle h; 06677 rval = mb.create_element( type, conn[i], conn_len, h ); 06678 if( MB_SUCCESS != rval ) return rval; 06679 elems.insert( h ); 06680 } 06681 06682 // create one reversed side 06683 EntityHandle side_conn[3]; 06684 int side_indices[3] = { 0, 0, 0 }; 06685 CN::SubEntityVertexIndices( type, dim - 1, 0, side_indices ); 06686 side_conn[0] = conn[0][side_indices[1]]; 06687 side_conn[1] = conn[0][side_indices[0]]; 06688 side_conn[2] = conn[0][side_indices[2]]; 06689 EntityHandle side; 06690 rval = mb.create_element( subtype, side_conn, dim, side ); 06691 if( MB_SUCCESS != rval ) return rval; 06692 06693 Range forward, reverse; 06694 Skinner tool( &mb ); 06695 rval = tool.find_skin( 0, elems, false, forward, &reverse, use_adj, true ); 06696 if( MB_SUCCESS != rval ) 06697 { 06698 std::cout << "Skinner failed." << std::endl; 06699 return rval; 06700 } 06701 06702 // expect all faces created by the skinner to be forward, 06703 // so the only reversed side should be the one created above. 06704 if( reverse.size() != 1 || reverse.front() != side ) 06705 { 06706 std::cout << "Expected 1 reversed side, got: " << reverse.size() << std::endl; 06707 return MB_FAILURE; 06708 } 06709 06710 return MB_SUCCESS; 06711 } 06712 ErrorCode mb_skin_faces_reversed_test() 06713 { 06714 return mb_skin_reversed_common( 2, false ); 06715 } 06716 ErrorCode mb_skin_adj_faces_reversed_test() 06717 { 06718 return mb_skin_reversed_common( 2, true ); 06719 } 06720 ErrorCode mb_skin_regions_reversed_test() 06721 { 06722 return mb_skin_reversed_common( 3, false ); 06723 } 06724 ErrorCode mb_skin_adj_regions_reversed_test() 06725 { 06726 return mb_skin_reversed_common( 3, true ); 06727 } 06728 06729 ErrorCode mb_skin_subset_common( int dimension, bool use_adj ) 06730 { 06731 EntityType type; 06732 switch( dimension ) 06733 { 06734 case 2: 06735 type = MBTRI; 06736 break; 06737 case 3: 06738 type = MBPRISM; 06739 break; 06740 default: 06741 assert( false ); 06742 return MB_FAILURE; 06743 } 06744 06745 /* 0 06746 /|\ 06747 / | \ 06748 5 | 1 06749 |\ | /| 06750 | \|/ | 06751 | 6 | 06752 | /|\ | 06753 |/ | \| 06754 4 | 2 06755 \ | / 06756 \|/ 06757 3 06758 */ 06759 06760 ErrorCode rval; 06761 Core moab; 06762 Interface& mb = moab; 06763 Range expected_verts; 06764 06765 const double coords2D[7][2] = { { 0, 2 }, { 1, 1 }, { 1, -1 }, { 0, -2 }, { -1, -1 }, { -1, 1 }, { 0, 0 } }; 06766 EntityHandle verts[2][7] = { { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 } }; 06767 for( int d = 1; d < dimension; ++d ) 06768 { 06769 for( int i = 0; i < 7; ++i ) 06770 { 06771 double coords[3] = { coords2D[i][0], coords2D[i][1], static_cast< double >( d - 1 ) }; 06772 rval = mb.create_vertex( coords, verts[d - 1][i] ); 06773 if( MB_SUCCESS != rval ) return rval; 06774 if( i != 4 && i != 5 ) expected_verts.insert( verts[d - 1][i] ); 06775 } 06776 } 06777 06778 EntityHandle elems[6]; 06779 for( int i = 0; i < 6; ++i ) 06780 { 06781 EntityHandle conn[6] = { verts[0][6], verts[0][( i + 1 ) % 6], verts[0][i], 06782 verts[1][6], verts[1][( i + 1 ) % 6], verts[1][i] }; 06783 rval = mb.create_element( type, conn, CN::VerticesPerEntity( type ), elems[i] ); 06784 if( MB_SUCCESS != rval ) return rval; 06785 } 06786 06787 Range input; 06788 input.insert( elems[0] ); 06789 input.insert( elems[1] ); 06790 input.insert( elems[2] ); 06791 06792 Range skin; 06793 Skinner tool( &mb ); 06794 rval = tool.find_skin( 0, input, true, skin, 0, use_adj, false ); 06795 if( MB_SUCCESS != rval ) 06796 { 06797 std::cout << "Skinner failed to find skin vertices" << std::endl; 06798 return MB_FAILURE; 06799 } 06800 if( skin != expected_verts ) 06801 { 06802 std::cout << "Skinner returned incorrect skin vertices" << std::endl; 06803 return MB_FAILURE; 06804 } 06805 int n = 0; 06806 mb.get_number_entities_by_dimension( 0, dimension - 1, n ); 06807 if( n > 0 ) 06808 { 06809 std::cout << "Skinner created lower-dimension entities for vertex-only skinning" << std::endl; 06810 return MB_FAILURE; 06811 } 06812 06813 std::vector< EntityHandle > sv( skin.begin(), skin.end() ); 06814 std::vector< int > counts( sv.size(), 0 ); 06815 skin.clear(); 06816 rval = tool.find_skin( 0, input, false, skin, 0, use_adj, true ); 06817 if( MB_SUCCESS != rval ) 06818 { 06819 std::cout << "Skinner failed to find skin elements" << std::endl; 06820 return MB_FAILURE; 06821 } 06822 for( Range::iterator i = skin.begin(); i != skin.end(); ++i ) 06823 { 06824 const EntityHandle* conn; 06825 int len; 06826 rval = mb.get_connectivity( *i, conn, len ); 06827 if( MB_SUCCESS != rval ) return rval; 06828 for( int j = 0; j < len; ++j ) 06829 { 06830 size_t idx = std::find( sv.begin(), sv.end(), conn[j] ) - sv.begin(); 06831 if( idx == sv.size() ) 06832 { 06833 std::cout << "Skinner returned non-skin element" << std::endl; 06834 return MB_FAILURE; 06835 } 06836 counts[idx]++; 06837 } 06838 } 06839 for( size_t i = 0; i < counts.size(); ++i ) 06840 { 06841 if( counts[i] < dimension ) 06842 { // 2 for dim==2, {3,4,5} for dim==3 06843 std::cout << "Skinner did not return all skin elements" << std::endl; 06844 return MB_FAILURE; 06845 } 06846 } 06847 mb.get_number_entities_by_dimension( 0, dimension - 1, n ); 06848 if( (size_t)n != skin.size() ) 06849 { 06850 std::cout << "Skinner created extra lower-dimension entities" << std::endl; 06851 return MB_FAILURE; 06852 } 06853 06854 return MB_SUCCESS; 06855 } 06856 06857 ErrorCode mb_skin_faces_subset_test() 06858 { 06859 return mb_skin_subset_common( 2, false ); 06860 } 06861 ErrorCode mb_skin_adj_faces_subset_test() 06862 { 06863 return mb_skin_subset_common( 2, true ); 06864 } 06865 ErrorCode mb_skin_regions_subset_test() 06866 { 06867 return mb_skin_subset_common( 3, false ); 06868 } 06869 ErrorCode mb_skin_adj_regions_subset_test() 06870 { 06871 return mb_skin_subset_common( 3, true ); 06872 } 06873 06874 ErrorCode mb_skin_full_common( int dimension, bool use_adj ) 06875 { 06876 EntityType type; 06877 switch( dimension ) 06878 { 06879 case 2: 06880 type = MBQUAD; 06881 break; 06882 case 3: 06883 type = MBHEX; 06884 break; 06885 default: 06886 assert( false ); 06887 return MB_FAILURE; 06888 } 06889 06890 /* 06891 3----4----5 06892 | | | 06893 | | | 06894 0----1----2 06895 */ 06896 06897 ErrorCode rval; 06898 Core moab; 06899 Interface& mb = moab; 06900 06901 // create vertices 06902 const double coords2D[6][2] = { { 0, 0 }, { 1, 0 }, { 2, 0 }, { 0, 1 }, { 1, 1 }, { 2, 1 } }; 06903 EntityHandle v[2][6] = { { 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0 } }; 06904 for( int d = 1; d < dimension; ++d ) 06905 { 06906 for( int i = 0; i < 6; ++i ) 06907 { 06908 double coords[3] = { coords2D[i][0], coords2D[i][1], static_cast< double >( d - 1 ) }; 06909 rval = mb.create_vertex( coords, v[d - 1][i] ); 06910 if( MB_SUCCESS != rval ) return rval; 06911 } 06912 } 06913 06914 // create elements 06915 Range input; 06916 EntityHandle elems[2], econn[2][8]; 06917 ; 06918 for( int i = 0; i < 2; ++i ) 06919 { 06920 EntityHandle conn[8] = { v[0][i], v[0][i + 1], v[0][i + 4], v[0][i + 3], 06921 v[1][i], v[1][i + 1], v[1][i + 4], v[1][i + 3] }; 06922 memcpy( econn[i], conn, sizeof( conn ) ); 06923 rval = mb.create_element( type, conn, CN::VerticesPerEntity( type ), elems[i] ); 06924 if( MB_SUCCESS != rval ) return rval; 06925 input.insert( elems[i] ); 06926 } 06927 06928 // create sides 06929 // NOTE: Shared side is element 0 side 1 and element 1 side 3 06930 Range expected; 06931 for( int i = 0; i < CN::NumSubEntities( type, dimension - 1 ); ++i ) 06932 { 06933 EntityType subtype; 06934 int len; 06935 const short* indices = CN::SubEntityVertexIndices( type, dimension - 1, i, subtype, len ); 06936 EntityHandle conn[4]; 06937 assert( (size_t)len <= sizeof( conn ) / sizeof( conn[0] ) ); 06938 for( int j = 0; j < 2; ++j ) 06939 { 06940 if( j == 1 && i == 3 ) // don't create shared face twice 06941 continue; 06942 for( int k = 0; k < len; ++k ) 06943 conn[k] = econn[j][indices[k]]; 06944 EntityHandle h; 06945 rval = mb.create_element( subtype, conn, len, h ); 06946 if( MB_SUCCESS != rval ) return rval; 06947 if( j != 0 || i != 1 ) // don't insert shared face 06948 expected.insert( h ); 06949 } 06950 } 06951 06952 Range skin; 06953 Skinner tool( &mb ); 06954 rval = tool.find_skin( 0, input, false, skin, 0, use_adj, true ); 06955 if( MB_SUCCESS != rval ) 06956 { 06957 std::cout << "Skinner failed to find skin elements" << std::endl; 06958 return MB_FAILURE; 06959 } 06960 if( skin != expected ) 06961 { 06962 std::cout << "Skinner returned incorrect skin elements" << std::endl; 06963 return MB_FAILURE; 06964 } 06965 06966 int n = 0; 06967 mb.get_number_entities_by_dimension( 0, dimension - 1, n ); 06968 if( (size_t)n != expected.size() + 1 ) 06969 { 06970 std::cout << "Skinner created extra lower-dimension entities" << std::endl; 06971 return MB_FAILURE; 06972 } 06973 06974 return MB_SUCCESS; 06975 } 06976 06977 ErrorCode mb_skin_faces_full_test() 06978 { 06979 return mb_skin_full_common( 2, false ); 06980 } 06981 ErrorCode mb_skin_adj_faces_full_test() 06982 { 06983 return mb_skin_full_common( 2, true ); 06984 } 06985 ErrorCode mb_skin_regions_full_test() 06986 { 06987 return mb_skin_full_common( 3, false ); 06988 } 06989 ErrorCode mb_skin_adj_regions_full_test() 06990 { 06991 return mb_skin_full_common( 3, true ); 06992 } 06993 06994 ErrorCode mb_skin_adjacent_surf_patches() 06995 { 06996 Core moab; 06997 Interface& mb = moab; 06998 ErrorCode rval; 06999 Skinner tool( &mb ); 07000 07001 /* Mesh with vertices and quads numbered. 07002 Groups are indicated by letters {A,B,C,D} 07003 07004 0----1----2----3----4----5 07005 | (0)| (1)| (2)| (3)| (4)| 07006 | A | A | B | B | B | 07007 6----7----8----9---10---11 07008 | (5)| (6)| (7)| (8)| (9)| 07009 | A | A | A | B | B | 07010 12---13---14---15---16---17 07011 |(10)|(11)|(12)|(13)|(14)| 07012 | A | C | D | D | D | 07013 18---19---20---21---22---23 07014 |(15)|(16)|(17)|(18)|(19)| 07015 | C | C | C | D | D | 07016 24---25---26---27---28---29 07017 */ 07018 07019 const int num_vtx = 30; 07020 EntityHandle vtx[num_vtx]; 07021 for( int i = 0; i < 6; ++i ) 07022 { 07023 for( int j = 0; j < 5; ++j ) 07024 { 07025 double coords[3] = { static_cast< double >( i ), static_cast< double >( j ), 0 }; 07026 rval = mb.create_vertex( coords, vtx[6 * j + i] ); 07027 if( MB_SUCCESS != rval ) return rval; 07028 } 07029 } 07030 07031 EntityHandle quads[20]; 07032 for( int i = 0; i < 5; ++i ) 07033 { 07034 for( int j = 0; j < 4; ++j ) 07035 { 07036 int v = 6 * j + i; 07037 EntityHandle conn[4] = { vtx[v + 6], vtx[v + 7], vtx[v + 1], vtx[v + 0] }; 07038 rval = mb.create_element( MBQUAD, conn, 4, quads[5 * j + i] ); 07039 if( MB_SUCCESS != rval ) return rval; 07040 } 07041 } 07042 07043 // Define four groups of quads (as labeled above) 07044 const int Aquads[] = { 0, 1, 5, 6, 7, 10 }; 07045 const int Aquads_size = sizeof( Aquads ) / sizeof( Aquads[0] ); 07046 const int Bquads[] = { 2, 3, 4, 8, 9 }; 07047 const int Bquads_size = sizeof( Bquads ) / sizeof( Bquads[0] ); 07048 const int Cquads[] = { 11, 15, 16, 17 }; 07049 const int Cquads_size = sizeof( Cquads ) / sizeof( Cquads[0] ); 07050 const int Dquads[] = { 12, 13, 14, 18, 19 }; 07051 const int Dquads_size = sizeof( Dquads ) / sizeof( Dquads[0] ); 07052 07053 // Define the results we expect for each group as a loop 07054 // of vertex indices 07055 const int Askin[] = { 0, 1, 2, 8, 9, 15, 14, 13, 19, 18, 12, 6 }; 07056 const int Ashared[] = { -1, -1, 1, 1, 1, 3, 2, 2, 2, -1, -1, -1 }; 07057 const int Askin_size = sizeof( Askin ) / sizeof( Askin[0] ); 07058 const int Bskin[] = { 2, 3, 4, 5, 11, 17, 16, 15, 9, 8 }; 07059 const int Bshared[] = { -1, -1, -1, -1, -1, 3, 3, 0, 0, 0 }; 07060 const int Bskin_size = sizeof( Bskin ) / sizeof( Bskin[0] ); 07061 const int Cskin[] = { 18, 19, 13, 14, 20, 21, 27, 26, 25, 24 }; 07062 const int Cshared[] = { 0, 0, 0, 3, 3, 3, -1, -1, -1, -1 }; 07063 const int Cskin_size = sizeof( Cskin ) / sizeof( Cskin[0] ); 07064 const int Dskin[] = { 14, 15, 16, 17, 23, 29, 28, 27, 21, 20 }; 07065 const int Dshared[] = { 0, 1, 1, -1, -1, -1, -1, 2, 2, 2 }; 07066 const int Dskin_size = sizeof( Dskin ) / sizeof( Dskin[0] ); 07067 07068 // Make the above stuff indexable for easier looping 07069 const int* const gquads[4] = { Aquads, Bquads, Cquads, Dquads }; 07070 const int gquads_size[4] = { Aquads_size, Bquads_size, Cquads_size, Dquads_size }; 07071 const int* const skin[4] = { Askin, Bskin, Cskin, Dskin }; 07072 const int* const shared[4] = { Ashared, Bshared, Cshared, Dshared }; 07073 const int skin_size[4] = { Askin_size, Bskin_size, Cskin_size, Dskin_size }; 07074 07075 // Create an Range for each group of quads 07076 Range ranges[4]; 07077 for( int grp = 0; grp < 4; ++grp ) 07078 for( int i = 0; i < gquads_size[grp]; ++i ) 07079 ranges[grp].insert( quads[gquads[grp][i]] ); 07080 07081 // run test 4 times, one for each of: 07082 // o no adjacencies, no edges 07083 // o no adjacencies, edges 07084 // o adjacencies, edges 07085 // o adjacencies, no edges 07086 // 07087 // Be careful here: once we specify use_adj, we can't 07088 // unspecify it (the adjacencies will exist so the skinner 07089 // will use them, regardless of the passed flag.) 07090 int error_count = 0; 07091 for( int run = 0; run < 4; ++run ) 07092 { 07093 const bool use_adj = run > 1; 07094 if( run == 3 ) 07095 { 07096 Range dead; 07097 mb.get_entities_by_type( 0, MBEDGE, dead ); 07098 mb.delete_entities( dead ); 07099 } 07100 07101 // test each group 07102 Range edges[4]; 07103 for( int grp = 0; grp < 4; ++grp ) 07104 { 07105 // get the skin edges 07106 rval = tool.find_skin( 0, ranges[grp], 1, edges[grp], use_adj ); 07107 if( MB_SUCCESS != rval ) 07108 { 07109 std::cout << "Skinner failed for run " << run << " group " << grp << std::endl; 07110 return rval; 07111 } 07112 07113 // check that we have the expected result 07114 std::vector< bool > seen( skin_size[grp], false ); 07115 for( Range::iterator e = edges[grp].begin(); e != edges[grp].end(); ++e ) 07116 { 07117 const EntityHandle* conn; 07118 int len; 07119 rval = mb.get_connectivity( *e, conn, len ); 07120 if( MB_SUCCESS != rval ) return rval; 07121 if( len != 2 ) return MB_FAILURE; 07122 const int idx1 = std::find( vtx, vtx + num_vtx, conn[0] ) - vtx; 07123 const int idx2 = std::find( vtx, vtx + num_vtx, conn[1] ) - vtx; 07124 int pos = std::find( skin[grp], skin[grp] + skin_size[grp], idx1 ) - skin[grp]; 07125 if( pos == skin_size[grp] ) 07126 { 07127 std::cout << "Non-skin vertex in skin for run " << run << " group " << grp << std::endl; 07128 std::cout << "idx1 = " << idx1 << ", idx2 = " << idx2 << std::endl; 07129 ++error_count; 07130 continue; 07131 } 07132 07133 if( skin[grp][( pos + skin_size[grp] - 1 ) % skin_size[grp]] == idx2 ) 07134 pos = ( pos + skin_size[grp] - 1 ) % skin_size[grp]; 07135 else if( skin[grp][( pos + 1 ) % skin_size[grp]] != idx2 ) 07136 { 07137 std::cout << "Non-skin edge in skin for run " << run << " group " << grp << std::endl; 07138 std::cout << "idx1 = " << idx1 << ", idx2 = " << idx2 << std::endl; 07139 ++error_count; 07140 continue; 07141 } 07142 07143 if( seen[pos] ) 07144 { 07145 std::cout << "Duplicate edge in skin for run " << run << " group " << grp << std::endl; 07146 std::cout << "idx1 = " << idx1 << ", idx2 = " << idx2 << std::endl; 07147 ++error_count; 07148 } 07149 seen[pos] = true; 07150 07151 int shared_with = shared[grp][pos]; 07152 if( shared_with < 0 ) // not shared with another group 07153 continue; 07154 if( shared_with > grp ) // didn't skin other group yet 07155 continue; 07156 if( edges[shared_with].find( *e ) == edges[shared_with].end() ) 07157 { 07158 std::cout << "Skin edge duplicated for run " << run << " group " << grp << std::endl; 07159 std::cout << "idx1 = " << idx1 << ", idx2 = " << idx2 << " not in skin for group " << shared_with 07160 << std::endl; 07161 ++error_count; 07162 } 07163 } 07164 07165 int missing = std::count( seen.begin(), seen.end(), false ); 07166 if( missing ) 07167 { 07168 std::cout << "Missking " << missing << " skin edges for run " << run << " group " << grp << std::endl; 07169 error_count += missing; 07170 } 07171 } 07172 } 07173 07174 return error_count ? MB_FAILURE : MB_SUCCESS; 07175 } 07176 07177 static ErrorCode get_by_all_types_and_tag( Interface* mb, 07178 EntityHandle meshset, 07179 const Tag* tag_handles, 07180 const void* const* values, 07181 int num_tags, 07182 Range& result, 07183 int condition, 07184 bool recursive ) 07185 { 07186 ErrorCode rval; 07187 Range tmp; 07188 const EntityType LAST = recursive ? MBENTITYSET : MBMAXTYPE; 07189 for( EntityType t = MBVERTEX; t < LAST; ++t ) 07190 { 07191 tmp.clear(); 07192 rval = mb->get_entities_by_type_and_tag( meshset, t, tag_handles, values, num_tags, tmp, condition, recursive ); 07193 if( MB_SUCCESS != rval ) return rval; 07194 result.insert( tmp.begin(), tmp.end() ); 07195 } 07196 return MB_SUCCESS; 07197 } 07198 07199 /** Check that functions which accept a type return the 07200 * result for all types when passed MBMAXTYPE 07201 */ 07202 ErrorCode mb_type_is_maxtype_test() 07203 { 07204 Core moab; 07205 Interface* mb = &moab; 07206 ErrorCode rval = create_some_mesh( mb ); 07207 if( MB_SUCCESS != rval ) return rval; 07208 07209 Range r1, r2; 07210 rval = mb->get_entities_by_type( 0, MBMAXTYPE, r1, false );MB_CHK_ERR( rval ); 07211 rval = mb->get_entities_by_handle( 0, r2, false );MB_CHK_ERR( rval ); 07212 CHECK( r1 == r2 ); 07213 07214 std::vector< EntityHandle > v1, v2; 07215 rval = mb->get_entities_by_type( 0, MBMAXTYPE, v1, false );MB_CHK_ERR( rval ); 07216 rval = mb->get_entities_by_handle( 0, v2, false );MB_CHK_ERR( rval ); 07217 CHECK( v1 == v2 ); 07218 07219 int c1, c2; 07220 rval = mb->get_number_entities_by_type( 0, MBMAXTYPE, c1, false );MB_CHK_ERR( rval ); 07221 rval = mb->get_number_entities_by_handle( 0, c2, false );MB_CHK_ERR( rval ); 07222 CHECK( c1 == c2 ); 07223 07224 Range h1, h2; 07225 Range::iterator it = r1.begin() + r1.size() / 2; 07226 h1.insert( r1.begin(), it ); 07227 if( it != r1.end() ) h2.insert( ++it, r1.end() ); 07228 07229 EntityHandle s1, s2; 07230 rval = mb->create_meshset( MESHSET_SET, s1 );MB_CHK_ERR( rval ); 07231 rval = mb->create_meshset( MESHSET_ORDERED, s2 );MB_CHK_ERR( rval ); 07232 rval = mb->add_entities( s1, r1 );MB_CHK_ERR( rval ); 07233 rval = mb->add_entities( s2, r2 );MB_CHK_ERR( rval ); 07234 rval = mb->add_entities( s2, &s1, 1 );MB_CHK_ERR( rval ); 07235 07236 r1.clear(); 07237 r2.clear(); 07238 rval = mb->get_entities_by_type( s1, MBMAXTYPE, r1, false );MB_CHK_ERR( rval ); 07239 rval = mb->get_entities_by_handle( s1, r2, false );MB_CHK_ERR( rval ); 07240 CHECK( r1 == r2 ); 07241 07242 r1.clear(); 07243 r2.clear(); 07244 rval = mb->get_entities_by_type( s2, MBMAXTYPE, r1, false );MB_CHK_ERR( rval ); 07245 rval = mb->get_entities_by_handle( s2, r2, false );MB_CHK_ERR( rval ); 07246 CHECK( r1 == r2 ); 07247 07248 r1.clear(); 07249 r2.clear(); 07250 rval = mb->get_entities_by_type( s2, MBMAXTYPE, r1, true );MB_CHK_ERR( rval ); 07251 rval = mb->get_entities_by_handle( s2, r2, true );MB_CHK_ERR( rval ); 07252 CHECK( r1 == r2 ); 07253 07254 v1.clear(); 07255 v2.clear(); 07256 rval = mb->get_entities_by_type( s1, MBMAXTYPE, v1, false );MB_CHK_ERR( rval ); 07257 rval = mb->get_entities_by_handle( s1, v2, false );MB_CHK_ERR( rval ); 07258 CHECK( v1 == v2 ); 07259 07260 v1.clear(); 07261 v2.clear(); 07262 rval = mb->get_entities_by_type( s2, MBMAXTYPE, v1, false );MB_CHK_ERR( rval ); 07263 rval = mb->get_entities_by_handle( s2, v2, false );MB_CHK_ERR( rval ); 07264 CHECK( v1 == v2 ); 07265 07266 v1.clear(); 07267 v2.clear(); 07268 rval = mb->get_entities_by_type( s2, MBMAXTYPE, v1, true );MB_CHK_ERR( rval ); 07269 rval = mb->get_entities_by_handle( s2, v2, true );MB_CHK_ERR( rval ); 07270 CHECK( v1 == v2 ); 07271 07272 rval = mb->get_number_entities_by_type( s1, MBMAXTYPE, c1, false );MB_CHK_ERR( rval ); 07273 rval = mb->get_number_entities_by_handle( s1, c2, false );MB_CHK_ERR( rval ); 07274 CHECK( c1 == c2 ); 07275 07276 rval = mb->get_number_entities_by_type( s2, MBMAXTYPE, c1, false );MB_CHK_ERR( rval ); 07277 rval = mb->get_number_entities_by_handle( s2, c2, false );MB_CHK_ERR( rval ); 07278 CHECK( c1 == c2 ); 07279 07280 rval = mb->get_number_entities_by_type( s2, MBMAXTYPE, c1, true );MB_CHK_ERR( rval ); 07281 rval = mb->get_number_entities_by_handle( s2, c2, true );MB_CHK_ERR( rval ); 07282 CHECK( c1 == c2 ); 07283 07284 r1.clear(); 07285 rval = mb->get_entities_by_handle( s1, r1 );MB_CHK_ERR( rval ); 07286 Tag t1; 07287 rval = mb->tag_get_handle( "maxtype1", 1, MB_TYPE_INTEGER, t1, MB_TAG_SPARSE | MB_TAG_EXCL );MB_CHK_ERR( rval ); 07288 std::vector< int > d1( r1.size() ); 07289 Range::iterator ri; 07290 std::vector< int >::iterator ii = d1.begin(); 07291 for( ri = r1.begin(); ri != r1.end(); ++ri, ++ii ) 07292 *ii = ( (int)ID_FROM_HANDLE( *ri ) ) % 20; 07293 rval = mb->tag_set_data( t1, r1, &d1[0] );MB_CHK_ERR( rval ); 07294 07295 r1.clear(); 07296 r2.clear(); 07297 rval = mb->get_entities_by_type_and_tag( 0, MBMAXTYPE, &t1, 0, 1, r1, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07298 rval = mb->get_number_entities_by_type_and_tag( 0, MBMAXTYPE, &t1, 0, 1, c1, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07299 rval = get_by_all_types_and_tag( mb, 0, &t1, 0, 1, r2, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07300 CHECK( r1 == r2 ); 07301 CHECK( (unsigned)c1 == r2.size() ); 07302 07303 r1.clear(); 07304 r2.clear(); 07305 rval = mb->get_entities_by_type_and_tag( s1, MBMAXTYPE, &t1, 0, 1, r1, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07306 rval = mb->get_number_entities_by_type_and_tag( s1, MBMAXTYPE, &t1, 0, 1, c1, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07307 rval = get_by_all_types_and_tag( mb, s1, &t1, 0, 1, r2, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07308 CHECK( r1 == r2 ); 07309 CHECK( (unsigned)c1 == r2.size() ); 07310 07311 r1.clear(); 07312 r2.clear(); 07313 rval = mb->get_entities_by_type_and_tag( s2, MBMAXTYPE, &t1, 0, 1, r1, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07314 rval = mb->get_number_entities_by_type_and_tag( s2, MBMAXTYPE, &t1, 0, 1, c1, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07315 rval = get_by_all_types_and_tag( mb, s2, &t1, 0, 1, r2, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07316 CHECK( r1 == r2 ); 07317 CHECK( (unsigned)c1 == r2.size() ); 07318 07319 r1.clear(); 07320 r2.clear(); 07321 rval = mb->get_entities_by_type_and_tag( s2, MBMAXTYPE, &t1, 0, 1, r1, Interface::INTERSECT, true );MB_CHK_ERR( rval ); 07322 rval = mb->get_number_entities_by_type_and_tag( s2, MBMAXTYPE, &t1, 0, 1, c1, Interface::INTERSECT, true );MB_CHK_ERR( rval ); 07323 rval = get_by_all_types_and_tag( mb, s2, &t1, 0, 1, r2, Interface::INTERSECT, true );MB_CHK_ERR( rval ); 07324 CHECK( r1 == r2 ); 07325 CHECK( (unsigned)c1 == r2.size() ); 07326 07327 int value = 3; 07328 const void* vallist[2] = { &value, 0 }; 07329 07330 r1.clear(); 07331 r2.clear(); 07332 rval = mb->get_entities_by_type_and_tag( 0, MBMAXTYPE, &t1, vallist, 1, r1, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07333 rval = mb->get_number_entities_by_type_and_tag( 0, MBMAXTYPE, &t1, vallist, 1, c1, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07334 rval = get_by_all_types_and_tag( mb, 0, &t1, vallist, 1, r2, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07335 CHECK( r1 == r2 ); 07336 CHECK( (unsigned)c1 == r2.size() ); 07337 07338 r1.clear(); 07339 r2.clear(); 07340 rval = mb->get_entities_by_type_and_tag( s1, MBMAXTYPE, &t1, vallist, 1, r1, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07341 rval = mb->get_number_entities_by_type_and_tag( s1, MBMAXTYPE, &t1, vallist, 1, c1, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07342 rval = get_by_all_types_and_tag( mb, s1, &t1, vallist, 1, r2, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07343 CHECK( r1 == r2 ); 07344 CHECK( (unsigned)c1 == r2.size() ); 07345 07346 r1.clear(); 07347 r2.clear(); 07348 rval = mb->get_entities_by_type_and_tag( s2, MBMAXTYPE, &t1, vallist, 1, r1, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07349 rval = mb->get_number_entities_by_type_and_tag( s2, MBMAXTYPE, &t1, vallist, 1, c1, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07350 rval = get_by_all_types_and_tag( mb, s2, &t1, vallist, 1, r2, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07351 CHECK( r1 == r2 ); 07352 CHECK( (unsigned)c1 == r2.size() ); 07353 07354 r1.clear(); 07355 r2.clear(); 07356 rval = mb->get_entities_by_type_and_tag( s2, MBMAXTYPE, &t1, vallist, 1, r1, Interface::INTERSECT, true );MB_CHK_ERR( rval ); 07357 rval = mb->get_number_entities_by_type_and_tag( s2, MBMAXTYPE, &t1, vallist, 1, c1, Interface::INTERSECT, true );MB_CHK_ERR( rval ); 07358 rval = get_by_all_types_and_tag( mb, s2, &t1, vallist, 1, r2, Interface::INTERSECT, true );MB_CHK_ERR( rval ); 07359 CHECK( r1 == r2 ); 07360 CHECK( (unsigned)c1 == r2.size() ); 07361 07362 r1.clear(); 07363 r2.clear(); 07364 rval = mb->get_entities_by_handle( s1, r1 );MB_CHK_ERR( rval ); 07365 r2.insert( r1.back() ); 07366 r1.clear(); 07367 rval = mb->get_entities_by_handle( s2, r1 );MB_CHK_ERR( rval ); 07368 r2.insert( r1.front() ); 07369 07370 Tag t2; 07371 rval = mb->tag_get_handle( "maxtype2", 1, MB_TYPE_INTEGER, t2, MB_TAG_DENSE | MB_TAG_EXCL );MB_CHK_ERR( rval ); 07372 d1.resize( r2.size() ); 07373 ii = d1.begin(); 07374 ; 07375 for( ri = r2.begin(); ri != r2.end(); ++ri, ++ii ) 07376 *ii = ( (int)ID_FROM_HANDLE( *ri ) ) % 2; 07377 rval = mb->tag_set_data( t2, r2, &d1[0] );MB_CHK_ERR( rval ); 07378 07379 Tag tags[] = { t1, t2 }; 07380 07381 r1.clear(); 07382 r2.clear(); 07383 rval = mb->get_entities_by_type_and_tag( 0, MBMAXTYPE, tags, 0, 2, r1, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07384 rval = mb->get_number_entities_by_type_and_tag( 0, MBMAXTYPE, tags, 0, 2, c1, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07385 rval = get_by_all_types_and_tag( mb, 0, tags, 0, 2, r2, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07386 CHECK( r1 == r2 ); 07387 CHECK( (unsigned)c1 == r2.size() ); 07388 07389 r1.clear(); 07390 r2.clear(); 07391 rval = mb->get_entities_by_type_and_tag( s1, MBMAXTYPE, tags, 0, 2, r1, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07392 rval = mb->get_number_entities_by_type_and_tag( s1, MBMAXTYPE, tags, 0, 2, c1, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07393 rval = get_by_all_types_and_tag( mb, s1, tags, 0, 2, r2, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07394 CHECK( r1 == r2 ); 07395 CHECK( (unsigned)c1 == r2.size() ); 07396 07397 r1.clear(); 07398 r2.clear(); 07399 rval = mb->get_entities_by_type_and_tag( s2, MBMAXTYPE, tags, 0, 2, r1, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07400 rval = mb->get_number_entities_by_type_and_tag( s2, MBMAXTYPE, tags, 0, 2, c1, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07401 rval = get_by_all_types_and_tag( mb, s2, tags, 0, 2, r2, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07402 CHECK( r1 == r2 ); 07403 CHECK( (unsigned)c1 == r2.size() ); 07404 07405 r1.clear(); 07406 r2.clear(); 07407 rval = mb->get_entities_by_type_and_tag( s2, MBMAXTYPE, tags, 0, 2, r1, Interface::INTERSECT, true );MB_CHK_ERR( rval ); 07408 rval = mb->get_number_entities_by_type_and_tag( s2, MBMAXTYPE, tags, 0, 2, c1, Interface::INTERSECT, true );MB_CHK_ERR( rval ); 07409 rval = get_by_all_types_and_tag( mb, s2, tags, 0, 2, r2, Interface::INTERSECT, true );MB_CHK_ERR( rval ); 07410 CHECK( r1 == r2 ); 07411 CHECK( (unsigned)c1 == r2.size() ); 07412 07413 int val2 = 1; 07414 vallist[1] = &val2; 07415 07416 r1.clear(); 07417 r2.clear(); 07418 rval = mb->get_entities_by_type_and_tag( 0, MBMAXTYPE, tags, vallist, 2, r1, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07419 rval = mb->get_number_entities_by_type_and_tag( 0, MBMAXTYPE, tags, vallist, 2, c1, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07420 rval = get_by_all_types_and_tag( mb, 0, tags, vallist, 2, r2, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07421 CHECK( r1 == r2 ); 07422 CHECK( (unsigned)c1 == r2.size() ); 07423 07424 r1.clear(); 07425 r2.clear(); 07426 rval = mb->get_entities_by_type_and_tag( s1, MBMAXTYPE, tags, vallist, 2, r1, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07427 rval = mb->get_number_entities_by_type_and_tag( s1, MBMAXTYPE, tags, vallist, 2, c1, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07428 rval = get_by_all_types_and_tag( mb, s1, tags, vallist, 2, r2, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07429 CHECK( r1 == r2 ); 07430 CHECK( (unsigned)c1 == r2.size() ); 07431 07432 r1.clear(); 07433 r2.clear(); 07434 rval = mb->get_entities_by_type_and_tag( s2, MBMAXTYPE, tags, vallist, 2, r1, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07435 rval = mb->get_number_entities_by_type_and_tag( s2, MBMAXTYPE, tags, vallist, 2, c1, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07436 rval = get_by_all_types_and_tag( mb, s2, tags, vallist, 2, r2, Interface::INTERSECT, false );MB_CHK_ERR( rval ); 07437 CHECK( r1 == r2 ); 07438 CHECK( (unsigned)c1 == r2.size() ); 07439 07440 r1.clear(); 07441 r2.clear(); 07442 rval = mb->get_entities_by_type_and_tag( s2, MBMAXTYPE, tags, vallist, 2, r1, Interface::INTERSECT, true );MB_CHK_ERR( rval ); 07443 rval = mb->get_number_entities_by_type_and_tag( s2, MBMAXTYPE, tags, vallist, 2, c1, Interface::INTERSECT, true );MB_CHK_ERR( rval ); 07444 rval = get_by_all_types_and_tag( mb, s2, tags, vallist, 2, r2, Interface::INTERSECT, true );MB_CHK_ERR( rval ); 07445 CHECK( r1 == r2 ); 07446 CHECK( (unsigned)c1 == r2.size() ); 07447 07448 r1.clear(); 07449 r2.clear(); 07450 rval = mb->get_entities_by_type_and_tag( 0, MBMAXTYPE, tags, vallist, 2, r1, Interface::UNION, false );MB_CHK_ERR( rval ); 07451 rval = mb->get_number_entities_by_type_and_tag( 0, MBMAXTYPE, tags, vallist, 2, c1, Interface::UNION, false );MB_CHK_ERR( rval ); 07452 rval = get_by_all_types_and_tag( mb, 0, tags, vallist, 2, r2, Interface::UNION, false );MB_CHK_ERR( rval ); 07453 CHECK( r1 == r2 ); 07454 CHECK( (unsigned)c1 == r2.size() ); 07455 07456 r1.clear(); 07457 r2.clear(); 07458 rval = mb->get_entities_by_type_and_tag( s1, MBMAXTYPE, tags, vallist, 2, r1, Interface::UNION, false );MB_CHK_ERR( rval ); 07459 rval = mb->get_number_entities_by_type_and_tag( s1, MBMAXTYPE, tags, vallist, 2, c1, Interface::UNION, false );MB_CHK_ERR( rval ); 07460 rval = get_by_all_types_and_tag( mb, s1, tags, vallist, 2, r2, Interface::UNION, false );MB_CHK_ERR( rval ); 07461 CHECK( r1 == r2 ); 07462 CHECK( (unsigned)c1 == r2.size() ); 07463 07464 r1.clear(); 07465 r2.clear(); 07466 rval = mb->get_entities_by_type_and_tag( s2, MBMAXTYPE, tags, vallist, 2, r1, Interface::UNION, false );MB_CHK_ERR( rval ); 07467 rval = mb->get_number_entities_by_type_and_tag( s2, MBMAXTYPE, tags, vallist, 2, c1, Interface::UNION, false );MB_CHK_ERR( rval ); 07468 rval = get_by_all_types_and_tag( mb, s2, tags, vallist, 2, r2, Interface::UNION, false );MB_CHK_ERR( rval ); 07469 CHECK( r1 == r2 ); 07470 CHECK( (unsigned)c1 == r2.size() ); 07471 07472 r1.clear(); 07473 r2.clear(); 07474 rval = mb->get_entities_by_type_and_tag( s2, MBMAXTYPE, tags, vallist, 2, r1, Interface::UNION, true );MB_CHK_ERR( rval ); 07475 rval = mb->get_number_entities_by_type_and_tag( s2, MBMAXTYPE, tags, vallist, 2, c1, Interface::UNION, true );MB_CHK_ERR( rval ); 07476 rval = get_by_all_types_and_tag( mb, s2, tags, vallist, 2, r2, Interface::UNION, true );MB_CHK_ERR( rval ); 07477 CHECK( r1 == r2 ); 07478 CHECK( (unsigned)c1 == r2.size() ); 07479 07480 return MB_SUCCESS; 07481 } 07482 07483 /** Test behavior of various functions when passed the root set 07484 */ 07485 ErrorCode mb_root_set_test() 07486 { 07487 ErrorCode rval; 07488 Core moab; 07489 Interface* mb = &moab; 07490 EntityHandle rs = mb->get_root_set(); 07491 07492 // expect root set to have zero handle 07493 CHECK( !rs ); 07494 07495 // check type 07496 EntityType type = mb->type_from_handle( rs ); 07497 CHECK( MBENTITYSET == type ); 07498 07499 // Create a set to test with 07500 EntityHandle some_set; 07501 rval = mb->create_meshset( MESHSET_SET, some_set );MB_CHK_ERR( rval ); 07502 Range sets; 07503 sets.insert( some_set ); 07504 07505 int exp_dim = mb->dimension_from_handle( some_set ); 07506 int dim = mb->dimension_from_handle( rs ); 07507 CHECK( exp_dim == dim ); 07508 07509 // test some stuff that should fail 07510 rval = mb->clear_meshset( &rs, 1 ); 07511 CHECK( MB_SUCCESS != rval ); 07512 rval = mb->set_meshset_options( rs, MESHSET_ORDERED ); 07513 CHECK( MB_SUCCESS != rval ); 07514 rval = mb->subtract_meshset( rs, some_set ); 07515 CHECK( MB_SUCCESS != rval ); 07516 rval = mb->intersect_meshset( rs, some_set ); 07517 CHECK( MB_SUCCESS != rval ); 07518 rval = mb->unite_meshset( rs, some_set ); 07519 CHECK( MB_SUCCESS != rval ); 07520 07521 // add/remove should fail for root set? 07522 rval = mb->add_entities( rs, &some_set, 1 ); 07523 CHECK( MB_SUCCESS != rval ); 07524 rval = mb->remove_entities( rs, &some_set, 1 ); 07525 CHECK( MB_SUCCESS != rval ); 07526 rval = mb->replace_entities( rs, &some_set, &some_set, 1 ); 07527 CHECK( MB_SUCCESS != rval ); 07528 07529 // check flags 07530 unsigned flags; 07531 rval = mb->get_meshset_options( rs, flags ); 07532 CHECK( flags & MESHSET_SET ); 07533 CHECK( !( flags & MESHSET_ORDERED ) ); 07534 CHECK( flags & MESHSET_TRACK_OWNER ); 07535 07536 // contains tests 07537 bool c = mb->contains_entities( rs, &some_set, 1 ); 07538 CHECK( c ); 07539 07540 Range sets2; 07541 rval = mb->get_contained_meshsets( rs, sets2 );MB_CHK_ERR( rval ); 07542 CHECK( sets == sets2 ); 07543 07544 int count; 07545 rval = mb->num_contained_meshsets( rs, &count );MB_CHK_ERR( rval ); 07546 CHECK( count == (int)sets.size() ); 07547 07548 // The expected behavior for parent/child queries on the root set 07549 // is to return an error. 07550 07551 rval = mb->get_parent_meshsets( rs, sets2 ); 07552 CHECK( MB_SUCCESS != rval ); 07553 rval = mb->get_parent_meshsets( rs, sets2, 2 ); 07554 CHECK( MB_SUCCESS != rval ); 07555 07556 rval = mb->get_child_meshsets( rs, sets2 ); 07557 CHECK( MB_SUCCESS != rval ); 07558 rval = mb->get_child_meshsets( rs, sets2, 2 ); 07559 CHECK( MB_SUCCESS != rval ); 07560 07561 rval = mb->num_parent_meshsets( rs, &count ); 07562 CHECK( MB_SUCCESS != rval ); 07563 rval = mb->num_parent_meshsets( rs, &count, 2 ); 07564 CHECK( MB_SUCCESS != rval ); 07565 07566 rval = mb->num_child_meshsets( rs, &count ); 07567 CHECK( MB_SUCCESS != rval ); 07568 rval = mb->num_child_meshsets( rs, &count, 2 ); 07569 CHECK( MB_SUCCESS != rval ); 07570 07571 rval = mb->add_parent_meshset( rs, some_set ); 07572 CHECK( MB_SUCCESS != rval ); 07573 rval = mb->add_parent_meshsets( rs, &some_set, 1 ); 07574 CHECK( MB_SUCCESS != rval ); 07575 rval = mb->add_child_meshset( rs, some_set ); 07576 CHECK( MB_SUCCESS != rval ); 07577 rval = mb->add_child_meshsets( rs, &some_set, 1 ); 07578 CHECK( MB_SUCCESS != rval ); 07579 rval = mb->add_parent_child( rs, some_set ); 07580 CHECK( MB_SUCCESS != rval ); 07581 rval = mb->remove_parent_child( rs, some_set ); 07582 CHECK( MB_SUCCESS != rval ); 07583 rval = mb->remove_parent_meshset( rs, some_set ); 07584 CHECK( MB_SUCCESS != rval ); 07585 rval = mb->remove_child_meshset( rs, some_set ); 07586 CHECK( MB_SUCCESS != rval ); 07587 07588 return MB_SUCCESS; 07589 } 07590 07591 /* Create a regular 2x2x2 hex mesh */ 07592 ErrorCode create_some_mesh( Interface* iface ) 07593 { 07594 const double coords[] = { 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 1, 0, 1, 1, 0, 2, 1, 0, 0, 2, 0, 1, 2, 0, 2, 2, 0, 07595 0, 0, 1, 1, 0, 1, 2, 0, 1, 0, 1, 1, 1, 1, 1, 2, 1, 1, 0, 2, 1, 1, 2, 1, 2, 2, 1, 07596 0, 0, 2, 1, 0, 2, 2, 0, 2, 0, 1, 2, 1, 1, 2, 2, 1, 2, 0, 2, 2, 1, 2, 2, 2, 2, 2 }; 07597 const size_t num_vtx = sizeof( coords ) / sizeof( double ) / 3; 07598 assert( num_vtx == 27u ); 07599 07600 const int conn[] = { 0, 1, 4, 3, 9, 10, 13, 12, 1, 2, 5, 4, 10, 11, 14, 13, 3, 4, 7, 6, 12, 13, 07601 16, 15, 4, 5, 8, 9, 13, 14, 17, 16, 9, 10, 13, 12, 18, 19, 22, 21, 10, 11, 14, 13, 07602 19, 20, 23, 22, 12, 13, 16, 15, 21, 22, 25, 24, 13, 14, 17, 18, 22, 23, 26, 25 }; 07603 const size_t num_elem = sizeof( conn ) / sizeof( conn[0] ) / 8; 07604 assert( num_elem == 8u ); 07605 07606 EntityHandle verts[num_vtx], hexes[num_elem]; 07607 for( size_t i = 0; i < num_vtx; ++i ) 07608 { 07609 ErrorCode err = iface->create_vertex( coords + 3 * i, verts[i] ); 07610 if( MB_SUCCESS != err ) return err; 07611 } 07612 07613 for( size_t i = 0; i < num_elem; ++i ) 07614 { 07615 EntityHandle c[8]; 07616 for( int j = 0; j < 8; ++j ) 07617 { 07618 assert( conn[8 * i + j] < (int)num_vtx ); 07619 c[j] = verts[conn[8 * i + j]]; 07620 } 07621 ErrorCode err = iface->create_element( MBHEX, c, 8, hexes[i] ); 07622 if( MB_SUCCESS != err ) return err; 07623 } 07624 07625 return MB_SUCCESS; 07626 } 07627 07628 inline bool contained( const std::vector< EntityHandle >& list, EntityHandle h ) 07629 { 07630 std::vector< EntityHandle >::const_iterator i; 07631 i = std::lower_bound( list.begin(), list.end(), h ); 07632 return i != list.end() && *i == h; 07633 } 07634 07635 ErrorCode check_valid_connectivity( Interface* iface ) 07636 { 07637 ErrorCode rval; 07638 07639 // get sorted array of vertex handles so that we can 07640 // check that all vertices in connectivity are valid 07641 // handles 07642 std::vector< EntityHandle > vertices, storage; 07643 rval = iface->get_entities_by_type( 0, MBVERTEX, vertices );MB_CHK_ERR( rval ); 07644 std::sort( vertices.begin(), vertices.end() ); 07645 07646 // get all the elements 07647 Range elements, tmp; 07648 for( int d = 1; d < 4; ++d ) 07649 { 07650 tmp.clear(); 07651 rval = iface->get_entities_by_dimension( 0, d, tmp );MB_CHK_ERR( rval ); 07652 elements.merge( tmp ); 07653 } 07654 07655 // check that all connectivity handles are valid 07656 Range::iterator it; 07657 ErrorCode result = MB_SUCCESS; 07658 for( it = elements.begin(); it != elements.end(); ++it ) 07659 { 07660 const EntityHandle* conn; 07661 int len; 07662 rval = iface->get_connectivity( *it, conn, len, false, &storage );MB_CHK_ERR( rval ); 07663 for( int i = 0; i < len; ++i ) 07664 { 07665 if( !contained( vertices, conn[i] ) ) 07666 { 07667 printf( "Invalid handle (%s %d) in connectivity of %s %d\n", 07668 CN::EntityTypeName( TYPE_FROM_HANDLE( conn[i] ) ), (int)ID_FROM_HANDLE( conn[i] ), 07669 CN::EntityTypeName( TYPE_FROM_HANDLE( *it ) ), (int)ID_FROM_HANDLE( *it ) ); 07670 result = MB_FAILURE; 07671 } 07672 } 07673 } 07674 07675 return result; 07676 } 07677 07678 static void usage( const char* exe ) 07679 { 07680 cerr << "Usage: " << exe << " [-nostress] [-d input_file_dir]\n"; 07681 exit( 1 ); 07682 } 07683 07684 int number_tests = 0; 07685 int number_tests_failed = 0; 07686 #define RUN_TEST_ERR( A ) _run_test( ( A ), #A ) 07687 07688 typedef ErrorCode ( *TestFunc )(); 07689 static int _run_test( TestFunc func, const char* func_str ) 07690 { 07691 ++number_tests; 07692 return run_test( func, func_str ); 07693 } 07694 07695 /*! 07696 main routine for test harness 07697 */ 07698 int main( int argc, char* argv[] ) 07699 { 07700 #ifdef MOAB_HAVE_MPI 07701 int fail = MPI_Init( &argc, &argv ); 07702 if( fail ) return fail; 07703 #endif 07704 07705 argv0 = argv[0]; 07706 07707 // Check command line arg to see if we should avoid doing the stress test 07708 #ifdef MOAB_HAVE_NETCDF 07709 bool stress_test = true; 07710 #endif 07711 07712 std::cout << "Size of mConnMap = " << sizeof( CN::mConnectivityMap ) << std::endl; 07713 std::cout << "Size of mUpConnMap = " << sizeof( CN::mUpConnMap ) << std::endl; 07714 std::cout << "Size of CN = " << sizeof( CN ) << std::endl; 07715 07716 for( int i = 1; i < argc; ++i ) 07717 { 07718 07719 if( string( argv[i] ) == "-h" || string( argv[i] ) == "--help" ) usage( argv[0] ); 07720 #if MOAB_HAVE_NETCDF 07721 else if( string( argv[i] ) == "-nostress" ) 07722 stress_test = false; 07723 #endif 07724 else 07725 { 07726 cerr << "Invalid argument: " << argv[i] << endl; 07727 usage( argv[0] ); 07728 } 07729 } 07730 07731 // Print out Header information 07732 07733 cout << "\n\nMOAB Comprehensive test suite:\n\n"; 07734 07735 number_tests = number_tests_failed = 0; 07736 number_tests_failed += RUN_TEST_ERR( mb_adjacent_vertex_test ); 07737 number_tests_failed += RUN_TEST_ERR( mb_adjacencies_create_delete_test ); 07738 number_tests_failed += RUN_TEST_ERR( mb_upward_adjacencies_test ); 07739 number_tests_failed += RUN_TEST_ERR( mb_adjacent_create_test ); 07740 number_tests_failed += RUN_TEST_ERR( mb_vertex_coordinate_test ); 07741 number_tests_failed += RUN_TEST_ERR( mb_vertex_tag_test ); 07742 number_tests_failed += RUN_TEST_ERR( mb_temporary_test ); 07743 number_tests_failed += RUN_TEST_ERR( mb_mesh_sets_set_test ); 07744 number_tests_failed += RUN_TEST_ERR( mb_mesh_sets_list_test ); 07745 number_tests_failed += RUN_TEST_ERR( mb_mesh_set_parent_child_test ); 07746 number_tests_failed += RUN_TEST_ERR( mb_mesh_set_set_appends ); 07747 number_tests_failed += RUN_TEST_ERR( mb_mesh_set_list_appends ); 07748 number_tests_failed += RUN_TEST_ERR( mb_mesh_set_root_appends ); 07749 number_tests_failed += RUN_TEST_ERR( mb_mesh_set_set_replace_test ); 07750 number_tests_failed += RUN_TEST_ERR( mb_mesh_set_list_replace_test ); 07751 number_tests_failed += RUN_TEST_ERR( mb_mesh_set_flag_test ); 07752 number_tests_failed += RUN_TEST_ERR( mb_mesh_set_set_add_remove_test ); 07753 number_tests_failed += RUN_TEST_ERR( mb_dense_tag_test ); 07754 number_tests_failed += RUN_TEST_ERR( mb_sparse_tag_test ); 07755 number_tests_failed += RUN_TEST_ERR( mb_higher_order_test ); 07756 number_tests_failed += RUN_TEST_ERR( mb_bit_tags_test ); 07757 #if MOAB_HAVE_NETCDF 07758 number_tests_failed += RUN_TEST_ERR( mb_adjacencies_test ); 07759 number_tests_failed += RUN_TEST_ERR( mb_tags_test ); 07760 number_tests_failed += RUN_TEST_ERR( mb_delete_mesh_test ); 07761 number_tests_failed += RUN_TEST_ERR( mb_entity_conversion_test ); 07762 number_tests_failed += RUN_TEST_ERR( mb_mesh_set_tracking_test ); 07763 #endif 07764 number_tests_failed += RUN_TEST_ERR( mb_forced_adjacencies_test ); 07765 number_tests_failed += RUN_TEST_ERR( mb_canon_number_test ); 07766 number_tests_failed += RUN_TEST_ERR( mb_side_number_test ); 07767 number_tests_failed += RUN_TEST_ERR( mb_poly_test ); 07768 number_tests_failed += RUN_TEST_ERR( mb_topo_util_test ); 07769 number_tests_failed += RUN_TEST_ERR( mb_split_test ); 07770 number_tests_failed += RUN_TEST_ERR( mb_range_seq_intersect_test ); 07771 number_tests_failed += RUN_TEST_ERR( mb_poly_adjacency_test ); 07772 number_tests_failed += RUN_TEST_ERR( mb_poly_adjacency_test2 ); 07773 number_tests_failed += RUN_TEST_ERR( mb_memory_use_test ); 07774 number_tests_failed += RUN_TEST_ERR( mb_skin_curve_test ); 07775 number_tests_failed += RUN_TEST_ERR( mb_skin_curve_adj_test ); 07776 number_tests_failed += RUN_TEST_ERR( mb_skin_surface_test ); 07777 number_tests_failed += RUN_TEST_ERR( mb_skin_surface_adj_test ); 07778 number_tests_failed += RUN_TEST_ERR( mb_skin_volume_test ); 07779 number_tests_failed += RUN_TEST_ERR( mb_skin_volume_adj_test ); 07780 number_tests_failed += RUN_TEST_ERR( mb_skin_surf_verts_test ); 07781 number_tests_failed += RUN_TEST_ERR( mb_skin_vol_verts_test ); 07782 number_tests_failed += RUN_TEST_ERR( mb_skin_surf_verts_elems_test ); 07783 number_tests_failed += RUN_TEST_ERR( mb_skin_vol_verts_elems_test ); 07784 number_tests_failed += RUN_TEST_ERR( mb_skin_poly_test ); 07785 number_tests_failed += RUN_TEST_ERR( mb_skin_higher_order_faces_test ); 07786 number_tests_failed += RUN_TEST_ERR( mb_skin_higher_order_regions_test ); 07787 number_tests_failed += RUN_TEST_ERR( mb_skin_adj_higher_order_faces_test ); 07788 number_tests_failed += RUN_TEST_ERR( mb_skin_adj_higher_order_regions_test ); 07789 number_tests_failed += RUN_TEST_ERR( mb_skin_faces_reversed_test ); 07790 number_tests_failed += RUN_TEST_ERR( mb_skin_adj_faces_reversed_test ); 07791 number_tests_failed += RUN_TEST_ERR( mb_skin_regions_reversed_test ); 07792 number_tests_failed += RUN_TEST_ERR( mb_skin_adj_regions_reversed_test ); 07793 number_tests_failed += RUN_TEST_ERR( mb_skin_faces_subset_test ); 07794 number_tests_failed += RUN_TEST_ERR( mb_skin_adj_faces_subset_test ); 07795 number_tests_failed += RUN_TEST_ERR( mb_skin_regions_subset_test ); 07796 number_tests_failed += RUN_TEST_ERR( mb_skin_adj_regions_subset_test ); 07797 number_tests_failed += RUN_TEST_ERR( mb_skin_faces_full_test ); 07798 number_tests_failed += RUN_TEST_ERR( mb_skin_adj_faces_full_test ); 07799 number_tests_failed += RUN_TEST_ERR( mb_skin_regions_full_test ); 07800 number_tests_failed += RUN_TEST_ERR( mb_skin_adj_regions_full_test ); 07801 number_tests_failed += RUN_TEST_ERR( mb_skin_adjacent_surf_patches ); 07802 number_tests_failed += RUN_TEST_ERR( mb_skin_scd_test ); 07803 number_tests_failed += RUN_TEST_ERR( mb_skin_fileset_test ); 07804 number_tests_failed += RUN_TEST_ERR( mb_read_fail_test ); 07805 number_tests_failed += RUN_TEST_ERR( mb_enum_string_test ); 07806 number_tests_failed += RUN_TEST_ERR( mb_merge_update_test ); 07807 number_tests_failed += RUN_TEST_ERR( mb_type_is_maxtype_test ); 07808 number_tests_failed += RUN_TEST_ERR( mb_root_set_test ); 07809 #if MOAB_HAVE_NETCDF 07810 number_tests_failed += RUN_TEST_ERR( mb_merge_test ); 07811 if( stress_test ) number_tests_failed += RUN_TEST_ERR( mb_stress_test ); 07812 #endif 07813 07814 // summary 07815 07816 cout << "\nMB TEST SUMMARY: \n" 07817 << " Number Tests: " << number_tests << "\n" 07818 << " Number Successful: " << number_tests - number_tests_failed << "\n" 07819 << " Number Failed: " << number_tests_failed << "\n\n"; 07820 07821 #ifdef MOAB_HAVE_MPI 07822 fail = MPI_Finalize(); 07823 if( fail ) return fail; 07824 #endif 07825 07826 return number_tests_failed; 07827 }