xref: /petsc/src/ksp/pc/impls/bjacobi/bjacobi.c (revision f7c6e6aaaf12910997c044fca6674251bc2ff4e3) !
1 #define PETSCKSP_DLL
2 
3 /*
4    Defines a block Jacobi preconditioner.
5 */
6 #include "src/mat/matimpl.h"
7 #include "private/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 separate 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 #if defined (PETSC_USE_LOG)
1022   static PetscEvent     SUBKspSolve;
1023 #endif
1024   PetscFunctionBegin;
1025   if (flag) {
1026     ierr = PetscLogEventRegister(&SUBKspSolve,"SubKspSolve",KSP_COOKIE);CHKERRQ(ierr);
1027     flag = PETSC_FALSE;
1028   }
1029   ierr = VecGetArray(x,&xin);CHKERRQ(ierr);
1030   ierr = VecGetArray(y,&yin);CHKERRQ(ierr);
1031   for (i=0; i<n_local; i++) {
1032     /*
1033        To avoid copying the subvector from x into a workspace we instead
1034        make the workspace vector array point to the subpart of the array of
1035        the global vector.
1036     */
1037     ierr = VecPlaceArray(bjac->x[i],xin+bjac->starts[i]);CHKERRQ(ierr);
1038     ierr = VecPlaceArray(bjac->y[i],yin+bjac->starts[i]);CHKERRQ(ierr);
1039 
1040     ierr = PetscLogEventBegin(SUBKspSolve,jac->ksp[i],bjac->x[i],bjac->y[i],0);CHKERRQ(ierr);
1041     ierr = KSPSolve(jac->ksp[i],bjac->x[i],bjac->y[i]);CHKERRQ(ierr);
1042     ierr = PetscLogEventEnd(SUBKspSolve,jac->ksp[i],bjac->x[i],bjac->y[i],0);CHKERRQ(ierr);
1043 
1044     ierr = VecResetArray(bjac->x[i]);CHKERRQ(ierr);
1045     ierr = VecResetArray(bjac->y[i]);CHKERRQ(ierr);
1046   }
1047   ierr = VecRestoreArray(x,&xin);CHKERRQ(ierr);
1048   ierr = VecRestoreArray(y,&yin);CHKERRQ(ierr);
1049   PetscFunctionReturn(0);
1050 }
1051 
1052 /*
1053       Preconditioner for block Jacobi
1054 */
1055 #undef __FUNCT__
1056 #define __FUNCT__ "PCApplyTranspose_BJacobi_Multiblock"
1057 PetscErrorCode PCApplyTranspose_BJacobi_Multiblock(PC pc,Vec x,Vec y)
1058 {
1059   PC_BJacobi            *jac = (PC_BJacobi*)pc->data;
1060   PetscErrorCode        ierr;
1061   PetscInt              i,n_local = jac->n_local;
1062   PC_BJacobi_Multiblock *bjac = (PC_BJacobi_Multiblock*)jac->data;
1063   PetscScalar           *xin,*yin;
1064   static PetscTruth     flag = PETSC_TRUE;
1065 #if defined (PETSC_USE_LOG)
1066   static PetscEvent     SUBKspSolve;
1067 #endif
1068 
1069   PetscFunctionBegin;
1070   if (flag) {
1071     ierr = PetscLogEventRegister(&SUBKspSolve,"SubKspSolveTranspose",KSP_COOKIE);CHKERRQ(ierr);
1072     flag = PETSC_FALSE;
1073   }
1074   ierr = VecGetArray(x,&xin);CHKERRQ(ierr);
1075   ierr = VecGetArray(y,&yin);CHKERRQ(ierr);
1076   for (i=0; i<n_local; i++) {
1077     /*
1078        To avoid copying the subvector from x into a workspace we instead
1079        make the workspace vector array point to the subpart of the array of
1080        the global vector.
1081     */
1082     ierr = VecPlaceArray(bjac->x[i],xin+bjac->starts[i]);CHKERRQ(ierr);
1083     ierr = VecPlaceArray(bjac->y[i],yin+bjac->starts[i]);CHKERRQ(ierr);
1084 
1085     ierr = PetscLogEventBegin(SUBKspSolve,jac->ksp[i],bjac->x[i],bjac->y[i],0);CHKERRQ(ierr);
1086     ierr = KSPSolveTranspose(jac->ksp[i],bjac->x[i],bjac->y[i]);CHKERRQ(ierr);
1087     ierr = PetscLogEventEnd(SUBKspSolve,jac->ksp[i],bjac->x[i],bjac->y[i],0);CHKERRQ(ierr);
1088   }
1089   ierr = VecRestoreArray(x,&xin);CHKERRQ(ierr);
1090   ierr = VecRestoreArray(y,&yin);CHKERRQ(ierr);
1091   PetscFunctionReturn(0);
1092 }
1093 
1094 #undef __FUNCT__
1095 #define __FUNCT__ "PCSetUp_BJacobi_Multiblock"
1096 static PetscErrorCode PCSetUp_BJacobi_Multiblock(PC pc,Mat mat,Mat pmat)
1097 {
1098   PC_BJacobi             *jac = (PC_BJacobi*)pc->data;
1099   PetscErrorCode         ierr;
1100   PetscInt               m,n_local,N,M,start,i;
1101   const char             *prefix,*pprefix,*mprefix;
1102   KSP                    ksp;
1103   Vec                    x,y;
1104   PC_BJacobi_Multiblock  *bjac = (PC_BJacobi_Multiblock*)jac->data;
1105   PC                     subpc;
1106   IS                     is;
1107   MatReuse               scall = MAT_REUSE_MATRIX;
1108 
1109   PetscFunctionBegin;
1110   ierr = MatGetLocalSize(pc->pmat,&M,&N);CHKERRQ(ierr);
1111 
1112   n_local = jac->n_local;
1113 
1114   if (jac->use_true_local) {
1115     if (mat->type != pmat->type) SETERRQ(PETSC_ERR_ARG_INCOMP,"Matrices not of same type");
1116   }
1117 
1118   /* set default direct solver with no Krylov method */
1119   if (!pc->setupcalled) {
1120     scall                  = MAT_INITIAL_MATRIX;
1121     pc->ops->destroy       = PCDestroy_BJacobi_Multiblock;
1122     pc->ops->apply         = PCApply_BJacobi_Multiblock;
1123     pc->ops->applytranspose= PCApplyTranspose_BJacobi_Multiblock;
1124     pc->ops->setuponblocks = PCSetUpOnBlocks_BJacobi_Multiblock;
1125 
1126     ierr = PetscMalloc(sizeof(PC_BJacobi_Multiblock),&bjac);CHKERRQ(ierr);
1127     ierr = PetscLogObjectMemory(pc,sizeof(PC_BJacobi_Multiblock));CHKERRQ(ierr);
1128     ierr = PetscMalloc(n_local*sizeof(KSP),&jac->ksp);CHKERRQ(ierr);
1129     ierr = PetscLogObjectMemory(pc,sizeof(n_local*sizeof(KSP)));CHKERRQ(ierr);
1130     ierr = PetscMalloc(2*n_local*sizeof(Vec),&bjac->x);CHKERRQ(ierr);
1131     ierr = PetscLogObjectMemory(pc,sizeof(2*n_local*sizeof(Vec)));CHKERRQ(ierr);
1132     bjac->y      = bjac->x + n_local;
1133     ierr = PetscMalloc(n_local*sizeof(PetscScalar),&bjac->starts);CHKERRQ(ierr);
1134     ierr = PetscLogObjectMemory(pc,sizeof(n_local*sizeof(PetscScalar)));CHKERRQ(ierr);
1135 
1136     jac->data    = (void*)bjac;
1137     ierr = PetscMalloc(n_local*sizeof(IS),&bjac->is);CHKERRQ(ierr);
1138     ierr = PetscLogObjectMemory(pc,sizeof(n_local*sizeof(IS)));CHKERRQ(ierr);
1139 
1140     start = 0;
1141     for (i=0; i<n_local; i++) {
1142       ierr = KSPCreate(PETSC_COMM_SELF,&ksp);CHKERRQ(ierr);
1143       ierr = PetscLogObjectParent(pc,ksp);CHKERRQ(ierr);
1144       ierr = KSPSetType(ksp,KSPPREONLY);CHKERRQ(ierr);
1145       ierr = KSPGetPC(ksp,&subpc);CHKERRQ(ierr);
1146       ierr = PCGetOptionsPrefix(pc,&prefix);CHKERRQ(ierr);
1147       ierr = KSPSetOptionsPrefix(ksp,prefix);CHKERRQ(ierr);
1148       ierr = KSPAppendOptionsPrefix(ksp,"sub_");CHKERRQ(ierr);
1149 
1150       m = jac->l_lens[i];
1151 
1152       /*
1153       The reason we need to generate these vectors is to serve
1154       as the right-hand side and solution vector for the solve on the
1155       block. We do not need to allocate space for the vectors since
1156       that is provided via VecPlaceArray() just before the call to
1157       KSPSolve() on the block.
1158 
1159       */
1160       ierr = VecCreateSeq(PETSC_COMM_SELF,m,&x);CHKERRQ(ierr);
1161       ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,m,PETSC_NULL,&y);CHKERRQ(ierr);
1162       ierr = PetscLogObjectParent(pc,x);CHKERRQ(ierr);
1163       ierr = PetscLogObjectParent(pc,y);CHKERRQ(ierr);
1164       bjac->x[i]      = x;
1165       bjac->y[i]      = y;
1166       bjac->starts[i] = start;
1167       jac->ksp[i]    = ksp;
1168 
1169       ierr = ISCreateStride(PETSC_COMM_SELF,m,start,1,&is);CHKERRQ(ierr);
1170       bjac->is[i] = is;
1171       ierr = PetscLogObjectParent(pc,is);CHKERRQ(ierr);
1172 
1173       start += m;
1174     }
1175   } else {
1176     bjac = (PC_BJacobi_Multiblock*)jac->data;
1177     /*
1178        Destroy the blocks from the previous iteration
1179     */
1180     if (pc->flag == DIFFERENT_NONZERO_PATTERN) {
1181       ierr = MatDestroyMatrices(n_local,&bjac->pmat);CHKERRQ(ierr);
1182       if (jac->use_true_local) {
1183         ierr = MatDestroyMatrices(n_local,&bjac->mat);CHKERRQ(ierr);
1184       }
1185       scall = MAT_INITIAL_MATRIX;
1186     }
1187   }
1188 
1189   ierr = MatGetSubMatrices(pmat,n_local,bjac->is,bjac->is,scall,&bjac->pmat);CHKERRQ(ierr);
1190   if (jac->use_true_local) {
1191     ierr = PetscObjectGetOptionsPrefix((PetscObject)mat,&mprefix);CHKERRQ(ierr);
1192     ierr = MatGetSubMatrices(mat,n_local,bjac->is,bjac->is,scall,&bjac->mat);CHKERRQ(ierr);
1193   }
1194   /* Return control to the user so that the submatrices can be modified (e.g., to apply
1195      different boundary conditions for the submatrices than for the global problem) */
1196   ierr = PCModifySubMatrices(pc,n_local,bjac->is,bjac->is,bjac->pmat,pc->modifysubmatricesP);CHKERRQ(ierr);
1197 
1198   ierr = PetscObjectGetOptionsPrefix((PetscObject)pmat,&pprefix);CHKERRQ(ierr);
1199   for (i=0; i<n_local; i++) {
1200     ierr = PetscLogObjectParent(pc,bjac->pmat[i]);CHKERRQ(ierr);
1201     ierr = PetscObjectSetOptionsPrefix((PetscObject)bjac->pmat[i],pprefix);CHKERRQ(ierr);
1202     if (jac->use_true_local) {
1203       ierr = PetscLogObjectParent(pc,bjac->mat[i]);CHKERRQ(ierr);
1204       ierr = PetscObjectSetOptionsPrefix((PetscObject)bjac->mat[i],mprefix);CHKERRQ(ierr);
1205       ierr = KSPSetOperators(jac->ksp[i],bjac->mat[i],bjac->pmat[i],pc->flag);CHKERRQ(ierr);
1206     } else {
1207       ierr = KSPSetOperators(jac->ksp[i],bjac->pmat[i],bjac->pmat[i],pc->flag);CHKERRQ(ierr);
1208     }
1209     ierr = KSPSetFromOptions(jac->ksp[i]);CHKERRQ(ierr);
1210   }
1211 
1212   PetscFunctionReturn(0);
1213 }
1214 
1215 
1216 
1217 
1218 
1219 
1220 
1221 
1222 
1223 
1224