MOAB: Mesh Oriented datABase  (version 5.4.1)
cubit_perf.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 // Cubit performance tests building mapped mesh with CubitNodes
00017 // and CubitHexes.
00018 
00019 // Different platforms follow different conventions for usage
00020 #ifndef NT
00021 #include <sys/resource.h>
00022 #endif
00023 #ifdef SOLARIS
00024 extern "C" int getrusage( int, struct rusage* );
00025 #ifndef RUSAGE_SELF
00026 #include </usr/ucbinclude/sys/rusage.h>
00027 #endif
00028 #endif
00029 
00030 #include <cstdlib>
00031 #include <cstdio>
00032 #include <iostream>
00033 #include "CubitNode.hpp"
00034 #include "NodeHex.hpp"
00035 
00036 using namespace moab;
00037 
00038 const double LENGTH = 1.0;
00039 
00040 extern "C" {
00041 void __ctype_toupper() {}
00042 }
00043 
00044 void print_time( const bool print_em, double& tot_time, double& utime, double& stime );
00045 
00046 void build_coords( const int nelem, double*& coords )
00047 {
00048     // allocate the memory
00049     int numv     = nelem + 1;
00050     int numv_sq  = numv * numv;
00051     int tot_numv = numv * numv * numv;
00052     coords       = new double[3 * tot_numv];
00053 
00054     double scale = LENGTH / nelem;
00055 // use FORTRAN-like indexing
00056 #define VINDEX( i, j, k ) ( ( i ) + ( (j)*numv ) + ( (k)*numv_sq ) )
00057 
00058     int idx;
00059     for( int i = 0; i < numv; i++ )
00060     {
00061         for( int j = 0; j < numv; j++ )
00062         {
00063             for( int k = 0; k < numv; k++ )
00064             {
00065                 idx = VINDEX( i, j, k );
00066                 // interleaved coordinate ordering
00067                 coords[3 * idx]     = i * scale;
00068                 coords[3 * idx + 1] = j * scale;
00069                 coords[3 * idx + 2] = k * scale;
00070             }
00071         }
00072     }
00073 }
00074 
00075 void build_connect( const int nelem, int*& connect )
00076 {
00077     // allocate the memory
00078     int nume_tot = nelem * nelem * nelem;
00079     connect      = new int[8 * nume_tot];
00080 
00081     int numv    = nelem + 1;
00082     int numv_sq = numv * numv;
00083     int idx     = 0;
00084     int vijk;
00085     for( int i = 0; i < nelem; i++ )
00086     {
00087         for( int j = 0; j < nelem; j++ )
00088         {
00089             for( int k = 0; k < nelem; k++ )
00090             {
00091                 vijk           = VINDEX( i, j, k );
00092                 connect[idx++] = vijk;
00093                 connect[idx++] = vijk + 1;
00094                 connect[idx++] = vijk + 1 + numv;
00095                 connect[idx++] = vijk + numv;
00096                 connect[idx++] = vijk + numv * numv;
00097                 connect[idx++] = vijk + 1 + numv * numv;
00098                 connect[idx++] = vijk + 1 + numv + numv * numv;
00099                 connect[idx++] = vijk + numv + numv * numv;
00100                 assert( idx <= 8 * nume_tot );
00101             }
00102         }
00103     }
00104 }
00105 
00106 int main( int argc, char* argv[] )
00107 {
00108     int nelem = 20;
00109     if( argc > 1 )
00110     {
00111         sscanf( argv[1], "%d", &nelem );
00112     }
00113     std::cout << "number of elements: " << nelem << std::endl;
00114 
00115     // create a hex mesh in a 1x1x1 cube with nelem number of
00116     // elements along an edge
00117     int nnodes = nelem + 1;
00118 
00119     double* coords = NULL;
00120     int* connect   = NULL;
00121 
00122     // build the coordinates
00123     build_coords( nelem, coords );
00124 
00125     // build the connectivity
00126     build_connect( nelem, connect );
00127 
00128     assert( NULL != connect && NULL != coords );
00129 
00130     double ttime0, ttime1, ttime2, ttime3, utime, stime;
00131     print_time( false, ttime0, utime, stime );
00132     int nodes_tot          = nnodes * nnodes * nnodes;
00133     CubitNode** node_array = new CubitNode*[nodes_tot];
00134     int i;
00135     for( i = 0; i < nodes_tot; i++ )
00136         node_array[i] = new CubitNode( coords[3 * i], coords[3 * i + 1], coords[3 * i + 2] );
00137 
00138     int nelem_tot       = nelem * nelem * nelem;
00139     NodeHex** hex_array = new NodeHex*[nelem_tot];
00140     int j               = 0;
00141     CubitNode* conn[8];
00142     for( i = 0; i < nelem_tot; i++ )
00143     {
00144         conn[0] = node_array[connect[j]];
00145         conn[1] = node_array[connect[j + 1]];
00146         conn[2] = node_array[connect[j + 2]];
00147         conn[3] = node_array[connect[j + 3]];
00148         conn[4] = node_array[connect[j + 4]];
00149         conn[5] = node_array[connect[j + 5]];
00150         conn[6] = node_array[connect[j + 6]];
00151         conn[7] = node_array[connect[j + 7]];
00152         j += 8;
00153 
00154         hex_array[i] = new NodeHex( conn );
00155     }
00156 
00157     print_time( false, ttime1, utime, stime );
00158 
00159     // query element to vertex
00160 
00161     for( i = 0; i < nelem_tot; i++ )
00162     {
00163         double centroid[3] = { 0.0, 0.0, 0.0 };
00164         hex_array[i]->hex_nodes( conn[0], conn[1], conn[2], conn[3], conn[4], conn[5], conn[6], conn[7] );
00165         for( j = 0; j < 8; j++ )
00166         {
00167             centroid[0] += conn[j]->node_x();
00168             centroid[1] += conn[j]->node_y();
00169             centroid[2] += conn[j]->node_z();
00170         }
00171     }
00172 
00173     print_time( false, ttime2, utime, stime );
00174 
00175     // need to allocate & populate TDHexKnowing for these
00176     for( i = 0; i < nelem_tot; i++ )
00177         hex_array[i]->add_hex_to_nodes();
00178 
00179     DLIList< CubitHex* > hexes;
00180     for( i = 0; i < nodes_tot; i++ )
00181     {
00182         node_array[i]->all_hexes( hexes );
00183     }
00184 
00185     print_time( false, ttime3, utime, stime );
00186 
00187     std::cout << "CUBIT: nelem, construct, e_to_v query, v_to_e query = " << nelem << ", " << ttime1 - ttime0 << ", "
00188               << ttime2 - ttime1 << ", " << ttime3 - ttime2 << " seconds" << std::endl;
00189     return 0;
00190 }
00191 
00192 void print_time( const bool print_em, double& tot_time, double& utime, double& stime )
00193 {
00194     struct rusage r_usage;
00195     getrusage( RUSAGE_SELF, &r_usage );
00196     utime    = (double)r_usage.ru_utime.tv_sec + ( (double)r_usage.ru_utime.tv_usec / 1.e6 );
00197     stime    = (double)r_usage.ru_stime.tv_sec + ( (double)r_usage.ru_stime.tv_usec / 1.e6 );
00198     tot_time = utime + stime;
00199     if( print_em )
00200         std::cout << "User, system, total time = " << utime << ", " << stime << ", " << tot_time << std::endl;
00201 #ifndef LINUX
00202     std::cout << "Max resident set size = " << r_usage.ru_maxrss * 4096 << " bytes" << std::endl;
00203     std::cout << "Int resident set size = " << r_usage.ru_idrss << std::endl;
00204 #else
00205     system( "ps o args,drs,rss | grep perf | grep -v grep" );  // RedHat 9.0 doesnt fill in actual
00206                                                                // memory data
00207 #endif
00208 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines