int main(int argc, char* argv[]) {
    long int s, it;
	unsigned int flag, verbose;
	unsigned int NXPROB, NYPROB;
	double start, end;
	int iz;

  	// create file and verbose flags 
  	flag = 0;
  	verbose = 0;

 	// Parse command line options 
  	int opt;
  	char *file = NULL;
  	while ((opt = getopt(argc, argv, "hvs:f:")) != -1) {
        switch (opt) {
        case 'v': 
			verbose = 1; 
			break;
        case 's': 
			if( !(s=atoi(optarg)) )  {
				fprintf(stderr, "Cannot parse %s value.\n", optarg);
           		exit(EXIT_FAILURE);
			}
			
			break;
        case 'f': 
			file = optarg;
			flag = 1;
			break;
		case 'h':
        default:
            fprintf(stderr, "Usage: %s [-s SIZE] [-f output file]\n", argv[0]);
            exit(EXIT_FAILURE);
        }
    }


	// Set initial data values	
	NXPROB = NX - 1;
	NYPROB = NY - 1;

	if(verbose) {
		fprintf(stdout, "[INFO] Setting map size to %d (%dx%d)\n", NX*NY, NX, NY);	
		fprintf(stdout, "[INFO] Max iter %d\n", MAXSTEP);
	}
	if(verbose && flag) {
		fprintf(stdout, "[INFO] Using output file %s\n", file);
	}

	// Program starts here 

	// Set initial and boundary conditions 
	initializeArray (X1, NX, NY);
	setupBoundaryConditions(X1, NX, NY);
	setupBoundaryConditions(X2, NX, NY);


	// Main calculations
	iz = 0;
	for (it = 0; it < MAXSTEP; it++) 
	{
  		if(verbose && (it%(MAXSTEP/10) == 0)) {
			fprintf(stdout, "[INFO] iteration %ld, time %.3f seconds\n", it, gettime()-start);
		}
  		long int i, j;

		for (i = 1; i < NXPROB; i++) 
		{
		      for (j = 1; j < NYPROB; j++) 
		      {
			      X2[i][j] = X1[i][j] 
				      + CX * ( X1[i+1][j] + X1[i-1][j] - 2.0 * X1[i][j] )
					      + CY * ( X1[i][j+1] + X1[i][j-1] - 2.0 * X1[i][j] );
		      }
		}
  		iz = 1 - iz;
    }

	// Save output file
    if(flag) save(X2, NX, NY, file);

	// End time
	end = gettime();
	
	// Get information: wall clock time, problem size, ... 
	if(verbose)
	{
		fprintf(stdout, "[INFO] Convergence after %d steps\n", MAXSTEP);
		fprintf(stdout, "[INFO] Problem size %d [%dx%d]\n", NY*NX, NX, NY);
		fprintf(stdout, "[INFO] Wall clock time %lf seconds\n",(end-start));
		if(flag) fprintf(stdout, "[INFO] Output file  %s\n", file);
	} 
	else 
	{
		printf("Time %.3f seconds, Size %d [%dx%d]\n", end - start, NY*NX, NX, NY);
	}

	exit(EXIT_SUCCESS);
}
 virtual void initBoundaryConditions(const Opm::parameter::ParameterGroup& param)
 {
     setupBoundaryConditions(param, this->ginterf_, this->bcond_);
 }