MOAB: Mesh Oriented datABase
(version 5.4.1)
|
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 }