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