1 #include "pargrid.h"
2 
3 /*+ main - the main routine for this grid program
4 
5      Input Parameters:
6      argc, argv - the usual
7      argv[1] - the number of processors in the x direction
8      argv[2] - the number of processors in the y direction
9      argv[3] - the number of processors in the z direction
10      argv[4] - the number of points in the x direction on each processor
11                do not use less than 3 points
12      argv[5] - the number of points in the y direction on each processor
13                do not use less than 3 points
14      argv[6] - the number of points in the z direction on each processor
15                do not use less than 3 points
16      argv[7] - symmetric = 0, nonsymmetric = 1
17      argv[8] - 0 = do not use, 1 = use inode/clique stuff
18      argv[9] - number of components per grid point
19      argv[10] - 0 = use identity for shift, 1 = use positive of A
20      argv[11] - shift
21 
22      To Run, use mpirun
23 
24      Notes: The grid program solves a linear system associated with
25             a 3-D grid distributed across the processors.  The 3-D
26             grid is partitioned in all three dimensions among the
27             processors.  A 7pt stencil is used.
28 
29  +*/
30 
main(int argc,char ** argv)31 int main(int argc, char **argv)
32 {
33 	par_grid grid;
34 	BSprocinfo *procinfo;
35 	int	inode, nonsymmetric;
36 
37 	/* Call BSinit() to initialize BlocklSolve and MPI */
38     BSinit(&argc,&argv);
39 
40 	/* set up the context for BlockSolve */
41 	procinfo = BScreate_ctx(); CHKERRN(0);
42 	/* tell it to print out some information on the reordering */
43 	BSctx_set_pr(procinfo,TRUE); CHKERRN(0);
44 
45 	if(procinfo->my_id==0) {
46 		printf("\n");
47 		printf("************** Blocksolve Example Grid7 *******************\n");
48 	}
49 
50 	/* read in grid parameters */
51 	if (argc < 12) {
52 		SETERRC(ARG_ERR,"Argument list too small\n");
53 		if(procinfo->my_id==0) {
54 		printf("Example: mpirun -np P grid7.ARCH PX PY PZ NX NY NZ SYM IN NC BMAT SHIFT\n");
55 		printf("ARCH = Machine architecture\n");
56 		printf("P = number of processors\n");
57 		printf("PX = the number of processors in the x direction\n");
58 		printf("PY = the number of processors in the y direction\n");
59 		printf("PZ = the number of processors in the z direction\n");
60 		printf("NX = number of points in the x direction on each processor\n");
61 		printf("NY = number of points in the y direction on each processor\n");
62 		printf("NZ = number of points in the z direction on each processor\n");
63 		printf("SYM = 0, use symmetric data structure, = 1, use nonsymmetric\n");
64 		printf("IN = 0, do not use, = 1, use inode/clique stuff\n");
65 		printf("NC = number of components per grid point\n");
66 		printf("BMAT = 0, use I, = 1, use positive(A)\n");
67 		printf("SHIFT = shift in (A - shift*B) \n");
68 		}
69 		return(-1);
70 	}
71 	sscanf(argv[1],"%d",&grid.worker_x);
72 	sscanf(argv[2],"%d",&grid.worker_y);
73 	sscanf(argv[3],"%d",&grid.worker_z);
74 	if (procinfo->my_id == 0) {
75 		printf("o  Number of workers (x,y,z): %d %d %d\n",
76 			grid.worker_x,grid.worker_y,grid.worker_z);
77 	}
78 	if (procinfo->nprocs != grid.worker_x*grid.worker_y*grid.worker_z) {
79 		SETERRC(ARG_ERR,"Number of processors is not correct\n");
80 		return(-1);
81 	}
82 	sscanf(argv[4],"%d",&grid.l_num_x);
83 	sscanf(argv[5],"%d",&grid.l_num_y);
84 	sscanf(argv[6],"%d",&grid.l_num_z);
85 	sscanf(argv[7],"%d",&nonsymmetric);
86 	sscanf(argv[8],"%d",&inode);
87 	sscanf(argv[9],"%d",&grid.ncomp);
88 	sscanf(argv[10],"%d",&grid.bmatrix);
89 	sscanf(argv[11],"%lf",&grid.shift);
90 	if(grid.ncomp<1) grid.ncomp = 1;
91 	if(grid.ncomp>20) grid.ncomp = 20;
92 	grid.symmetric = TRUE;
93 	grid.icc_storage = (!nonsymmetric);
94 	grid.positive = FALSE;
95 	BSctx_set_method(procinfo,SYMMLQ);
96 
97 	/* tell it to use the nonsymmetric matrix data structure */
98 	if(nonsymmetric) {
99 		if (procinfo->my_id == 0)
100 			printf("o  Using nonsymmetric data structure\n");
101 		BSctx_set_pre(procinfo,PRE_ILU);
102 	} else {
103 		if (procinfo->my_id == 0)
104 			printf("o  Using symmetric data structure\n");
105 		BSctx_set_pre(procinfo,PRE_ICC);
106 	}
107 
108 	/* decide whether to look for i-nodes or cliques */
109 	if(inode) {
110 		if (procinfo->my_id == 0)
111 			printf("o  Using inode/clique information\n");
112 		BSctx_set_si(procinfo,FALSE); CHKERRN(0);
113 	} else {
114 		if (procinfo->my_id == 0)
115 			printf("o  Not using inode/clique information\n");
116 		BSctx_set_si(procinfo,TRUE); CHKERRN(0);
117 	}
118 
119 	if (procinfo->my_id == 0)
120 		printf("o  Multi component grid, %d components per point\n",grid.ncomp);
121 
122 	if (procinfo->my_id == 0) {
123 		if(grid.bmatrix) printf("o  B = positive(A)\n");
124 		else printf("o  B = I\n");
125 		printf("o  Shift = %e\n",grid.shift);
126 	}
127 
128 	/* local grid size and type */
129 	grid.type = 7;
130 	if (procinfo->my_id == 0) {
131 		printf("o  Local discretizations (x,y,z): %d %d %d\n",
132 			grid.l_num_x,grid.l_num_y,grid.l_num_z);
133 	}
134 
135 	/* call the worker */
136 	worker(&grid,procinfo);
137 
138 	if(procinfo->my_id==0) {
139 		printf("************ End Blocksolve Example Grid7 *****************\n");
140 		printf("\n");
141 	}
142 
143 	/* print logging if enabled */
144 	BSprint_log(procinfo); CHKERRN(0);
145 
146 	/* free the context */
147 	BSfree_ctx(procinfo); CHKERRN(0);
148 
149 	/* finalize BlockSolve and MPI */
150 	BSfinalize();
151 
152 	exit(0);
153 }
154