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