出典:h5fortran/docs/USAGE-visualization.md
可視化用HDF5出力
t_hdf5_writer はローカルのmeshとfieldを逐次出力します。
t_phdf5_writer は全MPI rankのデータを一つのHDF5ファイルへ集合的に書きます。
Parallel APIを有効にしたビルドでは、用途に応じて二つのwriterを使い分けられます。
どちらも同じscheme_version=1のレイアウトを生成します。Fortran側ではXDMF/XMLを生成しません。HDF5時系列を出力した後、
独立ツールh5xdmfでXDMF3を生成します。
snapshot HDF5を正本とし、metadata.h5 はPythonが作る再生成可能な索引とする。
ソルバーは metadata.h5 へ追記しない。
想定する完成形:
result/
├── seq000000.h5
├── seq000001.h5
├── ...
├── metadata.h5
├── fluid.xdmf
└── soil_particles.xdmf
HDF5出力
use hdf5, only: h5open_f, h5close_f
use h5fort
use mpi
use iso_fortran_env, only: int64, real64
type(t_phdf5_writer) :: writer
integer :: ierr, hdferr
real(real64) :: nodes(3, num_points)
integer(int64) :: connectivity(8, num_cells)
real(real64) :: pressure(num_points)
real(real64) :: velocity(3, num_points)
call MPI_Init(ierr)
call h5open_f(hdferr)
if (hdferr /= 0) call MPI_Abort(MPI_COMM_WORLD, 1, ierr)
writer%h5_filepath = 'result/seq000000.h5'
writer%output_type = 'UnstructuredGrid'
writer%num_points = num_points
writer%num_cells = num_cells
writer%time = 0.0_real64
call writer%init()
call writer%write_geometry_ugrid(nodes, connectivity)
call writer%write_point_data(pressure, 'Pressure')
call writer%write_point_data(velocity, 'Velocity')
call writer%close()
call h5close_f(hdferr)
if (hdferr /= 0) call MPI_Abort(MPI_COMM_WORLD, 1, ierr)
call MPI_Finalize(ierr)
逐次出力には型を type(t_hdf5_writer) に変更し、use mpi とMPIの初期化・終了を
省略します。HDF5のエラー判定は if (hdferr /= 0) error stop とします。
writerの設定とwrite呼び出しは共通です。逐次writerはMPI有効ビルドでも利用できます。
複数rankから逐次出力する場合、rankごとに異なるファイル名を指定してください。
h5fort は常に t_hdf5_writer を公開し、
H5FORTRAN_ENABLE_PARALLEL=ON で t_phdf5_writer を公開します。
逐次writerだけを使うconsumerでは h5fortran_serial のみをリンクし、
use h5fort_serial_visualization, only: t_hdf5_writer とします。
インストール後のtarget名は h5fortran::h5fortran_serial です。
並列consumerは h5fortran_parallel、全APIを使う場合は h5fortran をリンクします。
H5FORTRAN_HDF5_ROOT(または HDF5_ROOT)に使用するHDF5のprefixを指定します。
一つのビルドでは全targetが同じHDF5を使います。parallel構成にはparallel HDF5が必要です。
この構成では h5fortran_serial だけをリンクしても、parallel HDF5由来のMPI依存が残ります。
MPI依存のない構成には、H5FORTRAN_ENABLE_PARALLEL=OFF とserial HDF5を指定して
別途ビルドしてください。serial構成でparallel HDF5を使用することもできますが、
その場合もHDF5由来のMPI依存は残ります。
以下のrankに関する説明はparallel writerに適用します。
num_cells は各rankが出力するowned cell数で、ghost cellは含めません。
num_points はowned cellが参照する全local node数です。rank境界の共有・halo nodeは
rankごとに別nodeとして重複して構いません。
connectivityは nodes(:, :) を参照するrank-local 0-origin node IDで渡します。
writerがrankごとのnode offsetを加え、HDF5全体のIDへ変換します。呼び出し側で
global node IDを計算するための通信は不要です。init、write、close は全rankが
同じ順序で呼びます。
両writerともHDF5ライブラリ自体の開始・終了を行いません。parallelでは全rankがプログラム全体で
MPI_Init → h5open_f → writer処理 → h5close_f → MPI_Finalize の順に
呼びます。複数stepや複数meshを書いても、h5open_f / h5close_f はそれぞれ
1回だけです。
! nodes(:, 1:4) を参照するrank-local connectivity
connectivity(:, 1) = [0_int64, 1_int64, 2_int64, 3_int64]
call writer%write_geometry(nodes, connectivity)
共有nodeのfield値を一致させて可視化したい場合、必要に応じて出力前に通常のhalo exchangeを行います。これはnode番号を統合する通信ではなく、field値を同期するための 通信です。
重複nodeを結合したい場合はParaViewの Clean to Grid filterを利用できます。
ghost cellまで出力するとcellが重複するため、出力対象はowned cellだけにします。
PolyDataは output_type='PolyData'、num_cells=0 として
write_geometry_polydata(nodes) を呼びます。同じ h5_filepath に
UnstructuredGrid、PolyDataの順で書くと、/ugrid と /polydata に保存されます。
Connectivity meshの一般形
connectivityを持つmeshは、同じwriterで任意のXDMF topologyを扱えます。
mesh_name はHDF5のroot直下group名です。
writer%h5_filepath = 'result/seq000000.h5'
writer%output_type = 'UnstructuredGrid'
writer%mesh_name = 'tetra'
writer%topology_type = 'Tetrahedron'
writer%nodes_per_element = 4
writer%num_points = num_points
writer%num_cells = num_cells
writer%time = time
call writer%init()
call writer%write_geometry(nodes, connectivity)
call writer%write_point_data(pressure, 'Pressure')
call writer%close()
代表的な指定は次のとおりです。
| 要素 | topology_type |
nodes_per_element |
|---|---|---|
| 六面体 | Hexahedron |
8 |
| 四面体 | Tetrahedron |
4 |
| 2D四角形 | Quadrilateral |
4 |
| 三角形 | Triangle |
3 |
topology_type と nodes_per_element は同時に指定します。省略した場合だけ
Hexahedron、8が既定値になります。同じHDF5へ異なる mesh_name で順番に
書き込むことで、複数種類のmeshを一つのtime stepに保存できます。
scheme_version=1
保存先と属性は共有仕様の可視化レイアウトを参照してください。
Fortran配列はcolumn-majorで、第1次元が最も速く変化します。HDF5 Fortran APIは 次元を反転して保存するため、C/C++・h5pyのrow-major表記とは次の対応になります。
| Fortranで渡す形状 | ファイル上の形状 |
|---|---|
nodes(3, num_points) |
(num_points, 3) |
connectivity(nodes_per_element, num_cells) |
(num_cells, nodes_per_element) |
field(ncomp, nlocal) |
(nlocal, ncomp) |
field(nlocal) |
(nlocal) |
並列出力ではFortranの最終次元(ファイル上の第0次元)に沿ってrankのデータを連結します。
呼び出し側で転置する必要はありません。一般の配列も a(nx, ny) がファイルでは
(ny, nx) になります。次元順序も参照してください。
Tensor6 は field(6, nlocal) の第1次元を XX, YY, ZZ, XY, YZ, XZ の順にします。
テンソル成分の順序に従ってください。
geometryは real(real32/real64/real128)、connectivityは
integer(int8/int16/int32/int64)、point/cell dataはこれら7 kindの1D/2Dに
対応します。
XDMFの生成
Python 3.10以上とuvを用意し、h5xdmfをインストールして実行します。
uv tool install ../h5xdmf
h5xdmf "result/seq*.h5" --metadata result/metadata.h5 --outdir result
更新・再構築、空stepの扱いと運用上の注意は POSTPROCESS.md を参照してください。
完成形のexample
逐次・並列のどちらも、5 stepの流体・土粒子snapshot出力からポストプロセスまで 一括実行できます。流体は四面体mesh上の圧力波と渦速度、土粒子は沈降・拡散と応力を持つ。
| example | writer | 実行ファイル | データ規模 |
|---|---|---|---|
serial-viz |
t_hdf5_writer |
example_serial_viz |
1プロセスで全meshを作成 |
parallel-viz |
t_phdf5_writer |
example_parallel_viz |
既定2 rankのlocal meshを結合 |
1プロセスで出力する場合は逐次例を使います。
example/serial-viz/generate.sh build
複数rankから集合的に出力する場合は example/parallel-viz/generate.sh build を
使います。
両例は同じmesh・field名で result/seq000000.h5 〜 seq000004.h5 を生成します。
生成されるファイルと使い方は各exampleのREADMEを参照してください。
ParaViewでの色付け、Glyph、粒子表示の手順もexample READMEに記載している。
必要な実行時ツールはPython 3.10以上、h5py、numpyです。依存関係と固定版は
h5xdmfの pyproject.toml と uv.lock で管理されています。生成XDMFの確認にはParaView、
HDF5構造の手動確認には h5dump または h5ls が便利ですが、どちらも生成処理の
必須依存ではありません。