sandbox/acastillo/output_fields/vtkhdf/output_vtkhdf_facets.h
#ifndef OUTPUT_VTKHDF_FACETS_H
#define OUTPUT_VTKHDF_FACETS_H
#include "acastillo/output_fields/output_common_helpers_facets.h"
#include "output_vtkhdf_facets_populate.h"output_facets_vtkhdf(): Exports VOF facets.
This function writes one VTKHDF file which can be read using Paraview. It handles the variable size polygons generated by the VOF method natively in parallel.
The arguments and their default values are:
- c
- vof scalar field.
- s
- scalar field to store, for instance, curvature.
- name
-
Output file name generally uses the
.vtkhdfextension. - compression_level
- Level of compression to use when writing data to the HDF5 file (default=9).
trace void output_facets_vtkhdf(scalar c, scalar s, char *name = "domain.vtkhdf", int compression_level = 9){
#ifdef HAVE_HDF5
hid_t file_id; // HDF5 file ID
hid_t group_id; // HDF5 group ID
hid_t subgroup_id; // HDF5 subgroup ID
hsize_t count[2]; // Hyperslab selection parameters
hsize_t offset[2]; // Offset for hyperslab
hsize_t dims[1] = {2};
// Obtain the number of vertices and facets
long num_points_loc = 0, num_cells_loc = 0;
long num_points = 0, num_cells = 0;
count_vertices_and_facets(c, &num_points_loc, &num_cells_loc);
// Connectivity size is identical to num_points_loc because every vertex is unique
long num_ids_loc = num_points_loc;
long num_ids = 0;
// Calculate offsets for parallel I/O
long offset_points[npe()], offset_cells[npe()], offset_ids[npe()], offset_offset[npe()];
calculate_offsets2(offset_offset, num_cells_loc+1, offset);
calculate_offsets2(offset_ids, num_ids_loc, offset);
calculate_offsets2(offset_cells, num_cells_loc, offset);
calculate_offsets2(offset_points, num_points_loc, offset);
// Global counts
#if _MPI
MPI_Allreduce(&num_points_loc, &num_points, 1, MPI_LONG, MPI_SUM, MPI_COMM_WORLD);
MPI_Allreduce(&num_cells_loc, &num_cells, 1, MPI_LONG, MPI_SUM, MPI_COMM_WORLD);
MPI_Allreduce(&num_ids_loc, &num_ids, 1, MPI_LONG, MPI_SUM, MPI_COMM_WORLD);
#else
num_points = num_points_loc;
num_cells = num_cells_loc;
num_ids = num_ids_loc;
#endif
// Centralized chunk size calculation
hsize_t chunk_size = compute_chunk_size(num_cells);
// Create a new HDF5 file using helper
file_id = create_hdf5_file(name);
if (file_id < 0) return;
// Create group
group_id = H5Gcreate(file_id, "VTKHDF", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
// Create "Version", "Type" (and other) attributes
dims[0] = 2;
int version_data[2] = {2, 1};
create_attribute(group_id, "Version", version_data, dims);
create_attribute_type(group_id, "Type", "UnstructuredGrid", 16);
create_attribute_type(group_id, "Description", "Simulation perfomed using Basilisk (/)", 57);
// Write "NumberOfConnectivityIds", "NumberOfPoints", "NumberOfCells"
dims[0] = npe();
write_simple_dataset(group_id, "NumberOfConnectivityIds", offset_ids, dims);
write_simple_dataset(group_id, "NumberOfPoints", offset_points, dims);
write_simple_dataset(group_id, "NumberOfCells", offset_cells, dims);
// Populate and write the points dataset
double *points_dset;
populate_points_dset_facets_vtkhdf(c, &points_dset, num_points_loc, offset_points, count, offset);
write_dataset(group_id, count, offset, "Points", num_points, num_points_loc, 3, points_dset, H5T_NATIVE_DOUBLE, HDF5_CHUNKED, compute_chunk_size(num_points), compression_level);
free(points_dset);
// Populate and write the types dataset
char * types_dset;
populate_types_dset_facets_vtkhdf(&types_dset, num_cells_loc, offset_cells, count, offset);
write_dataset(group_id, count, offset, "Types", num_cells, num_cells_loc, 1, types_dset, H5T_STD_U8LE, HDF5_CHUNKED, chunk_size, compression_level);
free(types_dset);
// Populate and write the connectivity dataset
long *topo_dset;
populate_topo_dset_facets_vtkhdf(c, &topo_dset, num_ids_loc, offset_ids, count, offset);
write_dataset(group_id, count, offset, "Connectivity", num_ids, num_ids_loc, 1, topo_dset, H5T_NATIVE_LONG, HDF5_CHUNKED, compute_chunk_size(num_ids), compression_level);
free(topo_dset);
// Populate and write the offsets dataset
long *offsets_dset;
populate_offsets_dset_facets_vtkhdf(c, &offsets_dset, num_cells_loc, offset_offset, count, offset);
write_dataset(group_id, count, offset, "Offsets", num_cells+npe(), num_cells_loc+1, 1, offsets_dset, H5T_NATIVE_LONG, HDF5_CHUNKED, chunk_size, compression_level);
free(offsets_dset);
// Create subgroup "CellData"
subgroup_id = H5Gcreate(group_id, "CellData", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
// Allocate memory and write scalar datasets
double *scalar_dset = (double *)malloc(num_cells_loc * sizeof(double));
populate_scalar_dset_facets_vtkhdf(c, s, scalar_dset, num_cells_loc, offset_cells, count, offset);
write_dataset(subgroup_id, count, offset, s.name, num_cells, num_cells_loc, 1, scalar_dset, H5T_NATIVE_DOUBLE, HDF5_CHUNKED, chunk_size, compression_level);
free(scalar_dset);
H5Gclose(subgroup_id);
// Create subgroup "FieldData"
subgroup_id = H5Gcreate(group_id, "FieldData", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
H5Gclose(subgroup_id);
// Create subgroup "PointData"
subgroup_id = H5Gcreate(group_id, "PointData", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
H5Gclose(subgroup_id);
H5Gclose(group_id);
// Close HDF5 resources
H5Fflush(file_id, H5F_SCOPE_GLOBAL);
H5Fclose(file_id);
#else
// HDF5 not available
static int warning_printed = 0;
if (!warning_printed && pid() == 0) {
fprintf(stderr, "Warning: output_facets_vtkhdf() called but HDF5 is not available. Output skipped.\n");
warning_printed = 1;
}
#endif
}
#endif // OUTPUT_VTKHDF_FACETS_H