MOAB: Mesh Oriented datABase
(version 5.4.1)
|
00001 /** TSTT Mesh Interface brick mesh performance test 00002 * 00003 * This program tests TSTT mesh interface functions used to create a square structured 00004 * mesh. Boilerplate taken from tstt mesh interface test in MOAB and performance test in MOAB 00005 * 00006 */ 00007 00008 // Different platforms follow different conventions for usage 00009 #ifndef _WIN32 00010 #include <sys/resource.h> 00011 #endif 00012 #ifdef SOLARIS 00013 extern "C" int getrusage( int, struct rusage* ); 00014 #ifndef RUSAGE_SELF 00015 #include </usr/ucbinclude/sys/rusage.h> 00016 #endif 00017 #endif 00018 00019 #include <cstdlib> 00020 #include <cstdio> 00021 #include <iostream> 00022 00023 #include <iostream> 00024 #include <cassert> 00025 #include "iMesh.h" 00026 00027 // needed to get the proper size for handles 00028 00029 using namespace std; 00030 00031 double LENGTH = 1.0; 00032 00033 // forward declare some functions 00034 void query_elem_to_vert( iMesh_Instance mesh ); 00035 void query_vert_to_elem( iMesh_Instance mesh ); 00036 void print_time( const bool print_em, double& tot_time, double& utime, double& stime, long& imem, long& rmem ); 00037 void build_connect( const int nelem, const int vstart, int*& connect ); 00038 void testB( iMesh_Instance mesh, const int nelem, const double* coords, int* connect ); 00039 void testC( iMesh_Instance mesh, const int nelem, const double* coords ); 00040 void compute_edge( double* start, const int nelem, const double xint, const int stride ); 00041 void compute_face( double* a, const int nelem, const double xint, const int stride1, const int stride2 ); 00042 void build_coords( const int nelem, double*& coords ); 00043 void build_connect( const int nelem, const int vstart, int*& connect ); 00044 00045 int main( int argc, char* argv[] ) 00046 { 00047 int nelem = 20; 00048 if( argc < 3 ) 00049 { 00050 std::cout << "Usage: " << argv[0] << " <ints_per_side> <A|B|C>" << std::endl; 00051 return 1; 00052 } 00053 00054 char which_test = '\0'; 00055 00056 sscanf( argv[1], "%d", &nelem ); 00057 sscanf( argv[2], "%c", &which_test ); 00058 00059 if( which_test != 'B' && which_test != 'C' ) 00060 { 00061 std::cout << "Must indicate B or C for test." << std::endl; 00062 return 1; 00063 } 00064 00065 std::cout << "number of elements: " << nelem << "; test " << which_test << std::endl; 00066 00067 // initialize the data in native format 00068 00069 // pre-build the coords array 00070 double* coords; 00071 build_coords( nelem, coords ); 00072 assert( NULL != coords ); 00073 00074 // test B: create mesh using bulk interface 00075 00076 // create an implementation 00077 iMesh_Instance mesh; 00078 int result; 00079 iMesh_newMesh( NULL, &mesh, &result, 0 ); 00080 int* connect = NULL; 00081 00082 if( iBase_SUCCESS != result ) 00083 { 00084 cerr << "Couldn't create mesh instance." << endl; 00085 iMesh_dtor( mesh, &result ); 00086 return 1; 00087 } 00088 00089 iMesh_setGeometricDimension( mesh, 3, &result ); 00090 if( iBase_SUCCESS != result ) 00091 { 00092 cerr << "Couldn't set geometric dimension." << endl; 00093 iMesh_dtor( mesh, &result ); 00094 return 1; 00095 } 00096 00097 switch( which_test ) 00098 { 00099 case 'B': 00100 build_connect( nelem, 1, connect ); 00101 00102 // test B: create mesh using bulk interface 00103 testB( mesh, nelem, coords, connect ); 00104 break; 00105 00106 case 'C': 00107 // test C: create mesh using individual interface 00108 testC( mesh, nelem, coords ); 00109 break; 00110 } 00111 00112 free( coords ); 00113 00114 return 0; 00115 } 00116 00117 void testB( iMesh_Instance mesh, const int nelem, const double* coords, int* connect ) 00118 { 00119 double utime, stime, ttime0, ttime1, ttime2, ttime3, ttime4; 00120 long imem0, rmem0, imem1, rmem1, imem2, rmem2, imem3, rmem3, imem4, rmem4; 00121 00122 print_time( false, ttime0, utime, stime, imem0, rmem0 ); 00123 int num_verts = ( nelem + 1 ) * ( nelem + 1 ) * ( nelem + 1 ); 00124 int num_elems = nelem * nelem * nelem; 00125 00126 // create vertices as a block; initialize to NULL so allocation is done in interface 00127 iBase_EntityHandle* vertices = NULL; 00128 int vertices_allocated = 0, vertices_size; 00129 int result; 00130 iMesh_createVtxArr( mesh, num_verts, iBase_BLOCKED, coords, 3 * num_verts, &vertices, &vertices_allocated, 00131 &vertices_size, &result ); 00132 if( iBase_SUCCESS != result ) 00133 { 00134 cerr << "Couldn't create vertices in bulk call" << endl; 00135 free( vertices ); 00136 return; 00137 } 00138 00139 // need to explicitly fill connectivity array, since we don't know 00140 // the format of entity handles 00141 int nconnect = 8 * num_elems; 00142 iBase_EntityHandle* sidl_connect = (iBase_EntityHandle*)malloc( nconnect * sizeof( iBase_EntityHandle ) ); 00143 00144 for( int i = 0; i < nconnect; i++ ) 00145 { 00146 // use connect[i]-1 because we used starting vertex index (vstart) of 1 00147 assert( connect[i] - 1 < num_verts ); 00148 sidl_connect[i] = vertices[connect[i] - 1]; 00149 } 00150 00151 // no longer need vertices and connect arrays, free here to reduce overall peak memory usage 00152 free( vertices ); 00153 free( connect ); 00154 00155 // create the entities 00156 iBase_EntityHandle* new_hexes = NULL; 00157 int new_hexes_allocated = 0, new_hexes_size; 00158 int* status = NULL; 00159 int status_allocated = 0, status_size; 00160 00161 iMesh_createEntArr( mesh, iMesh_HEXAHEDRON, sidl_connect, nconnect, &new_hexes, &new_hexes_allocated, 00162 &new_hexes_size, &status, &status_allocated, &status_size, &result ); 00163 if( iBase_SUCCESS != result ) 00164 { 00165 cerr << "Couldn't create hex elements in bulk call" << endl; 00166 free( new_hexes ); 00167 free( status ); 00168 free( sidl_connect ); 00169 return; 00170 } 00171 00172 print_time( false, ttime1, utime, stime, imem1, rmem1 ); 00173 00174 free( status ); 00175 free( new_hexes ); 00176 free( sidl_connect ); 00177 00178 // query the mesh 2 ways 00179 query_elem_to_vert( mesh ); 00180 00181 print_time( false, ttime2, utime, stime, imem2, rmem2 ); 00182 00183 query_vert_to_elem( mesh ); 00184 00185 print_time( false, ttime3, utime, stime, imem3, rmem3 ); 00186 00187 iMesh_dtor( mesh, &result ); 00188 00189 print_time( false, ttime4, utime, stime, imem4, rmem4 ); 00190 00191 std::cout << "TSTTb/MOAB_ucd_blocked: nelem, construct, e_to_v, v_to_e, after_dtor = " << nelem << ", " 00192 << ttime1 - ttime0 << ", " << ttime2 - ttime1 << ", " << ttime3 - ttime2 << ", " << ttime4 - ttime3 00193 << " seconds" << std::endl; 00194 std::cout << "TSTTb/MOAB_ucd_blocked_memory_(rss): initial, after_construction, e-v, v-e, after_dtor:" << rmem0 00195 << ", " << rmem1 << ", " << rmem2 << ", " << rmem3 << ", " << rmem4 << " kb" << std::endl; 00196 } 00197 00198 void testC( iMesh_Instance mesh, const int nelem, const double* coords ) 00199 { 00200 double utime, stime, ttime0, ttime1, ttime2, ttime3, ttime4; 00201 long imem0, rmem0, imem1, rmem1, imem2, rmem2, imem3, rmem3, imem4, rmem4; 00202 print_time( false, ttime0, utime, stime, imem0, rmem0 ); 00203 00204 // need some dimensions 00205 int numv = nelem + 1; 00206 int numv_sq = numv * numv; 00207 int num_verts = numv * numv * numv; 00208 #define VINDEX( i, j, k ) ( ( i ) + ( (j)*numv ) + ( (k)*numv_sq ) ) 00209 00210 // array to hold vertices created individually 00211 iBase_EntityHandle* sidl_vertices = (iBase_EntityHandle*)malloc( num_verts * sizeof( iBase_EntityHandle ) ); 00212 int result; 00213 00214 for( int i = 0; i < num_verts; i++ ) 00215 { 00216 // create the vertex 00217 iMesh_createVtx( mesh, coords[i], coords[i + num_verts], coords[i + 2 * num_verts], sidl_vertices + i, 00218 &result ); 00219 if( iBase_SUCCESS != result ) 00220 { 00221 cerr << "Couldn't create vertex in individual call" << endl; 00222 return; 00223 } 00224 } 00225 00226 iBase_EntityHandle tmp_conn[8], new_hex; 00227 00228 for( int i = 0; i < nelem; i++ ) 00229 { 00230 for( int j = 0; j < nelem; j++ ) 00231 { 00232 for( int k = 0; k < nelem; k++ ) 00233 { 00234 int vijk = VINDEX( i, j, k ); 00235 tmp_conn[0] = sidl_vertices[vijk]; 00236 tmp_conn[1] = sidl_vertices[vijk + 1]; 00237 tmp_conn[2] = sidl_vertices[vijk + 1 + numv]; 00238 tmp_conn[3] = sidl_vertices[vijk + numv]; 00239 tmp_conn[4] = sidl_vertices[vijk + numv * numv]; 00240 tmp_conn[5] = sidl_vertices[vijk + 1 + numv * numv]; 00241 tmp_conn[6] = sidl_vertices[vijk + 1 + numv + numv * numv]; 00242 tmp_conn[7] = sidl_vertices[vijk + numv + numv * numv]; 00243 00244 // create the entity 00245 00246 int status; 00247 iMesh_createEnt( mesh, iMesh_HEXAHEDRON, tmp_conn, 8, &new_hex, &status, &result ); 00248 if( iBase_SUCCESS != result ) 00249 { 00250 cerr << "Couldn't create hex element in individual call" << endl; 00251 // return; do not return if errors, as we would leak memory 00252 } 00253 } 00254 } 00255 } 00256 00257 print_time( false, ttime1, utime, stime, imem1, rmem1 ); 00258 00259 free( sidl_vertices ); 00260 00261 // query the mesh 2 ways 00262 query_elem_to_vert( mesh ); 00263 00264 print_time( false, ttime2, utime, stime, imem2, rmem2 ); 00265 00266 query_vert_to_elem( mesh ); 00267 00268 print_time( false, ttime3, utime, stime, imem3, rmem3 ); 00269 00270 iMesh_dtor( mesh, &result ); 00271 00272 print_time( false, ttime4, utime, stime, imem4, rmem4 ); 00273 00274 std::cout << "TSTTb/MOAB_ucd_indiv: nelem, construct, e_to_v, v_to_e, after_dtor = " << nelem << ", " 00275 << ttime1 - ttime0 << ", " << ttime2 - ttime1 << ", " << ttime3 - ttime2 << ", " << ttime4 - ttime3 00276 << " seconds" << std::endl; 00277 std::cout << "TSTTb/MOAB_ucd_indiv_memory_(rss): initial, after_construction, e-v, v-e, after_dtor:" << rmem0 00278 << ", " << rmem1 << ", " << rmem2 << ", " << rmem3 << ", " << rmem4 << " kb" << std::endl; 00279 } 00280 00281 void query_elem_to_vert( iMesh_Instance mesh ) 00282 { 00283 iBase_EntityHandle* all_hexes = NULL; 00284 int all_hexes_size, all_hexes_allocated = 0; 00285 00286 // get all the hex elements 00287 int success; 00288 iBase_EntitySetHandle root_set; 00289 iMesh_getRootSet( mesh, &root_set, &success ); 00290 if( iBase_SUCCESS != success ) 00291 { 00292 cerr << "Couldn't get root set." << endl; 00293 return; 00294 } 00295 00296 iMesh_getEntities( mesh, root_set, iBase_REGION, iMesh_HEXAHEDRON, &all_hexes, &all_hexes_allocated, 00297 &all_hexes_size, &success ); 00298 if( iBase_SUCCESS != success ) 00299 { 00300 cerr << "Couldn't get all hex elements in query_mesh" << endl; 00301 return; 00302 } 00303 00304 // now loop over elements 00305 iBase_EntityHandle* dum_connect = NULL; 00306 int dum_connect_allocated = 0, dum_connect_size; 00307 double* dum_coords = NULL; 00308 int dum_coords_size, dum_coords_allocated = 0; 00309 int order; 00310 iMesh_getDfltStorage( mesh, &order, &success ); 00311 if( iBase_SUCCESS != success ) return; 00312 00313 for( int i = 0; i < all_hexes_size; i++ ) 00314 { 00315 // get the connectivity of this element; will allocate space on 1st iteration, 00316 // but will have correct size on subsequent ones 00317 iMesh_getEntAdj( mesh, all_hexes[i], iBase_VERTEX, &dum_connect, &dum_connect_allocated, &dum_connect_size, 00318 &success ); 00319 00320 if( iBase_SUCCESS == success ) 00321 { 00322 // get vertex coordinates; ; will allocate space on 1st iteration, 00323 // but will have correct size on subsequent ones 00324 iMesh_getVtxArrCoords( mesh, dum_connect, dum_connect_size, order, &dum_coords, &dum_coords_allocated, 00325 &dum_coords_size, &success ); 00326 00327 double centroid[3] = { 0.0, 0.0, 0.0 }; 00328 if( order == iBase_BLOCKED ) 00329 { 00330 for( int j = 0; j < 8; j++ ) 00331 { 00332 centroid[0] += dum_coords[j]; 00333 centroid[1] += dum_coords[8 + j]; 00334 centroid[2] += dum_coords[16 + j]; 00335 } 00336 } 00337 else 00338 { 00339 for( int j = 0; j < 8; j++ ) 00340 { 00341 centroid[0] += dum_coords[3 * j]; 00342 centroid[1] += dum_coords[3 * j + 1]; 00343 centroid[2] += dum_coords[3 * j + 2]; 00344 } 00345 } 00346 } 00347 00348 if( iBase_SUCCESS != success ) 00349 { 00350 cerr << "Problem getting connectivity or vertex coords." << endl; 00351 return; 00352 } 00353 } 00354 00355 free( all_hexes ); 00356 free( dum_connect ); 00357 free( dum_coords ); 00358 } 00359 00360 void query_vert_to_elem( iMesh_Instance mesh ) 00361 { 00362 iBase_EntityHandle* all_verts = NULL; 00363 int all_verts_allocated = 0, all_verts_size; 00364 00365 iBase_EntitySetHandle root_set; 00366 int success; 00367 iMesh_getRootSet( mesh, &root_set, &success ); 00368 if( iBase_SUCCESS != success ) 00369 { 00370 cerr << "Couldn't get root set." << endl; 00371 return; 00372 } 00373 00374 // get all the vertices elements 00375 iMesh_getEntities( mesh, root_set, iBase_VERTEX, iMesh_POINT, &all_verts, &all_verts_allocated, &all_verts_size, 00376 &success ); 00377 if( iBase_SUCCESS != success ) 00378 { 00379 cerr << "Couldn't get all vertices in query_vert_to_elem" << endl; 00380 return; 00381 } 00382 00383 // for this mesh, should never be more than 8 hexes connected to a vertex 00384 iBase_EntityHandle* dum_hexes = (iBase_EntityHandle*)calloc( 8, sizeof( iBase_EntityHandle ) ); 00385 00386 int dum_hexes_allocated = 8, dum_hexes_size; 00387 00388 // now loop over vertices 00389 for( int i = 0; i < all_verts_size; i++ ) 00390 { 00391 00392 // get the connectivity of this element; will have to allocate space on every 00393 // iteration, since size can vary 00394 iMesh_getEntAdj( mesh, all_verts[i], iBase_REGION, &dum_hexes, &dum_hexes_allocated, &dum_hexes_size, 00395 &success ); 00396 if( iBase_SUCCESS != success ) 00397 { 00398 cerr << "Problem getting connectivity or vertex coords." << endl; 00399 // do not return early, as we would leak memory 00400 } 00401 } 00402 00403 free( dum_hexes ); 00404 free( all_verts ); 00405 } 00406 00407 void print_time( const bool print_em, double& tot_time, double& utime, double& stime, long& imem, long& rmem ) 00408 { 00409 // Disabling this for windows 00410 // Different platforms follow different conventions for usage 00411 #ifndef _WIN32 // Windows does not have rusage 00412 struct rusage r_usage; 00413 getrusage( RUSAGE_SELF, &r_usage ); 00414 utime = (double)r_usage.ru_utime.tv_sec + ( (double)r_usage.ru_utime.tv_usec / 1.e6 ); 00415 stime = (double)r_usage.ru_stime.tv_sec + ( (double)r_usage.ru_stime.tv_usec / 1.e6 ); 00416 tot_time = utime + stime; 00417 if( print_em ) 00418 std::cout << "User, system, total time = " << utime << ", " << stime << ", " << tot_time << std::endl; 00419 00420 #ifndef LINUX 00421 imem = r_usage.ru_idrss; 00422 rmem = r_usage.ru_maxrss; 00423 std::cout << "Max resident set size = " << r_usage.ru_maxrss << " kbytes" << std::endl; 00424 std::cout << "Int resident set size = " << r_usage.ru_idrss << " kbytes" << std::endl; 00425 #else 00426 imem = rmem = 0; 00427 system( "ps o args,drs,rss | grep perf | grep -v grep" ); // RedHat 9.0 doesnt fill in actual 00428 // memory data 00429 #endif 00430 // delete [] hex_array; 00431 #endif // if not on windows 00432 } 00433 00434 void compute_edge( double* start, const int nelem, const double xint, const int stride ) 00435 { 00436 for( int i = 1; i < nelem; i++ ) 00437 { 00438 start[i * stride] = start[0] + i * xint; 00439 start[nelem + 1 + i * stride] = start[nelem + 1] + i * xint; 00440 start[2 * ( nelem + 1 ) + i * stride] = start[2 * ( nelem + 1 )] + i * xint; 00441 } 00442 } 00443 00444 void compute_face( double* a, const int nelem, const double xint, const int stride1, const int stride2 ) 00445 { 00446 // 2D TFI on a face starting at a, with strides stride1 in ada and stride2 in tse 00447 for( int j = 1; j < nelem; j++ ) 00448 { 00449 double tse = j * xint; 00450 for( int i = 1; i < nelem; i++ ) 00451 { 00452 double ada = i * xint; 00453 00454 a[i * stride1 + j * stride2] = 00455 ( 1.0 - ada ) * a[i * stride1] + ada * a[i * stride1 + nelem * stride2] + 00456 ( 1.0 - tse ) * a[j * stride2] + tse * a[j * stride2 + nelem * stride1] - 00457 ( 1.0 - tse ) * ( 1.0 - ada ) * a[0] - ( 1.0 - tse ) * ada * a[nelem * stride1] - 00458 tse * ( 1.0 - ada ) * a[nelem * stride2] - tse * ada * a[nelem * ( stride1 + stride2 )]; 00459 a[nelem + 1 + i * stride1 + j * stride2] = 00460 ( 1.0 - ada ) * a[nelem + 1 + i * stride1] + ada * a[nelem + 1 + i * stride1 + nelem * stride2] + 00461 ( 1.0 - tse ) * a[nelem + 1 + j * stride2] + tse * a[nelem + 1 + j * stride2 + nelem * stride1] - 00462 ( 1.0 - tse ) * ( 1.0 - ada ) * a[nelem + 1 + 0] - 00463 ( 1.0 - tse ) * ada * a[nelem + 1 + nelem * stride1] - 00464 tse * ( 1.0 - ada ) * a[nelem + 1 + nelem * stride2] - 00465 tse * ada * a[nelem + 1 + nelem * ( stride1 + stride2 )]; 00466 a[2 * ( nelem + 1 ) + i * stride1 + j * stride2] = 00467 ( 1.0 - ada ) * a[2 * ( nelem + 1 ) + i * stride1] + 00468 ada * a[2 * ( nelem + 1 ) + i * stride1 + nelem * stride2] + 00469 ( 1.0 - tse ) * a[2 * ( nelem + 1 ) + j * stride2] + 00470 tse * a[2 * ( nelem + 1 ) + j * stride2 + nelem * stride1] - 00471 ( 1.0 - tse ) * ( 1.0 - ada ) * a[2 * ( nelem + 1 ) + 0] - 00472 ( 1.0 - tse ) * ada * a[2 * ( nelem + 1 ) + nelem * stride1] - 00473 tse * ( 1.0 - ada ) * a[2 * ( nelem + 1 ) + nelem * stride2] - 00474 tse * ada * a[2 * ( nelem + 1 ) + nelem * ( stride1 + stride2 )]; 00475 } 00476 } 00477 } 00478 00479 void build_coords( const int nelem, double*& coords ) 00480 { 00481 double ttime0, ttime1, utime1, stime1; 00482 long imem, rmem; 00483 print_time( false, ttime0, utime1, stime1, imem, rmem ); 00484 00485 // allocate the memory 00486 int numv = nelem + 1; 00487 int numv_sq = numv * numv; 00488 int tot_numv = numv * numv * numv; 00489 coords = (double*)malloc( 3 * tot_numv * sizeof( double ) ); 00490 00491 // use FORTRAN-like indexing 00492 #define VINDEX( i, j, k ) ( ( i ) + ( (j)*numv ) + ( (k)*numv_sq ) ) 00493 int idx; 00494 double scale1, scale2, scale3; 00495 // use these to prevent optimization on 1-scale, etc (real map wouldn't have 00496 // all these equal) 00497 scale1 = LENGTH / nelem; 00498 scale2 = LENGTH / nelem; 00499 scale3 = LENGTH / nelem; 00500 00501 #ifdef REALTFI 00502 // use a real TFI xform to compute coordinates 00503 // compute edges 00504 // i (stride=1) 00505 compute_edge( &coords[VINDEX( 0, 0, 0 )], nelem, scale1, 1 ); 00506 compute_edge( &coords[VINDEX( 0, nelem, 0 )], nelem, scale1, 1 ); 00507 compute_edge( &coords[VINDEX( 0, 0, nelem )], nelem, scale1, 1 ); 00508 compute_edge( &coords[VINDEX( 0, nelem, nelem )], nelem, scale1, 1 ); 00509 // j (stride=numv) 00510 compute_edge( &coords[VINDEX( 0, 0, 0 )], nelem, scale1, numv ); 00511 compute_edge( &coords[VINDEX( nelem, 0, 0 )], nelem, scale1, numv ); 00512 compute_edge( &coords[VINDEX( 0, 0, nelem )], nelem, scale1, numv ); 00513 compute_edge( &coords[VINDEX( nelem, 0, nelem )], nelem, scale1, numv ); 00514 // k (stride=numv^2) 00515 compute_edge( &coords[VINDEX( 0, 0, 0 )], nelem, scale1, numv_sq ); 00516 compute_edge( &coords[VINDEX( nelem, 0, 0 )], nelem, scale1, numv_sq ); 00517 compute_edge( &coords[VINDEX( 0, nelem, 0 )], nelem, scale1, numv_sq ); 00518 compute_edge( &coords[VINDEX( nelem, nelem, 0 )], nelem, scale1, numv_sq ); 00519 00520 // compute faces 00521 // i=0, nelem 00522 compute_face( &coords[VINDEX( 0, 0, 0 )], nelem, scale1, numv, numv_sq ); 00523 compute_face( &coords[VINDEX( nelem, 0, 0 )], nelem, scale1, numv, numv_sq ); 00524 // j=0, nelem 00525 compute_face( &coords[VINDEX( 0, 0, 0 )], nelem, scale1, 1, numv_sq ); 00526 compute_face( &coords[VINDEX( 0, nelem, 0 )], nelem, scale1, 1, numv_sq ); 00527 // k=0, nelem 00528 compute_face( &coords[VINDEX( 0, 0, 0 )], nelem, scale1, 1, numv ); 00529 compute_face( &coords[VINDEX( 0, 0, nelem )], nelem, scale1, 1, numv ); 00530 00531 // initialize corner indices 00532 int i000 = VINDEX( 0, 0, 0 ); 00533 int ia00 = VINDEX( nelem, 0, 0 ); 00534 int i0t0 = VINDEX( 0, nelem, 0 ); 00535 int iat0 = VINDEX( nelem, nelem, 0 ); 00536 int i00g = VINDEX( 0, 0, nelem ); 00537 int ia0g = VINDEX( nelem, 0, nelem ); 00538 int i0tg = VINDEX( 0, nelem, nelem ); 00539 int iatg = VINDEX( nelem, nelem, nelem ); 00540 double cX, cY, cZ; 00541 int adaInts = nelem; 00542 int tseInts = nelem; 00543 int gammaInts = nelem; 00544 00545 for( int i = 1; i < nelem; i++ ) 00546 { 00547 for( int j = 1; j < nelem; j++ ) 00548 { 00549 for( int k = 1; k < nelem; k++ ) 00550 { 00551 // idx = VINDEX(i,j,k); 00552 double tse = i * scale1; 00553 double ada = j * scale2; 00554 double gamma = k * scale3; 00555 double tm1 = 1.0 - tse; 00556 double am1 = 1.0 - ada; 00557 double gm1 = 1.0 - gamma; 00558 00559 cX = gm1 * ( am1 * ( tm1 * coords[i000] + tse * coords[i0t0] ) + 00560 ada * ( tm1 * coords[ia00] + tse * coords[iat0] ) ) + 00561 gamma * ( am1 * ( tm1 * coords[i00g] + tse * coords[i0tg] ) + 00562 ada * ( tm1 * coords[ia0g] + tse * coords[iatg] ) ); 00563 00564 cY = gm1 * ( am1 * ( tm1 * coords[i000] + tse * coords[i0t0] ) + 00565 ada * ( tm1 * coords[ia00] + tse * coords[iat0] ) ) + 00566 gamma * ( am1 * ( tm1 * coords[i00g] + tse * coords[i0tg] ) + 00567 ada * ( tm1 * coords[ia0g] + tse * coords[iatg] ) ); 00568 00569 cZ = gm1 * ( am1 * ( tm1 * coords[i000] + tse * coords[i0t0] ) + 00570 ada * ( tm1 * coords[ia00] + tse * coords[iat0] ) ) + 00571 gamma * ( am1 * ( tm1 * coords[i00g] + tse * coords[i0tg] ) + 00572 ada * ( tm1 * coords[ia0g] + tse * coords[iatg] ) ); 00573 00574 double* ai0k = &coords[VINDEX( k, 0, i )]; 00575 double* aiak = &coords[VINDEX( k, adaInts, i )]; 00576 double* a0jk = &coords[VINDEX( k, j, 0 )]; 00577 double* atjk = &coords[VINDEX( k, j, tseInts )]; 00578 double* aij0 = &coords[VINDEX( 0, j, i )]; 00579 double* aijg = &coords[VINDEX( gammaInts, j, i )]; 00580 00581 coords[VINDEX( i, j, k )] = ( am1 * ai0k[0] + ada * aiak[0] + tm1 * a0jk[0] + tse * atjk[0] + 00582 gm1 * aij0[0] + gamma * aijg[0] ) / 00583 2.0 - 00584 cX / 2.0; 00585 00586 coords[nelem + 1 + VINDEX( i, j, k )] = 00587 ( am1 * ai0k[nelem + 1] + ada * aiak[nelem + 1] + tm1 * a0jk[nelem + 1] + tse * atjk[nelem + 1] + 00588 gm1 * aij0[nelem + 1] + gamma * aijg[nelem + 1] ) / 00589 2.0 - 00590 cY / 2.0; 00591 00592 coords[2 * ( nelem + 1 ) + VINDEX( i, j, k )] = 00593 ( am1 * ai0k[2 * ( nelem + 1 )] + ada * aiak[2 * ( nelem + 1 )] + tm1 * a0jk[2 * ( nelem + 1 )] + 00594 tse * atjk[2 * ( nelem + 1 )] + gm1 * aij0[2 * ( nelem + 1 )] + 00595 gamma * aijg[2 * ( nelem + 1 )] ) / 00596 2.0 - 00597 cZ / 2.0; 00598 } 00599 } 00600 } 00601 00602 #else 00603 for( int i = 0; i < numv; i++ ) 00604 { 00605 for( int j = 0; j < numv; j++ ) 00606 { 00607 for( int k = 0; k < numv; k++ ) 00608 { 00609 idx = VINDEX( i, j, k ); 00610 // blocked coordinate ordering 00611 coords[idx] = i * scale1; 00612 coords[tot_numv + idx] = j * scale2; 00613 coords[2 * tot_numv + idx] = k * scale3; 00614 } 00615 } 00616 } 00617 #endif 00618 00619 print_time( false, ttime1, utime1, stime1, imem, rmem ); 00620 std::cout << "TSTTbinding/MOAB: TFI time = " << ttime1 - ttime0 << " sec" << std::endl; 00621 } 00622 00623 void build_connect( const int nelem, const int vstart, int*& connect ) 00624 { 00625 // allocate the memory 00626 int nume_tot = nelem * nelem * nelem; 00627 connect = (int*)malloc( 8 * nume_tot * sizeof( int ) ); 00628 00629 int vijk; 00630 int numv = nelem + 1; 00631 int numv_sq = numv * numv; 00632 int idx = 0; 00633 for( int i = 0; i < nelem; i++ ) 00634 { 00635 for( int j = 0; j < nelem; j++ ) 00636 { 00637 for( int k = 0; k < nelem; k++ ) 00638 { 00639 vijk = vstart + VINDEX( i, j, k ); 00640 connect[idx++] = vijk; 00641 connect[idx++] = vijk + 1; 00642 connect[idx++] = vijk + 1 + numv; 00643 connect[idx++] = vijk + numv; 00644 connect[idx++] = vijk + numv * numv; 00645 connect[idx++] = vijk + 1 + numv * numv; 00646 connect[idx++] = vijk + 1 + numv + numv * numv; 00647 connect[idx++] = vijk + numv + numv * numv; 00648 assert( i <= numv * numv * numv ); 00649 } 00650 } 00651 } 00652 }