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