20 #pragma warning( disable : 4786 )
45 #ifndef MOAB_HAVE_NETCDF
46 #error Attempt to compile WriteSLAC with NetCDF disabled.
52 #define INS_ID( stringvar, prefix, id ) sprintf( stringvar, prefix, id )
54 #define GET_VAR( name, id, dims ) \
57 int gvfail = nc_inq_varid( ncFile, name, &( id ) ); \
58 if( NC_NOERR == gvfail ) \
61 gvfail = nc_inq_varndims( ncFile, id, &ndims ); \
62 if( NC_NOERR == gvfail ) \
64 ( dims ).resize( ndims ); \
65 gvfail = nc_inq_vardimid( ncFile, id, &( dims )[0] ); \
77 assert( impl != NULL );
109 std::vector< WriteSLAC::MaterialSetData >::iterator iter;
111 for( iter = matset_info.begin(); iter != matset_info.end(); ++iter )
112 delete( *iter ).elements;
116 const bool overwrite,
120 const std::vector< std::string >& ,
128 if( NULL == strstr( file_name,
".ncdf" ) )
return MB_FAILURE;
130 std::vector< EntityHandle > matsets, dirsets, neusets,
entities;
141 std::copy( this_range.
begin(), this_range.
end(), std::back_inserter( matsets ) );
144 std::copy( this_range.
begin(), this_range.
end(), std::back_inserter( dirsets ) );
147 std::copy( this_range.
begin(), this_range.
end(), std::back_inserter( neusets ) );
152 for(
const EntityHandle* iter = ent_handles; iter < ent_handles + num_sets; ++iter )
155 matsets.push_back( *iter );
157 dirsets.push_back( *iter );
159 neusets.push_back( *iter );
166 std::vector< WriteSLAC::MaterialSetData > matset_info;
167 std::vector< WriteSLAC::DirichletSetData > dirset_info;
168 std::vector< WriteSLAC::NeumannSetData > neuset_info;
181 int fail = nc_create( file_name, overwrite ? NC_CLOBBER : NC_NOCLOBBER, &
ncFile );
182 if( NC_NOERR !=
fail )
207 if( NC_NOERR !=
fail )
return MB_FAILURE;
213 std::vector< WriteSLAC::MaterialSetData >& matset_info,
214 std::vector< WriteSLAC::NeumannSetData >& neuset_info,
215 std::vector< WriteSLAC::DirichletSetData >& dirset_info,
216 std::vector< EntityHandle >& matsets,
217 std::vector< EntityHandle >& neusets,
218 std::vector< EntityHandle >& dirsets )
220 std::vector< EntityHandle >::iterator vector_iter, end_vector_iter;
228 vector_iter = matsets.begin();
229 end_vector_iter = matsets.end();
233 std::vector< EntityHandle > parent_meshsets;
239 int highest_dimension_of_element_matsets = 0;
241 for( vector_iter = matsets.begin(); vector_iter != matsets.end(); ++vector_iter )
257 entity_iter = dummy_range.
end();
260 entity_iter = dummy_range.
begin();
264 if( entity_iter != dummy_range.
end() )
273 MB_SET_ERR( MB_FAILURE,
"Couldn't get matset id from a tag for an element matset" );
287 --end_elem_range_iter;
290 MB_SET_ERR( MB_FAILURE,
"Entities in matset " <<
id <<
" not of common type" );
294 if( entity_type ==
MBQUAD || entity_type ==
MBTRI )
296 else if( entity_type ==
MBEDGE )
301 if( dimension > highest_dimension_of_element_matsets ) highest_dimension_of_element_matsets = dimension;
306 std::vector< EntityHandle > tmp_conn;
313 MB_SET_ERR( MB_FAILURE,
"Element type in matset " <<
id <<
" didn't get set correctly" );
327 if( !neusets.empty() )
332 unsigned char bit = 0x1;
337 matset_info.push_back( matset_data );
344 if( highest_dimension_of_element_matsets < 2 )
347 mesh_info.
num_dim = highest_dimension_of_element_matsets;
352 end_range_iter = mesh_info.
nodes.
end();
358 vector_iter = dirsets.begin();
359 end_vector_iter = dirsets.end();
361 for( ; vector_iter != end_vector_iter; ++vector_iter )
370 MB_SET_ERR( MB_FAILURE,
"Couldn't get id tag for dirset " <<
id );
375 std::vector< EntityHandle > node_vector;
379 MB_SET_ERR( MB_FAILURE,
"Couldn't get nodes in dirset " <<
id );
382 std::vector< EntityHandle >::iterator iter, end_iter;
383 iter = node_vector.begin();
384 end_iter = node_vector.end();
387 unsigned char node_marked = 0;
389 for( ; iter != end_iter; ++iter )
394 if( 0x1 == node_marked ) dirset_data.
nodes.push_back( *iter );
399 dirset_info.push_back( dirset_data );
403 vector_iter = neusets.begin();
404 end_vector_iter = neusets.end();
406 for( ; vector_iter != end_vector_iter; ++vector_iter )
418 Range forward_elems, reverse_elems;
419 if(
get_neuset_elems( *vector_iter, 0, forward_elems, reverse_elems ) == MB_FAILURE )
return MB_FAILURE;
425 neuset_info.push_back( neuset_data );
436 unsigned char element_marked = 0;
443 if( 0x1 == element_marked )
445 neuset_data.
elements.push_back( *iter );
448 neuset_data.
side_numbers.push_back( ( sense == 1 ? 1 : 2 ) );
452 std::vector< EntityHandle > parents;
458 MB_SET_ERR( MB_FAILURE,
"Couldn't get adjacencies for neuset" );
461 if( !parents.empty() )
464 for(
unsigned int k = 0; k < parents.size(); k++ )
468 int side_no, this_sense, this_offset;
469 if( 0x1 == element_marked &&
471 this_sense == sense )
473 neuset_data.
elements.push_back( parents[k] );
481 MB_SET_ERR( MB_FAILURE,
"No parent element exists for element in neuset " << neuset_data.
id );
495 bool transform_needed =
true;
498 int num_coords_to_fill = transform_needed ? 3 : dimension;
500 std::vector< double* > coord_arrays( 3 );
501 coord_arrays[0] =
new double[num_nodes];
502 coord_arrays[1] =
new double[num_nodes];
503 coord_arrays[2] = NULL;
505 if( num_coords_to_fill == 3 ) coord_arrays[2] =
new double[num_nodes];
510 delete[] coord_arrays[0];
511 delete[] coord_arrays[1];
512 if( coord_arrays[2] )
delete[] coord_arrays[2];
516 if( transform_needed )
518 double trans_matrix[16];
522 for(
int i = 0; i < num_nodes; i++ )
527 vec2[0] = coord_arrays[0][i];
528 vec2[1] = coord_arrays[1][i];
529 vec2[2] = coord_arrays[2][i];
531 for(
int row = 0; row < 3; row++ )
534 for(
int col = 0; col < 3; col++ )
535 vec1[row] += ( trans_matrix[( row * 4 ) + col] * vec2[col] );
538 coord_arrays[0][i] = vec1[0];
539 coord_arrays[1][i] = vec1[1];
540 coord_arrays[2][i] = vec1[2];
546 std::vector< int > dims;
547 GET_VAR(
"coords", nc_var, dims );
548 if( -1 == nc_var )
return MB_FAILURE;
549 size_t start[2] = { 0, 0 }, count[2] = {
static_cast< size_t >( num_nodes ), 1 };
550 int fail = nc_put_vara_double(
ncFile, nc_var, start, count, coord_arrays[0] );
551 if( NC_NOERR !=
fail )
return MB_FAILURE;
553 fail = nc_put_vara_double(
ncFile, nc_var, start, count, coord_arrays[1] );
554 if( NC_NOERR !=
fail )
return MB_FAILURE;
556 fail = nc_put_vara_double(
ncFile, nc_var, start, count, coord_arrays[2] );
557 if( NC_NOERR !=
fail )
return MB_FAILURE;
559 delete[] coord_arrays[0];
560 delete[] coord_arrays[1];
561 if( coord_arrays[2] )
delete[] coord_arrays[2];
567 std::vector< WriteSLAC::MaterialSetData >& matset_data,
568 std::vector< WriteSLAC::NeumannSetData >& neuset_data )
581 for( i = 0; i < matset_data.size(); i++ )
604 std::vector< EntityHandle >::iterator vit;
605 for( i = 0; i < neuset_data.size(); i++ )
626 std::vector< WriteSLAC::MaterialSetData >& matset_data,
627 std::vector< WriteSLAC::NeumannSetData >& neuset_data )
630 std::vector< int > connect;
637 std::vector< int > dims;
640 GET_VAR(
"hexahedron_interior", hex_conn, dims );
641 if( -1 == hex_conn )
return MB_FAILURE;
643 connect.reserve( 13 );
648 size_t start[2] = { 0, 0 }, count[2] = { 1, 1 };
650 for( i = 0; i < matset_data.size(); i++ )
652 matset = matset_data[i];
672 start[0] = elem_num++;
676 fail = nc_put_vara_int(
ncFile, hex_conn, start, count, &connect[0] );
677 if( NC_NOERR !=
fail )
return MB_FAILURE;
684 GET_VAR(
"tetrahedron_interior", tet_conn, dims );
685 if( -1 == tet_conn )
return MB_FAILURE;
690 for( i = 0; i < matset_data.size(); i++ )
692 matset = matset_data[i];
712 start[0] = elem_num++;
714 fail = nc_put_vara_int(
ncFile, tet_conn, start, count, &connect[0] );
716 if( NC_NOERR !=
fail )
return MB_FAILURE;
724 GET_VAR(
"hexahedron_exterior", hex_conn, dims );
725 if( -1 == hex_conn )
return MB_FAILURE;
727 connect.reserve( 15 );
746 for( i = 9; i < 15; i++ )
750 for( i = 0; i < neuset_data.size(); i++ )
752 std::vector< EntityHandle >::iterator vit =
753 std::find( neuset_data[i].elements.begin(), neuset_data[i].elements.end(), *rit );
754 while( vit != neuset_data[i].elements.end() )
757 int side_no = neuset_data[i].side_numbers[vit - neuset_data[i].elements.begin()];
758 connect[9 + side_no] = neuset_data[i].id;
760 vit = std::find( vit, neuset_data[i].elements.end(), *rit );
765 start[0] = elem_num++;
767 fail = nc_put_vara_int(
ncFile, hex_conn, start, count, &connect[0] );
769 if( NC_NOERR !=
fail )
return MB_FAILURE;
777 GET_VAR(
"tetrahedron_exterior", tet_conn, dims );
778 if( -1 == tet_conn )
return MB_FAILURE;
780 connect.reserve( 9 );
799 for( i = 5; i < 9; i++ )
803 for( i = 0; i < neuset_data.size(); i++ )
805 std::vector< EntityHandle >::iterator vit =
806 std::find( neuset_data[i].elements.begin(), neuset_data[i].elements.end(), *rit );
807 while( vit != neuset_data[i].elements.end() )
810 int side_no = neuset_data[i].side_numbers[vit - neuset_data[i].elements.begin()];
811 connect[5 + side_no] = neuset_data[i].id;
813 vit = std::find( vit, neuset_data[i].elements.end(), *rit );
818 start[0] = elem_num++;
820 fail = nc_put_vara_int(
ncFile, tet_conn, start, count, &connect[0] );
822 if( NC_NOERR !=
fail )
return MB_FAILURE;
833 int coord_size = -1, ncoords = -1;
835 int hexinterior = -1, hexinteriorsize, hexexterior = -1, hexexteriorsize = -1;
836 int tetinterior = -1, tetinteriorsize, tetexterior = -1, tetexteriorsize = -1;
838 if( nc_def_dim(
ncFile,
"coord_size", (
size_t)mesh_info.
num_dim, &coord_size ) != NC_NOERR )
840 MB_SET_ERR( MB_FAILURE,
"WriteSLAC: failed to define number of dimensions" );
843 if( nc_def_dim(
ncFile,
"ncoords", (
size_t)mesh_info.
num_nodes, &ncoords ) != NC_NOERR )
845 MB_SET_ERR( MB_FAILURE,
"WriteSLAC: failed to define number of nodes" );
849 nc_def_dim(
ncFile,
"hexinterior", (
size_t)mesh_info.
num_int_hexes, &hexinterior ) != NC_NOERR )
851 MB_SET_ERR( MB_FAILURE,
"WriteSLAC: failed to define number of interior hex elements" );
854 if( nc_def_dim(
ncFile,
"hexinteriorsize", (
size_t)9, &hexinteriorsize ) != NC_NOERR )
856 MB_SET_ERR( MB_FAILURE,
"WriteSLAC: failed to define interior hex element size" );
860 nc_def_dim(
ncFile,
"hexexterior", (
size_t)mesh_info.
bdy_hexes.
size(), &hexexterior ) != NC_NOERR )
862 MB_SET_ERR( MB_FAILURE,
"WriteSLAC: failed to define number of exterior hex elements" );
865 if( nc_def_dim(
ncFile,
"hexexteriorsize", (
size_t)15, &hexexteriorsize ) != NC_NOERR )
867 MB_SET_ERR( MB_FAILURE,
"WriteSLAC: failed to define exterior hex element size" );
871 nc_def_dim(
ncFile,
"tetinterior", (
size_t)mesh_info.
num_int_tets, &tetinterior ) != NC_NOERR )
873 MB_SET_ERR( MB_FAILURE,
"WriteSLAC: failed to define number of interior tet elements" );
876 if( nc_def_dim(
ncFile,
"tetinteriorsize", (
size_t)5, &tetinteriorsize ) != NC_NOERR )
878 MB_SET_ERR( MB_FAILURE,
"WriteSLAC: failed to define interior tet element size" );
882 nc_def_dim(
ncFile,
"tetexterior", (
size_t)mesh_info.
bdy_tets.
size(), &tetexterior ) != NC_NOERR )
884 MB_SET_ERR( MB_FAILURE,
"WriteSLAC: failed to define number of exterior tet elements" );
887 if( nc_def_dim(
ncFile,
"tetexteriorsize", (
size_t)9, &tetexteriorsize ) != NC_NOERR )
889 MB_SET_ERR( MB_FAILURE,
"WriteSLAC: failed to define exterior tet element size" );
895 dims[0] = hexinterior;
896 dims[1] = hexinteriorsize;
899 NC_NOERR != nc_def_var(
ncFile,
"hexahedron_interior", NC_LONG, 2, dims, &dum_var ) )
901 MB_SET_ERR( MB_FAILURE,
"WriteSLAC: failed to create connectivity array for interior hexes" );
904 dims[0] = hexexterior;
905 dims[1] = hexexteriorsize;
907 NC_NOERR != nc_def_var(
ncFile,
"hexahedron_exterior", NC_LONG, 2, dims, &dum_var ) )
909 MB_SET_ERR( MB_FAILURE,
"WriteSLAC: failed to create connectivity array for exterior hexes" );
912 dims[0] = tetinterior;
913 dims[1] = tetinteriorsize;
915 NC_NOERR != nc_def_var(
ncFile,
"tetrahedron_exterior", NC_LONG, 2, dims, &dum_var ) )
917 MB_SET_ERR( MB_FAILURE,
"WriteSLAC: failed to create connectivity array for interior tets" );
920 dims[0] = tetexterior;
921 dims[1] = tetexteriorsize;
923 NC_NOERR != nc_def_var(
ncFile,
"tetrahedron_exterior", NC_LONG, 2, dims, &dum_var ) )
925 MB_SET_ERR( MB_FAILURE,
"WriteSLAC: failed to create connectivity array for exterior tets" );
931 dims[1] = coord_size;
932 if( NC_NOERR != nc_def_var(
ncFile,
"coords", NC_DOUBLE, 2, dims, &dum_var ) )
934 MB_SET_ERR( MB_FAILURE,
"WriteSLAC: failed to define node coordinate array" );
943 if( strlen( (
const char*)filename ) == 0 )
945 MB_SET_ERR( MB_FAILURE,
"Output filename not specified" );
948 int fail = nc_create( filename, NC_CLOBBER, &
ncFile );
950 if( NC_NOERR !=
fail )
952 MB_SET_ERR( MB_FAILURE,
"Cannot open " << filename );
960 Range& forward_elems,
961 Range& reverse_elems )
963 Range ss_elems, ss_meshsets;
972 if( MB_FAILURE == result )
return result;
980 if( range_iter != ss_elems.
end() )
983 ss_elems.
erase( range_iter, ss_elems.
end() );
993 dum_it = ss_elems.
begin();
997 if( current_sense == 1 || current_sense == 0 ) std::copy( dum_it, ss_elems.
end(),
range_inserter( forward_elems ) );
998 if( current_sense == -1 || current_sense == 0 )
1003 for( range_iter = ss_meshsets.
begin(); range_iter != ss_meshsets.
end(); ++range_iter )
1007 if( 0 == sense_tag || MB_FAILURE ==
mbImpl->
tag_get_data( sense_tag, &( *range_iter ), 1, &this_sense ) )
1011 get_neuset_elems( *range_iter, this_sense * current_sense, forward_elems, reverse_elems );