xref: /petsc/src/ksp/pc/impls/bjacobi/bjacobi.c (revision bb6a94b07f42224f42eaa6d31e46344e9580f813)
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) SETERRQ(PETSC_ERR_ORDER,"Cannot set 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 
810   ierr = VecRestoreArray(x,&x_array);CHKERRQ(ierr);
811   ierr = VecRestoreArray(y,&y_array);CHKERRQ(ierr);
812   PetscFunctionReturn(0);
813 }
814 
815 #undef __FUNCT__
816 #define __FUNCT__ "PCApplySymmetricRight_BJacobi_Singleblock"
817 PetscErrorCode PCApplySymmetricRight_BJacobi_Singleblock(PC pc,Vec x,Vec y)
818 {
819   PetscErrorCode         ierr;
820   PC_BJacobi             *jac = (PC_BJacobi*)pc->data;
821   PC_BJacobi_Singleblock *bjac = (PC_BJacobi_Singleblock*)jac->data;
822   PetscScalar            *x_array,*y_array;
823   PC                     subpc;
824 
825   PetscFunctionBegin;
826   /*
827       The VecPlaceArray() is to avoid having to copy the
828     y vector into the bjac->x vector. The reason for
829     the bjac->x vector is that we need a sequential vector
830     for the sequential solve.
831   */
832   ierr = VecGetArray(x,&x_array);CHKERRQ(ierr);
833   ierr = VecGetArray(y,&y_array);CHKERRQ(ierr);
834   ierr = VecPlaceArray(bjac->x,x_array);CHKERRQ(ierr);
835   ierr = VecPlaceArray(bjac->y,y_array);CHKERRQ(ierr);
836 
837   /* apply the symmetric right portion of the inner PC operator */
838   /* note this by-passes the inner KSP and its options completely */
839 
840   ierr = KSPGetPC(jac->ksp[0],&subpc);CHKERRQ(ierr);
841   ierr = PCApplySymmetricRight(subpc,bjac->x,bjac->y);CHKERRQ(ierr);
842 
843   ierr = VecRestoreArray(x,&x_array);CHKERRQ(ierr);
844   ierr = VecRestoreArray(y,&y_array);CHKERRQ(ierr);
845   PetscFunctionReturn(0);
846 }
847 
848 #undef __FUNCT__
849 #define __FUNCT__ "PCApplyTranspose_BJacobi_Singleblock"
850 PetscErrorCode PCApplyTranspose_BJacobi_Singleblock(PC pc,Vec x,Vec y)
851 {
852   PetscErrorCode         ierr;
853   PC_BJacobi             *jac = (PC_BJacobi*)pc->data;
854   PC_BJacobi_Singleblock *bjac = (PC_BJacobi_Singleblock*)jac->data;
855   PetscScalar            *x_array,*y_array;
856 
857   PetscFunctionBegin;
858   /*
859       The VecPlaceArray() is to avoid having to copy the
860     y vector into the bjac->x vector. The reason for
861     the bjac->x vector is that we need a sequential vector
862     for the sequential solve.
863   */
864   ierr = VecGetArray(x,&x_array);CHKERRQ(ierr);
865   ierr = VecGetArray(y,&y_array);CHKERRQ(ierr);
866   ierr = VecPlaceArray(bjac->x,x_array);CHKERRQ(ierr);
867   ierr = VecPlaceArray(bjac->y,y_array);CHKERRQ(ierr);
868   ierr = KSPSolveTranspose(jac->ksp[0],bjac->x,bjac->y);CHKERRQ(ierr);
869   ierr = VecRestoreArray(x,&x_array);CHKERRQ(ierr);
870   ierr = VecRestoreArray(y,&y_array);CHKERRQ(ierr);
871   PetscFunctionReturn(0);
872 }
873 
874 #undef __FUNCT__
875 #define __FUNCT__ "PCSetUp_BJacobi_Singleblock"
876 static PetscErrorCode PCSetUp_BJacobi_Singleblock(PC pc,Mat mat,Mat pmat)
877 {
878   PC_BJacobi             *jac = (PC_BJacobi*)pc->data;
879   PetscErrorCode         ierr;
880   PetscInt               m;
881   KSP                    ksp;
882   Vec                    x,y;
883   PC_BJacobi_Singleblock *bjac;
884   PC                     subpc;
885 
886   PetscFunctionBegin;
887 
888   /* set default direct solver with no Krylov method */
889   if (!pc->setupcalled) {
890     const char *prefix;
891     ierr = KSPCreate(PETSC_COMM_SELF,&ksp);CHKERRQ(ierr);
892     ierr = PetscLogObjectParent(pc,ksp);CHKERRQ(ierr);
893     ierr = KSPSetType(ksp,KSPPREONLY);CHKERRQ(ierr);
894     ierr = KSPGetPC(ksp,&subpc);CHKERRQ(ierr);
895     ierr = PCGetOptionsPrefix(pc,&prefix);CHKERRQ(ierr);
896     ierr = KSPSetOptionsPrefix(ksp,prefix);CHKERRQ(ierr);
897     ierr = KSPAppendOptionsPrefix(ksp,"sub_");CHKERRQ(ierr);
898     /*
899       The reason we need to generate these vectors is to serve
900       as the right-hand side and solution vector for the solve on the
901       block. We do not need to allocate space for the vectors since
902       that is provided via VecPlaceArray() just before the call to
903       KSPSolve() on the block.
904     */
905     ierr = MatGetSize(pmat,&m,&m);CHKERRQ(ierr);
906     ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,m,PETSC_NULL,&x);CHKERRQ(ierr);
907     ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,m,PETSC_NULL,&y);CHKERRQ(ierr);
908     ierr = PetscLogObjectParent(pc,x);CHKERRQ(ierr);
909     ierr = PetscLogObjectParent(pc,y);CHKERRQ(ierr);
910 
911     pc->ops->destroy             = PCDestroy_BJacobi_Singleblock;
912     pc->ops->apply               = PCApply_BJacobi_Singleblock;
913     pc->ops->applysymmetricleft  = PCApplySymmetricLeft_BJacobi_Singleblock;
914     pc->ops->applysymmetricright = PCApplySymmetricRight_BJacobi_Singleblock;
915     pc->ops->applytranspose      = PCApplyTranspose_BJacobi_Singleblock;
916     pc->ops->setuponblocks       = PCSetUpOnBlocks_BJacobi_Singleblock;
917 
918     ierr = PetscMalloc(sizeof(PC_BJacobi_Singleblock),&bjac);CHKERRQ(ierr);
919     ierr = PetscLogObjectMemory(pc,sizeof(PC_BJacobi_Singleblock));CHKERRQ(ierr);
920     bjac->x      = x;
921     bjac->y      = y;
922 
923     ierr = PetscMalloc(sizeof(KSP),&jac->ksp);CHKERRQ(ierr);
924     jac->ksp[0] = ksp;
925     jac->data    = (void*)bjac;
926   } else {
927     ksp = jac->ksp[0];
928     bjac = (PC_BJacobi_Singleblock *)jac->data;
929   }
930   if (jac->use_true_local) {
931     ierr = KSPSetOperators(ksp,mat,pmat,pc->flag);CHKERRQ(ierr);
932   }  else {
933     ierr = KSPSetOperators(ksp,pmat,pmat,pc->flag);CHKERRQ(ierr);
934   }
935   ierr = KSPSetFromOptions(ksp);CHKERRQ(ierr);
936   PetscFunctionReturn(0);
937 }
938 
939 /* ---------------------------------------------------------------------------------------------*/
940 
941 #undef __FUNCT__
942 #define __FUNCT__ "PCDestroy_BJacobi_Multiblock"
943 PetscErrorCode PCDestroy_BJacobi_Multiblock(PC pc)
944 {
945   PC_BJacobi            *jac = (PC_BJacobi*)pc->data;
946   PC_BJacobi_Multiblock *bjac = (PC_BJacobi_Multiblock*)jac->data;
947   PetscErrorCode        ierr;
948   PetscInt              i;
949 
950   PetscFunctionBegin;
951   ierr = MatDestroyMatrices(jac->n_local,&bjac->pmat);CHKERRQ(ierr);
952   if (jac->use_true_local) {
953     ierr = MatDestroyMatrices(jac->n_local,&bjac->mat);CHKERRQ(ierr);
954   }
955 
956   /*
957         If the on processor block had to be generated via a MatGetDiagonalBlock()
958      that creates a copy (for example MPIBDiag matrices do), this frees the space
959   */
960   if (jac->tp_mat) {
961     ierr = MatDestroy(jac->tp_mat);CHKERRQ(ierr);
962   }
963   if (jac->tp_pmat) {
964     ierr = MatDestroy(jac->tp_pmat);CHKERRQ(ierr);
965   }
966 
967   for (i=0; i<jac->n_local; i++) {
968     ierr = KSPDestroy(jac->ksp[i]);CHKERRQ(ierr);
969     ierr = VecDestroy(bjac->x[i]);CHKERRQ(ierr);
970     ierr = VecDestroy(bjac->y[i]);CHKERRQ(ierr);
971     ierr = ISDestroy(bjac->is[i]);CHKERRQ(ierr);
972   }
973   ierr = PetscFree(jac->ksp);CHKERRQ(ierr);
974   ierr = PetscFree(bjac->x);CHKERRQ(ierr);
975   ierr = PetscFree(bjac->starts);CHKERRQ(ierr);
976   ierr = PetscFree(bjac->is);CHKERRQ(ierr);
977   ierr = PetscFree(bjac);CHKERRQ(ierr);
978   if (jac->l_lens) {ierr = PetscFree(jac->l_lens);CHKERRQ(ierr);}
979   if (jac->g_lens) {ierr = PetscFree(jac->g_lens);CHKERRQ(ierr);}
980   ierr = PetscFree(jac);CHKERRQ(ierr);
981   PetscFunctionReturn(0);
982 }
983 
984 #undef __FUNCT__
985 #define __FUNCT__ "PCSetUpOnBlocks_BJacobi_Multiblock"
986 PetscErrorCode PCSetUpOnBlocks_BJacobi_Multiblock(PC pc)
987 {
988   PC_BJacobi     *jac = (PC_BJacobi*)pc->data;
989   PetscErrorCode ierr;
990   PetscInt       i,n_local = jac->n_local;
991 
992   PetscFunctionBegin;
993   for (i=0; i<n_local; i++) {
994     ierr = KSPSetUp(jac->ksp[i]);CHKERRQ(ierr);
995   }
996   PetscFunctionReturn(0);
997 }
998 
999 /*
1000       Preconditioner for block Jacobi
1001 */
1002 #undef __FUNCT__
1003 #define __FUNCT__ "PCApply_BJacobi_Multiblock"
1004 PetscErrorCode PCApply_BJacobi_Multiblock(PC pc,Vec x,Vec y)
1005 {
1006   PC_BJacobi            *jac = (PC_BJacobi*)pc->data;
1007   PetscErrorCode        ierr;
1008   PetscInt              i,n_local = jac->n_local;
1009   PC_BJacobi_Multiblock *bjac = (PC_BJacobi_Multiblock*)jac->data;
1010   PetscScalar           *xin,*yin;
1011   static PetscTruth     flag = PETSC_TRUE;
1012   static PetscEvent     SUBKspSolve;
1013 
1014   PetscFunctionBegin;
1015   if (flag) {
1016     ierr = PetscLogEventRegister(&SUBKspSolve,"SubKspSolve",KSP_COOKIE);CHKERRQ(ierr);
1017     flag = PETSC_FALSE;
1018   }
1019   ierr = VecGetArray(x,&xin);CHKERRQ(ierr);
1020   ierr = VecGetArray(y,&yin);CHKERRQ(ierr);
1021   for (i=0; i<n_local; i++) {
1022     /*
1023        To avoid copying the subvector from x into a workspace we instead
1024        make the workspace vector array point to the subpart of the array of
1025        the global vector.
1026     */
1027     ierr = VecPlaceArray(bjac->x[i],xin+bjac->starts[i]);CHKERRQ(ierr);
1028     ierr = VecPlaceArray(bjac->y[i],yin+bjac->starts[i]);CHKERRQ(ierr);
1029 
1030     ierr = PetscLogEventBegin(SUBKspSolve,jac->ksp[i],bjac->x[i],bjac->y[i],0);CHKERRQ(ierr);
1031     ierr = KSPSolve(jac->ksp[i],bjac->x[i],bjac->y[i]);CHKERRQ(ierr);
1032     ierr = PetscLogEventEnd(SUBKspSolve,jac->ksp[i],bjac->x[i],bjac->y[i],0);CHKERRQ(ierr);
1033   }
1034   ierr = VecRestoreArray(x,&xin);CHKERRQ(ierr);
1035   ierr = VecRestoreArray(y,&yin);CHKERRQ(ierr);
1036   PetscFunctionReturn(0);
1037 }
1038 
1039 /*
1040       Preconditioner for block Jacobi
1041 */
1042 #undef __FUNCT__
1043 #define __FUNCT__ "PCApplyTranspose_BJacobi_Multiblock"
1044 PetscErrorCode PCApplyTranspose_BJacobi_Multiblock(PC pc,Vec x,Vec y)
1045 {
1046   PC_BJacobi            *jac = (PC_BJacobi*)pc->data;
1047   PetscErrorCode        ierr;
1048   PetscInt              i,n_local = jac->n_local;
1049   PC_BJacobi_Multiblock *bjac = (PC_BJacobi_Multiblock*)jac->data;
1050   PetscScalar           *xin,*yin;
1051   static PetscTruth     flag = PETSC_TRUE;
1052   static PetscEvent     SUBKspSolve;
1053 
1054   PetscFunctionBegin;
1055   if (flag) {
1056     ierr = PetscLogEventRegister(&SUBKspSolve,"SubKspSolveTranspose",KSP_COOKIE);CHKERRQ(ierr);
1057     flag = PETSC_FALSE;
1058   }
1059   ierr = VecGetArray(x,&xin);CHKERRQ(ierr);
1060   ierr = VecGetArray(y,&yin);CHKERRQ(ierr);
1061   for (i=0; i<n_local; i++) {
1062     /*
1063        To avoid copying the subvector from x into a workspace we instead
1064        make the workspace vector array point to the subpart of the array of
1065        the global vector.
1066     */
1067     ierr = VecPlaceArray(bjac->x[i],xin+bjac->starts[i]);CHKERRQ(ierr);
1068     ierr = VecPlaceArray(bjac->y[i],yin+bjac->starts[i]);CHKERRQ(ierr);
1069 
1070     ierr = PetscLogEventBegin(SUBKspSolve,jac->ksp[i],bjac->x[i],bjac->y[i],0);CHKERRQ(ierr);
1071     ierr = KSPSolveTranspose(jac->ksp[i],bjac->x[i],bjac->y[i]);CHKERRQ(ierr);
1072     ierr = PetscLogEventEnd(SUBKspSolve,jac->ksp[i],bjac->x[i],bjac->y[i],0);CHKERRQ(ierr);
1073   }
1074   ierr = VecRestoreArray(x,&xin);CHKERRQ(ierr);
1075   ierr = VecRestoreArray(y,&yin);CHKERRQ(ierr);
1076   PetscFunctionReturn(0);
1077 }
1078 
1079 #undef __FUNCT__
1080 #define __FUNCT__ "PCSetUp_BJacobi_Multiblock"
1081 static PetscErrorCode PCSetUp_BJacobi_Multiblock(PC pc,Mat mat,Mat pmat)
1082 {
1083   PC_BJacobi             *jac = (PC_BJacobi*)pc->data;
1084   PetscErrorCode         ierr;
1085   PetscInt               m,n_local,N,M,start,i;
1086   const char             *prefix,*pprefix,*mprefix;
1087   KSP                    ksp;
1088   Vec                    x,y;
1089   PC_BJacobi_Multiblock  *bjac = (PC_BJacobi_Multiblock*)jac->data;
1090   PC                     subpc;
1091   IS                     is;
1092   MatReuse               scall = MAT_REUSE_MATRIX;
1093 
1094   PetscFunctionBegin;
1095   ierr = MatGetLocalSize(pc->pmat,&M,&N);CHKERRQ(ierr);
1096 
1097   n_local = jac->n_local;
1098 
1099   if (jac->use_true_local) {
1100     if (mat->type != pmat->type) SETERRQ(PETSC_ERR_ARG_INCOMP,"Matrices not of same type");
1101   }
1102 
1103   /* set default direct solver with no Krylov method */
1104   if (!pc->setupcalled) {
1105     scall                  = MAT_INITIAL_MATRIX;
1106     pc->ops->destroy       = PCDestroy_BJacobi_Multiblock;
1107     pc->ops->apply         = PCApply_BJacobi_Multiblock;
1108     pc->ops->applytranspose= PCApplyTranspose_BJacobi_Multiblock;
1109     pc->ops->setuponblocks = PCSetUpOnBlocks_BJacobi_Multiblock;
1110 
1111     ierr = PetscMalloc(sizeof(PC_BJacobi_Multiblock),&bjac);CHKERRQ(ierr);
1112     ierr = PetscLogObjectMemory(pc,sizeof(PC_BJacobi_Multiblock));CHKERRQ(ierr);
1113     ierr = PetscMalloc(n_local*sizeof(KSP),&jac->ksp);CHKERRQ(ierr);
1114     ierr = PetscLogObjectMemory(pc,sizeof(n_local*sizeof(KSP)));CHKERRQ(ierr);
1115     ierr = PetscMalloc(2*n_local*sizeof(Vec),&bjac->x);CHKERRQ(ierr);
1116     ierr = PetscLogObjectMemory(pc,sizeof(2*n_local*sizeof(Vec)));CHKERRQ(ierr);
1117     bjac->y      = bjac->x + n_local;
1118     ierr = PetscMalloc(n_local*sizeof(PetscScalar),&bjac->starts);CHKERRQ(ierr);
1119     ierr = PetscLogObjectMemory(pc,sizeof(n_local*sizeof(PetscScalar)));CHKERRQ(ierr);
1120 
1121     jac->data    = (void*)bjac;
1122     ierr = PetscMalloc(n_local*sizeof(IS),&bjac->is);CHKERRQ(ierr);
1123     ierr = PetscLogObjectMemory(pc,sizeof(n_local*sizeof(IS)));CHKERRQ(ierr);
1124 
1125     start = 0;
1126     for (i=0; i<n_local; i++) {
1127       ierr = KSPCreate(PETSC_COMM_SELF,&ksp);CHKERRQ(ierr);
1128       ierr = PetscLogObjectParent(pc,ksp);CHKERRQ(ierr);
1129       ierr = KSPSetType(ksp,KSPPREONLY);CHKERRQ(ierr);
1130       ierr = KSPGetPC(ksp,&subpc);CHKERRQ(ierr);
1131       ierr = PCGetOptionsPrefix(pc,&prefix);CHKERRQ(ierr);
1132       ierr = KSPSetOptionsPrefix(ksp,prefix);CHKERRQ(ierr);
1133       ierr = KSPAppendOptionsPrefix(ksp,"sub_");CHKERRQ(ierr);
1134 
1135       m = jac->l_lens[i];
1136 
1137       /*
1138       The reason we need to generate these vectors is to serve
1139       as the right-hand side and solution vector for the solve on the
1140       block. We do not need to allocate space for the vectors since
1141       that is provided via VecPlaceArray() just before the call to
1142       KSPSolve() on the block.
1143 
1144       */
1145       ierr = VecCreateSeq(PETSC_COMM_SELF,m,&x);CHKERRQ(ierr);
1146       ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,m,PETSC_NULL,&y);CHKERRQ(ierr);
1147       ierr = PetscLogObjectParent(pc,x);CHKERRQ(ierr);
1148       ierr = PetscLogObjectParent(pc,y);CHKERRQ(ierr);
1149       bjac->x[i]      = x;
1150       bjac->y[i]      = y;
1151       bjac->starts[i] = start;
1152       jac->ksp[i]    = ksp;
1153 
1154       ierr = ISCreateStride(PETSC_COMM_SELF,m,start,1,&is);CHKERRQ(ierr);
1155       bjac->is[i] = is;
1156       ierr = PetscLogObjectParent(pc,is);CHKERRQ(ierr);
1157 
1158       start += m;
1159     }
1160   } else {
1161     bjac = (PC_BJacobi_Multiblock*)jac->data;
1162     /*
1163        Destroy the blocks from the previous iteration
1164     */
1165     if (pc->flag == DIFFERENT_NONZERO_PATTERN) {
1166       ierr = MatDestroyMatrices(n_local,&bjac->pmat);CHKERRQ(ierr);
1167       if (jac->use_true_local) {
1168         ierr = MatDestroyMatrices(n_local,&bjac->mat);CHKERRQ(ierr);
1169       }
1170       scall = MAT_INITIAL_MATRIX;
1171     }
1172   }
1173 
1174   ierr = MatGetSubMatrices(pmat,n_local,bjac->is,bjac->is,scall,&bjac->pmat);CHKERRQ(ierr);
1175   if (jac->use_true_local) {
1176     ierr = PetscObjectGetOptionsPrefix((PetscObject)mat,&mprefix);CHKERRQ(ierr);
1177     ierr = MatGetSubMatrices(mat,n_local,bjac->is,bjac->is,scall,&bjac->mat);CHKERRQ(ierr);
1178   }
1179   /* Return control to the user so that the submatrices can be modified (e.g., to apply
1180      different boundary conditions for the submatrices than for the global problem) */
1181   ierr = PCModifySubMatrices(pc,n_local,bjac->is,bjac->is,bjac->pmat,pc->modifysubmatricesP);CHKERRQ(ierr);
1182 
1183   ierr = PetscObjectGetOptionsPrefix((PetscObject)pmat,&pprefix);CHKERRQ(ierr);
1184   for (i=0; i<n_local; i++) {
1185     ierr = PetscLogObjectParent(pc,bjac->pmat[i]);CHKERRQ(ierr);
1186     ierr = PetscObjectSetOptionsPrefix((PetscObject)bjac->pmat[i],pprefix);CHKERRQ(ierr);
1187     if (jac->use_true_local) {
1188       ierr = PetscLogObjectParent(pc,bjac->mat[i]);CHKERRQ(ierr);
1189       ierr = PetscObjectSetOptionsPrefix((PetscObject)bjac->mat[i],mprefix);CHKERRQ(ierr);
1190       ierr = KSPSetOperators(jac->ksp[i],bjac->mat[i],bjac->pmat[i],pc->flag);CHKERRQ(ierr);
1191     } else {
1192       ierr = KSPSetOperators(jac->ksp[i],bjac->pmat[i],bjac->pmat[i],pc->flag);CHKERRQ(ierr);
1193     }
1194     ierr = KSPSetFromOptions(jac->ksp[i]);CHKERRQ(ierr);
1195   }
1196 
1197   PetscFunctionReturn(0);
1198 }
1199 
1200 
1201 
1202 
1203 
1204 
1205 
1206 
1207 
1208 
1209