110 const std::array<long, N>& owned_extents,
111 const std::array<long, N>& global_extents )
113 using value_type =
typename Array_t::value_type;
114 const auto& global_grid = array.layout()->localGrid()->globalGrid();
116 std::array<int, N> local_start;
117 std::array<int, N> local_size;
118 std::array<int, N> global_size;
119 for ( std::size_t i = 0; i < N - 1; ++i )
122 static_cast<int>( global_grid.globalOffset( N - i - 2 ) );
123 local_size[i] =
static_cast<int>( owned_extents[N - i - 2] );
124 global_size[i] =
static_cast<int>( global_extents[N - i - 2] );
126 local_start.back() = 0;
127 local_size.back() = owned_extents.back();
128 global_size.back() = global_extents.back();
130 MPI_Datatype subarray;
131 MPI_Type_create_subarray( N, global_size.data(), local_size.data(),
132 local_start.data(), MPI_ORDER_C,
185 const int time_step_index,
const double time,
186 const Array_t& array,
const bool gather_array =
true )
189 "ViSIT BOV writer can only be used with uniform mesh" );
192 using entity_type =
typename Array_t::entity_type;
193 using value_type =
typename Array_t::value_type;
194 using memory_space =
typename Array_t::memory_space;
195 const std::size_t num_space_dim = Array_t::num_space_dim;
198 const auto& global_grid = array.layout()->localGrid()->globalGrid();
201 const auto& global_mesh = global_grid.globalMesh();
205 std::array<long, num_space_dim + 1> global_extents;
206 for ( std::size_t i = 0; i < num_space_dim + 1; ++i )
208 global_extents[i] = -1;
210 for ( std::size_t d = 0; d < num_space_dim; ++d )
212 if ( std::is_same<entity_type, Cell>::value )
213 global_extents[d] = global_grid.globalNumEntity(
Cell(), d );
214 else if ( std::is_same<entity_type, Node>::value )
215 global_extents[d] = global_grid.globalNumEntity(
Cell(), d ) + 1;
217 global_extents[num_space_dim] = array.layout()->dofsPerEntity();
219 auto owned_index_space = array.layout()->indexSpace(
Own(),
Local() );
220 std::array<long, num_space_dim + 1> owned_extents;
221 for ( std::size_t i = 0; i < num_space_dim + 1; ++i )
223 owned_extents[i] = -1;
225 for ( std::size_t d = 0; d < num_space_dim; ++d )
227 if ( std::is_same<entity_type, Cell>::value )
229 owned_extents[d] = owned_index_space.extent( d );
231 else if ( std::is_same<entity_type, Node>::value )
233 if ( !global_grid.isPeriodic( d ) ||
234 global_grid.dimBlockId( d ) <
235 global_grid.dimNumBlock( d ) - 1 )
236 owned_extents[d] = owned_index_space.extent( d );
238 owned_extents[d] = owned_index_space.extent( d ) + 1;
241 owned_extents[num_space_dim] = array.layout()->dofsPerEntity();
246 for ( std::size_t d = 0; d < num_space_dim; ++d )
248 if ( global_grid.isPeriodic( d ) )
252 halo->gather( ExecutionSpace(), array );
260 std::array<long, num_space_dim + 1> local_space_min;
261 std::array<long, num_space_dim + 1> local_space_max;
262 for ( std::size_t d = 0; d < num_space_dim; ++d )
264 local_space_min[d] = owned_index_space.min( d );
265 local_space_max[d] = owned_index_space.min( d ) + owned_extents[d];
267 local_space_min.back() = 0;
268 local_space_max.back() = owned_extents.back();
271 auto owned_subview =
createSubview( array.view(), local_space );
273 std::array<long, num_space_dim + 1> reorder_space_size;
274 for ( std::size_t d = 0; d < num_space_dim; ++d )
276 reorder_space_size[d] = owned_extents[num_space_dim - d - 1];
278 reorder_space_size.back() = owned_extents.back();
281 array.label(), reorder_space );
282 reorderView( owned_view, owned_subview, reorder_space, ExecutionSpace() );
285 std::stringstream file_name;
286 file_name << prefix <<
"_" << std::setfill(
'0' ) << std::setw( 6 )
290 std::string data_file_name = file_name.str() +
".dat";
292 MPI_File_open( global_grid.comm(), data_file_name.c_str(),
293 MPI_MODE_WRONLY | MPI_MODE_CREATE, MPI_INFO_NULL,
297 auto subarray =
createSubarray( array, owned_extents, global_extents );
298 MPI_Type_commit( &subarray );
302 "native", MPI_INFO_NULL );
306 MPI_File_write_all( data_file, owned_view.data(), owned_view.size(),
310 MPI_File_close( &data_file );
311 MPI_Type_free( &subarray );
316 MPI_Comm_rank( global_grid.comm(), &rank );
320 std::string header_file_name = file_name.str() +
".bov";
322 header.open( header_file_name, std::fstream::out );
325 header <<
"TIME: " << time << std::endl;
328 header <<
"DATA_FILE: " << data_file_name << std::endl;
331 header <<
"DATA_SIZE: ";
332 for ( std::size_t d = 0; d < num_space_dim; ++d )
334 header << global_extents[d] <<
" ";
336 for ( std::size_t d = num_space_dim; d < 3; ++d )
347 header <<
"VARIABLE: " << array.label() << std::endl;
350 header <<
"DATA_ENDIAN: LITTLE" << std::endl;
357 header <<
"BRICK_ORIGIN: ";
358 for ( std::size_t d = 0; d < num_space_dim; ++d )
360 header << global_mesh.lowCorner( d ) <<
" ";
362 for ( std::size_t d = num_space_dim; d < 3; ++d )
369 header <<
"BRICK_SIZE: ";
370 for ( std::size_t d = 0; d < num_space_dim; ++d )
372 header << global_grid.globalNumEntity(
Cell(), d ) *
373 global_mesh.cellSize( d )
376 for ( std::size_t d = num_space_dim; d < 3; ++d )
384 header <<
"DATA_COMPONENTS: " << global_extents[num_space_dim]