#include "pargrid.h"
/*+ main - the main routine for this grid program
Input Parameters:
argc, argv - the usual
argv[1] - the number of processors in the x direction
argv[2] - the number of processors in the y direction
argv[3] - the number of processors in the z direction
argv[4] - the number of points in the x direction on each processor
do not use less than 3 points
argv[5] - the number of points in the y direction on each processor
do not use less than 3 points
argv[6] - the number of points in the z direction on each processor
do not use less than 3 points
argv[7] - symmetric matrix = 0, nonsymmetric matrix = 1
argv[8] - number of components per grid point
argv[9] - 0 = do not use, 1 = use inode/clique stuff
argv[10] - 0 = ICC, 1 = ILU
argv[11] - 0 => method = CG, 1 => method = GMRES
Notes: The grid program solves a linear system associated with
a 3-D grid distributed across the processors. The 3-D
grid is partitioned in all three dimensions among the
processors. A 7pt stencil is used.
+*/
int main(int argc, char **argv)
{
par_grid grid;
BSprocinfo *procinfo;
int inode, method, scaling, num_rhs;
int nonsym_storage, nonsymmetric;
/* Call BSinit() to initialize BlocklSolve and MPI */
BSinit(&argc,&argv);
/* set up the context for BlockSolve */
procinfo = BScreate_ctx(); CHKERRN(0);
/* tell it to print out some information on the reordering */
BSctx_set_pr(procinfo,TRUE); CHKERRN(0);
if(procinfo->my_id==0) {
printf("\n");
printf("************** Blocksolve Example Grid5 *******************\n");
}
/* read in grid parameters */
if (argc < 14) {
SETERRC(ARG_ERR,"Argument list too small\n");
if(procinfo->my_id==0) {
printf("Example: mpirun -np P grid5.ARCH PX PY PZ NX NY NZ SYM NC IN PRE METHOD SCALE NUM_RHS\n");
printf("ARCH = Machine architecture\n");
printf("P = number of processors\n");
printf("PX = the number of processors in the x direction\n");
printf("PY = the number of processors in the y direction\n");
printf("PZ = the number of processors in the z direction\n");
printf("NX = number of points in the x direction on each processor\n");
printf("NY = number of points in the y direction on each processor\n");
printf("NZ = number of points in the z direction on each processor\n");
printf("SYM = 0, generate symmetric matrix, = 1, generate nonsymmetric\n");
printf("NC = number of components per grid point\n");
printf("IN = 0, do not use, = 1, use inode/clique stuff\n");
printf("PRE = 0, compute ICC factor, = 1, compute ILU factor\n");
printf("METHOD = 0, use PCG, = 1, use GMRES\n");
printf("SCALE = 0, do not scale matrix, = 1, scale matrix\n");
printf("NUM_RHS = number of RHS to solve for\n");
}
return(-1);
}
sscanf(argv[1],"%d",&grid.worker_x);
sscanf(argv[2],"%d",&grid.worker_y);
sscanf(argv[3],"%d",&grid.worker_z);
if (procinfo->my_id == 0) {
printf("o ");
printf("Number of workers (x,y,z): %d %d %d\n",
grid.worker_x,grid.worker_y,grid.worker_z);
}
if (procinfo->nprocs != grid.worker_x*grid.worker_y*grid.worker_z) {
SETERRC(ARG_ERR,"Number of processors is not correct\n");
return(-1);
}
sscanf(argv[4],"%d",&grid.l_num_x);
sscanf(argv[5],"%d",&grid.l_num_y);
sscanf(argv[6],"%d",&grid.l_num_z);
sscanf(argv[7],"%d",&nonsymmetric);
sscanf(argv[8],"%d",&grid.ncomp);
sscanf(argv[9],"%d",&inode);
sscanf(argv[10],"%d",&nonsym_storage);
sscanf(argv[11],"%d",&method);
sscanf(argv[12],"%d",&scaling);
sscanf(argv[13],"%d",&num_rhs);
if(grid.ncomp<1) grid.ncomp = 1;
if(grid.ncomp>20) grid.ncomp = 20;
grid.symmetric = (!nonsymmetric);
grid.icc_storage = (!nonsym_storage);
grid.positive = FALSE;
/* tell it to use the nonsymmetric matrix data structure */
if (procinfo->my_id == 0) {
printf("o ");
if(nonsymmetric)
printf("Generating nonsymmetric matrix\n");
else
printf("Generating symmetric matrix\n");
}
if (procinfo->my_id == 0) {
printf("o ");
printf("Multi component grid, %d components per point\n",grid.ncomp);
}
/* decide whether to look for i-nodes or cliques */
if(inode) {
BSctx_set_si(procinfo,FALSE); CHKERRN(0);
} else {
BSctx_set_si(procinfo,TRUE); CHKERRN(0);
}
/* decide on preconditioner */
if(nonsym_storage) {
BSctx_set_pre(procinfo,PRE_ILU); CHKERRN(0);
} else {
BSctx_set_pre(procinfo,PRE_ICC); CHKERRN(0);
}
/* decide on iterative method */
if(method) {
BSctx_set_method(procinfo,GMRES); CHKERRN(0);
} else {
BSctx_set_method(procinfo,CG); CHKERRN(0);
}
BSctx_set_scaling(procinfo,scaling); CHKERRN(0);
BSctx_set_num_rhs(procinfo,num_rhs); CHKERRN(0);
/* local grid size and type */
grid.type = 7;
if (procinfo->my_id == 0) {
printf("o ");
printf("Local discretizations (x,y,z): %d %d %d\n",
grid.l_num_x,grid.l_num_y,grid.l_num_z);
}
/* call the worker */
worker(&grid,procinfo);
/* print out the log info (if desired) */
/* MLOG_PRINT(procinfo); */
if(procinfo->my_id==0) {
printf("************ End Blocksolve Example Grid5 *****************\n");
printf("\n");
}
/* print logging if enabled */
BSprint_log(procinfo); CHKERRN(0);
/* free the context */
BSfree_ctx(procinfo); CHKERRN(0);
/* finalize BlockSolve and MPI */
BSfinalize();
exit(0);
}
syntax highlighted by Code2HTML, v. 0.9.1