![]() |
Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
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 #ifdef WIN32
00017 #ifdef _DEBUG
00018 // turn off warnings that say they debugging identifier has been truncated
00019 // this warning comes up when using some STL containers
00020 #pragma warning( disable : 4786 )
00021 #endif
00022 #endif
00023
00024 #include "WriteAns.hpp"
00025
00026 #include
00027 #include
00028 #include
00029 #include
00030 #include
00031 #include
00032 #include
00033 #include
00034 #include
00035
00036 #include "moab/Interface.hpp"
00037 #include "moab/Range.hpp"
00038 #include
00039 #include "Internals.hpp"
00040 #include "ExoIIUtil.hpp"
00041 #include "MBTagConventions.hpp"
00042
00043 #define INS_ID( stringvar, prefix, id ) sprintf( stringvar, prefix, id )
00044
00045 namespace moab
00046 {
00047
00048 WriterIface* WriteAns::factory( Interface* iface )
00049 {
00050 return new WriteAns( iface );
00051 }
00052
00053 WriteAns::WriteAns( Interface* impl ) : mbImpl( impl ), mCurrentMeshHandle( 0 ), mGlobalIdTag( 0 ), mMatSetIdTag( 0 )
00054 {
00055 assert( impl != NULL );
00056
00057 // impl->query_interface( mWriteIface );
00058
00059 // initialize in case tag_get_handle fails below
00060 //! get and cache predefined tag handles
00061 const int negone = -1;
00062 impl->tag_get_handle( MATERIAL_SET_TAG_NAME, 1, MB_TYPE_INTEGER, mMaterialSetTag, MB_TAG_SPARSE | MB_TAG_CREAT,
00063 &negone );
00064
00065 impl->tag_get_handle( DIRICHLET_SET_TAG_NAME, 1, MB_TYPE_INTEGER, mDirichletSetTag, MB_TAG_SPARSE | MB_TAG_CREAT,
00066 &negone );
00067
00068 impl->tag_get_handle( NEUMANN_SET_TAG_NAME, 1, MB_TYPE_INTEGER, mNeumannSetTag, MB_TAG_SPARSE | MB_TAG_CREAT,
00069 &negone );
00070 }
00071
00072 WriteAns::~WriteAns()
00073 {
00074 // mbImpl->release_interface(mWriteIface);
00075 }
00076
00077 ErrorCode WriteAns::write_file( const char* file_name,
00078 const bool /* overwrite (commented out to remove warning) */,
00079 const FileOptions&,
00080 const EntityHandle* ent_handles,
00081 const int num_sets,
00082 const std::vector< std::string >&,
00083 const Tag*,
00084 int,
00085 int )
00086 {
00087 assert( 0 != mMaterialSetTag && 0 != mNeumannSetTag && 0 != mDirichletSetTag );
00088
00089 ErrorCode result;
00090
00091 // set SOLID45 element type to #60000, hope nobody has already...
00092 const char* ETSolid45 = "60045";
00093 const char* ETSolid92 = "60042";
00094 const char* ETSolid95 = "60095";
00095
00096 // set Material id # to be used as default for all elements
00097 // will need to be subsequently reassigned inside ANSYS
00098 // Can, although have not, declare similar defaults for other attributes
00099 const char* MATDefault = "1";
00100
00101 // create file streams for writing
00102 std::ofstream node_file;
00103 std::ofstream elem_file;
00104 std::ofstream ans_file;
00105
00106 // get base filename from filename.ans
00107 std::string temp_string;
00108 std::string base_string;
00109 base_string.assign( file_name );
00110 base_string.replace( base_string.find_last_of( ".ans" ) - 3, 4, "" );
00111
00112 // open node file for writing
00113 temp_string = base_string + ".node";
00114 node_file.open( temp_string.c_str() );
00115 node_file.setf( std::ios::scientific, std::ios::floatfield );
00116 node_file.precision( 13 );
00117
00118 // open elem file for writing
00119 temp_string = base_string + ".elem";
00120 elem_file.open( temp_string.c_str() );
00121
00122 // open ans file for writing
00123 ans_file.open( file_name );
00124 ans_file << "/prep7" << std::endl;
00125
00126 // gather single output set
00127 EntityHandle output_set = 0;
00128 if( ent_handles && num_sets > 0 )
00129 {
00130 for( int i = 0; i < num_sets; i++ )
00131 {
00132 // from template, maybe can be removed
00133 result = mbImpl->unite_meshset( output_set, ent_handles[i] );
00134 if( result != MB_SUCCESS ) return result;
00135 }
00136 }
00137
00138 // search for all nodes
00139 Range node_range;
00140 result = mbImpl->get_entities_by_type( output_set, MBVERTEX, node_range, true );
00141 if( result != MB_SUCCESS ) return result;
00142
00143 // Commented out until Seg Fault taken care of in gather_nodes...
00144 // get any missing nodes which are needed for elements
00145 // Range all_ent_range,missing_range;
00146 // result=mbImpl->get_entities_by_handle(output_set,all_ent_range,true);
00147 // if(result !=MB_SUCCESS) return result;
00148 // result=mWriteIface->gather_nodes_from_elements(all_ent_range,0,missing_range);
00149 // node_range.merge(missing_range);
00150
00151 // write the nodes
00152 double coord[3];
00153 for( Range::iterator it = node_range.begin(); it != node_range.end(); ++it )
00154 {
00155 EntityHandle node_handle = *it;
00156
00157 result = mbImpl->get_coords( &node_handle, 1, coord );
00158 if( result != MB_SUCCESS ) return result;
00159
00160 node_file.width( 8 );
00161 node_file << mbImpl->id_from_handle( node_handle );
00162 node_file.width( 20 );
00163 node_file << coord[0];
00164 node_file.width( 20 );
00165 node_file << coord[1];
00166 node_file.width( 20 );
00167 node_file << coord[2] << std::endl;
00168 }
00169
00170 // update header to load nodes
00171 ans_file << "nread," << base_string << ",node" << std::endl;
00172
00173 // search for all node sets (Dirichlet Sets)
00174 Range node_mesh_sets;
00175 int ns_id;
00176 result = mbImpl->get_entities_by_type_and_tag( 0, MBENTITYSET, &mDirichletSetTag, NULL, 1, node_mesh_sets );
00177 if( result != MB_SUCCESS ) return result;
00178
00179 for( Range::iterator ns_it = node_mesh_sets.begin(); ns_it != node_mesh_sets.end(); ++ns_it )
00180 {
00181 result = mbImpl->tag_get_data( mDirichletSetTag, &( *ns_it ), 1, &ns_id );
00182 if( result != MB_SUCCESS ) return result;
00183 std::vector< EntityHandle > node_vector;
00184 result = mbImpl->get_entities_by_handle( *ns_it, node_vector, true );
00185 if( result != MB_SUCCESS ) return result;
00186 // for every nodeset found, cycle through nodes in set:
00187 for( std::vector< EntityHandle >::iterator node_it = node_vector.begin(); node_it != node_vector.end();
00188 ++node_it )
00189 {
00190 int ns_node_id = mbImpl->id_from_handle( *node_it );
00191 if( node_it == node_vector.begin() )
00192 {
00193 // select first node in new list
00194 ans_file << "nsel,s,node,," << std::setw( 8 ) << ns_node_id << std::endl;
00195 }
00196 else
00197 {
00198 // append node to list
00199 ans_file << "nsel,a,node,," << std::setw( 8 ) << ns_node_id << std::endl;
00200 }
00201 }
00202 // create NS(#) nodeset
00203 ans_file << "cm,NS" << ns_id << ",node" << std::endl;
00204 }
00205
00206 // ANSYS Element format:
00207 // I, J, K, L, M, N, O, P,etc... MAT, TYPE, REAL, SECNUM, ESYS, IEL
00208 // I-P are nodes of element
00209 // MAT = material number
00210 // TYPE = Element type number
00211 // REAL = Real constant set number
00212 // SECNUM = section attribute number
00213 // ESYS = coordinate system for nodes
00214 // IEL = element # (unique?)
00215 // For all nodes past 8, write on second line
00216
00217 // Write all MBTET elements
00218 Range tet_range;
00219 result = mbImpl->get_entities_by_type( output_set, MBTET, tet_range, true );
00220 if( result != MB_SUCCESS ) return result;
00221 for( Range::iterator elem_it = tet_range.begin(); elem_it != tet_range.end(); ++elem_it )
00222 {
00223 EntityHandle elem_handle = *elem_it;
00224 int elem_id = mbImpl->id_from_handle( elem_handle );
00225 std::vector< EntityHandle > conn;
00226 result = mbImpl->get_connectivity( &elem_handle, 1, conn, false );
00227 if( result != MB_SUCCESS ) return result;
00228 // make sure 4 or 10 node tet
00229 if( conn.size() != 4 && conn.size() != 10 )
00230 {
00231 std::cout << "Support not added for element type. \n";
00232 return MB_FAILURE;
00233 }
00234 // write information for 4 node tet
00235 if( conn.size() == 4 )
00236 {
00237 elem_file << std::setw( 8 ) << conn[0] << std::setw( 8 ) << conn[1];
00238 elem_file << std::setw( 8 ) << conn[2] << std::setw( 8 ) << conn[2];
00239 elem_file << std::setw( 8 ) << conn[3] << std::setw( 8 ) << conn[3];
00240 elem_file << std::setw( 8 ) << conn[3] << std::setw( 8 ) << conn[3];
00241
00242 elem_file << std::setw( 8 ) << MATDefault << std::setw( 8 ) << ETSolid45;
00243 elem_file << std::setw( 8 ) << "1" << std::setw( 8 ) << "1";
00244 elem_file << std::setw( 8 ) << "0" << std::setw( 8 ) << elem_id;
00245 elem_file << std::endl;
00246 }
00247
00248 // write information for 10 node tet
00249 if( conn.size() == 10 )
00250 {
00251 elem_file << std::setw( 8 ) << conn[0] << std::setw( 8 ) << conn[1];
00252 elem_file << std::setw( 8 ) << conn[2] << std::setw( 8 ) << conn[3];
00253 elem_file << std::setw( 8 ) << conn[4] << std::setw( 8 ) << conn[5];
00254 elem_file << std::setw( 8 ) << conn[6] << std::setw( 8 ) << conn[7];
00255
00256 elem_file << std::setw( 8 ) << MATDefault << std::setw( 8 ) << ETSolid92;
00257 elem_file << std::setw( 8 ) << "1" << std::setw( 8 ) << "1";
00258 elem_file << std::setw( 8 ) << "0" << std::setw( 8 ) << elem_id;
00259 elem_file << std::endl;
00260
00261 elem_file << std::setw( 8 ) << conn[8] << std::setw( 8 ) << conn[9];
00262 elem_file << std::endl;
00263 }
00264 }
00265
00266 // Write all MBHEX elements
00267 Range hex_range;
00268 result = mbImpl->get_entities_by_type( output_set, MBHEX, hex_range, true );
00269 if( result != MB_SUCCESS ) return result;
00270 for( Range::iterator elem_it = hex_range.begin(); elem_it != hex_range.end(); ++elem_it )
00271 {
00272 EntityHandle elem_handle = *elem_it;
00273 int elem_id = mbImpl->id_from_handle( elem_handle );
00274 std::vector< EntityHandle > conn;
00275 result = mbImpl->get_connectivity( &elem_handle, 1, conn, false );
00276 if( result != MB_SUCCESS ) return result;
00277 // make sure supported hex type
00278 if( conn.size() != 8 && conn.size() != 20 )
00279 {
00280 std::cout << "Support not added for element type. \n";
00281 return MB_FAILURE;
00282 }
00283
00284 // write information for 8 node hex
00285 if( conn.size() == 8 )
00286 {
00287 elem_file << std::setw( 8 ) << conn[0] << std::setw( 8 ) << conn[1];
00288 elem_file << std::setw( 8 ) << conn[2] << std::setw( 8 ) << conn[3];
00289 elem_file << std::setw( 8 ) << conn[4] << std::setw( 8 ) << conn[5];
00290 elem_file << std::setw( 8 ) << conn[6] << std::setw( 8 ) << conn[7];
00291
00292 elem_file << std::setw( 8 ) << MATDefault << std::setw( 8 ) << ETSolid45;
00293 elem_file << std::setw( 8 ) << "1" << std::setw( 8 ) << "1";
00294 elem_file << std::setw( 8 ) << "0" << std::setw( 8 ) << elem_id;
00295 elem_file << std::endl;
00296 }
00297
00298 // write information for 20 node hex
00299 if( conn.size() == 20 )
00300 {
00301
00302 elem_file << std::setw( 8 ) << conn[4] << std::setw( 8 ) << conn[5];
00303 elem_file << std::setw( 8 ) << conn[1] << std::setw( 8 ) << conn[0];
00304 elem_file << std::setw( 8 ) << conn[7] << std::setw( 8 ) << conn[6];
00305 elem_file << std::setw( 8 ) << conn[2] << std::setw( 8 ) << conn[3];
00306
00307 elem_file << std::setw( 8 ) << MATDefault << std::setw( 8 ) << ETSolid95;
00308 elem_file << std::setw( 8 ) << "1" << std::setw( 8 ) << "1";
00309 elem_file << std::setw( 8 ) << "0" << std::setw( 8 ) << elem_id;
00310 elem_file << std::endl;
00311
00312 elem_file << std::setw( 8 ) << conn[16] << std::setw( 8 ) << conn[13];
00313 elem_file << std::setw( 8 ) << conn[8] << std::setw( 8 ) << conn[12];
00314 elem_file << std::setw( 8 ) << conn[18] << std::setw( 8 ) << conn[14];
00315 elem_file << std::setw( 8 ) << conn[10] << std::setw( 8 ) << conn[15];
00316 elem_file << std::setw( 8 ) << conn[19] << std::setw( 8 ) << conn[17];
00317 elem_file << std::setw( 8 ) << conn[9] << std::setw( 8 ) << conn[11];
00318 elem_file << std::endl;
00319 }
00320 }
00321 // Write all MBPRISM elements
00322 Range prism_range;
00323 result = mbImpl->get_entities_by_type( output_set, MBPRISM, prism_range, true );
00324 if( result != MB_SUCCESS ) return result;
00325 for( Range::iterator elem_it = prism_range.begin(); elem_it != prism_range.end(); ++elem_it )
00326 {
00327 EntityHandle elem_handle = *elem_it;
00328 int elem_id = mbImpl->id_from_handle( elem_handle );
00329 std::vector< EntityHandle > conn;
00330 result = mbImpl->get_connectivity( &elem_handle, 1, conn, false );
00331 if( result != MB_SUCCESS ) return result;
00332 // make sure supported prism type
00333 if( conn.size() != 6 )
00334 {
00335 std::cout << "Support not added for element type. \n";
00336 return MB_FAILURE;
00337 }
00338
00339 // write information for 6 node prism
00340 if( conn.size() == 6 )
00341 {
00342 elem_file << std::setw( 8 ) << conn[0] << std::setw( 8 ) << conn[3];
00343 elem_file << std::setw( 8 ) << conn[4] << std::setw( 8 ) << conn[4];
00344 elem_file << std::setw( 8 ) << conn[1] << std::setw( 8 ) << conn[2];
00345 elem_file << std::setw( 8 ) << conn[5] << std::setw( 8 ) << conn[5];
00346
00347 elem_file << std::setw( 8 ) << MATDefault << std::setw( 8 ) << ETSolid45;
00348 elem_file << std::setw( 8 ) << "1" << std::setw( 8 ) << "1";
00349 elem_file << std::setw( 8 ) << "0" << std::setw( 8 ) << elem_id;
00350 elem_file << std::endl;
00351 }
00352 }
00353
00354 // create element types (for now writes all, even if not used)
00355 ans_file << "et," << ETSolid45 << ",SOLID45" << std::endl;
00356 ans_file << "et," << ETSolid92 << ",SOLID92" << std::endl;
00357 ans_file << "et," << ETSolid95 << ",SOLID95" << std::endl;
00358
00359 // xxx pyramids, other elements later...
00360
00361 // write header to load elements
00362 ans_file << "eread," << base_string << ",elem" << std::endl;
00363
00364 // search for all side sets (Neumann)
00365 Range side_mesh_sets;
00366 int ss_id;
00367 result = mbImpl->get_entities_by_type_and_tag( 0, MBENTITYSET, &mNeumannSetTag, NULL, 1, side_mesh_sets );
00368 if( result != MB_SUCCESS ) return result;
00369 // cycle through all sets found
00370 for( Range::iterator ss_it = side_mesh_sets.begin(); ss_it != side_mesh_sets.end(); ++ss_it )
00371 {
00372 result = mbImpl->tag_get_data( mNeumannSetTag, &( *ss_it ), 1, &ss_id );
00373 if( result != MB_SUCCESS ) return result;
00374 std::vector< EntityHandle > elem_vector;
00375 result = mbImpl->get_entities_by_handle( *ss_it, elem_vector, true );
00376 if( result != MB_SUCCESS ) return result;
00377
00378 // cycle through elements in current side set
00379 for( std::vector< EntityHandle >::iterator elem_it = elem_vector.begin(); elem_it != elem_vector.end();
00380 ++elem_it )
00381 {
00382 EntityHandle elem_handle = *elem_it;
00383
00384 // instead of selecting current element in set, select its nodes...
00385 std::vector< EntityHandle > conn;
00386 result = mbImpl->get_connectivity( &elem_handle, 1, conn );
00387 if( result != MB_SUCCESS ) return result;
00388 if( elem_it == elem_vector.begin() )
00389 {
00390 ans_file << "nsel,s,node,," << std::setw( 8 ) << conn[0] << std::endl;
00391 for( unsigned int i = 1; i < conn.size(); i++ )
00392 {
00393 ans_file << "nsel,a,node,," << std::setw( 8 ) << conn[i] << std::endl;
00394 }
00395 }
00396 else
00397 {
00398 for( unsigned int i = 0; i < conn.size(); i++ )
00399 {
00400 ans_file << "nsel,a,node,," << std::setw( 8 ) << conn[i] << std::endl;
00401 }
00402 }
00403 }
00404 // create SS(#) node set
00405 ans_file << "cm,SS" << ss_id << ",node" << std::endl;
00406 }
00407
00408 // Gather all element blocks
00409 Range matset;
00410 int mat_id;
00411 result = mbImpl->get_entities_by_type_and_tag( 0, MBENTITYSET, &mMaterialSetTag, NULL, 1, matset );
00412 if( result != MB_SUCCESS ) return result;
00413 // cycle through all elem blocks
00414 for( Range::iterator mat_it = matset.begin(); mat_it != matset.end(); ++mat_it )
00415 {
00416 EntityHandle matset_handle = *mat_it;
00417 result = mbImpl->tag_get_data( mMaterialSetTag, &matset_handle, 1, &mat_id );
00418 if( result != MB_SUCCESS ) return result;
00419 std::vector< EntityHandle > mat_vector;
00420 result = mbImpl->get_entities_by_handle( *mat_it, mat_vector, true );
00421 if( result != MB_SUCCESS ) return result;
00422 // cycle through elements in current mat set
00423 for( std::vector< EntityHandle >::iterator elem_it = mat_vector.begin(); elem_it != mat_vector.end();
00424 ++elem_it )
00425 {
00426 EntityHandle elem_handle = *elem_it;
00427 int elem_id = mbImpl->id_from_handle( elem_handle );
00428 if( elem_it == mat_vector.begin() )
00429 {
00430 ans_file << "esel,s,elem,," << std::setw( 8 ) << elem_id << std::endl;
00431 }
00432 else
00433 {
00434 ans_file << "esel,a,elem,," << std::setw( 8 ) << elem_id << std::endl;
00435 }
00436 }
00437 // for each matset, write block command
00438 ans_file << "cm,EB" << mat_id << ",elem" << std::endl;
00439 }
00440
00441 // close all file streams
00442 node_file.close();
00443 elem_file.close();
00444 ans_file.close();
00445
00446 return MB_SUCCESS;
00447 }
00448
00449 } // namespace moab