Demonstration how to write a field that is domain-decomposited into multiple sub-domains. Here, the full domain is a uniform cartesian grid and the fields are fragmented into eight sub-boxes.
Note that in this example all data are written into the same file. Alternatively, each cpu could write data into another file, or each timestep could go into another file, or each timestep for each cpu can go into another file. The information content is still uniquely defined in the file, but the user needs to ensure different file names in such a case if the truncation mode is used. Writing to the same file might only work in append mode, but depends on HDF5 capabilities when MPI is used (HDF5-parallel).
#include <hdf5.h> #include <F5/F5F.h> #include <F5/F5R.h> #include <F5/F5coordinates.h> #include <math.h> #define SMALL int main() { double time = 0.0; int timestep = 0; hid_t File_id; F5Path*myPath; int cpu; const char*filename = "FragmentedField.f5"; const char*gridname = "DemoGrid"; const char*fieldname = "NonsenseScalar"; const char*vfieldname = "SensitiveVectors"; #ifdef SMALL hsize_t dims[3] = { 129, 89, 45 }; #else hsize_t dims[3] = { 2048, 2048, 2048 }; #endif /* got one layer of overlapping nodes between adjacent blocks ghostzones==1, see below */ #ifdef SMALL hsize_t block_dims[3] = { 50, 25, 13 } ; #define num 50*25*13 #else hsize_t block_dims[3] = { 256,256,256 } ; #define num 256*256*256 #endif static float data[num]; static F5_vec3f_t vdata[num]; File_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT , H5P_DEFAULT ); for(time=0.0; time<1.0; time+=0.1) { int r; timestep++; /* refinement simulation */ for(r=0; r<3; r++) { F5_vec3_point_t origin; F5_vec3_float_t spacing; origin.x = -10.0; origin.y = - 5.0; origin.z = - 2.5; spacing.x = 0.2/(1<<r); spacing.y = 0.2/(1<<r); spacing.z = 0.2/(1<<r); for(cpu=0; cpu<8; cpu++) { hsize_t offset[3]; int i; for(i=0; i<3; i++) { offset[i] = (cpu&(1<<i)) ? block_dims[i]-1 : 0; if (r>0) offset[i] += (int)(20*time); } /* compute the data */ { int x,y,z; for(z=0;z<block_dims[2]; z++) for(y=0;y<block_dims[1]; y++) for(x=0;x<block_dims[0]; x++) { int i = x + block_dims[0]*(y+block_dims[1]*z); float X = origin.x + (x + offset[0]) * spacing.x, Y = origin.y + (y + offset[1]) * spacing.y, Z = origin.z + (z + offset[2]) * spacing.z; data[i] = //(float)cpu + sin(X*time) * sin(Y*Y*time) * sin(Z*time*time); vdata[i].x = time* cos(X*time)*sin(Y*Y*time)*sin(Z*time*time); vdata[i].y =2*Y*time* sin(X*time)*cos(Y*Y*time)*sin(Z*time*time); vdata[i].z =time*time*sin(X*time)*sin(Y*Y*time)*cos(Z*time*time); } } /* create F5Path object */ if (r==0) myPath = F5Rcreate_cartesian(File_id, time, gridname, 0); else { hsize_t refinement[3] = { r+1,r+1,r+1 }; myPath = F5Rcreate_vertex_refinement3D(File_id, time, gridname, refinement, 0); } F5Rset_timestep(myPath, timestep); /* Write global bounding box information */ { F5_vec3_point_t min, max, center; F5Fwrite_linear(myPath, FIBER_HDF5_POSITIONS_STRING, 3, dims, F5T_COORD3_FLOAT, &origin, &spacing); min = origin; max.x = min.x + spacing.x*(dims[0]-1); max.y = min.y + spacing.y*(dims[1]-1); max.z = min.z + spacing.z*(dims[2]-1); F5Fset_range(myPath, &min, &max); center.x = .5*(max.x + min.x); center.y = .5*(max.y + min.y); center.z = .5*(max.z + min.z); F5Fset_average(myPath, ¢er); } /* Write local domain fragment information */ { hsize_t ghost_zone_ldf[3], /* the extent of the ghost zone left down front */ ghost_zone_rub[3]; /* the extent of the ghost zone right up back */ hid_t creator_id = H5Pcreate(H5P_DATASET_CREATE); char fraction_name[1024]; int i; sprintf(fraction_name,"node-%05d", cpu); for(i=0; i<3; i++) { /* one layer of overlapping nodes between adjacent fragments */ ghost_zone_ldf[i] = offset[i]?1:0; ghost_zone_rub[i] = offset[i]?0:1; } if (!F5Fwrite_fraction(myPath, fieldname, 3, dims, block_dims, H5T_NATIVE_FLOAT, H5T_NATIVE_FLOAT, data, offset, ghost_zone_ldf, ghost_zone_rub, fraction_name, creator_id) ) { puts("Error in F5Fwrite_fraction, write scalar"); } if (!F5Fwrite_fraction(myPath, vfieldname, 3, dims, block_dims, F5T_VEC3_FLOAT, F5T_VEC3_FLOAT, vdata, offset, ghost_zone_ldf, ghost_zone_rub, fraction_name, creator_id) ) { puts("Error in F5Fwrite_fraction, write vector"); } } F5Fclose(myPath); F5close(myPath); } } } H5Fclose(File_id); return 0; }