Loading [MathJax]/extensions/tex2jax.js
Mesh Oriented datABase  (version 5.5.1)
An array-based unstructured mesh library
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
moab::WriteNCDF Class Reference

Output Exodus File for VERDE. More...

#include <WriteNCDF.hpp>

+ Inheritance diagram for moab::WriteNCDF:
+ Collaboration diagram for moab::WriteNCDF:

Classes

struct  ExodusMeshInfo
 contains the general information about a mesh More...
 

Public Member Functions

 WriteNCDF (Interface *impl)
 Constructor. More...
 
virtual ~WriteNCDF ()
 Destructor. More...
 
ErrorCode write_file (const char *exodus_file_name, const bool overwrite, const FileOptions &opts, const EntityHandle *output_list, const int num_sets, const std::vector< std::string > &qa_records, const Tag *=NULL, int=0, int user_dimension=3)
 writes out an ExoII file More...
 
- Public Member Functions inherited from moab::WriterIface
virtual ~WriterIface ()
 

Static Public Member Functions

static WriterIfacefactory (Interface *)
 

Protected Member Functions

ErrorCode open_file (const char *file_name)
 number of dimensions in this exo file More...
 

Private Member Functions

ErrorCode gather_mesh_information (ExodusMeshInfo &mesh_info, std::vector< MaterialSetData > &block_info, std::vector< NeumannSetData > &sideset_info, std::vector< DirichletSetData > &nodeset_info, std::vector< EntityHandle > &blocks, std::vector< EntityHandle > &sidesets, std::vector< EntityHandle > &nodesets)
 
ErrorCode write_header (ExodusMeshInfo &mesh_info, std::vector< MaterialSetData > &block_info, std::vector< NeumannSetData > &sideset_info, std::vector< DirichletSetData > &nodeset_info, const char *filename)
 
ErrorCode initialize_exodus_file (ExodusMeshInfo &mesh_info, std::vector< MaterialSetData > &block_data, std::vector< NeumannSetData > &sideset_data, std::vector< DirichletSetData > &nodeset_data, const char *title_string, bool write_maps=true, bool write_sideset_distribution_factors=true)
 
ErrorCode write_qa_string (const char *string, int record_number, int record_position)
 
ErrorCode write_qa_records (std::vector< std::string > &qa_record_list)
 
ErrorCode write_nodes (int num_nodes, Range &nodes, int dimension)
 
ErrorCode write_poly_faces (ExodusMeshInfo &mesh_info)
 
ErrorCode write_elementblocks (ExodusMeshInfo &mesh_info, std::vector< MaterialSetData > &block_data)
 
ErrorCode write_exodus_integer_variable (const char *variable_name, int *variable_array, int start_position, int number_values)
 
ErrorCode write_global_node_order_map (int num_nodes, Range &nodes)
 
ErrorCode write_global_element_order_map (int num_elements)
 
ErrorCode write_element_order_map (int num_elements)
 
ErrorCode write_BCs (std::vector< NeumannSetData > &sidesets, std::vector< DirichletSetData > &nodesets)
 
ErrorCode find_side_element_type (const int element_id, ExoIIElementType &type)
 
void reset_block (std::vector< MaterialSetData > &block_info)
 free up allocated Ranges More...
 
ErrorCode get_sideset_elems (EntityHandle sideset, int current_sense, Range &forward_elems, Range &reverse_elems)
 recursive function; given a meshset handle, get the entities and put them on the right list, then call recursively for any contained meshsets, first checking for sense reversals More...
 
ErrorCode get_valid_sides (Range &elems, ExodusMeshInfo &mesh_info, const int sense, NeumannSetData &sideset_data)
 

Static Private Member Functions

static void time_and_date (char *time_string, char *date_string)
 get the time and date in strings More...
 

Private Attributes

InterfacemdbImpl
 interface instance More...
 
WriteUtilIfacemWriteIface
 
std::string exodusFile
 file name More...
 
int ncFile
 
EntityHandle mCurrentMeshHandle
 Meshset Handle for the mesh that is currently being read. More...
 
Tag mMaterialSetTag
 Cached tags for reading. Note that all these tags are defined when the core is initialized. More...
 
Tag mDirichletSetTag
 
Tag mNeumannSetTag
 
Tag mHasMidNodesTag
 
Tag mGeomDimensionTag
 
Tag mDistFactorTag
 
Tag mGlobalIdTag
 
Tag mQaRecordTag
 
Tag mEntityMark
 
int repeat_face_blocks
 

Detailed Description

Output Exodus File for VERDE.

Definition at line 85 of file WriteNCDF.hpp.

Constructor & Destructor Documentation

◆ WriteNCDF()

moab::WriteNCDF::WriteNCDF ( Interface impl)

Constructor.

Get and cache predefined tag handles

Definition at line 102 of file WriteNCDF.cpp.

103  : mdbImpl( impl ), ncFile( 0 ), mCurrentMeshHandle( 0 ), mGeomDimensionTag( 0 ), repeat_face_blocks( 0 ) 104 { 105  assert( impl != NULL ); 106  107  impl->query_interface( mWriteIface ); 108  109  // Initialize in case tag_get_handle fails below 110  //! Get and cache predefined tag handles 111  int negone = -1; 112  impl->tag_get_handle( MATERIAL_SET_TAG_NAME, 1, MB_TYPE_INTEGER, mMaterialSetTag, MB_TAG_SPARSE | MB_TAG_CREAT, 113  &negone ); 114  115  impl->tag_get_handle( DIRICHLET_SET_TAG_NAME, 1, MB_TYPE_INTEGER, mDirichletSetTag, MB_TAG_SPARSE | MB_TAG_CREAT, 116  &negone ); 117  118  impl->tag_get_handle( NEUMANN_SET_TAG_NAME, 1, MB_TYPE_INTEGER, mNeumannSetTag, MB_TAG_SPARSE | MB_TAG_CREAT, 119  &negone ); 120  121  mGlobalIdTag = impl->globalId_tag(); 122  123  int dum_val_array[] = { -1, -1, -1, -1 }; 124  impl->tag_get_handle( HAS_MID_NODES_TAG_NAME, 4, MB_TYPE_INTEGER, mHasMidNodesTag, MB_TAG_SPARSE | MB_TAG_CREAT, 125  dum_val_array ); 126  127  impl->tag_get_handle( "distFactor", 0, MB_TYPE_DOUBLE, mDistFactorTag, 128  MB_TAG_SPARSE | MB_TAG_VARLEN | MB_TAG_CREAT ); 129  130  impl->tag_get_handle( "qaRecord", 0, MB_TYPE_OPAQUE, mQaRecordTag, MB_TAG_SPARSE | MB_TAG_VARLEN | MB_TAG_CREAT ); 131  132  impl->tag_get_handle( "WriteNCDF element mark", 1, MB_TYPE_BIT, mEntityMark, MB_TAG_CREAT ); 133 }

References DIRICHLET_SET_TAG_NAME, moab::Interface::globalId_tag(), HAS_MID_NODES_TAG_NAME, MATERIAL_SET_TAG_NAME, MB_TAG_CREAT, MB_TAG_SPARSE, MB_TAG_VARLEN, MB_TYPE_BIT, MB_TYPE_DOUBLE, MB_TYPE_INTEGER, MB_TYPE_OPAQUE, mDirichletSetTag, mDistFactorTag, mEntityMark, mGlobalIdTag, mHasMidNodesTag, mMaterialSetTag, mNeumannSetTag, mQaRecordTag, mWriteIface, NEUMANN_SET_TAG_NAME, moab::Interface::query_interface(), and moab::Interface::tag_get_handle().

Referenced by factory().

◆ ~WriteNCDF()

moab::WriteNCDF::~WriteNCDF ( )
virtual

Destructor.

Definition at line 135 of file WriteNCDF.cpp.

136 { 137  mdbImpl->release_interface( mWriteIface ); 138  139  mdbImpl->tag_delete( mEntityMark ); 140  141  if( 0 != ncFile ) ncFile = 0; 142 }

References mdbImpl, mEntityMark, mWriteIface, ncFile, moab::Interface::release_interface(), and moab::Interface::tag_delete().

Member Function Documentation

◆ factory()

WriterIface * moab::WriteNCDF::factory ( Interface iface)
static

Definition at line 97 of file WriteNCDF.cpp.

98 { 99  return new WriteNCDF( iface ); 100 }

References iface, and WriteNCDF().

Referenced by moab::ReaderWriterSet::ReaderWriterSet().

◆ find_side_element_type()

ErrorCode moab::WriteNCDF::find_side_element_type ( const int  element_id,
ExoIIElementType type 
)
private

◆ gather_mesh_information()

ErrorCode moab::WriteNCDF::gather_mesh_information ( ExodusMeshInfo mesh_info,
std::vector< MaterialSetData > &  block_info,
std::vector< NeumannSetData > &  sideset_info,
std::vector< DirichletSetData > &  nodeset_info,
std::vector< EntityHandle > &  blocks,
std::vector< EntityHandle > &  sidesets,
std::vector< EntityHandle > &  nodesets 
)
private

Definition at line 366 of file WriteNCDF.cpp.

373 { 374  ErrorCode rval; 375  std::vector< EntityHandle >::iterator vector_iter, end_vector_iter; 376  377  mesh_info.num_nodes = 0; 378  mesh_info.num_elements = 0; 379  mesh_info.num_elementblocks = 0; 380  mesh_info.num_polyhedra_blocks = 0; 381  382  int id = 0; 383  384  vector_iter = blocks.begin(); 385  end_vector_iter = blocks.end(); 386  387  std::vector< EntityHandle > parent_meshsets; 388  389  // Clean out the bits for the element mark 390  rval = mdbImpl->tag_delete( mEntityMark ); 391  if( MB_SUCCESS != rval ) return rval; 392  rval = mdbImpl->tag_get_handle( "WriteNCDF element mark", 1, MB_TYPE_BIT, mEntityMark, MB_TAG_CREAT ); 393  if( MB_SUCCESS != rval ) return rval; 394  395  int highest_dimension_of_element_blocks = 0; 396  397  for( vector_iter = blocks.begin(); vector_iter != blocks.end(); ++vector_iter ) 398  { 399  MaterialSetData block_data; 400  401  // For the purpose of qa records, get the parents of these blocks 402  if( mdbImpl->get_parent_meshsets( *vector_iter, parent_meshsets ) != MB_SUCCESS ) return MB_FAILURE; 403  404  // Get all Entity Handles in the mesh set 405  Range dummy_range; 406  rval = mdbImpl->get_entities_by_handle( *vector_iter, dummy_range, true ); 407  if( MB_SUCCESS != rval ) return rval; 408  409  // Skip empty blocks 410  if( dummy_range.empty() ) continue; 411  412  // Get the block's id 413  if( mdbImpl->tag_get_data( mMaterialSetTag, &( *vector_iter ), 1, &id ) != MB_SUCCESS ) 414  { 415  MB_SET_ERR( MB_FAILURE, "Couldn't get block id from a tag for an element block" ); 416  } 417  418  block_data.id = id; 419  block_data.number_attributes = 0; 420  421  // Wait a minute, we are doing some filtering here that doesn't make sense at this level CJS 422  423  // Find the dimension of the last entity in this range 424  int this_dim = CN::Dimension( TYPE_FROM_HANDLE( dummy_range.back() ) ); 425  if( this_dim > 3 ) 426  { 427  MB_SET_ERR( MB_TYPE_OUT_OF_RANGE, "Block " << id << " contains entity sets" ); 428  } 429  block_data.elements = dummy_range.subset_by_dimension( this_dim ); 430  431  // End of -- wait a minute, we are doing some filtering here that doesn't make sense at this 432  // level CJS 433  434  // Get the entity type for this block, verifying that it's the same for all elements 435  EntityType entity_type = TYPE_FROM_HANDLE( block_data.elements.front() ); 436  if( !block_data.elements.all_of_type( entity_type ) ) 437  { 438  MB_SET_ERR( MB_FAILURE, "Entities in block " << id << " not of common type" ); 439  } 440  441  int dimension = -1; 442  if( entity_type == MBQUAD || entity_type == MBTRI ) 443  dimension = 2; // Output shells by default 444  else if( entity_type == MBEDGE ) 445  dimension = 1; 446  else 447  dimension = CN::Dimension( entity_type ); 448  449  if( dimension > highest_dimension_of_element_blocks ) highest_dimension_of_element_blocks = dimension; 450  451  std::vector< EntityHandle > tmp_conn; 452  rval = mdbImpl->get_connectivity( &( block_data.elements.front() ), 1, tmp_conn ); 453  if( MB_SUCCESS != rval ) return rval; 454  block_data.element_type = ExoIIUtil::get_element_type_from_num_verts( tmp_conn.size(), entity_type, dimension ); 455  456  if( block_data.element_type == EXOII_MAX_ELEM_TYPE ) 457  { 458  MB_SET_ERR( MB_FAILURE, "Element type in block " << id << " didn't get set correctly" ); 459  } 460  461  if( block_data.element_type == EXOII_POLYGON ) 462  { 463  // get all poly connectivity 464  int numconn = 0; 465  for( Range::iterator eit = block_data.elements.begin(); eit != block_data.elements.end(); eit++ ) 466  { 467  EntityHandle polg = *eit; 468  int nnodes = 0; 469  const EntityHandle* conn = NULL; 470  rval = mdbImpl->get_connectivity( polg, conn, nnodes );MB_CHK_ERR( rval ); 471  numconn += nnodes; 472  } 473  block_data.number_nodes_per_element = numconn; 474  } 475  else 476  block_data.number_nodes_per_element = ExoIIUtil::VerticesPerElement[block_data.element_type]; 477  478  // Number of nodes for this block 479  block_data.number_elements = block_data.elements.size(); 480  481  // Total number of elements 482  mesh_info.num_elements += block_data.number_elements; 483  484  // Get the nodes for the elements 485  rval = mWriteIface->gather_nodes_from_elements( block_data.elements, mEntityMark, mesh_info.nodes ); 486  if( MB_SUCCESS != rval ) return rval; 487  488  // if polyhedra block 489  if( EXOII_POLYHEDRON == block_data.element_type ) 490  { 491  rval = mdbImpl->get_connectivity( block_data.elements, mesh_info.polyhedronFaces );MB_CHK_ERR( rval ); 492  mesh_info.num_polyhedra_blocks++; 493  } 494  495  if( !sidesets.empty() ) 496  { 497  // If there are sidesets, keep track of which elements are being written out 498  for( Range::iterator iter = block_data.elements.begin(); iter != block_data.elements.end(); ++iter ) 499  { 500  unsigned char bit = 0x1; 501  rval = mdbImpl->tag_set_data( mEntityMark, &( *iter ), 1, &bit ); 502  if( MB_SUCCESS != rval ) return rval; 503  } 504  } 505  506  block_info.push_back( block_data ); 507  508  const void* data = NULL; 509  int size = 0; 510  if( MB_SUCCESS == mdbImpl->tag_get_by_ptr( mQaRecordTag, &( *vector_iter ), 1, &data, &size ) && NULL != data ) 511  { 512  // There are qa records on this block - copy over to mesh qa records 513  const char* qa_rec = static_cast< const char* >( data ); 514  int start = 0; 515  int count = 0; 516  for( int i = 0; i < size; i++ ) 517  { 518  if( qa_rec[i] == '\0' ) 519  { 520  std::string qa_string( &qa_rec[start], i - start ); 521  mesh_info.qaRecords.push_back( qa_string ); 522  start = i + 1; 523  count++; 524  } 525  } 526  527  // Constrained to multiples of 4 qa records 528  if( count > 0 ) assert( count % 4 == 0 ); 529  } 530  } 531  532  mesh_info.num_elementblocks = block_info.size(); 533  534  for( std::vector< MaterialSetData >::iterator blit = block_info.begin(); blit != block_info.end(); blit++ ) 535  { 536  MaterialSetData& block = *blit; 537  if( block.element_type != EXOII_POLYHEDRON ) 538  { 539  mesh_info.polyhedronFaces = subtract( mesh_info.polyhedronFaces, block.elements ); 540  } 541  } 542  543  // If user hasn't entered dimension, we figure it out 544  if( mesh_info.num_dim == 0 ) 545  { 546  // Never want 1 or zero dimensions 547  if( highest_dimension_of_element_blocks < 2 ) 548  mesh_info.num_dim = 3; 549  else 550  mesh_info.num_dim = highest_dimension_of_element_blocks; 551  } 552  553  Range::iterator range_iter, end_range_iter; 554  range_iter = mesh_info.nodes.begin(); 555  end_range_iter = mesh_info.nodes.end(); 556  557  mesh_info.num_nodes = mesh_info.nodes.size(); 558  559  //------nodesets-------- 560  561  vector_iter = nodesets.begin(); 562  end_vector_iter = nodesets.end(); 563  564  for( ; vector_iter != end_vector_iter; ++vector_iter ) 565  { 566  DirichletSetData nodeset_data; 567  nodeset_data.id = 0; 568  nodeset_data.number_nodes = 0; 569  570  // Get the nodeset's id 571  if( mdbImpl->tag_get_data( mDirichletSetTag, &( *vector_iter ), 1, &id ) != MB_SUCCESS ) 572  { 573  MB_SET_ERR( MB_FAILURE, "Couldn't get id tag for nodeset " << id ); 574  } 575  576  nodeset_data.id = id; 577  578  std::vector< EntityHandle > node_vector; 579  // Get the nodes of the nodeset that are in mesh_info.nodes 580  if( mdbImpl->get_entities_by_handle( *vector_iter, node_vector, true ) != MB_SUCCESS ) 581  { 582  MB_SET_ERR( MB_FAILURE, "Couldn't get nodes in nodeset " << id ); 583  } 584  585  // Get the tag for distribution factors 586  const double* dist_factor_vector; 587  int dist_factor_size; 588  const void* ptr = 0; 589  590  int has_dist_factors = 0; 591  if( mdbImpl->tag_get_by_ptr( mDistFactorTag, &( *vector_iter ), 1, &ptr, &dist_factor_size ) == MB_SUCCESS && 592  dist_factor_size ) 593  has_dist_factors = 1; 594  dist_factor_size /= sizeof( double ); 595  dist_factor_vector = reinterpret_cast< const double* >( ptr ); 596  std::vector< EntityHandle >::iterator iter, end_iter; 597  iter = node_vector.begin(); 598  end_iter = node_vector.end(); 599  600  int j = 0; 601  unsigned char node_marked = 0; 602  ErrorCode result; 603  for( ; iter != end_iter; ++iter ) 604  { 605  if( TYPE_FROM_HANDLE( *iter ) != MBVERTEX ) continue; 606  result = mdbImpl->tag_get_data( mEntityMark, &( *iter ), 1, &node_marked );MB_CHK_SET_ERR( result, "Couldn't get mark data" ); 607  608  if( 0x1 == node_marked ) 609  { 610  nodeset_data.nodes.push_back( *iter ); 611  if( 0 != has_dist_factors ) 612  nodeset_data.node_dist_factors.push_back( dist_factor_vector[j] ); 613  else 614  nodeset_data.node_dist_factors.push_back( 1.0 ); 615  } 616  j++; 617  } 618  619  nodeset_data.number_nodes = nodeset_data.nodes.size(); 620  nodeset_info.push_back( nodeset_data ); 621  } 622  623  //------sidesets-------- 624  vector_iter = sidesets.begin(); 625  end_vector_iter = sidesets.end(); 626  627  for( ; vector_iter != end_vector_iter; ++vector_iter ) 628  { 629  NeumannSetData sideset_data; 630  631  // Get the sideset's id 632  if( mdbImpl->tag_get_data( mNeumannSetTag, &( *vector_iter ), 1, &id ) != MB_SUCCESS ) return MB_FAILURE; 633  634  sideset_data.id = id; 635  sideset_data.mesh_set_handle = *vector_iter; 636  637  // Get the sides in two lists, one forward the other reverse; starts with forward sense 638  // by convention 639  Range forward_elems, reverse_elems; 640  if( get_sideset_elems( *vector_iter, 0, forward_elems, reverse_elems ) == MB_FAILURE ) return MB_FAILURE; 641  642  ErrorCode result = get_valid_sides( forward_elems, mesh_info, 1, sideset_data );MB_CHK_SET_ERR( result, "Couldn't get valid sides data" ); 643  result = get_valid_sides( reverse_elems, mesh_info, -1, sideset_data );MB_CHK_SET_ERR( result, "Couldn't get valid sides data" ); 644  645  sideset_data.number_elements = sideset_data.elements.size(); 646  sideset_info.push_back( sideset_data ); 647  } 648  649  return MB_SUCCESS; 650 }

References moab::Range::all_of_type(), moab::Range::back(), moab::Range::begin(), moab::CN::Dimension(), moab::MaterialSetData::element_type, moab::MaterialSetData::elements, moab::NeumannSetData::elements, moab::Range::empty(), moab::Range::end(), ErrorCode, moab::EXOII_MAX_ELEM_TYPE, moab::EXOII_POLYGON, moab::EXOII_POLYHEDRON, moab::Range::front(), moab::WriteUtilIface::gather_nodes_from_elements(), moab::Interface::get_connectivity(), moab::ExoIIUtil::get_element_type_from_num_verts(), moab::Interface::get_entities_by_handle(), moab::Interface::get_parent_meshsets(), get_sideset_elems(), get_valid_sides(), moab::MaterialSetData::id, moab::DirichletSetData::id, moab::NeumannSetData::id, MB_CHK_ERR, MB_CHK_SET_ERR, MB_SET_ERR, MB_SUCCESS, MB_TAG_CREAT, MB_TYPE_BIT, MB_TYPE_OUT_OF_RANGE, MBEDGE, MBQUAD, MBTRI, MBVERTEX, mdbImpl, mDirichletSetTag, mDistFactorTag, mEntityMark, moab::NeumannSetData::mesh_set_handle, mMaterialSetTag, mNeumannSetTag, mQaRecordTag, mWriteIface, moab::DirichletSetData::node_dist_factors, moab::DirichletSetData::nodes, moab::WriteNCDF::ExodusMeshInfo::nodes, moab::WriteNCDF::ExodusMeshInfo::num_dim, moab::WriteNCDF::ExodusMeshInfo::num_elementblocks, moab::WriteNCDF::ExodusMeshInfo::num_elements, moab::WriteNCDF::ExodusMeshInfo::num_nodes, moab::WriteNCDF::ExodusMeshInfo::num_polyhedra_blocks, moab::MaterialSetData::number_attributes, moab::MaterialSetData::number_elements, moab::NeumannSetData::number_elements, moab::DirichletSetData::number_nodes, moab::MaterialSetData::number_nodes_per_element, moab::WriteNCDF::ExodusMeshInfo::polyhedronFaces, moab::WriteNCDF::ExodusMeshInfo::qaRecords, size, moab::Range::size(), moab::Range::subset_by_dimension(), moab::subtract(), moab::Interface::tag_delete(), moab::Interface::tag_get_by_ptr(), moab::Interface::tag_get_data(), moab::Interface::tag_get_handle(), moab::Interface::tag_set_data(), moab::TYPE_FROM_HANDLE(), and moab::ExoIIUtil::VerticesPerElement.

Referenced by write_file().

◆ get_sideset_elems()

ErrorCode moab::WriteNCDF::get_sideset_elems ( EntityHandle  sideset,
int  current_sense,
Range forward_elems,
Range reverse_elems 
)
private

recursive function; given a meshset handle, get the entities and put them on the right list, then call recursively for any contained meshsets, first checking for sense reversals

Definition at line 2287 of file WriteNCDF.cpp.

2291 { 2292  Range ss_elems, ss_meshsets; 2293  2294  // Get the sense tag; don't need to check return, might be an error if the tag 2295  // hasn't been created yet 2296  Tag sense_tag = 0; 2297  mdbImpl->tag_get_handle( "SENSE", 1, MB_TYPE_INTEGER, sense_tag ); 2298  2299  // Get the entities in this set 2300  ErrorCode result = mdbImpl->get_entities_by_handle( sideset, ss_elems, true ); 2301  if( MB_FAILURE == result ) return result; 2302  2303  // Now remove the meshsets into the ss_meshsets; first find the first meshset, 2304  Range::iterator range_iter = ss_elems.begin(); 2305  while( TYPE_FROM_HANDLE( *range_iter ) != MBENTITYSET && range_iter != ss_elems.end() ) 2306  ++range_iter; 2307  2308  // Then, if there are some, copy them into ss_meshsets and erase from ss_elems 2309  if( range_iter != ss_elems.end() ) 2310  { 2311  std::copy( range_iter, ss_elems.end(), range_inserter( ss_meshsets ) ); 2312  ss_elems.erase( range_iter, ss_elems.end() ); 2313  } 2314  2315  // OK, for the elements, check the sense of this set and copy into the right range 2316  // (if the sense is 0, copy into both ranges) 2317  2318  // Need to step forward on list until we reach the right dimension 2319  Range::iterator dum_it = ss_elems.end(); 2320  --dum_it; 2321  int target_dim = CN::Dimension( TYPE_FROM_HANDLE( *dum_it ) ); 2322  dum_it = ss_elems.begin(); 2323  while( target_dim != CN::Dimension( TYPE_FROM_HANDLE( *dum_it ) ) && dum_it != ss_elems.end() ) 2324  ++dum_it; 2325  2326  if( current_sense == 1 || current_sense == 0 ) std::copy( dum_it, ss_elems.end(), range_inserter( forward_elems ) ); 2327  if( current_sense == -1 || current_sense == 0 ) 2328  std::copy( dum_it, ss_elems.end(), range_inserter( reverse_elems ) ); 2329  2330  // Now loop over the contained meshsets, getting the sense of those and calling this 2331  // function recursively 2332  for( range_iter = ss_meshsets.begin(); range_iter != ss_meshsets.end(); ++range_iter ) 2333  { 2334  // First get the sense; if it's not there, by convention it's forward 2335  int this_sense; 2336  if( 0 == sense_tag || MB_FAILURE == mdbImpl->tag_get_data( sense_tag, &( *range_iter ), 1, &this_sense ) ) 2337  this_sense = 1; 2338  2339  // Now get all the entities on this meshset, with the proper (possibly reversed) sense 2340  get_sideset_elems( *range_iter, this_sense * current_sense, forward_elems, reverse_elems ); 2341  } 2342  2343  return result; 2344 }

References moab::Range::begin(), moab::CN::Dimension(), moab::Range::end(), moab::Range::erase(), ErrorCode, moab::Interface::get_entities_by_handle(), MB_TYPE_INTEGER, MBENTITYSET, mdbImpl, moab::Interface::tag_get_data(), moab::Interface::tag_get_handle(), and moab::TYPE_FROM_HANDLE().

Referenced by gather_mesh_information().

◆ get_valid_sides()

ErrorCode moab::WriteNCDF::get_valid_sides ( Range elems,
ExodusMeshInfo mesh_info,
const int  sense,
NeumannSetData sideset_data 
)
private

Definition at line 652 of file WriteNCDF.cpp.

656 { 657  // This is where we see if underlying element of side set element is included in output 658  659  // Get the sideset-based info for distribution factors 660  const double* dist_factor_vector = 0; 661  int dist_factor_size = 0; 662  663  // Initialize dist_fac_iter to get rid of compiler warning 664  const double* dist_fac_iter = 0; 665  const void* ptr = 0; 666  bool has_dist_factors = false; 667  if( mdbImpl->tag_get_by_ptr( mDistFactorTag, &( sideset_data.mesh_set_handle ), 1, &ptr, &dist_factor_size ) == 668  MB_SUCCESS && 669  dist_factor_size ) 670  { 671  has_dist_factors = true; 672  dist_factor_vector = reinterpret_cast< const double* >( ptr ); 673  dist_fac_iter = dist_factor_vector; 674  dist_factor_size /= sizeof( double ); 675  } 676  677  unsigned char element_marked = 0; 678  ErrorCode result; 679  for( Range::iterator iter = elems.begin(); iter != elems.end(); ++iter ) 680  { 681  // Should insert here if "side" is a quad/tri on a quad/tri mesh 682  result = mdbImpl->tag_get_data( mEntityMark, &( *iter ), 1, &element_marked );MB_CHK_SET_ERR( result, "Couldn't get mark data" ); 683  684  if( 0x1 == element_marked ) 685  { 686  sideset_data.elements.push_back( *iter ); 687  688  // TJT TODO: the sense should really be # edges + 1or2 689  sideset_data.side_numbers.push_back( ( sense == 1 ? 1 : 2 ) ); 690  } 691  else 692  { // Then "side" is probably a quad/tri on a hex/tet mesh 693  std::vector< EntityHandle > parents; 694  int dimension = CN::Dimension( TYPE_FROM_HANDLE( *iter ) ); 695  696  // Get the adjacent parent element of "side" 697  if( mdbImpl->get_adjacencies( &( *iter ), 1, dimension + 1, false, parents ) != MB_SUCCESS ) 698  { 699 #if 0 700  // This is not treated as an error, print warning messages for 701  // debugging only 702  fprintf(stderr, "[Warning]: Couldn't get adjacencies for sideset.\n"); 703 #endif 704  } 705  706  if( !parents.empty() ) 707  { 708  // Make sure the adjacent parent element will be output 709  for( unsigned int k = 0; k < parents.size(); k++ ) 710  { 711  result = mdbImpl->tag_get_data( mEntityMark, &( parents[k] ), 1, &element_marked );MB_CHK_SET_ERR( result, "Couldn't get mark data" ); 712  713  int side_no, this_sense, this_offset; 714  if( 0x1 == element_marked && 715  mdbImpl->side_number( parents[k], *iter, side_no, this_sense, this_offset ) == MB_SUCCESS && 716  this_sense == sense ) 717  { 718  sideset_data.elements.push_back( parents[k] ); 719  sideset_data.side_numbers.push_back( side_no + 1 ); 720  break; 721  } 722  } 723  } 724  else 725  { 726 #if 0 727  // This is not treated as an error, print warning messages for 728  // debugging only 729  fprintf(stderr, "[Warning]: No parent element exists for element in sideset %i\n", sideset_data.id); 730 #endif 731  } 732  } 733  734  if( sideset_data.elements.size() != 0 ) 735  { 736  // Distribution factors 737  int num_nodes = CN::VerticesPerEntity( TYPE_FROM_HANDLE( *iter ) ); 738  // put some dummy dist factors for polygons; why do we need them? 739  if( TYPE_FROM_HANDLE( *iter ) == MBPOLYGON ) num_nodes = 1; // dummy 740  if( has_dist_factors ) 741  { 742  std::copy( dist_fac_iter, dist_fac_iter + num_nodes, 743  std::back_inserter( sideset_data.ss_dist_factors ) ); 744  dist_fac_iter += num_nodes; 745  } 746  else 747  { 748  for( int j = 0; j < num_nodes; j++ ) 749  sideset_data.ss_dist_factors.push_back( 1.0 ); 750  } 751  } 752  } 753  754  return MB_SUCCESS; 755 }

References moab::Range::begin(), moab::CN::Dimension(), moab::NeumannSetData::elements, moab::Range::end(), ErrorCode, moab::Interface::get_adjacencies(), moab::NeumannSetData::id, MB_CHK_SET_ERR, MB_SUCCESS, MBPOLYGON, mdbImpl, mDistFactorTag, mEntityMark, moab::NeumannSetData::mesh_set_handle, moab::Interface::side_number(), moab::NeumannSetData::side_numbers, moab::NeumannSetData::ss_dist_factors, moab::Interface::tag_get_by_ptr(), moab::Interface::tag_get_data(), moab::TYPE_FROM_HANDLE(), and moab::CN::VerticesPerEntity().

Referenced by gather_mesh_information().

◆ initialize_exodus_file()

ErrorCode moab::WriteNCDF::initialize_exodus_file ( ExodusMeshInfo mesh_info,
std::vector< MaterialSetData > &  block_data,
std::vector< NeumannSetData > &  sideset_data,
std::vector< DirichletSetData > &  nodeset_data,
const char *  title_string,
bool  write_maps = true,
bool  write_sideset_distribution_factors = true 
)
private

Definition at line 1571 of file WriteNCDF.cpp.

1578 { 1579  // This routine takes the place of the exodusii routine ex_put_init, 1580  // and additionally pre-defines variables such as qa, element blocks, 1581  // sidesets and nodesets in a single pass. 1582  // 1583  // This is necessary because of the way exodusII works. Each time the 1584  // netcdf routine endef is called to take the file out of define mode, 1585  // the entire file is copied before the new information is added. 1586  // 1587  // With very large files, this is simply not workable. This routine takes 1588  // the definition portions of all applicable exodus routines and puts them 1589  // in a single definition, preventing repeated copying of the file. 1590  // 1591  // Most of the code is copied directly from the applicable exodus routine, 1592  // and thus this routine may not seem very consistent in usage or variable 1593  // naming, etc. 1594  1595  // Perform the initializations 1596  1597  int element_block_index; 1598  1599  // Inquire on defined string dimension and general dimension for qa 1600  1601  int dim_str, dim_four, dim_line, dim_time; 1602  if( nc_def_dim( ncFile, "len_string", ExoIIInterface::MAX_STR_LENGTH, &dim_str ) != NC_NOERR ) 1603  { 1604  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to get string length in file" ); 1605  } 1606  1607  if( nc_def_dim( ncFile, "len_line", ExoIIInterface::MAX_STR_LENGTH, &dim_line ) != NC_NOERR ) 1608  { 1609  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to get line length in file" ); 1610  } 1611  1612  if( nc_def_dim( ncFile, "four", 4, &dim_four ) != NC_NOERR ) 1613  { 1614  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to locate four in file" ); 1615  } 1616  1617  if( nc_def_dim( ncFile, "time_step", 1, &dim_time ) != NC_NOERR ) 1618  { 1619  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to locate time step in file" ); 1620  } 1621  // some whole_time dummy :( 1622  int dtime; 1623  if( NC_NOERR != nc_def_var( ncFile, "time_whole", NC_DOUBLE, 1, &dim_time, &dtime ) ) 1624  { 1625  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define time whole array" ); 1626  } 1627  1628  /* Put file into define mode */ 1629  1630  // It is possible that an NT filename using backslashes is in the title string 1631  // this can give fits to unix codes where the backslash is assumed to be an escape 1632  // sequence. For the exodus file, just flip the backslash to a slash to prevent 1633  // this problem 1634  1635  // Get a working copy of the title_string; 1636  1637  char working_title[80]; 1638  strncpy( working_title, title_string, 79 ); 1639  1640  int length = strlen( working_title ); 1641  for( int pos = 0; pos < length; pos++ ) 1642  { 1643  if( working_title[pos] == '\\' ) working_title[pos] = '/'; 1644  } 1645  1646  if( NC_NOERR != nc_put_att_text( ncFile, NC_GLOBAL, "title", length, working_title ) ) 1647  { 1648  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define title attribute" ); 1649  } 1650  1651  // Add other attributes while we're at it 1652  float dum_vers = 6.28F; 1653  if( NC_NOERR != nc_put_att_float( ncFile, NC_GLOBAL, "api_version", NC_FLOAT, 1, &dum_vers ) ) 1654  { 1655  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define api_version attribute" ); 1656  } 1657  dum_vers = 6.28F; 1658  if( NC_NOERR != nc_put_att_float( ncFile, NC_GLOBAL, "version", NC_FLOAT, 1, &dum_vers ) ) 1659  { 1660  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define version attribute" ); 1661  } 1662  int dum_siz = sizeof( double ); 1663  if( NC_NOERR != nc_put_att_int( ncFile, NC_GLOBAL, "floating_point_word_size", NC_INT, 1, &dum_siz ) ) 1664  { 1665  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define floating pt word size attribute" ); 1666  } 1667  1668  // Set up number of dimensions 1669  1670  int num_el_blk, num_elem, num_nodes, num_dim, num_fa_blk, num_faces; 1671  if( nc_def_dim( ncFile, "num_dim", (size_t)mesh_info.num_dim, &num_dim ) != NC_NOERR ) 1672  { 1673  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define number of dimensions" ); 1674  } 1675  1676  if( nc_def_dim( ncFile, "num_nodes", mesh_info.num_nodes, &num_nodes ) != NC_NOERR ) 1677  { 1678  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define number of nodes" ); 1679  } 1680  1681  int num_nod_per_fa; // it is needed for polyhedron only; need to compute it (connectivity of 1682  // faces of polyhedra) 1683  if( mesh_info.polyhedronFaces.size() > 0 ) 1684  if( nc_def_dim( ncFile, "num_faces", (int)mesh_info.polyhedronFaces.size(), &num_faces ) != NC_NOERR ) 1685  { 1686  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define number of nodes" ); 1687  } 1688  1689  if( nc_def_dim( ncFile, "num_elem", mesh_info.num_elements, &num_elem ) != NC_NOERR ) 1690  { 1691  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define number of elements" ); 1692  } 1693  1694  if( nc_def_dim( ncFile, "num_el_blk", mesh_info.num_elementblocks, &num_el_blk ) != NC_NOERR ) 1695  { 1696  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define number of element blocks" ); 1697  } 1698  1699  /* ...and some variables */ 1700  1701  /* Element block id status array */ 1702  int idstat = -1; 1703  if( NC_NOERR != nc_def_var( ncFile, "eb_status", NC_LONG, 1, &num_el_blk, &idstat ) ) 1704  { 1705  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define element block status array" ); 1706  } 1707  1708  /* Element block id array */ 1709  1710  int idarr = -1; 1711  if( NC_NOERR != nc_def_var( ncFile, "eb_prop1", NC_LONG, 1, &num_el_blk, &idarr ) ) 1712  { 1713  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define element block id array" ); 1714  } 1715  1716  /* store property name as attribute of property array variable */ 1717  if( NC_NOERR != nc_put_att_text( ncFile, idarr, "name", strlen( "ID" ), "ID" ) ) 1718  { 1719  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to store element block property name ID" ); 1720  } 1721  1722  // count how many are polyhedron blocks 1723  int num_fa_blocks = 0; //, num_polyh_blocks = 0; 1724  for( unsigned int i = 0; i < block_data.size(); i++ ) 1725  { 1726  MaterialSetData& block = block_data[i]; 1727  if( EXOII_POLYHEDRON == block.element_type ) 1728  { 1729  num_fa_blocks++; 1730  // num_polyh_blocks++; 1731  } 1732  } 1733  if( 0 == this->repeat_face_blocks && num_fa_blocks > 1 ) num_fa_blocks = 1; 1734  char wname[CHAR_STR_LEN]; 1735  1736  if( num_fa_blocks > 0 ) 1737  { 1738  /* face block id status array */ 1739  if( nc_def_dim( ncFile, "num_fa_blk", num_fa_blocks, &num_fa_blk ) != NC_NOERR ) 1740  { 1741  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define number of face blocks" ); 1742  } 1743  1744  int idstatf = -1; 1745  if( NC_NOERR != nc_def_var( ncFile, "fa_status", NC_LONG, 1, &num_fa_blk, &idstatf ) ) 1746  { 1747  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define face block status array" ); 1748  } 1749  1750  /* Element block id array */ 1751  1752  int idarrf = -1; 1753  if( NC_NOERR != nc_def_var( ncFile, "fa_prop1", NC_LONG, 1, &num_fa_blk, &idarrf ) ) 1754  { 1755  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define face block id array" ); 1756  } 1757  1758  /* store property name as attribute of property array variable */ 1759  if( NC_NOERR != nc_put_att_text( ncFile, idarrf, "name", strlen( "ID" ), "ID" ) ) 1760  { 1761  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to store face block property name ID" ); 1762  } 1763  // determine the number of num_nod_per_face 1764  /* 1765  num_fa_in_blk1 = 15 ; 1766  num_nod_per_fa1 = 58 ; 1767  1768  int fbconn1(num_nod_per_fa1) ; 1769  fbconn1:elem_type = "nsided" ; 1770  int fbepecnt1(num_fa_in_blk1) ; 1771  fbepecnt1:entity_type1 = "NODE" ; 1772  fbepecnt1:entity_type2 = "FACE" ; 1773  */ 1774  1775  int num_nodes_per_face = 0; 1776  1777  int dims[1]; // maybe 1 is enough here 1778  for( Range::iterator eit = mesh_info.polyhedronFaces.begin(); eit != mesh_info.polyhedronFaces.end(); eit++ ) 1779  { 1780  EntityHandle polyg = *eit; 1781  int nnodes = 0; 1782  const EntityHandle* conn = NULL; 1783  ErrorCode rval = mdbImpl->get_connectivity( polyg, conn, nnodes );MB_CHK_ERR( rval ); 1784  num_nodes_per_face += nnodes; 1785  } 1786  1787  // duplicate if needed; default is not duplicate 1788  for( int j = 1; j <= num_fa_blocks; j++ ) 1789  { 1790  INS_ID( wname, "num_nod_per_fa%d", j ); 1791  if( nc_def_dim( ncFile, wname, (size_t)num_nodes_per_face, &num_nod_per_fa ) != NC_NOERR ) 1792  { 1793  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define number of nodes for face block " ); 1794  } 1795  dims[0] = num_nod_per_fa; 1796  INS_ID( wname, "fbconn%d", j ); // first one, or more 1797  int fbconn; 1798  if( NC_NOERR != nc_def_var( ncFile, wname, NC_LONG, 1, dims, &fbconn ) ) 1799  { 1800  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to create connectivity array for face block " << 1 ); 1801  } 1802  std::string element_type_string( "nsided" ); 1803  if( NC_NOERR != nc_put_att_text( ncFile, fbconn, "elem_type", element_type_string.length(), 1804  element_type_string.c_str() ) ) 1805  { 1806  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to store element type nsided " ); 1807  } 1808  1809  INS_ID( wname, "num_fa_in_blk%d", j ); // first one, or more 1810  int num_fa_in_blk; 1811  if( nc_def_dim( ncFile, wname, (size_t)mesh_info.polyhedronFaces.size(), &num_fa_in_blk ) != NC_NOERR ) 1812  { 1813  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define number of nodes for face block " ); 1814  } 1815  1816  // fbepecnt 1817  INS_ID( wname, "fbepecnt%d", j ); // first one, or more 1818  int fbepecnt; 1819  dims[0] = num_fa_in_blk; 1820  if( NC_NOERR != nc_def_var( ncFile, wname, NC_LONG, 1, dims, &fbepecnt ) ) 1821  { 1822  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to create fbepecnt array for block " << 1 ); 1823  } 1824  std::string enttype1( "NODE" ); 1825  if( NC_NOERR != nc_put_att_text( ncFile, fbepecnt, "entity_type1", enttype1.length(), enttype1.c_str() ) ) 1826  { 1827  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to store entity type 1 " ); 1828  } 1829  std::string enttype2( "FACE" ); 1830  if( NC_NOERR != nc_put_att_text( ncFile, fbepecnt, "entity_type2", enttype2.length(), enttype2.c_str() ) ) 1831  { 1832  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to store entity type 2 " ); 1833  } 1834  } 1835  } 1836  1837  // Define element blocks 1838  1839  for( unsigned int i = 0; i < block_data.size(); i++ ) 1840  { 1841  MaterialSetData& block = block_data[i]; 1842  1843  element_block_index = i + 1; 1844  int num_el_in_blk = -1, num_att_in_blk = -1; 1845  int blk_attrib, connect; 1846  1847  /* Define number of elements in this block */ 1848  1849  INS_ID( wname, "num_el_in_blk%d", element_block_index ); 1850  if( nc_def_dim( ncFile, wname, (size_t)block.number_elements, &num_el_in_blk ) != NC_NOERR ) 1851  { 1852  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define number of elements/block for block " << i + 1 ); 1853  } 1854  1855  /* Define number of nodes per element for this block */ 1856  INS_ID( wname, "num_nod_per_el%d", element_block_index ); 1857  int num_nod_per_el = -1; 1858  if( EXOII_POLYHEDRON != block.element_type ) 1859  if( nc_def_dim( ncFile, wname, (size_t)block.number_nodes_per_element, &num_nod_per_el ) != NC_NOERR ) 1860  { 1861  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define number of nodes/element for block " << block.id ); 1862  } 1863  1864  /* Define element attribute array for this block */ 1865  int dims[3]; 1866  if( block.number_attributes > 0 ) 1867  { 1868  INS_ID( wname, "num_att_in_blk%d", element_block_index ); 1869  if( nc_def_dim( ncFile, wname, (size_t)block.number_attributes, &num_att_in_blk ) != NC_NOERR ) 1870  { 1871  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define number of attributes in block " << block.id ); 1872  } 1873  1874  INS_ID( wname, "attrib%d", element_block_index ); 1875  dims[0] = num_el_in_blk; 1876  dims[1] = num_att_in_blk; 1877  if( NC_NOERR != nc_def_var( ncFile, wname, NC_DOUBLE, 2, dims, &blk_attrib ) ) 1878  { 1879  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define attributes for element block " << block.id ); 1880  } 1881  } 1882  1883  /* Define element connectivity array for this block */ 1884  1885  if( EXOII_POLYGON != block.element_type && EXOII_POLYHEDRON != block.element_type ) 1886  { 1887  INS_ID( wname, "connect%d", element_block_index ); 1888  dims[0] = num_el_in_blk; 1889  dims[1] = num_nod_per_el; 1890  if( NC_NOERR != nc_def_var( ncFile, wname, NC_LONG, 2, dims, &connect ) ) 1891  { 1892  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to create connectivity array for block " << i + 1 ); 1893  } 1894  1895  /* Store element type as attribute of connectivity variable */ 1896  1897  std::string element_type_string( ExoIIUtil::ElementTypeNames[block.element_type] ); 1898  if( NC_NOERR != nc_put_att_text( ncFile, connect, "elem_type", element_type_string.length(), 1899  element_type_string.c_str() ) ) 1900  { 1901  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to store element type name " << (int)block.element_type ); 1902  } 1903  } 1904  else if( EXOII_POLYGON == block.element_type ) 1905  { 1906  INS_ID( wname, "connect%d", element_block_index ); 1907  // need to define num_nod_per_el as total number of nodes 1908  // ebepecnt1 as number of nodes per polygon 1909  /* 1910  * int connect1(num_nod_per_el1) ; 1911  connect1:elem_type = "nsided" ; 1912  int ebepecnt1(num_el_in_blk1) ; 1913  ebepecnt1:entity_type1 = "NODE" ; 1914  ebepecnt1:entity_type2 = "ELEM" ;*/ 1915  dims[0] = num_nod_per_el; 1916  if( NC_NOERR != nc_def_var( ncFile, wname, NC_LONG, 1, dims, &connect ) ) 1917  { 1918  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to create connectivity array for block " << i + 1 ); 1919  } 1920  std::string element_type_string( "nsided" ); 1921  if( NC_NOERR != nc_put_att_text( ncFile, connect, "elem_type", element_type_string.length(), 1922  element_type_string.c_str() ) ) 1923  { 1924  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to store element type name " << (int)block.element_type ); 1925  } 1926  INS_ID( wname, "ebepecnt%d", element_block_index ); 1927  int ebepecnt; 1928  dims[0] = num_el_in_blk; 1929  if( NC_NOERR != nc_def_var( ncFile, wname, NC_LONG, 1, dims, &ebepecnt ) ) 1930  { 1931  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to create ebepecnt array for block " << i + 1 ); 1932  } 1933  std::string etype1( "NODE" ); 1934  if( NC_NOERR != nc_put_att_text( ncFile, ebepecnt, "entity_type1", etype1.length(), etype1.c_str() ) ) 1935  { 1936  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to store entity type1 " << (int)block.element_type ); 1937  } 1938  std::string etype2( "ELEM" ); 1939  if( NC_NOERR != nc_put_att_text( ncFile, ebepecnt, "entity_type2", etype2.length(), etype2.c_str() ) ) 1940  { 1941  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to store entity type2 " << (int)block.element_type ); 1942  } 1943  } 1944  else if( EXOII_POLYHEDRON == block.element_type ) 1945  { 1946  // INS_ID(wname, "connect%d", element_block_index); 1947  /* 1948  testn face example: 3 polyh, 15 total faces, 2 shared; 15+2 = 17 1949  num_elem = 3 ; 1950  num_face = 15 ; // not needed? 1951  num_el_blk = 1 ; 1952  1953  num_el_in_blk1 = 3 ; 1954  num_fac_per_el1 = 17 ; 1955  1956  * num faces will be total face conn 1957  * num_faces_in_block will be number of faces (non repeated) 1958  * num_nodes_per_face will have total face connectivity 1959  */ 1960  int num_faces2 = 0; 1961  1962  for( Range::iterator eit = block.elements.begin(); eit != block.elements.end(); eit++ ) 1963  { 1964  EntityHandle polyh = *eit; 1965  int nfaces = 0; 1966  const EntityHandle* conn = NULL; 1967  ErrorCode rval = mdbImpl->get_connectivity( polyh, conn, nfaces );MB_CHK_ERR( rval ); 1968  num_faces2 += nfaces; 1969  } 1970  1971  int num_fac_per_el; 1972  1973  INS_ID( wname, "num_fac_per_el%d", element_block_index ); 1974  if( nc_def_dim( ncFile, wname, (size_t)num_faces2, &num_fac_per_el ) != NC_NOERR ) 1975  { 1976  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define number of faces per block " << block.id ); 1977  } 1978  1979  /* 1980  int facconn1(num_fac_per_el1) ; 1981  facconn1:elem_type = "NFACED" ; 1982  int ebepecnt1(num_el_in_blk1) ; 1983  ebepecnt1:entity_type1 = "FACE" ; 1984  ebepecnt1:entity_type2 = "ELEM" ; 1985  */ 1986  1987  // facconn 1988  INS_ID( wname, "facconn%d", element_block_index ); 1989  int facconn; 1990  dims[0] = num_fac_per_el; 1991  if( NC_NOERR != nc_def_var( ncFile, wname, NC_LONG, 1, dims, &facconn ) ) 1992  { 1993  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to create facconn array for block " << i + 1 ); 1994  } 1995  std::string etype( "NFACED" ); 1996  if( NC_NOERR != nc_put_att_text( ncFile, facconn, "elem_type", etype.length(), etype.c_str() ) ) 1997  { 1998  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to store elem type " << (int)block.element_type ); 1999  } 2000  2001  // ebepecnt 2002  INS_ID( wname, "ebepecnt%d", element_block_index ); 2003  int ebepecnt; 2004  dims[0] = num_el_in_blk; 2005  if( NC_NOERR != nc_def_var( ncFile, wname, NC_LONG, 1, dims, &ebepecnt ) ) 2006  { 2007  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to create ebepecnt array for block " << i + 1 ); 2008  } 2009  std::string etype1( "FACE" ); 2010  if( NC_NOERR != nc_put_att_text( ncFile, ebepecnt, "entity_type1", etype1.length(), etype1.c_str() ) ) 2011  { 2012  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to store entity type1 " << (int)block.element_type ); 2013  } 2014  std::string etype2( "ELEM" ); 2015  if( NC_NOERR != nc_put_att_text( ncFile, ebepecnt, "entity_type2", etype2.length(), etype2.c_str() ) ) 2016  { 2017  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to store entity type2 " << (int)block.element_type ); 2018  } 2019  2020  block.number_nodes_per_element = num_faces2; // connectivity for all polyhedra in block 2021  } 2022  } 2023  2024  /* Node set id array: */ 2025  2026  int non_empty_nss = 0; 2027  // Need to go through nodesets to compute # nodesets, some might be empty 2028  std::vector< DirichletSetData >::iterator ns_it; 2029  for( ns_it = nodeset_data.begin(); ns_it != nodeset_data.end(); ++ns_it ) 2030  { 2031  if( 0 != ( *ns_it ).number_nodes ) non_empty_nss++; 2032  } 2033  2034  int num_ns = -1; 2035  int ns_idstat = -1, ns_idarr = -1; 2036  if( non_empty_nss > 0 ) 2037  { 2038  if( nc_def_dim( ncFile, "num_node_sets", (size_t)( non_empty_nss ), &num_ns ) != NC_NOERR ) 2039  { 2040  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define number of node sets" ); 2041  } 2042  2043  /* Node set id status array: */ 2044  2045  if( NC_NOERR != nc_def_var( ncFile, "ns_status", NC_LONG, 1, &num_ns, &ns_idstat ) ) 2046  { 2047  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to create node sets status array" ); 2048  } 2049  2050  /* Node set id array: */ 2051  if( NC_NOERR != nc_def_var( ncFile, "ns_prop1", NC_LONG, 1, &num_ns, &ns_idarr ) ) 2052  { 2053  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to create node sets property array" ); 2054  } 2055  2056  /* Store property name as attribute of property array variable */ 2057  if( NC_NOERR != nc_put_att_text( ncFile, NC_GLOBAL, "name", strlen( "ID" ), "ID" ) ) 2058  { 2059  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to store node set property name ID" ); 2060  } 2061  2062  // Now, define the arrays needed for each node set 2063  2064  int index = 0; 2065  2066  for( unsigned i = 0; i < nodeset_data.size(); i++ ) 2067  { 2068  DirichletSetData node_set = nodeset_data[i]; 2069  2070  if( 0 == node_set.number_nodes ) 2071  { 2072  MB_SET_ERR_CONT( "WriteNCDF: empty nodeset " << node_set.id ); 2073  continue; 2074  } 2075  index++; 2076  2077  int num_nod_ns = -1; 2078  INS_ID( wname, "num_nod_ns%d", index ); 2079  if( nc_def_dim( ncFile, wname, (size_t)node_set.number_nodes, &num_nod_ns ) != NC_NOERR ) 2080  { 2081  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define number of nodes for set " << node_set.id ); 2082  } 2083  2084  /* Create variable array in which to store the node set node list */ 2085  int node_ns = -1; 2086  INS_ID( wname, "node_ns%d", index ); 2087  if( NC_NOERR != nc_def_var( ncFile, wname, NC_LONG, 1, &num_nod_ns, &node_ns ) ) 2088  { 2089  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to create node set " << node_set.id << " node list" ); 2090  } 2091  2092  // Create distribution factor array 2093  int fact_ns = -1; 2094  INS_ID( wname, "dist_fact_ns%d", index ); 2095  if( NC_NOERR != nc_def_var( ncFile, wname, NC_DOUBLE, 1, &num_nod_ns, &fact_ns ) ) 2096  { 2097  MB_SET_ERR( MB_FAILURE, 2098  "WriteNCDF: failed to create node set " << node_set.id << " distribution factor list" ); 2099  } 2100  } 2101  } 2102  2103  /* Side set id array: */ 2104  2105  long non_empty_ss = 0; 2106  // Need to go through nodesets to compute # nodesets, some might be empty 2107  std::vector< NeumannSetData >::iterator ss_it; 2108  for( ss_it = sideset_data.begin(); ss_it != sideset_data.end(); ++ss_it ) 2109  { 2110  if( 0 != ( *ss_it ).number_elements ) non_empty_ss++; 2111  } 2112  2113  if( non_empty_ss > 0 ) 2114  { 2115  int num_ss = -1; 2116  if( nc_def_dim( ncFile, "num_side_sets", non_empty_ss, &num_ss ) != NC_NOERR ) 2117  { 2118  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define number of side sets" ); 2119  } 2120  2121  /* Side set id status array: */ 2122  int ss_idstat = -1, ss_idarr = -1; 2123  if( NC_NOERR != nc_def_var( ncFile, "ss_status", NC_LONG, 1, &num_ss, &ss_idstat ) ) 2124  { 2125  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define side set status" ); 2126  } 2127  2128  /* Side set id array: */ 2129  if( NC_NOERR != nc_def_var( ncFile, "ss_prop1", NC_LONG, 1, &num_ss, &ss_idarr ) ) 2130  { 2131  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define side set property" ); 2132  } 2133  2134  /* Store property name as attribute of property array variable */ 2135  if( NC_NOERR != nc_put_att_text( ncFile, ss_idarr, "name", strlen( "ID" ), "ID" ) ) 2136  { 2137  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to store side set property name ID" ); 2138  } 2139  2140  // Now, define the arrays needed for each side set 2141  2142  int index = 0; 2143  for( unsigned int i = 0; i < sideset_data.size(); i++ ) 2144  { 2145  NeumannSetData side_set = sideset_data[i]; 2146  2147  // Don't define an empty set 2148  if( 0 == side_set.number_elements ) continue; 2149  2150  index++; 2151  2152  int num_side_ss = -1; 2153  int elem_ss = -1, side_ss = -1; 2154  INS_ID( wname, "num_side_ss%d", index ); 2155  if( nc_def_dim( ncFile, wname, (size_t)side_set.number_elements, &num_side_ss ) != NC_NOERR ) 2156  { 2157  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define number of sides in side set " << side_set.id ); 2158  } 2159  2160  INS_ID( wname, "elem_ss%d", index ); 2161  if( NC_NOERR != nc_def_var( ncFile, wname, NC_LONG, 1, &num_side_ss, &elem_ss ) ) 2162  { 2163  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to create element list for side set " 2164  << side_set.id ); /* Exit define mode and return */ 2165  } 2166  INS_ID( wname, "side_ss%d", index ); 2167  if( NC_NOERR != nc_def_var( ncFile, wname, NC_LONG, 1, &num_side_ss, &side_ss ) ) 2168  { 2169  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to create side list for side set " 2170  << side_set.id ); /* Exit define mode and return */ 2171  } 2172  2173  // sideset distribution factors 2174  int num_df_ss = -1; 2175  INS_ID( wname, "num_df_ss%d", index ); 2176  if( nc_def_dim( ncFile, wname, (size_t)side_set.ss_dist_factors.size(), &num_df_ss ) != NC_NOERR ) 2177  { 2178  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define number of dist factors in side set " 2179  << side_set.id ); /* Exit define mode and return */ 2180  } 2181  2182  /* Create variable array in which to store the side set distribution factors */ 2183  2184  int fact_ss = -1; 2185  INS_ID( wname, "dist_fact_ss%d", index ); 2186  if( NC_NOERR != nc_def_var( ncFile, wname, NC_LONG, 1, &num_df_ss, &fact_ss ) ) 2187  { 2188  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to create dist factors list for side set " 2189  << side_set.id ); /* Exit define mode and return */ 2190  } 2191  } 2192  } 2193  2194  /* Node coordinate arrays: */ 2195  2196  int coord, name_coord, dims[3]; 2197  dims[0] = num_dim; 2198  dims[1] = num_nodes; 2199  if( NC_NOERR != nc_def_var( ncFile, "coord", NC_DOUBLE, 2, dims, &coord ) ) 2200  { 2201  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define node coordinate array" ); 2202  } 2203  2204  /* Coordinate names array */ 2205  2206  dims[0] = num_dim; 2207  dims[1] = dim_str; 2208  if( NC_NOERR != nc_def_var( ncFile, "coor_names", NC_CHAR, 2, dims, &name_coord ) ) 2209  { 2210  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define coordinate name array" ); 2211  } 2212  2213  // Define genesis maps if required 2214  2215  if( write_maps ) 2216  { 2217  // Element map 2218  int elem_map = -1, elem_map2 = -1, node_map = -1; 2219  if( NC_NOERR != nc_def_var( ncFile, "elem_map", NC_LONG, 1, &num_elem, &elem_map ) ) 2220  { 2221  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to create element map array" ); /* Exit define mode and return */ 2222  } 2223  2224  // Create the element number map 2225  if( NC_NOERR != nc_def_var( ncFile, "elem_num_map", NC_LONG, 1, &num_elem, &elem_map2 ) ) 2226  { 2227  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to create element numbering map" ); /* Exit define mode 2228  and return */ 2229  } 2230  2231  // Create node number map 2232  if( NC_NOERR != nc_def_var( ncFile, "node_num_map", NC_LONG, 1, &num_nodes, &node_map ) ) 2233  { 2234  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to create node numbering map array" ); /* Exit define mode and 2235  return */ 2236  } 2237  } 2238  2239  // Define qa records to be used 2240  2241  int num_qa_rec = mesh_info.qaRecords.size() / 4; 2242  int num_qa = -1; 2243  2244  if( nc_def_dim( ncFile, "num_qa_rec", (long)num_qa_rec, &num_qa ) != NC_NOERR ) 2245  { 2246  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define qa record array size" ); 2247  } 2248  2249  // Define qa array 2250  int qa_title; 2251  dims[0] = num_qa; 2252  dims[1] = dim_four; 2253  dims[2] = dim_str; 2254  if( NC_NOERR != nc_def_var( ncFile, "qa_records", NC_CHAR, 3, dims, &qa_title ) ) 2255  { 2256  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define qa record array" ); 2257  } 2258  2259  // Take it out of define mode 2260  if( NC_NOERR != nc_enddef( ncFile ) ) 2261  { 2262  MB_SET_ERR( MB_FAILURE, "WriteNCDF: Trouble leaving define mode" ); 2263  } 2264  2265  return MB_SUCCESS; 2266 }

References moab::Range::begin(), CHAR_STR_LEN, moab::MaterialSetData::element_type, moab::MaterialSetData::elements, moab::ExoIIUtil::ElementTypeNames, moab::Range::end(), ErrorCode, moab::EXOII_POLYGON, moab::EXOII_POLYHEDRON, moab::Interface::get_connectivity(), moab::MaterialSetData::id, moab::DirichletSetData::id, moab::NeumannSetData::id, INS_ID, length(), moab::ExoIIInterface::MAX_STR_LENGTH, MB_CHK_ERR, MB_SET_ERR, MB_SET_ERR_CONT, MB_SUCCESS, mdbImpl, ncFile, moab::WriteNCDF::ExodusMeshInfo::num_dim, moab::WriteNCDF::ExodusMeshInfo::num_elementblocks, moab::WriteNCDF::ExodusMeshInfo::num_elements, moab::WriteNCDF::ExodusMeshInfo::num_nodes, moab::MaterialSetData::number_attributes, moab::MaterialSetData::number_elements, moab::NeumannSetData::number_elements, moab::DirichletSetData::number_nodes, moab::MaterialSetData::number_nodes_per_element, moab::WriteNCDF::ExodusMeshInfo::polyhedronFaces, moab::WriteNCDF::ExodusMeshInfo::qaRecords, repeat_face_blocks, moab::Range::size(), and moab::NeumannSetData::ss_dist_factors.

Referenced by write_header().

◆ open_file()

ErrorCode moab::WriteNCDF::open_file ( const char *  file_name)
protected

number of dimensions in this exo file

open an ExoII file for writing

Definition at line 2268 of file WriteNCDF.cpp.

2269 { 2270  // Not a valid filename 2271  if( strlen( (const char*)filename ) == 0 ) 2272  { 2273  MB_SET_ERR( MB_FAILURE, "Output Exodus filename not specified" ); 2274  } 2275  2276  int fail = nc_create( filename, NC_CLOBBER, &ncFile ); 2277  2278  // File couldn't be opened 2279  if( NC_NOERR != fail ) 2280  { 2281  MB_SET_ERR( MB_FAILURE, "Cannot open " << filename ); 2282  } 2283  2284  return MB_SUCCESS; 2285 }

References moab::fail(), MB_SET_ERR, MB_SUCCESS, and ncFile.

◆ reset_block()

void moab::WriteNCDF::reset_block ( std::vector< MaterialSetData > &  block_info)
private

free up allocated Ranges

Definition at line 144 of file WriteNCDF.cpp.

145 { 146  std::vector< MaterialSetData >::iterator iter; 147  148  for( iter = block_info.begin(); iter != block_info.end(); ++iter ) 149  { 150  iter->elements.clear(); 151  } 152 }

Referenced by write_file().

◆ time_and_date()

void moab::WriteNCDF::time_and_date ( char *  time_string,
char *  date_string 
)
staticprivate

get the time and date in strings

Definition at line 154 of file WriteNCDF.cpp.

155 { 156  struct tm* local_time; 157  time_t calendar_time; 158  159  calendar_time = time( NULL ); 160  local_time = localtime( &calendar_time ); 161  162  assert( NULL != time_string && NULL != date_string ); 163  164  strftime( time_string, TIME_STR_LEN, "%H:%M:%S", local_time ); 165  strftime( date_string, TIME_STR_LEN, "%m/%d/%Y", local_time ); 166  167  // Terminate with NULL character 168  time_string[10] = '\0'; 169  date_string[10] = '\0'; 170 }

References moab::TIME_STR_LEN.

Referenced by write_file(), and write_header().

◆ write_BCs()

ErrorCode moab::WriteNCDF::write_BCs ( std::vector< NeumannSetData > &  sidesets,
std::vector< DirichletSetData > &  nodesets 
)
private

Definition at line 1365 of file WriteNCDF.cpp.

1366 { 1367  unsigned int i, j; 1368  int id; 1369  int ns_index = -1; 1370  1371  for( std::vector< DirichletSetData >::iterator ns_it = nodesets.begin(); ns_it != nodesets.end(); ++ns_it ) 1372  { 1373  // Get number of nodes in set 1374  int number_nodes = ( *ns_it ).number_nodes; 1375  if( 0 == number_nodes ) continue; 1376  1377  // If we're here, we have a non-empty nodeset; increment the index 1378  ns_index++; 1379  1380  // Get the node set id 1381  id = ( *ns_it ).id; 1382  1383  // Build new array to old exodus ids 1384  int* exodus_id_array = new int[number_nodes]; 1385  double* dist_factor_array = new double[number_nodes]; 1386  1387  std::vector< EntityHandle >::iterator begin_iter, end_iter; 1388  std::vector< double >::iterator other_iter; 1389  begin_iter = ( *ns_it ).nodes.begin(); 1390  end_iter = ( *ns_it ).nodes.end(); 1391  other_iter = ( *ns_it ).node_dist_factors.begin(); 1392  1393  j = 0; 1394  int exodus_id; 1395  ErrorCode result; 1396  // Fill up node array and dist. factor array at the same time 1397  for( ; begin_iter != end_iter; ++begin_iter ) 1398  { 1399  result = mdbImpl->tag_get_data( mGlobalIdTag, &( *begin_iter ), 1, &exodus_id );MB_CHK_SET_ERR( result, "Problem getting id tag data" ); 1400  1401  exodus_id_array[j] = exodus_id; 1402  dist_factor_array[j] = *( other_iter ); 1403  ++other_iter; 1404  j++; 1405  } 1406  1407  // Write out the id for the nodeset 1408  1409  int num_values = 1; 1410  1411  result = write_exodus_integer_variable( "ns_prop1", &id, ns_index, num_values );MB_CHK_SET_ERR_RET_VAL( result, "Problem writing node set id " << id, MB_FAILURE ); 1412  1413  // Write out the nodeset status 1414  1415  int status = 1; 1416  if( !number_nodes ) status = 0; 1417  1418  result = write_exodus_integer_variable( "ns_status", &status, ns_index, num_values );MB_CHK_SET_ERR_RET_VAL( result, "Problem writing node set status", MB_FAILURE ); 1419  1420  // Write it out 1421  char wname[CHAR_STR_LEN]; 1422  int nc_var = -1; 1423  std::vector< int > dims; 1424  INS_ID( wname, "node_ns%d", ns_index + 1 ); 1425  GET_VAR( wname, nc_var, dims ); 1426  if( -1 == nc_var ) 1427  { 1428  MB_SET_ERR( MB_FAILURE, "Failed to get node_ns variable" ); 1429  } 1430  1431  size_t start = 0, count = number_nodes; 1432  int fail = nc_put_vara_int( ncFile, nc_var, &start, &count, exodus_id_array ); 1433  if( NC_NOERR != fail ) 1434  { 1435  MB_SET_ERR( MB_FAILURE, "Failed writing exodus id array" ); 1436  } 1437  1438  // Write out nodeset distribution factors 1439  INS_ID( wname, "dist_fact_ns%d", ns_index + 1 ); 1440  nc_var = -1; 1441  GET_VAR( wname, nc_var, dims ); 1442  if( -1 == nc_var ) 1443  { 1444  MB_SET_ERR( MB_FAILURE, "Failed to get dist_fact variable" ); 1445  } 1446  fail = nc_put_vara_double( ncFile, nc_var, &start, &count, dist_factor_array ); 1447  if( NC_NOERR != fail ) 1448  { 1449  MB_SET_ERR( MB_FAILURE, "Failed writing dist factor array" ); 1450  } 1451  1452  delete[] dist_factor_array; 1453  delete[] exodus_id_array; 1454  } 1455  1456  // Now do sidesets 1457  int ss_index = 0; // Index of sideset - not the same as 'i' because 1458  // only writing non-empty side sets 1459  for( i = 0; i < sidesets.size(); i++ ) 1460  { 1461  NeumannSetData sideset_data = sidesets[i]; 1462  1463  // Get the side set id 1464  int side_set_id = sideset_data.id; 1465  1466  // Get number of elements in set 1467  int number_elements = sideset_data.number_elements; 1468  if( 0 == number_elements ) continue; 1469  1470  // Build new array to old exodus ids 1471  int* output_element_ids = new int[number_elements]; 1472  int* output_element_side_numbers = new int[number_elements]; 1473  1474  std::vector< EntityHandle >::iterator begin_iter, end_iter; 1475  begin_iter = sideset_data.elements.begin(); 1476  end_iter = sideset_data.elements.end(); 1477  std::vector< int >::iterator side_iter = sideset_data.side_numbers.begin(); 1478  1479  // Get the tag handle 1480  j = 0; 1481  int exodus_id; 1482  1483  // For each "side" 1484  for( ; begin_iter != end_iter; ++begin_iter, ++side_iter ) 1485  { 1486  ErrorCode result = mdbImpl->tag_get_data( mGlobalIdTag, &( *begin_iter ), 1, &exodus_id );MB_CHK_SET_ERR( result, "Problem getting exodus id for sideset element " 1487  << (long unsigned int)ID_FROM_HANDLE( *begin_iter ) ); 1488  1489  output_element_ids[j] = exodus_id; 1490  output_element_side_numbers[j++] = *side_iter; 1491  } 1492  1493  if( 0 != number_elements ) 1494  { 1495  // Write out the id for the nodeset 1496  1497  int num_values = 1; 1498  1499  // ss_prop1[ss_index] = side_set_id 1500  ErrorCode result = write_exodus_integer_variable( "ss_prop1", &side_set_id, ss_index, num_values );MB_CHK_SET_ERR_RET_VAL( result, "Problem writing node set id " << id, MB_FAILURE ); 1501  1502  // FIXME : Something seems wrong here. The we are within a block 1503  // started with if (0 != number_elements), so this condition is always 1504  // false. This code seems to indicate that we want to write all 1505  // sidesets, not just empty ones. But the code both here and in 1506  // initialize_exodus_file() skip empty side sets. 1507  // - j.k. 2007-03-09 1508  int status = 1; 1509  if( 0 == number_elements ) status = 0; 1510  1511  // ss_status[ss_index] = status 1512  result = write_exodus_integer_variable( "ss_status", &status, ss_index, num_values );MB_CHK_SET_ERR_RET_VAL( result, "Problem writing side set status", MB_FAILURE ); 1513  1514  // Increment ss_index now because we want a) we need to 1515  // increment it somewhere within the if (0 != number_elements) 1516  // block and b) the above calls need a zero-based index 1517  // while the following use a one-based index. 1518  ++ss_index; 1519  1520  char wname[CHAR_STR_LEN]; 1521  int nc_var; 1522  std::vector< int > dims; 1523  INS_ID( wname, "elem_ss%d", ss_index ); 1524  GET_VAR( wname, nc_var, dims ); 1525  if( -1 == nc_var ) 1526  { 1527  MB_SET_ERR( MB_FAILURE, "Failed to get elem_ss variable" ); 1528  } 1529  size_t start = 0, count = number_elements; 1530  int fail = nc_put_vara_int( ncFile, nc_var, &start, &count, output_element_ids ); 1531  if( NC_NOERR != fail ) 1532  { 1533  MB_SET_ERR( MB_FAILURE, "Failed writing sideset element array" ); 1534  } 1535  1536  INS_ID( wname, "side_ss%d", ss_index ); 1537  nc_var = -1; 1538  GET_VAR( wname, nc_var, dims ); 1539  if( -1 == nc_var ) 1540  { 1541  MB_SET_ERR( MB_FAILURE, "Failed to get side_ss variable" ); 1542  } 1543  fail = nc_put_vara_int( ncFile, nc_var, &start, &count, output_element_side_numbers ); 1544  if( NC_NOERR != fail ) 1545  { 1546  MB_SET_ERR( MB_FAILURE, "Failed writing sideset side array" ); 1547  } 1548  1549  INS_ID( wname, "dist_fact_ss%d", ss_index ); 1550  nc_var = -1; 1551  GET_VAR( wname, nc_var, dims ); 1552  if( -1 == nc_var ) 1553  { 1554  MB_SET_ERR( MB_FAILURE, "Failed to get sideset dist factors variable" ); 1555  } 1556  count = sideset_data.ss_dist_factors.size(); 1557  fail = nc_put_vara_double( ncFile, nc_var, &start, &count, &( sideset_data.ss_dist_factors[0] ) ); 1558  if( NC_NOERR != fail ) 1559  { 1560  MB_SET_ERR( MB_FAILURE, "Failed writing sideset dist factors array" ); 1561  } 1562  } 1563  1564  delete[] output_element_ids; 1565  delete[] output_element_side_numbers; 1566  } 1567  1568  return MB_SUCCESS; 1569 }

References CHAR_STR_LEN, moab::NeumannSetData::elements, ErrorCode, moab::fail(), GET_VAR, moab::NeumannSetData::id, moab::ID_FROM_HANDLE(), INS_ID, MB_CHK_SET_ERR, MB_CHK_SET_ERR_RET_VAL, MB_SET_ERR, MB_SUCCESS, mdbImpl, mGlobalIdTag, ncFile, moab::NeumannSetData::number_elements, moab::NeumannSetData::side_numbers, moab::NeumannSetData::ss_dist_factors, moab::Interface::tag_get_data(), and write_exodus_integer_variable().

Referenced by write_file().

◆ write_element_order_map()

ErrorCode moab::WriteNCDF::write_element_order_map ( int  num_elements)
private

Definition at line 1291 of file WriteNCDF.cpp.

1292 { 1293  // Note: this routine bypasses the standard exodusII interface for efficiency! 1294  1295  // Element order map 1296  int* map = new int[num_elements]; 1297  1298  // For now, output a dummy map! 1299  1300  for( int i = 0; i < num_elements; i++ ) 1301  { 1302  map[i] = i + 1; 1303  } 1304  1305  // Output array and cleanup 1306  1307  int error = write_exodus_integer_variable( "elem_map", map, 0, num_elements ); 1308  1309  if( map ) delete[] map; 1310  1311  if( error < 0 ) 1312  { 1313  MB_SET_ERR( MB_FAILURE, "Failed writing element map" ); 1314  } 1315  1316  return MB_SUCCESS; 1317 }

References moab::error(), MB_SET_ERR, MB_SUCCESS, and write_exodus_integer_variable().

Referenced by write_file().

◆ write_elementblocks()

ErrorCode moab::WriteNCDF::write_elementblocks ( ExodusMeshInfo mesh_info,
std::vector< MaterialSetData > &  block_data 
)
private

Definition at line 1037 of file WriteNCDF.cpp.

1038 { 1039  unsigned int i; 1040  int block_index = 0; // Index into block list, may != 1 if there are inactive blocks 1041  int exodus_id = 1; 1042  1043  for( i = 0; i < block_data.size(); i++ ) 1044  { 1045  MaterialSetData& block = block_data[i]; 1046  1047  unsigned int num_nodes_per_elem = block.number_nodes_per_element; 1048  1049  // Write out the id for the block 1050  1051  int id = block.id; 1052  int num_values = 1; 1053  1054  if( write_exodus_integer_variable( "eb_prop1", &id, block_index, num_values ) != MB_SUCCESS ) 1055  { 1056  MB_SET_ERR_CONT( "Problem writing element block id " << id ); 1057  } 1058  1059  // Write out the block status 1060  1061  int status = 1; 1062  if( 0 == block.number_elements ) 1063  { 1064  MB_SET_ERR( MB_FAILURE, "No elements in block " << id ); 1065  } 1066  1067  if( write_exodus_integer_variable( "eb_status", &status, block_index, num_values ) != MB_SUCCESS ) 1068  { 1069  MB_SET_ERR( MB_FAILURE, "Problem writing element block status" ); 1070  } 1071  1072  // 1073  // Map the connectivity to the new nodes 1074  const unsigned int num_elem = block.number_elements; 1075  unsigned int num_nodes = num_nodes_per_elem * num_elem; 1076  if( EXOII_POLYGON == block.element_type || EXOII_POLYHEDRON == block.element_type ) 1077  { 1078  num_nodes = num_nodes_per_elem; 1079  } 1080  int* connectivity = new int[num_nodes]; 1081  1082  ErrorCode result = MB_SUCCESS; 1083  if( block.element_type != EXOII_POLYHEDRON ) 1084  mWriteIface->get_element_connect( num_elem, num_nodes_per_elem, mGlobalIdTag, block.elements, mGlobalIdTag, 1085  exodus_id, connectivity ); 1086  if( result != MB_SUCCESS ) 1087  { 1088  delete[] connectivity; 1089  MB_SET_ERR( result, "Couldn't get element array to write from" ); 1090  } 1091  1092  // If necessary, convert from EXODUS to CN node order 1093  const EntityType elem_type = ExoIIUtil::ExoIIElementMBEntity[block.element_type]; 1094  assert( block.elements.all_of_type( elem_type ) ); 1095  const int* reorder = 0; 1096  if( block.element_type != EXOII_POLYHEDRON && block.element_type != EXOII_POLYGON ) 1097  reorder = exodus_elem_order_map[elem_type][block.number_nodes_per_element]; 1098  if( reorder ) 1099  WriteUtilIface::reorder( reorder, connectivity, block.number_elements, block.number_nodes_per_element ); 1100  1101  char wname[CHAR_STR_LEN]; 1102  int nc_var = -1; 1103  std::vector< int > dims; 1104  if( block.element_type != EXOII_POLYHEDRON ) 1105  { 1106  exodus_id += num_elem; 1107  INS_ID( wname, "connect%u", i + 1 ); 1108  1109  GET_VAR( wname, nc_var, dims ); 1110  if( -1 == nc_var ) 1111  { 1112  delete[] connectivity; 1113  MB_SET_ERR( MB_FAILURE, "Couldn't get connectivity variable" ); 1114  } 1115  } 1116  1117  if( EXOII_POLYGON == block.element_type ) 1118  { 1119  size_t start[1] = { 0 }, count[1] = { num_nodes_per_elem }; 1120  int fail = nc_put_vara_int( ncFile, nc_var, start, count, connectivity ); 1121  if( NC_NOERR != fail ) 1122  { 1123  delete[] connectivity; 1124  MB_SET_ERR( MB_FAILURE, "Couldn't write connectivity variable" ); 1125  } 1126  // now put also number ebepecnt1 1127  INS_ID( wname, "ebepecnt%u", i + 1 ); 1128  GET_VAR( wname, nc_var, dims ); 1129  count[0] = block.number_elements; 1130  start[0] = 0; 1131  // reuse connectivity array, to not allocate another one 1132  int j = 0; 1133  for( Range::iterator eit = block.elements.begin(); eit != block.elements.end(); j++, eit++ ) 1134  { 1135  EntityHandle polg = *eit; 1136  int nnodes = 0; 1137  const EntityHandle* conn = NULL; 1138  ErrorCode rval = mdbImpl->get_connectivity( polg, conn, nnodes );MB_CHK_ERR( rval ); 1139  connectivity[j] = nnodes; 1140  } 1141  fail = nc_put_vara_int( ncFile, nc_var, start, count, connectivity ); 1142  if( NC_NOERR != fail ) 1143  { 1144  delete[] connectivity; 1145  MB_SET_ERR( MB_FAILURE, "Couldn't write ebepecnt variable" ); 1146  } 1147  } 1148  else if( block.element_type != EXOII_POLYHEDRON ) 1149  { 1150  size_t start[2] = { 0, 0 }, count[2] = { num_elem, num_nodes_per_elem }; 1151  int fail = nc_put_vara_int( ncFile, nc_var, start, count, connectivity ); 1152  if( NC_NOERR != fail ) 1153  { 1154  delete[] connectivity; 1155  MB_SET_ERR( MB_FAILURE, "Couldn't write connectivity variable" ); 1156  } 1157  } 1158  else // if (block.element_type == EXOII_POLYHEDRON) 1159  { 1160  /* write a lot of stuff // faconn 1161  num_fa_in_blk1 = 15 ; 1162  num_nod_per_fa1 = 58 ; 1163  num_el_in_blk1 = 3 ; 1164  num_fac_per_el1 = 17 ; 1165  int fbconn1(num_nod_per_fa1) ; 1166  fbconn1:elem_type = "nsided" ; 1167  int fbepecnt1(num_fa_in_blk1) ; 1168  fbepecnt1:entity_type1 = "NODE" ; 1169  fbepecnt1:entity_type2 = "FACE" ; 1170  int facconn1(num_fac_per_el1) ; 1171  facconn1:elem_type = "NFACED" ; 1172  int ebepecnt1(num_el_in_blk1) ; 1173  ebepecnt1:entity_type1 = "FACE" ; 1174  ebepecnt1:entity_type2 = "ELEM" ; 1175  1176  */ 1177  Range& block_faces = mesh_info.polyhedronFaces; 1178  // ErrorCode rval = mdbImpl->get_connectivity(block.elements, block_faces); 1179  // MB_CHK_ERR(rval); 1180  1181  // reuse now connectivity for facconn1 1182  INS_ID( wname, "facconn%u", i + 1 ); 1183  GET_VAR( wname, nc_var, dims ); // fbconn# variable, 1 dimensional 1184  1185  std::vector< int > ebepe( block.elements.size() ); // ebepecnt1 1186  int ixcon = 0, j = 0; 1187  size_t start[1] = { 0 }, count[1] = { 0 }; 1188  1189  for( Range::iterator eit = block.elements.begin(); eit != block.elements.end(); eit++ ) 1190  { 1191  EntityHandle polyh = *eit; 1192  int nfaces = 0; 1193  const EntityHandle* conn = NULL; 1194  ErrorCode rval = mdbImpl->get_connectivity( polyh, conn, nfaces );MB_CHK_ERR( rval ); 1195  for( int k = 0; k < nfaces; k++ ) 1196  { 1197  int index = block_faces.index( conn[k] ); 1198  if( index == -1 ) MB_SET_ERR( MB_FAILURE, "Couldn't find face in polyhedron" ); 1199  connectivity[ixcon++] = index + 1; 1200  } 1201  ebepe[j++] = nfaces; 1202  // num_faces+=nfaces; 1203  } 1204  count[0] = ixcon; // facconn1 1205  int fail = nc_put_vara_int( ncFile, nc_var, start, count, connectivity ); 1206  if( NC_NOERR != fail ) 1207  { 1208  delete[] connectivity; 1209  MB_SET_ERR( MB_FAILURE, "Couldn't write fbconn variable" ); 1210  } 1211  1212  INS_ID( wname, "ebepecnt%u", i + 1 ); 1213  GET_VAR( wname, nc_var, dims ); // ebepecnt# variable, 1 dimensional 1214  count[0] = block.elements.size(); 1215  1216  fail = nc_put_vara_int( ncFile, nc_var, start, count, &ebepe[0] ); 1217  if( NC_NOERR != fail ) 1218  { 1219  delete[] connectivity; 1220  MB_SET_ERR( MB_FAILURE, "Couldn't write fbepecnt variable" ); 1221  } 1222  } 1223  block_index++; 1224  delete[] connectivity; 1225  } 1226  1227  return MB_SUCCESS; 1228 }

References moab::Range::all_of_type(), moab::Range::begin(), CHAR_STR_LEN, moab::MaterialSetData::element_type, moab::MaterialSetData::elements, moab::Range::end(), ErrorCode, exodus_elem_order_map, moab::EXOII_POLYGON, moab::EXOII_POLYHEDRON, moab::ExoIIUtil::ExoIIElementMBEntity, moab::fail(), moab::Interface::get_connectivity(), moab::WriteUtilIface::get_element_connect(), GET_VAR, moab::MaterialSetData::id, moab::Range::index(), INS_ID, MB_CHK_ERR, MB_SET_ERR, MB_SET_ERR_CONT, MB_SUCCESS, mdbImpl, mGlobalIdTag, mWriteIface, ncFile, moab::MaterialSetData::number_elements, moab::MaterialSetData::number_nodes_per_element, moab::WriteNCDF::ExodusMeshInfo::polyhedronFaces, moab::WriteUtilIface::reorder(), moab::Range::size(), and write_exodus_integer_variable().

Referenced by write_file().

◆ write_exodus_integer_variable()

ErrorCode moab::WriteNCDF::write_exodus_integer_variable ( const char *  variable_name,
int *  variable_array,
int  start_position,
int  number_values 
)
private

Definition at line 1319 of file WriteNCDF.cpp.

1323 { 1324  // Note: this routine bypasses the standard exodusII interface for efficiency! 1325  1326  // Write directly to netcdf interface for efficiency 1327  1328  // Get the variable id of the element map 1329  int nc_var = -1; 1330  std::vector< int > dims; 1331  GET_VAR( variable_name, nc_var, dims ); 1332  if( -1 == nc_var ) 1333  { 1334  MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to locate variable " << variable_name << " in file" ); 1335  } 1336  // This contortion is necessary because netCDF is expecting nclongs; 1337  // fortunately it's necessary only when ints and nclongs aren't the same size 1338  1339  size_t start[1], count[1]; 1340  start[0] = start_position; 1341  count[0] = number_values; 1342  1343  int fail = NC_NOERR; 1344  if( sizeof( int ) == sizeof( long ) ) 1345  { 1346  fail = nc_put_vara_int( ncFile, nc_var, start, count, variable_array ); 1347  } 1348  else 1349  { 1350  long* lptr = new long[number_values]; 1351  for( int jj = 0; jj < number_values; jj++ ) 1352  lptr[jj] = variable_array[jj]; 1353  fail = nc_put_vara_long( ncFile, nc_var, start, count, lptr ); 1354  delete[] lptr; 1355  } 1356  1357  if( NC_NOERR != fail ) 1358  { 1359  MB_SET_ERR( MB_FAILURE, "Failed to store variable " << variable_name ); 1360  } 1361  1362  return MB_SUCCESS; 1363 }

References moab::fail(), GET_VAR, MB_SET_ERR, MB_SUCCESS, and ncFile.

Referenced by write_BCs(), write_element_order_map(), write_elementblocks(), write_global_element_order_map(), write_global_node_order_map(), and write_poly_faces().

◆ write_file()

ErrorCode moab::WriteNCDF::write_file ( const char *  exodus_file_name,
const bool  overwrite,
const FileOptions opts,
const EntityHandle output_list,
const int  num_sets,
const std::vector< std::string > &  qa_records,
const Tag = NULL,
int  = 0,
int  user_dimension = 3 
)
virtual

writes out an ExoII file

Implements moab::WriterIface.

Definition at line 172 of file WriteNCDF.cpp.

181 { 182  assert( 0 != mMaterialSetTag && 0 != mNeumannSetTag && 0 != mDirichletSetTag ); 183  184  if( user_dimension == 0 ) mdbImpl->get_dimension( user_dimension ); 185  186  if( opts.get_null_option( "REPEAT_FACE_BLOCKS" ) == MB_SUCCESS ) repeat_face_blocks = 1; 187  188  std::vector< EntityHandle > blocks, nodesets, sidesets, entities; 189  190  // Separate into blocks, nodesets, sidesets 191  192  if( num_sets == 0 ) 193  { 194  // Default to all defined block, nodeset and sideset-type sets 195  Range this_range; 196  mdbImpl->get_entities_by_type_and_tag( 0, MBENTITYSET, &mMaterialSetTag, NULL, 1, this_range ); 197  std::copy( this_range.begin(), this_range.end(), std::back_inserter( blocks ) ); 198  this_range.clear(); 199  mdbImpl->get_entities_by_type_and_tag( 0, MBENTITYSET, &mDirichletSetTag, NULL, 1, this_range ); 200  std::copy( this_range.begin(), this_range.end(), std::back_inserter( nodesets ) ); 201  this_range.clear(); 202  mdbImpl->get_entities_by_type_and_tag( 0, MBENTITYSET, &mNeumannSetTag, NULL, 1, this_range ); 203  std::copy( this_range.begin(), this_range.end(), std::back_inserter( sidesets ) ); 204  205  // If there is nothing to write, write everything as one block. 206  if( blocks.empty() && nodesets.empty() && sidesets.empty() ) 207  { 208  this_range.clear(); 209  for( int d = user_dimension; d > 0 && this_range.empty(); --d ) 210  mdbImpl->get_entities_by_dimension( 0, d, this_range, false ); 211  if( this_range.empty() ) return MB_FILE_WRITE_ERROR; 212  213  EntityHandle block_handle; 214  int block_id = 1; 215  mdbImpl->create_meshset( MESHSET_SET, block_handle ); 216  mdbImpl->tag_set_data( mMaterialSetTag, &block_handle, 1, &block_id ); 217  mdbImpl->add_entities( block_handle, this_range ); 218  blocks.push_back( block_handle ); 219  } 220  } 221  else 222  { 223  int dummy; 224  for( const EntityHandle* iter = ent_handles; iter < ent_handles + num_sets; ++iter ) 225  { 226  if( MB_SUCCESS == mdbImpl->tag_get_data( mMaterialSetTag, &( *iter ), 1, &dummy ) && -1 != dummy ) 227  blocks.push_back( *iter ); 228  else if( MB_SUCCESS == mdbImpl->tag_get_data( mDirichletSetTag, &( *iter ), 1, &dummy ) && -1 != dummy ) 229  nodesets.push_back( *iter ); 230  else if( MB_SUCCESS == mdbImpl->tag_get_data( mNeumannSetTag, &( *iter ), 1, &dummy ) && -1 != dummy ) 231  sidesets.push_back( *iter ); 232  } 233  } 234  235  // If there is nothing to write just return. 236  if( blocks.empty() && nodesets.empty() && sidesets.empty() ) return MB_FILE_WRITE_ERROR; 237  238  // Try to get mesh information 239  ExodusMeshInfo mesh_info; 240  241  std::vector< MaterialSetData > block_info; 242  std::vector< NeumannSetData > sideset_info; 243  std::vector< DirichletSetData > nodeset_info; 244  245  mesh_info.num_dim = user_dimension; 246  247  if( qa_records.empty() ) 248  { 249  // qa records are empty - initialize some MB-standard ones 250  mesh_info.qaRecords.push_back( "MB" ); 251  mesh_info.qaRecords.push_back( "0.99" ); 252  char string1[80], string2[80]; 253  time_and_date( string2, string1 ); 254  mesh_info.qaRecords.push_back( string2 ); 255  mesh_info.qaRecords.push_back( string1 ); 256  } 257  else 258  { 259  // Constrained to multiples of 4 qa records 260  assert( qa_records.size() % 4 == 0 ); 261  262  std::copy( qa_records.begin(), qa_records.end(), std::back_inserter( mesh_info.qaRecords ) ); 263  } 264  265  block_info.clear(); 266  if( gather_mesh_information( mesh_info, block_info, sideset_info, nodeset_info, blocks, sidesets, nodesets ) != 267  MB_SUCCESS ) 268  { 269  reset_block( block_info ); 270  return MB_FAILURE; 271  } 272  273  // Try to open the file after gather mesh info succeeds 274  int fail = nc_create( exodus_file_name, overwrite ? NC_CLOBBER : NC_NOCLOBBER, &ncFile ); 275  if( NC_NOERR != fail ) 276  { 277  reset_block( block_info ); 278  return MB_FAILURE; 279  } 280  281  if( write_header( mesh_info, block_info, sideset_info, nodeset_info, exodus_file_name ) != MB_SUCCESS ) 282  { 283  reset_block( block_info ); 284  return MB_FAILURE; 285  } 286  287  { 288  // write dummy time_whole 289  double timev = 0.0; // dummy, to make paraview happy 290  size_t start = 0, count = 1; 291  int nc_var; 292  std::vector< int > dims; 293  GET_VAR( "time_whole", nc_var, dims ); 294  fail = nc_put_vara_double( ncFile, nc_var, &start, &count, &timev ); 295  if( NC_NOERR != fail ) 296  { 297  MB_SET_ERR( MB_FAILURE, "Failed writing dist factor array" ); 298  } 299  } 300  301  if( write_nodes( mesh_info.num_nodes, mesh_info.nodes, mesh_info.num_dim ) != MB_SUCCESS ) 302  { 303  reset_block( block_info ); 304  return MB_FAILURE; 305  } 306  307  if( !mesh_info.polyhedronFaces.empty() ) 308  { 309  if( write_poly_faces( mesh_info ) != MB_SUCCESS ) 310  { 311  reset_block( block_info ); 312  return MB_FAILURE; 313  } 314  } 315  316  if( write_elementblocks( mesh_info, block_info ) ) 317  { 318  reset_block( block_info ); 319  return MB_FAILURE; 320  } 321  322  // Write the three maps 323  if( write_global_node_order_map( mesh_info.num_nodes, mesh_info.nodes ) != MB_SUCCESS ) 324  { 325  reset_block( block_info ); 326  return MB_FAILURE; 327  } 328  329  if( write_global_element_order_map( mesh_info.num_elements ) != MB_SUCCESS ) 330  { 331  reset_block( block_info ); 332  return MB_FAILURE; 333  } 334  335  if( write_element_order_map( mesh_info.num_elements ) != MB_SUCCESS ) 336  { 337  reset_block( block_info ); 338  return MB_FAILURE; 339  } 340  341  /* 342  if (write_elementmap(mesh_info) != MB_SUCCESS) 343  return MB_FAILURE; 344  */ 345  346  if( write_BCs( sideset_info, nodeset_info ) != MB_SUCCESS ) 347  { 348  reset_block( block_info ); 349  return MB_FAILURE; 350  } 351  352  if( write_qa_records( mesh_info.qaRecords ) != MB_SUCCESS ) return MB_FAILURE; 353  354  // Copy the qa records into the argument 355  // mesh_info.qaRecords.swap(qa_records); 356  // Close the file 357  fail = nc_close( ncFile ); 358  if( NC_NOERR != fail ) 359  { 360  MB_SET_ERR( MB_FAILURE, "Trouble closing file" ); 361  } 362  363  return MB_SUCCESS; 364 }

References moab::Interface::add_entities(), moab::Range::begin(), moab::Range::clear(), moab::Interface::create_meshset(), moab::Range::empty(), moab::Range::end(), entities, moab::fail(), gather_mesh_information(), moab::Interface::get_dimension(), moab::Interface::get_entities_by_dimension(), moab::Interface::get_entities_by_type_and_tag(), moab::FileOptions::get_null_option(), GET_VAR, MB_FILE_WRITE_ERROR, MB_SET_ERR, MB_SUCCESS, MBENTITYSET, mdbImpl, mDirichletSetTag, MESHSET_SET, mMaterialSetTag, mNeumannSetTag, ncFile, moab::WriteNCDF::ExodusMeshInfo::nodes, moab::WriteNCDF::ExodusMeshInfo::num_dim, moab::WriteNCDF::ExodusMeshInfo::num_elements, moab::WriteNCDF::ExodusMeshInfo::num_nodes, moab::WriteNCDF::ExodusMeshInfo::polyhedronFaces, moab::WriteNCDF::ExodusMeshInfo::qaRecords, repeat_face_blocks, reset_block(), moab::Interface::tag_get_data(), moab::Interface::tag_set_data(), time_and_date(), write_BCs(), write_element_order_map(), write_elementblocks(), write_global_element_order_map(), write_global_node_order_map(), write_header(), write_nodes(), write_poly_faces(), and write_qa_records().

◆ write_global_element_order_map()

ErrorCode moab::WriteNCDF::write_global_element_order_map ( int  num_elements)
private

Definition at line 1265 of file WriteNCDF.cpp.

1266 { 1267  // Allocate map array 1268  int* map = new int[num_elements]; 1269  1270  // Many Sandia codes assume this map is unique, and CUBIT does not currently 1271  // have unique ids for all elements. Therefore, to make sure nothing crashes, 1272  // insert a dummy map... 1273  1274  for( int i = 0; i < num_elements; i++ ) 1275  map[i] = i + 1; 1276  1277  // Output array and cleanup 1278  1279  int error = write_exodus_integer_variable( "elem_num_map", map, 0, num_elements ); 1280  1281  if( map ) delete[] map; 1282  1283  if( error < 0 ) 1284  { 1285  MB_SET_ERR( MB_FAILURE, "Failed writing global element order map" ); 1286  } 1287  1288  return MB_SUCCESS; 1289 }

References moab::error(), MB_SET_ERR, MB_SUCCESS, and write_exodus_integer_variable().

Referenced by write_file().

◆ write_global_node_order_map()

ErrorCode moab::WriteNCDF::write_global_node_order_map ( int  num_nodes,
Range nodes 
)
private

Definition at line 1230 of file WriteNCDF.cpp.

1231 { 1232  // Note: this routine bypasses the standard exodusII interface for efficiency! 1233  1234  // Node order map 1235  int* map = new int[num_nodes]; 1236  1237  // For now, output a dummy map! 1238  1239  Range::iterator range_iter, end_iter; 1240  range_iter = nodes.begin(); 1241  end_iter = nodes.end(); 1242  1243  int i = 0; 1244  1245  for( ; range_iter != end_iter; ++range_iter ) 1246  { 1247  // TODO -- do we really want to cast this to an int? 1248  map[i++] = (int)ID_FROM_HANDLE( *range_iter ); 1249  } 1250  1251  // Output array and cleanup 1252  1253  int error = write_exodus_integer_variable( "node_num_map", map, 0, num_nodes ); 1254  1255  if( map ) delete[] map; 1256  1257  if( error < 0 ) 1258  { 1259  MB_SET_ERR( MB_FAILURE, "Failed writing global node order map" ); 1260  } 1261  1262  return MB_SUCCESS; 1263 }

References moab::Range::begin(), moab::Range::end(), moab::error(), moab::ID_FROM_HANDLE(), MB_SET_ERR, MB_SUCCESS, and write_exodus_integer_variable().

Referenced by write_file().

◆ write_header()

ErrorCode moab::WriteNCDF::write_header ( ExodusMeshInfo mesh_info,
std::vector< MaterialSetData > &  block_info,
std::vector< NeumannSetData > &  sideset_info,
std::vector< DirichletSetData > &  nodeset_info,
const char *  filename 
)
private

Definition at line 1006 of file WriteNCDF.cpp.

1011 { 1012  // Get the date and time 1013  char time[TIME_STR_LEN]; 1014  char date[TIME_STR_LEN]; 1015  time_and_date( time, date ); 1016  1017  std::string title_string = "MOAB"; 1018  title_string.append( "(" ); 1019  title_string.append( filename ); 1020  title_string.append( "): " ); 1021  title_string.append( date ); 1022  title_string.append( ": " ); 1023  title_string.append( "time " ); 1024  1025  if( title_string.length() > ExoIIInterface::MAX_LINE_LENGTH ) 1026  title_string.resize( ExoIIInterface::MAX_LINE_LENGTH ); 1027  1028  // Initialize the exodus file 1029  1030  int result = initialize_exodus_file( mesh_info, block_info, sideset_info, nodeset_info, title_string.c_str() ); 1031  1032  if( result == MB_FAILURE ) return MB_FAILURE; 1033  1034  return MB_SUCCESS; 1035 }

References initialize_exodus_file(), moab::ExoIIInterface::MAX_LINE_LENGTH, MB_SUCCESS, time_and_date(), and moab::TIME_STR_LEN.

Referenced by write_file().

◆ write_nodes()

ErrorCode moab::WriteNCDF::write_nodes ( int  num_nodes,
Range nodes,
int  dimension 
)
private

Definition at line 801 of file WriteNCDF.cpp.

802 { 803  // Write coordinates names 804  int nc_var = -1; 805  std::vector< int > dims; 806  GET_VAR( "coor_names", nc_var, dims ); 807  if( -1 == nc_var ) 808  { 809  MB_SET_ERR( MB_FAILURE, "Trouble getting coordinate name variable" ); 810  } 811  812  size_t start[2] = { 0, 0 }, count[2] = { 1, ExoIIInterface::MAX_STR_LENGTH }; 813  char dum_str[ExoIIInterface::MAX_STR_LENGTH]; 814  strcpy( dum_str, "x" ); 815  int fail = nc_put_vara_text( ncFile, nc_var, start, count, dum_str ); 816  if( NC_NOERR != fail ) 817  { 818  MB_SET_ERR( MB_FAILURE, "Trouble adding x coordinate name; netcdf message: " << nc_strerror( fail ) ); 819  } 820  821  start[0] = 1; 822  strcpy( dum_str, "y" ); 823  fail = nc_put_vara_text( ncFile, nc_var, start, count, dum_str ); 824  if( NC_NOERR != fail ) 825  { 826  MB_SET_ERR( MB_FAILURE, "Trouble adding y coordinate name; netcdf message: " << nc_strerror( fail ) ); 827  } 828  829  start[0] = 2; 830  strcpy( dum_str, "z" ); 831  fail = nc_put_vara_text( ncFile, nc_var, start, count, dum_str ); 832  if( NC_NOERR != fail ) 833  { 834  MB_SET_ERR( MB_FAILURE, "Trouble adding z coordinate name; netcdf message: " << nc_strerror( fail ) ); 835  } 836  837  // See if should transform coordinates 838  ErrorCode result; 839  Tag trans_tag; 840  result = mdbImpl->tag_get_handle( MESH_TRANSFORM_TAG_NAME, 16, MB_TYPE_DOUBLE, trans_tag ); 841  bool transform_needed = true; 842  if( result == MB_TAG_NOT_FOUND ) transform_needed = false; 843  844  int num_coords_to_fill = transform_needed ? 3 : dimension; 845  846  std::vector< double* > coord_arrays( 3 ); 847  coord_arrays[0] = new double[num_nodes]; 848  coord_arrays[1] = new double[num_nodes]; 849  coord_arrays[2] = NULL; 850  851  if( num_coords_to_fill == 3 ) coord_arrays[2] = new double[num_nodes]; 852  853  result = mWriteIface->get_node_coords( dimension, num_nodes, nodes, mGlobalIdTag, 1, coord_arrays ); 854  if( result != MB_SUCCESS ) 855  { 856  delete[] coord_arrays[0]; 857  delete[] coord_arrays[1]; 858  if( coord_arrays[2] ) delete[] coord_arrays[2]; 859  return result; 860  } 861  862  if( transform_needed ) 863  { 864  double trans_matrix[16]; 865  const EntityHandle mesh = 0; 866  result = mdbImpl->tag_get_data( trans_tag, &mesh, 0, trans_matrix );MB_CHK_SET_ERR( result, "Couldn't get transform data" ); 867  868  for( int i = 0; i < num_nodes; i++ ) 869  { 870  double vec1[3]; 871  double vec2[3]; 872  873  vec2[0] = coord_arrays[0][i]; 874  vec2[1] = coord_arrays[1][i]; 875  vec2[2] = coord_arrays[2][i]; 876  877  for( int row = 0; row < 3; row++ ) 878  { 879  vec1[row] = 0.0; 880  for( int col = 0; col < 3; col++ ) 881  vec1[row] += ( trans_matrix[( row * 4 ) + col] * vec2[col] ); 882  } 883  884  coord_arrays[0][i] = vec1[0]; 885  coord_arrays[1][i] = vec1[1]; 886  coord_arrays[2][i] = vec1[2]; 887  } 888  } 889  890  // Write the nodes 891  nc_var = -1; 892  GET_VAR( "coord", nc_var, dims ); 893  if( -1 == nc_var ) 894  { 895  MB_SET_ERR( MB_FAILURE, "Trouble getting coordinate variable" ); 896  } 897  start[0] = 0; 898  count[1] = num_nodes; 899  fail = nc_put_vara_double( ncFile, nc_var, start, count, &( coord_arrays[0][0] ) ); 900  if( NC_NOERR != fail ) 901  { 902  MB_SET_ERR( MB_FAILURE, "Trouble writing x coordinate" ); 903  } 904  905  start[0] = 1; 906  fail = nc_put_vara_double( ncFile, nc_var, start, count, &( coord_arrays[1][0] ) ); 907  if( NC_NOERR != fail ) 908  { 909  MB_SET_ERR( MB_FAILURE, "Trouble writing y coordinate" ); 910  } 911  912  start[0] = 2; 913  fail = nc_put_vara_double( ncFile, nc_var, start, count, &( coord_arrays[2][0] ) ); 914  if( NC_NOERR != fail ) 915  { 916  MB_SET_ERR( MB_FAILURE, "Trouble writing z coordinate" ); 917  } 918  919  delete[] coord_arrays[0]; 920  delete[] coord_arrays[1]; 921  if( coord_arrays[2] ) delete[] coord_arrays[2]; 922  923  return MB_SUCCESS; 924 }

References ErrorCode, moab::fail(), moab::WriteUtilIface::get_node_coords(), GET_VAR, moab::ExoIIInterface::MAX_STR_LENGTH, MB_CHK_SET_ERR, MB_SET_ERR, MB_SUCCESS, MB_TAG_NOT_FOUND, MB_TYPE_DOUBLE, mdbImpl, MESH_TRANSFORM_TAG_NAME, mGlobalIdTag, mWriteIface, ncFile, moab::Interface::tag_get_data(), and moab::Interface::tag_get_handle().

Referenced by write_file().

◆ write_poly_faces()

ErrorCode moab::WriteNCDF::write_poly_faces ( ExodusMeshInfo mesh_info)
private

Definition at line 926 of file WriteNCDF.cpp.

927 { 928  // write all polygons that are not in another element block; 929  // usually they are nowhere else, but be sure, write in this block only ones that are not in the 930  // other blocks 931  Range pfaces = mesh_info.polyhedronFaces; 932  933  /* 934  * int fbconn1(num_nod_per_fa1) ; 935  fbconn1:elem_type = "nsided" ; 936  int fbepecnt1(num_fa_in_blk1) ; 937  fbepecnt1:entity_type1 = "NODE" ; 938  fbepecnt1:entity_type2 = "FACE" ; 939  */ 940  if( pfaces.empty() ) return MB_SUCCESS; 941  char wname[CHAR_STR_LEN]; 942  int nc_var = -1; 943  std::vector< int > dims; 944  945  // write one for each element block, to make paraview and visit happy 946  int num_faces_in_block = (int)pfaces.size(); 947  for( unsigned int bl = 0; bl < mesh_info.num_polyhedra_blocks; bl++ ) 948  { 949  INS_ID( wname, "fbconn%u", bl + 1 ); // it is the first block 950  GET_VAR( wname, nc_var, dims ); // fbconn# variable, 1 dimensional 951  952  INS_ID( wname, "num_nod_per_fa%u", bl + 1 ); 953  int ncdim, num_nod_per_face; 954  GET_DIM( ncdim, wname, num_nod_per_face ); 955  int* connectivity = new int[num_nod_per_face]; 956  int ixcon = 0, j = 0; 957  std::vector< int > fbepe( num_faces_in_block ); // fbepecnt1 958  for( Range::iterator eit = pfaces.begin(); eit != pfaces.end(); eit++ ) 959  { 960  EntityHandle polyg = *eit; 961  int nnodes = 0; 962  const EntityHandle* conn = NULL; 963  ErrorCode rval = mdbImpl->get_connectivity( polyg, conn, nnodes );MB_CHK_ERR( rval ); 964  for( int k = 0; k < nnodes; k++ ) 965  connectivity[ixcon++] = conn[k]; 966  fbepe[j++] = nnodes; 967  } 968  size_t start[1] = { 0 }, count[1] = { 0 }; 969  count[0] = ixcon; 970  int fail = nc_put_vara_int( ncFile, nc_var, start, count, connectivity ); 971  if( NC_NOERR != fail ) 972  { 973  delete[] connectivity; 974  MB_SET_ERR( MB_FAILURE, "Couldn't write fbconn variable" ); 975  } 976  977  INS_ID( wname, "fbepecnt%u", bl + 1 ); 978  GET_VAR( wname, nc_var, dims ); // fbconn# variable, 1 dimensional 979  count[0] = num_faces_in_block; 980  981  fail = nc_put_vara_int( ncFile, nc_var, start, count, &fbepe[0] ); 982  if( NC_NOERR != fail ) 983  { 984  delete[] connectivity; 985  MB_SET_ERR( MB_FAILURE, "Couldn't write fbepecnt variable" ); 986  } 987  988  int id = bl + 1; 989  if( write_exodus_integer_variable( "fa_prop1", &id, bl, 1 ) != MB_SUCCESS ) 990  { 991  MB_SET_ERR_CONT( "Problem writing element block id " << id ); 992  } 993  994  int status = 1; 995  if( write_exodus_integer_variable( "fa_status", &status, bl, 1 ) != MB_SUCCESS ) 996  { 997  MB_SET_ERR( MB_FAILURE, "Problem writing face block status" ); 998  } 999  1000  delete[] connectivity; 1001  if( 0 == repeat_face_blocks ) break; // do not repeat face blocks 1002  } 1003  1004  return MB_SUCCESS; 1005 }

References moab::Range::begin(), CHAR_STR_LEN, moab::Range::empty(), moab::Range::end(), ErrorCode, moab::fail(), moab::Interface::get_connectivity(), GET_DIM, GET_VAR, INS_ID, MB_CHK_ERR, MB_SET_ERR, MB_SET_ERR_CONT, MB_SUCCESS, mdbImpl, ncFile, moab::WriteNCDF::ExodusMeshInfo::num_polyhedra_blocks, moab::WriteNCDF::ExodusMeshInfo::polyhedronFaces, repeat_face_blocks, moab::Range::size(), and write_exodus_integer_variable().

Referenced by write_file().

◆ write_qa_records()

ErrorCode moab::WriteNCDF::write_qa_records ( std::vector< std::string > &  qa_record_list)
private

Definition at line 757 of file WriteNCDF.cpp.

758 { 759  int i = 0; 760  761  for( std::vector< std::string >::iterator string_it = qa_record_list.begin(); string_it != qa_record_list.end(); ) 762  { 763  for( int j = 0; j < 4; j++ ) 764  write_qa_string( ( *string_it++ ).c_str(), i, j ); 765  i++; 766  } 767  768  return MB_SUCCESS; 769 }

References MB_SUCCESS, and write_qa_string().

Referenced by write_file().

◆ write_qa_string()

ErrorCode moab::WriteNCDF::write_qa_string ( const char *  string,
int  record_number,
int  record_position 
)
private

Definition at line 771 of file WriteNCDF.cpp.

772 { 773  // Get the variable id in the exodus file 774  775  std::vector< int > dims; 776  int temp_var = -1; 777  GET_VAR( "qa_records", temp_var, dims ); 778  if( -1 == temp_var ) 779  { 780  MB_SET_ERR( MB_FAILURE, "WriteNCDF:: Problem getting qa record variable" ); 781  } 782  size_t count[3], start[3]; 783  784  // Write out the record 785  start[0] = record_number; 786  start[1] = record_position; 787  start[2] = 0; 788  789  count[0] = 1; 790  count[1] = 1; 791  count[2] = (long)strlen( string ) + 1; 792  int fail = nc_put_vara_text( ncFile, temp_var, start, count, string ); 793  if( NC_NOERR != fail ) 794  { 795  MB_SET_ERR( MB_FAILURE, "Failed to position qa string variable" ); 796  } 797  798  return MB_SUCCESS; 799 }

References moab::fail(), GET_VAR, MB_SET_ERR, MB_SUCCESS, and ncFile.

Referenced by write_qa_records().

Member Data Documentation

◆ exodusFile

std::string moab::WriteNCDF::exodusFile
private

file name

Definition at line 135 of file WriteNCDF.hpp.

◆ mCurrentMeshHandle

EntityHandle moab::WriteNCDF::mCurrentMeshHandle
private

Meshset Handle for the mesh that is currently being read.

Definition at line 139 of file WriteNCDF.hpp.

◆ mdbImpl

◆ mDirichletSetTag

Tag moab::WriteNCDF::mDirichletSetTag
private

Definition at line 144 of file WriteNCDF.hpp.

Referenced by gather_mesh_information(), write_file(), and WriteNCDF().

◆ mDistFactorTag

Tag moab::WriteNCDF::mDistFactorTag
private

Definition at line 148 of file WriteNCDF.hpp.

Referenced by gather_mesh_information(), get_valid_sides(), and WriteNCDF().

◆ mEntityMark

Tag moab::WriteNCDF::mEntityMark
private

Definition at line 152 of file WriteNCDF.hpp.

Referenced by gather_mesh_information(), get_valid_sides(), WriteNCDF(), and ~WriteNCDF().

◆ mGeomDimensionTag

Tag moab::WriteNCDF::mGeomDimensionTag
private

Definition at line 147 of file WriteNCDF.hpp.

◆ mGlobalIdTag

Tag moab::WriteNCDF::mGlobalIdTag
private

Definition at line 149 of file WriteNCDF.hpp.

Referenced by write_BCs(), write_elementblocks(), write_nodes(), and WriteNCDF().

◆ mHasMidNodesTag

Tag moab::WriteNCDF::mHasMidNodesTag
private

Definition at line 146 of file WriteNCDF.hpp.

Referenced by WriteNCDF().

◆ mMaterialSetTag

Tag moab::WriteNCDF::mMaterialSetTag
private

Cached tags for reading. Note that all these tags are defined when the core is initialized.

Definition at line 143 of file WriteNCDF.hpp.

Referenced by gather_mesh_information(), write_file(), and WriteNCDF().

◆ mNeumannSetTag

Tag moab::WriteNCDF::mNeumannSetTag
private

Definition at line 145 of file WriteNCDF.hpp.

Referenced by gather_mesh_information(), write_file(), and WriteNCDF().

◆ mQaRecordTag

Tag moab::WriteNCDF::mQaRecordTag
private

Definition at line 150 of file WriteNCDF.hpp.

Referenced by gather_mesh_information(), and WriteNCDF().

◆ mWriteIface

WriteUtilIface* moab::WriteNCDF::mWriteIface
private

◆ ncFile

◆ repeat_face_blocks

int moab::WriteNCDF::repeat_face_blocks
private

Definition at line 154 of file WriteNCDF.hpp.

Referenced by initialize_exodus_file(), write_file(), and write_poly_faces().


The documentation for this class was generated from the following files: