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,
183 const int time_step_index,
const double time,
184 const Array_t& array,
const bool gather_array =
true )
187 "ViSIT BOV writer can only be used with uniform mesh" );
190 using entity_type =
typename Array_t::entity_type;
191 using value_type =
typename Array_t::value_type;
192 using memory_space =
typename Array_t::memory_space;
193 const std::size_t num_space_dim = Array_t::num_space_dim;
196 const auto& global_grid = array.layout()->localGrid()->globalGrid();
199 const auto& global_mesh = global_grid.globalMesh();
203 std::array<long, num_space_dim + 1> global_extents;
204 for ( std::size_t i = 0; i < num_space_dim + 1; ++i )
206 global_extents[i] = -1;
208 for ( std::size_t d = 0; d < num_space_dim; ++d )
210 if ( std::is_same<entity_type, Cell>::value )
211 global_extents[d] = global_grid.globalNumEntity(
Cell(), d );
212 else if ( std::is_same<entity_type, Node>::value )
213 global_extents[d] = global_grid.globalNumEntity(
Cell(), d ) + 1;
215 global_extents[num_space_dim] = array.layout()->dofsPerEntity();
217 auto owned_index_space = array.layout()->indexSpace(
Own(),
Local() );
218 std::array<long, num_space_dim + 1> owned_extents;
219 for ( std::size_t i = 0; i < num_space_dim + 1; ++i )
221 owned_extents[i] = -1;
223 for ( std::size_t d = 0; d < num_space_dim; ++d )
225 if ( std::is_same<entity_type, Cell>::value )
227 owned_extents[d] = owned_index_space.extent( d );
229 else if ( std::is_same<entity_type, Node>::value )
231 if ( !global_grid.isPeriodic( d ) ||
232 global_grid.dimBlockId( d ) <
233 global_grid.dimNumBlock( d ) - 1 )
234 owned_extents[d] = owned_index_space.extent( d );
236 owned_extents[d] = owned_index_space.extent( d ) + 1;
239 owned_extents[num_space_dim] = array.layout()->dofsPerEntity();
244 for ( std::size_t d = 0; d < num_space_dim; ++d )
246 if ( global_grid.isPeriodic( d ) )
250 halo->gather( ExecutionSpace(), array );
258 std::array<long, num_space_dim + 1> local_space_min;
259 std::array<long, num_space_dim + 1> local_space_max;
260 for ( std::size_t d = 0; d < num_space_dim; ++d )
262 local_space_min[d] = owned_index_space.min( d );
263 local_space_max[d] = owned_index_space.min( d ) + owned_extents[d];
265 local_space_min.back() = 0;
266 local_space_max.back() = owned_extents.back();
269 auto owned_subview =
createSubview( array.view(), local_space );
271 std::array<long, num_space_dim + 1> reorder_space_size;
272 for ( std::size_t d = 0; d < num_space_dim; ++d )
274 reorder_space_size[d] = owned_extents[num_space_dim - d - 1];
276 reorder_space_size.back() = owned_extents.back();
279 array.label(), reorder_space );
280 reorderView( owned_view, owned_subview, reorder_space, ExecutionSpace() );
283 std::stringstream file_name;
284 file_name << prefix <<
"_" << std::setfill(
'0' ) << std::setw( 6 )
288 std::string data_file_name = file_name.str() +
".dat";
290 MPI_File_open( global_grid.comm(), data_file_name.c_str(),
291 MPI_MODE_WRONLY | MPI_MODE_CREATE, MPI_INFO_NULL,
295 auto subarray =
createSubarray( array, owned_extents, global_extents );
296 MPI_Type_commit( &subarray );
300 "native", MPI_INFO_NULL );
304 MPI_File_write_all( data_file, owned_view.data(), owned_view.size(),
308 MPI_File_close( &data_file );
309 MPI_Type_free( &subarray );
314 MPI_Comm_rank( global_grid.comm(), &rank );
318 std::string header_file_name = file_name.str() +
".bov";
320 header.open( header_file_name, std::fstream::out );
323 header <<
"TIME: " << time << std::endl;
326 header <<
"DATA_FILE: " << data_file_name << std::endl;
329 header <<
"DATA_SIZE: ";
330 for ( std::size_t d = 0; d < num_space_dim; ++d )
332 header << global_extents[d] <<
" ";
334 for ( std::size_t d = num_space_dim; d < 3; ++d )
345 header <<
"VARIABLE: " << array.label() << std::endl;
348 header <<
"DATA_ENDIAN: LITTLE" << std::endl;
355 header <<
"BRICK_ORIGIN: ";
356 for ( std::size_t d = 0; d < num_space_dim; ++d )
358 header << global_mesh.lowCorner( d ) <<
" ";
360 for ( std::size_t d = num_space_dim; d < 3; ++d )
367 header <<
"BRICK_SIZE: ";
368 for ( std::size_t d = 0; d < num_space_dim; ++d )
370 header << global_grid.globalNumEntity(
Cell(), d ) *
371 global_mesh.cellSize( d )
374 for ( std::size_t d = num_space_dim; d < 3; ++d )
382 header <<
"DATA_COMPONENTS: " << global_extents[num_space_dim]