![]() |
Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
#include <WriteAns.hpp>
Classes | |
struct | DirichletSetData |
struct used to hold data for each nodeset to be output; used by initialize_file to initialize the file header for increased speed More... | |
struct | MaterialSetData |
struct used to hold data for each block to be output; used by initialize_file to initialize the file header for increased speed More... | |
class | MeshInfo |
number of dimensions in this file More... | |
struct | NeumannSetData |
struct used to hold data for each sideset to be output; used by initialize_file to initialize the file header for increased speed More... | |
Public Member Functions | |
WriteAns (Interface *impl) | |
Constructor. | |
virtual | ~WriteAns () |
Destructor. | |
ErrorCode | write_file (const char *file_name, const bool overwrite, const FileOptions &opts, const EntityHandle *output_list, const int num_sets, const std::vector< std::string > &qa_list, const Tag *tag_list=NULL, int num_tags=0, int export_dimension=3) |
writes out a file | |
Static Public Member Functions | |
static WriterIface * | factory (Interface *) |
Private Member Functions | |
ErrorCode | write_nodes (const int num_nodes, const Range &nodes, const int dimension, const char *file_name) |
Private Attributes | |
Interface * | mbImpl |
interface instance | |
std::string | fileName |
file name | |
EntityHandle | mCurrentMeshHandle |
Meshset Handle for the mesh that is currently being read. | |
Tag | mMaterialSetTag |
Cached tags for reading. Note that all these tags are defined when the core is initialized. | |
Tag | mDirichletSetTag |
Tag | mNeumannSetTag |
Tag | mGlobalIdTag |
Tag | mMatSetIdTag |
Definition at line 49 of file WriteAns.hpp.
moab::WriteAns::WriteAns | ( | Interface * | impl | ) |
Constructor.
get and cache predefined tag handles
Definition at line 53 of file WriteAns.cpp.
References DIRICHLET_SET_TAG_NAME, MATERIAL_SET_TAG_NAME, MB_TAG_CREAT, MB_TAG_SPARSE, MB_TYPE_INTEGER, mDirichletSetTag, mMaterialSetTag, mNeumannSetTag, NEUMANN_SET_TAG_NAME, and moab::Interface::tag_get_handle().
Referenced by factory().
: mbImpl( impl ), mCurrentMeshHandle( 0 ), mGlobalIdTag( 0 ), mMatSetIdTag( 0 )
{
assert( impl != NULL );
// impl->query_interface( mWriteIface );
// initialize in case tag_get_handle fails below
//! get and cache predefined tag handles
const int negone = -1;
impl->tag_get_handle( MATERIAL_SET_TAG_NAME, 1, MB_TYPE_INTEGER, mMaterialSetTag, MB_TAG_SPARSE | MB_TAG_CREAT,
&negone );
impl->tag_get_handle( DIRICHLET_SET_TAG_NAME, 1, MB_TYPE_INTEGER, mDirichletSetTag, MB_TAG_SPARSE | MB_TAG_CREAT,
&negone );
impl->tag_get_handle( NEUMANN_SET_TAG_NAME, 1, MB_TYPE_INTEGER, mNeumannSetTag, MB_TAG_SPARSE | MB_TAG_CREAT,
&negone );
}
moab::WriteAns::~WriteAns | ( | ) | [virtual] |
Destructor.
Definition at line 72 of file WriteAns.cpp.
{
// mbImpl->release_interface(mWriteIface);
}
WriterIface * moab::WriteAns::factory | ( | Interface * | iface | ) | [static] |
Definition at line 48 of file WriteAns.cpp.
References WriteAns().
Referenced by moab::ReaderWriterSet::ReaderWriterSet().
{
return new WriteAns( iface );
}
ErrorCode moab::WriteAns::write_file | ( | const char * | file_name, |
const bool | overwrite, | ||
const FileOptions & | opts, | ||
const EntityHandle * | output_list, | ||
const int | num_sets, | ||
const std::vector< std::string > & | qa_list, | ||
const Tag * | tag_list = NULL , |
||
int | num_tags = 0 , |
||
int | export_dimension = 3 |
||
) | [virtual] |
writes out a file
Implements moab::WriterIface.
Definition at line 77 of file WriteAns.cpp.
References moab::Range::begin(), moab::Range::end(), ErrorCode, moab::Interface::get_connectivity(), moab::Interface::get_coords(), moab::Interface::get_entities_by_handle(), moab::Interface::get_entities_by_type(), moab::Interface::get_entities_by_type_and_tag(), moab::Interface::id_from_handle(), MB_SUCCESS, MBENTITYSET, MBHEX, mbImpl, MBPRISM, MBTET, MBVERTEX, mDirichletSetTag, mMaterialSetTag, mNeumannSetTag, moab::Interface::tag_get_data(), and moab::Interface::unite_meshset().
{
assert( 0 != mMaterialSetTag && 0 != mNeumannSetTag && 0 != mDirichletSetTag );
ErrorCode result;
// set SOLID45 element type to #60000, hope nobody has already...
const char* ETSolid45 = "60045";
const char* ETSolid92 = "60042";
const char* ETSolid95 = "60095";
// set Material id # to be used as default for all elements
// will need to be subsequently reassigned inside ANSYS
// Can, although have not, declare similar defaults for other attributes
const char* MATDefault = "1";
// create file streams for writing
std::ofstream node_file;
std::ofstream elem_file;
std::ofstream ans_file;
// get base filename from filename.ans
std::string temp_string;
std::string base_string;
base_string.assign( file_name );
base_string.replace( base_string.find_last_of( ".ans" ) - 3, 4, "" );
// open node file for writing
temp_string = base_string + ".node";
node_file.open( temp_string.c_str() );
node_file.setf( std::ios::scientific, std::ios::floatfield );
node_file.precision( 13 );
// open elem file for writing
temp_string = base_string + ".elem";
elem_file.open( temp_string.c_str() );
// open ans file for writing
ans_file.open( file_name );
ans_file << "/prep7" << std::endl;
// gather single output set
EntityHandle output_set = 0;
if( ent_handles && num_sets > 0 )
{
for( int i = 0; i < num_sets; i++ )
{
// from template, maybe can be removed
result = mbImpl->unite_meshset( output_set, ent_handles[i] );
if( result != MB_SUCCESS ) return result;
}
}
// search for all nodes
Range node_range;
result = mbImpl->get_entities_by_type( output_set, MBVERTEX, node_range, true );
if( result != MB_SUCCESS ) return result;
// Commented out until Seg Fault taken care of in gather_nodes...
// get any missing nodes which are needed for elements
// Range all_ent_range,missing_range;
// result=mbImpl->get_entities_by_handle(output_set,all_ent_range,true);
// if(result !=MB_SUCCESS) return result;
// result=mWriteIface->gather_nodes_from_elements(all_ent_range,0,missing_range);
// node_range.merge(missing_range);
// write the nodes
double coord[3];
for( Range::iterator it = node_range.begin(); it != node_range.end(); ++it )
{
EntityHandle node_handle = *it;
result = mbImpl->get_coords( &node_handle, 1, coord );
if( result != MB_SUCCESS ) return result;
node_file.width( 8 );
node_file << mbImpl->id_from_handle( node_handle );
node_file.width( 20 );
node_file << coord[0];
node_file.width( 20 );
node_file << coord[1];
node_file.width( 20 );
node_file << coord[2] << std::endl;
}
// update header to load nodes
ans_file << "nread," << base_string << ",node" << std::endl;
// search for all node sets (Dirichlet Sets)
Range node_mesh_sets;
int ns_id;
result = mbImpl->get_entities_by_type_and_tag( 0, MBENTITYSET, &mDirichletSetTag, NULL, 1, node_mesh_sets );
if( result != MB_SUCCESS ) return result;
for( Range::iterator ns_it = node_mesh_sets.begin(); ns_it != node_mesh_sets.end(); ++ns_it )
{
result = mbImpl->tag_get_data( mDirichletSetTag, &( *ns_it ), 1, &ns_id );
if( result != MB_SUCCESS ) return result;
std::vector< EntityHandle > node_vector;
result = mbImpl->get_entities_by_handle( *ns_it, node_vector, true );
if( result != MB_SUCCESS ) return result;
// for every nodeset found, cycle through nodes in set:
for( std::vector< EntityHandle >::iterator node_it = node_vector.begin(); node_it != node_vector.end();
++node_it )
{
int ns_node_id = mbImpl->id_from_handle( *node_it );
if( node_it == node_vector.begin() )
{
// select first node in new list
ans_file << "nsel,s,node,," << std::setw( 8 ) << ns_node_id << std::endl;
}
else
{
// append node to list
ans_file << "nsel,a,node,," << std::setw( 8 ) << ns_node_id << std::endl;
}
}
// create NS(#) nodeset
ans_file << "cm,NS" << ns_id << ",node" << std::endl;
}
// ANSYS Element format:
// I, J, K, L, M, N, O, P,etc... MAT, TYPE, REAL, SECNUM, ESYS, IEL
// I-P are nodes of element
// MAT = material number
// TYPE = Element type number
// REAL = Real constant set number
// SECNUM = section attribute number
// ESYS = coordinate system for nodes
// IEL = element # (unique?)
// For all nodes past 8, write on second line
// Write all MBTET elements
Range tet_range;
result = mbImpl->get_entities_by_type( output_set, MBTET, tet_range, true );
if( result != MB_SUCCESS ) return result;
for( Range::iterator elem_it = tet_range.begin(); elem_it != tet_range.end(); ++elem_it )
{
EntityHandle elem_handle = *elem_it;
int elem_id = mbImpl->id_from_handle( elem_handle );
std::vector< EntityHandle > conn;
result = mbImpl->get_connectivity( &elem_handle, 1, conn, false );
if( result != MB_SUCCESS ) return result;
// make sure 4 or 10 node tet
if( conn.size() != 4 && conn.size() != 10 )
{
std::cout << "Support not added for element type. \n";
return MB_FAILURE;
}
// write information for 4 node tet
if( conn.size() == 4 )
{
elem_file << std::setw( 8 ) << conn[0] << std::setw( 8 ) << conn[1];
elem_file << std::setw( 8 ) << conn[2] << std::setw( 8 ) << conn[2];
elem_file << std::setw( 8 ) << conn[3] << std::setw( 8 ) << conn[3];
elem_file << std::setw( 8 ) << conn[3] << std::setw( 8 ) << conn[3];
elem_file << std::setw( 8 ) << MATDefault << std::setw( 8 ) << ETSolid45;
elem_file << std::setw( 8 ) << "1" << std::setw( 8 ) << "1";
elem_file << std::setw( 8 ) << "0" << std::setw( 8 ) << elem_id;
elem_file << std::endl;
}
// write information for 10 node tet
if( conn.size() == 10 )
{
elem_file << std::setw( 8 ) << conn[0] << std::setw( 8 ) << conn[1];
elem_file << std::setw( 8 ) << conn[2] << std::setw( 8 ) << conn[3];
elem_file << std::setw( 8 ) << conn[4] << std::setw( 8 ) << conn[5];
elem_file << std::setw( 8 ) << conn[6] << std::setw( 8 ) << conn[7];
elem_file << std::setw( 8 ) << MATDefault << std::setw( 8 ) << ETSolid92;
elem_file << std::setw( 8 ) << "1" << std::setw( 8 ) << "1";
elem_file << std::setw( 8 ) << "0" << std::setw( 8 ) << elem_id;
elem_file << std::endl;
elem_file << std::setw( 8 ) << conn[8] << std::setw( 8 ) << conn[9];
elem_file << std::endl;
}
}
// Write all MBHEX elements
Range hex_range;
result = mbImpl->get_entities_by_type( output_set, MBHEX, hex_range, true );
if( result != MB_SUCCESS ) return result;
for( Range::iterator elem_it = hex_range.begin(); elem_it != hex_range.end(); ++elem_it )
{
EntityHandle elem_handle = *elem_it;
int elem_id = mbImpl->id_from_handle( elem_handle );
std::vector< EntityHandle > conn;
result = mbImpl->get_connectivity( &elem_handle, 1, conn, false );
if( result != MB_SUCCESS ) return result;
// make sure supported hex type
if( conn.size() != 8 && conn.size() != 20 )
{
std::cout << "Support not added for element type. \n";
return MB_FAILURE;
}
// write information for 8 node hex
if( conn.size() == 8 )
{
elem_file << std::setw( 8 ) << conn[0] << std::setw( 8 ) << conn[1];
elem_file << std::setw( 8 ) << conn[2] << std::setw( 8 ) << conn[3];
elem_file << std::setw( 8 ) << conn[4] << std::setw( 8 ) << conn[5];
elem_file << std::setw( 8 ) << conn[6] << std::setw( 8 ) << conn[7];
elem_file << std::setw( 8 ) << MATDefault << std::setw( 8 ) << ETSolid45;
elem_file << std::setw( 8 ) << "1" << std::setw( 8 ) << "1";
elem_file << std::setw( 8 ) << "0" << std::setw( 8 ) << elem_id;
elem_file << std::endl;
}
// write information for 20 node hex
if( conn.size() == 20 )
{
elem_file << std::setw( 8 ) << conn[4] << std::setw( 8 ) << conn[5];
elem_file << std::setw( 8 ) << conn[1] << std::setw( 8 ) << conn[0];
elem_file << std::setw( 8 ) << conn[7] << std::setw( 8 ) << conn[6];
elem_file << std::setw( 8 ) << conn[2] << std::setw( 8 ) << conn[3];
elem_file << std::setw( 8 ) << MATDefault << std::setw( 8 ) << ETSolid95;
elem_file << std::setw( 8 ) << "1" << std::setw( 8 ) << "1";
elem_file << std::setw( 8 ) << "0" << std::setw( 8 ) << elem_id;
elem_file << std::endl;
elem_file << std::setw( 8 ) << conn[16] << std::setw( 8 ) << conn[13];
elem_file << std::setw( 8 ) << conn[8] << std::setw( 8 ) << conn[12];
elem_file << std::setw( 8 ) << conn[18] << std::setw( 8 ) << conn[14];
elem_file << std::setw( 8 ) << conn[10] << std::setw( 8 ) << conn[15];
elem_file << std::setw( 8 ) << conn[19] << std::setw( 8 ) << conn[17];
elem_file << std::setw( 8 ) << conn[9] << std::setw( 8 ) << conn[11];
elem_file << std::endl;
}
}
// Write all MBPRISM elements
Range prism_range;
result = mbImpl->get_entities_by_type( output_set, MBPRISM, prism_range, true );
if( result != MB_SUCCESS ) return result;
for( Range::iterator elem_it = prism_range.begin(); elem_it != prism_range.end(); ++elem_it )
{
EntityHandle elem_handle = *elem_it;
int elem_id = mbImpl->id_from_handle( elem_handle );
std::vector< EntityHandle > conn;
result = mbImpl->get_connectivity( &elem_handle, 1, conn, false );
if( result != MB_SUCCESS ) return result;
// make sure supported prism type
if( conn.size() != 6 )
{
std::cout << "Support not added for element type. \n";
return MB_FAILURE;
}
// write information for 6 node prism
if( conn.size() == 6 )
{
elem_file << std::setw( 8 ) << conn[0] << std::setw( 8 ) << conn[3];
elem_file << std::setw( 8 ) << conn[4] << std::setw( 8 ) << conn[4];
elem_file << std::setw( 8 ) << conn[1] << std::setw( 8 ) << conn[2];
elem_file << std::setw( 8 ) << conn[5] << std::setw( 8 ) << conn[5];
elem_file << std::setw( 8 ) << MATDefault << std::setw( 8 ) << ETSolid45;
elem_file << std::setw( 8 ) << "1" << std::setw( 8 ) << "1";
elem_file << std::setw( 8 ) << "0" << std::setw( 8 ) << elem_id;
elem_file << std::endl;
}
}
// create element types (for now writes all, even if not used)
ans_file << "et," << ETSolid45 << ",SOLID45" << std::endl;
ans_file << "et," << ETSolid92 << ",SOLID92" << std::endl;
ans_file << "et," << ETSolid95 << ",SOLID95" << std::endl;
// xxx pyramids, other elements later...
// write header to load elements
ans_file << "eread," << base_string << ",elem" << std::endl;
// search for all side sets (Neumann)
Range side_mesh_sets;
int ss_id;
result = mbImpl->get_entities_by_type_and_tag( 0, MBENTITYSET, &mNeumannSetTag, NULL, 1, side_mesh_sets );
if( result != MB_SUCCESS ) return result;
// cycle through all sets found
for( Range::iterator ss_it = side_mesh_sets.begin(); ss_it != side_mesh_sets.end(); ++ss_it )
{
result = mbImpl->tag_get_data( mNeumannSetTag, &( *ss_it ), 1, &ss_id );
if( result != MB_SUCCESS ) return result;
std::vector< EntityHandle > elem_vector;
result = mbImpl->get_entities_by_handle( *ss_it, elem_vector, true );
if( result != MB_SUCCESS ) return result;
// cycle through elements in current side set
for( std::vector< EntityHandle >::iterator elem_it = elem_vector.begin(); elem_it != elem_vector.end();
++elem_it )
{
EntityHandle elem_handle = *elem_it;
// instead of selecting current element in set, select its nodes...
std::vector< EntityHandle > conn;
result = mbImpl->get_connectivity( &elem_handle, 1, conn );
if( result != MB_SUCCESS ) return result;
if( elem_it == elem_vector.begin() )
{
ans_file << "nsel,s,node,," << std::setw( 8 ) << conn[0] << std::endl;
for( unsigned int i = 1; i < conn.size(); i++ )
{
ans_file << "nsel,a,node,," << std::setw( 8 ) << conn[i] << std::endl;
}
}
else
{
for( unsigned int i = 0; i < conn.size(); i++ )
{
ans_file << "nsel,a,node,," << std::setw( 8 ) << conn[i] << std::endl;
}
}
}
// create SS(#) node set
ans_file << "cm,SS" << ss_id << ",node" << std::endl;
}
// Gather all element blocks
Range matset;
int mat_id;
result = mbImpl->get_entities_by_type_and_tag( 0, MBENTITYSET, &mMaterialSetTag, NULL, 1, matset );
if( result != MB_SUCCESS ) return result;
// cycle through all elem blocks
for( Range::iterator mat_it = matset.begin(); mat_it != matset.end(); ++mat_it )
{
EntityHandle matset_handle = *mat_it;
result = mbImpl->tag_get_data( mMaterialSetTag, &matset_handle, 1, &mat_id );
if( result != MB_SUCCESS ) return result;
std::vector< EntityHandle > mat_vector;
result = mbImpl->get_entities_by_handle( *mat_it, mat_vector, true );
if( result != MB_SUCCESS ) return result;
// cycle through elements in current mat set
for( std::vector< EntityHandle >::iterator elem_it = mat_vector.begin(); elem_it != mat_vector.end();
++elem_it )
{
EntityHandle elem_handle = *elem_it;
int elem_id = mbImpl->id_from_handle( elem_handle );
if( elem_it == mat_vector.begin() )
{
ans_file << "esel,s,elem,," << std::setw( 8 ) << elem_id << std::endl;
}
else
{
ans_file << "esel,a,elem,," << std::setw( 8 ) << elem_id << std::endl;
}
}
// for each matset, write block command
ans_file << "cm,EB" << mat_id << ",elem" << std::endl;
}
// close all file streams
node_file.close();
elem_file.close();
ans_file.close();
return MB_SUCCESS;
}
ErrorCode moab::WriteAns::write_nodes | ( | const int | num_nodes, |
const Range & | nodes, | ||
const int | dimension, | ||
const char * | file_name | ||
) | [private] |
std::string moab::WriteAns::fileName [private] |
file name
Definition at line 137 of file WriteAns.hpp.
Interface* moab::WriteAns::mbImpl [private] |
Meshset Handle for the mesh that is currently being read.
Definition at line 140 of file WriteAns.hpp.
Tag moab::WriteAns::mDirichletSetTag [private] |
Definition at line 145 of file WriteAns.hpp.
Referenced by write_file(), and WriteAns().
Tag moab::WriteAns::mGlobalIdTag [private] |
Definition at line 147 of file WriteAns.hpp.
Tag moab::WriteAns::mMaterialSetTag [private] |
Cached tags for reading. Note that all these tags are defined when the core is initialized.
Definition at line 144 of file WriteAns.hpp.
Referenced by write_file(), and WriteAns().
Tag moab::WriteAns::mMatSetIdTag [private] |
Definition at line 148 of file WriteAns.hpp.
Tag moab::WriteAns::mNeumannSetTag [private] |
Definition at line 146 of file WriteAns.hpp.
Referenced by write_file(), and WriteAns().