20 #pragma warning( disable : 4786 )
46 #ifndef MOAB_HAVE_NETCDF
47 #error Attempt to compile WriteNCDF with NetCDF support disabled
50 #define CHAR_STR_LEN 128
57 #define INS_ID( stringvar, prefix, id ) snprintf( stringvar, CHAR_STR_LEN, prefix, id )
59 #define GET_DIM( ncdim, name, val ) \
61 int gdfail = nc_inq_dimid( ncFile, name, &( ncdim ) ); \
62 if( NC_NOERR == gdfail ) \
65 gdfail = nc_inq_dimlen( ncFile, ncdim, &tmp_val ); \
66 if( NC_NOERR != gdfail ) \
68 MB_SET_ERR( MB_FAILURE, "WriteNCDF:: couldn't get dimension length" ); \
77 #define GET_DIMB( ncdim, name, varname, id, val ) \
78 INS_ID( name, CHAR_STR_LEN, varname, id ); \
79 GET_DIM( ncdim, name, val );
81 #define GET_VAR( name, id, dims ) \
84 int gvfail = nc_inq_varid( ncFile, name, &( id ) ); \
85 if( NC_NOERR == gvfail ) \
88 gvfail = nc_inq_varndims( ncFile, id, &ndims ); \
89 if( NC_NOERR == gvfail ) \
91 ( dims ).resize( ndims ); \
92 gvfail = nc_inq_vardimid( ncFile, id, &( dims )[0] ); \
103 : mdbImpl( impl ),
ncFile( 0 ), mCurrentMeshHandle( 0 ), mGeomDimensionTag( 0 ), repeat_face_blocks( 0 )
105 assert( impl != NULL );
123 int dum_val_array[] = { -1, -1, -1, -1 };
146 std::vector< MaterialSetData >::iterator iter;
148 for( iter = block_info.begin(); iter != block_info.end(); ++iter )
150 iter->elements.clear();
156 struct tm* local_time;
157 time_t calendar_time;
159 calendar_time = time( NULL );
160 local_time = localtime( &calendar_time );
162 assert( NULL != time_string && NULL != date_string );
164 strftime( time_string,
TIME_STR_LEN,
"%H:%M:%S", local_time );
165 strftime( date_string,
TIME_STR_LEN,
"%m/%d/%Y", local_time );
168 time_string[10] =
'\0';
169 date_string[10] =
'\0';
173 const bool overwrite,
177 const std::vector< std::string >& qa_records,
188 std::vector< EntityHandle > blocks, nodesets, sidesets,
entities;
197 std::copy( this_range.
begin(), this_range.
end(), std::back_inserter( blocks ) );
200 std::copy( this_range.
begin(), this_range.
end(), std::back_inserter( nodesets ) );
203 std::copy( this_range.
begin(), this_range.
end(), std::back_inserter( sidesets ) );
206 if( blocks.empty() && nodesets.empty() && sidesets.empty() )
209 for(
int d = user_dimension; d > 0 && this_range.
empty(); --d )
218 blocks.push_back( block_handle );
224 for(
const EntityHandle* iter = ent_handles; iter < ent_handles + num_sets; ++iter )
227 blocks.push_back( *iter );
229 nodesets.push_back( *iter );
231 sidesets.push_back( *iter );
241 std::vector< MaterialSetData > block_info;
242 std::vector< NeumannSetData > sideset_info;
243 std::vector< DirichletSetData > nodeset_info;
245 mesh_info.
num_dim = user_dimension;
247 if( qa_records.empty() )
252 char string1[80], string2[80];
254 mesh_info.
qaRecords.push_back( string2 );
255 mesh_info.
qaRecords.push_back( string1 );
260 assert( qa_records.size() % 4 == 0 );
262 std::copy( qa_records.begin(), qa_records.end(), std::back_inserter( mesh_info.
qaRecords ) );
266 if(
gather_mesh_information( mesh_info, block_info, sideset_info, nodeset_info, blocks, sidesets, nodesets ) !=
274 int fail = nc_create( exodus_file_name, overwrite ? NC_CLOBBER : NC_NOCLOBBER, &
ncFile );
275 if( NC_NOERR !=
fail )
290 size_t start = 0, count = 1;
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 )
297 MB_SET_ERR( MB_FAILURE,
"Failed writing dist factor array" );
358 if( NC_NOERR !=
fail )
360 MB_SET_ERR( MB_FAILURE,
"Trouble closing file" );
367 std::vector< MaterialSetData >& block_info,
368 std::vector< NeumannSetData >& sideset_info,
369 std::vector< DirichletSetData >& nodeset_info,
370 std::vector< EntityHandle >& blocks,
371 std::vector< EntityHandle >& sidesets,
372 std::vector< EntityHandle >& nodesets )
375 std::vector< EntityHandle >::iterator vector_iter, end_vector_iter;
384 vector_iter = blocks.begin();
385 end_vector_iter = blocks.end();
387 std::vector< EntityHandle > parent_meshsets;
395 int highest_dimension_of_element_blocks = 0;
397 for( vector_iter = blocks.begin(); vector_iter != blocks.end(); ++vector_iter )
410 if( dummy_range.
empty() )
continue;
415 MB_SET_ERR( MB_FAILURE,
"Couldn't get block id from a tag for an element block" );
438 MB_SET_ERR( MB_FAILURE,
"Entities in block " <<
id <<
" not of common type" );
442 if( entity_type ==
MBQUAD || entity_type ==
MBTRI )
444 else if( entity_type ==
MBEDGE )
449 if( dimension > highest_dimension_of_element_blocks ) highest_dimension_of_element_blocks = dimension;
451 std::vector< EntityHandle > tmp_conn;
458 MB_SET_ERR( MB_FAILURE,
"Element type in block " <<
id <<
" didn't get set correctly" );
495 if( !sidesets.empty() )
500 unsigned char bit = 0x1;
506 block_info.push_back( block_data );
508 const void* data = NULL;
513 const char* qa_rec =
static_cast< const char*
>( data );
516 for(
int i = 0; i <
size; i++ )
518 if( qa_rec[i] ==
'\0' )
520 std::string qa_string( &qa_rec[start], i - start );
521 mesh_info.
qaRecords.push_back( qa_string );
528 if( count > 0 ) assert( count % 4 == 0 );
534 for( std::vector< MaterialSetData >::iterator blit = block_info.begin(); blit != block_info.end(); blit++ )
547 if( highest_dimension_of_element_blocks < 2 )
550 mesh_info.
num_dim = highest_dimension_of_element_blocks;
555 end_range_iter = mesh_info.
nodes.
end();
561 vector_iter = nodesets.begin();
562 end_vector_iter = nodesets.end();
564 for( ; vector_iter != end_vector_iter; ++vector_iter )
573 MB_SET_ERR( MB_FAILURE,
"Couldn't get id tag for nodeset " <<
id );
576 nodeset_data.
id = id;
578 std::vector< EntityHandle > node_vector;
582 MB_SET_ERR( MB_FAILURE,
"Couldn't get nodes in nodeset " <<
id );
586 const double* dist_factor_vector;
587 int dist_factor_size;
590 int has_dist_factors = 0;
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();
601 unsigned char node_marked = 0;
603 for( ; iter != end_iter; ++iter )
608 if( 0x1 == node_marked )
610 nodeset_data.
nodes.push_back( *iter );
611 if( 0 != has_dist_factors )
620 nodeset_info.push_back( nodeset_data );
624 vector_iter = sidesets.begin();
625 end_vector_iter = sidesets.end();
627 for( ; vector_iter != end_vector_iter; ++vector_iter )
634 sideset_data.
id = id;
639 Range forward_elems, reverse_elems;
640 if(
get_sideset_elems( *vector_iter, 0, forward_elems, reverse_elems ) == MB_FAILURE )
return MB_FAILURE;
646 sideset_info.push_back( sideset_data );
660 const double* dist_factor_vector = 0;
661 int dist_factor_size = 0;
664 const double* dist_fac_iter = 0;
666 bool has_dist_factors =
false;
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 );
677 unsigned char element_marked = 0;
684 if( 0x1 == element_marked )
686 sideset_data.
elements.push_back( *iter );
689 sideset_data.
side_numbers.push_back( ( sense == 1 ? 1 : 2 ) );
693 std::vector< EntityHandle > parents;
702 fprintf(stderr,
"[Warning]: Couldn't get adjacencies for sideset.\n");
706 if( !parents.empty() )
709 for(
unsigned int k = 0; k < parents.size(); k++ )
713 int side_no, this_sense, this_offset;
714 if( 0x1 == element_marked &&
716 this_sense == sense )
718 sideset_data.
elements.push_back( parents[k] );
729 fprintf(stderr,
"[Warning]: No parent element exists for element in sideset %i\n", sideset_data.
id);
734 if( sideset_data.
elements.size() != 0 )
740 if( has_dist_factors )
742 std::copy( dist_fac_iter, dist_fac_iter + num_nodes,
744 dist_fac_iter += num_nodes;
748 for(
int j = 0; j < num_nodes; j++ )
761 for( std::vector< std::string >::iterator string_it = qa_record_list.begin(); string_it != qa_record_list.end(); )
763 for(
int j = 0; j < 4; j++ )
775 std::vector< int > dims;
777 GET_VAR(
"qa_records", temp_var, dims );
780 MB_SET_ERR( MB_FAILURE,
"WriteNCDF:: Problem getting qa record variable" );
782 size_t count[3], start[3];
785 start[0] = record_number;
786 start[1] = record_position;
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 )
795 MB_SET_ERR( MB_FAILURE,
"Failed to position qa string variable" );
805 std::vector< int > dims;
806 GET_VAR(
"coor_names", nc_var, dims );
809 MB_SET_ERR( MB_FAILURE,
"Trouble getting coordinate name variable" );
814 strcpy( dum_str,
"x" );
815 int fail = nc_put_vara_text(
ncFile, nc_var, start, count, dum_str );
816 if( NC_NOERR !=
fail )
818 MB_SET_ERR( MB_FAILURE,
"Trouble adding x coordinate name; netcdf message: " << nc_strerror(
fail ) );
822 strcpy( dum_str,
"y" );
823 fail = nc_put_vara_text(
ncFile, nc_var, start, count, dum_str );
824 if( NC_NOERR !=
fail )
826 MB_SET_ERR( MB_FAILURE,
"Trouble adding y coordinate name; netcdf message: " << nc_strerror(
fail ) );
830 strcpy( dum_str,
"z" );
831 fail = nc_put_vara_text(
ncFile, nc_var, start, count, dum_str );
832 if( NC_NOERR !=
fail )
834 MB_SET_ERR( MB_FAILURE,
"Trouble adding z coordinate name; netcdf message: " << nc_strerror(
fail ) );
841 bool transform_needed =
true;
844 int num_coords_to_fill = transform_needed ? 3 : dimension;
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;
851 if( num_coords_to_fill == 3 ) coord_arrays[2] =
new double[num_nodes];
856 delete[] coord_arrays[0];
857 delete[] coord_arrays[1];
858 if( coord_arrays[2] )
delete[] coord_arrays[2];
862 if( transform_needed )
864 double trans_matrix[16];
868 for(
int i = 0; i < num_nodes; i++ )
873 vec2[0] = coord_arrays[0][i];
874 vec2[1] = coord_arrays[1][i];
875 vec2[2] = coord_arrays[2][i];
877 for(
int row = 0; row < 3; row++ )
880 for(
int col = 0; col < 3; col++ )
881 vec1[row] += ( trans_matrix[( row * 4 ) + col] * vec2[col] );
884 coord_arrays[0][i] = vec1[0];
885 coord_arrays[1][i] = vec1[1];
886 coord_arrays[2][i] = vec1[2];
892 GET_VAR(
"coord", nc_var, dims );
895 MB_SET_ERR( MB_FAILURE,
"Trouble getting coordinate variable" );
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 )
902 MB_SET_ERR( MB_FAILURE,
"Trouble writing x coordinate" );
906 fail = nc_put_vara_double(
ncFile, nc_var, start, count, &( coord_arrays[1][0] ) );
907 if( NC_NOERR !=
fail )
909 MB_SET_ERR( MB_FAILURE,
"Trouble writing y coordinate" );
913 fail = nc_put_vara_double(
ncFile, nc_var, start, count, &( coord_arrays[2][0] ) );
914 if( NC_NOERR !=
fail )
916 MB_SET_ERR( MB_FAILURE,
"Trouble writing z coordinate" );
919 delete[] coord_arrays[0];
920 delete[] coord_arrays[1];
921 if( coord_arrays[2] )
delete[] coord_arrays[2];
943 std::vector< int > dims;
946 int num_faces_in_block = (int)pfaces.
size();
949 INS_ID( wname,
"fbconn%u", bl + 1 );
950 GET_VAR( wname, nc_var, dims );
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 );
964 for(
int k = 0; k < nnodes; k++ )
965 connectivity[ixcon++] = conn[k];
968 size_t start[1] = { 0 }, count[1] = { 0 };
970 int fail = nc_put_vara_int(
ncFile, nc_var, start, count, connectivity );
971 if( NC_NOERR !=
fail )
973 delete[] connectivity;
974 MB_SET_ERR( MB_FAILURE,
"Couldn't write fbconn variable" );
977 INS_ID( wname,
"fbepecnt%u", bl + 1 );
978 GET_VAR( wname, nc_var, dims );
979 count[0] = num_faces_in_block;
981 fail = nc_put_vara_int(
ncFile, nc_var, start, count, &fbepe[0] );
982 if( NC_NOERR !=
fail )
984 delete[] connectivity;
985 MB_SET_ERR( MB_FAILURE,
"Couldn't write fbepecnt variable" );
997 MB_SET_ERR( MB_FAILURE,
"Problem writing face block status" );
1000 delete[] connectivity;
1007 std::vector< MaterialSetData >& block_info,
1008 std::vector< NeumannSetData >& sideset_info,
1009 std::vector< DirichletSetData >& nodeset_info,
1010 const char* filename )
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 " );
1030 int result =
initialize_exodus_file( mesh_info, block_info, sideset_info, nodeset_info, title_string.c_str() );
1032 if( result == MB_FAILURE )
return MB_FAILURE;
1040 int block_index = 0;
1043 for( i = 0; i < block_data.size(); i++ )
1064 MB_SET_ERR( MB_FAILURE,
"No elements in block " <<
id );
1069 MB_SET_ERR( MB_FAILURE,
"Problem writing element block status" );
1075 unsigned int num_nodes = num_nodes_per_elem * num_elem;
1078 num_nodes = num_nodes_per_elem;
1080 int* connectivity =
new int[num_nodes];
1085 exodus_id, connectivity );
1088 delete[] connectivity;
1089 MB_SET_ERR( result,
"Couldn't get element array to write from" );
1095 const int* reorder = 0;
1103 std::vector< int > dims;
1106 exodus_id += num_elem;
1107 INS_ID( wname,
"connect%u", i + 1 );
1109 GET_VAR( wname, nc_var, dims );
1112 delete[] connectivity;
1113 MB_SET_ERR( MB_FAILURE,
"Couldn't get connectivity variable" );
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 )
1123 delete[] connectivity;
1124 MB_SET_ERR( MB_FAILURE,
"Couldn't write connectivity variable" );
1127 INS_ID( wname,
"ebepecnt%u", i + 1 );
1128 GET_VAR( wname, nc_var, dims );
1139 connectivity[j] = nnodes;
1141 fail = nc_put_vara_int(
ncFile, nc_var, start, count, connectivity );
1142 if( NC_NOERR !=
fail )
1144 delete[] connectivity;
1145 MB_SET_ERR( MB_FAILURE,
"Couldn't write ebepecnt variable" );
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 )
1154 delete[] connectivity;
1155 MB_SET_ERR( MB_FAILURE,
"Couldn't write connectivity variable" );
1182 INS_ID( wname,
"facconn%u", i + 1 );
1183 GET_VAR( wname, nc_var, dims );
1186 int ixcon = 0, j = 0;
1187 size_t start[1] = { 0 }, count[1] = { 0 };
1195 for(
int k = 0; k < nfaces; k++ )
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;
1201 ebepe[j++] = nfaces;
1205 int fail = nc_put_vara_int(
ncFile, nc_var, start, count, connectivity );
1206 if( NC_NOERR !=
fail )
1208 delete[] connectivity;
1209 MB_SET_ERR( MB_FAILURE,
"Couldn't write fbconn variable" );
1212 INS_ID( wname,
"ebepecnt%u", i + 1 );
1213 GET_VAR( wname, nc_var, dims );
1216 fail = nc_put_vara_int(
ncFile, nc_var, start, count, &ebepe[0] );
1217 if( NC_NOERR !=
fail )
1219 delete[] connectivity;
1220 MB_SET_ERR( MB_FAILURE,
"Couldn't write fbepecnt variable" );
1224 delete[] connectivity;
1235 int* map =
new int[num_nodes];
1240 range_iter = nodes.
begin();
1241 end_iter = nodes.
end();
1245 for( ; range_iter != end_iter; ++range_iter )
1255 if( map )
delete[] map;
1259 MB_SET_ERR( MB_FAILURE,
"Failed writing global node order map" );
1268 int* map =
new int[num_elements];
1274 for(
int i = 0; i < num_elements; i++ )
1281 if( map )
delete[] map;
1285 MB_SET_ERR( MB_FAILURE,
"Failed writing global element order map" );
1296 int* map =
new int[num_elements];
1300 for(
int i = 0; i < num_elements; i++ )
1309 if( map )
delete[] map;
1313 MB_SET_ERR( MB_FAILURE,
"Failed writing element map" );
1320 int* variable_array,
1330 std::vector< int > dims;
1331 GET_VAR( variable_name, nc_var, dims );
1334 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to locate variable " << variable_name <<
" in file" );
1339 size_t start[1], count[1];
1340 start[0] = start_position;
1341 count[0] = number_values;
1343 int fail = NC_NOERR;
1344 if(
sizeof(
int ) ==
sizeof(
long ) )
1346 fail = nc_put_vara_int(
ncFile, nc_var, start, count, variable_array );
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 );
1357 if( NC_NOERR !=
fail )
1359 MB_SET_ERR( MB_FAILURE,
"Failed to store variable " << variable_name );
1371 for( std::vector< DirichletSetData >::iterator ns_it = nodesets.begin(); ns_it != nodesets.end(); ++ns_it )
1374 int number_nodes = ( *ns_it ).number_nodes;
1375 if( 0 == number_nodes )
continue;
1384 int* exodus_id_array =
new int[number_nodes];
1385 double* dist_factor_array =
new double[number_nodes];
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();
1397 for( ; begin_iter != end_iter; ++begin_iter )
1401 exodus_id_array[j] = exodus_id;
1402 dist_factor_array[j] = *( other_iter );
1416 if( !number_nodes ) status = 0;
1423 std::vector< int > dims;
1424 INS_ID( wname,
"node_ns%d", ns_index + 1 );
1425 GET_VAR( wname, nc_var, dims );
1428 MB_SET_ERR( MB_FAILURE,
"Failed to get node_ns variable" );
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 )
1435 MB_SET_ERR( MB_FAILURE,
"Failed writing exodus id array" );
1439 INS_ID( wname,
"dist_fact_ns%d", ns_index + 1 );
1441 GET_VAR( wname, nc_var, dims );
1444 MB_SET_ERR( MB_FAILURE,
"Failed to get dist_fact variable" );
1446 fail = nc_put_vara_double(
ncFile, nc_var, &start, &count, dist_factor_array );
1447 if( NC_NOERR !=
fail )
1449 MB_SET_ERR( MB_FAILURE,
"Failed writing dist factor array" );
1452 delete[] dist_factor_array;
1453 delete[] exodus_id_array;
1459 for( i = 0; i < sidesets.size(); i++ )
1464 int side_set_id = sideset_data.
id;
1468 if( 0 == number_elements )
continue;
1471 int* output_element_ids =
new int[number_elements];
1472 int* output_element_side_numbers =
new int[number_elements];
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();
1484 for( ; begin_iter != end_iter; ++begin_iter, ++side_iter )
1489 output_element_ids[j] = exodus_id;
1490 output_element_side_numbers[j++] = *side_iter;
1493 if( 0 != number_elements )
1509 if( 0 == number_elements ) status = 0;
1522 std::vector< int > dims;
1523 INS_ID( wname,
"elem_ss%d", ss_index );
1524 GET_VAR( wname, nc_var, dims );
1527 MB_SET_ERR( MB_FAILURE,
"Failed to get elem_ss variable" );
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 )
1533 MB_SET_ERR( MB_FAILURE,
"Failed writing sideset element array" );
1536 INS_ID( wname,
"side_ss%d", ss_index );
1538 GET_VAR( wname, nc_var, dims );
1541 MB_SET_ERR( MB_FAILURE,
"Failed to get side_ss variable" );
1543 fail = nc_put_vara_int(
ncFile, nc_var, &start, &count, output_element_side_numbers );
1544 if( NC_NOERR !=
fail )
1546 MB_SET_ERR( MB_FAILURE,
"Failed writing sideset side array" );
1549 INS_ID( wname,
"dist_fact_ss%d", ss_index );
1551 GET_VAR( wname, nc_var, dims );
1554 MB_SET_ERR( MB_FAILURE,
"Failed to get sideset dist factors variable" );
1558 if( NC_NOERR !=
fail )
1560 MB_SET_ERR( MB_FAILURE,
"Failed writing sideset dist factors array" );
1564 delete[] output_element_ids;
1565 delete[] output_element_side_numbers;
1572 std::vector< MaterialSetData >& block_data,
1573 std::vector< NeumannSetData >& sideset_data,
1574 std::vector< DirichletSetData >& nodeset_data,
1575 const char* title_string,
1597 int element_block_index;
1601 int dim_str, dim_four, dim_line, dim_time;
1604 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to get string length in file" );
1609 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to get line length in file" );
1612 if( nc_def_dim(
ncFile,
"four", 4, &dim_four ) != NC_NOERR )
1614 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to locate four in file" );
1617 if( nc_def_dim(
ncFile,
"time_step", 1, &dim_time ) != NC_NOERR )
1619 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to locate time step in file" );
1623 if( NC_NOERR != nc_def_var(
ncFile,
"time_whole", NC_DOUBLE, 1, &dim_time, &dtime ) )
1625 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to define time whole array" );
1637 char working_title[80];
1638 strncpy( working_title, title_string, 79 );
1640 int length = strlen( working_title );
1641 for(
int pos = 0; pos <
length; pos++ )
1643 if( working_title[pos] ==
'\\' ) working_title[pos] =
'/';
1646 if( NC_NOERR != nc_put_att_text(
ncFile, NC_GLOBAL,
"title",
length, working_title ) )
1648 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to define title attribute" );
1652 float dum_vers = 6.28F;
1653 if( NC_NOERR != nc_put_att_float(
ncFile, NC_GLOBAL,
"api_version", NC_FLOAT, 1, &dum_vers ) )
1655 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to define api_version attribute" );
1658 if( NC_NOERR != nc_put_att_float(
ncFile, NC_GLOBAL,
"version", NC_FLOAT, 1, &dum_vers ) )
1660 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to define version attribute" );
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 ) )
1665 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to define floating pt word size attribute" );
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 )
1673 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to define number of dimensions" );
1676 if( nc_def_dim(
ncFile,
"num_nodes", mesh_info.
num_nodes, &num_nodes ) != NC_NOERR )
1678 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to define number of nodes" );
1686 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to define number of nodes" );
1689 if( nc_def_dim(
ncFile,
"num_elem", mesh_info.
num_elements, &num_elem ) != NC_NOERR )
1691 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to define number of elements" );
1696 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to define number of element blocks" );
1703 if( NC_NOERR != nc_def_var(
ncFile,
"eb_status", NC_LONG, 1, &num_el_blk, &idstat ) )
1705 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to define element block status array" );
1711 if( NC_NOERR != nc_def_var(
ncFile,
"eb_prop1", NC_LONG, 1, &num_el_blk, &idarr ) )
1713 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to define element block id array" );
1717 if( NC_NOERR != nc_put_att_text(
ncFile, idarr,
"name", strlen(
"ID" ),
"ID" ) )
1719 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to store element block property name ID" );
1723 int num_fa_blocks = 0;
1724 for(
unsigned int i = 0; i < block_data.size(); i++ )
1736 if( num_fa_blocks > 0 )
1739 if( nc_def_dim(
ncFile,
"num_fa_blk", num_fa_blocks, &num_fa_blk ) != NC_NOERR )
1741 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to define number of face blocks" );
1745 if( NC_NOERR != nc_def_var(
ncFile,
"fa_status", NC_LONG, 1, &num_fa_blk, &idstatf ) )
1747 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to define face block status array" );
1753 if( NC_NOERR != nc_def_var(
ncFile,
"fa_prop1", NC_LONG, 1, &num_fa_blk, &idarrf ) )
1755 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to define face block id array" );
1759 if( NC_NOERR != nc_put_att_text(
ncFile, idarrf,
"name", strlen(
"ID" ),
"ID" ) )
1761 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to store face block property name ID" );
1775 int num_nodes_per_face = 0;
1784 num_nodes_per_face += nnodes;
1788 for(
int j = 1; j <= num_fa_blocks; j++ )
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 )
1793 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to define number of nodes for face block " );
1795 dims[0] = num_nod_per_fa;
1796 INS_ID( wname,
"fbconn%d", j );
1798 if( NC_NOERR != nc_def_var(
ncFile, wname, NC_LONG, 1, dims, &fbconn ) )
1800 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to create connectivity array for face block " << 1 );
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() ) )
1806 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to store element type nsided " );
1809 INS_ID( wname,
"num_fa_in_blk%d", j );
1813 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to define number of nodes for face block " );
1817 INS_ID( wname,
"fbepecnt%d", j );
1819 dims[0] = num_fa_in_blk;
1820 if( NC_NOERR != nc_def_var(
ncFile, wname, NC_LONG, 1, dims, &fbepecnt ) )
1822 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to create fbepecnt array for block " << 1 );
1824 std::string enttype1(
"NODE" );
1825 if( NC_NOERR != nc_put_att_text(
ncFile, fbepecnt,
"entity_type1", enttype1.length(), enttype1.c_str() ) )
1827 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to store entity type 1 " );
1829 std::string enttype2(
"FACE" );
1830 if( NC_NOERR != nc_put_att_text(
ncFile, fbepecnt,
"entity_type2", enttype2.length(), enttype2.c_str() ) )
1832 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to store entity type 2 " );
1839 for(
unsigned int i = 0; i < block_data.size(); i++ )
1843 element_block_index = i + 1;
1844 int num_el_in_blk = -1, num_att_in_blk = -1;
1845 int blk_attrib, connect;
1849 INS_ID( wname,
"num_el_in_blk%d", element_block_index );
1852 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to define number of elements/block for block " << i + 1 );
1856 INS_ID( wname,
"num_nod_per_el%d", element_block_index );
1857 int num_nod_per_el = -1;
1861 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to define number of nodes/element for block " << block.
id );
1868 INS_ID( wname,
"num_att_in_blk%d", element_block_index );
1871 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to define number of attributes in block " << block.
id );
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 ) )
1879 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to define attributes for element block " << block.
id );
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 ) )
1892 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to create connectivity array for block " << i + 1 );
1898 if( NC_NOERR != nc_put_att_text(
ncFile, connect,
"elem_type", element_type_string.length(),
1899 element_type_string.c_str() ) )
1906 INS_ID( wname,
"connect%d", element_block_index );
1915 dims[0] = num_nod_per_el;
1916 if( NC_NOERR != nc_def_var(
ncFile, wname, NC_LONG, 1, dims, &connect ) )
1918 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to create connectivity array for block " << i + 1 );
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() ) )
1926 INS_ID( wname,
"ebepecnt%d", element_block_index );
1928 dims[0] = num_el_in_blk;
1929 if( NC_NOERR != nc_def_var(
ncFile, wname, NC_LONG, 1, dims, &ebepecnt ) )
1931 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to create ebepecnt array for block " << i + 1 );
1933 std::string etype1(
"NODE" );
1934 if( NC_NOERR != nc_put_att_text(
ncFile, ebepecnt,
"entity_type1", etype1.length(), etype1.c_str() ) )
1938 std::string etype2(
"ELEM" );
1939 if( NC_NOERR != nc_put_att_text(
ncFile, ebepecnt,
"entity_type2", etype2.length(), etype2.c_str() ) )
1968 num_faces2 += nfaces;
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 )
1976 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to define number of faces per block " << block.
id );
1988 INS_ID( wname,
"facconn%d", element_block_index );
1990 dims[0] = num_fac_per_el;
1991 if( NC_NOERR != nc_def_var(
ncFile, wname, NC_LONG, 1, dims, &facconn ) )
1993 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to create facconn array for block " << i + 1 );
1995 std::string etype(
"NFACED" );
1996 if( NC_NOERR != nc_put_att_text(
ncFile, facconn,
"elem_type", etype.length(), etype.c_str() ) )
2002 INS_ID( wname,
"ebepecnt%d", element_block_index );
2004 dims[0] = num_el_in_blk;
2005 if( NC_NOERR != nc_def_var(
ncFile, wname, NC_LONG, 1, dims, &ebepecnt ) )
2007 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to create ebepecnt array for block " << i + 1 );
2009 std::string etype1(
"FACE" );
2010 if( NC_NOERR != nc_put_att_text(
ncFile, ebepecnt,
"entity_type1", etype1.length(), etype1.c_str() ) )
2014 std::string etype2(
"ELEM" );
2015 if( NC_NOERR != nc_put_att_text(
ncFile, ebepecnt,
"entity_type2", etype2.length(), etype2.c_str() ) )
2026 int non_empty_nss = 0;
2028 std::vector< DirichletSetData >::iterator ns_it;
2029 for( ns_it = nodeset_data.begin(); ns_it != nodeset_data.end(); ++ns_it )
2031 if( 0 != ( *ns_it ).number_nodes ) non_empty_nss++;
2035 int ns_idstat = -1, ns_idarr = -1;
2036 if( non_empty_nss > 0 )
2038 if( nc_def_dim(
ncFile,
"num_node_sets", (
size_t)( non_empty_nss ), &num_ns ) != NC_NOERR )
2040 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to define number of node sets" );
2045 if( NC_NOERR != nc_def_var(
ncFile,
"ns_status", NC_LONG, 1, &num_ns, &ns_idstat ) )
2047 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to create node sets status array" );
2051 if( NC_NOERR != nc_def_var(
ncFile,
"ns_prop1", NC_LONG, 1, &num_ns, &ns_idarr ) )
2053 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to create node sets property array" );
2057 if( NC_NOERR != nc_put_att_text(
ncFile, NC_GLOBAL,
"name", strlen(
"ID" ),
"ID" ) )
2059 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to store node set property name ID" );
2066 for(
unsigned i = 0; i < nodeset_data.size(); i++ )
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 )
2081 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to define number of nodes for set " << node_set.
id );
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 ) )
2089 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to create node set " << node_set.
id <<
" node list" );
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 ) )
2098 "WriteNCDF: failed to create node set " << node_set.
id <<
" distribution factor list" );
2105 long non_empty_ss = 0;
2107 std::vector< NeumannSetData >::iterator ss_it;
2108 for( ss_it = sideset_data.begin(); ss_it != sideset_data.end(); ++ss_it )
2110 if( 0 != ( *ss_it ).number_elements ) non_empty_ss++;
2113 if( non_empty_ss > 0 )
2116 if( nc_def_dim(
ncFile,
"num_side_sets", non_empty_ss, &num_ss ) != NC_NOERR )
2118 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to define number of side sets" );
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 ) )
2125 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to define side set status" );
2129 if( NC_NOERR != nc_def_var(
ncFile,
"ss_prop1", NC_LONG, 1, &num_ss, &ss_idarr ) )
2131 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to define side set property" );
2135 if( NC_NOERR != nc_put_att_text(
ncFile, ss_idarr,
"name", strlen(
"ID" ),
"ID" ) )
2137 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to store side set property name ID" );
2143 for(
unsigned int i = 0; i < sideset_data.size(); i++ )
2152 int num_side_ss = -1;
2153 int elem_ss = -1, side_ss = -1;
2154 INS_ID( wname,
"num_side_ss%d", index );
2157 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to define number of sides in side set " << side_set.
id );
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 ) )
2163 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to create element list for side set "
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 ) )
2169 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to create side list for side set "
2175 INS_ID( wname,
"num_df_ss%d", index );
2178 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to define number of dist factors in side set "
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 ) )
2188 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to create dist factors list for side set "
2196 int coord, name_coord, dims[3];
2198 dims[1] = num_nodes;
2199 if( NC_NOERR != nc_def_var(
ncFile,
"coord", NC_DOUBLE, 2, dims, &coord ) )
2201 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to define node coordinate array" );
2208 if( NC_NOERR != nc_def_var(
ncFile,
"coor_names", NC_CHAR, 2, dims, &name_coord ) )
2210 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to define coordinate name array" );
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 ) )
2221 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to create element map array" );
2225 if( NC_NOERR != nc_def_var(
ncFile,
"elem_num_map", NC_LONG, 1, &num_elem, &elem_map2 ) )
2227 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to create element numbering map" );
2232 if( NC_NOERR != nc_def_var(
ncFile,
"node_num_map", NC_LONG, 1, &num_nodes, &node_map ) )
2234 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to create node numbering map array" );
2241 int num_qa_rec = mesh_info.
qaRecords.size() / 4;
2244 if( nc_def_dim(
ncFile,
"num_qa_rec", (
long)num_qa_rec, &num_qa ) != NC_NOERR )
2246 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to define qa record array size" );
2254 if( NC_NOERR != nc_def_var(
ncFile,
"qa_records", NC_CHAR, 3, dims, &qa_title ) )
2256 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: failed to define qa record array" );
2260 if( NC_NOERR != nc_enddef(
ncFile ) )
2262 MB_SET_ERR( MB_FAILURE,
"WriteNCDF: Trouble leaving define mode" );
2271 if( strlen( (
const char*)filename ) == 0 )
2273 MB_SET_ERR( MB_FAILURE,
"Output Exodus filename not specified" );
2276 int fail = nc_create( filename, NC_CLOBBER, &
ncFile );
2279 if( NC_NOERR !=
fail )
2281 MB_SET_ERR( MB_FAILURE,
"Cannot open " << filename );
2289 Range& forward_elems,
2290 Range& reverse_elems )
2292 Range ss_elems, ss_meshsets;
2301 if( MB_FAILURE == result )
return result;
2309 if( range_iter != ss_elems.
end() )
2312 ss_elems.
erase( range_iter, ss_elems.
end() );
2322 dum_it = ss_elems.
begin();
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 )
2332 for( range_iter = ss_meshsets.
begin(); range_iter != ss_meshsets.
end(); ++range_iter )
2336 if( 0 == sense_tag || MB_FAILURE ==
mdbImpl->
tag_get_data( sense_tag, &( *range_iter ), 1, &this_sense ) )
2340 get_sideset_elems( *range_iter, this_sense * current_sense, forward_elems, reverse_elems );