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