The vtkhdf_mb_file_type module

This module defines the vtkhdf_mb_file derived type for writing VTKHDF MultiBlockDataSet files.

A MultiBlockDataSet file contains a flat collection of named UnstructuredGrid blocks; hierarchical nesting of MultiBlockDataSet objects is not supported.

Each block behaves semantically like a vtkhdf_ug_file mesh: it has its own static mesh and associated point, cell, and field datasets.

As in vtkhdf_ug_file, partitions correspond 1:1 with MPI ranks. Each MPI rank contributes one VTKHDF partition for every block.

In the MPI build, all type-bound procedures are collective over the communicator passed to create and must be called in the same order on all ranks.

Most methods of vtkhdf_mb_file correspond directly to those of vtkhdf_ug_file, but operate on an opaque vtkhdf_block_handle returned by add_block.

use vtkhdf_mb_file_type
type(vtkhdf_mb_file) :: file
type(vtkhdf_block_handle) :: block
type(vtkhdf_cell_data_handle) :: cell_var
type(vtkhdf_point_data_handle) :: point_var
type(vtkhdf_field_data_handle) :: field_var

File Creation and Management

call file%create(filename, [comm,] stat, errmsg)

Create a new VTKHDF MultiBlockDataSet file.

Arguments are identical to those of vtkhdf_ug_file%create, except that there is no is_temporal argument.

call file%flush()

Collectively flush the file’s HDF5 buffers and request the operating system to flush file buffers.

call file%close()

Close the file and release internal resources. Users should always call this to “finalize” the object; automatic finalization cannot perform a proper collective cleanup.

Block definition

block = file%add_block(name [, is_temporal])

Define a new UnstructuredGrid block and return its handle.

name is normalized and disambiguated before it is used as the block name seen by the VTKHDF reader and ParaView. Input is trimmed, empty input is replaced by a default name, the characters /, ., and space are replaced by _, and duplicate internal names are made unique by appending a suffix.

The original user-facing input name is still written to the block group’s Name attribute for informational purposes.

If is_temporal is present and .true., the block supports time-dependent datasets. Temporal blocks must be defined before the first call to start_time_step. Non-temporal blocks may be defined at any time.

The returned vtkhdf_block_handle is opaque. Its components are private, so user code cannot inspect or construct handles directly; only store the returned value and pass it to later block-scoped operations.

The file is considered temporal if at least one block is temporal. All temporal blocks share a common timeline defined by calls to start_time_step.

Mesh Data

call file%write_mesh(block, points, cnode, xcnode, types)

Write the mesh geometry and topology for the block identified by block.

Mesh arguments and semantics are identical to those of vtkhdf_ug_file. The mesh for each block must be written exactly once and before writing any data for that block.

Static mesh-centered data

call file%write_cell_data(block, name, array)
call file%write_point_data(block, name, array)

Write static cell or point datasets for the block identified by block.

Dataset semantics are identical to those of vtkhdf_ug_file. array must conform to the same type and shape requirements described for vtkhdf_ug_file.

Within a block, cell datasets share a CellData namespace and point datasets share a PointData namespace. Input names are trimmed, empty input is replaced by a default name, the characters /, ., and space are replaced by _, and duplicate internal names are made unique by appending a suffix. The sanitized internal dataset name is what the VTKHDF reader and ParaView use. The original user-facing name is written to the dataset Name attribute for informational purposes.

Static field data

call file%write_field_data(block, name, array [, as_vector])

Write static field data for block.

Semantics are identical to vtkhdf_ug_file%write_field_data: scalar, rank-1, and rank-2 arrays are supported. For rank-1 arrays, as_vector=.true. marks the data as one tuple with n components; otherwise rank-1 is interpreted as n tuples of one component. In MPI builds, calls are collective and only rank 0 contributes the payload; all ranks must still pass matching array type/rank/shape.

Time-dependent mesh-centered data

MultiBlockDataSet files support time-dependent point and cell datasets on a per-block basis. A block is temporal if it was defined with is_temporal = .true. in add_block.

Temporal blocks must be defined before the first call to start_time_step. After the first time step is started, no further temporal block definitions or temporal dataset registrations are allowed.

cell_var = file%register_temporal_cell_data(block, name, mold)
point_var = file%register_temporal_point_data(block, name, mold)

Register name as a time-dependent dataset on the block identified by block. Registration semantics are identical to those of vtkhdf_ug_file. The returned handle is opaque; user code should store it and pass it to later temporal writes for the same block.

call file%start_time_step(time)

Start a new time step with time value time. The timeline is shared by all temporal blocks in the file. A call to start_time_step is required before writing any temporal dataset in any block.

For the first time step, each temporal dataset registered on each temporal block must be written once for that block.

call file%write_temporal_cell_data(block, cell_var, array)
call file%write_temporal_point_data(block, point_var, array)

Write array to the temporal dataset identified by cell_var or point_var for the specified block, associating it with the current time step. Write semantics are identical to those of vtkhdf_ug_file. After the first time step, writes may be skipped on later time steps; if omitted, the most recently written value is used.

The data handle and block handle must match the same block registration.

call file%finalize_time_step()

Finalize the current shared time step for all temporal blocks. Until this call, the file is in an in-progress state for that step. Best practice is to call finalize_time_step immediately after all temporal writes are complete.

finalize_time_step is called implicitly when start_time_step begins a new step while one is still open, and when close is called.

Time-dependent field data

field_var = file%register_temporal_field_data(block, name, mold)

Register time-dependent field data for block. Semantics match vtkhdf_ug_file%register_temporal_field_data.

call file%write_temporal_field_data(block, field_var, array [, as_vector])

Write time-dependent field data for the current shared time step. Semantics match vtkhdf_ug_file%write_temporal_field_data. In MPI builds, calls are collective and only rank 0 contributes the payload; all ranks must still pass matching array type/rank/shape.

The data handle and block handle must match the same block registration.