Output Exodus File for VERDE. More...
#include <WriteNCDF.hpp>
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... | |
![]() | |
virtual | ~WriterIface () |
Static Public Member Functions | |
static WriterIface * | factory (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 | |
Interface * | mdbImpl |
interface instance More... | |
WriteUtilIface * | mWriteIface |
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 |
Output Exodus File for VERDE.
Definition at line 85 of file WriteNCDF.hpp.
moab::WriteNCDF::WriteNCDF | ( | Interface * | impl | ) |
Constructor.
Get and cache predefined tag handles
Definition at line 102 of file WriteNCDF.cpp.
103 : mdbImpl( impl ), ncFile( 0 ), mCurrentMeshHandle( 0 ), mGeomDimensionTag( 0 ), repeat_face_blocks( 0 )
104 {
105 assert( impl != NULL );
106
107 impl->query_interface( mWriteIface );
108
109 // Initialize in case tag_get_handle fails below
110 //! Get and cache predefined tag handles
111 int negone = -1;
112 impl->tag_get_handle( MATERIAL_SET_TAG_NAME, 1, MB_TYPE_INTEGER, mMaterialSetTag, MB_TAG_SPARSE | MB_TAG_CREAT,
113 &negone );
114
115 impl->tag_get_handle( DIRICHLET_SET_TAG_NAME, 1, MB_TYPE_INTEGER, mDirichletSetTag, MB_TAG_SPARSE | MB_TAG_CREAT,
116 &negone );
117
118 impl->tag_get_handle( NEUMANN_SET_TAG_NAME, 1, MB_TYPE_INTEGER, mNeumannSetTag, MB_TAG_SPARSE | MB_TAG_CREAT,
119 &negone );
120
121 mGlobalIdTag = impl->globalId_tag();
122
123 int dum_val_array[] = { -1, -1, -1, -1 };
124 impl->tag_get_handle( HAS_MID_NODES_TAG_NAME, 4, MB_TYPE_INTEGER, mHasMidNodesTag, MB_TAG_SPARSE | MB_TAG_CREAT,
125 dum_val_array );
126
127 impl->tag_get_handle( "distFactor", 0, MB_TYPE_DOUBLE, mDistFactorTag,
128 MB_TAG_SPARSE | MB_TAG_VARLEN | MB_TAG_CREAT );
129
130 impl->tag_get_handle( "qaRecord", 0, MB_TYPE_OPAQUE, mQaRecordTag, MB_TAG_SPARSE | MB_TAG_VARLEN | MB_TAG_CREAT );
131
132 impl->tag_get_handle( "WriteNCDF element mark", 1, MB_TYPE_BIT, mEntityMark, MB_TAG_CREAT );
133 }
References DIRICHLET_SET_TAG_NAME, moab::Interface::globalId_tag(), HAS_MID_NODES_TAG_NAME, MATERIAL_SET_TAG_NAME, MB_TAG_CREAT, MB_TAG_SPARSE, MB_TAG_VARLEN, MB_TYPE_BIT, MB_TYPE_DOUBLE, MB_TYPE_INTEGER, MB_TYPE_OPAQUE, mDirichletSetTag, mDistFactorTag, mEntityMark, mGlobalIdTag, mHasMidNodesTag, mMaterialSetTag, mNeumannSetTag, mQaRecordTag, mWriteIface, NEUMANN_SET_TAG_NAME, moab::Interface::query_interface(), and moab::Interface::tag_get_handle().
Referenced by factory().
|
virtual |
Destructor.
Definition at line 135 of file WriteNCDF.cpp.
136 { 137 mdbImpl->release_interface( mWriteIface ); 138 139 mdbImpl->tag_delete( mEntityMark ); 140 141 if( 0 != ncFile ) ncFile = 0; 142 }
References mdbImpl, mEntityMark, mWriteIface, ncFile, moab::Interface::release_interface(), and moab::Interface::tag_delete().
|
static |
Definition at line 97 of file WriteNCDF.cpp.
98 {
99 return new WriteNCDF( iface );
100 }
References iface, and WriteNCDF().
Referenced by moab::ReaderWriterSet::ReaderWriterSet().
|
private |
|
private |
Definition at line 366 of file WriteNCDF.cpp.
373 {
374 ErrorCode rval;
375 std::vector< EntityHandle >::iterator vector_iter, end_vector_iter;
376
377 mesh_info.num_nodes = 0;
378 mesh_info.num_elements = 0;
379 mesh_info.num_elementblocks = 0;
380 mesh_info.num_polyhedra_blocks = 0;
381
382 int id = 0;
383
384 vector_iter = blocks.begin();
385 end_vector_iter = blocks.end();
386
387 std::vector< EntityHandle > parent_meshsets;
388
389 // Clean out the bits for the element mark
390 rval = mdbImpl->tag_delete( mEntityMark );
391 if( MB_SUCCESS != rval ) return rval;
392 rval = mdbImpl->tag_get_handle( "WriteNCDF element mark", 1, MB_TYPE_BIT, mEntityMark, MB_TAG_CREAT );
393 if( MB_SUCCESS != rval ) return rval;
394
395 int highest_dimension_of_element_blocks = 0;
396
397 for( vector_iter = blocks.begin(); vector_iter != blocks.end(); ++vector_iter )
398 {
399 MaterialSetData block_data;
400
401 // For the purpose of qa records, get the parents of these blocks
402 if( mdbImpl->get_parent_meshsets( *vector_iter, parent_meshsets ) != MB_SUCCESS ) return MB_FAILURE;
403
404 // Get all Entity Handles in the mesh set
405 Range dummy_range;
406 rval = mdbImpl->get_entities_by_handle( *vector_iter, dummy_range, true );
407 if( MB_SUCCESS != rval ) return rval;
408
409 // Skip empty blocks
410 if( dummy_range.empty() ) continue;
411
412 // Get the block's id
413 if( mdbImpl->tag_get_data( mMaterialSetTag, &( *vector_iter ), 1, &id ) != MB_SUCCESS )
414 {
415 MB_SET_ERR( MB_FAILURE, "Couldn't get block id from a tag for an element block" );
416 }
417
418 block_data.id = id;
419 block_data.number_attributes = 0;
420
421 // Wait a minute, we are doing some filtering here that doesn't make sense at this level CJS
422
423 // Find the dimension of the last entity in this range
424 int this_dim = CN::Dimension( TYPE_FROM_HANDLE( dummy_range.back() ) );
425 if( this_dim > 3 )
426 {
427 MB_SET_ERR( MB_TYPE_OUT_OF_RANGE, "Block " << id << " contains entity sets" );
428 }
429 block_data.elements = dummy_range.subset_by_dimension( this_dim );
430
431 // End of -- wait a minute, we are doing some filtering here that doesn't make sense at this
432 // level CJS
433
434 // Get the entity type for this block, verifying that it's the same for all elements
435 EntityType entity_type = TYPE_FROM_HANDLE( block_data.elements.front() );
436 if( !block_data.elements.all_of_type( entity_type ) )
437 {
438 MB_SET_ERR( MB_FAILURE, "Entities in block " << id << " not of common type" );
439 }
440
441 int dimension = -1;
442 if( entity_type == MBQUAD || entity_type == MBTRI )
443 dimension = 2; // Output shells by default
444 else if( entity_type == MBEDGE )
445 dimension = 1;
446 else
447 dimension = CN::Dimension( entity_type );
448
449 if( dimension > highest_dimension_of_element_blocks ) highest_dimension_of_element_blocks = dimension;
450
451 std::vector< EntityHandle > tmp_conn;
452 rval = mdbImpl->get_connectivity( &( block_data.elements.front() ), 1, tmp_conn );
453 if( MB_SUCCESS != rval ) return rval;
454 block_data.element_type = ExoIIUtil::get_element_type_from_num_verts( tmp_conn.size(), entity_type, dimension );
455
456 if( block_data.element_type == EXOII_MAX_ELEM_TYPE )
457 {
458 MB_SET_ERR( MB_FAILURE, "Element type in block " << id << " didn't get set correctly" );
459 }
460
461 if( block_data.element_type == EXOII_POLYGON )
462 {
463 // get all poly connectivity
464 int numconn = 0;
465 for( Range::iterator eit = block_data.elements.begin(); eit != block_data.elements.end(); eit++ )
466 {
467 EntityHandle polg = *eit;
468 int nnodes = 0;
469 const EntityHandle* conn = NULL;
470 rval = mdbImpl->get_connectivity( polg, conn, nnodes );MB_CHK_ERR( rval );
471 numconn += nnodes;
472 }
473 block_data.number_nodes_per_element = numconn;
474 }
475 else
476 block_data.number_nodes_per_element = ExoIIUtil::VerticesPerElement[block_data.element_type];
477
478 // Number of nodes for this block
479 block_data.number_elements = block_data.elements.size();
480
481 // Total number of elements
482 mesh_info.num_elements += block_data.number_elements;
483
484 // Get the nodes for the elements
485 rval = mWriteIface->gather_nodes_from_elements( block_data.elements, mEntityMark, mesh_info.nodes );
486 if( MB_SUCCESS != rval ) return rval;
487
488 // if polyhedra block
489 if( EXOII_POLYHEDRON == block_data.element_type )
490 {
491 rval = mdbImpl->get_connectivity( block_data.elements, mesh_info.polyhedronFaces );MB_CHK_ERR( rval );
492 mesh_info.num_polyhedra_blocks++;
493 }
494
495 if( !sidesets.empty() )
496 {
497 // If there are sidesets, keep track of which elements are being written out
498 for( Range::iterator iter = block_data.elements.begin(); iter != block_data.elements.end(); ++iter )
499 {
500 unsigned char bit = 0x1;
501 rval = mdbImpl->tag_set_data( mEntityMark, &( *iter ), 1, &bit );
502 if( MB_SUCCESS != rval ) return rval;
503 }
504 }
505
506 block_info.push_back( block_data );
507
508 const void* data = NULL;
509 int size = 0;
510 if( MB_SUCCESS == mdbImpl->tag_get_by_ptr( mQaRecordTag, &( *vector_iter ), 1, &data, &size ) && NULL != data )
511 {
512 // There are qa records on this block - copy over to mesh qa records
513 const char* qa_rec = static_cast< const char* >( data );
514 int start = 0;
515 int count = 0;
516 for( int i = 0; i < size; i++ )
517 {
518 if( qa_rec[i] == '\0' )
519 {
520 std::string qa_string( &qa_rec[start], i - start );
521 mesh_info.qaRecords.push_back( qa_string );
522 start = i + 1;
523 count++;
524 }
525 }
526
527 // Constrained to multiples of 4 qa records
528 if( count > 0 ) assert( count % 4 == 0 );
529 }
530 }
531
532 mesh_info.num_elementblocks = block_info.size();
533
534 for( std::vector< MaterialSetData >::iterator blit = block_info.begin(); blit != block_info.end(); blit++ )
535 {
536 MaterialSetData& block = *blit;
537 if( block.element_type != EXOII_POLYHEDRON )
538 {
539 mesh_info.polyhedronFaces = subtract( mesh_info.polyhedronFaces, block.elements );
540 }
541 }
542
543 // If user hasn't entered dimension, we figure it out
544 if( mesh_info.num_dim == 0 )
545 {
546 // Never want 1 or zero dimensions
547 if( highest_dimension_of_element_blocks < 2 )
548 mesh_info.num_dim = 3;
549 else
550 mesh_info.num_dim = highest_dimension_of_element_blocks;
551 }
552
553 Range::iterator range_iter, end_range_iter;
554 range_iter = mesh_info.nodes.begin();
555 end_range_iter = mesh_info.nodes.end();
556
557 mesh_info.num_nodes = mesh_info.nodes.size();
558
559 //------nodesets--------
560
561 vector_iter = nodesets.begin();
562 end_vector_iter = nodesets.end();
563
564 for( ; vector_iter != end_vector_iter; ++vector_iter )
565 {
566 DirichletSetData nodeset_data;
567 nodeset_data.id = 0;
568 nodeset_data.number_nodes = 0;
569
570 // Get the nodeset's id
571 if( mdbImpl->tag_get_data( mDirichletSetTag, &( *vector_iter ), 1, &id ) != MB_SUCCESS )
572 {
573 MB_SET_ERR( MB_FAILURE, "Couldn't get id tag for nodeset " << id );
574 }
575
576 nodeset_data.id = id;
577
578 std::vector< EntityHandle > node_vector;
579 // Get the nodes of the nodeset that are in mesh_info.nodes
580 if( mdbImpl->get_entities_by_handle( *vector_iter, node_vector, true ) != MB_SUCCESS )
581 {
582 MB_SET_ERR( MB_FAILURE, "Couldn't get nodes in nodeset " << id );
583 }
584
585 // Get the tag for distribution factors
586 const double* dist_factor_vector;
587 int dist_factor_size;
588 const void* ptr = 0;
589
590 int has_dist_factors = 0;
591 if( mdbImpl->tag_get_by_ptr( mDistFactorTag, &( *vector_iter ), 1, &ptr, &dist_factor_size ) == MB_SUCCESS &&
592 dist_factor_size )
593 has_dist_factors = 1;
594 dist_factor_size /= sizeof( double );
595 dist_factor_vector = reinterpret_cast< const double* >( ptr );
596 std::vector< EntityHandle >::iterator iter, end_iter;
597 iter = node_vector.begin();
598 end_iter = node_vector.end();
599
600 int j = 0;
601 unsigned char node_marked = 0;
602 ErrorCode result;
603 for( ; iter != end_iter; ++iter )
604 {
605 if( TYPE_FROM_HANDLE( *iter ) != MBVERTEX ) continue;
606 result = mdbImpl->tag_get_data( mEntityMark, &( *iter ), 1, &node_marked );MB_CHK_SET_ERR( result, "Couldn't get mark data" );
607
608 if( 0x1 == node_marked )
609 {
610 nodeset_data.nodes.push_back( *iter );
611 if( 0 != has_dist_factors )
612 nodeset_data.node_dist_factors.push_back( dist_factor_vector[j] );
613 else
614 nodeset_data.node_dist_factors.push_back( 1.0 );
615 }
616 j++;
617 }
618
619 nodeset_data.number_nodes = nodeset_data.nodes.size();
620 nodeset_info.push_back( nodeset_data );
621 }
622
623 //------sidesets--------
624 vector_iter = sidesets.begin();
625 end_vector_iter = sidesets.end();
626
627 for( ; vector_iter != end_vector_iter; ++vector_iter )
628 {
629 NeumannSetData sideset_data;
630
631 // Get the sideset's id
632 if( mdbImpl->tag_get_data( mNeumannSetTag, &( *vector_iter ), 1, &id ) != MB_SUCCESS ) return MB_FAILURE;
633
634 sideset_data.id = id;
635 sideset_data.mesh_set_handle = *vector_iter;
636
637 // Get the sides in two lists, one forward the other reverse; starts with forward sense
638 // by convention
639 Range forward_elems, reverse_elems;
640 if( get_sideset_elems( *vector_iter, 0, forward_elems, reverse_elems ) == MB_FAILURE ) return MB_FAILURE;
641
642 ErrorCode result = get_valid_sides( forward_elems, mesh_info, 1, sideset_data );MB_CHK_SET_ERR( result, "Couldn't get valid sides data" );
643 result = get_valid_sides( reverse_elems, mesh_info, -1, sideset_data );MB_CHK_SET_ERR( result, "Couldn't get valid sides data" );
644
645 sideset_data.number_elements = sideset_data.elements.size();
646 sideset_info.push_back( sideset_data );
647 }
648
649 return MB_SUCCESS;
650 }
References moab::Range::all_of_type(), moab::Range::back(), moab::Range::begin(), moab::CN::Dimension(), moab::MaterialSetData::element_type, moab::MaterialSetData::elements, moab::NeumannSetData::elements, moab::Range::empty(), moab::Range::end(), ErrorCode, moab::EXOII_MAX_ELEM_TYPE, moab::EXOII_POLYGON, moab::EXOII_POLYHEDRON, moab::Range::front(), moab::WriteUtilIface::gather_nodes_from_elements(), moab::Interface::get_connectivity(), moab::ExoIIUtil::get_element_type_from_num_verts(), moab::Interface::get_entities_by_handle(), moab::Interface::get_parent_meshsets(), get_sideset_elems(), get_valid_sides(), moab::MaterialSetData::id, moab::DirichletSetData::id, moab::NeumannSetData::id, MB_CHK_ERR, MB_CHK_SET_ERR, MB_SET_ERR, MB_SUCCESS, MB_TAG_CREAT, MB_TYPE_BIT, MB_TYPE_OUT_OF_RANGE, MBEDGE, MBQUAD, MBTRI, MBVERTEX, mdbImpl, mDirichletSetTag, mDistFactorTag, mEntityMark, moab::NeumannSetData::mesh_set_handle, mMaterialSetTag, mNeumannSetTag, mQaRecordTag, mWriteIface, moab::DirichletSetData::node_dist_factors, moab::DirichletSetData::nodes, moab::WriteNCDF::ExodusMeshInfo::nodes, moab::WriteNCDF::ExodusMeshInfo::num_dim, moab::WriteNCDF::ExodusMeshInfo::num_elementblocks, moab::WriteNCDF::ExodusMeshInfo::num_elements, moab::WriteNCDF::ExodusMeshInfo::num_nodes, moab::WriteNCDF::ExodusMeshInfo::num_polyhedra_blocks, moab::MaterialSetData::number_attributes, moab::MaterialSetData::number_elements, moab::NeumannSetData::number_elements, moab::DirichletSetData::number_nodes, moab::MaterialSetData::number_nodes_per_element, moab::WriteNCDF::ExodusMeshInfo::polyhedronFaces, moab::WriteNCDF::ExodusMeshInfo::qaRecords, size, moab::Range::size(), moab::Range::subset_by_dimension(), moab::subtract(), moab::Interface::tag_delete(), moab::Interface::tag_get_by_ptr(), moab::Interface::tag_get_data(), moab::Interface::tag_get_handle(), moab::Interface::tag_set_data(), moab::TYPE_FROM_HANDLE(), and moab::ExoIIUtil::VerticesPerElement.
Referenced by write_file().
|
private |
recursive function; given a meshset handle, get the entities and put them on the right list, then call recursively for any contained meshsets, first checking for sense reversals
Definition at line 2287 of file WriteNCDF.cpp.
2291 {
2292 Range ss_elems, ss_meshsets;
2293
2294 // Get the sense tag; don't need to check return, might be an error if the tag
2295 // hasn't been created yet
2296 Tag sense_tag = 0;
2297 mdbImpl->tag_get_handle( "SENSE", 1, MB_TYPE_INTEGER, sense_tag );
2298
2299 // Get the entities in this set
2300 ErrorCode result = mdbImpl->get_entities_by_handle( sideset, ss_elems, true );
2301 if( MB_FAILURE == result ) return result;
2302
2303 // Now remove the meshsets into the ss_meshsets; first find the first meshset,
2304 Range::iterator range_iter = ss_elems.begin();
2305 while( TYPE_FROM_HANDLE( *range_iter ) != MBENTITYSET && range_iter != ss_elems.end() )
2306 ++range_iter;
2307
2308 // Then, if there are some, copy them into ss_meshsets and erase from ss_elems
2309 if( range_iter != ss_elems.end() )
2310 {
2311 std::copy( range_iter, ss_elems.end(), range_inserter( ss_meshsets ) );
2312 ss_elems.erase( range_iter, ss_elems.end() );
2313 }
2314
2315 // OK, for the elements, check the sense of this set and copy into the right range
2316 // (if the sense is 0, copy into both ranges)
2317
2318 // Need to step forward on list until we reach the right dimension
2319 Range::iterator dum_it = ss_elems.end();
2320 --dum_it;
2321 int target_dim = CN::Dimension( TYPE_FROM_HANDLE( *dum_it ) );
2322 dum_it = ss_elems.begin();
2323 while( target_dim != CN::Dimension( TYPE_FROM_HANDLE( *dum_it ) ) && dum_it != ss_elems.end() )
2324 ++dum_it;
2325
2326 if( current_sense == 1 || current_sense == 0 ) std::copy( dum_it, ss_elems.end(), range_inserter( forward_elems ) );
2327 if( current_sense == -1 || current_sense == 0 )
2328 std::copy( dum_it, ss_elems.end(), range_inserter( reverse_elems ) );
2329
2330 // Now loop over the contained meshsets, getting the sense of those and calling this
2331 // function recursively
2332 for( range_iter = ss_meshsets.begin(); range_iter != ss_meshsets.end(); ++range_iter )
2333 {
2334 // First get the sense; if it's not there, by convention it's forward
2335 int this_sense;
2336 if( 0 == sense_tag || MB_FAILURE == mdbImpl->tag_get_data( sense_tag, &( *range_iter ), 1, &this_sense ) )
2337 this_sense = 1;
2338
2339 // Now get all the entities on this meshset, with the proper (possibly reversed) sense
2340 get_sideset_elems( *range_iter, this_sense * current_sense, forward_elems, reverse_elems );
2341 }
2342
2343 return result;
2344 }
References moab::Range::begin(), moab::CN::Dimension(), moab::Range::end(), moab::Range::erase(), ErrorCode, moab::Interface::get_entities_by_handle(), MB_TYPE_INTEGER, MBENTITYSET, mdbImpl, moab::Interface::tag_get_data(), moab::Interface::tag_get_handle(), and moab::TYPE_FROM_HANDLE().
Referenced by gather_mesh_information().
|
private |
Definition at line 652 of file WriteNCDF.cpp.
656 {
657 // This is where we see if underlying element of side set element is included in output
658
659 // Get the sideset-based info for distribution factors
660 const double* dist_factor_vector = 0;
661 int dist_factor_size = 0;
662
663 // Initialize dist_fac_iter to get rid of compiler warning
664 const double* dist_fac_iter = 0;
665 const void* ptr = 0;
666 bool has_dist_factors = false;
667 if( mdbImpl->tag_get_by_ptr( mDistFactorTag, &( sideset_data.mesh_set_handle ), 1, &ptr, &dist_factor_size ) ==
668 MB_SUCCESS &&
669 dist_factor_size )
670 {
671 has_dist_factors = true;
672 dist_factor_vector = reinterpret_cast< const double* >( ptr );
673 dist_fac_iter = dist_factor_vector;
674 dist_factor_size /= sizeof( double );
675 }
676
677 unsigned char element_marked = 0;
678 ErrorCode result;
679 for( Range::iterator iter = elems.begin(); iter != elems.end(); ++iter )
680 {
681 // Should insert here if "side" is a quad/tri on a quad/tri mesh
682 result = mdbImpl->tag_get_data( mEntityMark, &( *iter ), 1, &element_marked );MB_CHK_SET_ERR( result, "Couldn't get mark data" );
683
684 if( 0x1 == element_marked )
685 {
686 sideset_data.elements.push_back( *iter );
687
688 // TJT TODO: the sense should really be # edges + 1or2
689 sideset_data.side_numbers.push_back( ( sense == 1 ? 1 : 2 ) );
690 }
691 else
692 { // Then "side" is probably a quad/tri on a hex/tet mesh
693 std::vector< EntityHandle > parents;
694 int dimension = CN::Dimension( TYPE_FROM_HANDLE( *iter ) );
695
696 // Get the adjacent parent element of "side"
697 if( mdbImpl->get_adjacencies( &( *iter ), 1, dimension + 1, false, parents ) != MB_SUCCESS )
698 {
699 #if 0
700 // This is not treated as an error, print warning messages for
701 // debugging only
702 fprintf(stderr, "[Warning]: Couldn't get adjacencies for sideset.\n");
703 #endif
704 }
705
706 if( !parents.empty() )
707 {
708 // Make sure the adjacent parent element will be output
709 for( unsigned int k = 0; k < parents.size(); k++ )
710 {
711 result = mdbImpl->tag_get_data( mEntityMark, &( parents[k] ), 1, &element_marked );MB_CHK_SET_ERR( result, "Couldn't get mark data" );
712
713 int side_no, this_sense, this_offset;
714 if( 0x1 == element_marked &&
715 mdbImpl->side_number( parents[k], *iter, side_no, this_sense, this_offset ) == MB_SUCCESS &&
716 this_sense == sense )
717 {
718 sideset_data.elements.push_back( parents[k] );
719 sideset_data.side_numbers.push_back( side_no + 1 );
720 break;
721 }
722 }
723 }
724 else
725 {
726 #if 0
727 // This is not treated as an error, print warning messages for
728 // debugging only
729 fprintf(stderr, "[Warning]: No parent element exists for element in sideset %i\n", sideset_data.id);
730 #endif
731 }
732 }
733
734 if( sideset_data.elements.size() != 0 )
735 {
736 // Distribution factors
737 int num_nodes = CN::VerticesPerEntity( TYPE_FROM_HANDLE( *iter ) );
738 // put some dummy dist factors for polygons; why do we need them?
739 if( TYPE_FROM_HANDLE( *iter ) == MBPOLYGON ) num_nodes = 1; // dummy
740 if( has_dist_factors )
741 {
742 std::copy( dist_fac_iter, dist_fac_iter + num_nodes,
743 std::back_inserter( sideset_data.ss_dist_factors ) );
744 dist_fac_iter += num_nodes;
745 }
746 else
747 {
748 for( int j = 0; j < num_nodes; j++ )
749 sideset_data.ss_dist_factors.push_back( 1.0 );
750 }
751 }
752 }
753
754 return MB_SUCCESS;
755 }
References moab::Range::begin(), moab::CN::Dimension(), moab::NeumannSetData::elements, moab::Range::end(), ErrorCode, moab::Interface::get_adjacencies(), moab::NeumannSetData::id, MB_CHK_SET_ERR, MB_SUCCESS, MBPOLYGON, mdbImpl, mDistFactorTag, mEntityMark, moab::NeumannSetData::mesh_set_handle, moab::Interface::side_number(), moab::NeumannSetData::side_numbers, moab::NeumannSetData::ss_dist_factors, moab::Interface::tag_get_by_ptr(), moab::Interface::tag_get_data(), moab::TYPE_FROM_HANDLE(), and moab::CN::VerticesPerEntity().
Referenced by gather_mesh_information().
|
private |
Definition at line 1571 of file WriteNCDF.cpp.
1578 {
1579 // This routine takes the place of the exodusii routine ex_put_init,
1580 // and additionally pre-defines variables such as qa, element blocks,
1581 // sidesets and nodesets in a single pass.
1582 //
1583 // This is necessary because of the way exodusII works. Each time the
1584 // netcdf routine endef is called to take the file out of define mode,
1585 // the entire file is copied before the new information is added.
1586 //
1587 // With very large files, this is simply not workable. This routine takes
1588 // the definition portions of all applicable exodus routines and puts them
1589 // in a single definition, preventing repeated copying of the file.
1590 //
1591 // Most of the code is copied directly from the applicable exodus routine,
1592 // and thus this routine may not seem very consistent in usage or variable
1593 // naming, etc.
1594
1595 // Perform the initializations
1596
1597 int element_block_index;
1598
1599 // Inquire on defined string dimension and general dimension for qa
1600
1601 int dim_str, dim_four, dim_line, dim_time;
1602 if( nc_def_dim( ncFile, "len_string", ExoIIInterface::MAX_STR_LENGTH, &dim_str ) != NC_NOERR )
1603 {
1604 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to get string length in file" );
1605 }
1606
1607 if( nc_def_dim( ncFile, "len_line", ExoIIInterface::MAX_STR_LENGTH, &dim_line ) != NC_NOERR )
1608 {
1609 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to get line length in file" );
1610 }
1611
1612 if( nc_def_dim( ncFile, "four", 4, &dim_four ) != NC_NOERR )
1613 {
1614 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to locate four in file" );
1615 }
1616
1617 if( nc_def_dim( ncFile, "time_step", 1, &dim_time ) != NC_NOERR )
1618 {
1619 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to locate time step in file" );
1620 }
1621 // some whole_time dummy :(
1622 int dtime;
1623 if( NC_NOERR != nc_def_var( ncFile, "time_whole", NC_DOUBLE, 1, &dim_time, &dtime ) )
1624 {
1625 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define time whole array" );
1626 }
1627
1628 /* Put file into define mode */
1629
1630 // It is possible that an NT filename using backslashes is in the title string
1631 // this can give fits to unix codes where the backslash is assumed to be an escape
1632 // sequence. For the exodus file, just flip the backslash to a slash to prevent
1633 // this problem
1634
1635 // Get a working copy of the title_string;
1636
1637 char working_title[80];
1638 strncpy( working_title, title_string, 79 );
1639
1640 int length = strlen( working_title );
1641 for( int pos = 0; pos < length; pos++ )
1642 {
1643 if( working_title[pos] == '\\' ) working_title[pos] = '/';
1644 }
1645
1646 if( NC_NOERR != nc_put_att_text( ncFile, NC_GLOBAL, "title", length, working_title ) )
1647 {
1648 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define title attribute" );
1649 }
1650
1651 // Add other attributes while we're at it
1652 float dum_vers = 6.28F;
1653 if( NC_NOERR != nc_put_att_float( ncFile, NC_GLOBAL, "api_version", NC_FLOAT, 1, &dum_vers ) )
1654 {
1655 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define api_version attribute" );
1656 }
1657 dum_vers = 6.28F;
1658 if( NC_NOERR != nc_put_att_float( ncFile, NC_GLOBAL, "version", NC_FLOAT, 1, &dum_vers ) )
1659 {
1660 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define version attribute" );
1661 }
1662 int dum_siz = sizeof( double );
1663 if( NC_NOERR != nc_put_att_int( ncFile, NC_GLOBAL, "floating_point_word_size", NC_INT, 1, &dum_siz ) )
1664 {
1665 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define floating pt word size attribute" );
1666 }
1667
1668 // Set up number of dimensions
1669
1670 int num_el_blk, num_elem, num_nodes, num_dim, num_fa_blk, num_faces;
1671 if( nc_def_dim( ncFile, "num_dim", (size_t)mesh_info.num_dim, &num_dim ) != NC_NOERR )
1672 {
1673 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define number of dimensions" );
1674 }
1675
1676 if( nc_def_dim( ncFile, "num_nodes", mesh_info.num_nodes, &num_nodes ) != NC_NOERR )
1677 {
1678 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define number of nodes" );
1679 }
1680
1681 int num_nod_per_fa; // it is needed for polyhedron only; need to compute it (connectivity of
1682 // faces of polyhedra)
1683 if( mesh_info.polyhedronFaces.size() > 0 )
1684 if( nc_def_dim( ncFile, "num_faces", (int)mesh_info.polyhedronFaces.size(), &num_faces ) != NC_NOERR )
1685 {
1686 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define number of nodes" );
1687 }
1688
1689 if( nc_def_dim( ncFile, "num_elem", mesh_info.num_elements, &num_elem ) != NC_NOERR )
1690 {
1691 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define number of elements" );
1692 }
1693
1694 if( nc_def_dim( ncFile, "num_el_blk", mesh_info.num_elementblocks, &num_el_blk ) != NC_NOERR )
1695 {
1696 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define number of element blocks" );
1697 }
1698
1699 /* ...and some variables */
1700
1701 /* Element block id status array */
1702 int idstat = -1;
1703 if( NC_NOERR != nc_def_var( ncFile, "eb_status", NC_LONG, 1, &num_el_blk, &idstat ) )
1704 {
1705 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define element block status array" );
1706 }
1707
1708 /* Element block id array */
1709
1710 int idarr = -1;
1711 if( NC_NOERR != nc_def_var( ncFile, "eb_prop1", NC_LONG, 1, &num_el_blk, &idarr ) )
1712 {
1713 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define element block id array" );
1714 }
1715
1716 /* store property name as attribute of property array variable */
1717 if( NC_NOERR != nc_put_att_text( ncFile, idarr, "name", strlen( "ID" ), "ID" ) )
1718 {
1719 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to store element block property name ID" );
1720 }
1721
1722 // count how many are polyhedron blocks
1723 int num_fa_blocks = 0; //, num_polyh_blocks = 0;
1724 for( unsigned int i = 0; i < block_data.size(); i++ )
1725 {
1726 MaterialSetData& block = block_data[i];
1727 if( EXOII_POLYHEDRON == block.element_type )
1728 {
1729 num_fa_blocks++;
1730 // num_polyh_blocks++;
1731 }
1732 }
1733 if( 0 == this->repeat_face_blocks && num_fa_blocks > 1 ) num_fa_blocks = 1;
1734 char wname[CHAR_STR_LEN];
1735
1736 if( num_fa_blocks > 0 )
1737 {
1738 /* face block id status array */
1739 if( nc_def_dim( ncFile, "num_fa_blk", num_fa_blocks, &num_fa_blk ) != NC_NOERR )
1740 {
1741 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define number of face blocks" );
1742 }
1743
1744 int idstatf = -1;
1745 if( NC_NOERR != nc_def_var( ncFile, "fa_status", NC_LONG, 1, &num_fa_blk, &idstatf ) )
1746 {
1747 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define face block status array" );
1748 }
1749
1750 /* Element block id array */
1751
1752 int idarrf = -1;
1753 if( NC_NOERR != nc_def_var( ncFile, "fa_prop1", NC_LONG, 1, &num_fa_blk, &idarrf ) )
1754 {
1755 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define face block id array" );
1756 }
1757
1758 /* store property name as attribute of property array variable */
1759 if( NC_NOERR != nc_put_att_text( ncFile, idarrf, "name", strlen( "ID" ), "ID" ) )
1760 {
1761 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to store face block property name ID" );
1762 }
1763 // determine the number of num_nod_per_face
1764 /*
1765 num_fa_in_blk1 = 15 ;
1766 num_nod_per_fa1 = 58 ;
1767
1768 int fbconn1(num_nod_per_fa1) ;
1769 fbconn1:elem_type = "nsided" ;
1770 int fbepecnt1(num_fa_in_blk1) ;
1771 fbepecnt1:entity_type1 = "NODE" ;
1772 fbepecnt1:entity_type2 = "FACE" ;
1773 */
1774
1775 int num_nodes_per_face = 0;
1776
1777 int dims[1]; // maybe 1 is enough here
1778 for( Range::iterator eit = mesh_info.polyhedronFaces.begin(); eit != mesh_info.polyhedronFaces.end(); eit++ )
1779 {
1780 EntityHandle polyg = *eit;
1781 int nnodes = 0;
1782 const EntityHandle* conn = NULL;
1783 ErrorCode rval = mdbImpl->get_connectivity( polyg, conn, nnodes );MB_CHK_ERR( rval );
1784 num_nodes_per_face += nnodes;
1785 }
1786
1787 // duplicate if needed; default is not duplicate
1788 for( int j = 1; j <= num_fa_blocks; j++ )
1789 {
1790 INS_ID( wname, "num_nod_per_fa%d", j );
1791 if( nc_def_dim( ncFile, wname, (size_t)num_nodes_per_face, &num_nod_per_fa ) != NC_NOERR )
1792 {
1793 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define number of nodes for face block " );
1794 }
1795 dims[0] = num_nod_per_fa;
1796 INS_ID( wname, "fbconn%d", j ); // first one, or more
1797 int fbconn;
1798 if( NC_NOERR != nc_def_var( ncFile, wname, NC_LONG, 1, dims, &fbconn ) )
1799 {
1800 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to create connectivity array for face block " << 1 );
1801 }
1802 std::string element_type_string( "nsided" );
1803 if( NC_NOERR != nc_put_att_text( ncFile, fbconn, "elem_type", element_type_string.length(),
1804 element_type_string.c_str() ) )
1805 {
1806 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to store element type nsided " );
1807 }
1808
1809 INS_ID( wname, "num_fa_in_blk%d", j ); // first one, or more
1810 int num_fa_in_blk;
1811 if( nc_def_dim( ncFile, wname, (size_t)mesh_info.polyhedronFaces.size(), &num_fa_in_blk ) != NC_NOERR )
1812 {
1813 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define number of nodes for face block " );
1814 }
1815
1816 // fbepecnt
1817 INS_ID( wname, "fbepecnt%d", j ); // first one, or more
1818 int fbepecnt;
1819 dims[0] = num_fa_in_blk;
1820 if( NC_NOERR != nc_def_var( ncFile, wname, NC_LONG, 1, dims, &fbepecnt ) )
1821 {
1822 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to create fbepecnt array for block " << 1 );
1823 }
1824 std::string enttype1( "NODE" );
1825 if( NC_NOERR != nc_put_att_text( ncFile, fbepecnt, "entity_type1", enttype1.length(), enttype1.c_str() ) )
1826 {
1827 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to store entity type 1 " );
1828 }
1829 std::string enttype2( "FACE" );
1830 if( NC_NOERR != nc_put_att_text( ncFile, fbepecnt, "entity_type2", enttype2.length(), enttype2.c_str() ) )
1831 {
1832 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to store entity type 2 " );
1833 }
1834 }
1835 }
1836
1837 // Define element blocks
1838
1839 for( unsigned int i = 0; i < block_data.size(); i++ )
1840 {
1841 MaterialSetData& block = block_data[i];
1842
1843 element_block_index = i + 1;
1844 int num_el_in_blk = -1, num_att_in_blk = -1;
1845 int blk_attrib, connect;
1846
1847 /* Define number of elements in this block */
1848
1849 INS_ID( wname, "num_el_in_blk%d", element_block_index );
1850 if( nc_def_dim( ncFile, wname, (size_t)block.number_elements, &num_el_in_blk ) != NC_NOERR )
1851 {
1852 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define number of elements/block for block " << i + 1 );
1853 }
1854
1855 /* Define number of nodes per element for this block */
1856 INS_ID( wname, "num_nod_per_el%d", element_block_index );
1857 int num_nod_per_el = -1;
1858 if( EXOII_POLYHEDRON != block.element_type )
1859 if( nc_def_dim( ncFile, wname, (size_t)block.number_nodes_per_element, &num_nod_per_el ) != NC_NOERR )
1860 {
1861 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define number of nodes/element for block " << block.id );
1862 }
1863
1864 /* Define element attribute array for this block */
1865 int dims[3];
1866 if( block.number_attributes > 0 )
1867 {
1868 INS_ID( wname, "num_att_in_blk%d", element_block_index );
1869 if( nc_def_dim( ncFile, wname, (size_t)block.number_attributes, &num_att_in_blk ) != NC_NOERR )
1870 {
1871 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define number of attributes in block " << block.id );
1872 }
1873
1874 INS_ID( wname, "attrib%d", element_block_index );
1875 dims[0] = num_el_in_blk;
1876 dims[1] = num_att_in_blk;
1877 if( NC_NOERR != nc_def_var( ncFile, wname, NC_DOUBLE, 2, dims, &blk_attrib ) )
1878 {
1879 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define attributes for element block " << block.id );
1880 }
1881 }
1882
1883 /* Define element connectivity array for this block */
1884
1885 if( EXOII_POLYGON != block.element_type && EXOII_POLYHEDRON != block.element_type )
1886 {
1887 INS_ID( wname, "connect%d", element_block_index );
1888 dims[0] = num_el_in_blk;
1889 dims[1] = num_nod_per_el;
1890 if( NC_NOERR != nc_def_var( ncFile, wname, NC_LONG, 2, dims, &connect ) )
1891 {
1892 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to create connectivity array for block " << i + 1 );
1893 }
1894
1895 /* Store element type as attribute of connectivity variable */
1896
1897 std::string element_type_string( ExoIIUtil::ElementTypeNames[block.element_type] );
1898 if( NC_NOERR != nc_put_att_text( ncFile, connect, "elem_type", element_type_string.length(),
1899 element_type_string.c_str() ) )
1900 {
1901 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to store element type name " << (int)block.element_type );
1902 }
1903 }
1904 else if( EXOII_POLYGON == block.element_type )
1905 {
1906 INS_ID( wname, "connect%d", element_block_index );
1907 // need to define num_nod_per_el as total number of nodes
1908 // ebepecnt1 as number of nodes per polygon
1909 /*
1910 * int connect1(num_nod_per_el1) ;
1911 connect1:elem_type = "nsided" ;
1912 int ebepecnt1(num_el_in_blk1) ;
1913 ebepecnt1:entity_type1 = "NODE" ;
1914 ebepecnt1:entity_type2 = "ELEM" ;*/
1915 dims[0] = num_nod_per_el;
1916 if( NC_NOERR != nc_def_var( ncFile, wname, NC_LONG, 1, dims, &connect ) )
1917 {
1918 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to create connectivity array for block " << i + 1 );
1919 }
1920 std::string element_type_string( "nsided" );
1921 if( NC_NOERR != nc_put_att_text( ncFile, connect, "elem_type", element_type_string.length(),
1922 element_type_string.c_str() ) )
1923 {
1924 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to store element type name " << (int)block.element_type );
1925 }
1926 INS_ID( wname, "ebepecnt%d", element_block_index );
1927 int ebepecnt;
1928 dims[0] = num_el_in_blk;
1929 if( NC_NOERR != nc_def_var( ncFile, wname, NC_LONG, 1, dims, &ebepecnt ) )
1930 {
1931 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to create ebepecnt array for block " << i + 1 );
1932 }
1933 std::string etype1( "NODE" );
1934 if( NC_NOERR != nc_put_att_text( ncFile, ebepecnt, "entity_type1", etype1.length(), etype1.c_str() ) )
1935 {
1936 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to store entity type1 " << (int)block.element_type );
1937 }
1938 std::string etype2( "ELEM" );
1939 if( NC_NOERR != nc_put_att_text( ncFile, ebepecnt, "entity_type2", etype2.length(), etype2.c_str() ) )
1940 {
1941 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to store entity type2 " << (int)block.element_type );
1942 }
1943 }
1944 else if( EXOII_POLYHEDRON == block.element_type )
1945 {
1946 // INS_ID(wname, "connect%d", element_block_index);
1947 /*
1948 testn face example: 3 polyh, 15 total faces, 2 shared; 15+2 = 17
1949 num_elem = 3 ;
1950 num_face = 15 ; // not needed?
1951 num_el_blk = 1 ;
1952
1953 num_el_in_blk1 = 3 ;
1954 num_fac_per_el1 = 17 ;
1955
1956 * num faces will be total face conn
1957 * num_faces_in_block will be number of faces (non repeated)
1958 * num_nodes_per_face will have total face connectivity
1959 */
1960 int num_faces2 = 0;
1961
1962 for( Range::iterator eit = block.elements.begin(); eit != block.elements.end(); eit++ )
1963 {
1964 EntityHandle polyh = *eit;
1965 int nfaces = 0;
1966 const EntityHandle* conn = NULL;
1967 ErrorCode rval = mdbImpl->get_connectivity( polyh, conn, nfaces );MB_CHK_ERR( rval );
1968 num_faces2 += nfaces;
1969 }
1970
1971 int num_fac_per_el;
1972
1973 INS_ID( wname, "num_fac_per_el%d", element_block_index );
1974 if( nc_def_dim( ncFile, wname, (size_t)num_faces2, &num_fac_per_el ) != NC_NOERR )
1975 {
1976 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define number of faces per block " << block.id );
1977 }
1978
1979 /*
1980 int facconn1(num_fac_per_el1) ;
1981 facconn1:elem_type = "NFACED" ;
1982 int ebepecnt1(num_el_in_blk1) ;
1983 ebepecnt1:entity_type1 = "FACE" ;
1984 ebepecnt1:entity_type2 = "ELEM" ;
1985 */
1986
1987 // facconn
1988 INS_ID( wname, "facconn%d", element_block_index );
1989 int facconn;
1990 dims[0] = num_fac_per_el;
1991 if( NC_NOERR != nc_def_var( ncFile, wname, NC_LONG, 1, dims, &facconn ) )
1992 {
1993 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to create facconn array for block " << i + 1 );
1994 }
1995 std::string etype( "NFACED" );
1996 if( NC_NOERR != nc_put_att_text( ncFile, facconn, "elem_type", etype.length(), etype.c_str() ) )
1997 {
1998 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to store elem type " << (int)block.element_type );
1999 }
2000
2001 // ebepecnt
2002 INS_ID( wname, "ebepecnt%d", element_block_index );
2003 int ebepecnt;
2004 dims[0] = num_el_in_blk;
2005 if( NC_NOERR != nc_def_var( ncFile, wname, NC_LONG, 1, dims, &ebepecnt ) )
2006 {
2007 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to create ebepecnt array for block " << i + 1 );
2008 }
2009 std::string etype1( "FACE" );
2010 if( NC_NOERR != nc_put_att_text( ncFile, ebepecnt, "entity_type1", etype1.length(), etype1.c_str() ) )
2011 {
2012 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to store entity type1 " << (int)block.element_type );
2013 }
2014 std::string etype2( "ELEM" );
2015 if( NC_NOERR != nc_put_att_text( ncFile, ebepecnt, "entity_type2", etype2.length(), etype2.c_str() ) )
2016 {
2017 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to store entity type2 " << (int)block.element_type );
2018 }
2019
2020 block.number_nodes_per_element = num_faces2; // connectivity for all polyhedra in block
2021 }
2022 }
2023
2024 /* Node set id array: */
2025
2026 int non_empty_nss = 0;
2027 // Need to go through nodesets to compute # nodesets, some might be empty
2028 std::vector< DirichletSetData >::iterator ns_it;
2029 for( ns_it = nodeset_data.begin(); ns_it != nodeset_data.end(); ++ns_it )
2030 {
2031 if( 0 != ( *ns_it ).number_nodes ) non_empty_nss++;
2032 }
2033
2034 int num_ns = -1;
2035 int ns_idstat = -1, ns_idarr = -1;
2036 if( non_empty_nss > 0 )
2037 {
2038 if( nc_def_dim( ncFile, "num_node_sets", (size_t)( non_empty_nss ), &num_ns ) != NC_NOERR )
2039 {
2040 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define number of node sets" );
2041 }
2042
2043 /* Node set id status array: */
2044
2045 if( NC_NOERR != nc_def_var( ncFile, "ns_status", NC_LONG, 1, &num_ns, &ns_idstat ) )
2046 {
2047 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to create node sets status array" );
2048 }
2049
2050 /* Node set id array: */
2051 if( NC_NOERR != nc_def_var( ncFile, "ns_prop1", NC_LONG, 1, &num_ns, &ns_idarr ) )
2052 {
2053 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to create node sets property array" );
2054 }
2055
2056 /* Store property name as attribute of property array variable */
2057 if( NC_NOERR != nc_put_att_text( ncFile, NC_GLOBAL, "name", strlen( "ID" ), "ID" ) )
2058 {
2059 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to store node set property name ID" );
2060 }
2061
2062 // Now, define the arrays needed for each node set
2063
2064 int index = 0;
2065
2066 for( unsigned i = 0; i < nodeset_data.size(); i++ )
2067 {
2068 DirichletSetData node_set = nodeset_data[i];
2069
2070 if( 0 == node_set.number_nodes )
2071 {
2072 MB_SET_ERR_CONT( "WriteNCDF: empty nodeset " << node_set.id );
2073 continue;
2074 }
2075 index++;
2076
2077 int num_nod_ns = -1;
2078 INS_ID( wname, "num_nod_ns%d", index );
2079 if( nc_def_dim( ncFile, wname, (size_t)node_set.number_nodes, &num_nod_ns ) != NC_NOERR )
2080 {
2081 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define number of nodes for set " << node_set.id );
2082 }
2083
2084 /* Create variable array in which to store the node set node list */
2085 int node_ns = -1;
2086 INS_ID( wname, "node_ns%d", index );
2087 if( NC_NOERR != nc_def_var( ncFile, wname, NC_LONG, 1, &num_nod_ns, &node_ns ) )
2088 {
2089 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to create node set " << node_set.id << " node list" );
2090 }
2091
2092 // Create distribution factor array
2093 int fact_ns = -1;
2094 INS_ID( wname, "dist_fact_ns%d", index );
2095 if( NC_NOERR != nc_def_var( ncFile, wname, NC_DOUBLE, 1, &num_nod_ns, &fact_ns ) )
2096 {
2097 MB_SET_ERR( MB_FAILURE,
2098 "WriteNCDF: failed to create node set " << node_set.id << " distribution factor list" );
2099 }
2100 }
2101 }
2102
2103 /* Side set id array: */
2104
2105 long non_empty_ss = 0;
2106 // Need to go through nodesets to compute # nodesets, some might be empty
2107 std::vector< NeumannSetData >::iterator ss_it;
2108 for( ss_it = sideset_data.begin(); ss_it != sideset_data.end(); ++ss_it )
2109 {
2110 if( 0 != ( *ss_it ).number_elements ) non_empty_ss++;
2111 }
2112
2113 if( non_empty_ss > 0 )
2114 {
2115 int num_ss = -1;
2116 if( nc_def_dim( ncFile, "num_side_sets", non_empty_ss, &num_ss ) != NC_NOERR )
2117 {
2118 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define number of side sets" );
2119 }
2120
2121 /* Side set id status array: */
2122 int ss_idstat = -1, ss_idarr = -1;
2123 if( NC_NOERR != nc_def_var( ncFile, "ss_status", NC_LONG, 1, &num_ss, &ss_idstat ) )
2124 {
2125 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define side set status" );
2126 }
2127
2128 /* Side set id array: */
2129 if( NC_NOERR != nc_def_var( ncFile, "ss_prop1", NC_LONG, 1, &num_ss, &ss_idarr ) )
2130 {
2131 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define side set property" );
2132 }
2133
2134 /* Store property name as attribute of property array variable */
2135 if( NC_NOERR != nc_put_att_text( ncFile, ss_idarr, "name", strlen( "ID" ), "ID" ) )
2136 {
2137 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to store side set property name ID" );
2138 }
2139
2140 // Now, define the arrays needed for each side set
2141
2142 int index = 0;
2143 for( unsigned int i = 0; i < sideset_data.size(); i++ )
2144 {
2145 NeumannSetData side_set = sideset_data[i];
2146
2147 // Don't define an empty set
2148 if( 0 == side_set.number_elements ) continue;
2149
2150 index++;
2151
2152 int num_side_ss = -1;
2153 int elem_ss = -1, side_ss = -1;
2154 INS_ID( wname, "num_side_ss%d", index );
2155 if( nc_def_dim( ncFile, wname, (size_t)side_set.number_elements, &num_side_ss ) != NC_NOERR )
2156 {
2157 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define number of sides in side set " << side_set.id );
2158 }
2159
2160 INS_ID( wname, "elem_ss%d", index );
2161 if( NC_NOERR != nc_def_var( ncFile, wname, NC_LONG, 1, &num_side_ss, &elem_ss ) )
2162 {
2163 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to create element list for side set "
2164 << side_set.id ); /* Exit define mode and return */
2165 }
2166 INS_ID( wname, "side_ss%d", index );
2167 if( NC_NOERR != nc_def_var( ncFile, wname, NC_LONG, 1, &num_side_ss, &side_ss ) )
2168 {
2169 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to create side list for side set "
2170 << side_set.id ); /* Exit define mode and return */
2171 }
2172
2173 // sideset distribution factors
2174 int num_df_ss = -1;
2175 INS_ID( wname, "num_df_ss%d", index );
2176 if( nc_def_dim( ncFile, wname, (size_t)side_set.ss_dist_factors.size(), &num_df_ss ) != NC_NOERR )
2177 {
2178 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define number of dist factors in side set "
2179 << side_set.id ); /* Exit define mode and return */
2180 }
2181
2182 /* Create variable array in which to store the side set distribution factors */
2183
2184 int fact_ss = -1;
2185 INS_ID( wname, "dist_fact_ss%d", index );
2186 if( NC_NOERR != nc_def_var( ncFile, wname, NC_LONG, 1, &num_df_ss, &fact_ss ) )
2187 {
2188 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to create dist factors list for side set "
2189 << side_set.id ); /* Exit define mode and return */
2190 }
2191 }
2192 }
2193
2194 /* Node coordinate arrays: */
2195
2196 int coord, name_coord, dims[3];
2197 dims[0] = num_dim;
2198 dims[1] = num_nodes;
2199 if( NC_NOERR != nc_def_var( ncFile, "coord", NC_DOUBLE, 2, dims, &coord ) )
2200 {
2201 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define node coordinate array" );
2202 }
2203
2204 /* Coordinate names array */
2205
2206 dims[0] = num_dim;
2207 dims[1] = dim_str;
2208 if( NC_NOERR != nc_def_var( ncFile, "coor_names", NC_CHAR, 2, dims, &name_coord ) )
2209 {
2210 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define coordinate name array" );
2211 }
2212
2213 // Define genesis maps if required
2214
2215 if( write_maps )
2216 {
2217 // Element map
2218 int elem_map = -1, elem_map2 = -1, node_map = -1;
2219 if( NC_NOERR != nc_def_var( ncFile, "elem_map", NC_LONG, 1, &num_elem, &elem_map ) )
2220 {
2221 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to create element map array" ); /* Exit define mode and return */
2222 }
2223
2224 // Create the element number map
2225 if( NC_NOERR != nc_def_var( ncFile, "elem_num_map", NC_LONG, 1, &num_elem, &elem_map2 ) )
2226 {
2227 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to create element numbering map" ); /* Exit define mode
2228 and return */
2229 }
2230
2231 // Create node number map
2232 if( NC_NOERR != nc_def_var( ncFile, "node_num_map", NC_LONG, 1, &num_nodes, &node_map ) )
2233 {
2234 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to create node numbering map array" ); /* Exit define mode and
2235 return */
2236 }
2237 }
2238
2239 // Define qa records to be used
2240
2241 int num_qa_rec = mesh_info.qaRecords.size() / 4;
2242 int num_qa = -1;
2243
2244 if( nc_def_dim( ncFile, "num_qa_rec", (long)num_qa_rec, &num_qa ) != NC_NOERR )
2245 {
2246 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define qa record array size" );
2247 }
2248
2249 // Define qa array
2250 int qa_title;
2251 dims[0] = num_qa;
2252 dims[1] = dim_four;
2253 dims[2] = dim_str;
2254 if( NC_NOERR != nc_def_var( ncFile, "qa_records", NC_CHAR, 3, dims, &qa_title ) )
2255 {
2256 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to define qa record array" );
2257 }
2258
2259 // Take it out of define mode
2260 if( NC_NOERR != nc_enddef( ncFile ) )
2261 {
2262 MB_SET_ERR( MB_FAILURE, "WriteNCDF: Trouble leaving define mode" );
2263 }
2264
2265 return MB_SUCCESS;
2266 }
References moab::Range::begin(), CHAR_STR_LEN, moab::MaterialSetData::element_type, moab::MaterialSetData::elements, moab::ExoIIUtil::ElementTypeNames, moab::Range::end(), ErrorCode, moab::EXOII_POLYGON, moab::EXOII_POLYHEDRON, moab::Interface::get_connectivity(), moab::MaterialSetData::id, moab::DirichletSetData::id, moab::NeumannSetData::id, INS_ID, length(), moab::ExoIIInterface::MAX_STR_LENGTH, MB_CHK_ERR, MB_SET_ERR, MB_SET_ERR_CONT, MB_SUCCESS, mdbImpl, ncFile, moab::WriteNCDF::ExodusMeshInfo::num_dim, moab::WriteNCDF::ExodusMeshInfo::num_elementblocks, moab::WriteNCDF::ExodusMeshInfo::num_elements, moab::WriteNCDF::ExodusMeshInfo::num_nodes, moab::MaterialSetData::number_attributes, moab::MaterialSetData::number_elements, moab::NeumannSetData::number_elements, moab::DirichletSetData::number_nodes, moab::MaterialSetData::number_nodes_per_element, moab::WriteNCDF::ExodusMeshInfo::polyhedronFaces, moab::WriteNCDF::ExodusMeshInfo::qaRecords, repeat_face_blocks, moab::Range::size(), and moab::NeumannSetData::ss_dist_factors.
Referenced by write_header().
|
protected |
number of dimensions in this exo file
open an ExoII file for writing
Definition at line 2268 of file WriteNCDF.cpp.
2269 {
2270 // Not a valid filename
2271 if( strlen( (const char*)filename ) == 0 )
2272 {
2273 MB_SET_ERR( MB_FAILURE, "Output Exodus filename not specified" );
2274 }
2275
2276 int fail = nc_create( filename, NC_CLOBBER, &ncFile );
2277
2278 // File couldn't be opened
2279 if( NC_NOERR != fail )
2280 {
2281 MB_SET_ERR( MB_FAILURE, "Cannot open " << filename );
2282 }
2283
2284 return MB_SUCCESS;
2285 }
References moab::fail(), MB_SET_ERR, MB_SUCCESS, and ncFile.
|
private |
free up allocated Ranges
Definition at line 144 of file WriteNCDF.cpp.
145 {
146 std::vector< MaterialSetData >::iterator iter;
147
148 for( iter = block_info.begin(); iter != block_info.end(); ++iter )
149 {
150 iter->elements.clear();
151 }
152 }
Referenced by write_file().
|
staticprivate |
get the time and date in strings
Definition at line 154 of file WriteNCDF.cpp.
155 {
156 struct tm* local_time;
157 time_t calendar_time;
158
159 calendar_time = time( NULL );
160 local_time = localtime( &calendar_time );
161
162 assert( NULL != time_string && NULL != date_string );
163
164 strftime( time_string, TIME_STR_LEN, "%H:%M:%S", local_time );
165 strftime( date_string, TIME_STR_LEN, "%m/%d/%Y", local_time );
166
167 // Terminate with NULL character
168 time_string[10] = '\0';
169 date_string[10] = '\0';
170 }
References moab::TIME_STR_LEN.
Referenced by write_file(), and write_header().
|
private |
Definition at line 1365 of file WriteNCDF.cpp.
1366 {
1367 unsigned int i, j;
1368 int id;
1369 int ns_index = -1;
1370
1371 for( std::vector< DirichletSetData >::iterator ns_it = nodesets.begin(); ns_it != nodesets.end(); ++ns_it )
1372 {
1373 // Get number of nodes in set
1374 int number_nodes = ( *ns_it ).number_nodes;
1375 if( 0 == number_nodes ) continue;
1376
1377 // If we're here, we have a non-empty nodeset; increment the index
1378 ns_index++;
1379
1380 // Get the node set id
1381 id = ( *ns_it ).id;
1382
1383 // Build new array to old exodus ids
1384 int* exodus_id_array = new int[number_nodes];
1385 double* dist_factor_array = new double[number_nodes];
1386
1387 std::vector< EntityHandle >::iterator begin_iter, end_iter;
1388 std::vector< double >::iterator other_iter;
1389 begin_iter = ( *ns_it ).nodes.begin();
1390 end_iter = ( *ns_it ).nodes.end();
1391 other_iter = ( *ns_it ).node_dist_factors.begin();
1392
1393 j = 0;
1394 int exodus_id;
1395 ErrorCode result;
1396 // Fill up node array and dist. factor array at the same time
1397 for( ; begin_iter != end_iter; ++begin_iter )
1398 {
1399 result = mdbImpl->tag_get_data( mGlobalIdTag, &( *begin_iter ), 1, &exodus_id );MB_CHK_SET_ERR( result, "Problem getting id tag data" );
1400
1401 exodus_id_array[j] = exodus_id;
1402 dist_factor_array[j] = *( other_iter );
1403 ++other_iter;
1404 j++;
1405 }
1406
1407 // Write out the id for the nodeset
1408
1409 int num_values = 1;
1410
1411 result = write_exodus_integer_variable( "ns_prop1", &id, ns_index, num_values );MB_CHK_SET_ERR_RET_VAL( result, "Problem writing node set id " << id, MB_FAILURE );
1412
1413 // Write out the nodeset status
1414
1415 int status = 1;
1416 if( !number_nodes ) status = 0;
1417
1418 result = write_exodus_integer_variable( "ns_status", &status, ns_index, num_values );MB_CHK_SET_ERR_RET_VAL( result, "Problem writing node set status", MB_FAILURE );
1419
1420 // Write it out
1421 char wname[CHAR_STR_LEN];
1422 int nc_var = -1;
1423 std::vector< int > dims;
1424 INS_ID( wname, "node_ns%d", ns_index + 1 );
1425 GET_VAR( wname, nc_var, dims );
1426 if( -1 == nc_var )
1427 {
1428 MB_SET_ERR( MB_FAILURE, "Failed to get node_ns variable" );
1429 }
1430
1431 size_t start = 0, count = number_nodes;
1432 int fail = nc_put_vara_int( ncFile, nc_var, &start, &count, exodus_id_array );
1433 if( NC_NOERR != fail )
1434 {
1435 MB_SET_ERR( MB_FAILURE, "Failed writing exodus id array" );
1436 }
1437
1438 // Write out nodeset distribution factors
1439 INS_ID( wname, "dist_fact_ns%d", ns_index + 1 );
1440 nc_var = -1;
1441 GET_VAR( wname, nc_var, dims );
1442 if( -1 == nc_var )
1443 {
1444 MB_SET_ERR( MB_FAILURE, "Failed to get dist_fact variable" );
1445 }
1446 fail = nc_put_vara_double( ncFile, nc_var, &start, &count, dist_factor_array );
1447 if( NC_NOERR != fail )
1448 {
1449 MB_SET_ERR( MB_FAILURE, "Failed writing dist factor array" );
1450 }
1451
1452 delete[] dist_factor_array;
1453 delete[] exodus_id_array;
1454 }
1455
1456 // Now do sidesets
1457 int ss_index = 0; // Index of sideset - not the same as 'i' because
1458 // only writing non-empty side sets
1459 for( i = 0; i < sidesets.size(); i++ )
1460 {
1461 NeumannSetData sideset_data = sidesets[i];
1462
1463 // Get the side set id
1464 int side_set_id = sideset_data.id;
1465
1466 // Get number of elements in set
1467 int number_elements = sideset_data.number_elements;
1468 if( 0 == number_elements ) continue;
1469
1470 // Build new array to old exodus ids
1471 int* output_element_ids = new int[number_elements];
1472 int* output_element_side_numbers = new int[number_elements];
1473
1474 std::vector< EntityHandle >::iterator begin_iter, end_iter;
1475 begin_iter = sideset_data.elements.begin();
1476 end_iter = sideset_data.elements.end();
1477 std::vector< int >::iterator side_iter = sideset_data.side_numbers.begin();
1478
1479 // Get the tag handle
1480 j = 0;
1481 int exodus_id;
1482
1483 // For each "side"
1484 for( ; begin_iter != end_iter; ++begin_iter, ++side_iter )
1485 {
1486 ErrorCode result = mdbImpl->tag_get_data( mGlobalIdTag, &( *begin_iter ), 1, &exodus_id );MB_CHK_SET_ERR( result, "Problem getting exodus id for sideset element "
1487 << (long unsigned int)ID_FROM_HANDLE( *begin_iter ) );
1488
1489 output_element_ids[j] = exodus_id;
1490 output_element_side_numbers[j++] = *side_iter;
1491 }
1492
1493 if( 0 != number_elements )
1494 {
1495 // Write out the id for the nodeset
1496
1497 int num_values = 1;
1498
1499 // ss_prop1[ss_index] = side_set_id
1500 ErrorCode result = write_exodus_integer_variable( "ss_prop1", &side_set_id, ss_index, num_values );MB_CHK_SET_ERR_RET_VAL( result, "Problem writing node set id " << id, MB_FAILURE );
1501
1502 // FIXME : Something seems wrong here. The we are within a block
1503 // started with if (0 != number_elements), so this condition is always
1504 // false. This code seems to indicate that we want to write all
1505 // sidesets, not just empty ones. But the code both here and in
1506 // initialize_exodus_file() skip empty side sets.
1507 // - j.k. 2007-03-09
1508 int status = 1;
1509 if( 0 == number_elements ) status = 0;
1510
1511 // ss_status[ss_index] = status
1512 result = write_exodus_integer_variable( "ss_status", &status, ss_index, num_values );MB_CHK_SET_ERR_RET_VAL( result, "Problem writing side set status", MB_FAILURE );
1513
1514 // Increment ss_index now because we want a) we need to
1515 // increment it somewhere within the if (0 != number_elements)
1516 // block and b) the above calls need a zero-based index
1517 // while the following use a one-based index.
1518 ++ss_index;
1519
1520 char wname[CHAR_STR_LEN];
1521 int nc_var;
1522 std::vector< int > dims;
1523 INS_ID( wname, "elem_ss%d", ss_index );
1524 GET_VAR( wname, nc_var, dims );
1525 if( -1 == nc_var )
1526 {
1527 MB_SET_ERR( MB_FAILURE, "Failed to get elem_ss variable" );
1528 }
1529 size_t start = 0, count = number_elements;
1530 int fail = nc_put_vara_int( ncFile, nc_var, &start, &count, output_element_ids );
1531 if( NC_NOERR != fail )
1532 {
1533 MB_SET_ERR( MB_FAILURE, "Failed writing sideset element array" );
1534 }
1535
1536 INS_ID( wname, "side_ss%d", ss_index );
1537 nc_var = -1;
1538 GET_VAR( wname, nc_var, dims );
1539 if( -1 == nc_var )
1540 {
1541 MB_SET_ERR( MB_FAILURE, "Failed to get side_ss variable" );
1542 }
1543 fail = nc_put_vara_int( ncFile, nc_var, &start, &count, output_element_side_numbers );
1544 if( NC_NOERR != fail )
1545 {
1546 MB_SET_ERR( MB_FAILURE, "Failed writing sideset side array" );
1547 }
1548
1549 INS_ID( wname, "dist_fact_ss%d", ss_index );
1550 nc_var = -1;
1551 GET_VAR( wname, nc_var, dims );
1552 if( -1 == nc_var )
1553 {
1554 MB_SET_ERR( MB_FAILURE, "Failed to get sideset dist factors variable" );
1555 }
1556 count = sideset_data.ss_dist_factors.size();
1557 fail = nc_put_vara_double( ncFile, nc_var, &start, &count, &( sideset_data.ss_dist_factors[0] ) );
1558 if( NC_NOERR != fail )
1559 {
1560 MB_SET_ERR( MB_FAILURE, "Failed writing sideset dist factors array" );
1561 }
1562 }
1563
1564 delete[] output_element_ids;
1565 delete[] output_element_side_numbers;
1566 }
1567
1568 return MB_SUCCESS;
1569 }
References CHAR_STR_LEN, moab::NeumannSetData::elements, ErrorCode, moab::fail(), GET_VAR, moab::NeumannSetData::id, moab::ID_FROM_HANDLE(), INS_ID, MB_CHK_SET_ERR, MB_CHK_SET_ERR_RET_VAL, MB_SET_ERR, MB_SUCCESS, mdbImpl, mGlobalIdTag, ncFile, moab::NeumannSetData::number_elements, moab::NeumannSetData::side_numbers, moab::NeumannSetData::ss_dist_factors, moab::Interface::tag_get_data(), and write_exodus_integer_variable().
Referenced by write_file().
|
private |
Definition at line 1291 of file WriteNCDF.cpp.
1292 {
1293 // Note: this routine bypasses the standard exodusII interface for efficiency!
1294
1295 // Element order map
1296 int* map = new int[num_elements];
1297
1298 // For now, output a dummy map!
1299
1300 for( int i = 0; i < num_elements; i++ )
1301 {
1302 map[i] = i + 1;
1303 }
1304
1305 // Output array and cleanup
1306
1307 int error = write_exodus_integer_variable( "elem_map", map, 0, num_elements );
1308
1309 if( map ) delete[] map;
1310
1311 if( error < 0 )
1312 {
1313 MB_SET_ERR( MB_FAILURE, "Failed writing element map" );
1314 }
1315
1316 return MB_SUCCESS;
1317 }
References moab::error(), MB_SET_ERR, MB_SUCCESS, and write_exodus_integer_variable().
Referenced by write_file().
|
private |
Definition at line 1037 of file WriteNCDF.cpp.
1038 {
1039 unsigned int i;
1040 int block_index = 0; // Index into block list, may != 1 if there are inactive blocks
1041 int exodus_id = 1;
1042
1043 for( i = 0; i < block_data.size(); i++ )
1044 {
1045 MaterialSetData& block = block_data[i];
1046
1047 unsigned int num_nodes_per_elem = block.number_nodes_per_element;
1048
1049 // Write out the id for the block
1050
1051 int id = block.id;
1052 int num_values = 1;
1053
1054 if( write_exodus_integer_variable( "eb_prop1", &id, block_index, num_values ) != MB_SUCCESS )
1055 {
1056 MB_SET_ERR_CONT( "Problem writing element block id " << id );
1057 }
1058
1059 // Write out the block status
1060
1061 int status = 1;
1062 if( 0 == block.number_elements )
1063 {
1064 MB_SET_ERR( MB_FAILURE, "No elements in block " << id );
1065 }
1066
1067 if( write_exodus_integer_variable( "eb_status", &status, block_index, num_values ) != MB_SUCCESS )
1068 {
1069 MB_SET_ERR( MB_FAILURE, "Problem writing element block status" );
1070 }
1071
1072 //
1073 // Map the connectivity to the new nodes
1074 const unsigned int num_elem = block.number_elements;
1075 unsigned int num_nodes = num_nodes_per_elem * num_elem;
1076 if( EXOII_POLYGON == block.element_type || EXOII_POLYHEDRON == block.element_type )
1077 {
1078 num_nodes = num_nodes_per_elem;
1079 }
1080 int* connectivity = new int[num_nodes];
1081
1082 ErrorCode result = MB_SUCCESS;
1083 if( block.element_type != EXOII_POLYHEDRON )
1084 mWriteIface->get_element_connect( num_elem, num_nodes_per_elem, mGlobalIdTag, block.elements, mGlobalIdTag,
1085 exodus_id, connectivity );
1086 if( result != MB_SUCCESS )
1087 {
1088 delete[] connectivity;
1089 MB_SET_ERR( result, "Couldn't get element array to write from" );
1090 }
1091
1092 // If necessary, convert from EXODUS to CN node order
1093 const EntityType elem_type = ExoIIUtil::ExoIIElementMBEntity[block.element_type];
1094 assert( block.elements.all_of_type( elem_type ) );
1095 const int* reorder = 0;
1096 if( block.element_type != EXOII_POLYHEDRON && block.element_type != EXOII_POLYGON )
1097 reorder = exodus_elem_order_map[elem_type][block.number_nodes_per_element];
1098 if( reorder )
1099 WriteUtilIface::reorder( reorder, connectivity, block.number_elements, block.number_nodes_per_element );
1100
1101 char wname[CHAR_STR_LEN];
1102 int nc_var = -1;
1103 std::vector< int > dims;
1104 if( block.element_type != EXOII_POLYHEDRON )
1105 {
1106 exodus_id += num_elem;
1107 INS_ID( wname, "connect%u", i + 1 );
1108
1109 GET_VAR( wname, nc_var, dims );
1110 if( -1 == nc_var )
1111 {
1112 delete[] connectivity;
1113 MB_SET_ERR( MB_FAILURE, "Couldn't get connectivity variable" );
1114 }
1115 }
1116
1117 if( EXOII_POLYGON == block.element_type )
1118 {
1119 size_t start[1] = { 0 }, count[1] = { num_nodes_per_elem };
1120 int fail = nc_put_vara_int( ncFile, nc_var, start, count, connectivity );
1121 if( NC_NOERR != fail )
1122 {
1123 delete[] connectivity;
1124 MB_SET_ERR( MB_FAILURE, "Couldn't write connectivity variable" );
1125 }
1126 // now put also number ebepecnt1
1127 INS_ID( wname, "ebepecnt%u", i + 1 );
1128 GET_VAR( wname, nc_var, dims );
1129 count[0] = block.number_elements;
1130 start[0] = 0;
1131 // reuse connectivity array, to not allocate another one
1132 int j = 0;
1133 for( Range::iterator eit = block.elements.begin(); eit != block.elements.end(); j++, eit++ )
1134 {
1135 EntityHandle polg = *eit;
1136 int nnodes = 0;
1137 const EntityHandle* conn = NULL;
1138 ErrorCode rval = mdbImpl->get_connectivity( polg, conn, nnodes );MB_CHK_ERR( rval );
1139 connectivity[j] = nnodes;
1140 }
1141 fail = nc_put_vara_int( ncFile, nc_var, start, count, connectivity );
1142 if( NC_NOERR != fail )
1143 {
1144 delete[] connectivity;
1145 MB_SET_ERR( MB_FAILURE, "Couldn't write ebepecnt variable" );
1146 }
1147 }
1148 else if( block.element_type != EXOII_POLYHEDRON )
1149 {
1150 size_t start[2] = { 0, 0 }, count[2] = { num_elem, num_nodes_per_elem };
1151 int fail = nc_put_vara_int( ncFile, nc_var, start, count, connectivity );
1152 if( NC_NOERR != fail )
1153 {
1154 delete[] connectivity;
1155 MB_SET_ERR( MB_FAILURE, "Couldn't write connectivity variable" );
1156 }
1157 }
1158 else // if (block.element_type == EXOII_POLYHEDRON)
1159 {
1160 /* write a lot of stuff // faconn
1161 num_fa_in_blk1 = 15 ;
1162 num_nod_per_fa1 = 58 ;
1163 num_el_in_blk1 = 3 ;
1164 num_fac_per_el1 = 17 ;
1165 int fbconn1(num_nod_per_fa1) ;
1166 fbconn1:elem_type = "nsided" ;
1167 int fbepecnt1(num_fa_in_blk1) ;
1168 fbepecnt1:entity_type1 = "NODE" ;
1169 fbepecnt1:entity_type2 = "FACE" ;
1170 int facconn1(num_fac_per_el1) ;
1171 facconn1:elem_type = "NFACED" ;
1172 int ebepecnt1(num_el_in_blk1) ;
1173 ebepecnt1:entity_type1 = "FACE" ;
1174 ebepecnt1:entity_type2 = "ELEM" ;
1175
1176 */
1177 Range& block_faces = mesh_info.polyhedronFaces;
1178 // ErrorCode rval = mdbImpl->get_connectivity(block.elements, block_faces);
1179 // MB_CHK_ERR(rval);
1180
1181 // reuse now connectivity for facconn1
1182 INS_ID( wname, "facconn%u", i + 1 );
1183 GET_VAR( wname, nc_var, dims ); // fbconn# variable, 1 dimensional
1184
1185 std::vector< int > ebepe( block.elements.size() ); // ebepecnt1
1186 int ixcon = 0, j = 0;
1187 size_t start[1] = { 0 }, count[1] = { 0 };
1188
1189 for( Range::iterator eit = block.elements.begin(); eit != block.elements.end(); eit++ )
1190 {
1191 EntityHandle polyh = *eit;
1192 int nfaces = 0;
1193 const EntityHandle* conn = NULL;
1194 ErrorCode rval = mdbImpl->get_connectivity( polyh, conn, nfaces );MB_CHK_ERR( rval );
1195 for( int k = 0; k < nfaces; k++ )
1196 {
1197 int index = block_faces.index( conn[k] );
1198 if( index == -1 ) MB_SET_ERR( MB_FAILURE, "Couldn't find face in polyhedron" );
1199 connectivity[ixcon++] = index + 1;
1200 }
1201 ebepe[j++] = nfaces;
1202 // num_faces+=nfaces;
1203 }
1204 count[0] = ixcon; // facconn1
1205 int fail = nc_put_vara_int( ncFile, nc_var, start, count, connectivity );
1206 if( NC_NOERR != fail )
1207 {
1208 delete[] connectivity;
1209 MB_SET_ERR( MB_FAILURE, "Couldn't write fbconn variable" );
1210 }
1211
1212 INS_ID( wname, "ebepecnt%u", i + 1 );
1213 GET_VAR( wname, nc_var, dims ); // ebepecnt# variable, 1 dimensional
1214 count[0] = block.elements.size();
1215
1216 fail = nc_put_vara_int( ncFile, nc_var, start, count, &ebepe[0] );
1217 if( NC_NOERR != fail )
1218 {
1219 delete[] connectivity;
1220 MB_SET_ERR( MB_FAILURE, "Couldn't write fbepecnt variable" );
1221 }
1222 }
1223 block_index++;
1224 delete[] connectivity;
1225 }
1226
1227 return MB_SUCCESS;
1228 }
References moab::Range::all_of_type(), moab::Range::begin(), CHAR_STR_LEN, moab::MaterialSetData::element_type, moab::MaterialSetData::elements, moab::Range::end(), ErrorCode, exodus_elem_order_map, moab::EXOII_POLYGON, moab::EXOII_POLYHEDRON, moab::ExoIIUtil::ExoIIElementMBEntity, moab::fail(), moab::Interface::get_connectivity(), moab::WriteUtilIface::get_element_connect(), GET_VAR, moab::MaterialSetData::id, moab::Range::index(), INS_ID, MB_CHK_ERR, MB_SET_ERR, MB_SET_ERR_CONT, MB_SUCCESS, mdbImpl, mGlobalIdTag, mWriteIface, ncFile, moab::MaterialSetData::number_elements, moab::MaterialSetData::number_nodes_per_element, moab::WriteNCDF::ExodusMeshInfo::polyhedronFaces, moab::WriteUtilIface::reorder(), moab::Range::size(), and write_exodus_integer_variable().
Referenced by write_file().
|
private |
Definition at line 1319 of file WriteNCDF.cpp.
1323 {
1324 // Note: this routine bypasses the standard exodusII interface for efficiency!
1325
1326 // Write directly to netcdf interface for efficiency
1327
1328 // Get the variable id of the element map
1329 int nc_var = -1;
1330 std::vector< int > dims;
1331 GET_VAR( variable_name, nc_var, dims );
1332 if( -1 == nc_var )
1333 {
1334 MB_SET_ERR( MB_FAILURE, "WriteNCDF: failed to locate variable " << variable_name << " in file" );
1335 }
1336 // This contortion is necessary because netCDF is expecting nclongs;
1337 // fortunately it's necessary only when ints and nclongs aren't the same size
1338
1339 size_t start[1], count[1];
1340 start[0] = start_position;
1341 count[0] = number_values;
1342
1343 int fail = NC_NOERR;
1344 if( sizeof( int ) == sizeof( long ) )
1345 {
1346 fail = nc_put_vara_int( ncFile, nc_var, start, count, variable_array );
1347 }
1348 else
1349 {
1350 long* lptr = new long[number_values];
1351 for( int jj = 0; jj < number_values; jj++ )
1352 lptr[jj] = variable_array[jj];
1353 fail = nc_put_vara_long( ncFile, nc_var, start, count, lptr );
1354 delete[] lptr;
1355 }
1356
1357 if( NC_NOERR != fail )
1358 {
1359 MB_SET_ERR( MB_FAILURE, "Failed to store variable " << variable_name );
1360 }
1361
1362 return MB_SUCCESS;
1363 }
References moab::fail(), GET_VAR, MB_SET_ERR, MB_SUCCESS, and ncFile.
Referenced by write_BCs(), write_element_order_map(), write_elementblocks(), write_global_element_order_map(), write_global_node_order_map(), and write_poly_faces().
|
virtual |
writes out an ExoII file
Implements moab::WriterIface.
Definition at line 172 of file WriteNCDF.cpp.
181 {
182 assert( 0 != mMaterialSetTag && 0 != mNeumannSetTag && 0 != mDirichletSetTag );
183
184 if( user_dimension == 0 ) mdbImpl->get_dimension( user_dimension );
185
186 if( opts.get_null_option( "REPEAT_FACE_BLOCKS" ) == MB_SUCCESS ) repeat_face_blocks = 1;
187
188 std::vector< EntityHandle > blocks, nodesets, sidesets, entities;
189
190 // Separate into blocks, nodesets, sidesets
191
192 if( num_sets == 0 )
193 {
194 // Default to all defined block, nodeset and sideset-type sets
195 Range this_range;
196 mdbImpl->get_entities_by_type_and_tag( 0, MBENTITYSET, &mMaterialSetTag, NULL, 1, this_range );
197 std::copy( this_range.begin(), this_range.end(), std::back_inserter( blocks ) );
198 this_range.clear();
199 mdbImpl->get_entities_by_type_and_tag( 0, MBENTITYSET, &mDirichletSetTag, NULL, 1, this_range );
200 std::copy( this_range.begin(), this_range.end(), std::back_inserter( nodesets ) );
201 this_range.clear();
202 mdbImpl->get_entities_by_type_and_tag( 0, MBENTITYSET, &mNeumannSetTag, NULL, 1, this_range );
203 std::copy( this_range.begin(), this_range.end(), std::back_inserter( sidesets ) );
204
205 // If there is nothing to write, write everything as one block.
206 if( blocks.empty() && nodesets.empty() && sidesets.empty() )
207 {
208 this_range.clear();
209 for( int d = user_dimension; d > 0 && this_range.empty(); --d )
210 mdbImpl->get_entities_by_dimension( 0, d, this_range, false );
211 if( this_range.empty() ) return MB_FILE_WRITE_ERROR;
212
213 EntityHandle block_handle;
214 int block_id = 1;
215 mdbImpl->create_meshset( MESHSET_SET, block_handle );
216 mdbImpl->tag_set_data( mMaterialSetTag, &block_handle, 1, &block_id );
217 mdbImpl->add_entities( block_handle, this_range );
218 blocks.push_back( block_handle );
219 }
220 }
221 else
222 {
223 int dummy;
224 for( const EntityHandle* iter = ent_handles; iter < ent_handles + num_sets; ++iter )
225 {
226 if( MB_SUCCESS == mdbImpl->tag_get_data( mMaterialSetTag, &( *iter ), 1, &dummy ) && -1 != dummy )
227 blocks.push_back( *iter );
228 else if( MB_SUCCESS == mdbImpl->tag_get_data( mDirichletSetTag, &( *iter ), 1, &dummy ) && -1 != dummy )
229 nodesets.push_back( *iter );
230 else if( MB_SUCCESS == mdbImpl->tag_get_data( mNeumannSetTag, &( *iter ), 1, &dummy ) && -1 != dummy )
231 sidesets.push_back( *iter );
232 }
233 }
234
235 // If there is nothing to write just return.
236 if( blocks.empty() && nodesets.empty() && sidesets.empty() ) return MB_FILE_WRITE_ERROR;
237
238 // Try to get mesh information
239 ExodusMeshInfo mesh_info;
240
241 std::vector< MaterialSetData > block_info;
242 std::vector< NeumannSetData > sideset_info;
243 std::vector< DirichletSetData > nodeset_info;
244
245 mesh_info.num_dim = user_dimension;
246
247 if( qa_records.empty() )
248 {
249 // qa records are empty - initialize some MB-standard ones
250 mesh_info.qaRecords.push_back( "MB" );
251 mesh_info.qaRecords.push_back( "0.99" );
252 char string1[80], string2[80];
253 time_and_date( string2, string1 );
254 mesh_info.qaRecords.push_back( string2 );
255 mesh_info.qaRecords.push_back( string1 );
256 }
257 else
258 {
259 // Constrained to multiples of 4 qa records
260 assert( qa_records.size() % 4 == 0 );
261
262 std::copy( qa_records.begin(), qa_records.end(), std::back_inserter( mesh_info.qaRecords ) );
263 }
264
265 block_info.clear();
266 if( gather_mesh_information( mesh_info, block_info, sideset_info, nodeset_info, blocks, sidesets, nodesets ) !=
267 MB_SUCCESS )
268 {
269 reset_block( block_info );
270 return MB_FAILURE;
271 }
272
273 // Try to open the file after gather mesh info succeeds
274 int fail = nc_create( exodus_file_name, overwrite ? NC_CLOBBER : NC_NOCLOBBER, &ncFile );
275 if( NC_NOERR != fail )
276 {
277 reset_block( block_info );
278 return MB_FAILURE;
279 }
280
281 if( write_header( mesh_info, block_info, sideset_info, nodeset_info, exodus_file_name ) != MB_SUCCESS )
282 {
283 reset_block( block_info );
284 return MB_FAILURE;
285 }
286
287 {
288 // write dummy time_whole
289 double timev = 0.0; // dummy, to make paraview happy
290 size_t start = 0, count = 1;
291 int nc_var;
292 std::vector< int > dims;
293 GET_VAR( "time_whole", nc_var, dims );
294 fail = nc_put_vara_double( ncFile, nc_var, &start, &count, &timev );
295 if( NC_NOERR != fail )
296 {
297 MB_SET_ERR( MB_FAILURE, "Failed writing dist factor array" );
298 }
299 }
300
301 if( write_nodes( mesh_info.num_nodes, mesh_info.nodes, mesh_info.num_dim ) != MB_SUCCESS )
302 {
303 reset_block( block_info );
304 return MB_FAILURE;
305 }
306
307 if( !mesh_info.polyhedronFaces.empty() )
308 {
309 if( write_poly_faces( mesh_info ) != MB_SUCCESS )
310 {
311 reset_block( block_info );
312 return MB_FAILURE;
313 }
314 }
315
316 if( write_elementblocks( mesh_info, block_info ) )
317 {
318 reset_block( block_info );
319 return MB_FAILURE;
320 }
321
322 // Write the three maps
323 if( write_global_node_order_map( mesh_info.num_nodes, mesh_info.nodes ) != MB_SUCCESS )
324 {
325 reset_block( block_info );
326 return MB_FAILURE;
327 }
328
329 if( write_global_element_order_map( mesh_info.num_elements ) != MB_SUCCESS )
330 {
331 reset_block( block_info );
332 return MB_FAILURE;
333 }
334
335 if( write_element_order_map( mesh_info.num_elements ) != MB_SUCCESS )
336 {
337 reset_block( block_info );
338 return MB_FAILURE;
339 }
340
341 /*
342 if (write_elementmap(mesh_info) != MB_SUCCESS)
343 return MB_FAILURE;
344 */
345
346 if( write_BCs( sideset_info, nodeset_info ) != MB_SUCCESS )
347 {
348 reset_block( block_info );
349 return MB_FAILURE;
350 }
351
352 if( write_qa_records( mesh_info.qaRecords ) != MB_SUCCESS ) return MB_FAILURE;
353
354 // Copy the qa records into the argument
355 // mesh_info.qaRecords.swap(qa_records);
356 // Close the file
357 fail = nc_close( ncFile );
358 if( NC_NOERR != fail )
359 {
360 MB_SET_ERR( MB_FAILURE, "Trouble closing file" );
361 }
362
363 return MB_SUCCESS;
364 }
References moab::Interface::add_entities(), moab::Range::begin(), moab::Range::clear(), moab::Interface::create_meshset(), moab::Range::empty(), moab::Range::end(), entities, moab::fail(), gather_mesh_information(), moab::Interface::get_dimension(), moab::Interface::get_entities_by_dimension(), moab::Interface::get_entities_by_type_and_tag(), moab::FileOptions::get_null_option(), GET_VAR, MB_FILE_WRITE_ERROR, MB_SET_ERR, MB_SUCCESS, MBENTITYSET, mdbImpl, mDirichletSetTag, MESHSET_SET, mMaterialSetTag, mNeumannSetTag, ncFile, moab::WriteNCDF::ExodusMeshInfo::nodes, moab::WriteNCDF::ExodusMeshInfo::num_dim, moab::WriteNCDF::ExodusMeshInfo::num_elements, moab::WriteNCDF::ExodusMeshInfo::num_nodes, moab::WriteNCDF::ExodusMeshInfo::polyhedronFaces, moab::WriteNCDF::ExodusMeshInfo::qaRecords, repeat_face_blocks, reset_block(), moab::Interface::tag_get_data(), moab::Interface::tag_set_data(), time_and_date(), write_BCs(), write_element_order_map(), write_elementblocks(), write_global_element_order_map(), write_global_node_order_map(), write_header(), write_nodes(), write_poly_faces(), and write_qa_records().
|
private |
Definition at line 1265 of file WriteNCDF.cpp.
1266 {
1267 // Allocate map array
1268 int* map = new int[num_elements];
1269
1270 // Many Sandia codes assume this map is unique, and CUBIT does not currently
1271 // have unique ids for all elements. Therefore, to make sure nothing crashes,
1272 // insert a dummy map...
1273
1274 for( int i = 0; i < num_elements; i++ )
1275 map[i] = i + 1;
1276
1277 // Output array and cleanup
1278
1279 int error = write_exodus_integer_variable( "elem_num_map", map, 0, num_elements );
1280
1281 if( map ) delete[] map;
1282
1283 if( error < 0 )
1284 {
1285 MB_SET_ERR( MB_FAILURE, "Failed writing global element order map" );
1286 }
1287
1288 return MB_SUCCESS;
1289 }
References moab::error(), MB_SET_ERR, MB_SUCCESS, and write_exodus_integer_variable().
Referenced by write_file().
Definition at line 1230 of file WriteNCDF.cpp.
1231 {
1232 // Note: this routine bypasses the standard exodusII interface for efficiency!
1233
1234 // Node order map
1235 int* map = new int[num_nodes];
1236
1237 // For now, output a dummy map!
1238
1239 Range::iterator range_iter, end_iter;
1240 range_iter = nodes.begin();
1241 end_iter = nodes.end();
1242
1243 int i = 0;
1244
1245 for( ; range_iter != end_iter; ++range_iter )
1246 {
1247 // TODO -- do we really want to cast this to an int?
1248 map[i++] = (int)ID_FROM_HANDLE( *range_iter );
1249 }
1250
1251 // Output array and cleanup
1252
1253 int error = write_exodus_integer_variable( "node_num_map", map, 0, num_nodes );
1254
1255 if( map ) delete[] map;
1256
1257 if( error < 0 )
1258 {
1259 MB_SET_ERR( MB_FAILURE, "Failed writing global node order map" );
1260 }
1261
1262 return MB_SUCCESS;
1263 }
References moab::Range::begin(), moab::Range::end(), moab::error(), moab::ID_FROM_HANDLE(), MB_SET_ERR, MB_SUCCESS, and write_exodus_integer_variable().
Referenced by write_file().
|
private |
Definition at line 1006 of file WriteNCDF.cpp.
1011 {
1012 // Get the date and time
1013 char time[TIME_STR_LEN];
1014 char date[TIME_STR_LEN];
1015 time_and_date( time, date );
1016
1017 std::string title_string = "MOAB";
1018 title_string.append( "(" );
1019 title_string.append( filename );
1020 title_string.append( "): " );
1021 title_string.append( date );
1022 title_string.append( ": " );
1023 title_string.append( "time " );
1024
1025 if( title_string.length() > ExoIIInterface::MAX_LINE_LENGTH )
1026 title_string.resize( ExoIIInterface::MAX_LINE_LENGTH );
1027
1028 // Initialize the exodus file
1029
1030 int result = initialize_exodus_file( mesh_info, block_info, sideset_info, nodeset_info, title_string.c_str() );
1031
1032 if( result == MB_FAILURE ) return MB_FAILURE;
1033
1034 return MB_SUCCESS;
1035 }
References initialize_exodus_file(), moab::ExoIIInterface::MAX_LINE_LENGTH, MB_SUCCESS, time_and_date(), and moab::TIME_STR_LEN.
Referenced by write_file().
Definition at line 801 of file WriteNCDF.cpp.
802 {
803 // Write coordinates names
804 int nc_var = -1;
805 std::vector< int > dims;
806 GET_VAR( "coor_names", nc_var, dims );
807 if( -1 == nc_var )
808 {
809 MB_SET_ERR( MB_FAILURE, "Trouble getting coordinate name variable" );
810 }
811
812 size_t start[2] = { 0, 0 }, count[2] = { 1, ExoIIInterface::MAX_STR_LENGTH };
813 char dum_str[ExoIIInterface::MAX_STR_LENGTH];
814 strcpy( dum_str, "x" );
815 int fail = nc_put_vara_text( ncFile, nc_var, start, count, dum_str );
816 if( NC_NOERR != fail )
817 {
818 MB_SET_ERR( MB_FAILURE, "Trouble adding x coordinate name; netcdf message: " << nc_strerror( fail ) );
819 }
820
821 start[0] = 1;
822 strcpy( dum_str, "y" );
823 fail = nc_put_vara_text( ncFile, nc_var, start, count, dum_str );
824 if( NC_NOERR != fail )
825 {
826 MB_SET_ERR( MB_FAILURE, "Trouble adding y coordinate name; netcdf message: " << nc_strerror( fail ) );
827 }
828
829 start[0] = 2;
830 strcpy( dum_str, "z" );
831 fail = nc_put_vara_text( ncFile, nc_var, start, count, dum_str );
832 if( NC_NOERR != fail )
833 {
834 MB_SET_ERR( MB_FAILURE, "Trouble adding z coordinate name; netcdf message: " << nc_strerror( fail ) );
835 }
836
837 // See if should transform coordinates
838 ErrorCode result;
839 Tag trans_tag;
840 result = mdbImpl->tag_get_handle( MESH_TRANSFORM_TAG_NAME, 16, MB_TYPE_DOUBLE, trans_tag );
841 bool transform_needed = true;
842 if( result == MB_TAG_NOT_FOUND ) transform_needed = false;
843
844 int num_coords_to_fill = transform_needed ? 3 : dimension;
845
846 std::vector< double* > coord_arrays( 3 );
847 coord_arrays[0] = new double[num_nodes];
848 coord_arrays[1] = new double[num_nodes];
849 coord_arrays[2] = NULL;
850
851 if( num_coords_to_fill == 3 ) coord_arrays[2] = new double[num_nodes];
852
853 result = mWriteIface->get_node_coords( dimension, num_nodes, nodes, mGlobalIdTag, 1, coord_arrays );
854 if( result != MB_SUCCESS )
855 {
856 delete[] coord_arrays[0];
857 delete[] coord_arrays[1];
858 if( coord_arrays[2] ) delete[] coord_arrays[2];
859 return result;
860 }
861
862 if( transform_needed )
863 {
864 double trans_matrix[16];
865 const EntityHandle mesh = 0;
866 result = mdbImpl->tag_get_data( trans_tag, &mesh, 0, trans_matrix );MB_CHK_SET_ERR( result, "Couldn't get transform data" );
867
868 for( int i = 0; i < num_nodes; i++ )
869 {
870 double vec1[3];
871 double vec2[3];
872
873 vec2[0] = coord_arrays[0][i];
874 vec2[1] = coord_arrays[1][i];
875 vec2[2] = coord_arrays[2][i];
876
877 for( int row = 0; row < 3; row++ )
878 {
879 vec1[row] = 0.0;
880 for( int col = 0; col < 3; col++ )
881 vec1[row] += ( trans_matrix[( row * 4 ) + col] * vec2[col] );
882 }
883
884 coord_arrays[0][i] = vec1[0];
885 coord_arrays[1][i] = vec1[1];
886 coord_arrays[2][i] = vec1[2];
887 }
888 }
889
890 // Write the nodes
891 nc_var = -1;
892 GET_VAR( "coord", nc_var, dims );
893 if( -1 == nc_var )
894 {
895 MB_SET_ERR( MB_FAILURE, "Trouble getting coordinate variable" );
896 }
897 start[0] = 0;
898 count[1] = num_nodes;
899 fail = nc_put_vara_double( ncFile, nc_var, start, count, &( coord_arrays[0][0] ) );
900 if( NC_NOERR != fail )
901 {
902 MB_SET_ERR( MB_FAILURE, "Trouble writing x coordinate" );
903 }
904
905 start[0] = 1;
906 fail = nc_put_vara_double( ncFile, nc_var, start, count, &( coord_arrays[1][0] ) );
907 if( NC_NOERR != fail )
908 {
909 MB_SET_ERR( MB_FAILURE, "Trouble writing y coordinate" );
910 }
911
912 start[0] = 2;
913 fail = nc_put_vara_double( ncFile, nc_var, start, count, &( coord_arrays[2][0] ) );
914 if( NC_NOERR != fail )
915 {
916 MB_SET_ERR( MB_FAILURE, "Trouble writing z coordinate" );
917 }
918
919 delete[] coord_arrays[0];
920 delete[] coord_arrays[1];
921 if( coord_arrays[2] ) delete[] coord_arrays[2];
922
923 return MB_SUCCESS;
924 }
References ErrorCode, moab::fail(), moab::WriteUtilIface::get_node_coords(), GET_VAR, moab::ExoIIInterface::MAX_STR_LENGTH, MB_CHK_SET_ERR, MB_SET_ERR, MB_SUCCESS, MB_TAG_NOT_FOUND, MB_TYPE_DOUBLE, mdbImpl, MESH_TRANSFORM_TAG_NAME, mGlobalIdTag, mWriteIface, ncFile, moab::Interface::tag_get_data(), and moab::Interface::tag_get_handle().
Referenced by write_file().
|
private |
Definition at line 926 of file WriteNCDF.cpp.
927 {
928 // write all polygons that are not in another element block;
929 // usually they are nowhere else, but be sure, write in this block only ones that are not in the
930 // other blocks
931 Range pfaces = mesh_info.polyhedronFaces;
932
933 /*
934 * int fbconn1(num_nod_per_fa1) ;
935 fbconn1:elem_type = "nsided" ;
936 int fbepecnt1(num_fa_in_blk1) ;
937 fbepecnt1:entity_type1 = "NODE" ;
938 fbepecnt1:entity_type2 = "FACE" ;
939 */
940 if( pfaces.empty() ) return MB_SUCCESS;
941 char wname[CHAR_STR_LEN];
942 int nc_var = -1;
943 std::vector< int > dims;
944
945 // write one for each element block, to make paraview and visit happy
946 int num_faces_in_block = (int)pfaces.size();
947 for( unsigned int bl = 0; bl < mesh_info.num_polyhedra_blocks; bl++ )
948 {
949 INS_ID( wname, "fbconn%u", bl + 1 ); // it is the first block
950 GET_VAR( wname, nc_var, dims ); // fbconn# variable, 1 dimensional
951
952 INS_ID( wname, "num_nod_per_fa%u", bl + 1 );
953 int ncdim, num_nod_per_face;
954 GET_DIM( ncdim, wname, num_nod_per_face );
955 int* connectivity = new int[num_nod_per_face];
956 int ixcon = 0, j = 0;
957 std::vector< int > fbepe( num_faces_in_block ); // fbepecnt1
958 for( Range::iterator eit = pfaces.begin(); eit != pfaces.end(); eit++ )
959 {
960 EntityHandle polyg = *eit;
961 int nnodes = 0;
962 const EntityHandle* conn = NULL;
963 ErrorCode rval = mdbImpl->get_connectivity( polyg, conn, nnodes );MB_CHK_ERR( rval );
964 for( int k = 0; k < nnodes; k++ )
965 connectivity[ixcon++] = conn[k];
966 fbepe[j++] = nnodes;
967 }
968 size_t start[1] = { 0 }, count[1] = { 0 };
969 count[0] = ixcon;
970 int fail = nc_put_vara_int( ncFile, nc_var, start, count, connectivity );
971 if( NC_NOERR != fail )
972 {
973 delete[] connectivity;
974 MB_SET_ERR( MB_FAILURE, "Couldn't write fbconn variable" );
975 }
976
977 INS_ID( wname, "fbepecnt%u", bl + 1 );
978 GET_VAR( wname, nc_var, dims ); // fbconn# variable, 1 dimensional
979 count[0] = num_faces_in_block;
980
981 fail = nc_put_vara_int( ncFile, nc_var, start, count, &fbepe[0] );
982 if( NC_NOERR != fail )
983 {
984 delete[] connectivity;
985 MB_SET_ERR( MB_FAILURE, "Couldn't write fbepecnt variable" );
986 }
987
988 int id = bl + 1;
989 if( write_exodus_integer_variable( "fa_prop1", &id, bl, 1 ) != MB_SUCCESS )
990 {
991 MB_SET_ERR_CONT( "Problem writing element block id " << id );
992 }
993
994 int status = 1;
995 if( write_exodus_integer_variable( "fa_status", &status, bl, 1 ) != MB_SUCCESS )
996 {
997 MB_SET_ERR( MB_FAILURE, "Problem writing face block status" );
998 }
999
1000 delete[] connectivity;
1001 if( 0 == repeat_face_blocks ) break; // do not repeat face blocks
1002 }
1003
1004 return MB_SUCCESS;
1005 }
References moab::Range::begin(), CHAR_STR_LEN, moab::Range::empty(), moab::Range::end(), ErrorCode, moab::fail(), moab::Interface::get_connectivity(), GET_DIM, GET_VAR, INS_ID, MB_CHK_ERR, MB_SET_ERR, MB_SET_ERR_CONT, MB_SUCCESS, mdbImpl, ncFile, moab::WriteNCDF::ExodusMeshInfo::num_polyhedra_blocks, moab::WriteNCDF::ExodusMeshInfo::polyhedronFaces, repeat_face_blocks, moab::Range::size(), and write_exodus_integer_variable().
Referenced by write_file().
|
private |
Definition at line 757 of file WriteNCDF.cpp.
758 {
759 int i = 0;
760
761 for( std::vector< std::string >::iterator string_it = qa_record_list.begin(); string_it != qa_record_list.end(); )
762 {
763 for( int j = 0; j < 4; j++ )
764 write_qa_string( ( *string_it++ ).c_str(), i, j );
765 i++;
766 }
767
768 return MB_SUCCESS;
769 }
References MB_SUCCESS, and write_qa_string().
Referenced by write_file().
|
private |
Definition at line 771 of file WriteNCDF.cpp.
772 {
773 // Get the variable id in the exodus file
774
775 std::vector< int > dims;
776 int temp_var = -1;
777 GET_VAR( "qa_records", temp_var, dims );
778 if( -1 == temp_var )
779 {
780 MB_SET_ERR( MB_FAILURE, "WriteNCDF:: Problem getting qa record variable" );
781 }
782 size_t count[3], start[3];
783
784 // Write out the record
785 start[0] = record_number;
786 start[1] = record_position;
787 start[2] = 0;
788
789 count[0] = 1;
790 count[1] = 1;
791 count[2] = (long)strlen( string ) + 1;
792 int fail = nc_put_vara_text( ncFile, temp_var, start, count, string );
793 if( NC_NOERR != fail )
794 {
795 MB_SET_ERR( MB_FAILURE, "Failed to position qa string variable" );
796 }
797
798 return MB_SUCCESS;
799 }
References moab::fail(), GET_VAR, MB_SET_ERR, MB_SUCCESS, and ncFile.
Referenced by write_qa_records().
|
private |
file name
Definition at line 135 of file WriteNCDF.hpp.
|
private |
Meshset Handle for the mesh that is currently being read.
Definition at line 139 of file WriteNCDF.hpp.
|
private |
interface instance
Definition at line 131 of file WriteNCDF.hpp.
Referenced by gather_mesh_information(), get_sideset_elems(), get_valid_sides(), initialize_exodus_file(), write_BCs(), write_elementblocks(), write_file(), write_nodes(), write_poly_faces(), and ~WriteNCDF().
|
private |
Definition at line 144 of file WriteNCDF.hpp.
Referenced by gather_mesh_information(), write_file(), and WriteNCDF().
|
private |
Definition at line 148 of file WriteNCDF.hpp.
Referenced by gather_mesh_information(), get_valid_sides(), and WriteNCDF().
|
private |
Definition at line 152 of file WriteNCDF.hpp.
Referenced by gather_mesh_information(), get_valid_sides(), WriteNCDF(), and ~WriteNCDF().
|
private |
Definition at line 147 of file WriteNCDF.hpp.
|
private |
Definition at line 149 of file WriteNCDF.hpp.
Referenced by write_BCs(), write_elementblocks(), write_nodes(), and WriteNCDF().
|
private |
Definition at line 146 of file WriteNCDF.hpp.
Referenced by WriteNCDF().
|
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().
|
private |
Definition at line 145 of file WriteNCDF.hpp.
Referenced by gather_mesh_information(), write_file(), and WriteNCDF().
|
private |
Definition at line 150 of file WriteNCDF.hpp.
Referenced by gather_mesh_information(), and WriteNCDF().
|
private |
Definition at line 132 of file WriteNCDF.hpp.
Referenced by gather_mesh_information(), write_elementblocks(), write_nodes(), WriteNCDF(), and ~WriteNCDF().
|
private |
Definition at line 136 of file WriteNCDF.hpp.
Referenced by initialize_exodus_file(), open_file(), write_BCs(), write_elementblocks(), write_exodus_integer_variable(), write_file(), write_nodes(), write_poly_faces(), write_qa_string(), and ~WriteNCDF().
|
private |
Definition at line 154 of file WriteNCDF.hpp.
Referenced by initialize_exodus_file(), write_file(), and write_poly_faces().