Actual source code: ex27.c
petsc-3.3-p7 2013-05-11
2: static char help[] = "Reads a PETSc matrix and vector from a file and solves the normal equations.\n\n";
3: /*T
4: Concepts: KSP^solving a linear system
5: Concepts: Normal equations
6: Processors: n
7: T*/
9: /*
10: Include "petscksp.h" so that we can use KSP solvers. Note that this file
11: automatically includes:
12: petscsys.h - base PETSc routines petscvec.h - vectors
13: petscmat.h - matrices
14: petscis.h - index sets petscksp.h - Krylov subspace methods
15: petscviewer.h - viewers petscpc.h - preconditioners
16: */
17: #include <petscksp.h>
22: int main(int argc,char **args)
23: {
24: KSP ksp; /* linear solver context */
25: Mat A,N; /* matrix */
26: Vec x,b,u,Ab; /* approx solution, RHS, exact solution */
27: PetscViewer fd; /* viewer */
28: char file[PETSC_MAX_PATH_LEN]; /* input file name */
29: PetscErrorCode ierr,ierrp;
30: PetscInt its,n,m;
31: PetscReal norm;
33: PetscInitialize(&argc,&args,(char *)0,help);
36: /*
37: Determine files from which we read the linear system
38: (matrix and right-hand-side vector).
39: */
40: PetscOptionsGetString(PETSC_NULL,"-f",file,PETSC_MAX_PATH_LEN,PETSC_NULL);
42: /* -----------------------------------------------------------
43: Beginning of linear solver loop
44: ----------------------------------------------------------- */
45: /*
46: Loop through the linear solve 2 times.
47: - The intention here is to preload and solve a small system;
48: then load another (larger) system and solve it as well.
49: This process preloads the instructions with the smaller
50: system so that more accurate performance monitoring (via
51: -log_summary) can be done with the larger one (that actually
52: is the system of interest).
53: */
54: PetscPreLoadBegin(PETSC_FALSE,"Load system");
56: /* - - - - - - - - - - - New Stage - - - - - - - - - - - - -
57: Load system
58: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
60: /*
61: Open binary file. Note that we use FILE_MODE_READ to indicate
62: reading from this file.
63: */
64: PetscViewerBinaryOpen(PETSC_COMM_WORLD,file,FILE_MODE_READ,&fd);
66: /*
67: Load the matrix and vector; then destroy the viewer.
68: */
69: MatCreate(PETSC_COMM_WORLD,&A);
70: MatSetType(A,MATMPIAIJ);
71: MatLoad(A,fd);
72: VecCreate(PETSC_COMM_WORLD,&b);
73: PetscPushErrorHandler(PetscIgnoreErrorHandler,PETSC_NULL);
74: ierrp = VecLoad(b,fd);
75: PetscPopErrorHandler();
76: MatGetLocalSize(A,&m,&n);
77: if (ierrp) { /* if file contains no RHS, then use a vector of all ones */
78: PetscScalar one = 1.0;
79: VecCreate(PETSC_COMM_WORLD,&b);
80: VecSetSizes(b,m,PETSC_DECIDE);
81: VecSetFromOptions(b);
82: VecSet(b,one);
83: }
84: PetscViewerDestroy(&fd);
86: /*
87: If the loaded matrix is larger than the vector (due to being padded
88: to match the block size of the system), then create a new padded vector.
89: */
90: {
91: PetscInt j,mvec,start,end,idex;
92: Vec tmp;
93: PetscScalar *bold;
95: /* Create a new vector b by padding the old one */
96: VecCreate(PETSC_COMM_WORLD,&tmp);
97: VecSetSizes(tmp,m,PETSC_DECIDE);
98: VecSetFromOptions(tmp);
99: VecGetOwnershipRange(b,&start,&end);
100: VecGetLocalSize(b,&mvec);
101: VecGetArray(b,&bold);
102: for (j=0; j<mvec; j++) {
103: idex = start+j;
104: VecSetValues(tmp,1,&idex,bold+j,INSERT_VALUES);
105: }
106: VecRestoreArray(b,&bold);
107: VecDestroy(&b);
108: VecAssemblyBegin(tmp);
109: VecAssemblyEnd(tmp);
110: b = tmp;
111: }
112: VecDuplicate(b,&u);
113: VecCreateMPI(PETSC_COMM_WORLD,n,PETSC_DECIDE,&x);
114: VecDuplicate(x,&Ab);
115: VecSet(x,0.0);
117: /* - - - - - - - - - - - New Stage - - - - - - - - - - - - -
118: Setup solve for system
119: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
121: /*
122: Conclude profiling last stage; begin profiling next stage.
123: */
124: PetscPreLoadStage("KSPSetUp");
126: MatCreateNormal(A,&N);
127: MatMultTranspose(A,b,Ab);
129: /*
130: Create linear solver; set operators; set runtime options.
131: */
132: KSPCreate(PETSC_COMM_WORLD,&ksp);
134: KSPSetOperators(ksp,N,N,SAME_NONZERO_PATTERN);
135: KSPSetFromOptions(ksp);
137: /*
138: Here we explicitly call KSPSetUp() and KSPSetUpOnBlocks() to
139: enable more precise profiling of setting up the preconditioner.
140: These calls are optional, since both will be called within
141: KSPSolve() if they haven't been called already.
142: */
143: KSPSetUp(ksp);
144: KSPSetUpOnBlocks(ksp);
146: /*
147: Solve system
148: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
150: /*
151: Begin profiling next stage
152: */
153: PetscPreLoadStage("KSPSolve");
155: /*
156: Solve linear system
157: */
158: KSPSolve(ksp,Ab,x);
160: /*
161: Conclude profiling this stage
162: */
163: PetscPreLoadStage("Cleanup");
165: /* - - - - - - - - - - - New Stage - - - - - - - - - - - - -
166: Check error, print output, free data structures.
167: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
169: /*
170: Check error
171: */
172: MatMult(A,x,u);
173: VecAXPY(u,-1.0,b);
174: VecNorm(u,NORM_2,&norm);
175: KSPGetIterationNumber(ksp,&its);
176: PetscPrintf(PETSC_COMM_WORLD,"Number of iterations = %3D\n",its);
177: PetscPrintf(PETSC_COMM_WORLD,"Residual norm %G\n",norm);
179: /*
180: Free work space. All PETSc objects should be destroyed when they
181: are no longer needed.
182: */
183: MatDestroy(&A); VecDestroy(&b);
184: MatDestroy(&N); VecDestroy(&Ab);
185: VecDestroy(&u); VecDestroy(&x);
186: KSPDestroy(&ksp);
187: PetscPreLoadEnd();
188: /* -----------------------------------------------------------
189: End of linear solver loop
190: ----------------------------------------------------------- */
192: PetscFinalize();
193: return 0;
194: }