Actual source code: ex1.c
2: static char help[] = "Newton's method to solve a two-variable system, sequentially.\n\n";
4: /*T
5: Concepts: SNES^basic uniprocessor example
6: Processors: 1
7: T*/
9: /*
10: Include "petscsnes.h" so that we can use SNES solvers. Note that this
11: file automatically includes:
12: petsc.h - base PETSc routines petscvec.h - vectors
13: petscsys.h - system routines petscmat.h - matrices
14: petscis.h - index sets petscksp.h - Krylov subspace methods
15: petscviewer.h - viewers petscpc.h - preconditioners
16: petscksp.h - linear solvers
17: */
18: #include petscsnes.h
20: /*
21: User-defined routines
22: */
30: int main(int argc,char **argv)
31: {
32: SNES snes; /* nonlinear solver context */
33: KSP ksp; /* linear solver context */
34: PC pc; /* preconditioner context */
35: Vec x,r; /* solution, residual vectors */
36: Mat J; /* Jacobian matrix */
38: PetscInt its;
39: PetscMPIInt size;
40: PetscScalar pfive = .5,*xx;
41: PetscTruth flg;
43: PetscInitialize(&argc,&argv,(char *)0,help);
44: MPI_Comm_size(PETSC_COMM_WORLD,&size);
45: if (size != 1) SETERRQ(1,"This is a uniprocessor example only!");
47: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
48: Create nonlinear solver context
49: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
51: SNESCreate(PETSC_COMM_WORLD,&snes);
53: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
54: Create matrix and vector data structures; set corresponding routines
55: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
57: /*
58: Create vectors for solution and nonlinear function
59: */
60: VecCreateSeq(PETSC_COMM_SELF,2,&x);
61: VecDuplicate(x,&r);
63: /*
64: Create Jacobian matrix data structure
65: */
66: MatCreate(PETSC_COMM_SELF,PETSC_DECIDE,PETSC_DECIDE,2,2,&J);
67: MatSetFromOptions(J);
69: PetscOptionsHasName(PETSC_NULL,"-hard",&flg);
70: if (!flg) {
71: /*
72: Set function evaluation routine and vector.
73: */
74: SNESSetFunction(snes,r,FormFunction1,PETSC_NULL);
76: /*
77: Set Jacobian matrix data structure and Jacobian evaluation routine
78: */
79: SNESSetJacobian(snes,J,J,FormJacobian1,PETSC_NULL);
80: } else {
81: SNESSetFunction(snes,r,FormFunction2,PETSC_NULL);
82: SNESSetJacobian(snes,J,J,FormJacobian2,PETSC_NULL);
83: }
85: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
86: Customize nonlinear solver; set runtime options
87: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
89: /*
90: Set linear solver defaults for this problem. By extracting the
91: KSP, KSP, and PC contexts from the SNES context, we can then
92: directly call any KSP, KSP, and PC routines to set various options.
93: */
94: SNESGetKSP(snes,&ksp);
95: KSPGetPC(ksp,&pc);
96: PCSetType(pc,PCNONE);
97: KSPSetTolerances(ksp,1.e-4,PETSC_DEFAULT,PETSC_DEFAULT,20);
99: /*
100: Set SNES/KSP/KSP/PC runtime options, e.g.,
101: -snes_view -snes_monitor -ksp_type <ksp> -pc_type <pc>
102: These options will override those specified above as long as
103: SNESSetFromOptions() is called _after_ any other customization
104: routines.
105: */
106: SNESSetFromOptions(snes);
108: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
109: Evaluate initial guess; then solve nonlinear system
110: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
111: if (!flg) {
112: VecSet(&pfive,x);
113: } else {
114: VecGetArray(x,&xx);
115: xx[0] = 2.0; xx[1] = 3.0;
116: VecRestoreArray(x,&xx);
117: }
118: /*
119: Note: The user should initialize the vector, x, with the initial guess
120: for the nonlinear solver prior to calling SNESSolve(). In particular,
121: to employ an initial guess of zero, the user should explicitly set
122: this vector to zero by calling VecSet().
123: */
125: SNESSolve(snes,x);
126: SNESGetIterationNumber(snes,&its);
127: if (flg) {
128: Vec f;
129: VecView(x,PETSC_VIEWER_STDOUT_WORLD);
130: SNESGetFunction(snes,&f,0,0);
131: VecView(r,PETSC_VIEWER_STDOUT_WORLD);
132: }
134: PetscPrintf(PETSC_COMM_SELF,"number of Newton iterations = %D\n\n",its);
136: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
137: Free work space. All PETSc objects should be destroyed when they
138: are no longer needed.
139: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
141: VecDestroy(x); VecDestroy(r);
142: MatDestroy(J); SNESDestroy(snes);
144: PetscFinalize();
145: return 0;
146: }
147: /* ------------------------------------------------------------------- */
150: /*
151: FormFunction1 - Evaluates nonlinear function, F(x).
153: Input Parameters:
154: . snes - the SNES context
155: . x - input vector
156: . dummy - optional user-defined context (not used here)
158: Output Parameter:
159: . f - function vector
160: */
161: PetscErrorCode FormFunction1(SNES snes,Vec x,Vec f,void *dummy)
162: {
164: PetscScalar *xx,*ff;
166: /*
167: Get pointers to vector data.
168: - For default PETSc vectors, VecGetArray() returns a pointer to
169: the data array. Otherwise, the routine is implementation dependent.
170: - You MUST call VecRestoreArray() when you no longer need access to
171: the array.
172: */
173: VecGetArray(x,&xx);
174: VecGetArray(f,&ff);
176: /*
177: Compute function
178: */
179: ff[0] = xx[0]*xx[0] + xx[0]*xx[1] - 3.0;
180: ff[1] = xx[0]*xx[1] + xx[1]*xx[1] - 6.0;
182: /*
183: Restore vectors
184: */
185: VecRestoreArray(x,&xx);
186: VecRestoreArray(f,&ff);
188: return 0;
189: }
190: /* ------------------------------------------------------------------- */
193: /*
194: FormJacobian1 - Evaluates Jacobian matrix.
196: Input Parameters:
197: . snes - the SNES context
198: . x - input vector
199: . dummy - optional user-defined context (not used here)
201: Output Parameters:
202: . jac - Jacobian matrix
203: . B - optionally different preconditioning matrix
204: . flag - flag indicating matrix structure
205: */
206: PetscErrorCode FormJacobian1(SNES snes,Vec x,Mat *jac,Mat *B,MatStructure *flag,void *dummy)
207: {
208: PetscScalar *xx,A[4];
210: PetscInt idx[2] = {0,1};
212: /*
213: Get pointer to vector data
214: */
215: VecGetArray(x,&xx);
217: /*
218: Compute Jacobian entries and insert into matrix.
219: - Since this is such a small problem, we set all entries for
220: the matrix at once.
221: */
222: A[0] = 2.0*xx[0] + xx[1]; A[1] = xx[0];
223: A[2] = xx[1]; A[3] = xx[0] + 2.0*xx[1];
224: MatSetValues(*jac,2,idx,2,idx,A,INSERT_VALUES);
225: *flag = SAME_NONZERO_PATTERN;
227: /*
228: Restore vector
229: */
230: VecRestoreArray(x,&xx);
232: /*
233: Assemble matrix
234: */
235: MatAssemblyBegin(*jac,MAT_FINAL_ASSEMBLY);
236: MatAssemblyEnd(*jac,MAT_FINAL_ASSEMBLY);
238: return 0;
239: }
242: /* ------------------------------------------------------------------- */
245: PetscErrorCode FormFunction2(SNES snes,Vec x,Vec f,void *dummy)
246: {
248: PetscScalar *xx,*ff;
250: /*
251: Get pointers to vector data.
252: - For default PETSc vectors, VecGetArray() returns a pointer to
253: the data array. Otherwise, the routine is implementation dependent.
254: - You MUST call VecRestoreArray() when you no longer need access to
255: the array.
256: */
257: VecGetArray(x,&xx);
258: VecGetArray(f,&ff);
260: /*
261: Compute function
262: */
263: ff[0] = PetscSinScalar(3.0*xx[0]) + xx[0];
264: ff[1] = xx[1];
266: /*
267: Restore vectors
268: */
269: VecRestoreArray(x,&xx);
270: VecRestoreArray(f,&ff);
272: return 0;
273: }
274: /* ------------------------------------------------------------------- */
277: PetscErrorCode FormJacobian2(SNES snes,Vec x,Mat *jac,Mat *B,MatStructure *flag,void *dummy)
278: {
279: PetscScalar *xx,A[4];
281: PetscInt idx[2] = {0,1};
283: /*
284: Get pointer to vector data
285: */
286: VecGetArray(x,&xx);
288: /*
289: Compute Jacobian entries and insert into matrix.
290: - Since this is such a small problem, we set all entries for
291: the matrix at once.
292: */
293: A[0] = 3.0*PetscCosScalar(3.0*xx[0]) + 1.0; A[1] = 0.0;
294: A[2] = 0.0; A[3] = 1.0;
295: MatSetValues(*jac,2,idx,2,idx,A,INSERT_VALUES);
296: *flag = SAME_NONZERO_PATTERN;
298: /*
299: Restore vector
300: */
301: VecRestoreArray(x,&xx);
303: /*
304: Assemble matrix
305: */
306: MatAssemblyBegin(*jac,MAT_FINAL_ASSEMBLY);
307: MatAssemblyEnd(*jac,MAT_FINAL_ASSEMBLY);
309: return 0;
310: }