SchwarzschildF5.c

Writing a time-dependent metric tensor field on a uniform grid.

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <hdf5.h>

#include <F5/F5X.h>
#include <F5/F5uniform.h>

/* #include <malloc.h> */

int     main(int argc, char*argv[])
{
        double  time = 0.0;
        hid_t   file_id; 

        hsize_t dims[3] = {10,20,30};
        /*
        Note: do not use multidimensional C arrays.
        In the C notation, an array data[X][Y][Z] implies that
        the Z coordinate runs fastest and succeeding points in z are
        close in memory, whereas points close in X are separated by slices.
        Using C arrays, it is not possible to perform XY operations trivially.
        Thus in F5 we prefer to use FORTRAN order, which in C looks like
        data[Z][Y][X] , or, better, use one-dimensional arrays and do
        indexing yourself. This the more real-world case anyway, because
        the dimension of a multidimensional array must be known at compile-time,
        which is normally not the case.
        */
        F5_metric3_float_t m[10*20*30]; 
        F5_vec3_point_t origin; 
        F5_vec3_float_t delta; 

        F5Path*myPath;
                
        unlink("metric.f5");
        file_id = F5append( "metric.f5" ); 

        origin.x = -1;               origin.y = -1;                     origin.z = -1; 
        delta .x = 2.0/(int)dims[0]; delta .y = 2.0/(int)dims[1];       delta .z = 2.0/(int)dims[2];    
        
        for(time=0.0; time<10; time+=0.5)
        {
                int     i,j,k;          
                double  M = (10 - time)/10; 
                F5_metric3_float_t *g = m;

                for(k=0; k<dims[2]; k++)
                for(j=0; j<dims[1]; j++)
                for(i=0; i<dims[0]; i++)
                {
                        float x, y, z, r, psi;
                
                        x = origin.x + i * delta.x; 
                        y = origin.y + j * delta.y; 
                        z = origin.z + k * delta.z; 
                        r = sqrt(x*x+y*y+z*z); 
                        
                        psi = 1 + M / (2*r); 
                        psi *= psi;     // psi^2 
                        psi *= psi;     // psi^4 

        

                        g->gxx = psi;
                        g->gyy = psi; 
                        g->gzz = psi; 
                        g->gxy = 0; 
                        g->gyz = 0; 
                        g->gxz = 0; 
                        
                        g++;
                } 

                myPath = F5Fwrite_uniform_cartesian3D(file_id, time,
                                                      "schwarzschild",
                                                      &origin, &delta,
                                                      dims,
                                                      "metric",
                                                      F5T_METRIC33_FLOAT,
                                                      m, 0, F5P_DEFAULT); 
                F5close(myPath);
        }
        H5Fclose(file_id);      
        return 0;
}