Actual source code: ex17.c

petsc-3.10.5 2019-03-28
Report Typos and Errors
  1: static const char help[] = "Newton's method to solve a two-variable system, sequentially.\n"
  2:                            "The same problem is solved twice - i) fully assembled system + ii) block system\n\n";

  4: /*T
  5: Concepts: SNES^basic uniprocessor example, block objects
  6: Processors: 1
  7: T*/



 11: /*
 12: Include "petscsnes.h" so that we can use SNES solvers.  Note that this
 13: file automatically includes:
 14: petscsys.h       - base PETSc routines   petscvec.h - vectors
 15: petscsys.h    - system routines       petscmat.h - matrices
 16: petscis.h     - index sets            petscksp.h - Krylov subspace methods
 17: petscviewer.h - viewers               petscpc.h  - preconditioners
 18: petscksp.h   - linear solvers
 19: */
 20:  #include <petscsnes.h>

 22: /*
 23: This example is block version of the test found at
 24:   ${PETSC_DIR}/src/snes/examples/tutorials/ex1.c
 25: In this test we replace the Jacobian systems
 26:   [J]{x} = {F}
 27: where

 29: [J] = (j_00, j_01),  {x} = (x_0, x_1)^T,   {F} = (f_0, f_1)^T
 30:       (j_10, j_11)
 31: where [J] \in \mathbb^{2 \times 2}, {x},{F} \in \mathbb^{2 \times 1},

 33: with a block system in which each block is of length 1.
 34: i.e. The block system is thus

 36: [J] = ([j00], [j01]),  {x} = ({x0}, {x1})^T, {F} = ({f0}, {f1})^T
 37:       ([j10], [j11])
 38: where
 39: [j00], [j01], [j10], [j11] \in \mathbb^{1 \times 1}
 40: {x0}, {x1}, {f0}, {f1} \in \mathbb^{1 \times 1}

 42: In practice we would not bother defing blocks of size one, and would instead assemble the
 43: full system. This is just a simple test to illustrate how to manipulate the blocks and
 44: to confirm the implementation is correct.
 45: */

 47: /*
 48: User-defined routines
 49: */
 50: static PetscErrorCode FormJacobian1(SNES,Vec,Mat,Mat,void*);
 51: static PetscErrorCode FormFunction1(SNES,Vec,Vec,void*);
 52: static PetscErrorCode FormJacobian2(SNES,Vec,Mat,Mat,void*);
 53: static PetscErrorCode FormFunction2(SNES,Vec,Vec,void*);
 54: static PetscErrorCode FormJacobian1_block(SNES,Vec,Mat,Mat,void*);
 55: static PetscErrorCode FormFunction1_block(SNES,Vec,Vec,void*);
 56: static PetscErrorCode FormJacobian2_block(SNES,Vec,Mat,Mat,void*);
 57: static PetscErrorCode FormFunction2_block(SNES,Vec,Vec,void*);


 60: static PetscErrorCode assembled_system(void)
 61: {
 62:   SNES           snes;         /* nonlinear solver context */
 63:   KSP            ksp;         /* linear solver context */
 64:   PC             pc;           /* preconditioner context */
 65:   Vec            x,r;         /* solution, residual vectors */
 66:   Mat            J;            /* Jacobian matrix */
 68:   PetscInt       its;
 69:   PetscScalar    pfive = .5,*xx;
 70:   PetscBool      flg;

 73:   PetscPrintf(PETSC_COMM_WORLD, "\n\n========================= Assembled system =========================\n\n");

 75:   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 76:   Create nonlinear solver context
 77:   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

 79:   SNESCreate(PETSC_COMM_WORLD,&snes);

 81:   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 82:   Create matrix and vector data structures; set corresponding routines
 83:   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

 85:   /*
 86:   Create vectors for solution and nonlinear function
 87:   */
 88:   VecCreateSeq(PETSC_COMM_SELF,2,&x);
 89:   VecDuplicate(x,&r);

 91:   /*
 92:   Create Jacobian matrix data structure
 93:   */
 94:   MatCreate(PETSC_COMM_SELF,&J);
 95:   MatSetSizes(J,PETSC_DECIDE,PETSC_DECIDE,2,2);
 96:   MatSetFromOptions(J);
 97:   MatSetUp(J);

 99:   PetscOptionsHasName(NULL,NULL,"-hard",&flg);
100:   if (!flg) {
101:     /*
102:     Set function evaluation routine and vector.
103:     */
104:     SNESSetFunction(snes,r,FormFunction1,NULL);

106:     /*
107:     Set Jacobian matrix data structure and Jacobian evaluation routine
108:     */
109:     SNESSetJacobian(snes,J,J,FormJacobian1,NULL);
110:   } else {
111:     SNESSetFunction(snes,r,FormFunction2,NULL);
112:     SNESSetJacobian(snes,J,J,FormJacobian2,NULL);
113:   }

115:   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
116:   Customize nonlinear solver; set runtime options
117:   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

119:   /*
120:   Set linear solver defaults for this problem. By extracting the
121:   KSP, KSP, and PC contexts from the SNES context, we can then
122:   directly call any KSP, KSP, and PC routines to set various options.
123:   */
124:   SNESGetKSP(snes,&ksp);
125:   KSPGetPC(ksp,&pc);
126:   PCSetType(pc,PCNONE);
127:   KSPSetTolerances(ksp,1.e-4,PETSC_DEFAULT,PETSC_DEFAULT,20);

129:   /*
130:   Set SNES/KSP/KSP/PC runtime options, e.g.,
131:   -snes_view -snes_monitor -ksp_type <ksp> -pc_type <pc>
132:   These options will override those specified above as long as
133:   SNESSetFromOptions() is called _after_ any other customization
134:   routines.
135:   */
136:   SNESSetFromOptions(snes);

138:   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
139:   Evaluate initial guess; then solve nonlinear system
140:   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
141:   if (!flg) {
142:     VecSet(x,pfive);
143:   } else {
144:     VecGetArray(x,&xx);
145:     xx[0] = 2.0; xx[1] = 3.0;
146:     VecRestoreArray(x,&xx);
147:   }
148:   /*
149:   Note: The user should initialize the vector, x, with the initial guess
150:   for the nonlinear solver prior to calling SNESSolve().  In particular,
151:   to employ an initial guess of zero, the user should explicitly set
152:   this vector to zero by calling VecSet().
153:   */

155:   SNESSolve(snes,NULL,x);
156:   SNESGetIterationNumber(snes,&its);
157:   if (flg) {
158:     Vec f;
159:     VecView(x,PETSC_VIEWER_STDOUT_WORLD);
160:     SNESGetFunction(snes,&f,0,0);
161:     VecView(r,PETSC_VIEWER_STDOUT_WORLD);
162:   }

164:   PetscPrintf(PETSC_COMM_SELF,"number of SNES iterations = %D\n\n",its);

166:   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
167:   Free work space.  All PETSc objects should be destroyed when they
168:   are no longer needed.
169:   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

171:   VecDestroy(&x); VecDestroy(&r);
172:   MatDestroy(&J); SNESDestroy(&snes);
173:   return(0);
174: }

176: /* ------------------------------------------------------------------- */
177: /*
178: FormFunction1 - Evaluates nonlinear function, F(x).

180: Input Parameters:
181: .  snes - the SNES context
182: .  x - input vector
183: .  dummy - optional user-defined context (not used here)

185: Output Parameter:
186: .  f - function vector
187: */
188: static PetscErrorCode FormFunction1(SNES snes,Vec x,Vec f,void *dummy)
189: {
190:   PetscErrorCode    ierr;
191:   const PetscScalar *xx;
192:   PetscScalar       *ff;

195:   /*
196:   Get pointers to vector data.
197:   - For default PETSc vectors, VecGetArray() returns a pointer to
198:   the data array.  Otherwise, the routine is implementation dependent.
199:   - You MUST call VecRestoreArray() when you no longer need access to
200:   the array.
201:   */
202:   VecGetArrayRead(x,&xx);
203:   VecGetArray(f,&ff);

205:   /*
206:   Compute function
207:   */
208:   ff[0] = xx[0]*xx[0] + xx[0]*xx[1] - 3.0;
209:   ff[1] = xx[0]*xx[1] + xx[1]*xx[1] - 6.0;


212:   /*
213:   Restore vectors
214:   */
215:   VecRestoreArrayRead(x,&xx);
216:   VecRestoreArray(f,&ff);
217:   return(0);
218: }
219: /* ------------------------------------------------------------------- */
220: /*
221: FormJacobian1 - Evaluates Jacobian matrix.

223: Input Parameters:
224: .  snes - the SNES context
225: .  x - input vector
226: .  dummy - optional user-defined context (not used here)

228: Output Parameters:
229: .  jac - Jacobian matrix
230: .  B - optionally different preconditioning matrix
231: .  flag - flag indicating matrix structure
232: */
233: static PetscErrorCode FormJacobian1(SNES snes,Vec x,Mat jac,Mat B,void *dummy)
234: {
235:   const PetscScalar *xx;
236:   PetscScalar       A[4];
237:   PetscErrorCode    ierr;
238:   PetscInt          idx[2] = {0,1};

241:   /*
242:   Get pointer to vector data
243:   */
244:   VecGetArrayRead(x,&xx);

246:   /*
247:   Compute Jacobian entries and insert into matrix.
248:   - Since this is such a small problem, we set all entries for
249:   the matrix at once.
250:   */
251:   A[0]  = 2.0*xx[0] + xx[1]; A[1] = xx[0];
252:   A[2]  = xx[1]; A[3] = xx[0] + 2.0*xx[1];
253:   MatSetValues(jac,2,idx,2,idx,A,INSERT_VALUES);

255:   /*
256:   Restore vector
257:   */
258:   VecRestoreArrayRead(x,&xx);

260:   /*
261:   Assemble matrix
262:   */
263:   MatAssemblyBegin(jac,MAT_FINAL_ASSEMBLY);
264:   MatAssemblyEnd(jac,MAT_FINAL_ASSEMBLY);
265:   return(0);
266: }


269: /* ------------------------------------------------------------------- */
270: static PetscErrorCode FormFunction2(SNES snes,Vec x,Vec f,void *dummy)
271: {
272:   PetscErrorCode    ierr;
273:   const PetscScalar *xx;
274:   PetscScalar       *ff;

277:   /*
278:   Get pointers to vector data.
279:   - For default PETSc vectors, VecGetArray() returns a pointer to
280:   the data array.  Otherwise, the routine is implementation dependent.
281:   - You MUST call VecRestoreArray() when you no longer need access to
282:   the array.
283:   */
284:   VecGetArrayRead(x,&xx);
285:   VecGetArray(f,&ff);

287:   /*
288:   Compute function
289:   */
290:   ff[0] = PetscSinScalar(3.0*xx[0]) + xx[0];
291:   ff[1] = xx[1];

293:   /*
294:   Restore vectors
295:   */
296:   VecRestoreArrayRead(x,&xx);
297:   VecRestoreArray(f,&ff);
298:   return(0);
299: }

301: /* ------------------------------------------------------------------- */
302: static PetscErrorCode FormJacobian2(SNES snes,Vec x,Mat jac,Mat B,void *dummy)
303: {
304:   const PetscScalar *xx;
305:   PetscScalar       A[4];
306:   PetscErrorCode    ierr;
307:   PetscInt          idx[2] = {0,1};

310:   /*
311:   Get pointer to vector data
312:   */
313:   VecGetArrayRead(x,&xx);

315:   /*
316:   Compute Jacobian entries and insert into matrix.
317:   - Since this is such a small problem, we set all entries for
318:   the matrix at once.
319:   */
320:   A[0]  = 3.0*PetscCosScalar(3.0*xx[0]) + 1.0; A[1] = 0.0;
321:   A[2]  = 0.0;                     A[3] = 1.0;
322:   MatSetValues(jac,2,idx,2,idx,A,INSERT_VALUES);

324:   /*
325:   Restore vector
326:   */
327:   VecRestoreArrayRead(x,&xx);

329:   /*
330:   Assemble matrix
331:   */
332:   MatAssemblyBegin(jac,MAT_FINAL_ASSEMBLY);
333:   MatAssemblyEnd(jac,MAT_FINAL_ASSEMBLY);
334:   return(0);
335: }

337: static int block_system(void)
338: {
339:   SNES           snes;         /* nonlinear solver context */
340:   KSP            ksp;         /* linear solver context */
341:   PC             pc;           /* preconditioner context */
342:   Vec            x,r;         /* solution, residual vectors */
343:   Mat            J;            /* Jacobian matrix */
345:   PetscInt       its;
346:   PetscScalar    pfive = .5;
347:   PetscBool      flg;

349:   Mat j11, j12, j21, j22;
350:   Vec x1, x2, r1, r2;
351:   Vec bv;
352:   Vec bx[2];
353:   Mat bA[2][2];

356:   PetscPrintf(PETSC_COMM_WORLD, "\n\n========================= Block system =========================\n\n");

358:   SNESCreate(PETSC_COMM_WORLD,&snes);

360:   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
361:   Create matrix and vector data structures; set corresponding routines
362:   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

364:   /*
365:   Create sub vectors for solution and nonlinear function
366:   */
367:   VecCreateSeq(PETSC_COMM_SELF,1,&x1);
368:   VecDuplicate(x1,&r1);

370:   VecCreateSeq(PETSC_COMM_SELF,1,&x2);
371:   VecDuplicate(x2,&r2);

373:   /*
374:   Create the block vectors
375:   */
376:   bx[0] = x1;
377:   bx[1] = x2;
378:   VecCreateNest(PETSC_COMM_WORLD,2,NULL,bx,&x);
379:   VecAssemblyBegin(x);
380:   VecAssemblyEnd(x);
381:   VecDestroy(&x1);
382:   VecDestroy(&x2);

384:   bx[0] = r1;
385:   bx[1] = r2;
386:   VecCreateNest(PETSC_COMM_WORLD,2,NULL,bx,&r);
387:   VecDestroy(&r1);
388:   VecDestroy(&r2);
389:   VecAssemblyBegin(r);
390:   VecAssemblyEnd(r);

392:   /*
393:   Create sub Jacobian matrix data structure
394:   */
395:   MatCreate(PETSC_COMM_WORLD, &j11);
396:   MatSetSizes(j11, 1, 1, 1, 1);
397:   MatSetType(j11, MATSEQAIJ);
398:   MatSetUp(j11);

400:   MatCreate(PETSC_COMM_WORLD, &j12);
401:   MatSetSizes(j12, 1, 1, 1, 1);
402:   MatSetType(j12, MATSEQAIJ);
403:   MatSetUp(j12);

405:   MatCreate(PETSC_COMM_WORLD, &j21);
406:   MatSetSizes(j21, 1, 1, 1, 1);
407:   MatSetType(j21, MATSEQAIJ);
408:   MatSetUp(j21);

410:   MatCreate(PETSC_COMM_WORLD, &j22);
411:   MatSetSizes(j22, PETSC_DECIDE, PETSC_DECIDE, 1, 1);
412:   MatSetType(j22, MATSEQAIJ);
413:   MatSetUp(j22);
414:   /*
415:   Create block Jacobian matrix data structure
416:   */
417:   bA[0][0] = j11;
418:   bA[0][1] = j12;
419:   bA[1][0] = j21;
420:   bA[1][1] = j22;

422:   MatCreateNest(PETSC_COMM_WORLD,2,NULL,2,NULL,&bA[0][0],&J);
423:   MatSetUp(J);
424:   MatNestSetVecType(J,VECNEST);
425:   MatDestroy(&j11);
426:   MatDestroy(&j12);
427:   MatDestroy(&j21);
428:   MatDestroy(&j22);

430:   MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);
431:   MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);

433:   PetscOptionsHasName(NULL,NULL,"-hard",&flg);
434:   if (!flg) {
435:     /*
436:     Set function evaluation routine and vector.
437:     */
438:     SNESSetFunction(snes,r,FormFunction1_block,NULL);

440:     /*
441:     Set Jacobian matrix data structure and Jacobian evaluation routine
442:     */
443:     SNESSetJacobian(snes,J,J,FormJacobian1_block,NULL);
444:   } else {
445:     SNESSetFunction(snes,r,FormFunction2_block,NULL);
446:     SNESSetJacobian(snes,J,J,FormJacobian2_block,NULL);
447:   }

449:   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
450:   Customize nonlinear solver; set runtime options
451:   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

453:   /*
454:   Set linear solver defaults for this problem. By extracting the
455:   KSP, KSP, and PC contexts from the SNES context, we can then
456:   directly call any KSP, KSP, and PC routines to set various options.
457:   */
458:   SNESGetKSP(snes,&ksp);
459:   KSPGetPC(ksp,&pc);
460:   PCSetType(pc,PCNONE);
461:   KSPSetTolerances(ksp,1.e-4,PETSC_DEFAULT,PETSC_DEFAULT,20);

463:   /*
464:   Set SNES/KSP/KSP/PC runtime options, e.g.,
465:   -snes_view -snes_monitor -ksp_type <ksp> -pc_type <pc>
466:   These options will override those specified above as long as
467:   SNESSetFromOptions() is called _after_ any other customization
468:   routines.
469:   */
470:   SNESSetFromOptions(snes);

472:   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
473:   Evaluate initial guess; then solve nonlinear system
474:   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
475:   if (!flg) {
476:     VecSet(x,pfive);
477:   } else {
478:     Vec *vecs;
479:     VecNestGetSubVecs(x, NULL, &vecs);
480:     bv   = vecs[0];
481: /*    VecBlockGetSubVec(x, 0, &bv); */
482:     VecSetValue(bv, 0, 2.0, INSERT_VALUES);  /* xx[0] = 2.0; */
483:     VecAssemblyBegin(bv);
484:     VecAssemblyEnd(bv);

486: /*    VecBlockGetSubVec(x, 1, &bv); */
487:     bv   = vecs[1];
488:     VecSetValue(bv, 0, 3.0, INSERT_VALUES);  /* xx[1] = 3.0; */
489:     VecAssemblyBegin(bv);
490:     VecAssemblyEnd(bv);
491:   }
492:   /*
493:   Note: The user should initialize the vector, x, with the initial guess
494:   for the nonlinear solver prior to calling SNESSolve().  In particular,
495:   to employ an initial guess of zero, the user should explicitly set
496:   this vector to zero by calling VecSet().
497:   */
498:   SNESSolve(snes,NULL,x);
499:   SNESGetIterationNumber(snes,&its);
500:   if (flg) {
501:     Vec f;
502:     VecView(x,PETSC_VIEWER_STDOUT_WORLD);
503:     SNESGetFunction(snes,&f,0,0);
504:     VecView(r,PETSC_VIEWER_STDOUT_WORLD);
505:   }

507:   PetscPrintf(PETSC_COMM_SELF,"number of SNES iterations = %D\n\n",its);

509:   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
510:   Free work space.  All PETSc objects should be destroyed when they
511:   are no longer needed.
512:   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
513:   VecDestroy(&x); VecDestroy(&r);
514:   MatDestroy(&J); SNESDestroy(&snes);
515:   return(0);
516: }

518: /* ------------------------------------------------------------------- */
519: static PetscErrorCode FormFunction1_block(SNES snes,Vec x,Vec f,void *dummy)
520: {
521:   Vec            *xx, *ff, x1,x2, f1,f2;
522:   PetscScalar    ff_0, ff_1;
523:   PetscScalar    xx_0, xx_1;
524:   PetscInt       index,nb;

528:   /* get blocks for function */
529:   VecNestGetSubVecs(f, &nb, &ff);
530:   f1   = ff[0];  f2 = ff[1];

532:   /* get blocks for solution */
533:   VecNestGetSubVecs(x, &nb, &xx);
534:   x1   = xx[0];  x2 = xx[1];

536:   /* get solution values */
537:   index = 0;
538:   VecGetValues(x1,1, &index, &xx_0);
539:   VecGetValues(x2,1, &index, &xx_1);

541:   /* Compute function */
542:   ff_0 = xx_0*xx_0 + xx_0*xx_1 - 3.0;
543:   ff_1 = xx_0*xx_1 + xx_1*xx_1 - 6.0;

545:   /* set function values */
546:   VecSetValue(f1, index, ff_0, INSERT_VALUES);

548:   VecSetValue(f2, index, ff_1, INSERT_VALUES);

550:   VecAssemblyBegin(f);
551:   VecAssemblyEnd(f);
552:   return(0);
553: }

555: /* ------------------------------------------------------------------- */
556: static PetscErrorCode FormJacobian1_block(SNES snes,Vec x,Mat jac,Mat B,void *dummy)
557: {
558:   Vec            *xx, x1,x2;
559:   PetscScalar    xx_0, xx_1;
560:   PetscInt       index,nb;
561:   PetscScalar    A_00, A_01, A_10, A_11;
562:   Mat            j11, j12, j21, j22;
563:   Mat            **mats;

567:   /* get blocks for solution */
568:   VecNestGetSubVecs(x, &nb, &xx);
569:   x1   = xx[0];  x2 = xx[1];

571:   /* get solution values */
572:   index = 0;
573:   VecGetValues(x1,1, &index, &xx_0);
574:   VecGetValues(x2,1, &index, &xx_1);

576:   /* get block matrices */
577:   MatNestGetSubMats(jac,NULL,NULL,&mats);
578:   j11  = mats[0][0];
579:   j12  = mats[0][1];
580:   j21  = mats[1][0];
581:   j22  = mats[1][1];

583:   /* compute jacobian entries */
584:   A_00 = 2.0*xx_0 + xx_1;
585:   A_01 = xx_0;
586:   A_10 = xx_1;
587:   A_11 = xx_0 + 2.0*xx_1;

589:   /* set jacobian values */
590:   MatSetValue(j11, 0,0, A_00, INSERT_VALUES);
591:   MatSetValue(j12, 0,0, A_01, INSERT_VALUES);
592:   MatSetValue(j21, 0,0, A_10, INSERT_VALUES);
593:   MatSetValue(j22, 0,0, A_11, INSERT_VALUES);

595:   /* Assemble sub matrix */
596:   MatAssemblyBegin(jac,MAT_FINAL_ASSEMBLY);
597:   MatAssemblyEnd(jac,MAT_FINAL_ASSEMBLY);
598:   return(0);
599: }

601: /* ------------------------------------------------------------------- */
602: static PetscErrorCode FormFunction2_block(SNES snes,Vec x,Vec f,void *dummy)
603: {
604:   PetscErrorCode    ierr;
605:   PetscScalar       *ff;
606:   const PetscScalar *xx;

609:   /*
610:   Get pointers to vector data.
611:   - For default PETSc vectors, VecGetArray() returns a pointer to
612:   the data array.  Otherwise, the routine is implementation dependent.
613:   - You MUST call VecRestoreArray() when you no longer need access to
614:   the array.
615:   */
616:   VecGetArrayRead(x,&xx);
617:   VecGetArray(f,&ff);

619:   /*
620:   Compute function
621:   */
622:   ff[0] = PetscSinScalar(3.0*xx[0]) + xx[0];
623:   ff[1] = xx[1];

625:   /*
626:   Restore vectors
627:   */
628:   VecRestoreArrayRead(x,&xx);
629:   VecRestoreArray(f,&ff);
630:   return(0);
631: }

633: /* ------------------------------------------------------------------- */
634: static PetscErrorCode FormJacobian2_block(SNES snes,Vec x,Mat jac,Mat B,void *dummy)
635: {
636:   const PetscScalar *xx;
637:   PetscScalar       A[4];
638:   PetscErrorCode    ierr;
639:   PetscInt          idx[2] = {0,1};

642:   /*
643:   Get pointer to vector data
644:   */
645:   VecGetArrayRead(x,&xx);

647:   /*
648:   Compute Jacobian entries and insert into matrix.
649:   - Since this is such a small problem, we set all entries for
650:   the matrix at once.
651:   */
652:   A[0]  = 3.0*PetscCosScalar(3.0*xx[0]) + 1.0; A[1] = 0.0;
653:   A[2]  = 0.0;                     A[3] = 1.0;
654:   MatSetValues(jac,2,idx,2,idx,A,INSERT_VALUES);

656:   /*
657:   Restore vector
658:   */
659:   VecRestoreArrayRead(x,&xx);

661:   /*
662:   Assemble matrix
663:   */
664:   MatAssemblyBegin(jac,MAT_FINAL_ASSEMBLY);
665:   MatAssemblyEnd(jac,MAT_FINAL_ASSEMBLY);
666:   return(0);
667: }

669: int main(int argc,char **argv)
670: {
671:   PetscMPIInt    size;

674:   PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr;

676:   MPI_Comm_size(PETSC_COMM_WORLD,&size);
677:   if (size != 1) SETERRQ(PETSC_COMM_WORLD, 1,"This is a uniprocessor example only!");

679:   assembled_system();

681:   block_system();

683:   PetscFinalize();
684:   return ierr;
685: }


688: /*TEST

690:    test:
691:       args: -snes_monitor_short
692:       requires: !single

694: TEST*/