Actual source code: ex17.c

petsc-3.15.0 2021-03-30
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/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:   }
163:   PetscPrintf(PETSC_COMM_SELF,"number of SNES iterations = %D\n\n",its);

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

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

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

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

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

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

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


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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

357:   SNESCreate(PETSC_COMM_WORLD,&snes);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

678:   assembled_system();

680:   block_system();

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


687: /*TEST

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

693: TEST*/