FragmentedField.c

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; 

                printf("FragmentedField: Writing t=%lg\n", time); fflush(stdout);

                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, &center); 
                                } 

                                /* 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;
}