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