Mesh Oriented datABase  (version 5.5.0)
An array-based unstructured mesh library
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 100 of file WriteNCDF.cpp.

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

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 133 of file WriteNCDF.cpp.

134 {
136 
138 
139  if( 0 != ncFile ) ncFile = 0;
140 }

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 95 of file WriteNCDF.cpp.

96 {
97  return new WriteNCDF( iface );
98 }

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 364 of file WriteNCDF.cpp.

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

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 2285 of file WriteNCDF.cpp.

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

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 650 of file WriteNCDF.cpp.

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

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 1569 of file WriteNCDF.cpp.

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

References moab::Range::begin(), 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 2266 of file WriteNCDF.cpp.

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

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 142 of file WriteNCDF.cpp.

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

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 152 of file WriteNCDF.cpp.

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

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 1363 of file WriteNCDF.cpp.

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

References 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 1289 of file WriteNCDF.cpp.

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

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 1035 of file WriteNCDF.cpp.

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

References moab::Range::all_of_type(), moab::Range::begin(), 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 1317 of file WriteNCDF.cpp.

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

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 170 of file WriteNCDF.cpp.

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

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 1263 of file WriteNCDF.cpp.

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

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 1228 of file WriteNCDF.cpp.

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

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 1004 of file WriteNCDF.cpp.

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

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 799 of file WriteNCDF.cpp.

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

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 924 of file WriteNCDF.cpp.

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

References moab::Range::begin(), 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 755 of file WriteNCDF.cpp.

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

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 769 of file WriteNCDF.cpp.

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

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: