24 #if !defined( _NT ) && !defined( _MSC_VER ) && !defined( __MINGW32__ )
25 #include <sys/resource.h>
28 extern "C" int getrusage(
int,
struct rusage* );
30 #include </usr/ucbinclude/sys/rusage.h>
43 #include "TSTT_MOAB.hh"
46 #define IMPLEMENTATION_CLASS TSTT_MOAB::MoabMesh
49 #define CAST_INTERFACE( var_in, var_out, iface ) \
50 TSTT::iface var_out; \
53 ( var_out ) = var_in; \
55 catch( TSTT::Error ) \
57 cerr << "Error: current interface doesn't support iface." << endl; \
61 #define CAST_MINTERFACE( var_in, var_out, iface ) \
62 TSTTM::iface var_out; \
65 ( var_out ) = var_in; \
67 catch( TSTT::Error ) \
69 cerr << "Error: current interface doesn't support iface." << endl; \
82 #define ARRAY_PTR( array, type ) ( reinterpret_cast< ( type )* >( ( array )._get_ior()->d_firstElement ) )
83 #define HANDLE_ARRAY_PTR( array ) ( reinterpret_cast< Entity_Handle* >( ( array )._get_ior()->d_firstElement ) )
84 #define ARRAY_SIZE( array ) ( ( array )._is_nil() ? 0 : ( array ).upper( 0 ) - ( array ).lower( 0 ) + 1 )
85 #define CHECK_SIZE( array, size ) \
86 if( ( array )._is_nil() || ARRAY_SIZE( array ) == 0 ) \
87 ( array ) = ( array ).create1d( size ); \
88 else if( ARRAY_SIZE( array ) < ( size ) ) \
90 cerr << "Array passed in is non-zero but too short." << endl; \
99 void print_time(
const bool print_em,
double& tot_time,
double& utime,
double& stime );
100 void build_connect(
const int nelem,
const int vstart,
int*& connect );
101 void testB( TSTTM::Mesh&
mesh,
const int nelem, sidl::array< double >& coords,
const int* connect );
102 void testC( TSTTM::Mesh&
mesh,
const int nelem, sidl::array< double >& coords );
103 void compute_edge(
double* start,
const int nelem,
const double xint,
const int stride );
104 void compute_face(
double* a,
const int nelem,
const double xint,
const int stride1,
const int stride2 );
105 void build_coords(
const int nelem, sidl::array< double >& coords );
106 void build_connect(
const int nelem,
const int vstart,
int*& connect );
108 int main(
int argc,
char* argv[] )
113 std::cout <<
"Usage: " << argv[0] <<
" <ints_per_side> <A|B|C>" << std::endl;
117 char which_test =
'\0';
119 sscanf( argv[1],
"%d", &nelem );
120 sscanf( argv[2],
"%c", &which_test );
122 if( which_test !=
'B' && which_test !=
'C' )
124 std::cout <<
"Must indicate B or C for test." << std::endl;
128 std::cout <<
"number of elements: " << nelem <<
"; test " << which_test << std::endl;
131 sidl::array< double > coords;
133 assert( NULL != coords );
139 TSTTM::Mesh
mesh = IMPLEMENTATION_CLASS::_create();
157 void testB( TSTTM::Mesh&
mesh,
const int nelem, sidl::array< double >& coords,
const int* connect )
159 double utime, stime, ttime0, ttime1, ttime2, ttime3;
162 int num_verts = ( nelem + 1 ) * ( nelem + 1 ) * ( nelem + 1 );
163 int num_elems = nelem * nelem * nelem;
167 sidl::array< Entity_Handle > sidl_vertices, dum_handles;
169 int sidl_vertices_size;
173 mesh_arrmod.createVtxArr( num_verts, TSTTM::StorageOrder_BLOCKED, coords, 3 * num_verts, sidl_vertices,
174 sidl_vertices_size );
176 catch( TSTT::Error& )
178 cerr <<
"Couldn't create vertices in bulk call" << endl;
184 sidl::array< Entity_Handle > sidl_connect;
185 int sidl_connect_size = 8 * num_elems;
190 for(
int i = 0; i < sidl_connect_size; i++ )
193 assert( connect[i] - 1 < num_verts );
194 sidl_connect_ptr[i] = sidl_vertices_ptr[connect[i] - 1];
198 sidl::array< Entity_Handle > new_hexes;
200 sidl::array< TSTTM::CreationStatus > status;
205 mesh_arrmod.createEntArr( TSTTM::EntityTopology_HEXAHEDRON, sidl_connect, sidl_connect_size, new_hexes,
206 new_hexes_size, status, status_size );
208 catch( TSTT::Error& )
210 cerr <<
"Couldn't create hex elements in bulk call" << endl;
225 std::cout <<
"TSTT/MOAB ucd blocked: nelem, construct, e_to_v query, v_to_e query = " << nelem <<
", "
226 << ttime1 - ttime0 <<
", " << ttime2 - ttime1 <<
", " << ttime3 - ttime2 <<
" seconds" << std::endl;
229 void testC( TSTTM::Mesh&
mesh,
const int nelem, sidl::array< double >& coords )
231 double utime, stime, ttime0, ttime1, ttime2, ttime3;
237 int numv = nelem + 1;
238 int numv_sq = numv * numv;
239 int num_verts = numv * numv * numv;
240 #define VINDEX( i, j, k ) ( ( i ) + ( (j)*numv ) + ( (k)*numv_sq ) )
243 sidl::array< Entity_Handle > sidl_vertices;
248 sidl::array< double > tmp_coords;
249 int tmp_coords_size = 3;
251 double* dum_coords =
ARRAY_PTR( tmp_coords,
double );
254 double* coords_ptr =
ARRAY_PTR( coords,
double );
256 for(
int i = 0; i < num_verts; i++ )
260 sidl::array< Entity_Handle > tmp_vertices;
261 int tmp_vertices_size = 0;
264 dum_coords[0] = coords_ptr[i];
265 dum_coords[1] = coords_ptr[num_verts + i];
266 dum_coords[2] = coords_ptr[2 * num_verts + i];
269 mesh_arrmod.createVtxArr( 1, TSTTM::StorageOrder_BLOCKED, tmp_coords, tmp_coords_size, tmp_vertices,
272 catch( TSTT::Error& )
274 cerr <<
"Couldn't create vertex in individual call" << endl;
279 sidl_vertices.set( i, tmp_vertices.get( 0 ) );
285 for(
int i = 0; i < nelem; i++ )
287 for(
int j = 0; j < nelem; j++ )
289 for(
int k = 0; k < nelem; k++ )
292 sidl::array< Entity_Handle > tmp_conn;
293 int tmp_conn_size = 8;
296 int vijk =
VINDEX( i, j, k );
297 tmp_conn.set( 0, tmp_sidl_vertices[vijk] );
298 tmp_conn.set( 1, tmp_sidl_vertices[vijk + 1] );
299 tmp_conn.set( 2, tmp_sidl_vertices[vijk + 1 + numv] );
300 tmp_conn.set( 3, tmp_sidl_vertices[vijk + numv] );
301 tmp_conn.set( 4, tmp_sidl_vertices[vijk + numv * numv] );
302 tmp_conn.set( 5, tmp_sidl_vertices[vijk + 1 + numv * numv] );
303 tmp_conn.set( 6, tmp_sidl_vertices[vijk + 1 + numv + numv * numv] );
304 tmp_conn.set( 7, tmp_sidl_vertices[vijk + numv + numv * numv] );
308 sidl::array< Entity_Handle > new_hex;
309 int new_hex_size = 0;
310 sidl::array< TSTTM::CreationStatus > status;
315 mesh_arrmod.createEntArr( TSTTM::EntityTopology_HEXAHEDRON, tmp_conn, tmp_conn_size, new_hex,
316 new_hex_size, status, status_size );
318 catch( TSTT::Error& )
320 cerr <<
"Couldn't create hex element in individual call" << endl;
338 std::cout <<
"TSTT/MOAB ucd indiv: nelem, construct, e_to_v query, v_to_e query = " << nelem <<
", "
339 << ttime1 - ttime0 <<
", " << ttime2 - ttime1 <<
", " << ttime3 - ttime2 <<
" seconds" << std::endl;
344 sidl::array< Entity_Handle > all_hexes;
351 mesh.getEntities( 0, TSTTM::EntityType_REGION, TSTTM::EntityTopology_HEXAHEDRON, all_hexes, all_hexes_size );
353 catch( TSTT::Error& )
355 cerr <<
"Couldn't get all hex elements in query_mesh" << endl;
365 for(
int i = 0; i < all_hexes_size; i++ )
367 sidl::array< int > dum_offsets;
368 sidl::array< Entity_Handle > dum_connect;
369 int dum_connect_size = 0;
372 mesh_ent.getEntAdj( all_hexes_ptr[i], TSTTM::EntityType_VERTEX, dum_connect, dum_connect_size );
376 sidl::array< double > dum_coords;
377 int dum_coords_size = 0;
378 TSTTM::StorageOrder order = TSTTM::StorageOrder_UNDETERMINED;
379 mesh.getVtxArrCoords( dum_connect, dum_connect_size, order, dum_coords, dum_coords_size );
381 assert( 24 == dum_coords_size &&
ARRAY_SIZE( dum_coords ) == 24 );
382 double* dum_coords_ptr =
ARRAY_PTR( dum_coords,
double );
383 double centroid[3] = { 0.0, 0.0, 0.0 };
384 if( order == TSTTM::StorageOrder_BLOCKED )
386 for(
int j = 0; j < 8; j++ )
388 centroid[0] += dum_coords_ptr[j];
389 centroid[1] += dum_coords_ptr[8 + j];
390 centroid[2] += dum_coords_ptr[16 + j];
391 centroid[0] += dum_coords.get( j );
392 centroid[1] += dum_coords.get( 8 + j );
393 centroid[2] += dum_coords.get( 16 + j );
398 for(
int j = 0; j < 8; j++ )
400 centroid[0] += dum_coords_ptr[3 * j];
401 centroid[1] += dum_coords_ptr[3 * j + 1];
402 centroid[2] += dum_coords_ptr[3 * j + 2];
407 catch( TSTT::Error& )
409 cerr <<
"Problem getting connectivity or vertex coords." << endl;
416 sidl::array< Entity_Handle > all_verts;
423 mesh.getEntities( 0, TSTTM::EntityType_VERTEX, TSTTM::EntityTopology_POINT, all_verts, all_verts_size );
425 catch( TSTT::Error& )
427 cerr <<
"Couldn't get all vertices in query_vert_to_elem" << endl;
437 for(
int i = 0; i < all_verts_size; i++ )
439 sidl::array< Entity_Handle > dum_hexes;
444 mesh_ent.getEntAdj( all_verts_ptr[i], TSTTM::EntityType_REGION, dum_hexes, dum_hexes_size );
447 catch( TSTT::Error& )
449 cerr <<
"Problem getting connectivity or vertex coords." << endl;
454 void print_time(
const bool print_em,
double& tot_time,
double& utime,
double& stime )
456 struct rusage r_usage;
457 getrusage( RUSAGE_SELF, &r_usage );
458 utime = (double)r_usage.ru_utime.tv_sec + ( (
double)r_usage.ru_utime.tv_usec / 1.e6 );
459 stime = (double)r_usage.ru_stime.tv_sec + ( (
double)r_usage.ru_stime.tv_usec / 1.e6 );
460 tot_time = utime + stime;
462 std::cout <<
"User, system, total time = " << utime <<
", " << stime <<
", " << tot_time << std::endl;
464 std::cout <<
"Max resident set size = " << r_usage.ru_maxrss * 4096 <<
" bytes" << std::endl;
465 std::cout <<
"Int resident set size = " << r_usage.ru_idrss << std::endl;
467 system(
"ps o args,drs,rss | grep perf | grep -v grep" );
472 void compute_edge(
double* start,
const int nelem,
const double xint,
const int stride )
474 for(
int i = 1; i < nelem; i++ )
476 start[i * stride] = start[0] + i * xint;
477 start[nelem + 1 + i * stride] = start[nelem + 1] + i * xint;
478 start[2 * ( nelem + 1 ) + i * stride] = start[2 * ( nelem + 1 )] + i * xint;
482 void compute_face(
double* a,
const int nelem,
const double xint,
const int stride1,
const int stride2 )
485 for(
int j = 1; j < nelem; j++ )
487 double tse = j * xint;
488 for(
int i = 1; i < nelem; i++ )
490 double ada = i * xint;
492 a[i * stride1 + j * stride2] =
493 ( 1.0 - ada ) * a[i * stride1] + ada * a[i * stride1 + nelem * stride2] +
494 ( 1.0 - tse ) * a[j * stride2] + tse * a[j * stride2 + nelem * stride1] -
495 ( 1.0 - tse ) * ( 1.0 - ada ) * a[0] - ( 1.0 - tse ) * ada * a[nelem * stride1] -
496 tse * ( 1.0 - ada ) * a[nelem * stride2] - tse * ada * a[nelem * ( stride1 + stride2 )];
497 a[nelem + 1 + i * stride1 + j * stride2] =
498 ( 1.0 - ada ) * a[nelem + 1 + i * stride1] + ada * a[nelem + 1 + i * stride1 + nelem * stride2] +
499 ( 1.0 - tse ) * a[nelem + 1 + j * stride2] + tse * a[nelem + 1 + j * stride2 + nelem * stride1] -
500 ( 1.0 - tse ) * ( 1.0 - ada ) * a[nelem + 1 + 0] -
501 ( 1.0 - tse ) * ada * a[nelem + 1 + nelem * stride1] -
502 tse * ( 1.0 - ada ) * a[nelem + 1 + nelem * stride2] -
503 tse * ada * a[nelem + 1 + nelem * ( stride1 + stride2 )];
504 a[2 * ( nelem + 1 ) + i * stride1 + j * stride2] =
505 ( 1.0 - ada ) * a[2 * ( nelem + 1 ) + i * stride1] +
506 ada * a[2 * ( nelem + 1 ) + i * stride1 + nelem * stride2] +
507 ( 1.0 - tse ) * a[2 * ( nelem + 1 ) + j * stride2] +
508 tse * a[2 * ( nelem + 1 ) + j * stride2 + nelem * stride1] -
509 ( 1.0 - tse ) * ( 1.0 - ada ) * a[2 * ( nelem + 1 ) + 0] -
510 ( 1.0 - tse ) * ada * a[2 * ( nelem + 1 ) + nelem * stride1] -
511 tse * ( 1.0 - ada ) * a[2 * ( nelem + 1 ) + nelem * stride2] -
512 tse * ada * a[2 * ( nelem + 1 ) + nelem * ( stride1 + stride2 )];
519 double ttime0, ttime1, utime1, stime1;
523 int numv = nelem + 1;
524 int numv_sq = numv * numv;
525 int tot_numv = numv * numv * numv;
527 double* coords_ptr =
ARRAY_PTR( coords,
double );
530 #define VINDEX( i, j, k ) ( ( i ) + ( (j)*numv ) + ( (k)*numv_sq ) )
532 double scale1, scale2, scale3;
542 coords_ptr[
VINDEX( 0, 0, 0 )] = coords_ptr[
VINDEX( 0, 0, 0 ) + nelem + 1] =
543 coords_ptr[
VINDEX( 0, 0, 0 ) + 2 * ( nelem + 1 )] = 0.0;
544 coords_ptr[
VINDEX( 0, nelem, 0 )] = coords_ptr[
VINDEX( 0, nelem, 0 ) + 2 * ( nelem + 1 )] = 0.0;
546 coords_ptr[
VINDEX( 0, 0, nelem )] = coords_ptr[
VINDEX( 0, 0, nelem ) + nelem + 1] = 0.0;
547 coords_ptr[
VINDEX( 0, 0, nelem ) + 2 * ( nelem + 1 )] =
LENGTH;
548 coords_ptr[
VINDEX( 0, nelem, nelem )] = 0.0;
549 coords_ptr[
VINDEX( 0, nelem, nelem ) + nelem + 1] = coords_ptr[
VINDEX( 0, nelem, nelem ) + 2 * ( nelem + 1 )] =
552 coords_ptr[
VINDEX( nelem, 0, 0 ) + nelem + 1] = coords_ptr[
VINDEX( nelem, 0, 0 ) + 2 * ( nelem + 1 )] = 0.0;
553 coords_ptr[
VINDEX( nelem, 0, nelem )] = coords_ptr[
VINDEX( nelem, 0, nelem ) + 2 * ( nelem + 1 )] =
LENGTH;
554 coords_ptr[
VINDEX( nelem, 0, nelem ) + nelem + 1] = 0.0;
555 coords_ptr[
VINDEX( nelem, nelem, 0 )] = coords_ptr[
VINDEX( nelem, nelem, 0 ) + nelem + 1] =
LENGTH;
556 coords_ptr[
VINDEX( nelem, nelem, 0 ) + 2 * ( nelem + 1 )] = 0.0;
557 coords_ptr[
VINDEX( nelem, nelem, nelem )] = coords_ptr[
VINDEX( nelem, nelem, nelem ) + nelem + 1] =
558 coords_ptr[
VINDEX( nelem, nelem, nelem ) + 2 * ( nelem + 1 )] =
LENGTH;
589 int i000 =
VINDEX( 0, 0, 0 );
590 int ia00 =
VINDEX( nelem, 0, 0 );
591 int i0t0 =
VINDEX( 0, nelem, 0 );
592 int iat0 =
VINDEX( nelem, nelem, 0 );
593 int i00g =
VINDEX( 0, 0, nelem );
594 int ia0g =
VINDEX( nelem, 0, nelem );
595 int i0tg =
VINDEX( 0, nelem, nelem );
596 int iatg =
VINDEX( nelem, nelem, nelem );
600 int gammaInts = nelem;
602 for(
int i = 1; i < nelem; i++ )
604 for(
int j = 1; j < nelem; j++ )
606 for(
int k = 1; k < nelem; k++ )
609 double tse = i * scale1;
610 double ada = j * scale2;
611 double gamma = k * scale3;
612 double tm1 = 1.0 - tse;
613 double am1 = 1.0 - ada;
614 double gm1 = 1.0 - gamma;
616 cX = gm1 * ( am1 * ( tm1 * coords_ptr[i000] + tse * coords_ptr[i0t0] ) +
617 ada * ( tm1 * coords_ptr[ia00] + tse * coords_ptr[iat0] ) ) +
618 gamma * ( am1 * ( tm1 * coords_ptr[i00g] + tse * coords_ptr[i0tg] ) +
619 ada * ( tm1 * coords_ptr[ia0g] + tse * coords_ptr[iatg] ) );
621 cY = gm1 * ( am1 * ( tm1 * coords_ptr[i000] + tse * coords_ptr[i0t0] ) +
622 ada * ( tm1 * coords_ptr[ia00] + tse * coords_ptr[iat0] ) ) +
623 gamma * ( am1 * ( tm1 * coords_ptr[i00g] + tse * coords_ptr[i0tg] ) +
624 ada * ( tm1 * coords_ptr[ia0g] + tse * coords_ptr[iatg] ) );
626 cZ = gm1 * ( am1 * ( tm1 * coords_ptr[i000] + tse * coords_ptr[i0t0] ) +
627 ada * ( tm1 * coords_ptr[ia00] + tse * coords_ptr[iat0] ) ) +
628 gamma * ( am1 * ( tm1 * coords_ptr[i00g] + tse * coords_ptr[i0tg] ) +
629 ada * ( tm1 * coords_ptr[ia0g] + tse * coords_ptr[iatg] ) );
631 double* ai0k = &coords_ptr[
VINDEX( k, 0, i )];
632 double* aiak = &coords_ptr[
VINDEX( k, adaInts, i )];
633 double* a0jk = &coords_ptr[
VINDEX( k, j, 0 )];
634 double* atjk = &coords_ptr[
VINDEX( k, j, tseInts )];
635 double* aij0 = &coords_ptr[
VINDEX( 0, j, i )];
636 double* aijg = &coords_ptr[
VINDEX( gammaInts, j, i )];
638 coords_ptr[
VINDEX( i, j, k )] = ( am1 * ai0k[0] + ada * aiak[0] + tm1 * a0jk[0] + tse * atjk[0] +
639 gm1 * aij0[0] + gamma * aijg[0] ) /
643 coords_ptr[nelem + 1 +
VINDEX( i, j, k )] =
644 ( am1 * ai0k[nelem + 1] + ada * aiak[nelem + 1] + tm1 * a0jk[nelem + 1] + tse * atjk[nelem + 1] +
645 gm1 * aij0[nelem + 1] + gamma * aijg[nelem + 1] ) /
649 coords_ptr[2 * ( nelem + 1 ) +
VINDEX( i, j, k )] =
650 ( am1 * ai0k[2 * ( nelem + 1 )] + ada * aiak[2 * ( nelem + 1 )] + tm1 * a0jk[2 * ( nelem + 1 )] +
651 tse * atjk[2 * ( nelem + 1 )] + gm1 * aij0[2 * ( nelem + 1 )] +
652 gamma * aijg[2 * ( nelem + 1 )] ) /
660 for(
int i = 0; i < numv; i++ )
662 for(
int j = 0; j < numv; j++ )
664 for(
int k = 0; k < numv; k++ )
668 coords_ptr[idx] = i * scale1;
669 coords_ptr[tot_numv + idx] = j * scale2;
670 coords_ptr[2 * tot_numv + idx] = k * scale3;
676 std::cout <<
"TSTT/MOAB: TFI time = " << ttime1 - ttime0 <<
" sec" << std::endl;
682 int nume_tot = nelem * nelem * nelem;
683 connect =
new int[8 * nume_tot];
686 int numv = nelem + 1;
687 int numv_sq = numv * numv;
689 for(
int i = 0; i < nelem; i++ )
691 for(
int j = 0; j < nelem; j++ )
693 for(
int k = 0; k < nelem; k++ )
695 vijk = vstart +
VINDEX( i, j, k );
696 connect[idx++] = vijk;
697 connect[idx++] = vijk + 1;
698 connect[idx++] = vijk + 1 + numv;
699 connect[idx++] = vijk + numv;
700 connect[idx++] = vijk + numv * numv;
701 connect[idx++] = vijk + 1 + numv * numv;
702 connect[idx++] = vijk + 1 + numv + numv * numv;
703 connect[idx++] = vijk + numv + numv * numv;
704 assert( i <= numv * numv * numv );