Actual source code: ex17.c

petsc-3.5.4 2015-05-23
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*/

  9: /*
 10: Include "petscsnes.h" so that we can use SNES solvers.  Note that this
 11: file automatically includes:
 12: petscsys.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: This example is block version of the test found at
 22:   ${PETSC_DIR}/src/snes/examples/tutorials/ex1.c
 23: In this test we replace the Jacobian systems
 24:   [J]{x} = {F}
 25: where

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

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

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

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

 45: /*
 46: User-defined routines
 47: */
 48: static PetscErrorCode FormJacobian1(SNES,Vec,Mat,Mat,void*);
 49: static PetscErrorCode FormFunction1(SNES,Vec,Vec,void*);
 50: static PetscErrorCode FormJacobian2(SNES,Vec,Mat,Mat,void*);
 51: static PetscErrorCode FormFunction2(SNES,Vec,Vec,void*);
 52: static PetscErrorCode FormJacobian1_block(SNES,Vec,Mat,Mat,void*);
 53: static PetscErrorCode FormFunction1_block(SNES,Vec,Vec,void*);
 54: static PetscErrorCode FormJacobian2_block(SNES,Vec,Mat,Mat,void*);
 55: 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,"-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: /* ------------------------------------------------------------------- */
179: /*
180: FormFunction1 - Evaluates nonlinear function, F(x).

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

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

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

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


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

226: Input Parameters:
227: .  snes - the SNES context
228: .  x - input vector
229: .  dummy - optional user-defined context (not used here)

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

243:   /*
244:   Get pointer to vector data
245:   */
246:   VecGetArray(x,&xx);

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

257:   /*
258:   Restore vector
259:   */
260:   VecRestoreArray(x,&xx);

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


271: /* ------------------------------------------------------------------- */
274: static PetscErrorCode FormFunction2(SNES snes,Vec x,Vec f,void *dummy)
275: {
277:   PetscScalar    *xx,*ff;

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

290:   /*
291:   Compute function
292:   */
293:   ff[0] = PetscSinScalar(3.0*xx[0]) + xx[0];
294:   ff[1] = xx[1];

296:   /*
297:   Restore vectors
298:   */
299:   VecRestoreArray(x,&xx);
300:   VecRestoreArray(f,&ff);
301:   return(0);
302: }

304: /* ------------------------------------------------------------------- */
307: static PetscErrorCode FormJacobian2(SNES snes,Vec x,Mat jac,Mat B,void *dummy)
308: {
309:   PetscScalar    *xx,A[4];
311:   PetscInt       idx[2] = {0,1};

314:   /*
315:   Get pointer to vector data
316:   */
317:   VecGetArray(x,&xx);

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

328:   /*
329:   Restore vector
330:   */
331:   VecRestoreArray(x,&xx);

333:   /*
334:   Assemble matrix
335:   */
336:   MatAssemblyBegin(jac,MAT_FINAL_ASSEMBLY);
337:   MatAssemblyEnd(jac,MAT_FINAL_ASSEMBLY);
338:   return(0);
339: }

343: static int block_system(void)
344: {
345:   SNES           snes;         /* nonlinear solver context */
346:   KSP            ksp;         /* linear solver context */
347:   PC             pc;           /* preconditioner context */
348:   Vec            x,r;         /* solution, residual vectors */
349:   Mat            J;            /* Jacobian matrix */
351:   PetscInt       its;
352:   PetscScalar    pfive = .5;
353:   PetscBool      flg;

355:   Mat j11, j12, j21, j22;
356:   Vec x1, x2, r1, r2;
357:   Vec bv;
358:   Vec bx[2];
359:   Mat bA[2][2];

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

364:   SNESCreate(PETSC_COMM_WORLD,&snes);

366:   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
367:   Create matrix and vector data structures; set corresponding routines
368:   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

370:   /*
371:   Create sub vectors for solution and nonlinear function
372:   */
373:   VecCreateSeq(PETSC_COMM_SELF,1,&x1);
374:   VecDuplicate(x1,&r1);

376:   VecCreateSeq(PETSC_COMM_SELF,1,&x2);
377:   VecDuplicate(x2,&r2);

379:   /*
380:   Create the block vectors
381:   */
382:   bx[0] = x1;
383:   bx[1] = x2;
384:   VecCreateNest(PETSC_COMM_WORLD,2,NULL,bx,&x);
385:   VecAssemblyBegin(x);
386:   VecAssemblyEnd(x);
387:   VecDestroy(&x1);
388:   VecDestroy(&x2);

390:   bx[0] = r1;
391:   bx[1] = r2;
392:   VecCreateNest(PETSC_COMM_WORLD,2,NULL,bx,&r);
393:   VecDestroy(&r1);
394:   VecDestroy(&r2);
395:   VecAssemblyBegin(r);
396:   VecAssemblyEnd(r);

398:   /*
399:   Create sub Jacobian matrix data structure
400:   */
401:   MatCreate(PETSC_COMM_WORLD, &j11);
402:   MatSetSizes(j11, 1, 1, 1, 1);
403:   MatSetType(j11, MATSEQAIJ);
404:   MatSetUp(j11);

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

411:   MatCreate(PETSC_COMM_WORLD, &j21);
412:   MatSetSizes(j21, 1, 1, 1, 1);
413:   MatSetType(j21, MATSEQAIJ);
414:   MatSetUp(j21);

416:   MatCreate(PETSC_COMM_WORLD, &j22);
417:   MatSetSizes(j22, PETSC_DECIDE, PETSC_DECIDE, 1, 1);
418:   MatSetType(j22, MATSEQAIJ);
419:   MatSetUp(j22);
420:   /*
421:   Create block Jacobian matrix data structure
422:   */
423:   bA[0][0] = j11;
424:   bA[0][1] = j12;
425:   bA[1][0] = j21;
426:   bA[1][1] = j22;

428:   MatCreateNest(PETSC_COMM_WORLD,2,NULL,2,NULL,&bA[0][0],&J);
429:   MatSetUp(J);
430:   MatNestSetVecType(J,VECNEST);
431:   MatDestroy(&j11);
432:   MatDestroy(&j12);
433:   MatDestroy(&j21);
434:   MatDestroy(&j22);

436:   MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);
437:   MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);

439:   PetscOptionsHasName(NULL,"-hard",&flg);
440:   if (!flg) {
441:     /*
442:     Set function evaluation routine and vector.
443:     */
444:     SNESSetFunction(snes,r,FormFunction1_block,NULL);

446:     /*
447:     Set Jacobian matrix data structure and Jacobian evaluation routine
448:     */
449:     SNESSetJacobian(snes,J,J,FormJacobian1_block,NULL);
450:   } else {
451:     SNESSetFunction(snes,r,FormFunction2_block,NULL);
452:     SNESSetJacobian(snes,J,J,FormJacobian2_block,NULL);
453:   }

455:   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
456:   Customize nonlinear solver; set runtime options
457:   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

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

469:   /*
470:   Set SNES/KSP/KSP/PC runtime options, e.g.,
471:   -snes_view -snes_monitor -ksp_type <ksp> -pc_type <pc>
472:   These options will override those specified above as long as
473:   SNESSetFromOptions() is called _after_ any other customization
474:   routines.
475:   */
476:   SNESSetFromOptions(snes);

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

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

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

515:   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
516:   Free work space.  All PETSc objects should be destroyed when they
517:   are no longer needed.
518:   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
519:   VecDestroy(&x); VecDestroy(&r);
520:   MatDestroy(&J); SNESDestroy(&snes);
521:   return(0);
522: }

524: /* ------------------------------------------------------------------- */
527: static PetscErrorCode FormFunction1_block(SNES snes,Vec x,Vec f,void *dummy)
528: {
529:   Vec            *xx, *ff, x1,x2, f1,f2;
530:   PetscScalar    ff_0, ff_1;
531:   PetscScalar    xx_0, xx_1;
532:   PetscInt       index,nb;

536:   /* get blocks for function */
537:   VecNestGetSubVecs(f, &nb, &ff);
538:   f1   = ff[0];  f2 = ff[1];

540:   /* get blocks for solution */
541:   VecNestGetSubVecs(x, &nb, &xx);
542:   x1   = xx[0];  x2 = xx[1];

544:   /* get solution values */
545:   index = 0;
546:   VecGetValues(x1,1, &index, &xx_0);
547:   VecGetValues(x2,1, &index, &xx_1);

549:   /* Compute function */
550:   ff_0 = xx_0*xx_0 + xx_0*xx_1 - 3.0;
551:   ff_1 = xx_0*xx_1 + xx_1*xx_1 - 6.0;

553:   /* set function values */
554:   VecSetValue(f1, index, ff_0, INSERT_VALUES);

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

558:   VecAssemblyBegin(f);
559:   VecAssemblyEnd(f);
560:   return(0);
561: }

563: /* ------------------------------------------------------------------- */
566: static PetscErrorCode FormJacobian1_block(SNES snes,Vec x,Mat jac,Mat B,void *dummy)
567: {
568:   Vec            *xx, x1,x2;
569:   PetscScalar    xx_0, xx_1;
570:   PetscInt       index,nb;
571:   PetscScalar    A_00, A_01, A_10, A_11;
572:   Mat            j11, j12, j21, j22;
573:   Mat            **mats;

577:   /* get blocks for solution */
578:   VecNestGetSubVecs(x, &nb, &xx);
579:   x1   = xx[0];  x2 = xx[1];

581:   /* get solution values */
582:   index = 0;
583:   VecGetValues(x1,1, &index, &xx_0);
584:   VecGetValues(x2,1, &index, &xx_1);

586:   /* get block matrices */
587:   MatNestGetSubMats(jac,NULL,NULL,&mats);
588:   j11  = mats[0][0];
589:   j12  = mats[0][1];
590:   j21  = mats[1][0];
591:   j22  = mats[1][1];

593:   /* compute jacobian entries */
594:   A_00 = 2.0*xx_0 + xx_1;
595:   A_01 = xx_0;
596:   A_10 = xx_1;
597:   A_11 = xx_0 + 2.0*xx_1;

599:   /* set jacobian values */
600:   MatSetValue(j11, 0,0, A_00, INSERT_VALUES);
601:   MatSetValue(j12, 0,0, A_01, INSERT_VALUES);
602:   MatSetValue(j21, 0,0, A_10, INSERT_VALUES);
603:   MatSetValue(j22, 0,0, A_11, INSERT_VALUES);

605:   /* Assemble sub matrix */
606:   MatAssemblyBegin(jac,MAT_FINAL_ASSEMBLY);
607:   MatAssemblyEnd(jac,MAT_FINAL_ASSEMBLY);
608:   return(0);
609: }

611: /* ------------------------------------------------------------------- */
614: static PetscErrorCode FormFunction2_block(SNES snes,Vec x,Vec f,void *dummy)
615: {
617:   PetscScalar    *xx,*ff;

620:   /*
621:   Get pointers to vector data.
622:   - For default PETSc vectors, VecGetArray() returns a pointer to
623:   the data array.  Otherwise, the routine is implementation dependent.
624:   - You MUST call VecRestoreArray() when you no longer need access to
625:   the array.
626:   */
627:   VecGetArray(x,&xx);
628:   VecGetArray(f,&ff);

630:   /*
631:   Compute function
632:   */
633:   ff[0] = PetscSinScalar(3.0*xx[0]) + xx[0];
634:   ff[1] = xx[1];

636:   /*
637:   Restore vectors
638:   */
639:   VecRestoreArray(x,&xx);
640:   VecRestoreArray(f,&ff);
641:   return(0);
642: }

644: /* ------------------------------------------------------------------- */
647: static PetscErrorCode FormJacobian2_block(SNES snes,Vec x,Mat jac,Mat B,void *dummy)
648: {
649:   PetscScalar    *xx,A[4];
651:   PetscInt       idx[2] = {0,1};

654:   /*
655:   Get pointer to vector data
656:   */
657:   VecGetArray(x,&xx);

659:   /*
660:   Compute Jacobian entries and insert into matrix.
661:   - Since this is such a small problem, we set all entries for
662:   the matrix at once.
663:   */
664:   A[0]  = 3.0*PetscCosScalar(3.0*xx[0]) + 1.0; A[1] = 0.0;
665:   A[2]  = 0.0;                     A[3] = 1.0;
666:   MatSetValues(jac,2,idx,2,idx,A,INSERT_VALUES);

668:   /*
669:   Restore vector
670:   */
671:   VecRestoreArray(x,&xx);

673:   /*
674:   Assemble matrix
675:   */
676:   MatAssemblyBegin(jac,MAT_FINAL_ASSEMBLY);
677:   MatAssemblyEnd(jac,MAT_FINAL_ASSEMBLY);
678:   return(0);
679: }

683: int main(int argc,char **argv)
684: {
685:   PetscMPIInt    size;

688:   PetscInitialize(&argc,&argv,(char*)0,help);

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

693:   assembled_system();

695:   block_system();

697:   PetscFinalize();
698:   return 0;
699: }