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();