/* Heat flow model in C + HDF5 * * The left edge of a 2D grid starts with an initial temperature. As time * passes, the heat flows through the grid. * * This is an "I am the average of my neighbors" model: * temp = (t1 + t2 + ... + tN) / N * * Author: Aaron Weeden, Shodor, 2014 */ /* LIBS */ #include #include #include #include #include #include /* GLOBALS */ float **Grid; // Grid of temperature data float **Next_Grid; // Next time step of temperature data int N_Rows = 5; // Number of rows in the 2D temperature grid int N_Cols = 5; // Number of columns in the 2D temperature grid int N_Time_Steps = 5; // Number of time steps in the simulation float Init_Temp = 5.0; // Initial temperature for the left edge of the grid /* FUNCTIONS */ /* get arguments from command line and set global vars with them */ void parseArgs(int argc, char **argv) { int c; while((c = getopt(argc, argv, "r:c:t:i:")) != -1) { switch(c) { case 'r': N_Rows = atoi(optarg); break; case 'c': N_Cols = atoi(optarg); break; case 't': N_Time_Steps = atoi(optarg); break; case 'i': Init_Temp = atof(optarg); break; case '?': default: fprintf(stderr, "Usage: %s [OPTIONS]\n", argv[0]); fprintf(stderr, "OPTIONS:\n"); fprintf(stderr, "\t-r int : number of rows\n"); fprintf(stderr, "\t-c int : number of columns\n"); fprintf(stderr, "\t-t int : number of time steps\n"); fprintf(stderr, "\t-f float : initial temperature\n"); exit(EXIT_FAILURE); } } } /* check if the simulation can continue with valid parameters, exit if not */ void validateInput() { bool err = false; if (N_Rows <= 0) { fprintf(stderr, "ERROR: Number of rows (-r %d) must be positive.\n", N_Rows); err = true; } if (N_Cols <= 0) { fprintf(stderr, "ERROR: Number of columns (-c %d) must be positive.\n", N_Cols); err = true; } if (N_Time_Steps < 0) { fprintf(stderr, "ERROR: Number of time steps (-t %d) must be ", N_Time_Steps); fprintf(stderr, "non-negative.\n"); err = true; } if (err) exit(EXIT_FAILURE); } /* allocate memory for grids */ void allocMem() { int row_mem_size = N_Cols * sizeof(float); int grid_mem_size = N_Rows * row_mem_size; int row; if ((Grid = (float**)malloc(grid_mem_size)) == NULL) { fprintf(stderr, "ERROR allocating memory for 2D grid.\n"); exit(EXIT_FAILURE); } for (row=0; row 0) Next_Grid[row][col] += Grid[row-1][col]; else n_neighbors--; if (row < N_Rows-1) Next_Grid[row][col] += Grid[row+1][col]; else n_neighbors--; if (col > 0) Next_Grid[row][col] += Grid[row][col-1]; else n_neighbors--; if (col < N_Cols-1) Next_Grid[row][col] += Grid[row][col+1]; else n_neighbors--; Next_Grid[row][col] /= n_neighbors; } } } /* copy the next grid into the current grid */ void advanceGrid() { int row, col; for (row=0; row=0; row--) free(Next_Grid[row]); free(Next_Grid); for (row=N_Rows-1; row>=0; row--) free(Grid[row]); free(Grid); } int main(int argc, char **argv) { int i; char filename[80]; /* set up */ parseArgs(argc, argv); validateInput(); allocMem(); initGrid(); /* simulate */ displayGrid(0); writeHDF5(0); for (i=0; i