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