MOAB: Mesh Oriented datABase  (version 5.2.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 <stdlib.h>
00031 #include <stdio.h>
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 ) { sscanf( argv[1], "%d", &nelem ); }
00110     std::cout << "number of elements: " << nelem << std::endl;
00111 
00112     // create a hex mesh in a 1x1x1 cube with nelem number of
00113     // elements along an edge
00114     int nnodes = nelem + 1;
00115 
00116     double* coords = NULL;
00117     int* connect   = NULL;
00118 
00119     // build the coordinates
00120     build_coords( nelem, coords );
00121 
00122     // build the connectivity
00123     build_connect( nelem, connect );
00124 
00125     assert( NULL != connect && NULL != coords );
00126 
00127     double ttime0, ttime1, ttime2, ttime3, utime, stime;
00128     print_time( false, ttime0, utime, stime );
00129     int nodes_tot          = nnodes * nnodes * nnodes;
00130     CubitNode** node_array = new CubitNode*[nodes_tot];
00131     int i;
00132     for( i = 0; i < nodes_tot; i++ )
00133         node_array[i] = new CubitNode( coords[3 * i], coords[3 * i + 1], coords[3 * i + 2] );
00134 
00135     int nelem_tot       = nelem * nelem * nelem;
00136     NodeHex** hex_array = new NodeHex*[nelem_tot];
00137     int j               = 0;
00138     CubitNode* conn[8];
00139     for( i = 0; i < nelem_tot; i++ )
00140     {
00141         conn[0] = node_array[connect[j]];
00142         conn[1] = node_array[connect[j + 1]];
00143         conn[2] = node_array[connect[j + 2]];
00144         conn[3] = node_array[connect[j + 3]];
00145         conn[4] = node_array[connect[j + 4]];
00146         conn[5] = node_array[connect[j + 5]];
00147         conn[6] = node_array[connect[j + 6]];
00148         conn[7] = node_array[connect[j + 7]];
00149         j += 8;
00150 
00151         hex_array[i] = new NodeHex( conn );
00152     }
00153 
00154     print_time( false, ttime1, utime, stime );
00155 
00156     // query element to vertex
00157 
00158     for( i = 0; i < nelem_tot; i++ )
00159     {
00160         double centroid[3] = { 0.0, 0.0, 0.0 };
00161         hex_array[i]->hex_nodes( conn[0], conn[1], conn[2], conn[3], conn[4], conn[5], conn[6], conn[7] );
00162         for( j = 0; j < 8; j++ )
00163         {
00164             centroid[0] += conn[j]->node_x();
00165             centroid[1] += conn[j]->node_y();
00166             centroid[2] += conn[j]->node_z();
00167         }
00168     }
00169 
00170     print_time( false, ttime2, utime, stime );
00171 
00172     // need to allocate & populate TDHexKnowing for these
00173     for( i = 0; i < nelem_tot; i++ )
00174         hex_array[i]->add_hex_to_nodes();
00175 
00176     DLIList< CubitHex* > hexes;
00177     for( i = 0; i < nodes_tot; i++ )
00178     {
00179         node_array[i]->all_hexes( hexes );
00180     }
00181 
00182     print_time( false, ttime3, utime, stime );
00183 
00184     std::cout << "CUBIT: nelem, construct, e_to_v query, v_to_e query = " << nelem << ", " << ttime1 - ttime0 << ", "
00185               << ttime2 - ttime1 << ", " << ttime3 - ttime2 << " seconds" << std::endl;
00186     return 0;
00187 }
00188 
00189 void print_time( const bool print_em, double& tot_time, double& utime, double& stime )
00190 {
00191     struct rusage r_usage;
00192     getrusage( RUSAGE_SELF, &r_usage );
00193     utime    = (double)r_usage.ru_utime.tv_sec + ( (double)r_usage.ru_utime.tv_usec / 1.e6 );
00194     stime    = (double)r_usage.ru_stime.tv_sec + ( (double)r_usage.ru_stime.tv_usec / 1.e6 );
00195     tot_time = utime + stime;
00196     if( print_em )
00197         std::cout << "User, system, total time = " << utime << ", " << stime << ", " << tot_time << std::endl;
00198 #ifndef LINUX
00199     std::cout << "Max resident set size = " << r_usage.ru_maxrss * 4096 << " bytes" << std::endl;
00200     std::cout << "Int resident set size = " << r_usage.ru_idrss << std::endl;
00201 #else
00202     system( "ps o args,drs,rss | grep perf | grep -v grep" );  // RedHat 9.0 doesnt fill in actual
00203                                                                // memory data
00204 #endif
00205 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines