MOAB: Mesh Oriented datABase  (version 5.2.1)
scdseq_test.cpp
Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines