Actual source code: ex10.c
1: /*$Id: ex10.c,v 1.58 2001/09/11 16:33:29 bsmith Exp $*/
3: static char help[] = "Reads a PETSc matrix and vector from a file and solves a linear system.n
4: This version first preloads and solves a small system, then loads n
5: another (larger) system and solves it as well. This example illustratesn
6: preloading of instructions with the smaller system so that more accuraten
7: performance monitoring can be done with the larger one (that actuallyn
8: is the system of interest). See the 'Performance Hints' chapter of then
9: users manual for a discussion of preloading. Input parameters includen
10: -f0 <input_file> : first file to load (small system)n
11: -f1 <input_file> : second file to load (larger system)nn
12: -trans : solve transpose system insteadnn";
13: /*
14: This code can be used to test PETSc interface to other packages.n
15: Examples of command line options: n
16: ex10 -f0 <datafile> -ksp_monitor n
17: -sles_view n
18: -num_numfac <num_numfac> -num_rhs <num_rhs> n
19: -pc_type lu -mat_aij_spooles/superlu/superlu_dist n
20: -pc_type cholesky -mat_baij_dscpack -matload_type mpibaij n
21: -pc_type cholesky -mat_sbaij_spooles -matload_type mpisbaijnn";
22: */
23: /*T
24: Concepts: SLES^solving a linear system
25: Processors: n
26: T*/
28: /*
29: Include "petscsles.h" so that we can use SLES solvers. Note that this file
30: automatically includes:
31: petsc.h - base PETSc routines petscvec.h - vectors
32: petscsys.h - system routines petscmat.h - matrices
33: petscis.h - index sets petscksp.h - Krylov subspace methods
34: petscviewer.h - viewers petscpc.h - preconditioners
35: */
36: #include petscsles.h
38: #include src/vec/is/impls/general/general.h
40: int main(int argc,char **args)
41: {
42: SLES sles; /* linear solver context */
43: Mat A; /* matrix */
44: Vec x,b,u; /* approx solution, RHS, exact solution */
45: PetscViewer fd; /* viewer */
46: char file[2][128]; /* input file name */
47: PetscTruth table,flg,trans,partition = PETSC_FALSE;
48: int ierr,its,ierrp;
49: PetscReal norm;
50: PetscLogDouble tsetup,tsetup1,tsetup2,tsolve,tsolve1,tsolve2;
51: PetscScalar zero = 0.0,none = -1.0;
52: PetscTruth preload = PETSC_TRUE,diagonalscale;
53: int num_numfac;
55: PetscInitialize(&argc,&args,(char *)0,help);
57: PetscOptionsHasName(PETSC_NULL,"-table",&table);
58: PetscOptionsHasName(PETSC_NULL,"-trans",&trans);
59: PetscOptionsHasName(PETSC_NULL,"-partition",&partition);
61: /*
62: Determine files from which we read the two linear systems
63: (matrix and right-hand-side vector).
64: */
65: PetscOptionsGetString(PETSC_NULL,"-f",file[0],127,&flg);
66: if (flg) {
67: PetscStrcpy(file[1],file[0]);
68: } else {
69: PetscOptionsGetString(PETSC_NULL,"-f0",file[0],127,&flg);
70: if (!flg) SETERRQ(1,"Must indicate binary file with the -f0 or -f option");
71: PetscOptionsGetString(PETSC_NULL,"-f1",file[1],127,&flg);
72: if (!flg) {preload = PETSC_FALSE;} /* don't bother with second system */
73: }
75: /* -----------------------------------------------------------
76: Beginning of linear solver loop
77: ----------------------------------------------------------- */
78: /*
79: Loop through the linear solve 2 times.
80: - The intention here is to preload and solve a small system;
81: then load another (larger) system and solve it as well.
82: This process preloads the instructions with the smaller
83: system so that more accurate performance monitoring (via
84: -log_summary) can be done with the larger one (that actually
85: is the system of interest).
86: */
87: PreLoadBegin(preload,"Load system");
89: /* - - - - - - - - - - - New Stage - - - - - - - - - - - - -
90: Load system
91: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
93: /*
94: Open binary file. Note that we use PETSC_BINARY_RDONLY to indicate
95: reading from this file.
96: */
97: PetscViewerBinaryOpen(PETSC_COMM_WORLD,file[PreLoadIt],PETSC_BINARY_RDONLY,&fd);
99: /*
100: Load the matrix and vector; then destroy the viewer.
101: */
102: ierr = MatLoad(fd,MATMPIAIJ,&A);
103: ierr = PetscPushErrorHandler(PetscIgnoreErrorHandler,PETSC_NULL);
104: ierrp = VecLoad(fd,&b);
105: ierr = PetscPopErrorHandler();
106: if (ierrp) { /* if file contains no RHS, then use a vector of all ones */
107: int m;
108: PetscScalar one = 1.0;
109: MatGetLocalSize(A,&m,PETSC_NULL);
110: VecCreate(PETSC_COMM_WORLD,&b);
111: VecSetSizes(b,m,PETSC_DECIDE);
112: VecSetFromOptions(b);
113: VecSet(&one,b);
114: }
115: PetscViewerDestroy(fd);
117: /*
118: If the loaded matrix is larger than the vector (due to being padded
119: to match the block size of the system), then create a new padded vector.
120: */
121: {
122: int m,n,j,mvec,start,end,index;
123: Vec tmp;
124: PetscScalar *bold;
126: /* Create a new vector b by padding the old one */
127: MatGetLocalSize(A,&m,&n);
128: VecCreate(PETSC_COMM_WORLD,&tmp);
129: VecSetSizes(tmp,m,PETSC_DECIDE);
130: VecSetFromOptions(tmp);
131: VecGetOwnershipRange(b,&start,&end);
132: VecGetLocalSize(b,&mvec);
133: VecGetArray(b,&bold);
134: for (j=0; j<mvec; j++) {
135: index = start+j;
136: ierr = VecSetValues(tmp,1,&index,bold+j,INSERT_VALUES);
137: }
138: VecRestoreArray(b,&bold);
139: VecDestroy(b);
140: VecAssemblyBegin(tmp);
141: VecAssemblyEnd(tmp);
142: b = tmp;
143: }
144: VecDuplicate(b,&x);
145: VecDuplicate(b,&u);
146: VecSet(&zero,x);
148: /* - - - - - - - - - - - New Stage - - - - - - - - - - - - -
149: Setup solve for system
150: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
152: /*
153: Conclude profiling last stage; begin profiling next stage.
154: */
155: PreLoadStage("SLESSetUp");
157: if (partition) {
158: MatPartitioning mpart;
159: IS mis,nis,isn,is;
160: int *count,size,rank;
161: Mat B;
162: MPI_Comm_size(PETSC_COMM_WORLD,&size);
163: MPI_Comm_rank(PETSC_COMM_WORLD,&rank);
164: PetscMalloc(size*sizeof(int),&count);
165: MatPartitioningCreate(PETSC_COMM_WORLD, &mpart);
166: MatPartitioningSetAdjacency(mpart, A);
167: /* MatPartitioningSetVertexWeights(mpart, weight); */
168: MatPartitioningSetFromOptions(mpart);
169: MatPartitioningApply(mpart, &mis);
170: MatPartitioningDestroy(mpart);
171: ISPartitioningToNumbering(mis,&nis);
172: ISPartitioningCount(mis,count);
173: ISDestroy(mis);
174: ISInvertPermutation(nis, count[rank], &is);
175: PetscFree(count);
176: ISDestroy(nis);
177: ISSort(is);
178: ISAllGather(is,&isn);
179: MatGetSubMatrix(A,is,isn,PETSC_DECIDE,MAT_INITIAL_MATRIX,&B);
181: /* need to move the vector also */
182: ISDestroy(is);
183: ISDestroy(isn);
184: MatDestroy(A);
185: A = B;
186: }
187:
188: /*
189: We also explicitly time this stage via PetscGetTime()
190: */
191: PetscGetTime(&tsetup1);
193: /*
194: Create linear solver; set operators; set runtime options.
195: */
196: SLESCreate(PETSC_COMM_WORLD,&sles);
198: num_numfac = 1;
199: PetscOptionsGetInt(PETSC_NULL,"-num_numfac",&num_numfac,PETSC_NULL);
200: while ( num_numfac-- ){
201: /* SLESSetOperators(sles,A,A,DIFFERENT_NONZERO_PATTERN); */
202: SLESSetOperators(sles,A,A,SAME_NONZERO_PATTERN);
203: SLESSetFromOptions(sles);
205: /*
206: Here we explicitly call SLESSetUp() and SLESSetUpOnBlocks() to
207: enable more precise profiling of setting up the preconditioner.
208: These calls are optional, since both will be called within
209: SLESSolve() if they haven't been called already.
210: */
211: SLESSetUp(sles,b,x);
212: SLESSetUpOnBlocks(sles);
213: PetscGetTime(&tsetup2);
214: tsetup = tsetup2 - tsetup1;
216: /*
217: Tests "diagonal-scaling of preconditioned residual norm" as used
218: by many ODE integrator codes including PVODE. Note this is different
219: than diagonally scaling the matrix before computing the preconditioner
220: */
221: PetscOptionsHasName(PETSC_NULL,"-diagonal_scale",&diagonalscale);
222: if (diagonalscale) {
223: PC pc;
224: int j,start,end,n;
225: Vec scale;
226:
227: SLESGetPC(sles,&pc);
228: VecGetSize(x,&n);
229: VecDuplicate(x,&scale);
230: VecGetOwnershipRange(scale,&start,&end);
231: for (j=start; j<end; j++) {
232: VecSetValue(scale,j,((PetscReal)(j+1))/((PetscReal)n),INSERT_VALUES);
233: }
234: VecAssemblyBegin(scale);
235: VecAssemblyEnd(scale);
236: PCDiagonalScaleSet(pc,scale);
237: VecDestroy(scale);
239: }
241: /* - - - - - - - - - - - New Stage - - - - - - - - - - - - -
242: Solve system
243: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
245: /*
246: Begin profiling next stage
247: */
248: PreLoadStage("SLESSolve");
250: /*
251: Solve linear system; we also explicitly time this stage.
252: */
253: PetscGetTime(&tsolve1);
254: if (trans) {
255: SLESSolveTranspose(sles,b,x,&its);
256: } else {
257: int num_rhs=1;
258: PetscOptionsGetInt(PETSC_NULL,"-num_rhs",&num_rhs,PETSC_NULL);
259: while ( num_rhs-- ) {
260: SLESSolve(sles,b,x,&its);
261: }
262: }
263: PetscGetTime(&tsolve2);
264: tsolve = tsolve2 - tsolve1;
266: /*
267: Conclude profiling this stage
268: */
269: PreLoadStage("Cleanup");
271: /* - - - - - - - - - - - New Stage - - - - - - - - - - - - -
272: Check error, print output, free data structures.
273: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
275: /*
276: Check error
277: */
278: if (trans) {
279: MatMultTranspose(A,x,u);
280: } else {
281: MatMult(A,x,u);
282: }
283: VecAXPY(&none,b,u);
284: VecNorm(u,NORM_2,&norm);
286: /*
287: Write output (optinally using table for solver details).
288: - PetscPrintf() handles output for multiprocessor jobs
289: by printing from only one processor in the communicator.
290: - SLESView() prints information about the linear solver.
291: */
292: if (table) {
293: char *matrixname,slesinfo[120];
294: PetscViewer viewer;
296: /*
297: Open a string viewer; then write info to it.
298: */
299: PetscViewerStringOpen(PETSC_COMM_WORLD,slesinfo,120,&viewer);
300: SLESView(sles,viewer);
301: PetscStrrchr(file[PreLoadIt],'/',&matrixname);
302: PetscPrintf(PETSC_COMM_WORLD,"%-8.8s %3d %2.0e %2.1e %2.1e %2.1e %s n",
303: matrixname,its,norm,tsetup+tsolve,tsetup,tsolve,slesinfo);
305: /*
306: Destroy the viewer
307: */
308: PetscViewerDestroy(viewer);
309: } else {
310: PetscPrintf(PETSC_COMM_WORLD,"Number of iterations = %3dn",its);
311: PetscPrintf(PETSC_COMM_WORLD,"Residual norm %An",norm);
312: }
314: } /* while ( num_numfac-- ) */
316: /*
317: Free work space. All PETSc objects should be destroyed when they
318: are no longer needed.
319: */
320: MatDestroy(A); VecDestroy(b);
321: VecDestroy(u); VecDestroy(x);
322: SLESDestroy(sles);
323: PreLoadEnd();
324: /* -----------------------------------------------------------
325: End of linear solver loop
326: ----------------------------------------------------------- */
328: PetscFinalize();
329: return 0;
330: }