/*
 *******************************************************************
 * Laplace Eqn 
 * T is initially 0.0 everywhere except at boundaries where T=100.
 *                                                        
 *             T = 100                                      Y
 *     |-------------------|        |-------------------|   |
 *     |                   |        |        P0         |   |
 *  T  |                   |  T     |-------------------|   |
 *  =  |                   |  =     |        P1         |   |
 * 100 |                   | 100    |-------------------|   |_______X
 *     |                   |        |        P2         | 
 *     |                   |        |-------------------| 
 *     |                   |        |        P3         | 
 *     |-------------------|        |-------------------| 
 *            T = 100
 *
 * Use Central Differencing Method
 * Each process only has subgrid.
 * Each Processor works on a sub grid and then sends its
 * Boundaries to neighbours
 *
 *    /mpp/bin/cc -T cray-t3d -o laplace.par laplace.serial.c -lpvm3
 *
 * Raghu Reddy,  PSC.... Apr 1995;
 * Modified from the original Fortran version by Sushell Chitre, PSC 1994
 *
 ******************************************************************   */

#define NPROC    4
#define NROWS    1000
#define NCOLS    1000
#define NROWSL   NROWS/NPROC
#define NITER    1000
#define DOWN     100
#define UP       101

#include <mpp/pvm3.h>  /* Caution: T3D needs mpp directory of /usr/include */

extern int       _MPP_MY_PE;         /* Could use _my_pe() */

main(int argc, char **argv) {

  float T[NROWSL+2][NCOLS+2], Told[NROWSL+2][NCOLS+2];
  int   i, ii, j, jj, itop, ibot, iter, info;
  int   asrc, atag, alen;             /* "Actual"; values not used */

  int MYPE = _MPP_MY_PE;
  int NPES = _num_pes();

  for( i=0; i<=NROWSL+1; i++ )        /* Initialize */
    for ( j=0; j<=NCOLS+1; j++ )
      T[i][j] = 0.0;




            /* Set Left and Right bndry */


                 /* Top boundary */

               /* Bottom boundary */

  for( i=0; i<=NROWSL+1; i++ )       /* Copy the values */
    for( j=0; j<=NCOLS+1; j++ )
      Told[i][j] = T[i][j];

/*----------------------------------------------------------*
 |       Do Computation on Sub-grid for Niter iterations    |
 *----------------------------------------------------------*/

  for( iter=1; iter<=NITER; iter++ ) {

    for( i=1; i<=NROWSL; i++ )
      for( j=1; j<=NCOLS; j++ )
	T[i][j] = 0.25 * ( Told[i+1][j] + Told[i-1][j] +
			   Told[i][j+1] + Told[i][j-1] );

    for( i=1; i<=NROWSL; i++ )       /* Copy for next iteration  */
      for( j=1; j<=NCOLS; j++ )
	Told[i][j] = T[i][j];

/*   Exchange Boundary Values; Down first; Only NPES-1 do this  */


/*                             Now UP; Only NPES-1 do this  */

/*   Receive the data from above                                */


/*   Receive the data from below                                */


/*   Print some test Values   */

    if( (iter%100) == 0 ) {
      if( MYPE == 0 )
	printf("Iter = %4d: PE = %d: T[10][10]       = %20.8f\n",
	        iter, MYPE, T[10][10]);

      _barrier();

      if( MYPE == NPES-1 )
	printf("Iter = %4d: PE = %d: T[NROWSL-9][10] = %20.8f\n",
	        iter, MYPE, T[NROWSL-9][10]);
    }

    _barrier();

  }  /* End of iteration */

}    /* End of Program */

