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 // test the structured sequence stuff 00018 // 00019 00020 #include "moab/ScdInterface.hpp" 00021 #include "moab/Core.hpp" 00022 #include "TestUtil.hpp" 00023 00024 #include <iostream> 00025 00026 using namespace moab; 00027 00028 void test_vertex_seq(); 00029 void test_element_seq(); 00030 void test_periodic_seq(); 00031 void test_parallel_partitions(); 00032 00033 ErrorCode test_parallel_partition( int* gdims, int nprocs, int part_method ); 00034 00035 ErrorCode check_vertex_sequence( const ScdBox* this_box, 00036 const int imin, 00037 const int jmin, 00038 const int kmin, 00039 const int imax, 00040 const int jmax, 00041 const int kmax, 00042 const EntityHandle this_start ); 00043 ErrorCode evaluate_vertex_box( ScdBox* this_box ); 00044 ErrorCode check_element_sequence( const ScdBox* this_box, 00045 const HomCoord& min_params, 00046 const HomCoord& max_params, 00047 const EntityHandle this_start ); 00048 ErrorCode evaluate_element_sequence( ScdBox* this_box ); 00049 ErrorCode eseq_test1a( ScdInterface* scdi, HomCoord tmp_min, HomCoord tmp_max ); 00050 ErrorCode eseq_test1b( ScdInterface* scdi, HomCoord tmp_min, HomCoord tmp_max ); 00051 ErrorCode eseq_test1c( ScdInterface* scdi, const HomCoord& tmp_min, const HomCoord& tmp_max ); 00052 ErrorCode eseq_test2a( ScdInterface* scdi, const HomCoord& tmp_min, const HomCoord& tmp_max ); 00053 ErrorCode eseq_test2b( ScdInterface* scdi ); 00054 ErrorCode eseq_test2c( ScdInterface* scdi ); 00055 ErrorCode eseq_test2d( ScdInterface* scdi ); 00056 00057 ErrorCode create_1d_3_sequences( ScdInterface* scdi, HomCoord tmp_min, HomCoord tmp_max, ScdBox** vseq, ScdBox** eseq ); 00058 00059 ErrorCode create_2d_3_sequences( ScdInterface* scdi, ScdBox** vseq, ScdBox** eseq ); 00060 00061 ErrorCode create_2dtri_3_sequences( ScdInterface* scdi, 00062 const int int1, 00063 const int int2, 00064 const int int3, 00065 ScdBox** vseq, 00066 ScdBox** eseq ); 00067 ErrorCode create_3dtri_3_sequences( ScdInterface* scdi, 00068 const int int1, 00069 const int int2, 00070 const int int3, 00071 const int int4, 00072 ScdBox** vseq, 00073 ScdBox** eseq ); 00074 ErrorCode access_adjacencies( ScdBox* box ); 00075 00076 void test_partition_methods(); 00077 00078 void test_partition_method( ScdParData::PartitionMethod pm ); 00079 00080 // first comes general-capability code used by various tests; main and test functions 00081 // come after these, starting with main 00082 ErrorCode check_vertex_sequence( const ScdBox* this_box, 00083 const int imin, 00084 const int jmin, 00085 const int kmin, 00086 const int imax, 00087 const int jmax, 00088 const int kmax, 00089 const EntityHandle this_start ) 00090 { 00091 ErrorCode result = MB_SUCCESS; 00092 00093 // check data stored in sequence with that in arg list 00094 if( imin != this_box->box_min()[0] || jmin != this_box->box_min()[1] || kmin != this_box->box_min()[2] || 00095 imax != this_box->box_max()[0] || jmax != this_box->box_max()[1] || kmax != this_box->box_max()[2] ) 00096 { 00097 std::cout << "min/max params not correct for a sequence." << std::endl; 00098 result = MB_FAILURE; 00099 } 00100 00101 HomCoord ijk1 = this_box->box_min(), ijk2 = this_box->box_max(), dijk = this_box->box_size(); 00102 if( ijk2 - ijk1 + HomCoord( 1, 1, 1, 0 ) != dijk ) 00103 { 00104 std::cout << "min_params/max_params/param_extents functions returned inconsistent results" << std::endl; 00105 result = MB_FAILURE; 00106 } 00107 00108 if( this_start != this_box->start_vertex() ) 00109 { 00110 std::cout << "Start handle for sequence wrong." << std::endl; 00111 result = MB_FAILURE; 00112 } 00113 00114 return result; 00115 } 00116 00117 ErrorCode check_element_sequence( const ScdBox* this_box, 00118 const HomCoord& min_params, 00119 const HomCoord& max_params, 00120 const EntityHandle this_start ) 00121 { 00122 ErrorCode result = MB_SUCCESS; 00123 00124 // check data stored in sequence with that in arg list 00125 if( min_params.i() != this_box->box_min()[0] || min_params.j() != this_box->box_min()[1] || 00126 min_params.k() != this_box->box_min()[2] || max_params.i() != this_box->box_max()[0] || 00127 max_params.j() != this_box->box_max()[1] || max_params.k() != this_box->box_max()[2] ) 00128 { 00129 std::cout << "min/max params not correct for a sequence." << std::endl; 00130 result = MB_FAILURE; 00131 } 00132 00133 if( this_box->box_max() - this_box->box_min() + HomCoord( 1, 1, 1, 0 ) != this_box->box_size() ) 00134 { 00135 std::cout << "min_params/max_params/param_extents functions returned inconsistent results" << std::endl; 00136 result = MB_FAILURE; 00137 } 00138 00139 if( this_start != this_box->start_element() ) 00140 { 00141 std::cout << "Start handle for sequence wrong." << std::endl; 00142 result = MB_FAILURE; 00143 } 00144 00145 if( this_box->boundary_complete() == false ) 00146 { 00147 std::cout << "Element sequence didn't pass boundary_complete test." << std::endl; 00148 result = MB_FAILURE; 00149 } 00150 00151 return result; 00152 } 00153 00154 ErrorCode evaluate_vertex_sequence( ScdBox* this_box ) 00155 { 00156 ErrorCode result = MB_SUCCESS; 00157 00158 // first get the parametric extents 00159 HomCoord ijk1 = this_box->box_min(), ijk2 = this_box->box_max(); 00160 00161 // then the start vertex 00162 EntityHandle start_handle = this_box->start_vertex(); 00163 00164 // now evaluate all the vertices in forward and reverse 00165 EntityHandle tmp_handle, tmp_handle2; 00166 for( int i = ijk1[0]; i <= ijk2[0]; i++ ) 00167 { 00168 for( int j = ijk1[1]; j <= ijk2[1]; j++ ) 00169 { 00170 for( int k = ijk1[2]; k <= ijk2[2]; k++ ) 00171 { 00172 // compute what the vertex handle is supposed to be 00173 EntityHandle this_handle = start_handle + ( i - ijk1[0] ) + 00174 ( j - ijk1[1] ) * ( ijk2[0] - ijk1[0] + 1 ) + 00175 ( k - ijk1[2] ) * ( ijk2[1] - ijk1[1] + 1 ) * ( ijk2[0] - ijk1[0] + 1 ); 00176 00177 // get_vertex variants 00178 tmp_handle = this_box->get_vertex( i, j, k ); 00179 00180 if( this_box->get_vertex( i, j, k ) != this_handle ) 00181 { 00182 std::cout << "vertex seq: get_vertex(i, j, k) didn't work, i, j, k = " << i << ", " << j << ", " 00183 << k << "." << std::endl; 00184 result = MB_FAILURE; 00185 } 00186 00187 tmp_handle2 = this_box->get_vertex( HomCoord( i, j, k ) ); 00188 if( tmp_handle2 != this_handle ) 00189 { 00190 std::cout << "vertex seq: get_vertex(HomCoord) didn't work, i, j, k = " << i << ", " << j << ", " 00191 << k << "." << std::endl; 00192 result = MB_FAILURE; 00193 } 00194 00195 int itmp, jtmp, ktmp; 00196 itmp = jtmp = ktmp = 0xdeadbeef; 00197 ErrorCode tmp_result = this_box->get_params( tmp_handle, itmp, jtmp, ktmp ); 00198 if( MB_SUCCESS != tmp_result || i != itmp || j != jtmp || k != ktmp ) 00199 { 00200 std::cout << "vertex seq: get_params didn't work, i, j, k = " << i << ", " << j << ", " << k 00201 << "; itmp, jtmp, ktmp = " << itmp << ", " << jtmp << ", " << ktmp << std::endl; 00202 result = MB_FAILURE; 00203 } 00204 00205 if( !this_box->contains( i, j, k ) || !this_box->contains( HomCoord( i, j, k ) ) ) 00206 { 00207 std::cout << "vertex seq: contains didn't work, i, j, k = " << i << ", " << j << ", " << k << "." 00208 << std::endl; 00209 result = MB_FAILURE; 00210 } 00211 } 00212 } 00213 } 00214 00215 return result; 00216 } 00217 00218 ErrorCode evaluate_element_sequence( ScdBox* this_box ) 00219 { 00220 ErrorCode result = MB_SUCCESS; 00221 00222 // first get the parametric extents 00223 HomCoord ijk1 = this_box->box_min(), ijk2 = this_box->box_max(); 00224 00225 // now evaluate all the vertices and elements in forward and reverse 00226 EntityHandle tmp_handle, tmp_handle2; 00227 int is_periodic_i = ( this_box->locally_periodic_i() ? 1 : 0 ), 00228 is_periodic_j = ( this_box->locally_periodic_j() ? 1 : 0 ); 00229 for( int i = ijk1[0]; i < ijk2[0] + is_periodic_i; i++ ) 00230 { 00231 for( int j = ijk1[1]; j < ijk2[1] + is_periodic_j; j++ ) 00232 { 00233 for( int k = ijk1[2]; k < ijk2[2]; k++ ) 00234 { 00235 00236 // get_vertex variants 00237 tmp_handle = this_box->get_vertex( i, j, k ); 00238 00239 tmp_handle2 = this_box->get_vertex( HomCoord( i, j, k ) ); 00240 if( tmp_handle2 != tmp_handle ) 00241 { 00242 std::cout << "element seq: get_vertex(HomCoord) and get_vertex(i,j,k) didn't return" << std::endl 00243 << "consistent results, i, j, k = " << i << ", " << j << ", " << k << "." << std::endl; 00244 result = MB_FAILURE; 00245 } 00246 00247 // get element variants 00248 tmp_handle = this_box->get_element( i, j, k ); 00249 00250 tmp_handle2 = this_box->get_element( HomCoord( i, j, k ) ); 00251 if( tmp_handle2 != tmp_handle ) 00252 { 00253 std::cout << "element seq: get_element(HomCoord) and get_element(i,j,k) didn't return" << std::endl 00254 << "consistent results, i, j, k = " << i << ", " << j << ", " << k << "." << std::endl; 00255 result = MB_FAILURE; 00256 } 00257 00258 // get_params 00259 int itmp, jtmp, ktmp; 00260 itmp = jtmp = ktmp = 0xdeadbeef; 00261 ErrorCode tmp_result = this_box->get_params( tmp_handle, itmp, jtmp, ktmp ); 00262 if( MB_SUCCESS != tmp_result || i != itmp || j != jtmp || k != ktmp ) 00263 { 00264 std::cout << "element seq: get_params didn't work, i, j, k = " << i << ", " << j << ", " << k 00265 << "; itmp, jtmp, ktmp = " << itmp << ", " << jtmp << ", " << ktmp << std::endl; 00266 result = MB_FAILURE; 00267 } 00268 00269 if( !this_box->contains( i, j, k ) || !this_box->contains( HomCoord( i, j, k ) ) ) 00270 { 00271 std::cout << "element seq: contains didn't work, i, j, k = " << i << ", " << j << ", " << k << "." 00272 << std::endl; 00273 result = MB_FAILURE; 00274 } 00275 } 00276 } 00277 } 00278 00279 return result; 00280 } 00281 00282 int main( int, char** ) 00283 { 00284 // test partition methods 00285 int err = RUN_TEST( test_parallel_partitions ); 00286 00287 // test creating and evaluating vertex sequences 00288 err += RUN_TEST( test_vertex_seq ); 00289 00290 // test creating and evaluating element sequences 00291 err += RUN_TEST( test_element_seq ); 00292 00293 // test periodic sequences 00294 err += RUN_TEST( test_periodic_seq ); 00295 00296 return err; 00297 } 00298 00299 void test_vertex_seq() 00300 { 00301 Core moab; 00302 ScdInterface* scdi; 00303 ErrorCode rval = moab.Interface::query_interface( scdi );CHECK_ERR( rval ); 00304 00305 // get the seq manager from gMB 00306 ScdBox* dum_box = NULL; 00307 00308 // make a 1d sequence 00309 ErrorCode result = scdi->create_scd_sequence( HomCoord( -10, 0, 0 ), HomCoord( 10, 0, 0 ), MBVERTEX, 1, dum_box );CHECK_ERR( result ); 00310 if( !dum_box || dum_box->start_vertex() == 0 ) CHECK_ERR( MB_FAILURE ); 00311 00312 // check sequence data 00313 result = check_vertex_sequence( dum_box, -10, 0, 0, 10, 0, 0, dum_box->start_vertex() );CHECK_ERR( result ); 00314 00315 // evaluate that sequence for all possible values 00316 result = evaluate_vertex_sequence( dum_box );CHECK_ERR( result ); 00317 00318 // make a 2d sequence 00319 dum_box = NULL; 00320 result = scdi->create_scd_sequence( HomCoord( -10, -10, 0 ), HomCoord( 10, 10, 0 ), MBVERTEX, 1, dum_box );CHECK_ERR( result ); 00321 00322 // check sequence data 00323 result = check_vertex_sequence( dum_box, -10, -10, 0, 10, 10, 0, dum_box->start_vertex() );CHECK_ERR( result ); 00324 00325 // evaluate that sequence for all possible values 00326 result = evaluate_vertex_sequence( dum_box );CHECK_ERR( result ); 00327 00328 // make a 3d sequence 00329 dum_box = NULL; 00330 result = scdi->create_scd_sequence( HomCoord( -10, -10, -10 ), HomCoord( 10, 10, 10 ), MBVERTEX, 1, dum_box );CHECK_ERR( result ); 00331 if( !dum_box || dum_box->start_vertex() == 0 ) CHECK_ERR( MB_FAILURE ); 00332 00333 // check sequence data 00334 result = check_vertex_sequence( dum_box, -10, -10, -10, 10, 10, 10, dum_box->start_vertex() );CHECK_ERR( result ); 00335 00336 // evaluate that sequence for all possible values 00337 result = evaluate_vertex_sequence( dum_box );CHECK_ERR( result ); 00338 } 00339 00340 void test_element_seq() 00341 { 00342 Core moab; 00343 ScdInterface* scdi; 00344 ErrorCode rval = moab.Interface::query_interface( scdi );CHECK_ERR( rval ); 00345 00346 HomCoord TEST_MIN_PARAMS( 0, 0, 0 ); 00347 HomCoord TEST_BOX_MAX( 11, 5, 2 ); 00348 00349 // TEST 1: single vertex sequence blocks, unity mapping 00350 rval = eseq_test1a( scdi, TEST_MIN_PARAMS, TEST_BOX_MAX );CHECK_ERR( rval ); 00351 rval = eseq_test1b( scdi, TEST_MIN_PARAMS, TEST_BOX_MAX );CHECK_ERR( rval ); 00352 rval = eseq_test1c( scdi, TEST_MIN_PARAMS, TEST_BOX_MAX );CHECK_ERR( rval ); 00353 00354 // TEST 2: composites, 0d difference between element block "owning" 00355 // vertex block and element block sharing vertex block 00356 rval = eseq_test2a( scdi, TEST_MIN_PARAMS, TEST_BOX_MAX );CHECK_ERR( rval ); 00357 rval = eseq_test2b( scdi );CHECK_ERR( rval ); 00358 rval = eseq_test2c( scdi );CHECK_ERR( rval ); 00359 rval = eseq_test2d( scdi );CHECK_ERR( rval ); 00360 } 00361 00362 ErrorCode eseq_test1a( ScdInterface* scdi, HomCoord tmp_min, HomCoord tmp_max ) 00363 { 00364 // TEST 1a: 1d single vertex seq block, min/max = (-10,0,0)/(10,0,0) 00365 // create vertex seq 00366 00367 // first get 1d min/max by resetting j, k components 00368 tmp_min[1] = tmp_min[2] = tmp_max[1] = tmp_max[2] = 0; 00369 00370 ScdBox *ebox, *vbox; 00371 ErrorCode result = scdi->create_scd_sequence( tmp_min, tmp_max, MBVERTEX, 1, vbox );CHECK_ERR( result ); 00372 00373 // now create the element sequence 00374 result = scdi->create_scd_sequence( tmp_min, tmp_max, MBEDGE, 1, ebox );CHECK_ERR( result ); 00375 int num_edges = ebox->num_elements(); 00376 CHECK_EQUAL( ( tmp_max[0] - tmp_min[0] ), num_edges ); 00377 00378 // add vertex seq to element seq 00379 result = ebox->add_vbox( vbox, tmp_min, tmp_min, tmp_max, tmp_max, tmp_min, tmp_min );CHECK_ERR( result ); 00380 00381 // check/evaluate element sequence 00382 result = check_element_sequence( ebox, tmp_min, tmp_max, ebox->start_element() );CHECK_ERR( result ); 00383 00384 result = evaluate_element_sequence( ebox );CHECK_ERR( result ); 00385 00386 return result; 00387 } 00388 00389 ErrorCode eseq_test1b( ScdInterface* scdi, HomCoord tmp_min, HomCoord tmp_max ) 00390 { 00391 // TEST 1b: 2d single vertex seq block, min/max = (-10,-5,0)/(10,5,0) 00392 00393 // first get 2d min/max by resetting k component 00394 tmp_min[2] = tmp_max[2] = 0; 00395 00396 // get the seq manager from gMB 00397 ScdBox *ebox, *vbox; 00398 ErrorCode result = scdi->create_scd_sequence( tmp_min, tmp_max, MBVERTEX, 1, vbox );CHECK_ERR( result ); 00399 00400 // now create the element sequence 00401 result = scdi->create_scd_sequence( tmp_min, tmp_max, MBQUAD, 1, ebox );CHECK_ERR( result ); 00402 00403 // add vertex seq to element seq; first need to construct proper 3pt input (p1 is tmp_min) 00404 HomCoord p2( tmp_max.i(), tmp_min.j(), tmp_min.k() ); 00405 HomCoord p3( tmp_min.i(), tmp_max.j(), tmp_min.k() ); 00406 result = ebox->add_vbox( vbox, tmp_min, tmp_min, p2, p2, p3, p3 );CHECK_ERR( result ); 00407 00408 std::vector< EntityHandle > connect; 00409 EntityHandle dum_ent = ebox->start_element(); 00410 result = scdi->impl()->get_connectivity( &dum_ent, 1, connect );CHECK_ERR( result ); 00411 CHECK_EQUAL( (unsigned int)connect.size(), (unsigned int)4 ); 00412 00413 // check/evaluate element sequence 00414 result = check_element_sequence( ebox, tmp_min, tmp_max, ebox->start_element() );CHECK_ERR( result ); 00415 00416 result = evaluate_element_sequence( ebox );CHECK_ERR( result ); 00417 00418 result = access_adjacencies( ebox );CHECK_ERR( result ); 00419 00420 return result; 00421 } 00422 00423 ErrorCode eseq_test1c( ScdInterface* scdi, const HomCoord& tmp_min, const HomCoord& tmp_max ) 00424 { 00425 // TEST 1c: 3d single vertex seq block, min/max = (-10,-5,-1)/(10,5,1) 00426 00427 // get the seq manager from gMB 00428 ScdBox *ebox, *vbox; 00429 ErrorCode result = scdi->create_scd_sequence( tmp_min, tmp_max, MBVERTEX, 1, vbox );CHECK_ERR( result ); 00430 00431 // now create the element sequence 00432 result = scdi->create_scd_sequence( tmp_min, tmp_max, MBHEX, 1, ebox );CHECK_ERR( result ); 00433 00434 // add vertex seq to element seq; first need to construct proper 3pt input (p1 is tmp_min) 00435 HomCoord p2( tmp_max.i(), tmp_min.j(), tmp_min.k() ); 00436 HomCoord p3( tmp_min.i(), tmp_max.j(), tmp_min.k() ); 00437 result = ebox->add_vbox( vbox, tmp_min, tmp_min, p2, p2, p3, p3 );CHECK_ERR( result ); 00438 00439 // check/evaluate element sequence 00440 result = check_element_sequence( ebox, tmp_min, tmp_max, ebox->start_element() );CHECK_ERR( result ); 00441 00442 result = evaluate_element_sequence( ebox );CHECK_ERR( result ); 00443 00444 result = access_adjacencies( ebox );CHECK_ERR( result ); 00445 00446 return result; 00447 } 00448 00449 ErrorCode eseq_test2a( ScdInterface* scdi, const HomCoord& tmp_min, const HomCoord& tmp_max ) 00450 { 00451 // TEST 2a: 1d composite block, 0d difference between owning/sharing blocks 00452 // create vertex seq 00453 00454 ScdBox *vbox[3], *ebox[3]; 00455 ErrorCode result = create_1d_3_sequences( scdi, tmp_min, tmp_max, vbox, ebox );CHECK_ERR( result ); 00456 00457 // whew; that's done; now check and evaluate 00458 00459 // first check to make sure the parameter spaces tack onto one another 00460 if( ebox[0]->box_min() != tmp_min || ebox[0]->box_max() != ebox[1]->box_min() || 00461 ebox[1]->box_max() != ebox[2]->box_min() ) 00462 CHECK_ERR( MB_FAILURE ); 00463 00464 // check/evaluate element sequences 00465 for( int i = 0; i < 3; i++ ) 00466 { 00467 result = check_element_sequence( ebox[i], ebox[i]->box_min(), ebox[i]->box_max(), ebox[i]->start_element() );CHECK_ERR( result ); 00468 00469 result = evaluate_element_sequence( ebox[i] );CHECK_ERR( result ); 00470 } 00471 00472 return result; 00473 } 00474 00475 ErrorCode eseq_test2b( ScdInterface* scdi ) 00476 { 00477 // TEST 2b: 2d composite block, 0d difference between owning/sharing blocks 00478 // create vertex seq 00479 00480 ScdBox *ebox[3], *vbox[3]; 00481 ErrorCode result = create_2d_3_sequences( scdi, vbox, ebox );CHECK_ERR( result ); 00482 00483 // whew; that's done; now check and evaluate 00484 00485 // first check to make sure the parameter spaces tack onto one another 00486 if( ebox[0]->box_max() != HomCoord( ebox[1]->box_min().i(), ebox[1]->box_max().j(), 0 ) || 00487 ebox[1]->box_max() != HomCoord( ebox[2]->box_min().i(), ebox[2]->box_max().j(), 0 ) || 00488 // cheat on the i value of ebox0, since it's a periodic bdy (we don't check for that, so you 00489 // may get different values for that parameter) 00490 ebox[2]->box_max() != HomCoord( ebox[2]->box_max().i(), ebox[0]->box_max().j(), 0 ) ) 00491 CHECK_ERR( MB_FAILURE ); 00492 00493 // check/evaluate element sequences 00494 for( int i = 0; i < 3; i++ ) 00495 { 00496 result = check_element_sequence( ebox[i], ebox[i]->box_min(), ebox[i]->box_max(), ebox[i]->start_element() );CHECK_ERR( result ); 00497 00498 result = evaluate_element_sequence( ebox[i] );CHECK_ERR( result ); 00499 } 00500 00501 for( int i = 0; i < 3; i++ ) 00502 { 00503 result = access_adjacencies( ebox[i] );CHECK_ERR( result ); 00504 } 00505 00506 return result; 00507 } 00508 00509 ErrorCode eseq_test2c( ScdInterface* scdi ) 00510 { 00511 // TEST 2c: 2d composite block, 0d difference between owning/sharing blocks, 00512 // tri-valent shared vertex between the three blocks 00513 00514 // interval settings: only 3 of them 00515 int int1 = 5, int2 = 15, int3 = 25; 00516 ScdBox *ebox[3], *vbox[3]; 00517 ErrorCode result = create_2dtri_3_sequences( scdi, int1, int2, int3, vbox, ebox );CHECK_ERR( result ); 00518 00519 // whew; that's done; now check and evaluate 00520 00521 // check/evaluate element sequences 00522 for( int i = 0; i < 3; i++ ) 00523 { 00524 result = check_element_sequence( ebox[i], ebox[i]->box_min(), ebox[i]->box_max(), ebox[i]->start_element() );CHECK_ERR( result ); 00525 00526 result = evaluate_element_sequence( ebox[i] );CHECK_ERR( result ); 00527 } 00528 00529 for( int i = 0; i < 3; i++ ) 00530 { 00531 result = access_adjacencies( ebox[i] );CHECK_ERR( result ); 00532 } 00533 00534 return result; 00535 } 00536 00537 ErrorCode eseq_test2d( ScdInterface* scdi ) 00538 { 00539 // TEST 2d: 3d composite block, 0d difference between owning/sharing blocks, 00540 // tri-valent shared edge between the three blocks 00541 00542 // interval settings: only 3 of them 00543 int int1 = 10, int2 = 10, int3 = 10, int4 = 10; 00544 ScdBox *ebox[3], *vbox[3]; 00545 ErrorCode result = create_3dtri_3_sequences( scdi, int1, int2, int3, int4, vbox, ebox );CHECK_ERR( result ); 00546 00547 // whew; that's done; now check and evaluate 00548 00549 // check/evaluate element sequences 00550 for( int i = 0; i < 3; i++ ) 00551 { 00552 result = check_element_sequence( ebox[i], ebox[i]->box_min(), ebox[i]->box_max(), ebox[i]->start_element() );CHECK_ERR( result ); 00553 00554 result = evaluate_element_sequence( ebox[i] );CHECK_ERR( result ); 00555 } 00556 00557 for( int i = 0; i < 3; i++ ) 00558 { 00559 result = access_adjacencies( ebox[i] );CHECK_ERR( result ); 00560 } 00561 00562 return result; 00563 } 00564 00565 void test_periodic_seq() 00566 { 00567 Core moab; 00568 ScdInterface* scdi; 00569 ErrorCode rval = moab.Interface::query_interface( scdi );CHECK_ERR( rval ); 00570 HomCoord TEST_MIN_PARAMS( 0, 0, 0 ); 00571 HomCoord TEST_BOX_MAX( 11, 5, 2 ); 00572 00573 // periodic in i 00574 ScdBox* new_box; 00575 int lperiodic[2] = { 1, 0 }; 00576 rval = scdi->construct_box( TEST_MIN_PARAMS, TEST_BOX_MAX, NULL, 0, new_box, lperiodic );CHECK_ERR( rval ); 00577 rval = evaluate_element_sequence( new_box );CHECK_ERR( rval ); 00578 00579 // periodic in j 00580 lperiodic[0] = 0; 00581 lperiodic[1] = 1; 00582 rval = scdi->construct_box( TEST_MIN_PARAMS, TEST_BOX_MAX, NULL, 0, new_box, lperiodic );CHECK_ERR( rval ); 00583 rval = evaluate_element_sequence( new_box );CHECK_ERR( rval ); 00584 00585 // periodic in i and j 00586 lperiodic[0] = 1; 00587 lperiodic[1] = 1; 00588 rval = scdi->construct_box( TEST_MIN_PARAMS, TEST_BOX_MAX, NULL, 0, new_box, lperiodic );CHECK_ERR( rval ); 00589 rval = evaluate_element_sequence( new_box );CHECK_ERR( rval ); 00590 00591 // 2d, periodic in i 00592 TEST_BOX_MAX[2] = 0; 00593 lperiodic[0] = 1; 00594 lperiodic[1] = 0; 00595 rval = scdi->construct_box( TEST_MIN_PARAMS, TEST_BOX_MAX, NULL, 0, new_box, lperiodic );CHECK_ERR( rval ); 00596 rval = evaluate_element_sequence( new_box );CHECK_ERR( rval ); 00597 00598 // 2d, periodic in j 00599 lperiodic[0] = 0; 00600 lperiodic[1] = 1; 00601 rval = scdi->construct_box( TEST_MIN_PARAMS, TEST_BOX_MAX, NULL, 0, new_box, lperiodic );CHECK_ERR( rval ); 00602 rval = evaluate_element_sequence( new_box );CHECK_ERR( rval ); 00603 00604 // 2d, periodic in i and j 00605 lperiodic[0] = 1; 00606 lperiodic[1] = 1; 00607 rval = scdi->construct_box( TEST_MIN_PARAMS, TEST_BOX_MAX, NULL, 0, new_box, lperiodic );CHECK_ERR( rval ); 00608 rval = evaluate_element_sequence( new_box );CHECK_ERR( rval ); 00609 } 00610 00611 ErrorCode create_1d_3_sequences( ScdInterface* scdi, HomCoord tmp_min, HomCoord tmp_max, ScdBox** vbox, ScdBox** ebox ) 00612 { 00613 // first get 1d min/max by resetting j, k components 00614 tmp_min[1] = tmp_min[2] = tmp_max[1] = tmp_max[2] = 0; 00615 00616 // split the sequence in three in i parameter, at 1/2, 1/3 and 1/6, such that the 00617 // total # vertices is the expected number from tmp_max - tmp_min) 00618 int idiff = ( tmp_max[0] - tmp_min[0] + 1 ) / 6; 00619 HomCoord vseq0_minmax[2] = { HomCoord( tmp_min ), HomCoord( tmp_min[0] + 3 * idiff - 1, tmp_max[1], tmp_max[2] ) }; 00620 HomCoord vseq1_minmax[2] = { HomCoord( tmp_min ), HomCoord( tmp_min[0] + 2 * idiff - 1, tmp_max[1], tmp_max[2] ) }; 00621 HomCoord vseq2_minmax[2] = { HomCoord( tmp_min ), HomCoord( tmp_max[0] - 5 * idiff, tmp_max[1], tmp_max[2] ) }; 00622 00623 // create three vertex sequences 00624 vbox[0] = vbox[1] = vbox[2] = NULL; 00625 00626 // first vertex sequence 00627 ErrorCode result = scdi->create_scd_sequence( vseq0_minmax[0], vseq0_minmax[1], MBVERTEX, 1, vbox[0] );CHECK_ERR( result ); 00628 00629 // second vertex sequence 00630 result = scdi->create_scd_sequence( vseq1_minmax[0], vseq1_minmax[1], MBVERTEX, 1, vbox[1] );CHECK_ERR( result ); 00631 00632 // third vertex sequence 00633 result = scdi->create_scd_sequence( vseq2_minmax[0], vseq2_minmax[1], MBVERTEX, 1, vbox[2] );CHECK_ERR( result ); 00634 00635 // now create the three element sequences 00636 ebox[0] = ebox[1] = ebox[2] = NULL; 00637 00638 // create the first element sequence 00639 result = scdi->create_scd_sequence( vseq0_minmax[0], vseq0_minmax[1], MBEDGE, 1, ebox[0] );CHECK_ERR( result ); 00640 00641 // add first vertex seq to first element seq, forward orientation, unity transform 00642 result = ebox[0]->add_vbox( vbox[0], vseq0_minmax[0], vseq0_minmax[0], vseq0_minmax[1], vseq0_minmax[1], 00643 vseq0_minmax[0], vseq0_minmax[0] );CHECK_ERR( result ); 00644 00645 // create the second element sequence; make it use the second vseq in reverse and start 00646 // with the end vertex of the first sequence; parameterize it such that it tacks onto the 00647 // end of the previous ebox 00648 result = scdi->create_scd_sequence( 00649 HomCoord( vseq0_minmax[1].i(), 0, 0 ), 00650 HomCoord( 1 + vseq0_minmax[1].i() + vseq1_minmax[1].i() - vseq1_minmax[0].i(), 0, 0 ), MBEDGE, 1, ebox[1] );CHECK_ERR( result ); 00651 00652 // add shared vertex from first vseq to this ebox; parameter space should be the same since 00653 // we're adding to that parameter space 00654 result = ebox[1]->add_vbox( vbox[0], vseq0_minmax[0], vseq0_minmax[0], vseq0_minmax[1], vseq0_minmax[1], 00655 vseq0_minmax[0], vseq0_minmax[0], true, HomCoord( ebox[1]->box_min().i(), 0, 0 ), 00656 HomCoord( ebox[1]->box_min().i(), 0, 0 ) );CHECK_ERR( result ); 00657 00658 // add second vseq to this ebox, but reversed; parameter space should be such that the 00659 // last vertex in the second vseq occurs first, and so on 00660 result = ebox[1]->add_vbox( vbox[1], vseq1_minmax[1], ebox[1]->box_min() + HomCoord::getUnitv( 0 ), vseq1_minmax[0], 00661 ebox[1]->box_max(), vseq1_minmax[1], ebox[1]->box_min() + HomCoord::getUnitv( 0 ) );CHECK_ERR( result ); 00662 00663 // create the third element sequence; make it use the third vseq (forward sense) and start 00664 // with the start vertex of the second vseq; parameterize it such that it tacks onto the 00665 // end of the previous ebox 00666 result = scdi->create_scd_sequence( 00667 ebox[1]->box_max(), HomCoord( ebox[1]->box_max().i() + 1 + vseq2_minmax[1].i() - vseq2_minmax[0].i(), 0, 0 ), 00668 MBEDGE, 1, ebox[2] );CHECK_ERR( result ); 00669 00670 // add shared vertex from second vseq to this ebox; parameter space mapping such that we get 00671 // first vertex only of that vseq 00672 result = ebox[2]->add_vbox( vbox[1], vseq0_minmax[0], ebox[2]->box_min(), vseq0_minmax[0] + HomCoord::getUnitv( 0 ), 00673 ebox[2]->box_min() - HomCoord::getUnitv( 0 ), vseq0_minmax[0], ebox[2]->box_min(), true, 00674 ebox[2]->box_min(), ebox[2]->box_min() );CHECK_ERR( result ); 00675 00676 // add third vseq to this ebox, forward orientation 00677 result = ebox[2]->add_vbox( vbox[2], vseq2_minmax[0], ebox[2]->box_min() + HomCoord::getUnitv( 0 ), vseq2_minmax[1], 00678 ebox[2]->box_max(), vseq1_minmax[0], ebox[2]->box_min() + HomCoord::getUnitv( 0 ) );CHECK_ERR( result ); 00679 00680 return result; 00681 } 00682 00683 ErrorCode create_2d_3_sequences( ScdInterface* scdi, ScdBox** vbox, ScdBox** ebox ) 00684 { 00685 // create 3 rectangular sequences attached end to end and back (periodic); sequences are 00686 // assorted orientations, sequences have globally-consistent (periodic in i) parameter space 00687 00688 // set vbox parametric spaces directly 00689 HomCoord vbox0_minmax[2] = { HomCoord( 0, 0, 0 ), HomCoord( 5, 5, 0 ) }; 00690 HomCoord vbox1_minmax[2] = { HomCoord( -2, 4, 0 ), HomCoord( 8, 9, 0 ) }; 00691 HomCoord vbox2_minmax[2] = { HomCoord( 0, 0, 0 ), HomCoord( 8, 5, 0 ) }; 00692 00693 // create three vertex sequences 00694 vbox[0] = vbox[1] = vbox[2] = NULL; 00695 00696 // first vertex sequence 00697 ErrorCode result = scdi->create_scd_sequence( vbox0_minmax[0], vbox0_minmax[1], MBVERTEX, 1, vbox[0] );CHECK_ERR( result ); 00698 00699 // second vertex sequence 00700 result = scdi->create_scd_sequence( vbox1_minmax[0], vbox1_minmax[1], MBVERTEX, 1, vbox[1] );CHECK_ERR( result ); 00701 00702 // third vertex sequence 00703 result = scdi->create_scd_sequence( vbox2_minmax[0], vbox2_minmax[1], MBVERTEX, 1, vbox[2] );CHECK_ERR( result ); 00704 00705 // now create the three element sequences 00706 ebox[0] = ebox[1] = ebox[2] = NULL; 00707 00708 // create the first element sequence 00709 result = scdi->create_scd_sequence( vbox0_minmax[0], vbox0_minmax[1], MBQUAD, 1, ebox[0] );CHECK_ERR( result ); 00710 00711 // add first vertex seq to first element seq, forward orientation, unity transform 00712 result = ebox[0]->add_vbox( vbox[0], 00713 // p1: imin,jmin 00714 vbox0_minmax[0], vbox0_minmax[0], 00715 // p2: imax,jmin 00716 HomCoord( vbox0_minmax[1].i(), vbox0_minmax[0].j(), 0 ), 00717 HomCoord( vbox0_minmax[1].i(), vbox0_minmax[0].j(), 0 ), 00718 // p3: imin,jmax 00719 HomCoord( vbox0_minmax[0].i(), vbox0_minmax[1].j(), 0 ), 00720 HomCoord( vbox0_minmax[0].i(), vbox0_minmax[1].j(), 0 ) ); 00721 00722 CHECK_ERR( result ); 00723 00724 // create the second element sequence; make it use the right side of the first vbox; 00725 // parameterize it such that it tacks onto imax of the previous ebox 00726 result = scdi->create_scd_sequence( HomCoord( ebox[0]->box_max().i(), ebox[0]->box_min().j(), 0 ), 00727 HomCoord( vbox0_minmax[1].i() + 1 + vbox1_minmax[1].i() - vbox1_minmax[0].i(), 00728 ebox[0]->box_max().j(), 0 ), 00729 MBQUAD, 1, ebox[1] );CHECK_ERR( result ); 00730 00731 // add shared side from first vbox to this ebox; parameter space should be the same since 00732 // we're adding to that parameter space 00733 result = 00734 ebox[1]->add_vbox( vbox[0], 00735 // p1: lower right of box 0, lower left of box 1 00736 HomCoord( vbox0_minmax[1].i(), vbox0_minmax[0].j(), 0 ), ebox[1]->box_min(), 00737 // p2: one up from p1 00738 HomCoord( vbox0_minmax[1].i(), vbox0_minmax[0].j(), 0 ) + HomCoord::getUnitv( 1 ), 00739 ebox[1]->box_min() + HomCoord::getUnitv( 1 ), 00740 // p3: one right of p1 00741 HomCoord( vbox0_minmax[1].i(), vbox0_minmax[0].j(), 0 ) + HomCoord::getUnitv( 0 ), 00742 ebox[1]->box_min() + HomCoord::getUnitv( 0 ), 00743 // set bb such that it's the right side of the vbox, left of local ebox 00744 true, ebox[1]->box_min(), HomCoord( ebox[1]->box_min().i(), ebox[1]->box_max().j(), 0 ) );CHECK_ERR( result ); 00745 00746 // add second vbox to this ebox, with different orientation but all of it (no bb input) 00747 result = ebox[1]->add_vbox( vbox[1], 00748 // p1: one right of top left of ebox1 00749 vbox1_minmax[0], HomCoord( ebox[1]->box_min().i() + 1, ebox[1]->box_max().j(), 0 ), 00750 // p2: one right from p1 00751 vbox1_minmax[0] + HomCoord::getUnitv( 0 ), 00752 HomCoord( ebox[1]->box_min().i() + 2, ebox[1]->box_max().j(), 0 ), 00753 // p3: one down from p1 00754 vbox1_minmax[0] + HomCoord::getUnitv( 1 ), 00755 HomCoord( ebox[1]->box_min().i() + 1, ebox[1]->box_max().j() - 1, 0 ) );CHECK_ERR( result ); 00756 00757 // create the third element sequence; make it use the third vbox (middle) as well as the side of 00758 // the second sequence (left) and a side of the first sequence (right); parameterize it such 00759 // that it tacks onto the end of the previous ebox and the beginning of the 1st sequence (i.e. 00760 // periodic in i) 00761 result = 00762 scdi->create_scd_sequence( HomCoord( ebox[1]->box_max().i(), ebox[1]->box_min().j(), 0 ), 00763 // add one extra for each of left and right sides 00764 HomCoord( ebox[1]->box_max().i() + 1 + vbox2_minmax[1].i() - vbox2_minmax[0].i() + 1, 00765 ebox[1]->box_max().j(), 0 ), 00766 MBEDGE, 1, ebox[2] );CHECK_ERR( result ); 00767 00768 // add shared side from second vbox to this ebox; parameter space mapping such that we get 00769 // a side only of that vbox 00770 result = 00771 ebox[2]->add_vbox( vbox[1], 00772 // p1: bottom left 00773 vbox1_minmax[1], ebox[2]->box_min(), 00774 // p2: one right from p1 00775 vbox1_minmax[1] + HomCoord::getUnitv( 0 ), ebox[2]->box_min() + HomCoord::getUnitv( 0 ), 00776 // p3: one up 00777 vbox1_minmax[1] - HomCoord::getUnitv( 1 ), ebox[2]->box_min() + HomCoord::getUnitv( 1 ), 00778 // bb input such that we only get left side of ebox parameter space 00779 true, ebox[2]->box_min(), HomCoord( ebox[2]->box_min().i(), ebox[2]->box_max().j(), 0 ) );CHECK_ERR( result ); 00780 00781 // add shared side from first vbox to this ebox; parameter space mapping such that we get 00782 // a side only of that vbox 00783 result = ebox[2]->add_vbox( 00784 vbox[0], 00785 // p1: bottom right 00786 vbox0_minmax[0], HomCoord( ebox[2]->box_max().i(), ebox[2]->box_min().j(), 0 ), 00787 // p2: one right from p1 00788 vbox0_minmax[0] + HomCoord::getUnitv( 0 ), HomCoord( ebox[2]->box_max().i() + 1, ebox[2]->box_min().j(), 0 ), 00789 // p3: one up from p1 00790 vbox0_minmax[0] + HomCoord::getUnitv( 1 ), HomCoord( ebox[2]->box_max().i(), ebox[2]->box_min().j() + 1, 0 ), 00791 // bb input such that we only get left side of ebox parameter space 00792 true, HomCoord( ebox[2]->box_max().i(), ebox[2]->box_min().j(), 0 ), ebox[2]->box_max() );CHECK_ERR( result ); 00793 00794 // add third vbox to this ebox 00795 result = 00796 ebox[2]->add_vbox( vbox[2], 00797 // p1: top right and left one 00798 vbox2_minmax[0], ebox[2]->box_max() - HomCoord::getUnitv( 0 ), 00799 // p2: one left of p1 00800 vbox2_minmax[0] + HomCoord::getUnitv( 0 ), ebox[2]->box_max() - HomCoord::getUnitv( 0 ) * 2, 00801 // p3: one down from p1 00802 vbox2_minmax[0] + HomCoord::getUnitv( 1 ), 00803 ebox[2]->box_max() - HomCoord::getUnitv( 0 ) - HomCoord::getUnitv( 1 ) );CHECK_ERR( result ); 00804 00805 return result; 00806 } 00807 00808 ErrorCode create_2dtri_3_sequences( ScdInterface* scdi, 00809 const int int1, 00810 const int int2, 00811 const int int3, 00812 ScdBox** vbox, 00813 ScdBox** ebox ) 00814 { 00815 // create 3 rectangular sequences arranged such that the all share a common (tri-valent) corner; 00816 // orient each region such that its origin is at the tri-valent corner and the k direction is 00817 // out of the page 00818 // 00819 // int1 and int2 controls the i and j intervals in region 0, int3 follows from that. 00820 00821 // input is 3 interval settings controlling the 3 degrees of freedom on the interfacesp 00822 00823 // set vbox parametric spaces directly from int1-3 00824 // use 0-based parameterization on vbox's just for fun, which means we'll have to transform into 00825 // ebox system 00826 HomCoord vbox0_minmax[2] = { HomCoord( 0, 0, 0 ), HomCoord( int1, int2, 0 ) }; 00827 HomCoord vbox1_minmax[2] = { HomCoord( 0, 0, 0 ), HomCoord( int3 - 1, int1, 0 ) }; 00828 HomCoord vbox2_minmax[2] = { HomCoord( 0, 0, 0 ), HomCoord( int2 - 1, int3 - 1, 0 ) }; 00829 00830 // create three vertex sequences 00831 vbox[0] = vbox[1] = vbox[2] = NULL; 00832 00833 // first vertex sequence 00834 ErrorCode result = scdi->create_scd_sequence( vbox0_minmax[0], vbox0_minmax[1], MBVERTEX, 1, vbox[0] );CHECK_ERR( result ); 00835 00836 // second vertex sequence 00837 result = scdi->create_scd_sequence( vbox1_minmax[0], vbox1_minmax[1], MBVERTEX, 1, vbox[1] );CHECK_ERR( result ); 00838 00839 // third vertex sequence 00840 result = scdi->create_scd_sequence( vbox2_minmax[0], vbox2_minmax[1], MBVERTEX, 1, vbox[2] );CHECK_ERR( result ); 00841 00842 // now create the three element sequences 00843 00844 // set ebox parametric spaces directly from int1-3 00845 // use 0-based parameterization on ebox's just for fun, which means we'll have to transform into 00846 // ebox system 00847 HomCoord ebox0_minmax[2] = { HomCoord( 0, 0, 0 ), HomCoord( int1, int2, 0 ) }; 00848 HomCoord ebox1_minmax[2] = { HomCoord( 0, 0, 0 ), HomCoord( int3, int1, 0 ) }; 00849 HomCoord ebox2_minmax[2] = { HomCoord( 0, 0, 0 ), HomCoord( int2, int3, 0 ) }; 00850 00851 ebox[0] = ebox[1] = ebox[2] = NULL; 00852 00853 // create the first element sequence 00854 result = scdi->create_scd_sequence( ebox0_minmax[0], ebox0_minmax[1], MBQUAD, 1, ebox[0] );CHECK_ERR( result ); 00855 00856 // only need to add one vbox to this, unity transform 00857 result = ebox[0]->add_vbox( vbox[0], 00858 // trick: if I know it's going to be unity, just input 00859 // 3 sets of equivalent points 00860 vbox0_minmax[0], vbox0_minmax[0], vbox0_minmax[0], vbox0_minmax[0], vbox0_minmax[0], 00861 vbox0_minmax[0] ); 00862 00863 CHECK_ERR( result ); 00864 00865 // create the second element sequence 00866 result = scdi->create_scd_sequence( ebox1_minmax[0], ebox1_minmax[1], MBQUAD, 1, ebox[1] );CHECK_ERR( result ); 00867 00868 // add shared side from first vbox to this ebox, with bb to get just the line 00869 result = 00870 ebox[1]->add_vbox( vbox[0], 00871 // p1: origin in both systems 00872 vbox0_minmax[0], ebox0_minmax[0], 00873 // p2: one unit along the shared line (i in one, j in other) 00874 vbox0_minmax[0] + HomCoord::getUnitv( 0 ), ebox0_minmax[0] + HomCoord::getUnitv( 1 ), 00875 // p3: arbitrary 00876 vbox0_minmax[0], ebox0_minmax[0], 00877 // set bb such that it's the jmin side of vbox 00878 true, ebox[1]->box_min(), HomCoord( ebox[1]->box_min().i(), ebox[1]->box_max().j(), 0 ) );CHECK_ERR( result ); 00879 00880 // add second vbox to this ebox, with different orientation but all of it (no bb input) 00881 result = ebox[1]->add_vbox( vbox[1], 00882 // p1: origin/i+1 (vbox/ebox) 00883 vbox1_minmax[0], ebox1_minmax[0] + HomCoord::getUnitv( 0 ), 00884 // p2: j+1 from p1 00885 vbox1_minmax[0] + HomCoord::getUnitv( 1 ), 00886 ebox1_minmax[0] + HomCoord::getUnitv( 0 ) + HomCoord::getUnitv( 1 ), 00887 // p3: i+1 from p1 00888 vbox1_minmax[0] + HomCoord::getUnitv( 0 ), 00889 ebox[1]->box_min() + HomCoord::getUnitv( 0 ) * 2 );CHECK_ERR( result ); 00890 00891 // create the third element sequence 00892 result = scdi->create_scd_sequence( ebox2_minmax[0], ebox2_minmax[1], MBQUAD, 1, ebox[2] );CHECK_ERR( result ); 00893 00894 // add shared side from second vbox to this ebox 00895 result = 00896 ebox[2]->add_vbox( vbox[1], 00897 // p1: origin/j+1 (vbox/ebox) 00898 vbox1_minmax[0], ebox[2]->box_min() + HomCoord::getUnitv( 1 ), 00899 // p2: i+1/j+2 (vbox/ebox) 00900 vbox1_minmax[0] + HomCoord::getUnitv( 0 ), ebox[2]->box_min() + HomCoord::getUnitv( 1 ) * 2, 00901 // p3: arbitrary 00902 vbox1_minmax[0], ebox[2]->box_min() + HomCoord::getUnitv( 1 ), 00903 // bb input such that we only get one side of ebox parameter space 00904 true, ebox[2]->box_min() + HomCoord::getUnitv( 1 ), 00905 HomCoord( ebox[2]->box_min().i(), ebox[2]->box_max().j(), 0 ) );CHECK_ERR( result ); 00906 00907 // add shared side from first vbox to this ebox 00908 result = ebox[2]->add_vbox( vbox[0], 00909 // p1: origin/origin 00910 vbox1_minmax[0], ebox2_minmax[0], 00911 // p2: j+1/i+1 00912 vbox1_minmax[0] + HomCoord::getUnitv( 1 ), ebox2_minmax[0] + HomCoord::getUnitv( 0 ), 00913 // p3: arbitrary 00914 vbox1_minmax[0], ebox2_minmax[0], 00915 // bb input such that we only get one side of ebox parameter space 00916 true, ebox2_minmax[0], HomCoord( ebox2_minmax[1].i(), ebox2_minmax[0].j(), 0 ) );CHECK_ERR( result ); 00917 00918 // add third vbox to this ebox 00919 result = ebox[2]->add_vbox( vbox[2], 00920 // p1: origin/i+1,j+1 00921 vbox2_minmax[0], ebox[2]->box_min() + HomCoord::getUnitv( 0 ) + HomCoord::getUnitv( 1 ), 00922 // p2: i+1 from p1 00923 vbox2_minmax[0] + HomCoord::getUnitv( 0 ), 00924 ebox[2]->box_min() + HomCoord::getUnitv( 0 ) * 2 + HomCoord::getUnitv( 1 ), 00925 // p3: j+1 from p1 00926 vbox2_minmax[0] + HomCoord::getUnitv( 1 ), 00927 ebox[2]->box_min() + HomCoord::getUnitv( 0 ) + HomCoord::getUnitv( 1 ) * 2 );CHECK_ERR( result ); 00928 00929 return result; 00930 } 00931 00932 ErrorCode create_3dtri_3_sequences( ScdInterface* scdi, 00933 const int int1, 00934 const int int2, 00935 const int int3, 00936 const int int4, 00937 ScdBox** vbox, 00938 ScdBox** ebox ) 00939 { 00940 // create 3 brick sequences arranged such that the all share a common (tri-valent) edge; 00941 // orient each region similarly to the 2dtri_3_sequences test problem, swept into 3d in the 00942 // positive k direction. This direction is divided into int4 intervals 00943 // 00944 // int1 and int2 controls the i and j intervals in region 0, int3 follows from that; int4 00945 // divides the k axis 00946 00947 // input is 4 interval settings controlling the 4 degrees of freedom on the interfacesp 00948 00949 // set vbox parametric spaces directly from int1-4 00950 // use 0-based parameterization on vbox's just for fun, which means we'll have to transform into 00951 // ebox system 00952 HomCoord vbox0_minmax[2] = { HomCoord( 0, 0, 0 ), HomCoord( int1, int2, int4 ) }; 00953 HomCoord vbox1_minmax[2] = { HomCoord( 0, 0, 0 ), HomCoord( int3 - 1, int1, int4 ) }; 00954 HomCoord vbox2_minmax[2] = { HomCoord( 0, 0, 0 ), HomCoord( int2 - 1, int3 - 1, int4 ) }; 00955 00956 // create three vertex sequences 00957 vbox[0] = vbox[1] = vbox[2] = NULL; 00958 00959 // first vertex sequence 00960 ErrorCode result = scdi->create_scd_sequence( vbox0_minmax[0], vbox0_minmax[1], MBVERTEX, 1, vbox[0] );CHECK_ERR( result ); 00961 00962 // second vertex sequence 00963 result = scdi->create_scd_sequence( vbox1_minmax[0], vbox1_minmax[1], MBVERTEX, 1, vbox[1] );CHECK_ERR( result ); 00964 00965 // third vertex sequence 00966 result = scdi->create_scd_sequence( vbox2_minmax[0], vbox2_minmax[1], MBVERTEX, 1, vbox[2] );CHECK_ERR( result ); 00967 00968 // now create the three element sequences 00969 00970 // set ebox parametric spaces directly from int1-4 00971 // use 0-based parameterization on ebox's just for fun, which means we'll have to transform into 00972 // ebox system 00973 HomCoord ebox0_minmax[2] = { HomCoord( 0, 0, 0 ), HomCoord( int1, int2, int4 ) }; 00974 HomCoord ebox1_minmax[2] = { HomCoord( 0, 0, 0 ), HomCoord( int3, int1, int4 ) }; 00975 HomCoord ebox2_minmax[2] = { HomCoord( 0, 0, 0 ), HomCoord( int2, int3, int4 ) }; 00976 00977 ebox[0] = ebox[1] = ebox[2] = NULL; 00978 00979 // create the first element sequence 00980 result = scdi->create_scd_sequence( ebox0_minmax[0], ebox0_minmax[1], MBHEX, 1, ebox[0] );CHECK_ERR( result ); 00981 00982 // only need to add one vbox to this, unity transform 00983 result = ebox[0]->add_vbox( vbox[0], 00984 // trick: if I know it's going to be unity, just input 00985 // 3 sets of equivalent points 00986 vbox0_minmax[0], vbox0_minmax[0], vbox0_minmax[0], vbox0_minmax[0], vbox0_minmax[0], 00987 vbox0_minmax[0] ); 00988 00989 CHECK_ERR( result ); 00990 00991 // create the second element sequence 00992 result = scdi->create_scd_sequence( ebox1_minmax[0], ebox1_minmax[1], MBHEX, 1, ebox[1] );CHECK_ERR( result ); 00993 00994 // add shared side from first vbox to this ebox, with bb to get just the face 00995 result = ebox[1]->add_vbox( vbox[0], 00996 // p1: origin in both systems 00997 vbox0_minmax[0], ebox1_minmax[0], 00998 // p2: one unit along the shared line (i in one, j in other) 00999 vbox0_minmax[0] + HomCoord::getUnitv( 0 ), ebox1_minmax[0] + HomCoord::getUnitv( 1 ), 01000 // p3: +k in both (not arbitrary, since interface is 2d) 01001 vbox0_minmax[0] + HomCoord::getUnitv( 2 ), ebox1_minmax[0] + HomCoord::getUnitv( 2 ), 01002 // set bb such that it's the jmin side of vbox 01003 true, ebox[1]->box_min(), 01004 HomCoord( ebox[1]->box_min().i(), ebox[1]->box_max().j(), ebox[1]->box_max().k() ) );CHECK_ERR( result ); 01005 01006 // add second vbox to this ebox, with different orientation but all of it (no bb input) 01007 result = ebox[1]->add_vbox( vbox[1], 01008 // p1: origin/i+1 (vbox/ebox) 01009 vbox1_minmax[0], ebox1_minmax[0] + HomCoord::getUnitv( 0 ), 01010 // p2: j+1 from p1 01011 vbox1_minmax[0] + HomCoord::getUnitv( 1 ), 01012 ebox1_minmax[0] + HomCoord::getUnitv( 0 ) + HomCoord::getUnitv( 1 ), 01013 // p3: i+1 from p1 01014 vbox1_minmax[0] + HomCoord::getUnitv( 0 ), 01015 ebox[1]->box_min() + HomCoord::getUnitv( 0 ) * 2 );CHECK_ERR( result ); 01016 01017 // create the third element sequence 01018 result = scdi->create_scd_sequence( ebox2_minmax[0], ebox2_minmax[1], MBHEX, 1, ebox[2] );CHECK_ERR( result ); 01019 01020 // add shared side from second vbox to this ebox 01021 result = 01022 ebox[2]->add_vbox( vbox[1], 01023 // p1: origin/j+1 (vbox/ebox) 01024 vbox1_minmax[0], ebox[2]->box_min() + HomCoord::getUnitv( 1 ), 01025 // p2: i+1/j+2 (vbox/ebox) 01026 vbox1_minmax[0] + HomCoord::getUnitv( 0 ), ebox[2]->box_min() + HomCoord::getUnitv( 1 ) * 2, 01027 // p3: +k in both (not arbitrary, since interface is 2d) 01028 vbox1_minmax[0] + HomCoord::getUnitv( 2 ), 01029 ebox[2]->box_min() + HomCoord::getUnitv( 1 ) + HomCoord::getUnitv( 2 ), 01030 // bb input such that we only get one side of ebox parameter space 01031 true, ebox[2]->box_min() + HomCoord::getUnitv( 1 ), 01032 HomCoord( ebox[2]->box_min().i(), ebox[2]->box_max().j(), ebox[2]->box_max().k() ) );CHECK_ERR( result ); 01033 01034 // add shared side from first vbox to this ebox 01035 result = ebox[2]->add_vbox( vbox[0], 01036 // p1: origin/origin 01037 vbox0_minmax[0], ebox2_minmax[0], 01038 // p2: j+1/i+1 01039 vbox0_minmax[0] + HomCoord::getUnitv( 1 ), ebox2_minmax[0] + HomCoord::getUnitv( 0 ), 01040 // p3: +k in both (not arbitrary, since interface is 2d) 01041 vbox0_minmax[0] + HomCoord::getUnitv( 2 ), ebox[2]->box_min() + HomCoord::getUnitv( 2 ), 01042 // bb input such that we only get one side of ebox parameter space 01043 true, ebox2_minmax[0], 01044 HomCoord( ebox2_minmax[1].i(), ebox2_minmax[0].j(), ebox2_minmax[1].k() ) );CHECK_ERR( result ); 01045 01046 // add third vbox to this ebox 01047 result = ebox[2]->add_vbox( vbox[2], 01048 // p1: origin/i+1,j+1 01049 vbox2_minmax[0], ebox[2]->box_min() + HomCoord::getUnitv( 0 ) + HomCoord::getUnitv( 1 ), 01050 // p2: i+1 from p1 01051 vbox2_minmax[0] + HomCoord::getUnitv( 0 ), 01052 ebox[2]->box_min() + HomCoord::getUnitv( 0 ) * 2 + HomCoord::getUnitv( 1 ), 01053 // p3: j+1 from p1 01054 vbox2_minmax[0] + HomCoord::getUnitv( 1 ), 01055 ebox[2]->box_min() + HomCoord::getUnitv( 0 ) + HomCoord::getUnitv( 1 ) * 2 );CHECK_ERR( result ); 01056 01057 return result; 01058 } 01059 01060 ErrorCode access_adjacencies( ScdBox* box ) 01061 { 01062 // access the adjacencies in this box in a few places 01063 HomCoord box_size = box->box_size(), box_min = box->box_min(), box_max = box->box_max(); 01064 01065 EntityHandle dum_entity; 01066 const EntityHandle* connect; 01067 int num_connect; 01068 ErrorCode rval; 01069 bool is_2d = ( box_size.k() <= 1 ); 01070 01071 // edges first; bottom: 01072 for( int dir = 0; dir < 3; dir++ ) 01073 { 01074 // don't do 3rd direction for 2d box 01075 if( 2 == dir && is_2d ) continue; 01076 01077 rval = box->get_adj_edge_or_face( 1, box_min.i(), box_min.j(), box_min.k(), dir, dum_entity, true ); 01078 if( MB_SUCCESS != rval ) return rval; 01079 01080 // do a simple API call on that entity to make sure we can 01081 rval = box->sc_impl()->impl()->get_connectivity( dum_entity, connect, num_connect ); 01082 if( MB_SUCCESS != rval ) return rval; 01083 } 01084 // middle: 01085 for( int dir = 0; dir < 3; dir++ ) 01086 { 01087 // don't do 3rd direction for 2d box 01088 if( 2 == dir && is_2d ) continue; 01089 01090 rval = box->get_adj_edge_or_face( 1, box_min.i() + .5 * box_size.i(), box_min.j() + .5 * box_size.j(), 01091 box_min.k() + .5 * box_size.k(), dir, dum_entity, true ); 01092 if( MB_SUCCESS != rval ) return rval; 01093 01094 // do a simple API call on that entity to make sure we can 01095 rval = box->sc_impl()->impl()->get_connectivity( dum_entity, connect, num_connect ); 01096 if( MB_SUCCESS != rval ) return rval; 01097 } 01098 01099 // top: 01100 for( int dir = 0; dir < 3; dir++ ) 01101 { 01102 // don't do 3rd direction for 2d box 01103 if( 2 == dir && is_2d ) continue; 01104 01105 rval = box->get_adj_edge_or_face( 1, ( box_max.i() == box_min.i() ? box_max.i() : box_max.i() - 1 ), 01106 ( box_max.j() == box_min.j() ? box_max.j() : box_max.j() - 1 ), 01107 ( box_max.k() == box_min.k() ? box_max.k() : box_max.k() - 1 ), dir, 01108 dum_entity, true ); 01109 if( MB_SUCCESS != rval ) return rval; 01110 01111 // do a simple API call on that entity to make sure we can 01112 rval = box->sc_impl()->impl()->get_connectivity( dum_entity, connect, num_connect ); 01113 if( MB_SUCCESS != rval ) return rval; 01114 } 01115 01116 if( is_2d ) return MB_SUCCESS; 01117 01118 // now faces; bottom: 01119 for( int dir = 0; dir < 3; dir++ ) 01120 { 01121 rval = box->get_adj_edge_or_face( 2, box_min.i(), box_min.j(), box_min.k(), dir, dum_entity, true ); 01122 if( MB_SUCCESS != rval ) return rval; 01123 01124 // do a simple API call on that entity to make sure we can 01125 rval = box->sc_impl()->impl()->get_connectivity( dum_entity, connect, num_connect ); 01126 if( MB_SUCCESS != rval ) return rval; 01127 } 01128 // middle: 01129 for( int dir = 0; dir < 3; dir++ ) 01130 { 01131 // don't do 3rd direction for 2d box 01132 if( 2 == dir && is_2d ) continue; 01133 01134 rval = box->get_adj_edge_or_face( 2, box_min.i() + .5 * box_size.i(), box_min.j() + .5 * box_size.j(), 01135 box_min.k() + .5 * box_size.k(), dir, dum_entity, true ); 01136 if( MB_SUCCESS != rval ) return rval; 01137 01138 // do a simple API call on that entity to make sure we can 01139 rval = box->sc_impl()->impl()->get_connectivity( dum_entity, connect, num_connect ); 01140 if( MB_SUCCESS != rval ) return rval; 01141 } 01142 01143 // top: 01144 for( int dir = 0; dir < 3; dir++ ) 01145 { 01146 // don't do 3rd direction for 2d box 01147 if( 2 == dir && is_2d ) continue; 01148 01149 rval = box->get_adj_edge_or_face( 2, ( box_max.i() == box_min.i() ? box_max.i() : box_max.i() - 1 ), 01150 ( box_max.j() == box_min.j() ? box_max.j() : box_max.j() - 1 ), 01151 ( box_max.k() == box_min.k() ? box_max.k() : box_max.k() - 1 ), dir, 01152 dum_entity, true ); 01153 if( MB_SUCCESS != rval ) return rval; 01154 01155 // do a simple API call on that entity to make sure we can 01156 rval = box->sc_impl()->impl()->get_connectivity( dum_entity, connect, num_connect ); 01157 if( MB_SUCCESS != rval ) return rval; 01158 } 01159 01160 return MB_SUCCESS; 01161 } 01162 01163 void test_parallel_partitions() 01164 { 01165 01166 Core moab; 01167 ScdInterface* scdi; 01168 ErrorCode rval = moab.Interface::query_interface( scdi );CHECK_ERR( rval ); 01169 int gdims[] = { 0, 0, 0, 48, 40, 18 }; 01170 01171 // test for various numbers of procs, powers of two 01172 int maxpow = 4; 01173 01174 int fails = 0; 01175 for( int exp = 2; exp <= maxpow; exp += 2 ) 01176 { 01177 int nprocs = 0.1 + pow( 2.0, (double)exp ); 01178 01179 // alljorkori 01180 rval = test_parallel_partition( gdims, nprocs, ScdParData::ALLJORKORI ); 01181 if( MB_SUCCESS != rval ) fails++; 01182 01183 // alljkbal 01184 rval = test_parallel_partition( gdims, nprocs, ScdParData::ALLJKBAL ); 01185 if( MB_SUCCESS != rval ) fails++; 01186 01187 // sqij 01188 rval = test_parallel_partition( gdims, nprocs, ScdParData::SQIJ ); 01189 if( MB_SUCCESS != rval ) fails++; 01190 01191 // sqjk 01192 rval = test_parallel_partition( gdims, nprocs, ScdParData::SQJK ); 01193 if( MB_SUCCESS != rval ) fails++; 01194 01195 // sqijk 01196 rval = test_parallel_partition( gdims, nprocs, ScdParData::SQIJK ); 01197 if( MB_SUCCESS != rval ) fails++; 01198 } 01199 01200 if( fails ) CHECK_ERR( MB_FAILURE ); 01201 } 01202 01203 ErrorCode test_parallel_partition( int* gdims, int nprocs, int part_method ) 01204 { 01205 ErrorCode rval; 01206 int pto, pfrom, across_bdy_a[3], across_bdy_b[3], rdims_a[6], rdims_b[6], facedims_a[6], facedims_b[6], ldims[6], 01207 lper[3], pijk[3]; 01208 ScdParData spd; 01209 for( int i = 0; i < 6; i++ ) 01210 spd.gDims[i] = gdims[i]; 01211 for( int i = 0; i < 3; i++ ) 01212 spd.gPeriodic[i] = 0; 01213 spd.partMethod = part_method; 01214 int fails = 0; 01215 01216 for( int p = 0; p < nprocs / 2; p++ ) 01217 { 01218 rval = ScdInterface::compute_partition( nprocs, p, spd, ldims, lper, pijk ); 01219 if( MB_SUCCESS != rval ) continue; 01220 01221 for( int k = -1; k <= 1; k++ ) 01222 { 01223 for( int j = -1; j <= 1; j++ ) 01224 { 01225 for( int i = -1; i <= 1; i++ ) 01226 { 01227 int dijka[] = { i, j, k }, dijkb[] = { -i, -j, -k }; 01228 rval = ScdInterface::get_neighbor( nprocs, p, spd, dijka, pto, rdims_a, facedims_a, across_bdy_a ); 01229 if( MB_SUCCESS != rval ) return rval; 01230 if( -1 == pto ) continue; 01231 01232 bool fail = false; 01233 if( facedims_a[0] < rdims_a[0] || facedims_a[0] > rdims_a[3] || facedims_a[1] < rdims_a[1] || 01234 facedims_a[1] > rdims_a[4] || facedims_a[2] < rdims_a[2] || facedims_a[2] > rdims_a[5] ) 01235 fail = true; 01236 01237 // non-negative value of pto; check corresponding input from that proc to this 01238 01239 rval = 01240 ScdInterface::get_neighbor( nprocs, pto, spd, dijkb, pfrom, rdims_b, facedims_b, across_bdy_b ); 01241 if( MB_SUCCESS != rval ) return rval; 01242 for( int ind = 0; ind < 3; ind++ ) 01243 if( facedims_a[ind] < rdims_b[ind] || facedims_b[ind] > rdims_b[ind + 3] ) fail = true; 01244 for( int ind = 0; ind < 6; ind++ ) 01245 { 01246 if( facedims_a[ind] != facedims_b[ind] || rdims_b[ind] != ldims[ind] ) fail = true; 01247 } 01248 if( across_bdy_a[0] != across_bdy_b[0] || across_bdy_a[1] != across_bdy_b[1] ) fail = true; 01249 #define PARRAY( a ) "(" << ( a )[0] << "," << ( a )[1] << "," << ( a )[2] << ")" 01250 #define PARRAY3( a, b, c ) "(" << ( a ) << "," << ( b ) << "," << ( c ) << ")" 01251 #define PARRAY6( a ) PARRAY( a ) << "-" << PARRAY( ( ( a ) + 3 ) ) 01252 if( fail ) 01253 { 01254 fails++; 01255 for( int l = 0; l < 3; l++ ) 01256 spd.pDims[l] = pijk[l]; 01257 std::cerr << "partMeth = " << part_method << ", p/np = " << p << "/" << nprocs 01258 << ", (i,j,k) = " << PARRAY3( i, j, k ) << ", ldims = " << PARRAY6( ldims ) 01259 << std::endl 01260 << "facedims_a = " << PARRAY6( facedims_a ) 01261 << ", facedims_b = " << PARRAY6( facedims_b ) << std::endl 01262 << "rdims_a = " << PARRAY6( rdims_a ) << ", rdims_b = " << PARRAY6( rdims_b ) 01263 << std::endl; 01264 std::cerr << "ScdParData: " << spd << std::endl; 01265 } 01266 } // i 01267 } // j 01268 } // k 01269 } // p 01270 01271 return ( fails ? MB_FAILURE : MB_SUCCESS ); 01272 }