#ifndef GRID_H
/* Support for solving heat equation in rectangular grid */
#include <stdbool.h>

/* Parameters */
#define CONDUCTIVITY 0.8

/*
  Representation of (portion of) grid.
  Only contains data for local portion of grid + ghost rows
 */
typedef struct {
    int nrow;          // Total rows in grid
    int ncol;          // Columns in grid
    int process_id;   
    int process_count;
    int row_count;     // Number of rows in local region
    int row_start;     // Offset of local rows from global rows
    double *data;      // Size =  (row_count+2) X (ncol+2)
    double *ndata;     // Size = (row_count+2) X (ncol+2)
} grid_t;

/* Representation of boundary conditions */
typedef struct {
    int nrow;
    int ncol;
    int bcount;         // 2*nrow + 2*ncol
    double *bdata;      // All four boundaries in one sequence
    double *northRow;   // ncol
    double *eastColumn; // nrow
    double *southRow;   // ncol
    double *westColumn; // nrow
} boundary_t;

/*
  Locate value within grid array.
  Compensate for extra values on boundary
*/
#define GINDEX(g, r, c) (((r)+1)*((g)->ncol+2)+((c)+1))


grid_t *new_grid(int nrow, int ncol, int process_id, int process_count);
void free_grid(grid_t *g);

boundary_t *create_boundary(int nrow, int ncol, char mode);
void free_boundary(boundary_t *bc);

void initialize_grid(grid_t *g, boundary_t *bc);
int run_grid(grid_t *g, int maxSteps, double epsilon, bool verbose);

/* Run solver.  Returns number of steps performed */
int solve(int nrow, int ncol, char mode, double epsilon, int maxSteps, bool verbose, int process_id, int process_count);
#define GRID_H 1
#endif // !GRID_H
