xref: /petsc/src/ksp/pc/impls/bjacobi/bjacobi.c (revision 2f613bf53f46f9356e00a2ca2bd69453be72fc31)
1 
2 /*
3    Defines a block Jacobi preconditioner.
4 */
5 
6 #include <../src/ksp/pc/impls/bjacobi/bjacobi.h> /*I "petscpc.h" I*/
7 
8 static PetscErrorCode PCSetUp_BJacobi_Singleblock(PC,Mat,Mat);
9 static PetscErrorCode PCSetUp_BJacobi_Multiblock(PC,Mat,Mat);
10 static PetscErrorCode PCSetUp_BJacobi_Multiproc(PC);
11 
12 static PetscErrorCode PCSetUp_BJacobi(PC pc)
13 {
14   PC_BJacobi     *jac = (PC_BJacobi*)pc->data;
15   Mat            mat  = pc->mat,pmat = pc->pmat;
16   PetscErrorCode ierr;
17   PetscBool      hasop;
18   PetscInt       N,M,start,i,sum,end;
19   PetscInt       bs,i_start=-1,i_end=-1;
20   PetscMPIInt    rank,size;
21 
22   PetscFunctionBegin;
23   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRMPI(ierr);
24   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRMPI(ierr);
25   ierr = MatGetLocalSize(pc->pmat,&M,&N);CHKERRQ(ierr);
26   ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr);
27 
28   if (jac->n > 0 && jac->n < size) {
29     ierr = PCSetUp_BJacobi_Multiproc(pc);CHKERRQ(ierr);
30     PetscFunctionReturn(0);
31   }
32 
33   /* --------------------------------------------------------------------------
34       Determines the number of blocks assigned to each processor
35   -----------------------------------------------------------------------------*/
36 
37   /*   local block count  given */
38   if (jac->n_local > 0 && jac->n < 0) {
39     ierr = MPIU_Allreduce(&jac->n_local,&jac->n,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRMPI(ierr);
40     if (jac->l_lens) { /* check that user set these correctly */
41       sum = 0;
42       for (i=0; i<jac->n_local; i++) {
43         if (jac->l_lens[i]/bs*bs !=jac->l_lens[i]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat blocksize doesn't match block Jacobi layout");
44         sum += jac->l_lens[i];
45       }
46       if (sum != M) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Local lens set incorrectly");
47     } else {
48       ierr = PetscMalloc1(jac->n_local,&jac->l_lens);CHKERRQ(ierr);
49       for (i=0; i<jac->n_local; i++) jac->l_lens[i] = bs*((M/bs)/jac->n_local + (((M/bs) % jac->n_local) > i));
50     }
51   } else if (jac->n > 0 && jac->n_local < 0) { /* global block count given */
52     /* global blocks given: determine which ones are local */
53     if (jac->g_lens) {
54       /* check if the g_lens is has valid entries */
55       for (i=0; i<jac->n; i++) {
56         if (!jac->g_lens[i]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Zero block not allowed");
57         if (jac->g_lens[i]/bs*bs != jac->g_lens[i]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat blocksize doesn't match block Jacobi layout");
58       }
59       if (size == 1) {
60         jac->n_local = jac->n;
61         ierr         = PetscMalloc1(jac->n_local,&jac->l_lens);CHKERRQ(ierr);
62         ierr         = PetscArraycpy(jac->l_lens,jac->g_lens,jac->n_local);CHKERRQ(ierr);
63         /* check that user set these correctly */
64         sum = 0;
65         for (i=0; i<jac->n_local; i++) sum += jac->l_lens[i];
66         if (sum != M) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Global lens set incorrectly");
67       } else {
68         ierr = MatGetOwnershipRange(pc->pmat,&start,&end);CHKERRQ(ierr);
69         /* loop over blocks determing first one owned by me */
70         sum = 0;
71         for (i=0; i<jac->n+1; i++) {
72           if (sum == start) { i_start = i; goto start_1;}
73           if (i < jac->n) sum += jac->g_lens[i];
74         }
75         SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Block sizes used in PCBJacobiSetTotalBlocks()\nare not compatible with parallel matrix layout");
76 start_1:
77         for (i=i_start; i<jac->n+1; i++) {
78           if (sum == end) { i_end = i; goto end_1; }
79           if (i < jac->n) sum += jac->g_lens[i];
80         }
81         SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Block sizes used in PCBJacobiSetTotalBlocks()\nare not compatible with parallel matrix layout");
82 end_1:
83         jac->n_local = i_end - i_start;
84         ierr         = PetscMalloc1(jac->n_local,&jac->l_lens);CHKERRQ(ierr);
85         ierr         = PetscArraycpy(jac->l_lens,jac->g_lens+i_start,jac->n_local);CHKERRQ(ierr);
86       }
87     } else { /* no global blocks given, determine then using default layout */
88       jac->n_local = jac->n/size + ((jac->n % size) > rank);
89       ierr         = PetscMalloc1(jac->n_local,&jac->l_lens);CHKERRQ(ierr);
90       for (i=0; i<jac->n_local; i++) {
91         jac->l_lens[i] = ((M/bs)/jac->n_local + (((M/bs) % jac->n_local) > i))*bs;
92         if (!jac->l_lens[i]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Too many blocks given");
93       }
94     }
95   } else if (jac->n < 0 && jac->n_local < 0) { /* no blocks given */
96     jac->n         = size;
97     jac->n_local   = 1;
98     ierr           = PetscMalloc1(1,&jac->l_lens);CHKERRQ(ierr);
99     jac->l_lens[0] = M;
100   } else { /* jac->n > 0 && jac->n_local > 0 */
101     if (!jac->l_lens) {
102       ierr = PetscMalloc1(jac->n_local,&jac->l_lens);CHKERRQ(ierr);
103       for (i=0; i<jac->n_local; i++) jac->l_lens[i] = bs*((M/bs)/jac->n_local + (((M/bs) % jac->n_local) > i));
104     }
105   }
106   if (jac->n_local < 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Number of blocks is less than number of processors");
107 
108   /* -------------------------
109       Determines mat and pmat
110   ---------------------------*/
111   ierr = MatHasOperation(pc->mat,MATOP_GET_DIAGONAL_BLOCK,&hasop);CHKERRQ(ierr);
112   if (!hasop && size == 1) {
113     mat  = pc->mat;
114     pmat = pc->pmat;
115   } else {
116     if (pc->useAmat) {
117       /* use block from Amat matrix, not Pmat for local MatMult() */
118       ierr = MatGetDiagonalBlock(pc->mat,&mat);CHKERRQ(ierr);
119     }
120     if (pc->pmat != pc->mat || !pc->useAmat) {
121       ierr = MatGetDiagonalBlock(pc->pmat,&pmat);CHKERRQ(ierr);
122     } else pmat = mat;
123   }
124 
125   /* ------
126      Setup code depends on the number of blocks
127   */
128   if (jac->n_local == 1) {
129     ierr = PCSetUp_BJacobi_Singleblock(pc,mat,pmat);CHKERRQ(ierr);
130   } else {
131     ierr = PCSetUp_BJacobi_Multiblock(pc,mat,pmat);CHKERRQ(ierr);
132   }
133   PetscFunctionReturn(0);
134 }
135 
136 /* Default destroy, if it has never been setup */
137 static PetscErrorCode PCDestroy_BJacobi(PC pc)
138 {
139   PC_BJacobi     *jac = (PC_BJacobi*)pc->data;
140   PetscErrorCode ierr;
141 
142   PetscFunctionBegin;
143   ierr = PetscFree(jac->g_lens);CHKERRQ(ierr);
144   ierr = PetscFree(jac->l_lens);CHKERRQ(ierr);
145   ierr = PetscFree(pc->data);CHKERRQ(ierr);
146   PetscFunctionReturn(0);
147 }
148 
149 static PetscErrorCode PCSetFromOptions_BJacobi(PetscOptionItems *PetscOptionsObject,PC pc)
150 {
151   PC_BJacobi     *jac = (PC_BJacobi*)pc->data;
152   PetscErrorCode ierr;
153   PetscInt       blocks,i;
154   PetscBool      flg;
155 
156   PetscFunctionBegin;
157   ierr = PetscOptionsHead(PetscOptionsObject,"Block Jacobi options");CHKERRQ(ierr);
158   ierr = PetscOptionsInt("-pc_bjacobi_blocks","Total number of blocks","PCBJacobiSetTotalBlocks",jac->n,&blocks,&flg);CHKERRQ(ierr);
159   if (flg) {ierr = PCBJacobiSetTotalBlocks(pc,blocks,NULL);CHKERRQ(ierr);}
160   ierr = PetscOptionsInt("-pc_bjacobi_local_blocks","Local number of blocks","PCBJacobiSetLocalBlocks",jac->n_local,&blocks,&flg);CHKERRQ(ierr);
161   if (flg) {ierr = PCBJacobiSetLocalBlocks(pc,blocks,NULL);CHKERRQ(ierr);}
162   if (jac->ksp) {
163     /* The sub-KSP has already been set up (e.g., PCSetUp_BJacobi_Singleblock), but KSPSetFromOptions was not called
164      * unless we had already been called. */
165     for (i=0; i<jac->n_local; i++) {
166       ierr = KSPSetFromOptions(jac->ksp[i]);CHKERRQ(ierr);
167     }
168   }
169   ierr = PetscOptionsTail();CHKERRQ(ierr);
170   PetscFunctionReturn(0);
171 }
172 
173 #include <petscdraw.h>
174 static PetscErrorCode PCView_BJacobi(PC pc,PetscViewer viewer)
175 {
176   PC_BJacobi           *jac   = (PC_BJacobi*)pc->data;
177   PC_BJacobi_Multiproc *mpjac = (PC_BJacobi_Multiproc*)jac->data;
178   PetscErrorCode       ierr;
179   PetscMPIInt          rank;
180   PetscInt             i;
181   PetscBool            iascii,isstring,isdraw;
182   PetscViewer          sviewer;
183   PetscViewerFormat    format;
184   const char           *prefix;
185 
186   PetscFunctionBegin;
187   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
188   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr);
189   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
190   if (iascii) {
191     if (pc->useAmat) {
192       ierr = PetscViewerASCIIPrintf(viewer,"  using Amat local matrix, number of blocks = %D\n",jac->n);CHKERRQ(ierr);
193     }
194     ierr = PetscViewerASCIIPrintf(viewer,"  number of blocks = %D\n",jac->n);CHKERRQ(ierr);
195     ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRMPI(ierr);
196     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
197     if (format != PETSC_VIEWER_ASCII_INFO_DETAIL) {
198       ierr = PetscViewerASCIIPrintf(viewer,"  Local solver information for first block is in the following KSP and PC objects on rank 0:\n");CHKERRQ(ierr);
199       ierr = PCGetOptionsPrefix(pc,&prefix);CHKERRQ(ierr);
200       ierr = PetscViewerASCIIPrintf(viewer,"  Use -%sksp_view ::ascii_info_detail to display information for all blocks\n",prefix?prefix:"");CHKERRQ(ierr);
201       if (jac->ksp && !jac->psubcomm) {
202         ierr = PetscViewerGetSubViewer(viewer,PETSC_COMM_SELF,&sviewer);CHKERRQ(ierr);
203         if (rank == 0) {
204           ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
205           ierr = KSPView(jac->ksp[0],sviewer);CHKERRQ(ierr);
206           ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
207         }
208         ierr = PetscViewerFlush(sviewer);CHKERRQ(ierr);
209         ierr = PetscViewerRestoreSubViewer(viewer,PETSC_COMM_SELF,&sviewer);CHKERRQ(ierr);
210         ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
211         /*  extra call needed because of the two calls to PetscViewerASCIIPushSynchronized() in PetscViewerGetSubViewer() */
212         ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr);
213       } else if (mpjac && jac->ksp && mpjac->psubcomm) {
214         ierr = PetscViewerGetSubViewer(viewer,mpjac->psubcomm->child,&sviewer);CHKERRQ(ierr);
215         if (!mpjac->psubcomm->color) {
216           ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
217           ierr = KSPView(*(jac->ksp),sviewer);CHKERRQ(ierr);
218           ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
219         }
220         ierr = PetscViewerFlush(sviewer);CHKERRQ(ierr);
221         ierr = PetscViewerRestoreSubViewer(viewer,mpjac->psubcomm->child,&sviewer);CHKERRQ(ierr);
222         ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
223         /*  extra call needed because of the two calls to PetscViewerASCIIPushSynchronized() in PetscViewerGetSubViewer() */
224         ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr);
225       } else {
226         ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
227       }
228     } else {
229       PetscInt n_global;
230       ierr = MPIU_Allreduce(&jac->n_local,&n_global,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)pc));CHKERRMPI(ierr);
231       ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr);
232       ierr = PetscViewerASCIIPrintf(viewer,"  Local solver information for each block is in the following KSP and PC objects:\n");CHKERRQ(ierr);
233       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"[%d] number of local blocks = %D, first local block number = %D\n",
234                                                 rank,jac->n_local,jac->first_local);CHKERRQ(ierr);
235       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
236       ierr = PetscViewerGetSubViewer(viewer,PETSC_COMM_SELF,&sviewer);CHKERRQ(ierr);
237       for (i=0; i<jac->n_local; i++) {
238         ierr = PetscViewerASCIISynchronizedPrintf(viewer,"[%d] local block number %D\n",rank,i);CHKERRQ(ierr);
239         ierr = KSPView(jac->ksp[i],sviewer);CHKERRQ(ierr);
240         ierr = PetscViewerASCIISynchronizedPrintf(viewer,"- - - - - - - - - - - - - - - - - -\n");CHKERRQ(ierr);
241       }
242       ierr = PetscViewerRestoreSubViewer(viewer,PETSC_COMM_SELF,&sviewer);CHKERRQ(ierr);
243       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
244       ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
245       ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr);
246     }
247   } else if (isstring) {
248     ierr = PetscViewerStringSPrintf(viewer," blks=%D",jac->n);CHKERRQ(ierr);
249     ierr = PetscViewerGetSubViewer(viewer,PETSC_COMM_SELF,&sviewer);CHKERRQ(ierr);
250     if (jac->ksp) {ierr = KSPView(jac->ksp[0],sviewer);CHKERRQ(ierr);}
251     ierr = PetscViewerRestoreSubViewer(viewer,PETSC_COMM_SELF,&sviewer);CHKERRQ(ierr);
252   } else if (isdraw) {
253     PetscDraw draw;
254     char      str[25];
255     PetscReal x,y,bottom,h;
256 
257     ierr   = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
258     ierr   = PetscDrawGetCurrentPoint(draw,&x,&y);CHKERRQ(ierr);
259     ierr   = PetscSNPrintf(str,25,"Number blocks %D",jac->n);CHKERRQ(ierr);
260     ierr   = PetscDrawStringBoxed(draw,x,y,PETSC_DRAW_RED,PETSC_DRAW_BLACK,str,NULL,&h);CHKERRQ(ierr);
261     bottom = y - h;
262     ierr   = PetscDrawPushCurrentPoint(draw,x,bottom);CHKERRQ(ierr);
263     /* warning the communicator on viewer is different then on ksp in parallel */
264     if (jac->ksp) {ierr = KSPView(jac->ksp[0],viewer);CHKERRQ(ierr);}
265     ierr = PetscDrawPopCurrentPoint(draw);CHKERRQ(ierr);
266   }
267   PetscFunctionReturn(0);
268 }
269 
270 /* -------------------------------------------------------------------------------------*/
271 
272 static PetscErrorCode  PCBJacobiGetSubKSP_BJacobi(PC pc,PetscInt *n_local,PetscInt *first_local,KSP **ksp)
273 {
274   PC_BJacobi *jac = (PC_BJacobi*)pc->data;
275 
276   PetscFunctionBegin;
277   if (!pc->setupcalled) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"Must call KSPSetUp() or PCSetUp() first");
278 
279   if (n_local) *n_local = jac->n_local;
280   if (first_local) *first_local = jac->first_local;
281   if (ksp) *ksp                 = jac->ksp;
282   PetscFunctionReturn(0);
283 }
284 
285 static PetscErrorCode  PCBJacobiSetTotalBlocks_BJacobi(PC pc,PetscInt blocks,PetscInt *lens)
286 {
287   PC_BJacobi     *jac = (PC_BJacobi*)pc->data;
288   PetscErrorCode ierr;
289 
290   PetscFunctionBegin;
291   if (pc->setupcalled > 0 && jac->n!=blocks) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ORDER,"Cannot alter number of blocks after PCSetUp()/KSPSetUp() has been called");
292   jac->n = blocks;
293   if (!lens) jac->g_lens = NULL;
294   else {
295     ierr = PetscMalloc1(blocks,&jac->g_lens);CHKERRQ(ierr);
296     ierr = PetscLogObjectMemory((PetscObject)pc,blocks*sizeof(PetscInt));CHKERRQ(ierr);
297     ierr = PetscArraycpy(jac->g_lens,lens,blocks);CHKERRQ(ierr);
298   }
299   PetscFunctionReturn(0);
300 }
301 
302 static PetscErrorCode  PCBJacobiGetTotalBlocks_BJacobi(PC pc, PetscInt *blocks, const PetscInt *lens[])
303 {
304   PC_BJacobi *jac = (PC_BJacobi*) pc->data;
305 
306   PetscFunctionBegin;
307   *blocks = jac->n;
308   if (lens) *lens = jac->g_lens;
309   PetscFunctionReturn(0);
310 }
311 
312 static PetscErrorCode  PCBJacobiSetLocalBlocks_BJacobi(PC pc,PetscInt blocks,const PetscInt lens[])
313 {
314   PC_BJacobi     *jac;
315   PetscErrorCode ierr;
316 
317   PetscFunctionBegin;
318   jac = (PC_BJacobi*)pc->data;
319 
320   jac->n_local = blocks;
321   if (!lens) jac->l_lens = NULL;
322   else {
323     ierr = PetscMalloc1(blocks,&jac->l_lens);CHKERRQ(ierr);
324     ierr = PetscLogObjectMemory((PetscObject)pc,blocks*sizeof(PetscInt));CHKERRQ(ierr);
325     ierr = PetscArraycpy(jac->l_lens,lens,blocks);CHKERRQ(ierr);
326   }
327   PetscFunctionReturn(0);
328 }
329 
330 static PetscErrorCode  PCBJacobiGetLocalBlocks_BJacobi(PC pc, PetscInt *blocks, const PetscInt *lens[])
331 {
332   PC_BJacobi *jac = (PC_BJacobi*) pc->data;
333 
334   PetscFunctionBegin;
335   *blocks = jac->n_local;
336   if (lens) *lens = jac->l_lens;
337   PetscFunctionReturn(0);
338 }
339 
340 /* -------------------------------------------------------------------------------------*/
341 
342 /*@C
343    PCBJacobiGetSubKSP - Gets the local KSP contexts for all blocks on
344    this processor.
345 
346    Not Collective
347 
348    Input Parameter:
349 .  pc - the preconditioner context
350 
351    Output Parameters:
352 +  n_local - the number of blocks on this processor, or NULL
353 .  first_local - the global number of the first block on this processor, or NULL
354 -  ksp - the array of KSP contexts
355 
356    Notes:
357    After PCBJacobiGetSubKSP() the array of KSP contexts is not to be freed.
358 
359    Currently for some matrix implementations only 1 block per processor
360    is supported.
361 
362    You must call KSPSetUp() or PCSetUp() before calling PCBJacobiGetSubKSP().
363 
364    Fortran Usage: You must pass in a KSP array that is large enough to contain all the local KSPs.
365       You can call PCBJacobiGetSubKSP(pc,nlocal,firstlocal,PETSC_NULL_KSP,ierr) to determine how large the
366       KSP array must be.
367 
368    Level: advanced
369 
370 .seealso: PCASMGetSubKSP()
371 @*/
372 PetscErrorCode  PCBJacobiGetSubKSP(PC pc,PetscInt *n_local,PetscInt *first_local,KSP *ksp[])
373 {
374   PetscErrorCode ierr;
375 
376   PetscFunctionBegin;
377   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
378   ierr = PetscUseMethod(pc,"PCBJacobiGetSubKSP_C",(PC,PetscInt*,PetscInt*,KSP **),(pc,n_local,first_local,ksp));CHKERRQ(ierr);
379   PetscFunctionReturn(0);
380 }
381 
382 /*@
383    PCBJacobiSetTotalBlocks - Sets the global number of blocks for the block
384    Jacobi preconditioner.
385 
386    Collective on PC
387 
388    Input Parameters:
389 +  pc - the preconditioner context
390 .  blocks - the number of blocks
391 -  lens - [optional] integer array containing the size of each block
392 
393    Options Database Key:
394 .  -pc_bjacobi_blocks <blocks> - Sets the number of global blocks
395 
396    Notes:
397    Currently only a limited number of blocking configurations are supported.
398    All processors sharing the PC must call this routine with the same data.
399 
400    Level: intermediate
401 
402 .seealso: PCSetUseAmat(), PCBJacobiSetLocalBlocks()
403 @*/
404 PetscErrorCode  PCBJacobiSetTotalBlocks(PC pc,PetscInt blocks,const PetscInt lens[])
405 {
406   PetscErrorCode ierr;
407 
408   PetscFunctionBegin;
409   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
410   if (blocks <= 0) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Must have positive blocks");
411   ierr = PetscTryMethod(pc,"PCBJacobiSetTotalBlocks_C",(PC,PetscInt,const PetscInt[]),(pc,blocks,lens));CHKERRQ(ierr);
412   PetscFunctionReturn(0);
413 }
414 
415 /*@C
416    PCBJacobiGetTotalBlocks - Gets the global number of blocks for the block
417    Jacobi preconditioner.
418 
419    Not Collective
420 
421    Input Parameter:
422 .  pc - the preconditioner context
423 
424    Output parameters:
425 +  blocks - the number of blocks
426 -  lens - integer array containing the size of each block
427 
428    Level: intermediate
429 
430 .seealso: PCSetUseAmat(), PCBJacobiGetLocalBlocks()
431 @*/
432 PetscErrorCode  PCBJacobiGetTotalBlocks(PC pc, PetscInt *blocks, const PetscInt *lens[])
433 {
434   PetscErrorCode ierr;
435 
436   PetscFunctionBegin;
437   PetscValidHeaderSpecific(pc, PC_CLASSID,1);
438   PetscValidIntPointer(blocks,2);
439   ierr = PetscUseMethod(pc,"PCBJacobiGetTotalBlocks_C",(PC,PetscInt*, const PetscInt *[]),(pc,blocks,lens));CHKERRQ(ierr);
440   PetscFunctionReturn(0);
441 }
442 
443 /*@
444    PCBJacobiSetLocalBlocks - Sets the local number of blocks for the block
445    Jacobi preconditioner.
446 
447    Not Collective
448 
449    Input Parameters:
450 +  pc - the preconditioner context
451 .  blocks - the number of blocks
452 -  lens - [optional] integer array containing size of each block
453 
454    Options Database Key:
455 .  -pc_bjacobi_local_blocks <blocks> - Sets the number of local blocks
456 
457    Note:
458    Currently only a limited number of blocking configurations are supported.
459 
460    Level: intermediate
461 
462 .seealso: PCSetUseAmat(), PCBJacobiSetTotalBlocks()
463 @*/
464 PetscErrorCode  PCBJacobiSetLocalBlocks(PC pc,PetscInt blocks,const PetscInt lens[])
465 {
466   PetscErrorCode ierr;
467 
468   PetscFunctionBegin;
469   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
470   if (blocks < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have nonegative blocks");
471   ierr = PetscTryMethod(pc,"PCBJacobiSetLocalBlocks_C",(PC,PetscInt,const PetscInt []),(pc,blocks,lens));CHKERRQ(ierr);
472   PetscFunctionReturn(0);
473 }
474 
475 /*@C
476    PCBJacobiGetLocalBlocks - Gets the local number of blocks for the block
477    Jacobi preconditioner.
478 
479    Not Collective
480 
481    Input Parameters:
482 +  pc - the preconditioner context
483 .  blocks - the number of blocks
484 -  lens - [optional] integer array containing size of each block
485 
486    Note:
487    Currently only a limited number of blocking configurations are supported.
488 
489    Level: intermediate
490 
491 .seealso: PCSetUseAmat(), PCBJacobiGetTotalBlocks()
492 @*/
493 PetscErrorCode  PCBJacobiGetLocalBlocks(PC pc, PetscInt *blocks, const PetscInt *lens[])
494 {
495   PetscErrorCode ierr;
496 
497   PetscFunctionBegin;
498   PetscValidHeaderSpecific(pc, PC_CLASSID,1);
499   PetscValidIntPointer(blocks,2);
500   ierr = PetscUseMethod(pc,"PCBJacobiGetLocalBlocks_C",(PC,PetscInt*, const PetscInt *[]),(pc,blocks,lens));CHKERRQ(ierr);
501   PetscFunctionReturn(0);
502 }
503 
504 /* -----------------------------------------------------------------------------------*/
505 
506 /*MC
507    PCBJACOBI - Use block Jacobi preconditioning, each block is (approximately) solved with
508            its own KSP object.
509 
510    Options Database Keys:
511 +  -pc_use_amat - use Amat to apply block of operator in inner Krylov method
512 -  -pc_bjacobi_blocks <n> - use n total blocks
513 
514    Notes:
515     Each processor can have one or more blocks, or a single block can be shared by several processes. Defaults to one block per processor.
516 
517      To set options on the solvers for each block append -sub_ to all the KSP, KSP, and PC
518         options database keys. For example, -sub_pc_type ilu -sub_pc_factor_levels 1 -sub_ksp_type preonly
519 
520      To set the options on the solvers separate for each block call PCBJacobiGetSubKSP()
521          and set the options directly on the resulting KSP object (you can access its PC
522          KSPGetPC())
523 
524      For GPU-based vectors (CUDA, ViennaCL) it is recommended to use exactly one block per MPI process for best
525          performance.  Different block partitioning may lead to additional data transfers
526          between host and GPU that lead to degraded performance.
527 
528      The options prefix for each block is sub_, for example -sub_pc_type lu.
529 
530      When multiple processes share a single block, each block encompasses exactly all the unknowns owned its set of processes.
531 
532    Level: beginner
533 
534 .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
535            PCASM, PCSetUseAmat(), PCGetUseAmat(), PCBJacobiGetSubKSP(), PCBJacobiSetTotalBlocks(),
536            PCBJacobiSetLocalBlocks(), PCSetModifySubMatrices()
537 M*/
538 
539 PETSC_EXTERN PetscErrorCode PCCreate_BJacobi(PC pc)
540 {
541   PetscErrorCode ierr;
542   PetscMPIInt    rank;
543   PC_BJacobi     *jac;
544 
545   PetscFunctionBegin;
546   ierr = PetscNewLog(pc,&jac);CHKERRQ(ierr);
547   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRMPI(ierr);
548 
549   pc->ops->apply           = NULL;
550   pc->ops->matapply        = NULL;
551   pc->ops->applytranspose  = NULL;
552   pc->ops->setup           = PCSetUp_BJacobi;
553   pc->ops->destroy         = PCDestroy_BJacobi;
554   pc->ops->setfromoptions  = PCSetFromOptions_BJacobi;
555   pc->ops->view            = PCView_BJacobi;
556   pc->ops->applyrichardson = NULL;
557 
558   pc->data               = (void*)jac;
559   jac->n                 = -1;
560   jac->n_local           = -1;
561   jac->first_local       = rank;
562   jac->ksp               = NULL;
563   jac->g_lens            = NULL;
564   jac->l_lens            = NULL;
565   jac->psubcomm          = NULL;
566 
567   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBJacobiGetSubKSP_C",PCBJacobiGetSubKSP_BJacobi);CHKERRQ(ierr);
568   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBJacobiSetTotalBlocks_C",PCBJacobiSetTotalBlocks_BJacobi);CHKERRQ(ierr);
569   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBJacobiGetTotalBlocks_C",PCBJacobiGetTotalBlocks_BJacobi);CHKERRQ(ierr);
570   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBJacobiSetLocalBlocks_C",PCBJacobiSetLocalBlocks_BJacobi);CHKERRQ(ierr);
571   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBJacobiGetLocalBlocks_C",PCBJacobiGetLocalBlocks_BJacobi);CHKERRQ(ierr);
572   PetscFunctionReturn(0);
573 }
574 
575 /* --------------------------------------------------------------------------------------------*/
576 /*
577         These are for a single block per processor; works for AIJ, BAIJ; Seq and MPI
578 */
579 static PetscErrorCode PCReset_BJacobi_Singleblock(PC pc)
580 {
581   PC_BJacobi             *jac  = (PC_BJacobi*)pc->data;
582   PC_BJacobi_Singleblock *bjac = (PC_BJacobi_Singleblock*)jac->data;
583   PetscErrorCode         ierr;
584 
585   PetscFunctionBegin;
586   ierr = KSPReset(jac->ksp[0]);CHKERRQ(ierr);
587   ierr = VecDestroy(&bjac->x);CHKERRQ(ierr);
588   ierr = VecDestroy(&bjac->y);CHKERRQ(ierr);
589   PetscFunctionReturn(0);
590 }
591 
592 static PetscErrorCode PCDestroy_BJacobi_Singleblock(PC pc)
593 {
594   PC_BJacobi             *jac  = (PC_BJacobi*)pc->data;
595   PC_BJacobi_Singleblock *bjac = (PC_BJacobi_Singleblock*)jac->data;
596   PetscErrorCode         ierr;
597 
598   PetscFunctionBegin;
599   ierr = PCReset_BJacobi_Singleblock(pc);CHKERRQ(ierr);
600   ierr = KSPDestroy(&jac->ksp[0]);CHKERRQ(ierr);
601   ierr = PetscFree(jac->ksp);CHKERRQ(ierr);
602   ierr = PetscFree(jac->l_lens);CHKERRQ(ierr);
603   ierr = PetscFree(jac->g_lens);CHKERRQ(ierr);
604   ierr = PetscFree(bjac);CHKERRQ(ierr);
605   ierr = PetscFree(pc->data);CHKERRQ(ierr);
606   PetscFunctionReturn(0);
607 }
608 
609 static PetscErrorCode PCSetUpOnBlocks_BJacobi_Singleblock(PC pc)
610 {
611   PetscErrorCode     ierr;
612   PC_BJacobi         *jac = (PC_BJacobi*)pc->data;
613   KSP                subksp = jac->ksp[0];
614   KSPConvergedReason reason;
615 
616   PetscFunctionBegin;
617   ierr = KSPSetUp(subksp);CHKERRQ(ierr);
618   ierr = KSPGetConvergedReason(subksp,&reason);CHKERRQ(ierr);
619   if (reason == KSP_DIVERGED_PC_FAILED) {
620     pc->failedreason = PC_SUBPC_ERROR;
621   }
622   PetscFunctionReturn(0);
623 }
624 
625 static PetscErrorCode PCApply_BJacobi_Singleblock(PC pc,Vec x,Vec y)
626 {
627   PetscErrorCode         ierr;
628   PC_BJacobi             *jac  = (PC_BJacobi*)pc->data;
629   PC_BJacobi_Singleblock *bjac = (PC_BJacobi_Singleblock*)jac->data;
630 
631   PetscFunctionBegin;
632   ierr = VecGetLocalVectorRead(x, bjac->x);CHKERRQ(ierr);
633   ierr = VecGetLocalVector(y, bjac->y);CHKERRQ(ierr);
634  /* Since the inner KSP matrix may point directly to the diagonal block of an MPI matrix the inner
635      matrix may change even if the outer KSP/PC has not updated the preconditioner, this will trigger a rebuild
636      of the inner preconditioner automatically unless we pass down the outer preconditioners reuse flag.*/
637   ierr = KSPSetReusePreconditioner(jac->ksp[0],pc->reusepreconditioner);CHKERRQ(ierr);
638   ierr = KSPSolve(jac->ksp[0],bjac->x,bjac->y);CHKERRQ(ierr);
639   ierr = KSPCheckSolve(jac->ksp[0],pc,bjac->y);CHKERRQ(ierr);
640   ierr = VecRestoreLocalVectorRead(x, bjac->x);CHKERRQ(ierr);
641   ierr = VecRestoreLocalVector(y, bjac->y);CHKERRQ(ierr);
642   PetscFunctionReturn(0);
643 }
644 
645 static PetscErrorCode PCMatApply_BJacobi_Singleblock(PC pc,Mat X,Mat Y)
646 {
647   PC_BJacobi     *jac  = (PC_BJacobi*)pc->data;
648   Mat            sX,sY;
649   PetscErrorCode ierr;
650 
651   PetscFunctionBegin;
652  /* Since the inner KSP matrix may point directly to the diagonal block of an MPI matrix the inner
653      matrix may change even if the outer KSP/PC has not updated the preconditioner, this will trigger a rebuild
654      of the inner preconditioner automatically unless we pass down the outer preconditioners reuse flag.*/
655   ierr = KSPSetReusePreconditioner(jac->ksp[0],pc->reusepreconditioner);CHKERRQ(ierr);
656   ierr = MatDenseGetLocalMatrix(X,&sX);CHKERRQ(ierr);
657   ierr = MatDenseGetLocalMatrix(Y,&sY);CHKERRQ(ierr);
658   ierr = KSPMatSolve(jac->ksp[0],sX,sY);CHKERRQ(ierr);
659   PetscFunctionReturn(0);
660 }
661 
662 static PetscErrorCode PCApplySymmetricLeft_BJacobi_Singleblock(PC pc,Vec x,Vec y)
663 {
664   PetscErrorCode         ierr;
665   PC_BJacobi             *jac  = (PC_BJacobi*)pc->data;
666   PC_BJacobi_Singleblock *bjac = (PC_BJacobi_Singleblock*)jac->data;
667   PetscScalar            *y_array;
668   const PetscScalar      *x_array;
669   PC                     subpc;
670 
671   PetscFunctionBegin;
672   /*
673       The VecPlaceArray() is to avoid having to copy the
674     y vector into the bjac->x vector. The reason for
675     the bjac->x vector is that we need a sequential vector
676     for the sequential solve.
677   */
678   ierr = VecGetArrayRead(x,&x_array);CHKERRQ(ierr);
679   ierr = VecGetArray(y,&y_array);CHKERRQ(ierr);
680   ierr = VecPlaceArray(bjac->x,x_array);CHKERRQ(ierr);
681   ierr = VecPlaceArray(bjac->y,y_array);CHKERRQ(ierr);
682   /* apply the symmetric left portion of the inner PC operator */
683   /* note this by-passes the inner KSP and its options completely */
684   ierr = KSPGetPC(jac->ksp[0],&subpc);CHKERRQ(ierr);
685   ierr = PCApplySymmetricLeft(subpc,bjac->x,bjac->y);CHKERRQ(ierr);
686   ierr = VecResetArray(bjac->x);CHKERRQ(ierr);
687   ierr = VecResetArray(bjac->y);CHKERRQ(ierr);
688   ierr = VecRestoreArrayRead(x,&x_array);CHKERRQ(ierr);
689   ierr = VecRestoreArray(y,&y_array);CHKERRQ(ierr);
690   PetscFunctionReturn(0);
691 }
692 
693 static PetscErrorCode PCApplySymmetricRight_BJacobi_Singleblock(PC pc,Vec x,Vec y)
694 {
695   PetscErrorCode         ierr;
696   PC_BJacobi             *jac  = (PC_BJacobi*)pc->data;
697   PC_BJacobi_Singleblock *bjac = (PC_BJacobi_Singleblock*)jac->data;
698   PetscScalar            *y_array;
699   const PetscScalar      *x_array;
700   PC                     subpc;
701 
702   PetscFunctionBegin;
703   /*
704       The VecPlaceArray() is to avoid having to copy the
705     y vector into the bjac->x vector. The reason for
706     the bjac->x vector is that we need a sequential vector
707     for the sequential solve.
708   */
709   ierr = VecGetArrayRead(x,&x_array);CHKERRQ(ierr);
710   ierr = VecGetArray(y,&y_array);CHKERRQ(ierr);
711   ierr = VecPlaceArray(bjac->x,x_array);CHKERRQ(ierr);
712   ierr = VecPlaceArray(bjac->y,y_array);CHKERRQ(ierr);
713 
714   /* apply the symmetric right portion of the inner PC operator */
715   /* note this by-passes the inner KSP and its options completely */
716 
717   ierr = KSPGetPC(jac->ksp[0],&subpc);CHKERRQ(ierr);
718   ierr = PCApplySymmetricRight(subpc,bjac->x,bjac->y);CHKERRQ(ierr);
719 
720   ierr = VecRestoreArrayRead(x,&x_array);CHKERRQ(ierr);
721   ierr = VecRestoreArray(y,&y_array);CHKERRQ(ierr);
722   PetscFunctionReturn(0);
723 }
724 
725 static PetscErrorCode PCApplyTranspose_BJacobi_Singleblock(PC pc,Vec x,Vec y)
726 {
727   PetscErrorCode         ierr;
728   PC_BJacobi             *jac  = (PC_BJacobi*)pc->data;
729   PC_BJacobi_Singleblock *bjac = (PC_BJacobi_Singleblock*)jac->data;
730   PetscScalar            *y_array;
731   const PetscScalar      *x_array;
732 
733   PetscFunctionBegin;
734   /*
735       The VecPlaceArray() is to avoid having to copy the
736     y vector into the bjac->x vector. The reason for
737     the bjac->x vector is that we need a sequential vector
738     for the sequential solve.
739   */
740   ierr = VecGetArrayRead(x,&x_array);CHKERRQ(ierr);
741   ierr = VecGetArray(y,&y_array);CHKERRQ(ierr);
742   ierr = VecPlaceArray(bjac->x,x_array);CHKERRQ(ierr);
743   ierr = VecPlaceArray(bjac->y,y_array);CHKERRQ(ierr);
744   ierr = KSPSolveTranspose(jac->ksp[0],bjac->x,bjac->y);CHKERRQ(ierr);
745   ierr = KSPCheckSolve(jac->ksp[0],pc,bjac->y);CHKERRQ(ierr);
746   ierr = VecResetArray(bjac->x);CHKERRQ(ierr);
747   ierr = VecResetArray(bjac->y);CHKERRQ(ierr);
748   ierr = VecRestoreArrayRead(x,&x_array);CHKERRQ(ierr);
749   ierr = VecRestoreArray(y,&y_array);CHKERRQ(ierr);
750   PetscFunctionReturn(0);
751 }
752 
753 static PetscErrorCode PCSetUp_BJacobi_Singleblock(PC pc,Mat mat,Mat pmat)
754 {
755   PC_BJacobi             *jac = (PC_BJacobi*)pc->data;
756   PetscErrorCode         ierr;
757   PetscInt               m;
758   KSP                    ksp;
759   PC_BJacobi_Singleblock *bjac;
760   PetscBool              wasSetup = PETSC_TRUE;
761   VecType                vectype;
762   const char             *prefix;
763 
764   PetscFunctionBegin;
765   if (!pc->setupcalled) {
766     if (!jac->ksp) {
767       wasSetup = PETSC_FALSE;
768 
769       ierr = KSPCreate(PETSC_COMM_SELF,&ksp);CHKERRQ(ierr);
770       ierr = KSPSetErrorIfNotConverged(ksp,pc->erroriffailure);CHKERRQ(ierr);
771       ierr = PetscObjectIncrementTabLevel((PetscObject)ksp,(PetscObject)pc,1);CHKERRQ(ierr);
772       ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)ksp);CHKERRQ(ierr);
773       ierr = KSPSetType(ksp,KSPPREONLY);CHKERRQ(ierr);
774       ierr = PCGetOptionsPrefix(pc,&prefix);CHKERRQ(ierr);
775       ierr = KSPSetOptionsPrefix(ksp,prefix);CHKERRQ(ierr);
776       ierr = KSPAppendOptionsPrefix(ksp,"sub_");CHKERRQ(ierr);
777 
778       pc->ops->reset               = PCReset_BJacobi_Singleblock;
779       pc->ops->destroy             = PCDestroy_BJacobi_Singleblock;
780       pc->ops->apply               = PCApply_BJacobi_Singleblock;
781       pc->ops->matapply            = PCMatApply_BJacobi_Singleblock;
782       pc->ops->applysymmetricleft  = PCApplySymmetricLeft_BJacobi_Singleblock;
783       pc->ops->applysymmetricright = PCApplySymmetricRight_BJacobi_Singleblock;
784       pc->ops->applytranspose      = PCApplyTranspose_BJacobi_Singleblock;
785       pc->ops->setuponblocks       = PCSetUpOnBlocks_BJacobi_Singleblock;
786 
787       ierr        = PetscMalloc1(1,&jac->ksp);CHKERRQ(ierr);
788       jac->ksp[0] = ksp;
789 
790       ierr      = PetscNewLog(pc,&bjac);CHKERRQ(ierr);
791       jac->data = (void*)bjac;
792     } else {
793       ksp  = jac->ksp[0];
794       bjac = (PC_BJacobi_Singleblock*)jac->data;
795     }
796 
797     /*
798       The reason we need to generate these vectors is to serve
799       as the right-hand side and solution vector for the solve on the
800       block. We do not need to allocate space for the vectors since
801       that is provided via VecPlaceArray() just before the call to
802       KSPSolve() on the block.
803     */
804     ierr = MatGetSize(pmat,&m,&m);CHKERRQ(ierr);
805     ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,1,m,NULL,&bjac->x);CHKERRQ(ierr);
806     ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,1,m,NULL,&bjac->y);CHKERRQ(ierr);
807     ierr = MatGetVecType(pmat,&vectype);CHKERRQ(ierr);
808     ierr = VecSetType(bjac->x,vectype);CHKERRQ(ierr);
809     ierr = VecSetType(bjac->y,vectype);CHKERRQ(ierr);
810     ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)bjac->x);CHKERRQ(ierr);
811     ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)bjac->y);CHKERRQ(ierr);
812   } else {
813     ksp  = jac->ksp[0];
814     bjac = (PC_BJacobi_Singleblock*)jac->data;
815   }
816   ierr = KSPGetOptionsPrefix(ksp,&prefix);CHKERRQ(ierr);
817   if (pc->useAmat) {
818     ierr = KSPSetOperators(ksp,mat,pmat);CHKERRQ(ierr);
819     ierr = MatSetOptionsPrefix(mat,prefix);CHKERRQ(ierr);
820   } else {
821     ierr = KSPSetOperators(ksp,pmat,pmat);CHKERRQ(ierr);
822   }
823   ierr = MatSetOptionsPrefix(pmat,prefix);CHKERRQ(ierr);
824   if (!wasSetup && pc->setfromoptionscalled) {
825     /* If PCSetFromOptions_BJacobi is called later, KSPSetFromOptions will be called at that time. */
826     ierr = KSPSetFromOptions(ksp);CHKERRQ(ierr);
827   }
828   PetscFunctionReturn(0);
829 }
830 
831 /* ---------------------------------------------------------------------------------------------*/
832 static PetscErrorCode PCReset_BJacobi_Multiblock(PC pc)
833 {
834   PC_BJacobi            *jac  = (PC_BJacobi*)pc->data;
835   PC_BJacobi_Multiblock *bjac = (PC_BJacobi_Multiblock*)jac->data;
836   PetscErrorCode        ierr;
837   PetscInt              i;
838 
839   PetscFunctionBegin;
840   if (bjac && bjac->pmat) {
841     ierr = MatDestroyMatrices(jac->n_local,&bjac->pmat);CHKERRQ(ierr);
842     if (pc->useAmat) {
843       ierr = MatDestroyMatrices(jac->n_local,&bjac->mat);CHKERRQ(ierr);
844     }
845   }
846 
847   for (i=0; i<jac->n_local; i++) {
848     ierr = KSPReset(jac->ksp[i]);CHKERRQ(ierr);
849     if (bjac && bjac->x) {
850       ierr = VecDestroy(&bjac->x[i]);CHKERRQ(ierr);
851       ierr = VecDestroy(&bjac->y[i]);CHKERRQ(ierr);
852       ierr = ISDestroy(&bjac->is[i]);CHKERRQ(ierr);
853     }
854   }
855   ierr = PetscFree(jac->l_lens);CHKERRQ(ierr);
856   ierr = PetscFree(jac->g_lens);CHKERRQ(ierr);
857   PetscFunctionReturn(0);
858 }
859 
860 static PetscErrorCode PCDestroy_BJacobi_Multiblock(PC pc)
861 {
862   PC_BJacobi            *jac  = (PC_BJacobi*)pc->data;
863   PC_BJacobi_Multiblock *bjac = (PC_BJacobi_Multiblock*)jac->data;
864   PetscErrorCode        ierr;
865   PetscInt              i;
866 
867   PetscFunctionBegin;
868   ierr = PCReset_BJacobi_Multiblock(pc);CHKERRQ(ierr);
869   if (bjac) {
870     ierr = PetscFree2(bjac->x,bjac->y);CHKERRQ(ierr);
871     ierr = PetscFree(bjac->starts);CHKERRQ(ierr);
872     ierr = PetscFree(bjac->is);CHKERRQ(ierr);
873   }
874   ierr = PetscFree(jac->data);CHKERRQ(ierr);
875   for (i=0; i<jac->n_local; i++) {
876     ierr = KSPDestroy(&jac->ksp[i]);CHKERRQ(ierr);
877   }
878   ierr = PetscFree(jac->ksp);CHKERRQ(ierr);
879   ierr = PetscFree(pc->data);CHKERRQ(ierr);
880   PetscFunctionReturn(0);
881 }
882 
883 static PetscErrorCode PCSetUpOnBlocks_BJacobi_Multiblock(PC pc)
884 {
885   PC_BJacobi         *jac = (PC_BJacobi*)pc->data;
886   PetscErrorCode     ierr;
887   PetscInt           i,n_local = jac->n_local;
888   KSPConvergedReason reason;
889 
890   PetscFunctionBegin;
891   for (i=0; i<n_local; i++) {
892     ierr = KSPSetUp(jac->ksp[i]);CHKERRQ(ierr);
893     ierr = KSPGetConvergedReason(jac->ksp[i],&reason);CHKERRQ(ierr);
894     if (reason == KSP_DIVERGED_PC_FAILED) {
895       pc->failedreason = PC_SUBPC_ERROR;
896     }
897   }
898   PetscFunctionReturn(0);
899 }
900 
901 /*
902       Preconditioner for block Jacobi
903 */
904 static PetscErrorCode PCApply_BJacobi_Multiblock(PC pc,Vec x,Vec y)
905 {
906   PC_BJacobi            *jac = (PC_BJacobi*)pc->data;
907   PetscErrorCode        ierr;
908   PetscInt              i,n_local = jac->n_local;
909   PC_BJacobi_Multiblock *bjac = (PC_BJacobi_Multiblock*)jac->data;
910   PetscScalar           *yin;
911   const PetscScalar     *xin;
912 
913   PetscFunctionBegin;
914   ierr = VecGetArrayRead(x,&xin);CHKERRQ(ierr);
915   ierr = VecGetArray(y,&yin);CHKERRQ(ierr);
916   for (i=0; i<n_local; i++) {
917     /*
918        To avoid copying the subvector from x into a workspace we instead
919        make the workspace vector array point to the subpart of the array of
920        the global vector.
921     */
922     ierr = VecPlaceArray(bjac->x[i],xin+bjac->starts[i]);CHKERRQ(ierr);
923     ierr = VecPlaceArray(bjac->y[i],yin+bjac->starts[i]);CHKERRQ(ierr);
924 
925     ierr = PetscLogEventBegin(PC_ApplyOnBlocks,jac->ksp[i],bjac->x[i],bjac->y[i],0);CHKERRQ(ierr);
926     ierr = KSPSolve(jac->ksp[i],bjac->x[i],bjac->y[i]);CHKERRQ(ierr);
927     ierr = KSPCheckSolve(jac->ksp[i],pc,bjac->y[i]);CHKERRQ(ierr);
928     ierr = PetscLogEventEnd(PC_ApplyOnBlocks,jac->ksp[i],bjac->x[i],bjac->y[i],0);CHKERRQ(ierr);
929 
930     ierr = VecResetArray(bjac->x[i]);CHKERRQ(ierr);
931     ierr = VecResetArray(bjac->y[i]);CHKERRQ(ierr);
932   }
933   ierr = VecRestoreArrayRead(x,&xin);CHKERRQ(ierr);
934   ierr = VecRestoreArray(y,&yin);CHKERRQ(ierr);
935   PetscFunctionReturn(0);
936 }
937 
938 /*
939       Preconditioner for block Jacobi
940 */
941 static PetscErrorCode PCApplyTranspose_BJacobi_Multiblock(PC pc,Vec x,Vec y)
942 {
943   PC_BJacobi            *jac = (PC_BJacobi*)pc->data;
944   PetscErrorCode        ierr;
945   PetscInt              i,n_local = jac->n_local;
946   PC_BJacobi_Multiblock *bjac = (PC_BJacobi_Multiblock*)jac->data;
947   PetscScalar           *yin;
948   const PetscScalar     *xin;
949 
950   PetscFunctionBegin;
951   ierr = VecGetArrayRead(x,&xin);CHKERRQ(ierr);
952   ierr = VecGetArray(y,&yin);CHKERRQ(ierr);
953   for (i=0; i<n_local; i++) {
954     /*
955        To avoid copying the subvector from x into a workspace we instead
956        make the workspace vector array point to the subpart of the array of
957        the global vector.
958     */
959     ierr = VecPlaceArray(bjac->x[i],xin+bjac->starts[i]);CHKERRQ(ierr);
960     ierr = VecPlaceArray(bjac->y[i],yin+bjac->starts[i]);CHKERRQ(ierr);
961 
962     ierr = PetscLogEventBegin(PC_ApplyTransposeOnBlocks,jac->ksp[i],bjac->x[i],bjac->y[i],0);CHKERRQ(ierr);
963     ierr = KSPSolveTranspose(jac->ksp[i],bjac->x[i],bjac->y[i]);CHKERRQ(ierr);
964     ierr = KSPCheckSolve(jac->ksp[i],pc,bjac->y[i]);CHKERRQ(ierr);
965     ierr = PetscLogEventEnd(PC_ApplyTransposeOnBlocks,jac->ksp[i],bjac->x[i],bjac->y[i],0);CHKERRQ(ierr);
966 
967     ierr = VecResetArray(bjac->x[i]);CHKERRQ(ierr);
968     ierr = VecResetArray(bjac->y[i]);CHKERRQ(ierr);
969   }
970   ierr = VecRestoreArrayRead(x,&xin);CHKERRQ(ierr);
971   ierr = VecRestoreArray(y,&yin);CHKERRQ(ierr);
972   PetscFunctionReturn(0);
973 }
974 
975 static PetscErrorCode PCSetUp_BJacobi_Multiblock(PC pc,Mat mat,Mat pmat)
976 {
977   PC_BJacobi            *jac = (PC_BJacobi*)pc->data;
978   PetscErrorCode        ierr;
979   PetscInt              m,n_local,N,M,start,i;
980   const char            *prefix;
981   KSP                   ksp;
982   Vec                   x,y;
983   PC_BJacobi_Multiblock *bjac = (PC_BJacobi_Multiblock*)jac->data;
984   PC                    subpc;
985   IS                    is;
986   MatReuse              scall;
987   VecType               vectype;
988 
989   PetscFunctionBegin;
990   ierr = MatGetLocalSize(pc->pmat,&M,&N);CHKERRQ(ierr);
991 
992   n_local = jac->n_local;
993 
994   if (pc->useAmat) {
995     PetscBool same;
996     ierr = PetscObjectTypeCompare((PetscObject)mat,((PetscObject)pmat)->type_name,&same);CHKERRQ(ierr);
997     if (!same) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Matrices not of same type");
998   }
999 
1000   if (!pc->setupcalled) {
1001     scall = MAT_INITIAL_MATRIX;
1002 
1003     if (!jac->ksp) {
1004       pc->ops->reset         = PCReset_BJacobi_Multiblock;
1005       pc->ops->destroy       = PCDestroy_BJacobi_Multiblock;
1006       pc->ops->apply         = PCApply_BJacobi_Multiblock;
1007       pc->ops->matapply      = NULL;
1008       pc->ops->applytranspose= PCApplyTranspose_BJacobi_Multiblock;
1009       pc->ops->setuponblocks = PCSetUpOnBlocks_BJacobi_Multiblock;
1010 
1011       ierr = PetscNewLog(pc,&bjac);CHKERRQ(ierr);
1012       ierr = PetscMalloc1(n_local,&jac->ksp);CHKERRQ(ierr);
1013       ierr = PetscLogObjectMemory((PetscObject)pc,sizeof(n_local*sizeof(KSP)));CHKERRQ(ierr);
1014       ierr = PetscMalloc2(n_local,&bjac->x,n_local,&bjac->y);CHKERRQ(ierr);
1015       ierr = PetscMalloc1(n_local,&bjac->starts);CHKERRQ(ierr);
1016       ierr = PetscLogObjectMemory((PetscObject)pc,sizeof(n_local*sizeof(PetscScalar)));CHKERRQ(ierr);
1017 
1018       jac->data = (void*)bjac;
1019       ierr      = PetscMalloc1(n_local,&bjac->is);CHKERRQ(ierr);
1020       ierr      = PetscLogObjectMemory((PetscObject)pc,sizeof(n_local*sizeof(IS)));CHKERRQ(ierr);
1021 
1022       for (i=0; i<n_local; i++) {
1023         ierr = KSPCreate(PETSC_COMM_SELF,&ksp);CHKERRQ(ierr);
1024         ierr = KSPSetErrorIfNotConverged(ksp,pc->erroriffailure);CHKERRQ(ierr);
1025         ierr = PetscObjectIncrementTabLevel((PetscObject)ksp,(PetscObject)pc,1);CHKERRQ(ierr);
1026         ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)ksp);CHKERRQ(ierr);
1027         ierr = KSPSetType(ksp,KSPPREONLY);CHKERRQ(ierr);
1028         ierr = KSPGetPC(ksp,&subpc);CHKERRQ(ierr);
1029         ierr = PCGetOptionsPrefix(pc,&prefix);CHKERRQ(ierr);
1030         ierr = KSPSetOptionsPrefix(ksp,prefix);CHKERRQ(ierr);
1031         ierr = KSPAppendOptionsPrefix(ksp,"sub_");CHKERRQ(ierr);
1032 
1033         jac->ksp[i] = ksp;
1034       }
1035     } else {
1036       bjac = (PC_BJacobi_Multiblock*)jac->data;
1037     }
1038 
1039     start = 0;
1040     ierr = MatGetVecType(pmat,&vectype);CHKERRQ(ierr);
1041     for (i=0; i<n_local; i++) {
1042       m = jac->l_lens[i];
1043       /*
1044       The reason we need to generate these vectors is to serve
1045       as the right-hand side and solution vector for the solve on the
1046       block. We do not need to allocate space for the vectors since
1047       that is provided via VecPlaceArray() just before the call to
1048       KSPSolve() on the block.
1049 
1050       */
1051       ierr = VecCreateSeq(PETSC_COMM_SELF,m,&x);CHKERRQ(ierr);
1052       ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,1,m,NULL,&y);CHKERRQ(ierr);
1053       ierr = VecSetType(x,vectype);CHKERRQ(ierr);
1054       ierr = VecSetType(y,vectype);CHKERRQ(ierr);
1055       ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)x);CHKERRQ(ierr);
1056       ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)y);CHKERRQ(ierr);
1057 
1058       bjac->x[i]      = x;
1059       bjac->y[i]      = y;
1060       bjac->starts[i] = start;
1061 
1062       ierr        = ISCreateStride(PETSC_COMM_SELF,m,start,1,&is);CHKERRQ(ierr);
1063       bjac->is[i] = is;
1064       ierr        = PetscLogObjectParent((PetscObject)pc,(PetscObject)is);CHKERRQ(ierr);
1065 
1066       start += m;
1067     }
1068   } else {
1069     bjac = (PC_BJacobi_Multiblock*)jac->data;
1070     /*
1071        Destroy the blocks from the previous iteration
1072     */
1073     if (pc->flag == DIFFERENT_NONZERO_PATTERN) {
1074       ierr = MatDestroyMatrices(n_local,&bjac->pmat);CHKERRQ(ierr);
1075       if (pc->useAmat) {
1076         ierr = MatDestroyMatrices(n_local,&bjac->mat);CHKERRQ(ierr);
1077       }
1078       scall = MAT_INITIAL_MATRIX;
1079     } else scall = MAT_REUSE_MATRIX;
1080   }
1081 
1082   ierr = MatCreateSubMatrices(pmat,n_local,bjac->is,bjac->is,scall,&bjac->pmat);CHKERRQ(ierr);
1083   if (pc->useAmat) {
1084     ierr = MatCreateSubMatrices(mat,n_local,bjac->is,bjac->is,scall,&bjac->mat);CHKERRQ(ierr);
1085   }
1086   /* Return control to the user so that the submatrices can be modified (e.g., to apply
1087      different boundary conditions for the submatrices than for the global problem) */
1088   ierr = PCModifySubMatrices(pc,n_local,bjac->is,bjac->is,bjac->pmat,pc->modifysubmatricesP);CHKERRQ(ierr);
1089 
1090   for (i=0; i<n_local; i++) {
1091     ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)bjac->pmat[i]);CHKERRQ(ierr);
1092     ierr = KSPGetOptionsPrefix(jac->ksp[i],&prefix);CHKERRQ(ierr);
1093     if (pc->useAmat) {
1094       ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)bjac->mat[i]);CHKERRQ(ierr);
1095       ierr = KSPSetOperators(jac->ksp[i],bjac->mat[i],bjac->pmat[i]);CHKERRQ(ierr);
1096       ierr = MatSetOptionsPrefix(bjac->mat[i],prefix);CHKERRQ(ierr);
1097     } else {
1098       ierr = KSPSetOperators(jac->ksp[i],bjac->pmat[i],bjac->pmat[i]);CHKERRQ(ierr);
1099     }
1100     ierr = MatSetOptionsPrefix(bjac->pmat[i],prefix);CHKERRQ(ierr);
1101     if (pc->setfromoptionscalled) {
1102       ierr = KSPSetFromOptions(jac->ksp[i]);CHKERRQ(ierr);
1103     }
1104   }
1105   PetscFunctionReturn(0);
1106 }
1107 
1108 /* ---------------------------------------------------------------------------------------------*/
1109 /*
1110       These are for a single block with multiple processes
1111 */
1112 static PetscErrorCode PCSetUpOnBlocks_BJacobi_Multiproc(PC pc)
1113 {
1114   PetscErrorCode     ierr;
1115   PC_BJacobi         *jac = (PC_BJacobi*)pc->data;
1116   KSP                subksp = jac->ksp[0];
1117   KSPConvergedReason reason;
1118 
1119   PetscFunctionBegin;
1120   ierr = KSPSetUp(subksp);CHKERRQ(ierr);
1121   ierr = KSPGetConvergedReason(subksp,&reason);CHKERRQ(ierr);
1122   if (reason == KSP_DIVERGED_PC_FAILED) {
1123     pc->failedreason = PC_SUBPC_ERROR;
1124   }
1125   PetscFunctionReturn(0);
1126 }
1127 
1128 static PetscErrorCode PCReset_BJacobi_Multiproc(PC pc)
1129 {
1130   PC_BJacobi           *jac   = (PC_BJacobi*)pc->data;
1131   PC_BJacobi_Multiproc *mpjac = (PC_BJacobi_Multiproc*)jac->data;
1132   PetscErrorCode       ierr;
1133 
1134   PetscFunctionBegin;
1135   ierr = VecDestroy(&mpjac->ysub);CHKERRQ(ierr);
1136   ierr = VecDestroy(&mpjac->xsub);CHKERRQ(ierr);
1137   ierr = MatDestroy(&mpjac->submats);CHKERRQ(ierr);
1138   if (jac->ksp) {ierr = KSPReset(jac->ksp[0]);CHKERRQ(ierr);}
1139   PetscFunctionReturn(0);
1140 }
1141 
1142 static PetscErrorCode PCDestroy_BJacobi_Multiproc(PC pc)
1143 {
1144   PC_BJacobi           *jac   = (PC_BJacobi*)pc->data;
1145   PC_BJacobi_Multiproc *mpjac = (PC_BJacobi_Multiproc*)jac->data;
1146   PetscErrorCode       ierr;
1147 
1148   PetscFunctionBegin;
1149   ierr = PCReset_BJacobi_Multiproc(pc);CHKERRQ(ierr);
1150   ierr = KSPDestroy(&jac->ksp[0]);CHKERRQ(ierr);
1151   ierr = PetscFree(jac->ksp);CHKERRQ(ierr);
1152   ierr = PetscSubcommDestroy(&mpjac->psubcomm);CHKERRQ(ierr);
1153 
1154   ierr = PetscFree(mpjac);CHKERRQ(ierr);
1155   ierr = PetscFree(pc->data);CHKERRQ(ierr);
1156   PetscFunctionReturn(0);
1157 }
1158 
1159 static PetscErrorCode PCApply_BJacobi_Multiproc(PC pc,Vec x,Vec y)
1160 {
1161   PC_BJacobi           *jac   = (PC_BJacobi*)pc->data;
1162   PC_BJacobi_Multiproc *mpjac = (PC_BJacobi_Multiproc*)jac->data;
1163   PetscErrorCode       ierr;
1164   PetscScalar          *yarray;
1165   const PetscScalar    *xarray;
1166   KSPConvergedReason   reason;
1167 
1168   PetscFunctionBegin;
1169   /* place x's and y's local arrays into xsub and ysub */
1170   ierr = VecGetArrayRead(x,&xarray);CHKERRQ(ierr);
1171   ierr = VecGetArray(y,&yarray);CHKERRQ(ierr);
1172   ierr = VecPlaceArray(mpjac->xsub,xarray);CHKERRQ(ierr);
1173   ierr = VecPlaceArray(mpjac->ysub,yarray);CHKERRQ(ierr);
1174 
1175   /* apply preconditioner on each matrix block */
1176   ierr = PetscLogEventBegin(PC_ApplyOnBlocks,jac->ksp[0],mpjac->xsub,mpjac->ysub,0);CHKERRQ(ierr);
1177   ierr = KSPSolve(jac->ksp[0],mpjac->xsub,mpjac->ysub);CHKERRQ(ierr);
1178   ierr = KSPCheckSolve(jac->ksp[0],pc,mpjac->ysub);CHKERRQ(ierr);
1179   ierr = PetscLogEventEnd(PC_ApplyOnBlocks,jac->ksp[0],mpjac->xsub,mpjac->ysub,0);CHKERRQ(ierr);
1180   ierr = KSPGetConvergedReason(jac->ksp[0],&reason);CHKERRQ(ierr);
1181   if (reason == KSP_DIVERGED_PC_FAILED) {
1182     pc->failedreason = PC_SUBPC_ERROR;
1183   }
1184 
1185   ierr = VecResetArray(mpjac->xsub);CHKERRQ(ierr);
1186   ierr = VecResetArray(mpjac->ysub);CHKERRQ(ierr);
1187   ierr = VecRestoreArrayRead(x,&xarray);CHKERRQ(ierr);
1188   ierr = VecRestoreArray(y,&yarray);CHKERRQ(ierr);
1189   PetscFunctionReturn(0);
1190 }
1191 
1192 static PetscErrorCode PCMatApply_BJacobi_Multiproc(PC pc,Mat X,Mat Y)
1193 {
1194   PC_BJacobi           *jac   = (PC_BJacobi*)pc->data;
1195   KSPConvergedReason   reason;
1196   Mat                  sX,sY;
1197   const PetscScalar    *x;
1198   PetscScalar          *y;
1199   PetscInt             m,N,lda,ldb;
1200   PetscErrorCode       ierr;
1201 
1202   PetscFunctionBegin;
1203   /* apply preconditioner on each matrix block */
1204   ierr = MatGetLocalSize(X,&m,NULL);CHKERRQ(ierr);
1205   ierr = MatGetSize(X,NULL,&N);CHKERRQ(ierr);
1206   ierr = MatDenseGetLDA(X,&lda);CHKERRQ(ierr);
1207   ierr = MatDenseGetLDA(Y,&ldb);CHKERRQ(ierr);
1208   ierr = MatDenseGetArrayRead(X,&x);CHKERRQ(ierr);
1209   ierr = MatDenseGetArrayWrite(Y,&y);CHKERRQ(ierr);
1210   ierr = MatCreateDense(PetscObjectComm((PetscObject)jac->ksp[0]),m,PETSC_DECIDE,PETSC_DECIDE,N,(PetscScalar*)x,&sX);CHKERRQ(ierr);
1211   ierr = MatCreateDense(PetscObjectComm((PetscObject)jac->ksp[0]),m,PETSC_DECIDE,PETSC_DECIDE,N,y,&sY);CHKERRQ(ierr);
1212   ierr = MatDenseSetLDA(sX,lda);CHKERRQ(ierr);
1213   ierr = MatDenseSetLDA(sY,ldb);CHKERRQ(ierr);
1214   ierr = PetscLogEventBegin(PC_ApplyOnBlocks,jac->ksp[0],X,Y,0);CHKERRQ(ierr);
1215   ierr = KSPMatSolve(jac->ksp[0],sX,sY);CHKERRQ(ierr);
1216   ierr = KSPCheckSolve(jac->ksp[0],pc,NULL);CHKERRQ(ierr);
1217   ierr = PetscLogEventEnd(PC_ApplyOnBlocks,jac->ksp[0],X,Y,0);CHKERRQ(ierr);
1218   ierr = MatDestroy(&sY);CHKERRQ(ierr);
1219   ierr = MatDestroy(&sX);CHKERRQ(ierr);
1220   ierr = MatDenseRestoreArrayWrite(Y,&y);CHKERRQ(ierr);
1221   ierr = MatDenseRestoreArrayRead(X,&x);CHKERRQ(ierr);
1222   ierr = KSPGetConvergedReason(jac->ksp[0],&reason);CHKERRQ(ierr);
1223   if (reason == KSP_DIVERGED_PC_FAILED) {
1224     pc->failedreason = PC_SUBPC_ERROR;
1225   }
1226   PetscFunctionReturn(0);
1227 }
1228 
1229 static PetscErrorCode PCSetUp_BJacobi_Multiproc(PC pc)
1230 {
1231   PC_BJacobi           *jac   = (PC_BJacobi*)pc->data;
1232   PC_BJacobi_Multiproc *mpjac = (PC_BJacobi_Multiproc*)jac->data;
1233   PetscErrorCode       ierr;
1234   PetscInt             m,n;
1235   MPI_Comm             comm,subcomm=0;
1236   const char           *prefix;
1237   PetscBool            wasSetup = PETSC_TRUE;
1238   VecType              vectype;
1239 
1240   PetscFunctionBegin;
1241   ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr);
1242   if (jac->n_local > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only a single block in a subcommunicator is supported");
1243   jac->n_local = 1; /* currently only a single block is supported for a subcommunicator */
1244   if (!pc->setupcalled) {
1245     wasSetup  = PETSC_FALSE;
1246     ierr      = PetscNewLog(pc,&mpjac);CHKERRQ(ierr);
1247     jac->data = (void*)mpjac;
1248 
1249     /* initialize datastructure mpjac */
1250     if (!jac->psubcomm) {
1251       /* Create default contiguous subcommunicatiors if user does not provide them */
1252       ierr = PetscSubcommCreate(comm,&jac->psubcomm);CHKERRQ(ierr);
1253       ierr = PetscSubcommSetNumber(jac->psubcomm,jac->n);CHKERRQ(ierr);
1254       ierr = PetscSubcommSetType(jac->psubcomm,PETSC_SUBCOMM_CONTIGUOUS);CHKERRQ(ierr);
1255       ierr = PetscLogObjectMemory((PetscObject)pc,sizeof(PetscSubcomm));CHKERRQ(ierr);
1256     }
1257     mpjac->psubcomm = jac->psubcomm;
1258     subcomm         = PetscSubcommChild(mpjac->psubcomm);
1259 
1260     /* Get matrix blocks of pmat */
1261     ierr = MatGetMultiProcBlock(pc->pmat,subcomm,MAT_INITIAL_MATRIX,&mpjac->submats);CHKERRQ(ierr);
1262 
1263     /* create a new PC that processors in each subcomm have copy of */
1264     ierr = PetscMalloc1(1,&jac->ksp);CHKERRQ(ierr);
1265     ierr = KSPCreate(subcomm,&jac->ksp[0]);CHKERRQ(ierr);
1266     ierr = KSPSetErrorIfNotConverged(jac->ksp[0],pc->erroriffailure);CHKERRQ(ierr);
1267     ierr = PetscObjectIncrementTabLevel((PetscObject)jac->ksp[0],(PetscObject)pc,1);CHKERRQ(ierr);
1268     ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)jac->ksp[0]);CHKERRQ(ierr);
1269     ierr = KSPSetOperators(jac->ksp[0],mpjac->submats,mpjac->submats);CHKERRQ(ierr);
1270     ierr = KSPGetPC(jac->ksp[0],&mpjac->pc);CHKERRQ(ierr);
1271 
1272     ierr = PCGetOptionsPrefix(pc,&prefix);CHKERRQ(ierr);
1273     ierr = KSPSetOptionsPrefix(jac->ksp[0],prefix);CHKERRQ(ierr);
1274     ierr = KSPAppendOptionsPrefix(jac->ksp[0],"sub_");CHKERRQ(ierr);
1275     ierr = KSPGetOptionsPrefix(jac->ksp[0],&prefix);CHKERRQ(ierr);
1276     ierr = MatSetOptionsPrefix(mpjac->submats,prefix);CHKERRQ(ierr);
1277 
1278     /* create dummy vectors xsub and ysub */
1279     ierr = MatGetLocalSize(mpjac->submats,&m,&n);CHKERRQ(ierr);
1280     ierr = VecCreateMPIWithArray(subcomm,1,n,PETSC_DECIDE,NULL,&mpjac->xsub);CHKERRQ(ierr);
1281     ierr = VecCreateMPIWithArray(subcomm,1,m,PETSC_DECIDE,NULL,&mpjac->ysub);CHKERRQ(ierr);
1282     ierr = MatGetVecType(mpjac->submats,&vectype);CHKERRQ(ierr);
1283     ierr = VecSetType(mpjac->xsub,vectype);CHKERRQ(ierr);
1284     ierr = VecSetType(mpjac->ysub,vectype);CHKERRQ(ierr);
1285     ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)mpjac->xsub);CHKERRQ(ierr);
1286     ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)mpjac->ysub);CHKERRQ(ierr);
1287 
1288     pc->ops->setuponblocks = PCSetUpOnBlocks_BJacobi_Multiproc;
1289     pc->ops->reset         = PCReset_BJacobi_Multiproc;
1290     pc->ops->destroy       = PCDestroy_BJacobi_Multiproc;
1291     pc->ops->apply         = PCApply_BJacobi_Multiproc;
1292     pc->ops->matapply      = PCMatApply_BJacobi_Multiproc;
1293   } else { /* pc->setupcalled */
1294     subcomm = PetscSubcommChild(mpjac->psubcomm);
1295     if (pc->flag == DIFFERENT_NONZERO_PATTERN) {
1296       /* destroy old matrix blocks, then get new matrix blocks */
1297       if (mpjac->submats) {ierr = MatDestroy(&mpjac->submats);CHKERRQ(ierr);}
1298       ierr = MatGetMultiProcBlock(pc->pmat,subcomm,MAT_INITIAL_MATRIX,&mpjac->submats);CHKERRQ(ierr);
1299     } else {
1300       ierr = MatGetMultiProcBlock(pc->pmat,subcomm,MAT_REUSE_MATRIX,&mpjac->submats);CHKERRQ(ierr);
1301     }
1302     ierr = KSPSetOperators(jac->ksp[0],mpjac->submats,mpjac->submats);CHKERRQ(ierr);
1303   }
1304 
1305   if (!wasSetup && pc->setfromoptionscalled) {
1306     ierr = KSPSetFromOptions(jac->ksp[0]);CHKERRQ(ierr);
1307   }
1308   PetscFunctionReturn(0);
1309 }
1310