sandbox/acastillo/output_fields/xdmf/output_xdmf_facets_box.h
#ifndef OUTPUT_XDMF_FACETS_BOX_H
#define OUTPUT_XDMF_FACETS_BOX_H
#include "acastillo/output_fields/output_common_helpers_facets.h"
#include "output_xdmf_facets_populate.h"output_facets_xmf_box(): Exports the VOF interface, restricted to a box.
Same as output_facets_xmf_list() (multiple scalar fields
on the same VOF interface mesh, written as separate HDF5
/Cells/<name> datasets / XDMF Attributes) but only
includes interface cells whose cell center lies inside
box[2] = {min, max}. This is the same semantics
output_xmf_box() uses for its regular-field export: a
per-cell inclusion test, not a geometric clip of the reconstructed facet
polygon — a facet whose cell center is inside the box is included whole,
even if part of the polygon pokes outside; a facet whose cell center is
outside is dropped whole, even if part of the polygon pokes in.
The arguments and their default values are:
- c
- vof scalar field.
- slist
- list of scalar fields to store on the facets (e.g. curvature, pressure, etc.).
- subname
- subname to be used for the output file.
- box
-
array of two coordinates defining the bounding box [min, max]. Optional;
defaults to the whole domain (
[X0,Y0,Z0]to[X0+L0,Y0+L0,Z0+L0]), in which case this behaves exactly likeoutput_facets_xmf_list(). - mode
- HDF5 writing mode.
- compression_level
- HDF5 compression level.
#if dimension == 2
trace
void output_facets_xmf_box(scalar c, scalar * slist, char *subname, coord box[2] = {{X0, Y0}, {X0 + L0, Y0 + L0}}, int mode = HDF5_CHUNKED, int compression_level = 6){
#else
trace
void output_facets_xmf_box(scalar c, scalar * slist, char *subname, coord box[2] = {{X0, Y0, Z0}, {X0 + L0, Y0 + L0, Z0 + L0}}, int mode = HDF5_CHUNKED, int compression_level = 6){
#endif
#ifdef HAVE_HDF5
hid_t file_id; // HDF5 file ID
hid_t group_id; // HDF5 group ID
hsize_t count[2]; // Hyperslab selection parameters
hsize_t offset[2]; // Offset for hyperslab
// Construct the HDF5 file name
char name[260];
snprintf(name, sizeof(name), "%s.h5", subname);
// Obtain the number of vertices and facets within the box
long num_points_loc = 0, num_cells_loc = 0;
long num_points = 0, num_cells = 0;
count_vertices_and_facets_box(c, box, &num_points_loc, &num_cells_loc);
long topo_size_loc = 2 * num_cells_loc + num_points_loc;
long topo_size = 0;
// Calculate offsets for parallel I/O
long offset_points[npe()], offset_cells[npe()], offset_topo[npe()];
calculate_offsets(offset_points, offset_cells, num_points_loc, num_cells_loc, offset);
calculate_offsets2(offset_topo, topo_size_loc, offset);
// Determine 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(&topo_size_loc, &topo_size, 1, MPI_LONG, MPI_SUM, MPI_COMM_WORLD);
#else
num_points = num_points_loc;
num_cells = num_cells_loc;
topo_size = topo_size_loc;
#endif
// Write the light data
if (pid() == 0) {
char xmf_name[111];
sprintf(xmf_name, "%s.xmf", subname);
FILE *fp = fopen(xmf_name, "w");
write_xdmf_header(fp, name);
fputs("\t<Domain>\n", fp);
fputs("\t\t<Grid Name=\"Unstructured Grid\" GridType=\"Uniform\">\n", fp);
fprintf(fp, "\t\t\t<Time Type=\"Single\" Value=\"%g\" />\n", t);
fprintf(fp, "\t\t\t<Topology TopologyType=\"Mixed\" NumberOfElements=\"%ld\">\n", num_cells);
fprintf(fp, "\t\t\t\t<DataItem Format=\"HDF\" Dimensions=\"%ld\" DataType=\"Int\" Precision=\"8\" >\n", topo_size);
fputs("\t\t\t\t\t&HeavyData;/Topology\n", fp);
fputs("\t\t\t\t</DataItem>\n", fp);
fputs("\t\t\t</Topology>\n", fp);
fputs("\t\t\t<Geometry GeometryType=\"XYZ\">\n", fp);
fprintf(fp, "\t\t\t\t<DataItem Format=\"HDF\" NumberType=\"Float\" Dimensions=\"%ld 3\" Precision=\"8\" >\n", num_points);
fputs("\t\t\t\t\t&HeavyData;/Geometry/Points\n", fp);
fputs("\t\t\t\t</DataItem>\n", fp);
fputs("\t\t\t</Geometry>\n", fp);
for (scalar s in slist) {
fprintf(fp, "\t\t\t<Attribute Name=\"%s\" AttributeType=\"Scalar\" Center=\"Cell\">\n", s.name);
fprintf(fp, "\t\t\t\t<DataItem Dimensions=\"%ld\" NumberType=\"Float\" Precision=\"8\" Format=\"HDF\">\n", num_cells);
fprintf(fp, "\t\t\t\t\t&HeavyData;/Cells/%s\n", s.name);
fputs("\t\t\t\t</DataItem>\n", fp);
fputs("\t\t\t</Attribute>\n", fp);
}
write_xdmf_footer(fp);
fflush(fp);
fclose(fp);
}
// Write the heavy data
file_id = create_hdf5_file(name);
if (file_id < 0) return;
hsize_t chunk_size = compute_chunk_size(topo_size);
// Topology
long *topo_dset;
populate_topo_dset_facets_xdmf_box(c, box, &topo_dset, topo_size_loc, offset_topo, offset_points, count, offset);
write_dataset(file_id, count, offset, "/Topology", topo_size, topo_size_loc, 1, topo_dset, H5T_NATIVE_LONG, mode, chunk_size, compression_level);
free(topo_dset);
// Geometry
group_id = H5Gcreate(file_id, "Geometry", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
double *points_dset;
populate_points_dset_facets_xdmf_box(c, box, &points_dset, num_points_loc, offset_points, count, offset);
write_dataset(group_id, count, offset, "/Geometry/Points", num_points, num_points_loc, 3, points_dset, H5T_NATIVE_DOUBLE, mode, compute_chunk_size(num_points), compression_level);
free(points_dset);
H5Gclose(group_id);
// Cell data, one dataset per field in slist
group_id = H5Gcreate(file_id, "Cells", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
double *scalar_dset = (double *)malloc(num_cells_loc * sizeof(double));
hsize_t chunk_size_cells = compute_chunk_size(num_cells);
for (scalar s in slist) {
char substamp[1024];
sprintf(substamp, "/Cells/%s", s.name);
populate_scalar_dset_facets_xdmf_box(c, box, s, scalar_dset, num_cells_loc, offset_cells, count, offset);
write_dataset(group_id, count, offset, substamp, num_cells, num_cells_loc, 1, scalar_dset, H5T_NATIVE_DOUBLE, mode, chunk_size_cells, compression_level);
}
free(scalar_dset);
H5Gclose(group_id);
H5Fflush(file_id, H5F_SCOPE_GLOBAL);
H5Fclose(file_id);
#else
static int warning_printed = 0;
if (!warning_printed && pid() == 0) {
fprintf(stderr, "Warning: output_facets_xmf_box() called but HDF5 is not available. Output skipped.\n");
warning_printed = 1;
}
#endif
}
#endif // OUTPUT_XDMF_FACETS_BOX_H