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