xref: /petsc/src/mat/interface/matrix.c (revision 2a80812038b9881e71d725c7f5a502aeff50e549)
1 
2 /*
3    This is where the abstract matrix operations are defined
4 */
5 
6 #include <petsc/private/matimpl.h>        /*I "petscmat.h" I*/
7 #include <petsc/private/vecimpl.h>
8 #include <petsc/private/isimpl.h>
9 
10 /* Logging support */
11 PetscClassId MAT_CLASSID;
12 PetscClassId MAT_COLORING_CLASSID;
13 PetscClassId MAT_FDCOLORING_CLASSID;
14 PetscClassId MAT_TRANSPOSECOLORING_CLASSID;
15 
16 PetscLogEvent MAT_Mult, MAT_Mults, MAT_MultConstrained, MAT_MultAdd, MAT_MultTranspose;
17 PetscLogEvent MAT_MultTransposeConstrained, MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve;
18 PetscLogEvent MAT_SolveTransposeAdd, MAT_SOR, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic;
19 PetscLogEvent MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor;
20 PetscLogEvent MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin;
21 PetscLogEvent MAT_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetRowIJ, MAT_GetSubMatrices, MAT_GetOrdering, MAT_RedundantMat, MAT_GetSeqNonzeroStructure;
22 PetscLogEvent MAT_IncreaseOverlap, MAT_Partitioning, MAT_Coarsen, MAT_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate;
23 PetscLogEvent MAT_FDColoringSetUp, MAT_FDColoringApply,MAT_Transpose,MAT_FDColoringFunction, MAT_GetSubMatrix;
24 PetscLogEvent MAT_TransposeColoringCreate;
25 PetscLogEvent MAT_MatMult, MAT_MatMultSymbolic, MAT_MatMultNumeric;
26 PetscLogEvent MAT_PtAP, MAT_PtAPSymbolic, MAT_PtAPNumeric,MAT_RARt, MAT_RARtSymbolic, MAT_RARtNumeric;
27 PetscLogEvent MAT_MatTransposeMult, MAT_MatTransposeMultSymbolic, MAT_MatTransposeMultNumeric;
28 PetscLogEvent MAT_TransposeMatMult, MAT_TransposeMatMultSymbolic, MAT_TransposeMatMultNumeric;
29 PetscLogEvent MAT_MatMatMult, MAT_MatMatMultSymbolic, MAT_MatMatMultNumeric;
30 PetscLogEvent MAT_MultHermitianTranspose,MAT_MultHermitianTransposeAdd;
31 PetscLogEvent MAT_Getsymtranspose, MAT_Getsymtransreduced, MAT_Transpose_SeqAIJ, MAT_GetBrowsOfAcols;
32 PetscLogEvent MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym;
33 PetscLogEvent MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure;
34 PetscLogEvent MAT_GetMultiProcBlock;
35 PetscLogEvent MAT_CUSPCopyToGPU, MAT_CUSPARSECopyToGPU, MAT_SetValuesBatch, MAT_SetValuesBatchI, MAT_SetValuesBatchII, MAT_SetValuesBatchIII, MAT_SetValuesBatchIV;
36 PetscLogEvent MAT_ViennaCLCopyToGPU;
37 PetscLogEvent MAT_Merge,MAT_Residual;
38 PetscLogEvent Mat_Coloring_Apply,Mat_Coloring_Comm,Mat_Coloring_Local,Mat_Coloring_ISCreate,Mat_Coloring_SetUp,Mat_Coloring_Weights;
39 
40 const char *const MatFactorTypes[] = {"NONE","LU","CHOLESKY","ILU","ICC","ILUDT","MatFactorType","MAT_FACTOR_",0};
41 
42 #undef __FUNCT__
43 #define __FUNCT__ "MatSetRandom"
44 /*@
45    MatSetRandom - Sets all components of a matrix to random numbers. For sparse matrices that have been preallocated it randomly selects appropriate locations
46 
47    Logically Collective on Vec
48 
49    Input Parameters:
50 +  x  - the vector
51 -  rctx - the random number context, formed by PetscRandomCreate(), or NULL and
52           it will create one internally.
53 
54    Output Parameter:
55 .  x  - the vector
56 
57    Example of Usage:
58 .vb
59      PetscRandomCreate(PETSC_COMM_WORLD,&rctx);
60      VecSetRandom(x,rctx);
61      PetscRandomDestroy(rctx);
62 .ve
63 
64    Level: intermediate
65 
66    Concepts: vector^setting to random
67    Concepts: random^vector
68 
69 .seealso: MatZeroEntries(), MatSetValues(), PetscRandomCreate(), PetscRandomDestroy()
70 @*/
71 PetscErrorCode MatSetRandom(Mat x,PetscRandom rctx)
72 {
73   PetscErrorCode ierr;
74   PetscRandom    randObj = NULL;
75 
76   PetscFunctionBegin;
77   PetscValidHeaderSpecific(x,MAT_CLASSID,1);
78   if (rctx) PetscValidHeaderSpecific(rctx,PETSC_RANDOM_CLASSID,2);
79   PetscValidType(x,1);
80 
81   if (!rctx) {
82     MPI_Comm comm;
83     ierr = PetscObjectGetComm((PetscObject)x,&comm);CHKERRQ(ierr);
84     ierr = PetscRandomCreate(comm,&randObj);CHKERRQ(ierr);
85     ierr = PetscRandomSetFromOptions(randObj);CHKERRQ(ierr);
86     rctx = randObj;
87   }
88 
89   ierr = PetscLogEventBegin(VEC_SetRandom,x,rctx,0,0);CHKERRQ(ierr);
90   ierr = (*x->ops->setrandom)(x,rctx);CHKERRQ(ierr);
91   ierr = PetscLogEventEnd(VEC_SetRandom,x,rctx,0,0);CHKERRQ(ierr);
92 
93   x->assembled = PETSC_TRUE;
94   ierr         = PetscRandomDestroy(&randObj);CHKERRQ(ierr);
95   PetscFunctionReturn(0);
96 }
97 
98 
99 #undef __FUNCT__
100 #define __FUNCT__ "MatFindNonzeroRows"
101 /*@
102       MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix
103 
104   Input Parameter:
105 .    A  - the matrix
106 
107   Output Parameter:
108 .    keptrows - the rows that are not completely zero
109 
110   Level: intermediate
111 
112  @*/
113 PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows)
114 {
115   PetscErrorCode ierr;
116 
117   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
118   PetscValidType(mat,1);
119   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
120   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
121   if (!mat->ops->findnonzerorows) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not coded for this matrix type");
122   ierr = (*mat->ops->findnonzerorows)(mat,keptrows);CHKERRQ(ierr);
123   PetscFunctionReturn(0);
124 }
125 
126 #undef __FUNCT__
127 #define __FUNCT__ "MatGetDiagonalBlock"
128 /*@
129    MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling
130 
131    Not Collective
132 
133    Input Parameters:
134 .   A - the matrix
135 
136    Output Parameters:
137 .   a - the diagonal part (which is a SEQUENTIAL matrix)
138 
139    Notes: see the manual page for MatCreateAIJ() for more information on the "diagonal part" of the matrix.
140           Use caution, as the reference count on the returned matrix is not incremented and it is used as
141 	  part of the containing MPI Mat's normal operation.
142 
143    Level: advanced
144 
145 @*/
146 PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a)
147 {
148   PetscErrorCode ierr,(*f)(Mat,Mat*);
149   PetscMPIInt    size;
150 
151   PetscFunctionBegin;
152   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
153   PetscValidType(A,1);
154   PetscValidPointer(a,3);
155   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
156   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);CHKERRQ(ierr);
157   ierr = PetscObjectQueryFunction((PetscObject)A,"MatGetDiagonalBlock_C",&f);CHKERRQ(ierr);
158   if (f) {
159     ierr = (*f)(A,a);CHKERRQ(ierr);
160     PetscFunctionReturn(0);
161   } else if (size == 1) {
162     *a = A;
163   } else {
164     MatType mattype;
165     ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
166     SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix type %s does not support getting diagonal block",mattype);
167   }
168   PetscFunctionReturn(0);
169 }
170 
171 #undef __FUNCT__
172 #define __FUNCT__ "MatGetTrace"
173 /*@
174    MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries.
175 
176    Collective on Mat
177 
178    Input Parameters:
179 .  mat - the matrix
180 
181    Output Parameter:
182 .   trace - the sum of the diagonal entries
183 
184    Level: advanced
185 
186 @*/
187 PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace)
188 {
189   PetscErrorCode ierr;
190   Vec            diag;
191 
192   PetscFunctionBegin;
193   ierr = MatCreateVecs(mat,&diag,NULL);CHKERRQ(ierr);
194   ierr = MatGetDiagonal(mat,diag);CHKERRQ(ierr);
195   ierr = VecSum(diag,trace);CHKERRQ(ierr);
196   ierr = VecDestroy(&diag);CHKERRQ(ierr);
197   PetscFunctionReturn(0);
198 }
199 
200 #undef __FUNCT__
201 #define __FUNCT__ "MatRealPart"
202 /*@
203    MatRealPart - Zeros out the imaginary part of the matrix
204 
205    Logically Collective on Mat
206 
207    Input Parameters:
208 .  mat - the matrix
209 
210    Level: advanced
211 
212 
213 .seealso: MatImaginaryPart()
214 @*/
215 PetscErrorCode MatRealPart(Mat mat)
216 {
217   PetscErrorCode ierr;
218 
219   PetscFunctionBegin;
220   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
221   PetscValidType(mat,1);
222   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
223   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
224   if (!mat->ops->realpart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
225   MatCheckPreallocated(mat,1);
226   ierr = (*mat->ops->realpart)(mat);CHKERRQ(ierr);
227 #if defined(PETSC_HAVE_CUSP)
228   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
229     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
230   }
231 #elif defined(PETSC_HAVE_VIENNACL)
232   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
233     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
234   }
235 #elif defined(PETSC_HAVE_VECCUDA)
236   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
237     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
238   }
239 #endif
240   PetscFunctionReturn(0);
241 }
242 
243 #undef __FUNCT__
244 #define __FUNCT__ "MatGetGhosts"
245 /*@C
246    MatGetGhosts - Get the global index of all ghost nodes defined by the sparse matrix
247 
248    Collective on Mat
249 
250    Input Parameter:
251 .  mat - the matrix
252 
253    Output Parameters:
254 +   nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block)
255 -   ghosts - the global indices of the ghost points
256 
257    Notes: the nghosts and ghosts are suitable to pass into VecCreateGhost()
258 
259    Level: advanced
260 
261 @*/
262 PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[])
263 {
264   PetscErrorCode ierr;
265 
266   PetscFunctionBegin;
267   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
268   PetscValidType(mat,1);
269   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
270   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
271   if (!mat->ops->getghosts) {
272     if (nghosts) *nghosts = 0;
273     if (ghosts) *ghosts = 0;
274   } else {
275     ierr = (*mat->ops->getghosts)(mat,nghosts,ghosts);CHKERRQ(ierr);
276   }
277   PetscFunctionReturn(0);
278 }
279 
280 
281 #undef __FUNCT__
282 #define __FUNCT__ "MatImaginaryPart"
283 /*@
284    MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part
285 
286    Logically Collective on Mat
287 
288    Input Parameters:
289 .  mat - the matrix
290 
291    Level: advanced
292 
293 
294 .seealso: MatRealPart()
295 @*/
296 PetscErrorCode MatImaginaryPart(Mat mat)
297 {
298   PetscErrorCode ierr;
299 
300   PetscFunctionBegin;
301   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
302   PetscValidType(mat,1);
303   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
304   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
305   if (!mat->ops->imaginarypart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
306   MatCheckPreallocated(mat,1);
307   ierr = (*mat->ops->imaginarypart)(mat);CHKERRQ(ierr);
308 #if defined(PETSC_HAVE_CUSP)
309   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
310     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
311   }
312 #elif defined(PETSC_HAVE_VIENNACL)
313   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
314     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
315   }
316 #elif defined(PETSC_HAVE_VECCUDA)
317   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
318     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
319   }
320 #endif
321   PetscFunctionReturn(0);
322 }
323 
324 #undef __FUNCT__
325 #define __FUNCT__ "MatMissingDiagonal"
326 /*@
327    MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices)
328 
329    Collective on Mat
330 
331    Input Parameter:
332 .  mat - the matrix
333 
334    Output Parameters:
335 +  missing - is any diagonal missing
336 -  dd - first diagonal entry that is missing (optional)
337 
338    Level: advanced
339 
340 
341 .seealso: MatRealPart()
342 @*/
343 PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd)
344 {
345   PetscErrorCode ierr;
346 
347   PetscFunctionBegin;
348   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
349   PetscValidType(mat,1);
350   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
351   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
352   if (!mat->ops->missingdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
353   ierr = (*mat->ops->missingdiagonal)(mat,missing,dd);CHKERRQ(ierr);
354   PetscFunctionReturn(0);
355 }
356 
357 #undef __FUNCT__
358 #define __FUNCT__ "MatGetRow"
359 /*@C
360    MatGetRow - Gets a row of a matrix.  You MUST call MatRestoreRow()
361    for each row that you get to ensure that your application does
362    not bleed memory.
363 
364    Not Collective
365 
366    Input Parameters:
367 +  mat - the matrix
368 -  row - the row to get
369 
370    Output Parameters:
371 +  ncols -  if not NULL, the number of nonzeros in the row
372 .  cols - if not NULL, the column numbers
373 -  vals - if not NULL, the values
374 
375    Notes:
376    This routine is provided for people who need to have direct access
377    to the structure of a matrix.  We hope that we provide enough
378    high-level matrix routines that few users will need it.
379 
380    MatGetRow() always returns 0-based column indices, regardless of
381    whether the internal representation is 0-based (default) or 1-based.
382 
383    For better efficiency, set cols and/or vals to NULL if you do
384    not wish to extract these quantities.
385 
386    The user can only examine the values extracted with MatGetRow();
387    the values cannot be altered.  To change the matrix entries, one
388    must use MatSetValues().
389 
390    You can only have one call to MatGetRow() outstanding for a particular
391    matrix at a time, per processor. MatGetRow() can only obtain rows
392    associated with the given processor, it cannot get rows from the
393    other processors; for that we suggest using MatGetSubMatrices(), then
394    MatGetRow() on the submatrix. The row indix passed to MatGetRows()
395    is in the global number of rows.
396 
397    Fortran Notes:
398    The calling sequence from Fortran is
399 .vb
400    MatGetRow(matrix,row,ncols,cols,values,ierr)
401          Mat     matrix (input)
402          integer row    (input)
403          integer ncols  (output)
404          integer cols(maxcols) (output)
405          double precision (or double complex) values(maxcols) output
406 .ve
407    where maxcols >= maximum nonzeros in any row of the matrix.
408 
409 
410    Caution:
411    Do not try to change the contents of the output arrays (cols and vals).
412    In some cases, this may corrupt the matrix.
413 
414    Level: advanced
415 
416    Concepts: matrices^row access
417 
418 .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatGetSubMatrices(), MatGetDiagonal()
419 @*/
420 PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
421 {
422   PetscErrorCode ierr;
423   PetscInt       incols;
424 
425   PetscFunctionBegin;
426   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
427   PetscValidType(mat,1);
428   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
429   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
430   if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
431   MatCheckPreallocated(mat,1);
432   ierr = PetscLogEventBegin(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr);
433   ierr = (*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals);CHKERRQ(ierr);
434   if (ncols) *ncols = incols;
435   ierr = PetscLogEventEnd(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr);
436   PetscFunctionReturn(0);
437 }
438 
439 #undef __FUNCT__
440 #define __FUNCT__ "MatConjugate"
441 /*@
442    MatConjugate - replaces the matrix values with their complex conjugates
443 
444    Logically Collective on Mat
445 
446    Input Parameters:
447 .  mat - the matrix
448 
449    Level: advanced
450 
451 .seealso:  VecConjugate()
452 @*/
453 PetscErrorCode MatConjugate(Mat mat)
454 {
455 #if defined(PETSC_USE_COMPLEX)
456   PetscErrorCode ierr;
457 
458   PetscFunctionBegin;
459   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
460   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
461   if (!mat->ops->conjugate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not provided for this matrix format, send email to petsc-maint@mcs.anl.gov");
462   ierr = (*mat->ops->conjugate)(mat);CHKERRQ(ierr);
463 #if defined(PETSC_HAVE_CUSP)
464   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
465     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
466   }
467 #elif defined(PETSC_HAVE_VIENNACL)
468   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
469     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
470   }
471 #elif defined(PETSC_HAVE_VECCUDA)
472   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
473     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
474   }
475 #endif
476   PetscFunctionReturn(0);
477 #else
478   return 0;
479 #endif
480 }
481 
482 #undef __FUNCT__
483 #define __FUNCT__ "MatRestoreRow"
484 /*@C
485    MatRestoreRow - Frees any temporary space allocated by MatGetRow().
486 
487    Not Collective
488 
489    Input Parameters:
490 +  mat - the matrix
491 .  row - the row to get
492 .  ncols, cols - the number of nonzeros and their columns
493 -  vals - if nonzero the column values
494 
495    Notes:
496    This routine should be called after you have finished examining the entries.
497 
498    This routine zeros out ncols, cols, and vals. This is to prevent accidental
499    us of the array after it has been restored. If you pass NULL, it will
500    not zero the pointers.  Use of cols or vals after MatRestoreRow is invalid.
501 
502    Fortran Notes:
503    The calling sequence from Fortran is
504 .vb
505    MatRestoreRow(matrix,row,ncols,cols,values,ierr)
506       Mat     matrix (input)
507       integer row    (input)
508       integer ncols  (output)
509       integer cols(maxcols) (output)
510       double precision (or double complex) values(maxcols) output
511 .ve
512    Where maxcols >= maximum nonzeros in any row of the matrix.
513 
514    In Fortran MatRestoreRow() MUST be called after MatGetRow()
515    before another call to MatGetRow() can be made.
516 
517    Level: advanced
518 
519 .seealso:  MatGetRow()
520 @*/
521 PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
522 {
523   PetscErrorCode ierr;
524 
525   PetscFunctionBegin;
526   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
527   if (ncols) PetscValidIntPointer(ncols,3);
528   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
529   if (!mat->ops->restorerow) PetscFunctionReturn(0);
530   ierr = (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);CHKERRQ(ierr);
531   if (ncols) *ncols = 0;
532   if (cols)  *cols = NULL;
533   if (vals)  *vals = NULL;
534   PetscFunctionReturn(0);
535 }
536 
537 #undef __FUNCT__
538 #define __FUNCT__ "MatGetRowUpperTriangular"
539 /*@
540    MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format.
541    You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag.
542 
543    Not Collective
544 
545    Input Parameters:
546 +  mat - the matrix
547 
548    Notes:
549    The flag is to ensure that users are aware of MatGetRow() only provides the upper trianglular part of the row for the matrices in MATSBAIJ format.
550 
551    Level: advanced
552 
553    Concepts: matrices^row access
554 
555 .seealso: MatRestoreRowRowUpperTriangular()
556 @*/
557 PetscErrorCode MatGetRowUpperTriangular(Mat mat)
558 {
559   PetscErrorCode ierr;
560 
561   PetscFunctionBegin;
562   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
563   PetscValidType(mat,1);
564   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
565   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
566   if (!mat->ops->getrowuppertriangular) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
567   MatCheckPreallocated(mat,1);
568   ierr = (*mat->ops->getrowuppertriangular)(mat);CHKERRQ(ierr);
569   PetscFunctionReturn(0);
570 }
571 
572 #undef __FUNCT__
573 #define __FUNCT__ "MatRestoreRowUpperTriangular"
574 /*@
575    MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format.
576 
577    Not Collective
578 
579    Input Parameters:
580 +  mat - the matrix
581 
582    Notes:
583    This routine should be called after you have finished MatGetRow/MatRestoreRow().
584 
585 
586    Level: advanced
587 
588 .seealso:  MatGetRowUpperTriangular()
589 @*/
590 PetscErrorCode MatRestoreRowUpperTriangular(Mat mat)
591 {
592   PetscErrorCode ierr;
593 
594   PetscFunctionBegin;
595   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
596   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
597   if (!mat->ops->restorerowuppertriangular) PetscFunctionReturn(0);
598   ierr = (*mat->ops->restorerowuppertriangular)(mat);CHKERRQ(ierr);
599   PetscFunctionReturn(0);
600 }
601 
602 #undef __FUNCT__
603 #define __FUNCT__ "MatSetOptionsPrefix"
604 /*@C
605    MatSetOptionsPrefix - Sets the prefix used for searching for all
606    Mat options in the database.
607 
608    Logically Collective on Mat
609 
610    Input Parameter:
611 +  A - the Mat context
612 -  prefix - the prefix to prepend to all option names
613 
614    Notes:
615    A hyphen (-) must NOT be given at the beginning of the prefix name.
616    The first character of all runtime options is AUTOMATICALLY the hyphen.
617 
618    Level: advanced
619 
620 .keywords: Mat, set, options, prefix, database
621 
622 .seealso: MatSetFromOptions()
623 @*/
624 PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[])
625 {
626   PetscErrorCode ierr;
627 
628   PetscFunctionBegin;
629   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
630   ierr = PetscObjectSetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
631   PetscFunctionReturn(0);
632 }
633 
634 #undef __FUNCT__
635 #define __FUNCT__ "MatAppendOptionsPrefix"
636 /*@C
637    MatAppendOptionsPrefix - Appends to the prefix used for searching for all
638    Mat options in the database.
639 
640    Logically Collective on Mat
641 
642    Input Parameters:
643 +  A - the Mat context
644 -  prefix - the prefix to prepend to all option names
645 
646    Notes:
647    A hyphen (-) must NOT be given at the beginning of the prefix name.
648    The first character of all runtime options is AUTOMATICALLY the hyphen.
649 
650    Level: advanced
651 
652 .keywords: Mat, append, options, prefix, database
653 
654 .seealso: MatGetOptionsPrefix()
655 @*/
656 PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[])
657 {
658   PetscErrorCode ierr;
659 
660   PetscFunctionBegin;
661   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
662   ierr = PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
663   PetscFunctionReturn(0);
664 }
665 
666 #undef __FUNCT__
667 #define __FUNCT__ "MatGetOptionsPrefix"
668 /*@C
669    MatGetOptionsPrefix - Sets the prefix used for searching for all
670    Mat options in the database.
671 
672    Not Collective
673 
674    Input Parameter:
675 .  A - the Mat context
676 
677    Output Parameter:
678 .  prefix - pointer to the prefix string used
679 
680    Notes: On the fortran side, the user should pass in a string 'prefix' of
681    sufficient length to hold the prefix.
682 
683    Level: advanced
684 
685 .keywords: Mat, get, options, prefix, database
686 
687 .seealso: MatAppendOptionsPrefix()
688 @*/
689 PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[])
690 {
691   PetscErrorCode ierr;
692 
693   PetscFunctionBegin;
694   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
695   ierr = PetscObjectGetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
696   PetscFunctionReturn(0);
697 }
698 
699 #undef __FUNCT__
700 #define __FUNCT__ "MatSetUp"
701 /*@
702    MatSetUp - Sets up the internal matrix data structures for the later use.
703 
704    Collective on Mat
705 
706    Input Parameters:
707 .  A - the Mat context
708 
709    Notes:
710    If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used.
711 
712    If a suitable preallocation routine is used, this function does not need to be called.
713 
714    See the Performance chapter of the PETSc users manual for how to preallocate matrices
715 
716    Level: beginner
717 
718 .keywords: Mat, setup
719 
720 .seealso: MatCreate(), MatDestroy()
721 @*/
722 PetscErrorCode MatSetUp(Mat A)
723 {
724   PetscMPIInt    size;
725   PetscErrorCode ierr;
726 
727   PetscFunctionBegin;
728   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
729   if (!((PetscObject)A)->type_name) {
730     ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A), &size);CHKERRQ(ierr);
731     if (size == 1) {
732       ierr = MatSetType(A, MATSEQAIJ);CHKERRQ(ierr);
733     } else {
734       ierr = MatSetType(A, MATMPIAIJ);CHKERRQ(ierr);
735     }
736   }
737   if (!A->preallocated && A->ops->setup) {
738     ierr = PetscInfo(A,"Warning not preallocating matrix storage\n");CHKERRQ(ierr);
739     ierr = (*A->ops->setup)(A);CHKERRQ(ierr);
740   }
741   A->preallocated = PETSC_TRUE;
742   PetscFunctionReturn(0);
743 }
744 
745 #if defined(PETSC_HAVE_SAWS)
746 #include <petscviewersaws.h>
747 #endif
748 #undef __FUNCT__
749 #define __FUNCT__ "MatView"
750 /*@C
751    MatView - Visualizes a matrix object.
752 
753    Collective on Mat
754 
755    Input Parameters:
756 +  mat - the matrix
757 -  viewer - visualization context
758 
759   Notes:
760   The available visualization contexts include
761 +    PETSC_VIEWER_STDOUT_SELF - for sequential matrices
762 .    PETSC_VIEWER_STDOUT_WORLD - for parallel matrices created on PETSC_COMM_WORLD
763 .    PETSC_VIEWER_STDOUT_(comm) - for matrices created on MPI communicator comm
764 -     PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure
765 
766    The user can open alternative visualization contexts with
767 +    PetscViewerASCIIOpen() - Outputs matrix to a specified file
768 .    PetscViewerBinaryOpen() - Outputs matrix in binary to a
769          specified file; corresponding input uses MatLoad()
770 .    PetscViewerDrawOpen() - Outputs nonzero matrix structure to
771          an X window display
772 -    PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
773          Currently only the sequential dense and AIJ
774          matrix types support the Socket viewer.
775 
776    The user can call PetscViewerPushFormat() to specify the output
777    format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
778    PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen).  Available formats include
779 +    PETSC_VIEWER_DEFAULT - default, prints matrix contents
780 .    PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
781 .    PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
782 .    PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse
783          format common among all matrix types
784 .    PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific
785          format (which is in many cases the same as the default)
786 .    PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
787          size and structure (not the matrix entries)
788 .    PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about
789          the matrix structure
790 
791    Options Database Keys:
792 +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
793 .  -mat_view ::ascii_info_detail - Prints more detailed info
794 .  -mat_view - Prints matrix in ASCII format
795 .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
796 .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
797 .  -display <name> - Sets display name (default is host)
798 .  -draw_pause <sec> - Sets number of seconds to pause after display
799 .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: ch_matlab for details)
800 .  -viewer_socket_machine <machine> -
801 .  -viewer_socket_port <port> -
802 .  -mat_view binary - save matrix to file in binary format
803 -  -viewer_binary_filename <name> -
804    Level: beginner
805 
806    Notes: see the manual page for MatLoad() for the exact format of the binary file when the binary
807       viewer is used.
808 
809       See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary
810       viewer is used.
811 
812       One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure.
813       And then use the following mouse functions:
814           left mouse: zoom in
815           middle mouse: zoom out
816           right mouse: continue with the simulation
817 
818    Concepts: matrices^viewing
819    Concepts: matrices^plotting
820    Concepts: matrices^printing
821 
822 .seealso: PetscViewerPushFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(),
823           PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
824 @*/
825 PetscErrorCode MatView(Mat mat,PetscViewer viewer)
826 {
827   PetscErrorCode    ierr;
828   PetscInt          rows,cols,rbs,cbs;
829   PetscBool         iascii,ibinary;
830   PetscViewerFormat format;
831 #if defined(PETSC_HAVE_SAWS)
832   PetscBool         issaws;
833 #endif
834 
835   PetscFunctionBegin;
836   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
837   PetscValidType(mat,1);
838   if (!viewer) {
839     ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);CHKERRQ(ierr);
840   }
841   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
842   PetscCheckSameComm(mat,1,viewer,2);
843   MatCheckPreallocated(mat,1);
844   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr);
845   if (ibinary) {
846     PetscBool mpiio;
847     ierr = PetscViewerBinaryGetUseMPIIO(viewer,&mpiio);CHKERRQ(ierr);
848     if (mpiio) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"PETSc matrix viewers do not support using MPI-IO, turn off that flag");
849   }
850 
851   ierr = PetscLogEventBegin(MAT_View,mat,viewer,0,0);CHKERRQ(ierr);
852   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
853   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
854   if ((!iascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) {
855     SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detailed");
856   }
857 
858 #if defined(PETSC_HAVE_SAWS)
859   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr);
860 #endif
861   if (iascii) {
862     if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
863     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer);CHKERRQ(ierr);
864     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
865       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
866       ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr);
867       ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr);
868       if (rbs != 1 || cbs != 1) {
869         if (rbs != cbs) {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, rbs=%D, cbs = %D\n",rows,cols,rbs,cbs);CHKERRQ(ierr);}
870         else            {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,rbs);CHKERRQ(ierr);}
871       } else {
872         ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);CHKERRQ(ierr);
873       }
874       if (mat->factortype) {
875         const MatSolverPackage solver;
876         ierr = MatFactorGetSolverPackage(mat,&solver);CHKERRQ(ierr);
877         ierr = PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);CHKERRQ(ierr);
878       }
879       if (mat->ops->getinfo) {
880         MatInfo info;
881         ierr = MatGetInfo(mat,MAT_GLOBAL_SUM,&info);CHKERRQ(ierr);
882         ierr = PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated);CHKERRQ(ierr);
883         ierr = PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls =%D\n",(PetscInt)info.mallocs);CHKERRQ(ierr);
884       }
885       if (mat->nullsp) {ierr = PetscViewerASCIIPrintf(viewer,"  has attached null space\n");CHKERRQ(ierr);}
886       if (mat->nearnullsp) {ierr = PetscViewerASCIIPrintf(viewer,"  has attached near null space\n");CHKERRQ(ierr);}
887     }
888 #if defined(PETSC_HAVE_SAWS)
889   } else if (issaws) {
890     PetscMPIInt rank;
891 
892     ierr = PetscObjectName((PetscObject)mat);CHKERRQ(ierr);
893     ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
894     if (!((PetscObject)mat)->amsmem && !rank) {
895       ierr = PetscObjectViewSAWs((PetscObject)mat,viewer);CHKERRQ(ierr);
896     }
897 #endif
898   }
899   if (mat->ops->view) {
900     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
901     ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr);
902     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
903   }
904   if (iascii) {
905     if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
906     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
907     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
908       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
909     }
910   }
911   ierr = PetscLogEventEnd(MAT_View,mat,viewer,0,0);CHKERRQ(ierr);
912   PetscFunctionReturn(0);
913 }
914 
915 #if defined(PETSC_USE_DEBUG)
916 #include <../src/sys/totalview/tv_data_display.h>
917 PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat)
918 {
919   TV_add_row("Local rows", "int", &mat->rmap->n);
920   TV_add_row("Local columns", "int", &mat->cmap->n);
921   TV_add_row("Global rows", "int", &mat->rmap->N);
922   TV_add_row("Global columns", "int", &mat->cmap->N);
923   TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name);
924   return TV_format_OK;
925 }
926 #endif
927 
928 #undef __FUNCT__
929 #define __FUNCT__ "MatLoad"
930 /*@C
931    MatLoad - Loads a matrix that has been stored in binary format
932    with MatView().  The matrix format is determined from the options database.
933    Generates a parallel MPI matrix if the communicator has more than one
934    processor.  The default matrix type is AIJ.
935 
936    Collective on PetscViewer
937 
938    Input Parameters:
939 +  newmat - the newly loaded matrix, this needs to have been created with MatCreate()
940             or some related function before a call to MatLoad()
941 -  viewer - binary file viewer, created with PetscViewerBinaryOpen()
942 
943    Options Database Keys:
944    Used with block matrix formats (MATSEQBAIJ,  ...) to specify
945    block size
946 .    -matload_block_size <bs>
947 
948    Level: beginner
949 
950    Notes:
951    If the Mat type has not yet been given then MATAIJ is used, call MatSetFromOptions() on the
952    Mat before calling this routine if you wish to set it from the options database.
953 
954    MatLoad() automatically loads into the options database any options
955    given in the file filename.info where filename is the name of the file
956    that was passed to the PetscViewerBinaryOpen(). The options in the info
957    file will be ignored if you use the -viewer_binary_skip_info option.
958 
959    If the type or size of newmat is not set before a call to MatLoad, PETSc
960    sets the default matrix type AIJ and sets the local and global sizes.
961    If type and/or size is already set, then the same are used.
962 
963    In parallel, each processor can load a subset of rows (or the
964    entire matrix).  This routine is especially useful when a large
965    matrix is stored on disk and only part of it is desired on each
966    processor.  For example, a parallel solver may access only some of
967    the rows from each processor.  The algorithm used here reads
968    relatively small blocks of data rather than reading the entire
969    matrix and then subsetting it.
970 
971    Notes for advanced users:
972    Most users should not need to know the details of the binary storage
973    format, since MatLoad() and MatView() completely hide these details.
974    But for anyone who's interested, the standard binary matrix storage
975    format is
976 
977 $    int    MAT_FILE_CLASSID
978 $    int    number of rows
979 $    int    number of columns
980 $    int    total number of nonzeros
981 $    int    *number nonzeros in each row
982 $    int    *column indices of all nonzeros (starting index is zero)
983 $    PetscScalar *values of all nonzeros
984 
985    PETSc automatically does the byte swapping for
986 machines that store the bytes reversed, e.g.  DEC alpha, freebsd,
987 linux, Windows and the paragon; thus if you write your own binary
988 read/write routines you have to swap the bytes; see PetscBinaryRead()
989 and PetscBinaryWrite() to see how this may be done.
990 
991 .keywords: matrix, load, binary, input
992 
993 .seealso: PetscViewerBinaryOpen(), MatView(), VecLoad()
994 
995  @*/
996 PetscErrorCode MatLoad(Mat newmat,PetscViewer viewer)
997 {
998   PetscErrorCode ierr;
999   PetscBool      isbinary,flg;
1000 
1001   PetscFunctionBegin;
1002   PetscValidHeaderSpecific(newmat,MAT_CLASSID,1);
1003   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1004   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1005   if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()");
1006 
1007   if (!((PetscObject)newmat)->type_name) {
1008     ierr = MatSetType(newmat,MATAIJ);CHKERRQ(ierr);
1009   }
1010 
1011   if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type");
1012   ierr = PetscLogEventBegin(MAT_Load,viewer,0,0,0);CHKERRQ(ierr);
1013   ierr = (*newmat->ops->load)(newmat,viewer);CHKERRQ(ierr);
1014   ierr = PetscLogEventEnd(MAT_Load,viewer,0,0,0);CHKERRQ(ierr);
1015 
1016   flg  = PETSC_FALSE;
1017   ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,NULL);CHKERRQ(ierr);
1018   if (flg) {
1019     ierr = MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
1020     ierr = MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);CHKERRQ(ierr);
1021   }
1022   flg  = PETSC_FALSE;
1023   ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_spd",&flg,NULL);CHKERRQ(ierr);
1024   if (flg) {
1025     ierr = MatSetOption(newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr);
1026   }
1027   PetscFunctionReturn(0);
1028 }
1029 
1030 #undef __FUNCT__
1031 #define __FUNCT__ "MatDestroy_Redundant"
1032 PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant)
1033 {
1034   PetscErrorCode ierr;
1035   Mat_Redundant  *redund = *redundant;
1036   PetscInt       i;
1037 
1038   PetscFunctionBegin;
1039   if (redund){
1040     if (redund->matseq) { /* via MatGetSubMatrices()  */
1041       ierr = ISDestroy(&redund->isrow);CHKERRQ(ierr);
1042       ierr = ISDestroy(&redund->iscol);CHKERRQ(ierr);
1043       ierr = MatDestroy(&redund->matseq[0]);CHKERRQ(ierr);
1044       ierr = PetscFree(redund->matseq);CHKERRQ(ierr);
1045     } else {
1046       ierr = PetscFree2(redund->send_rank,redund->recv_rank);CHKERRQ(ierr);
1047       ierr = PetscFree(redund->sbuf_j);CHKERRQ(ierr);
1048       ierr = PetscFree(redund->sbuf_a);CHKERRQ(ierr);
1049       for (i=0; i<redund->nrecvs; i++) {
1050         ierr = PetscFree(redund->rbuf_j[i]);CHKERRQ(ierr);
1051         ierr = PetscFree(redund->rbuf_a[i]);CHKERRQ(ierr);
1052       }
1053       ierr = PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a);CHKERRQ(ierr);
1054     }
1055 
1056     if (redund->subcomm) {
1057       ierr = PetscCommDestroy(&redund->subcomm);CHKERRQ(ierr);
1058     }
1059     ierr = PetscFree(redund);CHKERRQ(ierr);
1060   }
1061   PetscFunctionReturn(0);
1062 }
1063 
1064 #undef __FUNCT__
1065 #define __FUNCT__ "MatDestroy"
1066 /*@
1067    MatDestroy - Frees space taken by a matrix.
1068 
1069    Collective on Mat
1070 
1071    Input Parameter:
1072 .  A - the matrix
1073 
1074    Level: beginner
1075 
1076 @*/
1077 PetscErrorCode MatDestroy(Mat *A)
1078 {
1079   PetscErrorCode ierr;
1080 
1081   PetscFunctionBegin;
1082   if (!*A) PetscFunctionReturn(0);
1083   PetscValidHeaderSpecific(*A,MAT_CLASSID,1);
1084   if (--((PetscObject)(*A))->refct > 0) {*A = NULL; PetscFunctionReturn(0);}
1085 
1086   /* if memory was published with SAWs then destroy it */
1087   ierr = PetscObjectSAWsViewOff((PetscObject)*A);CHKERRQ(ierr);
1088   if ((*A)->ops->destroy) {
1089     ierr = (*(*A)->ops->destroy)(*A);CHKERRQ(ierr);
1090   }
1091 
1092   ierr = PetscFree((*A)->solvertype);CHKERRQ(ierr);
1093   ierr = MatDestroy_Redundant(&(*A)->redundant);CHKERRQ(ierr);
1094   ierr = MatNullSpaceDestroy(&(*A)->nullsp);CHKERRQ(ierr);
1095   ierr = MatNullSpaceDestroy(&(*A)->transnullsp);CHKERRQ(ierr);
1096   ierr = MatNullSpaceDestroy(&(*A)->nearnullsp);CHKERRQ(ierr);
1097   ierr = PetscLayoutDestroy(&(*A)->rmap);CHKERRQ(ierr);
1098   ierr = PetscLayoutDestroy(&(*A)->cmap);CHKERRQ(ierr);
1099   ierr = PetscHeaderDestroy(A);CHKERRQ(ierr);
1100   PetscFunctionReturn(0);
1101 }
1102 
1103 #undef __FUNCT__
1104 #define __FUNCT__ "MatSetValues"
1105 /*@
1106    MatSetValues - Inserts or adds a block of values into a matrix.
1107    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1108    MUST be called after all calls to MatSetValues() have been completed.
1109 
1110    Not Collective
1111 
1112    Input Parameters:
1113 +  mat - the matrix
1114 .  v - a logically two-dimensional array of values
1115 .  m, idxm - the number of rows and their global indices
1116 .  n, idxn - the number of columns and their global indices
1117 -  addv - either ADD_VALUES or INSERT_VALUES, where
1118    ADD_VALUES adds values to any existing entries, and
1119    INSERT_VALUES replaces existing entries with new values
1120 
1121    Notes:
1122    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
1123       MatSetUp() before using this routine
1124 
1125    By default the values, v, are row-oriented. See MatSetOption() for other options.
1126 
1127    Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
1128    options cannot be mixed without intervening calls to the assembly
1129    routines.
1130 
1131    MatSetValues() uses 0-based row and column numbers in Fortran
1132    as well as in C.
1133 
1134    Negative indices may be passed in idxm and idxn, these rows and columns are
1135    simply ignored. This allows easily inserting element stiffness matrices
1136    with homogeneous Dirchlet boundary conditions that you don't want represented
1137    in the matrix.
1138 
1139    Efficiency Alert:
1140    The routine MatSetValuesBlocked() may offer much better efficiency
1141    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1142 
1143    Level: beginner
1144 
1145    Concepts: matrices^putting entries in
1146 
1147 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1148           InsertMode, INSERT_VALUES, ADD_VALUES
1149 @*/
1150 PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1151 {
1152   PetscErrorCode ierr;
1153 #if defined(PETSC_USE_DEBUG)
1154   PetscInt       i,j;
1155 #endif
1156 
1157   PetscFunctionBeginHot;
1158   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1159   PetscValidType(mat,1);
1160   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1161   PetscValidIntPointer(idxm,3);
1162   PetscValidIntPointer(idxn,5);
1163   PetscValidScalarPointer(v,6);
1164   MatCheckPreallocated(mat,1);
1165   if (mat->insertmode == NOT_SET_VALUES) {
1166     mat->insertmode = addv;
1167   }
1168 #if defined(PETSC_USE_DEBUG)
1169   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1170   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1171   if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1172 
1173   for (i=0; i<m; i++) {
1174     for (j=0; j<n; j++) {
1175       if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j]))
1176 #if defined(PETSC_USE_COMPLEX)
1177         SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g+ig at matrix entry (%D,%D)",(double)PetscRealPart(v[i*n+j]),(double)PetscImaginaryPart(v[i*n+j]),idxm[i],idxn[j]);
1178 #else
1179         SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%D,%D)",(double)v[i*n+j],idxm[i],idxn[j]);
1180 #endif
1181     }
1182   }
1183 #endif
1184 
1185   if (mat->assembled) {
1186     mat->was_assembled = PETSC_TRUE;
1187     mat->assembled     = PETSC_FALSE;
1188   }
1189   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1190   ierr = (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
1191   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1192 #if defined(PETSC_HAVE_CUSP)
1193   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1194     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1195   }
1196 #elif defined(PETSC_HAVE_VIENNACL)
1197   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1198     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1199   }
1200 #elif defined(PETSC_HAVE_VECCUDA)
1201   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1202     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1203   }
1204 #endif
1205   PetscFunctionReturn(0);
1206 }
1207 
1208 
1209 #undef __FUNCT__
1210 #define __FUNCT__ "MatSetValuesRowLocal"
1211 /*@
1212    MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
1213         values into a matrix
1214 
1215    Not Collective
1216 
1217    Input Parameters:
1218 +  mat - the matrix
1219 .  row - the (block) row to set
1220 -  v - a logically two-dimensional array of values
1221 
1222    Notes:
1223    By the values, v, are column-oriented (for the block version) and sorted
1224 
1225    All the nonzeros in the row must be provided
1226 
1227    The matrix must have previously had its column indices set
1228 
1229    The row must belong to this process
1230 
1231    Level: intermediate
1232 
1233    Concepts: matrices^putting entries in
1234 
1235 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1236           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping()
1237 @*/
1238 PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
1239 {
1240   PetscErrorCode ierr;
1241   PetscInt       globalrow;
1242 
1243   PetscFunctionBegin;
1244   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1245   PetscValidType(mat,1);
1246   PetscValidScalarPointer(v,2);
1247   ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);CHKERRQ(ierr);
1248   ierr = MatSetValuesRow(mat,globalrow,v);CHKERRQ(ierr);
1249 #if defined(PETSC_HAVE_CUSP)
1250   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1251     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1252   }
1253 #elif defined(PETSC_HAVE_VIENNACL)
1254   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1255     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1256   }
1257 #elif defined(PETSC_HAVE_VECCUDA)
1258   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1259     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1260   }
1261 #endif
1262   PetscFunctionReturn(0);
1263 }
1264 
1265 #undef __FUNCT__
1266 #define __FUNCT__ "MatSetValuesRow"
1267 /*@
1268    MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
1269         values into a matrix
1270 
1271    Not Collective
1272 
1273    Input Parameters:
1274 +  mat - the matrix
1275 .  row - the (block) row to set
1276 -  v - a logically two-dimensional array of values
1277 
1278    Notes:
1279    The values, v, are column-oriented for the block version.
1280 
1281    All the nonzeros in the row must be provided
1282 
1283    THE MATRIX MUSAT HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually MatSetValues() is used.
1284 
1285    The row must belong to this process
1286 
1287    Level: advanced
1288 
1289    Concepts: matrices^putting entries in
1290 
1291 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1292           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1293 @*/
1294 PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
1295 {
1296   PetscErrorCode ierr;
1297 
1298   PetscFunctionBeginHot;
1299   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1300   PetscValidType(mat,1);
1301   MatCheckPreallocated(mat,1);
1302   PetscValidScalarPointer(v,2);
1303 #if defined(PETSC_USE_DEBUG)
1304   if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
1305   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1306 #endif
1307   mat->insertmode = INSERT_VALUES;
1308 
1309   if (mat->assembled) {
1310     mat->was_assembled = PETSC_TRUE;
1311     mat->assembled     = PETSC_FALSE;
1312   }
1313   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1314   if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1315   ierr = (*mat->ops->setvaluesrow)(mat,row,v);CHKERRQ(ierr);
1316   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1317 #if defined(PETSC_HAVE_CUSP)
1318   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1319     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1320   }
1321 #elif defined(PETSC_HAVE_VIENNACL)
1322   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1323     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1324   }
1325 #elif defined(PETSC_HAVE_VECCUDA)
1326   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1327     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1328   }
1329 #endif
1330   PetscFunctionReturn(0);
1331 }
1332 
1333 #undef __FUNCT__
1334 #define __FUNCT__ "MatSetValuesStencil"
1335 /*@
1336    MatSetValuesStencil - Inserts or adds a block of values into a matrix.
1337      Using structured grid indexing
1338 
1339    Not Collective
1340 
1341    Input Parameters:
1342 +  mat - the matrix
1343 .  m - number of rows being entered
1344 .  idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
1345 .  n - number of columns being entered
1346 .  idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered
1347 .  v - a logically two-dimensional array of values
1348 -  addv - either ADD_VALUES or INSERT_VALUES, where
1349    ADD_VALUES adds values to any existing entries, and
1350    INSERT_VALUES replaces existing entries with new values
1351 
1352    Notes:
1353    By default the values, v, are row-oriented.  See MatSetOption() for other options.
1354 
1355    Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
1356    options cannot be mixed without intervening calls to the assembly
1357    routines.
1358 
1359    The grid coordinates are across the entire grid, not just the local portion
1360 
1361    MatSetValuesStencil() uses 0-based row and column numbers in Fortran
1362    as well as in C.
1363 
1364    For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1365 
1366    In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1367    or call MatSetLocalToGlobalMapping() and MatSetStencil() first.
1368 
1369    The columns and rows in the stencil passed in MUST be contained within the
1370    ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1371    if you create a DMDA with an overlap of one grid level and on a particular process its first
1372    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1373    first i index you can use in your column and row indices in MatSetStencil() is 5.
1374 
1375    In Fortran idxm and idxn should be declared as
1376 $     MatStencil idxm(4,m),idxn(4,n)
1377    and the values inserted using
1378 $    idxm(MatStencil_i,1) = i
1379 $    idxm(MatStencil_j,1) = j
1380 $    idxm(MatStencil_k,1) = k
1381 $    idxm(MatStencil_c,1) = c
1382    etc
1383 
1384    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
1385    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
1386    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
1387    DM_BOUNDARY_PERIODIC boundary type.
1388 
1389    For indices that don't mean anything for your case (like the k index when working in 2d) or the c index when you have
1390    a single value per point) you can skip filling those indices.
1391 
1392    Inspired by the structured grid interface to the HYPRE package
1393    (http://www.llnl.gov/CASC/hypre)
1394 
1395    Efficiency Alert:
1396    The routine MatSetValuesBlockedStencil() may offer much better efficiency
1397    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1398 
1399    Level: beginner
1400 
1401    Concepts: matrices^putting entries in
1402 
1403 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1404           MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil
1405 @*/
1406 PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1407 {
1408   PetscErrorCode ierr;
1409   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1410   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1411   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1412 
1413   PetscFunctionBegin;
1414   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1415   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1416   PetscValidType(mat,1);
1417   PetscValidIntPointer(idxm,3);
1418   PetscValidIntPointer(idxn,5);
1419   PetscValidScalarPointer(v,6);
1420 
1421   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1422     jdxm = buf; jdxn = buf+m;
1423   } else {
1424     ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr);
1425     jdxm = bufm; jdxn = bufn;
1426   }
1427   for (i=0; i<m; i++) {
1428     for (j=0; j<3-sdim; j++) dxm++;
1429     tmp = *dxm++ - starts[0];
1430     for (j=0; j<dim-1; j++) {
1431       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1432       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1433     }
1434     if (mat->stencil.noc) dxm++;
1435     jdxm[i] = tmp;
1436   }
1437   for (i=0; i<n; i++) {
1438     for (j=0; j<3-sdim; j++) dxn++;
1439     tmp = *dxn++ - starts[0];
1440     for (j=0; j<dim-1; j++) {
1441       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1442       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1443     }
1444     if (mat->stencil.noc) dxn++;
1445     jdxn[i] = tmp;
1446   }
1447   ierr = MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr);
1448   ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr);
1449   PetscFunctionReturn(0);
1450 }
1451 
1452 #undef __FUNCT__
1453 #define __FUNCT__ "MatSetValuesBlockedStencil"
1454 /*@
1455    MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1456      Using structured grid indexing
1457 
1458    Not Collective
1459 
1460    Input Parameters:
1461 +  mat - the matrix
1462 .  m - number of rows being entered
1463 .  idxm - grid coordinates for matrix rows being entered
1464 .  n - number of columns being entered
1465 .  idxn - grid coordinates for matrix columns being entered
1466 .  v - a logically two-dimensional array of values
1467 -  addv - either ADD_VALUES or INSERT_VALUES, where
1468    ADD_VALUES adds values to any existing entries, and
1469    INSERT_VALUES replaces existing entries with new values
1470 
1471    Notes:
1472    By default the values, v, are row-oriented and unsorted.
1473    See MatSetOption() for other options.
1474 
1475    Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
1476    options cannot be mixed without intervening calls to the assembly
1477    routines.
1478 
1479    The grid coordinates are across the entire grid, not just the local portion
1480 
1481    MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran
1482    as well as in C.
1483 
1484    For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1485 
1486    In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1487    or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first.
1488 
1489    The columns and rows in the stencil passed in MUST be contained within the
1490    ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1491    if you create a DMDA with an overlap of one grid level and on a particular process its first
1492    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1493    first i index you can use in your column and row indices in MatSetStencil() is 5.
1494 
1495    In Fortran idxm and idxn should be declared as
1496 $     MatStencil idxm(4,m),idxn(4,n)
1497    and the values inserted using
1498 $    idxm(MatStencil_i,1) = i
1499 $    idxm(MatStencil_j,1) = j
1500 $    idxm(MatStencil_k,1) = k
1501    etc
1502 
1503    Negative indices may be passed in idxm and idxn, these rows and columns are
1504    simply ignored. This allows easily inserting element stiffness matrices
1505    with homogeneous Dirchlet boundary conditions that you don't want represented
1506    in the matrix.
1507 
1508    Inspired by the structured grid interface to the HYPRE package
1509    (http://www.llnl.gov/CASC/hypre)
1510 
1511    Level: beginner
1512 
1513    Concepts: matrices^putting entries in
1514 
1515 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1516           MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil,
1517           MatSetBlockSize(), MatSetLocalToGlobalMapping()
1518 @*/
1519 PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1520 {
1521   PetscErrorCode ierr;
1522   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1523   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1524   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1525 
1526   PetscFunctionBegin;
1527   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1528   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1529   PetscValidType(mat,1);
1530   PetscValidIntPointer(idxm,3);
1531   PetscValidIntPointer(idxn,5);
1532   PetscValidScalarPointer(v,6);
1533 
1534   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1535     jdxm = buf; jdxn = buf+m;
1536   } else {
1537     ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr);
1538     jdxm = bufm; jdxn = bufn;
1539   }
1540   for (i=0; i<m; i++) {
1541     for (j=0; j<3-sdim; j++) dxm++;
1542     tmp = *dxm++ - starts[0];
1543     for (j=0; j<sdim-1; j++) {
1544       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1545       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1546     }
1547     dxm++;
1548     jdxm[i] = tmp;
1549   }
1550   for (i=0; i<n; i++) {
1551     for (j=0; j<3-sdim; j++) dxn++;
1552     tmp = *dxn++ - starts[0];
1553     for (j=0; j<sdim-1; j++) {
1554       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1555       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1556     }
1557     dxn++;
1558     jdxn[i] = tmp;
1559   }
1560   ierr = MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr);
1561   ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr);
1562 #if defined(PETSC_HAVE_CUSP)
1563   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1564     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1565   }
1566 #elif defined(PETSC_HAVE_VIENNACL)
1567   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1568     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1569   }
1570 #elif defined(PETSC_HAVE_VECCUDA)
1571   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1572     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1573   }
1574 #endif
1575   PetscFunctionReturn(0);
1576 }
1577 
1578 #undef __FUNCT__
1579 #define __FUNCT__ "MatSetStencil"
1580 /*@
1581    MatSetStencil - Sets the grid information for setting values into a matrix via
1582         MatSetValuesStencil()
1583 
1584    Not Collective
1585 
1586    Input Parameters:
1587 +  mat - the matrix
1588 .  dim - dimension of the grid 1, 2, or 3
1589 .  dims - number of grid points in x, y, and z direction, including ghost points on your processor
1590 .  starts - starting point of ghost nodes on your processor in x, y, and z direction
1591 -  dof - number of degrees of freedom per node
1592 
1593 
1594    Inspired by the structured grid interface to the HYPRE package
1595    (www.llnl.gov/CASC/hyper)
1596 
1597    For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the
1598    user.
1599 
1600    Level: beginner
1601 
1602    Concepts: matrices^putting entries in
1603 
1604 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1605           MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
1606 @*/
1607 PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1608 {
1609   PetscInt i;
1610 
1611   PetscFunctionBegin;
1612   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1613   PetscValidIntPointer(dims,3);
1614   PetscValidIntPointer(starts,4);
1615 
1616   mat->stencil.dim = dim + (dof > 1);
1617   for (i=0; i<dim; i++) {
1618     mat->stencil.dims[i]   = dims[dim-i-1];      /* copy the values in backwards */
1619     mat->stencil.starts[i] = starts[dim-i-1];
1620   }
1621   mat->stencil.dims[dim]   = dof;
1622   mat->stencil.starts[dim] = 0;
1623   mat->stencil.noc         = (PetscBool)(dof == 1);
1624   PetscFunctionReturn(0);
1625 }
1626 
1627 #undef __FUNCT__
1628 #define __FUNCT__ "MatSetValuesBlocked"
1629 /*@
1630    MatSetValuesBlocked - Inserts or adds a block of values into a matrix.
1631 
1632    Not Collective
1633 
1634    Input Parameters:
1635 +  mat - the matrix
1636 .  v - a logically two-dimensional array of values
1637 .  m, idxm - the number of block rows and their global block indices
1638 .  n, idxn - the number of block columns and their global block indices
1639 -  addv - either ADD_VALUES or INSERT_VALUES, where
1640    ADD_VALUES adds values to any existing entries, and
1641    INSERT_VALUES replaces existing entries with new values
1642 
1643    Notes:
1644    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call
1645    MatXXXXSetPreallocation() or MatSetUp() before using this routine.
1646 
1647    The m and n count the NUMBER of blocks in the row direction and column direction,
1648    NOT the total number of rows/columns; for example, if the block size is 2 and
1649    you are passing in values for rows 2,3,4,5  then m would be 2 (not 4).
1650    The values in idxm would be 1 2; that is the first index for each block divided by
1651    the block size.
1652 
1653    Note that you must call MatSetBlockSize() when constructing this matrix (before
1654    preallocating it).
1655 
1656    By default the values, v, are row-oriented, so the layout of
1657    v is the same as for MatSetValues(). See MatSetOption() for other options.
1658 
1659    Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
1660    options cannot be mixed without intervening calls to the assembly
1661    routines.
1662 
1663    MatSetValuesBlocked() uses 0-based row and column numbers in Fortran
1664    as well as in C.
1665 
1666    Negative indices may be passed in idxm and idxn, these rows and columns are
1667    simply ignored. This allows easily inserting element stiffness matrices
1668    with homogeneous Dirchlet boundary conditions that you don't want represented
1669    in the matrix.
1670 
1671    Each time an entry is set within a sparse matrix via MatSetValues(),
1672    internal searching must be done to determine where to place the the
1673    data in the matrix storage space.  By instead inserting blocks of
1674    entries via MatSetValuesBlocked(), the overhead of matrix assembly is
1675    reduced.
1676 
1677    Example:
1678 $   Suppose m=n=2 and block size(bs) = 2 The array is
1679 $
1680 $   1  2  | 3  4
1681 $   5  6  | 7  8
1682 $   - - - | - - -
1683 $   9  10 | 11 12
1684 $   13 14 | 15 16
1685 $
1686 $   v[] should be passed in like
1687 $   v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
1688 $
1689 $  If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then
1690 $   v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16]
1691 
1692    Level: intermediate
1693 
1694    Concepts: matrices^putting entries in blocked
1695 
1696 .seealso: MatSetBlockSize(), MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal()
1697 @*/
1698 PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1699 {
1700   PetscErrorCode ierr;
1701 
1702   PetscFunctionBeginHot;
1703   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1704   PetscValidType(mat,1);
1705   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1706   PetscValidIntPointer(idxm,3);
1707   PetscValidIntPointer(idxn,5);
1708   PetscValidScalarPointer(v,6);
1709   MatCheckPreallocated(mat,1);
1710   if (mat->insertmode == NOT_SET_VALUES) {
1711     mat->insertmode = addv;
1712   }
1713 #if defined(PETSC_USE_DEBUG)
1714   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1715   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1716   if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1717 #endif
1718 
1719   if (mat->assembled) {
1720     mat->was_assembled = PETSC_TRUE;
1721     mat->assembled     = PETSC_FALSE;
1722   }
1723   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1724   if (mat->ops->setvaluesblocked) {
1725     ierr = (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
1726   } else {
1727     PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn;
1728     PetscInt i,j,bs,cbs;
1729     ierr = MatGetBlockSizes(mat,&bs,&cbs);CHKERRQ(ierr);
1730     if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1731       iidxm = buf; iidxn = buf + m*bs;
1732     } else {
1733       ierr  = PetscMalloc2(m*bs,&bufr,n*cbs,&bufc);CHKERRQ(ierr);
1734       iidxm = bufr; iidxn = bufc;
1735     }
1736     for (i=0; i<m; i++) {
1737       for (j=0; j<bs; j++) {
1738         iidxm[i*bs+j] = bs*idxm[i] + j;
1739       }
1740     }
1741     for (i=0; i<n; i++) {
1742       for (j=0; j<cbs; j++) {
1743         iidxn[i*cbs+j] = cbs*idxn[i] + j;
1744       }
1745     }
1746     ierr = MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv);CHKERRQ(ierr);
1747     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
1748   }
1749   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1750 #if defined(PETSC_HAVE_CUSP)
1751   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1752     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1753   }
1754 #elif defined(PETSC_HAVE_VIENNACL)
1755   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1756     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1757   }
1758 #elif defined(PETSC_HAVE_VECCUDA)
1759   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1760     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1761   }
1762 #endif
1763   PetscFunctionReturn(0);
1764 }
1765 
1766 #undef __FUNCT__
1767 #define __FUNCT__ "MatGetValues"
1768 /*@
1769    MatGetValues - Gets a block of values from a matrix.
1770 
1771    Not Collective; currently only returns a local block
1772 
1773    Input Parameters:
1774 +  mat - the matrix
1775 .  v - a logically two-dimensional array for storing the values
1776 .  m, idxm - the number of rows and their global indices
1777 -  n, idxn - the number of columns and their global indices
1778 
1779    Notes:
1780    The user must allocate space (m*n PetscScalars) for the values, v.
1781    The values, v, are then returned in a row-oriented format,
1782    analogous to that used by default in MatSetValues().
1783 
1784    MatGetValues() uses 0-based row and column numbers in
1785    Fortran as well as in C.
1786 
1787    MatGetValues() requires that the matrix has been assembled
1788    with MatAssemblyBegin()/MatAssemblyEnd().  Thus, calls to
1789    MatSetValues() and MatGetValues() CANNOT be made in succession
1790    without intermediate matrix assembly.
1791 
1792    Negative row or column indices will be ignored and those locations in v[] will be
1793    left unchanged.
1794 
1795    Level: advanced
1796 
1797    Concepts: matrices^accessing values
1798 
1799 .seealso: MatGetRow(), MatGetSubMatrices(), MatSetValues()
1800 @*/
1801 PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1802 {
1803   PetscErrorCode ierr;
1804 
1805   PetscFunctionBegin;
1806   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1807   PetscValidType(mat,1);
1808   if (!m || !n) PetscFunctionReturn(0);
1809   PetscValidIntPointer(idxm,3);
1810   PetscValidIntPointer(idxn,5);
1811   PetscValidScalarPointer(v,6);
1812   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1813   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1814   if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1815   MatCheckPreallocated(mat,1);
1816 
1817   ierr = PetscLogEventBegin(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
1818   ierr = (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);CHKERRQ(ierr);
1819   ierr = PetscLogEventEnd(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
1820   PetscFunctionReturn(0);
1821 }
1822 
1823 #undef __FUNCT__
1824 #define __FUNCT__ "MatSetValuesBatch"
1825 /*@
1826   MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and
1827   the same size. Currently, this can only be called once and creates the given matrix.
1828 
1829   Not Collective
1830 
1831   Input Parameters:
1832 + mat - the matrix
1833 . nb - the number of blocks
1834 . bs - the number of rows (and columns) in each block
1835 . rows - a concatenation of the rows for each block
1836 - v - a concatenation of logically two-dimensional arrays of values
1837 
1838   Notes:
1839   In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix.
1840 
1841   Level: advanced
1842 
1843   Concepts: matrices^putting entries in
1844 
1845 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1846           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1847 @*/
1848 PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[])
1849 {
1850   PetscErrorCode ierr;
1851 
1852   PetscFunctionBegin;
1853   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1854   PetscValidType(mat,1);
1855   PetscValidScalarPointer(rows,4);
1856   PetscValidScalarPointer(v,5);
1857 #if defined(PETSC_USE_DEBUG)
1858   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1859 #endif
1860 
1861   ierr = PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr);
1862   if (mat->ops->setvaluesbatch) {
1863     ierr = (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);CHKERRQ(ierr);
1864   } else {
1865     PetscInt b;
1866     for (b = 0; b < nb; ++b) {
1867       ierr = MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);CHKERRQ(ierr);
1868     }
1869   }
1870   ierr = PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr);
1871   PetscFunctionReturn(0);
1872 }
1873 
1874 #undef __FUNCT__
1875 #define __FUNCT__ "MatSetLocalToGlobalMapping"
1876 /*@
1877    MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
1878    the routine MatSetValuesLocal() to allow users to insert matrix entries
1879    using a local (per-processor) numbering.
1880 
1881    Not Collective
1882 
1883    Input Parameters:
1884 +  x - the matrix
1885 .  rmapping - row mapping created with ISLocalToGlobalMappingCreate()   or ISLocalToGlobalMappingCreateIS()
1886 - cmapping - column mapping
1887 
1888    Level: intermediate
1889 
1890    Concepts: matrices^local to global mapping
1891    Concepts: local to global mapping^for matrices
1892 
1893 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
1894 @*/
1895 PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
1896 {
1897   PetscErrorCode ierr;
1898 
1899   PetscFunctionBegin;
1900   PetscValidHeaderSpecific(x,MAT_CLASSID,1);
1901   PetscValidType(x,1);
1902   PetscValidHeaderSpecific(rmapping,IS_LTOGM_CLASSID,2);
1903   PetscValidHeaderSpecific(cmapping,IS_LTOGM_CLASSID,3);
1904 
1905   if (x->ops->setlocaltoglobalmapping) {
1906     ierr = (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);CHKERRQ(ierr);
1907   } else {
1908     ierr = PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);CHKERRQ(ierr);
1909     ierr = PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);CHKERRQ(ierr);
1910   }
1911   PetscFunctionReturn(0);
1912 }
1913 
1914 
1915 #undef __FUNCT__
1916 #define __FUNCT__ "MatGetLocalToGlobalMapping"
1917 /*@
1918    MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping()
1919 
1920    Not Collective
1921 
1922    Input Parameters:
1923 .  A - the matrix
1924 
1925    Output Parameters:
1926 + rmapping - row mapping
1927 - cmapping - column mapping
1928 
1929    Level: advanced
1930 
1931    Concepts: matrices^local to global mapping
1932    Concepts: local to global mapping^for matrices
1933 
1934 .seealso:  MatSetValuesLocal()
1935 @*/
1936 PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
1937 {
1938   PetscFunctionBegin;
1939   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
1940   PetscValidType(A,1);
1941   if (rmapping) PetscValidPointer(rmapping,2);
1942   if (cmapping) PetscValidPointer(cmapping,3);
1943   if (rmapping) *rmapping = A->rmap->mapping;
1944   if (cmapping) *cmapping = A->cmap->mapping;
1945   PetscFunctionReturn(0);
1946 }
1947 
1948 #undef __FUNCT__
1949 #define __FUNCT__ "MatGetLayouts"
1950 /*@
1951    MatGetLayouts - Gets the PetscLayout objects for rows and columns
1952 
1953    Not Collective
1954 
1955    Input Parameters:
1956 .  A - the matrix
1957 
1958    Output Parameters:
1959 + rmap - row layout
1960 - cmap - column layout
1961 
1962    Level: advanced
1963 
1964 .seealso:  MatCreateVecs(), MatGetLocalToGlobalMapping()
1965 @*/
1966 PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap)
1967 {
1968   PetscFunctionBegin;
1969   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
1970   PetscValidType(A,1);
1971   if (rmap) PetscValidPointer(rmap,2);
1972   if (cmap) PetscValidPointer(cmap,3);
1973   if (rmap) *rmap = A->rmap;
1974   if (cmap) *cmap = A->cmap;
1975   PetscFunctionReturn(0);
1976 }
1977 
1978 #undef __FUNCT__
1979 #define __FUNCT__ "MatSetValuesLocal"
1980 /*@
1981    MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
1982    using a local ordering of the nodes.
1983 
1984    Not Collective
1985 
1986    Input Parameters:
1987 +  x - the matrix
1988 .  nrow, irow - number of rows and their local indices
1989 .  ncol, icol - number of columns and their local indices
1990 .  y -  a logically two-dimensional array of values
1991 -  addv - either INSERT_VALUES or ADD_VALUES, where
1992    ADD_VALUES adds values to any existing entries, and
1993    INSERT_VALUES replaces existing entries with new values
1994 
1995    Notes:
1996    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
1997       MatSetUp() before using this routine
1998 
1999    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine
2000 
2001    Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
2002    options cannot be mixed without intervening calls to the assembly
2003    routines.
2004 
2005    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2006    MUST be called after all calls to MatSetValuesLocal() have been completed.
2007 
2008    Level: intermediate
2009 
2010    Concepts: matrices^putting entries in with local numbering
2011 
2012 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
2013            MatSetValueLocal()
2014 @*/
2015 PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2016 {
2017   PetscErrorCode ierr;
2018 
2019   PetscFunctionBeginHot;
2020   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2021   PetscValidType(mat,1);
2022   MatCheckPreallocated(mat,1);
2023   if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */
2024   PetscValidIntPointer(irow,3);
2025   PetscValidIntPointer(icol,5);
2026   PetscValidScalarPointer(y,6);
2027   if (mat->insertmode == NOT_SET_VALUES) {
2028     mat->insertmode = addv;
2029   }
2030 #if defined(PETSC_USE_DEBUG)
2031   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2032   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2033   if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2034 #endif
2035 
2036   if (mat->assembled) {
2037     mat->was_assembled = PETSC_TRUE;
2038     mat->assembled     = PETSC_FALSE;
2039   }
2040   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2041   if (mat->ops->setvalueslocal) {
2042     ierr = (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr);
2043   } else {
2044     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2045     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2046       irowm = buf; icolm = buf+nrow;
2047     } else {
2048       ierr  = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr);
2049       irowm = bufr; icolm = bufc;
2050     }
2051     ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr);
2052     ierr = ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr);
2053     ierr = MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
2054     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
2055   }
2056   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2057 #if defined(PETSC_HAVE_CUSP)
2058   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
2059     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
2060   }
2061 #elif defined(PETSC_HAVE_VIENNACL)
2062   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
2063     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
2064   }
2065 #elif defined(PETSC_HAVE_VECCUDA)
2066   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
2067     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
2068   }
2069 #endif
2070   PetscFunctionReturn(0);
2071 }
2072 
2073 #undef __FUNCT__
2074 #define __FUNCT__ "MatSetValuesBlockedLocal"
2075 /*@
2076    MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix,
2077    using a local ordering of the nodes a block at a time.
2078 
2079    Not Collective
2080 
2081    Input Parameters:
2082 +  x - the matrix
2083 .  nrow, irow - number of rows and their local indices
2084 .  ncol, icol - number of columns and their local indices
2085 .  y -  a logically two-dimensional array of values
2086 -  addv - either INSERT_VALUES or ADD_VALUES, where
2087    ADD_VALUES adds values to any existing entries, and
2088    INSERT_VALUES replaces existing entries with new values
2089 
2090    Notes:
2091    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
2092       MatSetUp() before using this routine
2093 
2094    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMapping()
2095       before using this routineBefore calling MatSetValuesLocal(), the user must first set the
2096 
2097    Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
2098    options cannot be mixed without intervening calls to the assembly
2099    routines.
2100 
2101    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2102    MUST be called after all calls to MatSetValuesBlockedLocal() have been completed.
2103 
2104    Level: intermediate
2105 
2106    Concepts: matrices^putting blocked values in with local numbering
2107 
2108 .seealso:  MatSetBlockSize(), MatSetLocalToGlobalMapping(), MatAssemblyBegin(), MatAssemblyEnd(),
2109            MatSetValuesLocal(),  MatSetValuesBlocked()
2110 @*/
2111 PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2112 {
2113   PetscErrorCode ierr;
2114 
2115   PetscFunctionBeginHot;
2116   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2117   PetscValidType(mat,1);
2118   MatCheckPreallocated(mat,1);
2119   if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */
2120   PetscValidIntPointer(irow,3);
2121   PetscValidIntPointer(icol,5);
2122   PetscValidScalarPointer(y,6);
2123   if (mat->insertmode == NOT_SET_VALUES) {
2124     mat->insertmode = addv;
2125   }
2126 #if defined(PETSC_USE_DEBUG)
2127   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2128   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2129   if (!mat->ops->setvaluesblockedlocal && !mat->ops->setvaluesblocked && !mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2130 #endif
2131 
2132   if (mat->assembled) {
2133     mat->was_assembled = PETSC_TRUE;
2134     mat->assembled     = PETSC_FALSE;
2135   }
2136   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2137   if (mat->ops->setvaluesblockedlocal) {
2138     ierr = (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr);
2139   } else {
2140     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2141     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2142       irowm = buf; icolm = buf + nrow;
2143     } else {
2144       ierr  = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr);
2145       irowm = bufr; icolm = bufc;
2146     }
2147     ierr = ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr);
2148     ierr = ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr);
2149     ierr = MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
2150     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
2151   }
2152   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2153 #if defined(PETSC_HAVE_CUSP)
2154   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
2155     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
2156   }
2157 #elif defined(PETSC_HAVE_VIENNACL)
2158   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
2159     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
2160   }
2161 #elif defined(PETSC_HAVE_VECCUDA)
2162   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
2163     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
2164   }
2165 #endif
2166   PetscFunctionReturn(0);
2167 }
2168 
2169 #undef __FUNCT__
2170 #define __FUNCT__ "MatMultDiagonalBlock"
2171 /*@
2172    MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal
2173 
2174    Collective on Mat and Vec
2175 
2176    Input Parameters:
2177 +  mat - the matrix
2178 -  x   - the vector to be multiplied
2179 
2180    Output Parameters:
2181 .  y - the result
2182 
2183    Notes:
2184    The vectors x and y cannot be the same.  I.e., one cannot
2185    call MatMult(A,y,y).
2186 
2187    Level: developer
2188 
2189    Concepts: matrix-vector product
2190 
2191 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2192 @*/
2193 PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y)
2194 {
2195   PetscErrorCode ierr;
2196 
2197   PetscFunctionBegin;
2198   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2199   PetscValidType(mat,1);
2200   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2201   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2202 
2203   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2204   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2205   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2206   MatCheckPreallocated(mat,1);
2207 
2208   if (!mat->ops->multdiagonalblock) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2209   ierr = (*mat->ops->multdiagonalblock)(mat,x,y);CHKERRQ(ierr);
2210   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2211   PetscFunctionReturn(0);
2212 }
2213 
2214 /* --------------------------------------------------------*/
2215 #undef __FUNCT__
2216 #define __FUNCT__ "MatMult"
2217 /*@
2218    MatMult - Computes the matrix-vector product, y = Ax.
2219 
2220    Neighbor-wise Collective on Mat and Vec
2221 
2222    Input Parameters:
2223 +  mat - the matrix
2224 -  x   - the vector to be multiplied
2225 
2226    Output Parameters:
2227 .  y - the result
2228 
2229    Notes:
2230    The vectors x and y cannot be the same.  I.e., one cannot
2231    call MatMult(A,y,y).
2232 
2233    Level: beginner
2234 
2235    Concepts: matrix-vector product
2236 
2237 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2238 @*/
2239 PetscErrorCode MatMult(Mat mat,Vec x,Vec y)
2240 {
2241   PetscErrorCode ierr;
2242 
2243   PetscFunctionBegin;
2244   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2245   PetscValidType(mat,1);
2246   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2247   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2248   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2249   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2250   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2251 #if !defined(PETSC_HAVE_CONSTRAINTS)
2252   if (mat->cmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
2253   if (mat->rmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
2254   if (mat->rmap->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %D %D",mat->rmap->n,y->map->n);
2255 #endif
2256   VecLocked(y,3);
2257   if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);}
2258   MatCheckPreallocated(mat,1);
2259 
2260   ierr = VecLockPush(x);CHKERRQ(ierr);
2261   if (!mat->ops->mult) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2262   ierr = PetscLogEventBegin(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
2263   ierr = (*mat->ops->mult)(mat,x,y);CHKERRQ(ierr);
2264   ierr = PetscLogEventEnd(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
2265   if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);}
2266   ierr = VecLockPop(x);CHKERRQ(ierr);
2267   PetscFunctionReturn(0);
2268 }
2269 
2270 #undef __FUNCT__
2271 #define __FUNCT__ "MatMultTranspose"
2272 /*@
2273    MatMultTranspose - Computes matrix transpose times a vector.
2274 
2275    Neighbor-wise Collective on Mat and Vec
2276 
2277    Input Parameters:
2278 +  mat - the matrix
2279 -  x   - the vector to be multilplied
2280 
2281    Output Parameters:
2282 .  y - the result
2283 
2284    Notes:
2285    The vectors x and y cannot be the same.  I.e., one cannot
2286    call MatMultTranspose(A,y,y).
2287 
2288    For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple,
2289    use MatMultHermitianTranspose()
2290 
2291    Level: beginner
2292 
2293    Concepts: matrix vector product^transpose
2294 
2295 .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose()
2296 @*/
2297 PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y)
2298 {
2299   PetscErrorCode ierr;
2300 
2301   PetscFunctionBegin;
2302   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2303   PetscValidType(mat,1);
2304   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2305   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2306 
2307   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2308   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2309   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2310 #if !defined(PETSC_HAVE_CONSTRAINTS)
2311   if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
2312   if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N);
2313 #endif
2314   if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);}
2315   MatCheckPreallocated(mat,1);
2316 
2317   if (!mat->ops->multtranspose) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply tranpose defined");
2318   ierr = PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
2319   ierr = VecLockPush(x);CHKERRQ(ierr);
2320   ierr = (*mat->ops->multtranspose)(mat,x,y);CHKERRQ(ierr);
2321   ierr = VecLockPop(x);CHKERRQ(ierr);
2322   ierr = PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
2323   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2324   if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);}
2325   PetscFunctionReturn(0);
2326 }
2327 
2328 #undef __FUNCT__
2329 #define __FUNCT__ "MatMultHermitianTranspose"
2330 /*@
2331    MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.
2332 
2333    Neighbor-wise Collective on Mat and Vec
2334 
2335    Input Parameters:
2336 +  mat - the matrix
2337 -  x   - the vector to be multilplied
2338 
2339    Output Parameters:
2340 .  y - the result
2341 
2342    Notes:
2343    The vectors x and y cannot be the same.  I.e., one cannot
2344    call MatMultHermitianTranspose(A,y,y).
2345 
2346    Also called the conjugate transpose, complex conjugate transpose, or adjoint.
2347 
2348    For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical.
2349 
2350    Level: beginner
2351 
2352    Concepts: matrix vector product^transpose
2353 
2354 .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose()
2355 @*/
2356 PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y)
2357 {
2358   PetscErrorCode ierr;
2359   Vec            w;
2360 
2361   PetscFunctionBegin;
2362   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2363   PetscValidType(mat,1);
2364   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2365   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2366 
2367   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2368   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2369   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2370 #if !defined(PETSC_HAVE_CONSTRAINTS)
2371   if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
2372   if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N);
2373 #endif
2374   MatCheckPreallocated(mat,1);
2375 
2376   ierr = PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr);
2377   if (mat->ops->multhermitiantranspose) {
2378     ierr = VecLockPush(x);CHKERRQ(ierr);
2379     ierr = (*mat->ops->multhermitiantranspose)(mat,x,y);CHKERRQ(ierr);
2380     ierr = VecLockPop(x);CHKERRQ(ierr);
2381   } else {
2382     ierr = VecDuplicate(x,&w);CHKERRQ(ierr);
2383     ierr = VecCopy(x,w);CHKERRQ(ierr);
2384     ierr = VecConjugate(w);CHKERRQ(ierr);
2385     ierr = MatMultTranspose(mat,w,y);CHKERRQ(ierr);
2386     ierr = VecDestroy(&w);CHKERRQ(ierr);
2387     ierr = VecConjugate(y);CHKERRQ(ierr);
2388   }
2389   ierr = PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr);
2390   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2391   PetscFunctionReturn(0);
2392 }
2393 
2394 #undef __FUNCT__
2395 #define __FUNCT__ "MatMultAdd"
2396 /*@
2397     MatMultAdd -  Computes v3 = v2 + A * v1.
2398 
2399     Neighbor-wise Collective on Mat and Vec
2400 
2401     Input Parameters:
2402 +   mat - the matrix
2403 -   v1, v2 - the vectors
2404 
2405     Output Parameters:
2406 .   v3 - the result
2407 
2408     Notes:
2409     The vectors v1 and v3 cannot be the same.  I.e., one cannot
2410     call MatMultAdd(A,v1,v2,v1).
2411 
2412     Level: beginner
2413 
2414     Concepts: matrix vector product^addition
2415 
2416 .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
2417 @*/
2418 PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2419 {
2420   PetscErrorCode ierr;
2421 
2422   PetscFunctionBegin;
2423   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2424   PetscValidType(mat,1);
2425   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2426   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2427   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2428 
2429   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2430   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2431   if (mat->cmap->N != v1->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->cmap->N,v1->map->N);
2432   /* if (mat->rmap->N != v2->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->rmap->N,v2->map->N);
2433      if (mat->rmap->N != v3->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->rmap->N,v3->map->N); */
2434   if (mat->rmap->n != v3->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: local dim %D %D",mat->rmap->n,v3->map->n);
2435   if (mat->rmap->n != v2->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: local dim %D %D",mat->rmap->n,v2->map->n);
2436   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2437   MatCheckPreallocated(mat,1);
2438 
2439   if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name);
2440   ierr = PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2441   ierr = VecLockPush(v1);CHKERRQ(ierr);
2442   ierr = (*mat->ops->multadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2443   ierr = VecLockPop(v1);CHKERRQ(ierr);
2444   ierr = PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2445   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2446   PetscFunctionReturn(0);
2447 }
2448 
2449 #undef __FUNCT__
2450 #define __FUNCT__ "MatMultTransposeAdd"
2451 /*@
2452    MatMultTransposeAdd - Computes v3 = v2 + A' * v1.
2453 
2454    Neighbor-wise Collective on Mat and Vec
2455 
2456    Input Parameters:
2457 +  mat - the matrix
2458 -  v1, v2 - the vectors
2459 
2460    Output Parameters:
2461 .  v3 - the result
2462 
2463    Notes:
2464    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2465    call MatMultTransposeAdd(A,v1,v2,v1).
2466 
2467    Level: beginner
2468 
2469    Concepts: matrix vector product^transpose and addition
2470 
2471 .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
2472 @*/
2473 PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2474 {
2475   PetscErrorCode ierr;
2476 
2477   PetscFunctionBegin;
2478   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2479   PetscValidType(mat,1);
2480   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2481   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2482   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2483 
2484   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2485   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2486   if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2487   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2488   if (mat->rmap->N != v1->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->rmap->N,v1->map->N);
2489   if (mat->cmap->N != v2->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->cmap->N,v2->map->N);
2490   if (mat->cmap->N != v3->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->cmap->N,v3->map->N);
2491   MatCheckPreallocated(mat,1);
2492 
2493   ierr = PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2494   ierr = VecLockPush(v1);CHKERRQ(ierr);
2495   ierr = (*mat->ops->multtransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2496   ierr = VecLockPop(v1);CHKERRQ(ierr);
2497   ierr = PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2498   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2499   PetscFunctionReturn(0);
2500 }
2501 
2502 #undef __FUNCT__
2503 #define __FUNCT__ "MatMultHermitianTransposeAdd"
2504 /*@
2505    MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1.
2506 
2507    Neighbor-wise Collective on Mat and Vec
2508 
2509    Input Parameters:
2510 +  mat - the matrix
2511 -  v1, v2 - the vectors
2512 
2513    Output Parameters:
2514 .  v3 - the result
2515 
2516    Notes:
2517    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2518    call MatMultHermitianTransposeAdd(A,v1,v2,v1).
2519 
2520    Level: beginner
2521 
2522    Concepts: matrix vector product^transpose and addition
2523 
2524 .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult()
2525 @*/
2526 PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2527 {
2528   PetscErrorCode ierr;
2529 
2530   PetscFunctionBegin;
2531   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2532   PetscValidType(mat,1);
2533   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2534   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2535   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2536 
2537   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2538   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2539   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2540   if (mat->rmap->N != v1->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->rmap->N,v1->map->N);
2541   if (mat->cmap->N != v2->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->cmap->N,v2->map->N);
2542   if (mat->cmap->N != v3->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->cmap->N,v3->map->N);
2543   MatCheckPreallocated(mat,1);
2544 
2545   ierr = PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2546   ierr = VecLockPush(v1);CHKERRQ(ierr);
2547   if (mat->ops->multhermitiantransposeadd) {
2548     ierr = (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2549    } else {
2550     Vec w,z;
2551     ierr = VecDuplicate(v1,&w);CHKERRQ(ierr);
2552     ierr = VecCopy(v1,w);CHKERRQ(ierr);
2553     ierr = VecConjugate(w);CHKERRQ(ierr);
2554     ierr = VecDuplicate(v3,&z);CHKERRQ(ierr);
2555     ierr = MatMultTranspose(mat,w,z);CHKERRQ(ierr);
2556     ierr = VecDestroy(&w);CHKERRQ(ierr);
2557     ierr = VecConjugate(z);CHKERRQ(ierr);
2558     ierr = VecWAXPY(v3,1.0,v2,z);CHKERRQ(ierr);
2559     ierr = VecDestroy(&z);CHKERRQ(ierr);
2560   }
2561   ierr = VecLockPop(v1);CHKERRQ(ierr);
2562   ierr = PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2563   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2564   PetscFunctionReturn(0);
2565 }
2566 
2567 #undef __FUNCT__
2568 #define __FUNCT__ "MatMultConstrained"
2569 /*@
2570    MatMultConstrained - The inner multiplication routine for a
2571    constrained matrix P^T A P.
2572 
2573    Neighbor-wise Collective on Mat and Vec
2574 
2575    Input Parameters:
2576 +  mat - the matrix
2577 -  x   - the vector to be multilplied
2578 
2579    Output Parameters:
2580 .  y - the result
2581 
2582    Notes:
2583    The vectors x and y cannot be the same.  I.e., one cannot
2584    call MatMult(A,y,y).
2585 
2586    Level: beginner
2587 
2588 .keywords: matrix, multiply, matrix-vector product, constraint
2589 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2590 @*/
2591 PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y)
2592 {
2593   PetscErrorCode ierr;
2594 
2595   PetscFunctionBegin;
2596   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2597   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2598   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2599   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2600   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2601   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2602   if (mat->cmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
2603   if (mat->rmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
2604   if (mat->rmap->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %D %D",mat->rmap->n,y->map->n);
2605 
2606   ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2607   ierr = VecLockPush(x);CHKERRQ(ierr);
2608   ierr = (*mat->ops->multconstrained)(mat,x,y);CHKERRQ(ierr);
2609   ierr = VecLockPop(x);CHKERRQ(ierr);
2610   ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2611   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2612   PetscFunctionReturn(0);
2613 }
2614 
2615 #undef __FUNCT__
2616 #define __FUNCT__ "MatMultTransposeConstrained"
2617 /*@
2618    MatMultTransposeConstrained - The inner multiplication routine for a
2619    constrained matrix P^T A^T P.
2620 
2621    Neighbor-wise Collective on Mat and Vec
2622 
2623    Input Parameters:
2624 +  mat - the matrix
2625 -  x   - the vector to be multilplied
2626 
2627    Output Parameters:
2628 .  y - the result
2629 
2630    Notes:
2631    The vectors x and y cannot be the same.  I.e., one cannot
2632    call MatMult(A,y,y).
2633 
2634    Level: beginner
2635 
2636 .keywords: matrix, multiply, matrix-vector product, constraint
2637 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2638 @*/
2639 PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2640 {
2641   PetscErrorCode ierr;
2642 
2643   PetscFunctionBegin;
2644   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2645   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2646   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2647   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2648   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2649   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2650   if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
2651   if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
2652 
2653   ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2654   ierr = (*mat->ops->multtransposeconstrained)(mat,x,y);CHKERRQ(ierr);
2655   ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2656   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2657   PetscFunctionReturn(0);
2658 }
2659 
2660 #undef __FUNCT__
2661 #define __FUNCT__ "MatGetFactorType"
2662 /*@C
2663    MatGetFactorType - gets the type of factorization it is
2664 
2665    Note Collective
2666    as the flag
2667 
2668    Input Parameters:
2669 .  mat - the matrix
2670 
2671    Output Parameters:
2672 .  t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT
2673 
2674     Level: intermediate
2675 
2676 .seealso:    MatFactorType, MatGetFactor()
2677 @*/
2678 PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t)
2679 {
2680   PetscFunctionBegin;
2681   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2682   PetscValidType(mat,1);
2683   *t = mat->factortype;
2684   PetscFunctionReturn(0);
2685 }
2686 
2687 /* ------------------------------------------------------------*/
2688 #undef __FUNCT__
2689 #define __FUNCT__ "MatGetInfo"
2690 /*@C
2691    MatGetInfo - Returns information about matrix storage (number of
2692    nonzeros, memory, etc.).
2693 
2694    Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag
2695 
2696    Input Parameters:
2697 .  mat - the matrix
2698 
2699    Output Parameters:
2700 +  flag - flag indicating the type of parameters to be returned
2701    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2702    MAT_GLOBAL_SUM - sum over all processors)
2703 -  info - matrix information context
2704 
2705    Notes:
2706    The MatInfo context contains a variety of matrix data, including
2707    number of nonzeros allocated and used, number of mallocs during
2708    matrix assembly, etc.  Additional information for factored matrices
2709    is provided (such as the fill ratio, number of mallocs during
2710    factorization, etc.).  Much of this info is printed to PETSC_STDOUT
2711    when using the runtime options
2712 $       -info -mat_view ::ascii_info
2713 
2714    Example for C/C++ Users:
2715    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2716    data within the MatInfo context.  For example,
2717 .vb
2718       MatInfo info;
2719       Mat     A;
2720       double  mal, nz_a, nz_u;
2721 
2722       MatGetInfo(A,MAT_LOCAL,&info);
2723       mal  = info.mallocs;
2724       nz_a = info.nz_allocated;
2725 .ve
2726 
2727    Example for Fortran Users:
2728    Fortran users should declare info as a double precision
2729    array of dimension MAT_INFO_SIZE, and then extract the parameters
2730    of interest.  See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h
2731    a complete list of parameter names.
2732 .vb
2733       double  precision info(MAT_INFO_SIZE)
2734       double  precision mal, nz_a
2735       Mat     A
2736       integer ierr
2737 
2738       call MatGetInfo(A,MAT_LOCAL,info,ierr)
2739       mal = info(MAT_INFO_MALLOCS)
2740       nz_a = info(MAT_INFO_NZ_ALLOCATED)
2741 .ve
2742 
2743     Level: intermediate
2744 
2745     Concepts: matrices^getting information on
2746 
2747     Developer Note: fortran interface is not autogenerated as the f90
2748     interface defintion cannot be generated correctly [due to MatInfo]
2749 
2750 .seealso: MatStashGetInfo()
2751 
2752 @*/
2753 PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2754 {
2755   PetscErrorCode ierr;
2756 
2757   PetscFunctionBegin;
2758   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2759   PetscValidType(mat,1);
2760   PetscValidPointer(info,3);
2761   if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2762   MatCheckPreallocated(mat,1);
2763   ierr = (*mat->ops->getinfo)(mat,flag,info);CHKERRQ(ierr);
2764   PetscFunctionReturn(0);
2765 }
2766 
2767 /* ----------------------------------------------------------*/
2768 
2769 #undef __FUNCT__
2770 #define __FUNCT__ "MatLUFactor"
2771 /*@C
2772    MatLUFactor - Performs in-place LU factorization of matrix.
2773 
2774    Collective on Mat
2775 
2776    Input Parameters:
2777 +  mat - the matrix
2778 .  row - row permutation
2779 .  col - column permutation
2780 -  info - options for factorization, includes
2781 $          fill - expected fill as ratio of original fill.
2782 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2783 $                   Run with the option -info to determine an optimal value to use
2784 
2785    Notes:
2786    Most users should employ the simplified KSP interface for linear solvers
2787    instead of working directly with matrix algebra routines such as this.
2788    See, e.g., KSPCreate().
2789 
2790    This changes the state of the matrix to a factored matrix; it cannot be used
2791    for example with MatSetValues() unless one first calls MatSetUnfactored().
2792 
2793    Level: developer
2794 
2795    Concepts: matrices^LU factorization
2796 
2797 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2798           MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor()
2799 
2800     Developer Note: fortran interface is not autogenerated as the f90
2801     interface defintion cannot be generated correctly [due to MatFactorInfo]
2802 
2803 @*/
2804 PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2805 {
2806   PetscErrorCode ierr;
2807   MatFactorInfo  tinfo;
2808 
2809   PetscFunctionBegin;
2810   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2811   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
2812   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
2813   if (info) PetscValidPointer(info,4);
2814   PetscValidType(mat,1);
2815   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2816   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2817   if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2818   MatCheckPreallocated(mat,1);
2819   if (!info) {
2820     ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr);
2821     info = &tinfo;
2822   }
2823 
2824   ierr = PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
2825   ierr = (*mat->ops->lufactor)(mat,row,col,info);CHKERRQ(ierr);
2826   ierr = PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
2827   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
2828   PetscFunctionReturn(0);
2829 }
2830 
2831 #undef __FUNCT__
2832 #define __FUNCT__ "MatILUFactor"
2833 /*@C
2834    MatILUFactor - Performs in-place ILU factorization of matrix.
2835 
2836    Collective on Mat
2837 
2838    Input Parameters:
2839 +  mat - the matrix
2840 .  row - row permutation
2841 .  col - column permutation
2842 -  info - structure containing
2843 $      levels - number of levels of fill.
2844 $      expected fill - as ratio of original fill.
2845 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2846                 missing diagonal entries)
2847 
2848    Notes:
2849    Probably really in-place only when level of fill is zero, otherwise allocates
2850    new space to store factored matrix and deletes previous memory.
2851 
2852    Most users should employ the simplified KSP interface for linear solvers
2853    instead of working directly with matrix algebra routines such as this.
2854    See, e.g., KSPCreate().
2855 
2856    Level: developer
2857 
2858    Concepts: matrices^ILU factorization
2859 
2860 .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
2861 
2862     Developer Note: fortran interface is not autogenerated as the f90
2863     interface defintion cannot be generated correctly [due to MatFactorInfo]
2864 
2865 @*/
2866 PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2867 {
2868   PetscErrorCode ierr;
2869 
2870   PetscFunctionBegin;
2871   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2872   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
2873   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
2874   PetscValidPointer(info,4);
2875   PetscValidType(mat,1);
2876   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
2877   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2878   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2879   if (!mat->ops->ilufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2880   MatCheckPreallocated(mat,1);
2881 
2882   ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
2883   ierr = (*mat->ops->ilufactor)(mat,row,col,info);CHKERRQ(ierr);
2884   ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
2885   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
2886   PetscFunctionReturn(0);
2887 }
2888 
2889 #undef __FUNCT__
2890 #define __FUNCT__ "MatLUFactorSymbolic"
2891 /*@C
2892    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
2893    Call this routine before calling MatLUFactorNumeric().
2894 
2895    Collective on Mat
2896 
2897    Input Parameters:
2898 +  fact - the factor matrix obtained with MatGetFactor()
2899 .  mat - the matrix
2900 .  row, col - row and column permutations
2901 -  info - options for factorization, includes
2902 $          fill - expected fill as ratio of original fill.
2903 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2904 $                   Run with the option -info to determine an optimal value to use
2905 
2906 
2907    Notes: See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
2908 
2909    Most users should employ the simplified KSP interface for linear solvers
2910    instead of working directly with matrix algebra routines such as this.
2911    See, e.g., KSPCreate().
2912 
2913    Level: developer
2914 
2915    Concepts: matrices^LU symbolic factorization
2916 
2917 .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo, MatFactorInfoInitialize()
2918 
2919     Developer Note: fortran interface is not autogenerated as the f90
2920     interface defintion cannot be generated correctly [due to MatFactorInfo]
2921 
2922 @*/
2923 PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
2924 {
2925   PetscErrorCode ierr;
2926 
2927   PetscFunctionBegin;
2928   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2929   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
2930   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
2931   if (info) PetscValidPointer(info,4);
2932   PetscValidType(mat,1);
2933   PetscValidPointer(fact,5);
2934   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2935   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2936   if (!(fact)->ops->lufactorsymbolic) {
2937     const MatSolverPackage spackage;
2938     ierr = MatFactorGetSolverPackage(fact,&spackage);CHKERRQ(ierr);
2939     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage);
2940   }
2941   MatCheckPreallocated(mat,2);
2942 
2943   ierr = PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
2944   ierr = (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
2945   ierr = PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
2946   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
2947   PetscFunctionReturn(0);
2948 }
2949 
2950 #undef __FUNCT__
2951 #define __FUNCT__ "MatLUFactorNumeric"
2952 /*@C
2953    MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
2954    Call this routine after first calling MatLUFactorSymbolic().
2955 
2956    Collective on Mat
2957 
2958    Input Parameters:
2959 +  fact - the factor matrix obtained with MatGetFactor()
2960 .  mat - the matrix
2961 -  info - options for factorization
2962 
2963    Notes:
2964    See MatLUFactor() for in-place factorization.  See
2965    MatCholeskyFactorNumeric() for the symmetric, positive definite case.
2966 
2967    Most users should employ the simplified KSP interface for linear solvers
2968    instead of working directly with matrix algebra routines such as this.
2969    See, e.g., KSPCreate().
2970 
2971    Level: developer
2972 
2973    Concepts: matrices^LU numeric factorization
2974 
2975 .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()
2976 
2977     Developer Note: fortran interface is not autogenerated as the f90
2978     interface defintion cannot be generated correctly [due to MatFactorInfo]
2979 
2980 @*/
2981 PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
2982 {
2983   PetscErrorCode ierr;
2984 
2985   PetscFunctionBegin;
2986   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2987   PetscValidType(mat,1);
2988   PetscValidPointer(fact,2);
2989   PetscValidHeaderSpecific(fact,MAT_CLASSID,2);
2990   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2991   if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) SETERRQ4(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dimensions are different %D should = %D %D should = %D",mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N);
2992 
2993   if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name);
2994   MatCheckPreallocated(mat,2);
2995   ierr = PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
2996   ierr = (fact->ops->lufactornumeric)(fact,mat,info);CHKERRQ(ierr);
2997   ierr = PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
2998   ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr);
2999   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3000   PetscFunctionReturn(0);
3001 }
3002 
3003 #undef __FUNCT__
3004 #define __FUNCT__ "MatCholeskyFactor"
3005 /*@C
3006    MatCholeskyFactor - Performs in-place Cholesky factorization of a
3007    symmetric matrix.
3008 
3009    Collective on Mat
3010 
3011    Input Parameters:
3012 +  mat - the matrix
3013 .  perm - row and column permutations
3014 -  f - expected fill as ratio of original fill
3015 
3016    Notes:
3017    See MatLUFactor() for the nonsymmetric case.  See also
3018    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().
3019 
3020    Most users should employ the simplified KSP interface for linear solvers
3021    instead of working directly with matrix algebra routines such as this.
3022    See, e.g., KSPCreate().
3023 
3024    Level: developer
3025 
3026    Concepts: matrices^Cholesky factorization
3027 
3028 .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
3029           MatGetOrdering()
3030 
3031     Developer Note: fortran interface is not autogenerated as the f90
3032     interface defintion cannot be generated correctly [due to MatFactorInfo]
3033 
3034 @*/
3035 PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
3036 {
3037   PetscErrorCode ierr;
3038 
3039   PetscFunctionBegin;
3040   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3041   PetscValidType(mat,1);
3042   if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2);
3043   if (info) PetscValidPointer(info,3);
3044   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3045   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3046   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3047   if (!mat->ops->choleskyfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3048   MatCheckPreallocated(mat,1);
3049 
3050   ierr = PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
3051   ierr = (*mat->ops->choleskyfactor)(mat,perm,info);CHKERRQ(ierr);
3052   ierr = PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
3053   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
3054   PetscFunctionReturn(0);
3055 }
3056 
3057 #undef __FUNCT__
3058 #define __FUNCT__ "MatCholeskyFactorSymbolic"
3059 /*@C
3060    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
3061    of a symmetric matrix.
3062 
3063    Collective on Mat
3064 
3065    Input Parameters:
3066 +  fact - the factor matrix obtained with MatGetFactor()
3067 .  mat - the matrix
3068 .  perm - row and column permutations
3069 -  info - options for factorization, includes
3070 $          fill - expected fill as ratio of original fill.
3071 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3072 $                   Run with the option -info to determine an optimal value to use
3073 
3074    Notes:
3075    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
3076    MatCholeskyFactor() and MatCholeskyFactorNumeric().
3077 
3078    Most users should employ the simplified KSP interface for linear solvers
3079    instead of working directly with matrix algebra routines such as this.
3080    See, e.g., KSPCreate().
3081 
3082    Level: developer
3083 
3084    Concepts: matrices^Cholesky symbolic factorization
3085 
3086 .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
3087           MatGetOrdering()
3088 
3089     Developer Note: fortran interface is not autogenerated as the f90
3090     interface defintion cannot be generated correctly [due to MatFactorInfo]
3091 
3092 @*/
3093 PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
3094 {
3095   PetscErrorCode ierr;
3096 
3097   PetscFunctionBegin;
3098   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3099   PetscValidType(mat,1);
3100   if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2);
3101   if (info) PetscValidPointer(info,3);
3102   PetscValidPointer(fact,4);
3103   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3104   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3105   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3106   if (!(fact)->ops->choleskyfactorsymbolic) {
3107     const MatSolverPackage spackage;
3108     ierr = MatFactorGetSolverPackage(fact,&spackage);CHKERRQ(ierr);
3109     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage);
3110   }
3111   MatCheckPreallocated(mat,2);
3112 
3113   ierr = PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
3114   ierr = (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
3115   ierr = PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
3116   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3117   PetscFunctionReturn(0);
3118 }
3119 
3120 #undef __FUNCT__
3121 #define __FUNCT__ "MatCholeskyFactorNumeric"
3122 /*@C
3123    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
3124    of a symmetric matrix. Call this routine after first calling
3125    MatCholeskyFactorSymbolic().
3126 
3127    Collective on Mat
3128 
3129    Input Parameters:
3130 +  fact - the factor matrix obtained with MatGetFactor()
3131 .  mat - the initial matrix
3132 .  info - options for factorization
3133 -  fact - the symbolic factor of mat
3134 
3135 
3136    Notes:
3137    Most users should employ the simplified KSP interface for linear solvers
3138    instead of working directly with matrix algebra routines such as this.
3139    See, e.g., KSPCreate().
3140 
3141    Level: developer
3142 
3143    Concepts: matrices^Cholesky numeric factorization
3144 
3145 .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
3146 
3147     Developer Note: fortran interface is not autogenerated as the f90
3148     interface defintion cannot be generated correctly [due to MatFactorInfo]
3149 
3150 @*/
3151 PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3152 {
3153   PetscErrorCode ierr;
3154 
3155   PetscFunctionBegin;
3156   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3157   PetscValidType(mat,1);
3158   PetscValidPointer(fact,2);
3159   PetscValidHeaderSpecific(fact,MAT_CLASSID,2);
3160   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3161   if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name);
3162   if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) SETERRQ4(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dim %D should = %D %D should = %D",mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N);
3163   MatCheckPreallocated(mat,2);
3164 
3165   ierr = PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3166   ierr = (fact->ops->choleskyfactornumeric)(fact,mat,info);CHKERRQ(ierr);
3167   ierr = PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3168   ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr);
3169   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3170   PetscFunctionReturn(0);
3171 }
3172 
3173 /* ----------------------------------------------------------------*/
3174 #undef __FUNCT__
3175 #define __FUNCT__ "MatSolve"
3176 /*@
3177    MatSolve - Solves A x = b, given a factored matrix.
3178 
3179    Neighbor-wise Collective on Mat and Vec
3180 
3181    Input Parameters:
3182 +  mat - the factored matrix
3183 -  b - the right-hand-side vector
3184 
3185    Output Parameter:
3186 .  x - the result vector
3187 
3188    Notes:
3189    The vectors b and x cannot be the same.  I.e., one cannot
3190    call MatSolve(A,x,x).
3191 
3192    Notes:
3193    Most users should employ the simplified KSP interface for linear solvers
3194    instead of working directly with matrix algebra routines such as this.
3195    See, e.g., KSPCreate().
3196 
3197    Level: developer
3198 
3199    Concepts: matrices^triangular solves
3200 
3201 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
3202 @*/
3203 PetscErrorCode MatSolve(Mat mat,Vec b,Vec x)
3204 {
3205   PetscErrorCode ierr;
3206 
3207   PetscFunctionBegin;
3208   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3209   PetscValidType(mat,1);
3210   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3211   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3212   PetscCheckSameComm(mat,1,b,2);
3213   PetscCheckSameComm(mat,1,x,3);
3214   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3215   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3216   if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3217   if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3218   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3219   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3220   if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3221   MatCheckPreallocated(mat,1);
3222 
3223   ierr = PetscLogEventBegin(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
3224   if (mat->errortype) {
3225     ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->errortype);CHKERRQ(ierr);
3226     ierr = VecSetInf(x);CHKERRQ(ierr);
3227   } else {
3228     ierr = (*mat->ops->solve)(mat,b,x);CHKERRQ(ierr);
3229   }
3230   ierr = PetscLogEventEnd(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
3231   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3232   PetscFunctionReturn(0);
3233 }
3234 
3235 #undef __FUNCT__
3236 #define __FUNCT__ "MatMatSolve_Basic"
3237 PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X)
3238 {
3239   PetscErrorCode ierr;
3240   Vec            b,x;
3241   PetscInt       m,N,i;
3242   PetscScalar    *bb,*xx;
3243   PetscBool      flg;
3244 
3245   PetscFunctionBegin;
3246   ierr = PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr);
3247   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
3248   ierr = PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr);
3249   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");
3250 
3251   ierr = MatDenseGetArray(B,&bb);CHKERRQ(ierr);
3252   ierr = MatDenseGetArray(X,&xx);CHKERRQ(ierr);
3253   ierr = MatGetLocalSize(B,&m,NULL);CHKERRQ(ierr);  /* number local rows */
3254   ierr = MatGetSize(B,NULL,&N);CHKERRQ(ierr);       /* total columns in dense matrix */
3255   ierr = MatCreateVecs(A,&x,&b);CHKERRQ(ierr);
3256   for (i=0; i<N; i++) {
3257     ierr = VecPlaceArray(b,bb + i*m);CHKERRQ(ierr);
3258     ierr = VecPlaceArray(x,xx + i*m);CHKERRQ(ierr);
3259     ierr = MatSolve(A,b,x);CHKERRQ(ierr);
3260     ierr = VecResetArray(x);CHKERRQ(ierr);
3261     ierr = VecResetArray(b);CHKERRQ(ierr);
3262   }
3263   ierr = VecDestroy(&b);CHKERRQ(ierr);
3264   ierr = VecDestroy(&x);CHKERRQ(ierr);
3265   ierr = MatDenseRestoreArray(B,&bb);CHKERRQ(ierr);
3266   ierr = MatDenseRestoreArray(X,&xx);CHKERRQ(ierr);
3267   PetscFunctionReturn(0);
3268 }
3269 
3270 #undef __FUNCT__
3271 #define __FUNCT__ "MatMatSolve"
3272 /*@
3273    MatMatSolve - Solves A X = B, given a factored matrix.
3274 
3275    Neighbor-wise Collective on Mat
3276 
3277    Input Parameters:
3278 +  A - the factored matrix
3279 -  B - the right-hand-side matrix  (dense matrix)
3280 
3281    Output Parameter:
3282 .  X - the result matrix (dense matrix)
3283 
3284    Notes:
3285    The matrices b and x cannot be the same.  I.e., one cannot
3286    call MatMatSolve(A,x,x).
3287 
3288    Notes:
3289    Most users should usually employ the simplified KSP interface for linear solvers
3290    instead of working directly with matrix algebra routines such as this.
3291    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3292    at a time.
3293 
3294    When using SuperLU_Dist as a parallel solver PETSc will use the SuperLU_Dist functionality to solve multiple right hand sides simultaneously. For MUMPS
3295    it calls a separate solve for each right hand side since MUMPS does not yet support distributed right hand sides.
3296 
3297    Since the resulting matrix X must always be dense we do not support sparse representation of the matrix B.
3298 
3299    Level: developer
3300 
3301    Concepts: matrices^triangular solves
3302 
3303 .seealso: MatMatSolveAdd(), MatMatSolveTranspose(), MatMatSolveTransposeAdd(), MatLUFactor(), MatCholeskyFactor()
3304 @*/
3305 PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X)
3306 {
3307   PetscErrorCode ierr;
3308 
3309   PetscFunctionBegin;
3310   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3311   PetscValidType(A,1);
3312   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3313   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3314   PetscCheckSameComm(A,1,B,2);
3315   PetscCheckSameComm(A,1,X,3);
3316   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3317   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3318   if (A->cmap->N != X->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %D %D",A->cmap->N,X->rmap->N);
3319   if (A->rmap->N != B->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %D %D",A->rmap->N,B->rmap->N);
3320   if (A->rmap->n != B->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat A,Mat B: local dim %D %D",A->rmap->n,B->rmap->n);
3321   if (X->cmap->N < B->cmap->N) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as rhs matrix");
3322   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3323   MatCheckPreallocated(A,1);
3324 
3325   ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3326   if (!A->ops->matsolve) {
3327     ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name);CHKERRQ(ierr);
3328     ierr = MatMatSolve_Basic(A,B,X);CHKERRQ(ierr);
3329   } else {
3330     ierr = (*A->ops->matsolve)(A,B,X);CHKERRQ(ierr);
3331   }
3332   ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3333   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3334   PetscFunctionReturn(0);
3335 }
3336 
3337 
3338 #undef __FUNCT__
3339 #define __FUNCT__ "MatForwardSolve"
3340 /*@
3341    MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or
3342                             U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U,
3343 
3344    Neighbor-wise Collective on Mat and Vec
3345 
3346    Input Parameters:
3347 +  mat - the factored matrix
3348 -  b - the right-hand-side vector
3349 
3350    Output Parameter:
3351 .  x - the result vector
3352 
3353    Notes:
3354    MatSolve() should be used for most applications, as it performs
3355    a forward solve followed by a backward solve.
3356 
3357    The vectors b and x cannot be the same,  i.e., one cannot
3358    call MatForwardSolve(A,x,x).
3359 
3360    For matrix in seqsbaij format with block size larger than 1,
3361    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3362    MatForwardSolve() solves U^T*D y = b, and
3363    MatBackwardSolve() solves U x = y.
3364    Thus they do not provide a symmetric preconditioner.
3365 
3366    Most users should employ the simplified KSP interface for linear solvers
3367    instead of working directly with matrix algebra routines such as this.
3368    See, e.g., KSPCreate().
3369 
3370    Level: developer
3371 
3372    Concepts: matrices^forward solves
3373 
3374 .seealso: MatSolve(), MatBackwardSolve()
3375 @*/
3376 PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x)
3377 {
3378   PetscErrorCode ierr;
3379 
3380   PetscFunctionBegin;
3381   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3382   PetscValidType(mat,1);
3383   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3384   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3385   PetscCheckSameComm(mat,1,b,2);
3386   PetscCheckSameComm(mat,1,x,3);
3387   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3388   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3389   if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3390   if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3391   if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3392   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3393   MatCheckPreallocated(mat,1);
3394   ierr = PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
3395   ierr = (*mat->ops->forwardsolve)(mat,b,x);CHKERRQ(ierr);
3396   ierr = PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
3397   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3398   PetscFunctionReturn(0);
3399 }
3400 
3401 #undef __FUNCT__
3402 #define __FUNCT__ "MatBackwardSolve"
3403 /*@
3404    MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
3405                              D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U,
3406 
3407    Neighbor-wise Collective on Mat and Vec
3408 
3409    Input Parameters:
3410 +  mat - the factored matrix
3411 -  b - the right-hand-side vector
3412 
3413    Output Parameter:
3414 .  x - the result vector
3415 
3416    Notes:
3417    MatSolve() should be used for most applications, as it performs
3418    a forward solve followed by a backward solve.
3419 
3420    The vectors b and x cannot be the same.  I.e., one cannot
3421    call MatBackwardSolve(A,x,x).
3422 
3423    For matrix in seqsbaij format with block size larger than 1,
3424    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3425    MatForwardSolve() solves U^T*D y = b, and
3426    MatBackwardSolve() solves U x = y.
3427    Thus they do not provide a symmetric preconditioner.
3428 
3429    Most users should employ the simplified KSP interface for linear solvers
3430    instead of working directly with matrix algebra routines such as this.
3431    See, e.g., KSPCreate().
3432 
3433    Level: developer
3434 
3435    Concepts: matrices^backward solves
3436 
3437 .seealso: MatSolve(), MatForwardSolve()
3438 @*/
3439 PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x)
3440 {
3441   PetscErrorCode ierr;
3442 
3443   PetscFunctionBegin;
3444   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3445   PetscValidType(mat,1);
3446   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3447   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3448   PetscCheckSameComm(mat,1,b,2);
3449   PetscCheckSameComm(mat,1,x,3);
3450   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3451   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3452   if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3453   if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3454   if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3455   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3456   MatCheckPreallocated(mat,1);
3457 
3458   ierr = PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
3459   ierr = (*mat->ops->backwardsolve)(mat,b,x);CHKERRQ(ierr);
3460   ierr = PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
3461   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3462   PetscFunctionReturn(0);
3463 }
3464 
3465 #undef __FUNCT__
3466 #define __FUNCT__ "MatSolveAdd"
3467 /*@
3468    MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
3469 
3470    Neighbor-wise Collective on Mat and Vec
3471 
3472    Input Parameters:
3473 +  mat - the factored matrix
3474 .  b - the right-hand-side vector
3475 -  y - the vector to be added to
3476 
3477    Output Parameter:
3478 .  x - the result vector
3479 
3480    Notes:
3481    The vectors b and x cannot be the same.  I.e., one cannot
3482    call MatSolveAdd(A,x,y,x).
3483 
3484    Most users should employ the simplified KSP interface for linear solvers
3485    instead of working directly with matrix algebra routines such as this.
3486    See, e.g., KSPCreate().
3487 
3488    Level: developer
3489 
3490    Concepts: matrices^triangular solves
3491 
3492 .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3493 @*/
3494 PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3495 {
3496   PetscScalar    one = 1.0;
3497   Vec            tmp;
3498   PetscErrorCode ierr;
3499 
3500   PetscFunctionBegin;
3501   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3502   PetscValidType(mat,1);
3503   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3504   PetscValidHeaderSpecific(b,VEC_CLASSID,3);
3505   PetscValidHeaderSpecific(x,VEC_CLASSID,4);
3506   PetscCheckSameComm(mat,1,b,2);
3507   PetscCheckSameComm(mat,1,y,2);
3508   PetscCheckSameComm(mat,1,x,3);
3509   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3510   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3511   if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3512   if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3513   if (mat->rmap->N != y->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
3514   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3515   if (x->map->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %D %D",x->map->n,y->map->n);
3516   MatCheckPreallocated(mat,1);
3517 
3518   ierr = PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
3519   if (mat->ops->solveadd) {
3520     ierr = (*mat->ops->solveadd)(mat,b,y,x);CHKERRQ(ierr);
3521   } else {
3522     /* do the solve then the add manually */
3523     if (x != y) {
3524       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
3525       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
3526     } else {
3527       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
3528       ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr);
3529       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
3530       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
3531       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
3532       ierr = VecDestroy(&tmp);CHKERRQ(ierr);
3533     }
3534   }
3535   ierr = PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
3536   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3537   PetscFunctionReturn(0);
3538 }
3539 
3540 #undef __FUNCT__
3541 #define __FUNCT__ "MatSolveTranspose"
3542 /*@
3543    MatSolveTranspose - Solves A' x = b, given a factored matrix.
3544 
3545    Neighbor-wise Collective on Mat and Vec
3546 
3547    Input Parameters:
3548 +  mat - the factored matrix
3549 -  b - the right-hand-side vector
3550 
3551    Output Parameter:
3552 .  x - the result vector
3553 
3554    Notes:
3555    The vectors b and x cannot be the same.  I.e., one cannot
3556    call MatSolveTranspose(A,x,x).
3557 
3558    Most users should employ the simplified KSP interface for linear solvers
3559    instead of working directly with matrix algebra routines such as this.
3560    See, e.g., KSPCreate().
3561 
3562    Level: developer
3563 
3564    Concepts: matrices^triangular solves
3565 
3566 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
3567 @*/
3568 PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x)
3569 {
3570   PetscErrorCode ierr;
3571 
3572   PetscFunctionBegin;
3573   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3574   PetscValidType(mat,1);
3575   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3576   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3577   PetscCheckSameComm(mat,1,b,2);
3578   PetscCheckSameComm(mat,1,x,3);
3579   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3580   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3581   if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3582   if (mat->rmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
3583   if (mat->cmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->cmap->N,b->map->N);
3584   MatCheckPreallocated(mat,1);
3585   ierr = PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
3586   if (mat->errortype) {
3587     ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->errortype);CHKERRQ(ierr);
3588     ierr = VecSetInf(x);CHKERRQ(ierr);
3589   } else {
3590     ierr = (*mat->ops->solvetranspose)(mat,b,x);CHKERRQ(ierr);
3591   }
3592   ierr = PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
3593   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3594   PetscFunctionReturn(0);
3595 }
3596 
3597 #undef __FUNCT__
3598 #define __FUNCT__ "MatSolveTransposeAdd"
3599 /*@
3600    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
3601                       factored matrix.
3602 
3603    Neighbor-wise Collective on Mat and Vec
3604 
3605    Input Parameters:
3606 +  mat - the factored matrix
3607 .  b - the right-hand-side vector
3608 -  y - the vector to be added to
3609 
3610    Output Parameter:
3611 .  x - the result vector
3612 
3613    Notes:
3614    The vectors b and x cannot be the same.  I.e., one cannot
3615    call MatSolveTransposeAdd(A,x,y,x).
3616 
3617    Most users should employ the simplified KSP interface for linear solvers
3618    instead of working directly with matrix algebra routines such as this.
3619    See, e.g., KSPCreate().
3620 
3621    Level: developer
3622 
3623    Concepts: matrices^triangular solves
3624 
3625 .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3626 @*/
3627 PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3628 {
3629   PetscScalar    one = 1.0;
3630   PetscErrorCode ierr;
3631   Vec            tmp;
3632 
3633   PetscFunctionBegin;
3634   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3635   PetscValidType(mat,1);
3636   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3637   PetscValidHeaderSpecific(b,VEC_CLASSID,3);
3638   PetscValidHeaderSpecific(x,VEC_CLASSID,4);
3639   PetscCheckSameComm(mat,1,b,2);
3640   PetscCheckSameComm(mat,1,y,3);
3641   PetscCheckSameComm(mat,1,x,4);
3642   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3643   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3644   if (mat->rmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
3645   if (mat->cmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->cmap->N,b->map->N);
3646   if (mat->cmap->N != y->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N);
3647   if (x->map->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %D %D",x->map->n,y->map->n);
3648   MatCheckPreallocated(mat,1);
3649 
3650   ierr = PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
3651   if (mat->ops->solvetransposeadd) {
3652     if (mat->errortype) {
3653       ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->errortype);CHKERRQ(ierr);
3654       ierr = VecSetInf(x);CHKERRQ(ierr);
3655     } else {
3656       ierr = (*mat->ops->solvetransposeadd)(mat,b,y,x);CHKERRQ(ierr);
3657     }
3658   } else {
3659     /* do the solve then the add manually */
3660     if (x != y) {
3661       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
3662       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
3663     } else {
3664       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
3665       ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr);
3666       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
3667       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
3668       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
3669       ierr = VecDestroy(&tmp);CHKERRQ(ierr);
3670     }
3671   }
3672   ierr = PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
3673   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3674   PetscFunctionReturn(0);
3675 }
3676 /* ----------------------------------------------------------------*/
3677 
3678 #undef __FUNCT__
3679 #define __FUNCT__ "MatSOR"
3680 /*@
3681    MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps.
3682 
3683    Neighbor-wise Collective on Mat and Vec
3684 
3685    Input Parameters:
3686 +  mat - the matrix
3687 .  b - the right hand side
3688 .  omega - the relaxation factor
3689 .  flag - flag indicating the type of SOR (see below)
3690 .  shift -  diagonal shift
3691 .  its - the number of iterations
3692 -  lits - the number of local iterations
3693 
3694    Output Parameters:
3695 .  x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess)
3696 
3697    SOR Flags:
3698 .     SOR_FORWARD_SWEEP - forward SOR
3699 .     SOR_BACKWARD_SWEEP - backward SOR
3700 .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3701 .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR
3702 .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
3703 .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3704 .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
3705          upper/lower triangular part of matrix to
3706          vector (with omega)
3707 .     SOR_ZERO_INITIAL_GUESS - zero initial guess
3708 
3709    Notes:
3710    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3711    SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3712    on each processor.
3713 
3714    Application programmers will not generally use MatSOR() directly,
3715    but instead will employ the KSP/PC interface.
3716 
3717    Notes: for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing
3718 
3719    Notes for Advanced Users:
3720    The flags are implemented as bitwise inclusive or operations.
3721    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3722    to specify a zero initial guess for SSOR.
3723 
3724    Most users should employ the simplified KSP interface for linear solvers
3725    instead of working directly with matrix algebra routines such as this.
3726    See, e.g., KSPCreate().
3727 
3728    Vectors x and b CANNOT be the same
3729 
3730    Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes
3731 
3732    Level: developer
3733 
3734    Concepts: matrices^relaxation
3735    Concepts: matrices^SOR
3736    Concepts: matrices^Gauss-Seidel
3737 
3738 @*/
3739 PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3740 {
3741   PetscErrorCode ierr;
3742 
3743   PetscFunctionBegin;
3744   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3745   PetscValidType(mat,1);
3746   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3747   PetscValidHeaderSpecific(x,VEC_CLASSID,8);
3748   PetscCheckSameComm(mat,1,b,2);
3749   PetscCheckSameComm(mat,1,x,8);
3750   if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3751   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3752   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3753   if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3754   if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3755   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3756   if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
3757   if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
3758   if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");
3759 
3760   MatCheckPreallocated(mat,1);
3761   ierr = PetscLogEventBegin(MAT_SOR,mat,b,x,0);CHKERRQ(ierr);
3762   ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr);
3763   ierr = PetscLogEventEnd(MAT_SOR,mat,b,x,0);CHKERRQ(ierr);
3764   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3765   PetscFunctionReturn(0);
3766 }
3767 
3768 #undef __FUNCT__
3769 #define __FUNCT__ "MatCopy_Basic"
3770 /*
3771       Default matrix copy routine.
3772 */
3773 PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
3774 {
3775   PetscErrorCode    ierr;
3776   PetscInt          i,rstart = 0,rend = 0,nz;
3777   const PetscInt    *cwork;
3778   const PetscScalar *vwork;
3779 
3780   PetscFunctionBegin;
3781   if (B->assembled) {
3782     ierr = MatZeroEntries(B);CHKERRQ(ierr);
3783   }
3784   ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
3785   for (i=rstart; i<rend; i++) {
3786     ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
3787     ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);CHKERRQ(ierr);
3788     ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
3789   }
3790   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3791   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3792   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
3793   PetscFunctionReturn(0);
3794 }
3795 
3796 #undef __FUNCT__
3797 #define __FUNCT__ "MatCopy"
3798 /*@
3799    MatCopy - Copys a matrix to another matrix.
3800 
3801    Collective on Mat
3802 
3803    Input Parameters:
3804 +  A - the matrix
3805 -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
3806 
3807    Output Parameter:
3808 .  B - where the copy is put
3809 
3810    Notes:
3811    If you use SAME_NONZERO_PATTERN then the two matrices had better have the
3812    same nonzero pattern or the routine will crash.
3813 
3814    MatCopy() copies the matrix entries of a matrix to another existing
3815    matrix (after first zeroing the second matrix).  A related routine is
3816    MatConvert(), which first creates a new matrix and then copies the data.
3817 
3818    Level: intermediate
3819 
3820    Concepts: matrices^copying
3821 
3822 .seealso: MatConvert(), MatDuplicate()
3823 
3824 @*/
3825 PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str)
3826 {
3827   PetscErrorCode ierr;
3828   PetscInt       i;
3829 
3830   PetscFunctionBegin;
3831   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3832   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3833   PetscValidType(A,1);
3834   PetscValidType(B,2);
3835   PetscCheckSameComm(A,1,B,2);
3836   MatCheckPreallocated(B,2);
3837   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3838   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3839   if (A->rmap->N != B->rmap->N || A->cmap->N != B->cmap->N) SETERRQ4(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim (%D,%D) (%D,%D)",A->rmap->N,B->rmap->N,A->cmap->N,B->cmap->N);
3840   MatCheckPreallocated(A,1);
3841 
3842   ierr = PetscLogEventBegin(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
3843   if (A->ops->copy) {
3844     ierr = (*A->ops->copy)(A,B,str);CHKERRQ(ierr);
3845   } else { /* generic conversion */
3846     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
3847   }
3848 
3849   B->stencil.dim = A->stencil.dim;
3850   B->stencil.noc = A->stencil.noc;
3851   for (i=0; i<=A->stencil.dim; i++) {
3852     B->stencil.dims[i]   = A->stencil.dims[i];
3853     B->stencil.starts[i] = A->stencil.starts[i];
3854   }
3855 
3856   ierr = PetscLogEventEnd(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
3857   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
3858   PetscFunctionReturn(0);
3859 }
3860 
3861 #undef __FUNCT__
3862 #define __FUNCT__ "MatConvert"
3863 /*@C
3864    MatConvert - Converts a matrix to another matrix, either of the same
3865    or different type.
3866 
3867    Collective on Mat
3868 
3869    Input Parameters:
3870 +  mat - the matrix
3871 .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
3872    same type as the original matrix.
3873 -  reuse - denotes if the destination matrix is to be created or reused.
3874    Use MAT_INPLACE_MATRIX for inplace conversion, otherwise use
3875    MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX.
3876 
3877    Output Parameter:
3878 .  M - pointer to place new matrix
3879 
3880    Notes:
3881    MatConvert() first creates a new matrix and then copies the data from
3882    the first matrix.  A related routine is MatCopy(), which copies the matrix
3883    entries of one matrix to another already existing matrix context.
3884 
3885    Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
3886    the MPI communicator of the generated matrix is always the same as the communicator
3887    of the input matrix.
3888 
3889    Level: intermediate
3890 
3891    Concepts: matrices^converting between storage formats
3892 
3893 .seealso: MatCopy(), MatDuplicate()
3894 @*/
3895 PetscErrorCode MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M)
3896 {
3897   PetscErrorCode ierr;
3898   PetscBool      sametype,issame,flg;
3899   char           convname[256],mtype[256];
3900   Mat            B;
3901 
3902   PetscFunctionBegin;
3903   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3904   PetscValidType(mat,1);
3905   PetscValidPointer(M,3);
3906   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3907   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3908   MatCheckPreallocated(mat,1);
3909   ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr);
3910 
3911   ierr = PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);CHKERRQ(ierr);
3912   if (flg) {
3913     newtype = mtype;
3914   }
3915   ierr = PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);CHKERRQ(ierr);
3916   ierr = PetscStrcmp(newtype,"same",&issame);CHKERRQ(ierr);
3917   if ((reuse == MAT_INPLACE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix");
3918 
3919   if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) PetscFunctionReturn(0);
3920 
3921   if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
3922     ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
3923   } else {
3924     PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL;
3925     const char     *prefix[3] = {"seq","mpi",""};
3926     PetscInt       i;
3927     /*
3928        Order of precedence:
3929        1) See if a specialized converter is known to the current matrix.
3930        2) See if a specialized converter is known to the desired matrix class.
3931        3) See if a good general converter is registered for the desired class
3932           (as of 6/27/03 only MATMPIADJ falls into this category).
3933        4) See if a good general converter is known for the current matrix.
3934        5) Use a really basic converter.
3935     */
3936 
3937     /* 1) See if a specialized converter is known to the current matrix and the desired class */
3938     for (i=0; i<3; i++) {
3939       ierr = PetscStrcpy(convname,"MatConvert_");CHKERRQ(ierr);
3940       ierr = PetscStrcat(convname,((PetscObject)mat)->type_name);CHKERRQ(ierr);
3941       ierr = PetscStrcat(convname,"_");CHKERRQ(ierr);
3942       ierr = PetscStrcat(convname,prefix[i]);CHKERRQ(ierr);
3943       ierr = PetscStrcat(convname,issame ? ((PetscObject)mat)->type_name : newtype);CHKERRQ(ierr);
3944       ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
3945       ierr = PetscObjectQueryFunction((PetscObject)mat,convname,&conv);CHKERRQ(ierr);
3946       if (conv) goto foundconv;
3947     }
3948 
3949     /* 2)  See if a specialized converter is known to the desired matrix class. */
3950     ierr = MatCreate(PetscObjectComm((PetscObject)mat),&B);CHKERRQ(ierr);
3951     ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);CHKERRQ(ierr);
3952     ierr = MatSetType(B,newtype);CHKERRQ(ierr);
3953     for (i=0; i<3; i++) {
3954       ierr = PetscStrcpy(convname,"MatConvert_");CHKERRQ(ierr);
3955       ierr = PetscStrcat(convname,((PetscObject)mat)->type_name);CHKERRQ(ierr);
3956       ierr = PetscStrcat(convname,"_");CHKERRQ(ierr);
3957       ierr = PetscStrcat(convname,prefix[i]);CHKERRQ(ierr);
3958       ierr = PetscStrcat(convname,newtype);CHKERRQ(ierr);
3959       ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
3960       ierr = PetscObjectQueryFunction((PetscObject)B,convname,&conv);CHKERRQ(ierr);
3961       if (conv) {
3962         ierr = MatDestroy(&B);CHKERRQ(ierr);
3963         goto foundconv;
3964       }
3965     }
3966 
3967     /* 3) See if a good general converter is registered for the desired class */
3968     conv = B->ops->convertfrom;
3969     ierr = MatDestroy(&B);CHKERRQ(ierr);
3970     if (conv) goto foundconv;
3971 
3972     /* 4) See if a good general converter is known for the current matrix */
3973     if (mat->ops->convert) {
3974       conv = mat->ops->convert;
3975     }
3976     if (conv) goto foundconv;
3977 
3978     /* 5) Use a really basic converter. */
3979     conv = MatConvert_Basic;
3980 
3981 foundconv:
3982     ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
3983     ierr = (*conv)(mat,newtype,reuse,M);CHKERRQ(ierr);
3984     ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
3985   }
3986   ierr = PetscObjectStateIncrease((PetscObject)*M);CHKERRQ(ierr);
3987 
3988   /* Copy Mat options */
3989   if (mat->symmetric) {ierr = MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);}
3990   if (mat->hermitian) {ierr = MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);}
3991   PetscFunctionReturn(0);
3992 }
3993 
3994 #undef __FUNCT__
3995 #define __FUNCT__ "MatFactorGetSolverPackage"
3996 /*@C
3997    MatFactorGetSolverPackage - Returns name of the package providing the factorization routines
3998 
3999    Not Collective
4000 
4001    Input Parameter:
4002 .  mat - the matrix, must be a factored matrix
4003 
4004    Output Parameter:
4005 .   type - the string name of the package (do not free this string)
4006 
4007    Notes:
4008       In Fortran you pass in a empty string and the package name will be copied into it.
4009     (Make sure the string is long enough)
4010 
4011    Level: intermediate
4012 
4013 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
4014 @*/
4015 PetscErrorCode MatFactorGetSolverPackage(Mat mat, const MatSolverPackage *type)
4016 {
4017   PetscErrorCode ierr, (*conv)(Mat,const MatSolverPackage*);
4018 
4019   PetscFunctionBegin;
4020   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4021   PetscValidType(mat,1);
4022   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
4023   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverPackage_C",&conv);CHKERRQ(ierr);
4024   if (!conv) {
4025     *type = MATSOLVERPETSC;
4026   } else {
4027     ierr = (*conv)(mat,type);CHKERRQ(ierr);
4028   }
4029   PetscFunctionReturn(0);
4030 }
4031 
4032 typedef struct _MatSolverPackageForSpecifcType* MatSolverPackageForSpecifcType;
4033 struct _MatSolverPackageForSpecifcType {
4034   MatType                        mtype;
4035   PetscErrorCode                 (*getfactor[4])(Mat,MatFactorType,Mat*);
4036   MatSolverPackageForSpecifcType next;
4037 };
4038 
4039 typedef struct _MatSolverPackageHolder* MatSolverPackageHolder;
4040 struct _MatSolverPackageHolder {
4041   char                           *name;
4042   MatSolverPackageForSpecifcType handlers;
4043   MatSolverPackageHolder         next;
4044 };
4045 
4046 static MatSolverPackageHolder MatSolverPackageHolders = NULL;
4047 
4048 #undef __FUNCT__
4049 #define __FUNCT__ "MatSolverPackageRegister"
4050 /*@C
4051    MatSolvePackageRegister - Registers a MatSolverPackage that works for a particular matrix type
4052 
4053    Input Parameters:
4054 +    package - name of the package, for example petsc or superlu
4055 .    mtype - the matrix type that works with this package
4056 .    ftype - the type of factorization supported by the package
4057 -    getfactor - routine that will create the factored matrix ready to be used
4058 
4059     Level: intermediate
4060 
4061 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4062 @*/
4063 PetscErrorCode MatSolverPackageRegister(const MatSolverPackage package,const MatType mtype,MatFactorType ftype,PetscErrorCode (*getfactor)(Mat,MatFactorType,Mat*))
4064 {
4065   PetscErrorCode                 ierr;
4066   MatSolverPackageHolder         next = MatSolverPackageHolders,prev;
4067   PetscBool                      flg;
4068   MatSolverPackageForSpecifcType inext,iprev = NULL;
4069 
4070   PetscFunctionBegin;
4071   if (!next) {
4072     ierr = PetscNew(&MatSolverPackageHolders);CHKERRQ(ierr);
4073     ierr = PetscStrallocpy(package,&MatSolverPackageHolders->name);CHKERRQ(ierr);
4074     ierr = PetscNew(&MatSolverPackageHolders->handlers);CHKERRQ(ierr);
4075     ierr = PetscStrallocpy(mtype,(char **)&MatSolverPackageHolders->handlers->mtype);CHKERRQ(ierr);
4076     MatSolverPackageHolders->handlers->getfactor[(int)ftype-1] = getfactor;
4077     PetscFunctionReturn(0);
4078   }
4079   while (next) {
4080     ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr);
4081     if (flg) {
4082       if (!next->handlers) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverPackageHolder is missing handlers");
4083       inext = next->handlers;
4084       while (inext) {
4085         ierr = PetscStrcasecmp(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4086         if (flg) {
4087           inext->getfactor[(int)ftype-1] = getfactor;
4088           PetscFunctionReturn(0);
4089         }
4090         iprev = inext;
4091         inext = inext->next;
4092       }
4093       ierr = PetscNew(&iprev->next);CHKERRQ(ierr);
4094       ierr = PetscStrallocpy(mtype,(char **)&iprev->next->mtype);CHKERRQ(ierr);
4095       iprev->next->getfactor[(int)ftype-1] = getfactor;
4096       PetscFunctionReturn(0);
4097     }
4098     prev = next;
4099     next = next->next;
4100   }
4101   ierr = PetscNew(&prev->next);CHKERRQ(ierr);
4102   ierr = PetscStrallocpy(package,&prev->next->name);CHKERRQ(ierr);
4103   ierr = PetscNew(&prev->next->handlers);CHKERRQ(ierr);
4104   ierr = PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);CHKERRQ(ierr);
4105   prev->next->handlers->getfactor[(int)ftype-1] = getfactor;
4106   PetscFunctionReturn(0);
4107 }
4108 
4109 #undef __FUNCT__
4110 #define __FUNCT__ "MatSolverPackageGet"
4111 /*@C
4112    MatSolvePackageGet - Get's the function that creates the factor matrix if it exist
4113 
4114    Input Parameters:
4115 +    package - name of the package, for example petsc or superlu
4116 .    ftype - the type of factorization supported by the package
4117 -    mtype - the matrix type that works with this package
4118 
4119    Output Parameters:
4120 +   foundpackage - PETSC_TRUE if the package was registered
4121 .   foundmtype - PETSC_TRUE if the package supports the requested mtype
4122 -   getfactor - routine that will create the factored matrix ready to be used or NULL if not found
4123 
4124     Level: intermediate
4125 
4126 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4127 @*/
4128 PetscErrorCode MatSolverPackageGet(const MatSolverPackage package,const MatType mtype,MatFactorType ftype,PetscBool *foundpackage,PetscBool *foundmtype,PetscErrorCode (**getfactor)(Mat,MatFactorType,Mat*))
4129 {
4130   PetscErrorCode                 ierr;
4131   MatSolverPackageHolder         next = MatSolverPackageHolders;
4132   PetscBool                      flg;
4133   MatSolverPackageForSpecifcType inext;
4134 
4135   PetscFunctionBegin;
4136   if (foundpackage) *foundpackage = PETSC_FALSE;
4137   if (foundmtype)   *foundmtype   = PETSC_FALSE;
4138   if (getfactor)    *getfactor    = NULL;
4139 
4140   if (package) {
4141     while (next) {
4142       ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr);
4143       if (flg) {
4144         if (foundpackage) *foundpackage = PETSC_TRUE;
4145         inext = next->handlers;
4146         while (inext) {
4147           ierr = PetscStrcasecmp(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4148           if (flg) {
4149             if (foundmtype) *foundmtype = PETSC_TRUE;
4150             if (getfactor)  *getfactor  = inext->getfactor[(int)ftype-1];
4151             PetscFunctionReturn(0);
4152           }
4153           inext = inext->next;
4154         }
4155       }
4156       next = next->next;
4157     }
4158   } else {
4159     while (next) {
4160       inext = next->handlers;
4161       while (inext) {
4162         ierr = PetscStrcasecmp(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4163         if (flg && inext->getfactor[(int)ftype-1]) {
4164           if (foundpackage) *foundpackage = PETSC_TRUE;
4165           if (foundmtype)   *foundmtype   = PETSC_TRUE;
4166           if (getfactor)    *getfactor    = inext->getfactor[(int)ftype-1];
4167           PetscFunctionReturn(0);
4168         }
4169         inext = inext->next;
4170       }
4171       next = next->next;
4172     }
4173   }
4174   PetscFunctionReturn(0);
4175 }
4176 
4177 #undef __FUNCT__
4178 #define __FUNCT__ "MatSolverPackageDestroy"
4179 PetscErrorCode MatSolverPackageDestroy(void)
4180 {
4181   PetscErrorCode                 ierr;
4182   MatSolverPackageHolder         next = MatSolverPackageHolders,prev;
4183   MatSolverPackageForSpecifcType inext,iprev;
4184 
4185   PetscFunctionBegin;
4186   while (next) {
4187     ierr = PetscFree(next->name);CHKERRQ(ierr);
4188     inext = next->handlers;
4189     while (inext) {
4190       ierr = PetscFree(inext->mtype);CHKERRQ(ierr);
4191       iprev = inext;
4192       inext = inext->next;
4193       ierr = PetscFree(iprev);CHKERRQ(ierr);
4194     }
4195     prev = next;
4196     next = next->next;
4197     ierr = PetscFree(prev);CHKERRQ(ierr);
4198   }
4199   MatSolverPackageHolders = NULL;
4200   PetscFunctionReturn(0);
4201 }
4202 
4203 #undef __FUNCT__
4204 #define __FUNCT__ "MatGetFactor"
4205 /*@C
4206    MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic()
4207 
4208    Collective on Mat
4209 
4210    Input Parameters:
4211 +  mat - the matrix
4212 .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4213 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4214 
4215    Output Parameters:
4216 .  f - the factor matrix used with MatXXFactorSymbolic() calls
4217 
4218    Notes:
4219       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4220      such as pastix, superlu, mumps etc.
4221 
4222       PETSc must have been ./configure to use the external solver, using the option --download-package
4223 
4224    Level: intermediate
4225 
4226 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4227 @*/
4228 PetscErrorCode MatGetFactor(Mat mat, const MatSolverPackage type,MatFactorType ftype,Mat *f)
4229 {
4230   PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
4231   PetscBool      foundpackage,foundmtype;
4232 
4233   PetscFunctionBegin;
4234   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4235   PetscValidType(mat,1);
4236 
4237   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4238   MatCheckPreallocated(mat,1);
4239 
4240   ierr = MatSolverPackageGet(type,((PetscObject)mat)->type_name,ftype,&foundpackage,&foundmtype,&conv);CHKERRQ(ierr);
4241   if (!foundpackage) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver package %s. Perhaps you must ./configure with --download-%s",type,type);
4242   if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverPackage %s does not support matrix type %s",type,((PetscObject)mat)->type_name);
4243   if (!conv) SETERRQ3(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverPackage %s does not support factorization type %s for  matrix type %s",type,MatFactorTypes[ftype],((PetscObject)mat)->type_name);
4244 
4245   ierr = (*conv)(mat,ftype,f);CHKERRQ(ierr);
4246   PetscFunctionReturn(0);
4247 }
4248 
4249 #undef __FUNCT__
4250 #define __FUNCT__ "MatGetFactorAvailable"
4251 /*@C
4252    MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type
4253 
4254    Not Collective
4255 
4256    Input Parameters:
4257 +  mat - the matrix
4258 .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4259 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4260 
4261    Output Parameter:
4262 .    flg - PETSC_TRUE if the factorization is available
4263 
4264    Notes:
4265       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4266      such as pastix, superlu, mumps etc.
4267 
4268       PETSc must have been ./configure to use the external solver, using the option --download-package
4269 
4270    Level: intermediate
4271 
4272 .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
4273 @*/
4274 PetscErrorCode MatGetFactorAvailable(Mat mat, const MatSolverPackage type,MatFactorType ftype,PetscBool  *flg)
4275 {
4276   PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*);
4277 
4278   PetscFunctionBegin;
4279   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4280   PetscValidType(mat,1);
4281 
4282   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4283   MatCheckPreallocated(mat,1);
4284 
4285   *flg = PETSC_FALSE;
4286   ierr = MatSolverPackageGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);CHKERRQ(ierr);
4287   if (gconv) {
4288     *flg = PETSC_TRUE;
4289   }
4290   PetscFunctionReturn(0);
4291 }
4292 
4293 #include <petscdmtypes.h>
4294 
4295 #undef __FUNCT__
4296 #define __FUNCT__ "MatDuplicate"
4297 /*@
4298    MatDuplicate - Duplicates a matrix including the non-zero structure.
4299 
4300    Collective on Mat
4301 
4302    Input Parameters:
4303 +  mat - the matrix
4304 -  op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy the numerical values in the matrix
4305         MAT_SHARE_NONZERO_PATTERN to share the nonzero patterns with the previous matrix and not copy them.
4306 
4307    Output Parameter:
4308 .  M - pointer to place new matrix
4309 
4310    Level: intermediate
4311 
4312    Concepts: matrices^duplicating
4313 
4314     Notes: You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN.
4315 
4316 .seealso: MatCopy(), MatConvert()
4317 @*/
4318 PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4319 {
4320   PetscErrorCode ierr;
4321   Mat            B;
4322   PetscInt       i;
4323   DM             dm;
4324 
4325   PetscFunctionBegin;
4326   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4327   PetscValidType(mat,1);
4328   PetscValidPointer(M,3);
4329   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4330   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4331   MatCheckPreallocated(mat,1);
4332 
4333   *M = 0;
4334   if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type");
4335   ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4336   ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr);
4337   B    = *M;
4338 
4339   B->stencil.dim = mat->stencil.dim;
4340   B->stencil.noc = mat->stencil.noc;
4341   for (i=0; i<=mat->stencil.dim; i++) {
4342     B->stencil.dims[i]   = mat->stencil.dims[i];
4343     B->stencil.starts[i] = mat->stencil.starts[i];
4344   }
4345 
4346   B->nooffproczerorows = mat->nooffproczerorows;
4347   B->nooffprocentries  = mat->nooffprocentries;
4348 
4349   ierr = PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);CHKERRQ(ierr);
4350   if (dm) {
4351     ierr = PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr);
4352   }
4353   ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4354   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
4355   PetscFunctionReturn(0);
4356 }
4357 
4358 #undef __FUNCT__
4359 #define __FUNCT__ "MatGetDiagonal"
4360 /*@
4361    MatGetDiagonal - Gets the diagonal of a matrix.
4362 
4363    Logically Collective on Mat and Vec
4364 
4365    Input Parameters:
4366 +  mat - the matrix
4367 -  v - the vector for storing the diagonal
4368 
4369    Output Parameter:
4370 .  v - the diagonal of the matrix
4371 
4372    Level: intermediate
4373 
4374    Note:
4375    Currently only correct in parallel for square matrices.
4376 
4377    Concepts: matrices^accessing diagonals
4378 
4379 .seealso: MatGetRow(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs()
4380 @*/
4381 PetscErrorCode MatGetDiagonal(Mat mat,Vec v)
4382 {
4383   PetscErrorCode ierr;
4384 
4385   PetscFunctionBegin;
4386   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4387   PetscValidType(mat,1);
4388   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4389   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4390   if (!mat->ops->getdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4391   MatCheckPreallocated(mat,1);
4392 
4393   ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr);
4394   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4395   PetscFunctionReturn(0);
4396 }
4397 
4398 #undef __FUNCT__
4399 #define __FUNCT__ "MatGetRowMin"
4400 /*@C
4401    MatGetRowMin - Gets the minimum value (of the real part) of each
4402         row of the matrix
4403 
4404    Logically Collective on Mat and Vec
4405 
4406    Input Parameters:
4407 .  mat - the matrix
4408 
4409    Output Parameter:
4410 +  v - the vector for storing the maximums
4411 -  idx - the indices of the column found for each row (optional)
4412 
4413    Level: intermediate
4414 
4415    Notes: The result of this call are the same as if one converted the matrix to dense format
4416       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4417 
4418     This code is only implemented for a couple of matrix formats.
4419 
4420    Concepts: matrices^getting row maximums
4421 
4422 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(),
4423           MatGetRowMax()
4424 @*/
4425 PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4426 {
4427   PetscErrorCode ierr;
4428 
4429   PetscFunctionBegin;
4430   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4431   PetscValidType(mat,1);
4432   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4433   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4434   if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4435   MatCheckPreallocated(mat,1);
4436 
4437   ierr = (*mat->ops->getrowmin)(mat,v,idx);CHKERRQ(ierr);
4438   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4439   PetscFunctionReturn(0);
4440 }
4441 
4442 #undef __FUNCT__
4443 #define __FUNCT__ "MatGetRowMinAbs"
4444 /*@C
4445    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4446         row of the matrix
4447 
4448    Logically Collective on Mat and Vec
4449 
4450    Input Parameters:
4451 .  mat - the matrix
4452 
4453    Output Parameter:
4454 +  v - the vector for storing the minimums
4455 -  idx - the indices of the column found for each row (or NULL if not needed)
4456 
4457    Level: intermediate
4458 
4459    Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
4460     row is 0 (the first column).
4461 
4462     This code is only implemented for a couple of matrix formats.
4463 
4464    Concepts: matrices^getting row maximums
4465 
4466 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4467 @*/
4468 PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4469 {
4470   PetscErrorCode ierr;
4471 
4472   PetscFunctionBegin;
4473   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4474   PetscValidType(mat,1);
4475   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4476   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4477   if (!mat->ops->getrowminabs) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4478   MatCheckPreallocated(mat,1);
4479   if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);}
4480 
4481   ierr = (*mat->ops->getrowminabs)(mat,v,idx);CHKERRQ(ierr);
4482   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4483   PetscFunctionReturn(0);
4484 }
4485 
4486 #undef __FUNCT__
4487 #define __FUNCT__ "MatGetRowMax"
4488 /*@C
4489    MatGetRowMax - Gets the maximum value (of the real part) of each
4490         row of the matrix
4491 
4492    Logically Collective on Mat and Vec
4493 
4494    Input Parameters:
4495 .  mat - the matrix
4496 
4497    Output Parameter:
4498 +  v - the vector for storing the maximums
4499 -  idx - the indices of the column found for each row (optional)
4500 
4501    Level: intermediate
4502 
4503    Notes: The result of this call are the same as if one converted the matrix to dense format
4504       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4505 
4506     This code is only implemented for a couple of matrix formats.
4507 
4508    Concepts: matrices^getting row maximums
4509 
4510 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4511 @*/
4512 PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4513 {
4514   PetscErrorCode ierr;
4515 
4516   PetscFunctionBegin;
4517   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4518   PetscValidType(mat,1);
4519   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4520   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4521   if (!mat->ops->getrowmax) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4522   MatCheckPreallocated(mat,1);
4523 
4524   ierr = (*mat->ops->getrowmax)(mat,v,idx);CHKERRQ(ierr);
4525   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4526   PetscFunctionReturn(0);
4527 }
4528 
4529 #undef __FUNCT__
4530 #define __FUNCT__ "MatGetRowMaxAbs"
4531 /*@C
4532    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4533         row of the matrix
4534 
4535    Logically Collective on Mat and Vec
4536 
4537    Input Parameters:
4538 .  mat - the matrix
4539 
4540    Output Parameter:
4541 +  v - the vector for storing the maximums
4542 -  idx - the indices of the column found for each row (or NULL if not needed)
4543 
4544    Level: intermediate
4545 
4546    Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
4547     row is 0 (the first column).
4548 
4549     This code is only implemented for a couple of matrix formats.
4550 
4551    Concepts: matrices^getting row maximums
4552 
4553 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4554 @*/
4555 PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4556 {
4557   PetscErrorCode ierr;
4558 
4559   PetscFunctionBegin;
4560   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4561   PetscValidType(mat,1);
4562   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4563   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4564   if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4565   MatCheckPreallocated(mat,1);
4566   if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);}
4567 
4568   ierr = (*mat->ops->getrowmaxabs)(mat,v,idx);CHKERRQ(ierr);
4569   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4570   PetscFunctionReturn(0);
4571 }
4572 
4573 #undef __FUNCT__
4574 #define __FUNCT__ "MatGetRowSum"
4575 /*@
4576    MatGetRowSum - Gets the sum of each row of the matrix
4577 
4578    Logically Collective on Mat and Vec
4579 
4580    Input Parameters:
4581 .  mat - the matrix
4582 
4583    Output Parameter:
4584 .  v - the vector for storing the sum of rows
4585 
4586    Level: intermediate
4587 
4588    Notes: This code is slow since it is not currently specialized for different formats
4589 
4590    Concepts: matrices^getting row sums
4591 
4592 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4593 @*/
4594 PetscErrorCode MatGetRowSum(Mat mat, Vec v)
4595 {
4596   PetscInt       start = 0, end = 0, row;
4597   PetscScalar    *array;
4598   PetscErrorCode ierr;
4599 
4600   PetscFunctionBegin;
4601   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4602   PetscValidType(mat,1);
4603   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4604   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4605   MatCheckPreallocated(mat,1);
4606   ierr = MatGetOwnershipRange(mat, &start, &end);CHKERRQ(ierr);
4607   ierr = VecGetArray(v, &array);CHKERRQ(ierr);
4608   for (row = start; row < end; ++row) {
4609     PetscInt          ncols, col;
4610     const PetscInt    *cols;
4611     const PetscScalar *vals;
4612 
4613     array[row - start] = 0.0;
4614 
4615     ierr = MatGetRow(mat, row, &ncols, &cols, &vals);CHKERRQ(ierr);
4616     for (col = 0; col < ncols; col++) {
4617       array[row - start] += vals[col];
4618     }
4619     ierr = MatRestoreRow(mat, row, &ncols, &cols, &vals);CHKERRQ(ierr);
4620   }
4621   ierr = VecRestoreArray(v, &array);CHKERRQ(ierr);
4622   ierr = PetscObjectStateIncrease((PetscObject) v);CHKERRQ(ierr);
4623   PetscFunctionReturn(0);
4624 }
4625 
4626 #undef __FUNCT__
4627 #define __FUNCT__ "MatTranspose"
4628 /*@
4629    MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
4630 
4631    Collective on Mat
4632 
4633    Input Parameter:
4634 +  mat - the matrix to transpose
4635 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
4636 
4637    Output Parameters:
4638 .  B - the transpose
4639 
4640    Notes:
4641      If you  pass in &mat for B the transpose will be done in place, for example MatTranspose(mat,MAT_REUSE_MATRIX,&mat);
4642 
4643      Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed.
4644 
4645    Level: intermediate
4646 
4647    Concepts: matrices^transposing
4648 
4649 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4650 @*/
4651 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4652 {
4653   PetscErrorCode ierr;
4654 
4655   PetscFunctionBegin;
4656   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4657   PetscValidType(mat,1);
4658   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4659   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4660   if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4661   MatCheckPreallocated(mat,1);
4662 
4663   ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4664   ierr = (*mat->ops->transpose)(mat,reuse,B);CHKERRQ(ierr);
4665   ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4666   if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);}
4667   PetscFunctionReturn(0);
4668 }
4669 
4670 #undef __FUNCT__
4671 #define __FUNCT__ "MatIsTranspose"
4672 /*@
4673    MatIsTranspose - Test whether a matrix is another one's transpose,
4674         or its own, in which case it tests symmetry.
4675 
4676    Collective on Mat
4677 
4678    Input Parameter:
4679 +  A - the matrix to test
4680 -  B - the matrix to test against, this can equal the first parameter
4681 
4682    Output Parameters:
4683 .  flg - the result
4684 
4685    Notes:
4686    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4687    has a running time of the order of the number of nonzeros; the parallel
4688    test involves parallel copies of the block-offdiagonal parts of the matrix.
4689 
4690    Level: intermediate
4691 
4692    Concepts: matrices^transposing, matrix^symmetry
4693 
4694 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4695 @*/
4696 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4697 {
4698   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4699 
4700   PetscFunctionBegin;
4701   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4702   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4703   PetscValidPointer(flg,3);
4704   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);CHKERRQ(ierr);
4705   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);CHKERRQ(ierr);
4706   *flg = PETSC_FALSE;
4707   if (f && g) {
4708     if (f == g) {
4709       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
4710     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4711   } else {
4712     MatType mattype;
4713     if (!f) {
4714       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
4715     } else {
4716       ierr = MatGetType(B,&mattype);CHKERRQ(ierr);
4717     }
4718     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
4719   }
4720   PetscFunctionReturn(0);
4721 }
4722 
4723 #undef __FUNCT__
4724 #define __FUNCT__ "MatHermitianTranspose"
4725 /*@
4726    MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate.
4727 
4728    Collective on Mat
4729 
4730    Input Parameter:
4731 +  mat - the matrix to transpose and complex conjugate
4732 -  reuse - store the transpose matrix in the provided B
4733 
4734    Output Parameters:
4735 .  B - the Hermitian
4736 
4737    Notes:
4738      If you  pass in &mat for B the Hermitian will be done in place
4739 
4740    Level: intermediate
4741 
4742    Concepts: matrices^transposing, complex conjugatex
4743 
4744 .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4745 @*/
4746 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
4747 {
4748   PetscErrorCode ierr;
4749 
4750   PetscFunctionBegin;
4751   ierr = MatTranspose(mat,reuse,B);CHKERRQ(ierr);
4752 #if defined(PETSC_USE_COMPLEX)
4753   ierr = MatConjugate(*B);CHKERRQ(ierr);
4754 #endif
4755   PetscFunctionReturn(0);
4756 }
4757 
4758 #undef __FUNCT__
4759 #define __FUNCT__ "MatIsHermitianTranspose"
4760 /*@
4761    MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,
4762 
4763    Collective on Mat
4764 
4765    Input Parameter:
4766 +  A - the matrix to test
4767 -  B - the matrix to test against, this can equal the first parameter
4768 
4769    Output Parameters:
4770 .  flg - the result
4771 
4772    Notes:
4773    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4774    has a running time of the order of the number of nonzeros; the parallel
4775    test involves parallel copies of the block-offdiagonal parts of the matrix.
4776 
4777    Level: intermediate
4778 
4779    Concepts: matrices^transposing, matrix^symmetry
4780 
4781 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
4782 @*/
4783 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4784 {
4785   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4786 
4787   PetscFunctionBegin;
4788   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4789   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4790   PetscValidPointer(flg,3);
4791   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);CHKERRQ(ierr);
4792   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);CHKERRQ(ierr);
4793   if (f && g) {
4794     if (f==g) {
4795       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
4796     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
4797   }
4798   PetscFunctionReturn(0);
4799 }
4800 
4801 #undef __FUNCT__
4802 #define __FUNCT__ "MatPermute"
4803 /*@
4804    MatPermute - Creates a new matrix with rows and columns permuted from the
4805    original.
4806 
4807    Collective on Mat
4808 
4809    Input Parameters:
4810 +  mat - the matrix to permute
4811 .  row - row permutation, each processor supplies only the permutation for its rows
4812 -  col - column permutation, each processor supplies only the permutation for its columns
4813 
4814    Output Parameters:
4815 .  B - the permuted matrix
4816 
4817    Level: advanced
4818 
4819    Note:
4820    The index sets map from row/col of permuted matrix to row/col of original matrix.
4821    The index sets should be on the same communicator as Mat and have the same local sizes.
4822 
4823    Concepts: matrices^permuting
4824 
4825 .seealso: MatGetOrdering(), ISAllGather()
4826 
4827 @*/
4828 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
4829 {
4830   PetscErrorCode ierr;
4831 
4832   PetscFunctionBegin;
4833   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4834   PetscValidType(mat,1);
4835   PetscValidHeaderSpecific(row,IS_CLASSID,2);
4836   PetscValidHeaderSpecific(col,IS_CLASSID,3);
4837   PetscValidPointer(B,4);
4838   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4839   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4840   if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
4841   MatCheckPreallocated(mat,1);
4842 
4843   ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr);
4844   ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);
4845   PetscFunctionReturn(0);
4846 }
4847 
4848 #undef __FUNCT__
4849 #define __FUNCT__ "MatEqual"
4850 /*@
4851    MatEqual - Compares two matrices.
4852 
4853    Collective on Mat
4854 
4855    Input Parameters:
4856 +  A - the first matrix
4857 -  B - the second matrix
4858 
4859    Output Parameter:
4860 .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
4861 
4862    Level: intermediate
4863 
4864    Concepts: matrices^equality between
4865 @*/
4866 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool  *flg)
4867 {
4868   PetscErrorCode ierr;
4869 
4870   PetscFunctionBegin;
4871   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4872   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4873   PetscValidType(A,1);
4874   PetscValidType(B,2);
4875   PetscValidIntPointer(flg,3);
4876   PetscCheckSameComm(A,1,B,2);
4877   MatCheckPreallocated(B,2);
4878   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4879   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4880   if (A->rmap->N != B->rmap->N || A->cmap->N != B->cmap->N) SETERRQ4(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %D %D %D %D",A->rmap->N,B->rmap->N,A->cmap->N,B->cmap->N);
4881   if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4882   if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4883   if (A->ops->equal != B->ops->equal) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"A is type: %s\nB is type: %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
4884   MatCheckPreallocated(A,1);
4885 
4886   ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr);
4887   PetscFunctionReturn(0);
4888 }
4889 
4890 #undef __FUNCT__
4891 #define __FUNCT__ "MatDiagonalScale"
4892 /*@
4893    MatDiagonalScale - Scales a matrix on the left and right by diagonal
4894    matrices that are stored as vectors.  Either of the two scaling
4895    matrices can be NULL.
4896 
4897    Collective on Mat
4898 
4899    Input Parameters:
4900 +  mat - the matrix to be scaled
4901 .  l - the left scaling vector (or NULL)
4902 -  r - the right scaling vector (or NULL)
4903 
4904    Notes:
4905    MatDiagonalScale() computes A = LAR, where
4906    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
4907    The L scales the rows of the matrix, the R scales the columns of the matrix.
4908 
4909    Level: intermediate
4910 
4911    Concepts: matrices^diagonal scaling
4912    Concepts: diagonal scaling of matrices
4913 
4914 .seealso: MatScale()
4915 @*/
4916 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
4917 {
4918   PetscErrorCode ierr;
4919 
4920   PetscFunctionBegin;
4921   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4922   PetscValidType(mat,1);
4923   if (!mat->ops->diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4924   if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);}
4925   if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);}
4926   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4927   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4928   MatCheckPreallocated(mat,1);
4929 
4930   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4931   ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr);
4932   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4933   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4934 #if defined(PETSC_HAVE_CUSP)
4935   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4936     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4937   }
4938 #elif defined(PETSC_HAVE_VIENNACL)
4939   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
4940     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
4941   }
4942 #elif defined(PETSC_HAVE_VECCUDA)
4943   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
4944     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
4945   }
4946 #endif
4947   PetscFunctionReturn(0);
4948 }
4949 
4950 #undef __FUNCT__
4951 #define __FUNCT__ "MatScale"
4952 /*@
4953     MatScale - Scales all elements of a matrix by a given number.
4954 
4955     Logically Collective on Mat
4956 
4957     Input Parameters:
4958 +   mat - the matrix to be scaled
4959 -   a  - the scaling value
4960 
4961     Output Parameter:
4962 .   mat - the scaled matrix
4963 
4964     Level: intermediate
4965 
4966     Concepts: matrices^scaling all entries
4967 
4968 .seealso: MatDiagonalScale()
4969 @*/
4970 PetscErrorCode MatScale(Mat mat,PetscScalar a)
4971 {
4972   PetscErrorCode ierr;
4973 
4974   PetscFunctionBegin;
4975   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4976   PetscValidType(mat,1);
4977   if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4978   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4979   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4980   PetscValidLogicalCollectiveScalar(mat,a,2);
4981   MatCheckPreallocated(mat,1);
4982 
4983   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4984   if (a != (PetscScalar)1.0) {
4985     ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr);
4986     ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4987   }
4988   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4989 #if defined(PETSC_HAVE_CUSP)
4990   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4991     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4992   }
4993 #elif defined(PETSC_HAVE_VIENNACL)
4994   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
4995     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
4996   }
4997 #elif defined(PETSC_HAVE_VECCUDA)
4998   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
4999     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5000   }
5001 #endif
5002   PetscFunctionReturn(0);
5003 }
5004 
5005 #undef __FUNCT__
5006 #define __FUNCT__ "MatNorm"
5007 /*@
5008    MatNorm - Calculates various norms of a matrix.
5009 
5010    Collective on Mat
5011 
5012    Input Parameters:
5013 +  mat - the matrix
5014 -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
5015 
5016    Output Parameters:
5017 .  nrm - the resulting norm
5018 
5019    Level: intermediate
5020 
5021    Concepts: matrices^norm
5022    Concepts: norm^of matrix
5023 @*/
5024 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
5025 {
5026   PetscErrorCode ierr;
5027 
5028   PetscFunctionBegin;
5029   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5030   PetscValidType(mat,1);
5031   PetscValidScalarPointer(nrm,3);
5032 
5033   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5034   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5035   if (!mat->ops->norm) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5036   MatCheckPreallocated(mat,1);
5037 
5038   ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr);
5039   PetscFunctionReturn(0);
5040 }
5041 
5042 /*
5043      This variable is used to prevent counting of MatAssemblyBegin() that
5044    are called from within a MatAssemblyEnd().
5045 */
5046 static PetscInt MatAssemblyEnd_InUse = 0;
5047 #undef __FUNCT__
5048 #define __FUNCT__ "MatAssemblyBegin"
5049 /*@
5050    MatAssemblyBegin - Begins assembling the matrix.  This routine should
5051    be called after completing all calls to MatSetValues().
5052 
5053    Collective on Mat
5054 
5055    Input Parameters:
5056 +  mat - the matrix
5057 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5058 
5059    Notes:
5060    MatSetValues() generally caches the values.  The matrix is ready to
5061    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5062    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5063    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5064    using the matrix.
5065 
5066    ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the
5067    same flag of MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY for all processes. Thus you CANNOT locally change from ADD_VALUES to INSERT_VALUES, that is
5068    a global collective operation requring all processes that share the matrix.
5069 
5070    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5071    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5072    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5073 
5074    Level: beginner
5075 
5076    Concepts: matrices^assembling
5077 
5078 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
5079 @*/
5080 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
5081 {
5082   PetscErrorCode ierr;
5083 
5084   PetscFunctionBegin;
5085   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5086   PetscValidType(mat,1);
5087   MatCheckPreallocated(mat,1);
5088   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
5089   if (mat->assembled) {
5090     mat->was_assembled = PETSC_TRUE;
5091     mat->assembled     = PETSC_FALSE;
5092   }
5093   if (!MatAssemblyEnd_InUse) {
5094     ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5095     if (mat->ops->assemblybegin) {ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
5096     ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5097   } else if (mat->ops->assemblybegin) {
5098     ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);
5099   }
5100   PetscFunctionReturn(0);
5101 }
5102 
5103 #undef __FUNCT__
5104 #define __FUNCT__ "MatAssembled"
5105 /*@
5106    MatAssembled - Indicates if a matrix has been assembled and is ready for
5107      use; for example, in matrix-vector product.
5108 
5109    Not Collective
5110 
5111    Input Parameter:
5112 .  mat - the matrix
5113 
5114    Output Parameter:
5115 .  assembled - PETSC_TRUE or PETSC_FALSE
5116 
5117    Level: advanced
5118 
5119    Concepts: matrices^assembled?
5120 
5121 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
5122 @*/
5123 PetscErrorCode MatAssembled(Mat mat,PetscBool  *assembled)
5124 {
5125   PetscFunctionBegin;
5126   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5127   PetscValidType(mat,1);
5128   PetscValidPointer(assembled,2);
5129   *assembled = mat->assembled;
5130   PetscFunctionReturn(0);
5131 }
5132 
5133 #undef __FUNCT__
5134 #define __FUNCT__ "MatAssemblyEnd"
5135 /*@
5136    MatAssemblyEnd - Completes assembling the matrix.  This routine should
5137    be called after MatAssemblyBegin().
5138 
5139    Collective on Mat
5140 
5141    Input Parameters:
5142 +  mat - the matrix
5143 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5144 
5145    Options Database Keys:
5146 +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
5147 .  -mat_view ::ascii_info_detail - Prints more detailed info
5148 .  -mat_view - Prints matrix in ASCII format
5149 .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
5150 .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
5151 .  -display <name> - Sets display name (default is host)
5152 .  -draw_pause <sec> - Sets number of seconds to pause after display
5153 .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab )
5154 .  -viewer_socket_machine <machine> - Machine to use for socket
5155 .  -viewer_socket_port <port> - Port number to use for socket
5156 -  -mat_view binary:filename[:append] - Save matrix to file in binary format
5157 
5158    Notes:
5159    MatSetValues() generally caches the values.  The matrix is ready to
5160    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5161    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5162    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5163    using the matrix.
5164 
5165    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5166    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5167    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5168 
5169    Level: beginner
5170 
5171 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
5172 @*/
5173 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
5174 {
5175   PetscErrorCode  ierr;
5176   static PetscInt inassm = 0;
5177   PetscBool       flg    = PETSC_FALSE;
5178 
5179   PetscFunctionBegin;
5180   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5181   PetscValidType(mat,1);
5182 
5183   inassm++;
5184   MatAssemblyEnd_InUse++;
5185   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
5186     ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5187     if (mat->ops->assemblyend) {
5188       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5189     }
5190     ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5191   } else if (mat->ops->assemblyend) {
5192     ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5193   }
5194 
5195   /* Flush assembly is not a true assembly */
5196   if (type != MAT_FLUSH_ASSEMBLY) {
5197     mat->assembled = PETSC_TRUE; mat->num_ass++;
5198   }
5199   mat->insertmode = NOT_SET_VALUES;
5200   MatAssemblyEnd_InUse--;
5201   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5202   if (!mat->symmetric_eternal) {
5203     mat->symmetric_set              = PETSC_FALSE;
5204     mat->hermitian_set              = PETSC_FALSE;
5205     mat->structurally_symmetric_set = PETSC_FALSE;
5206   }
5207 #if defined(PETSC_HAVE_CUSP)
5208   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5209     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5210   }
5211 #elif defined(PETSC_HAVE_VIENNACL)
5212   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5213     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5214   }
5215 #elif defined(PETSC_HAVE_VECCUDA)
5216   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5217     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5218   }
5219 #endif
5220   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
5221     ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5222 
5223     if (mat->checksymmetryonassembly) {
5224       ierr = MatIsSymmetric(mat,mat->checksymmetrytol,&flg);CHKERRQ(ierr);
5225       if (flg) {
5226         ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5227       } else {
5228         ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5229       }
5230     }
5231     if (mat->nullsp && mat->checknullspaceonassembly) {
5232       ierr = MatNullSpaceTest(mat->nullsp,mat,NULL);CHKERRQ(ierr);
5233     }
5234   }
5235   inassm--;
5236   PetscFunctionReturn(0);
5237 }
5238 
5239 #undef __FUNCT__
5240 #define __FUNCT__ "MatSetOption"
5241 /*@
5242    MatSetOption - Sets a parameter option for a matrix. Some options
5243    may be specific to certain storage formats.  Some options
5244    determine how values will be inserted (or added). Sorted,
5245    row-oriented input will generally assemble the fastest. The default
5246    is row-oriented.
5247 
5248    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5249 
5250    Input Parameters:
5251 +  mat - the matrix
5252 .  option - the option, one of those listed below (and possibly others),
5253 -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5254 
5255   Options Describing Matrix Structure:
5256 +    MAT_SPD - symmetric positive definite
5257 .    MAT_SYMMETRIC - symmetric in terms of both structure and value
5258 .    MAT_HERMITIAN - transpose is the complex conjugation
5259 .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5260 -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5261                             you set to be kept with all future use of the matrix
5262                             including after MatAssemblyBegin/End() which could
5263                             potentially change the symmetry structure, i.e. you
5264                             KNOW the matrix will ALWAYS have the property you set.
5265 
5266 
5267    Options For Use with MatSetValues():
5268    Insert a logically dense subblock, which can be
5269 .    MAT_ROW_ORIENTED - row-oriented (default)
5270 
5271    Note these options reflect the data you pass in with MatSetValues(); it has
5272    nothing to do with how the data is stored internally in the matrix
5273    data structure.
5274 
5275    When (re)assembling a matrix, we can restrict the input for
5276    efficiency/debugging purposes.  These options include:
5277 +    MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow)
5278 .    MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
5279 .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
5280 .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
5281 .    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
5282 .    MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
5283         any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
5284         performance for very large process counts.
5285 -    MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset
5286         of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly
5287         functions, instead sending only neighbor messages.
5288 
5289    Notes:
5290    Except for MAT_UNUSED_NONZERO_LOCATION_ERR and  MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg!
5291 
5292    Some options are relevant only for particular matrix types and
5293    are thus ignored by others.  Other options are not supported by
5294    certain matrix types and will generate an error message if set.
5295 
5296    If using a Fortran 77 module to compute a matrix, one may need to
5297    use the column-oriented option (or convert to the row-oriented
5298    format).
5299 
5300    MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
5301    that would generate a new entry in the nonzero structure is instead
5302    ignored.  Thus, if memory has not alredy been allocated for this particular
5303    data, then the insertion is ignored. For dense matrices, in which
5304    the entire array is allocated, no entries are ever ignored.
5305    Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5306 
5307    MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5308    that would generate a new entry in the nonzero structure instead produces
5309    an error. (Currently supported for AIJ and BAIJ formats only.) If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5310 
5311    MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5312    that would generate a new entry that has not been preallocated will
5313    instead produce an error. (Currently supported for AIJ and BAIJ formats
5314    only.) This is a useful flag when debugging matrix memory preallocation.
5315    If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5316 
5317    MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for
5318    other processors should be dropped, rather than stashed.
5319    This is useful if you know that the "owning" processor is also
5320    always generating the correct matrix entries, so that PETSc need
5321    not transfer duplicate entries generated on another processor.
5322 
5323    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5324    searches during matrix assembly. When this flag is set, the hash table
5325    is created during the first Matrix Assembly. This hash table is
5326    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5327    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5328    should be used with MAT_USE_HASH_TABLE flag. This option is currently
5329    supported by MATMPIBAIJ format only.
5330 
5331    MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries
5332    are kept in the nonzero structure
5333 
5334    MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
5335    a zero location in the matrix
5336 
5337    MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types
5338 
5339    MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the
5340         zero row routines and thus improves performance for very large process counts.
5341 
5342    MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular
5343         part of the matrix (since they should match the upper triangular part).
5344 
5345    Notes: Can only be called after MatSetSizes() and MatSetType() have been set.
5346 
5347    Level: intermediate
5348 
5349    Concepts: matrices^setting options
5350 
5351 .seealso:  MatOption, Mat
5352 
5353 @*/
5354 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg)
5355 {
5356   PetscErrorCode ierr;
5357 
5358   PetscFunctionBegin;
5359   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5360   PetscValidType(mat,1);
5361   if (op > 0) {
5362     PetscValidLogicalCollectiveEnum(mat,op,2);
5363     PetscValidLogicalCollectiveBool(mat,flg,3);
5364   }
5365 
5366   if (((int) op) <= MAT_OPTION_MIN || ((int) op) >= MAT_OPTION_MAX) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Options %d is out of range",(int)op);
5367   if (!((PetscObject)mat)->type_name) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_TYPENOTSET,"Cannot set options until type and size have been set, see MatSetType() and MatSetSizes()");
5368 
5369   switch (op) {
5370   case MAT_NO_OFF_PROC_ENTRIES:
5371     mat->nooffprocentries = flg;
5372     PetscFunctionReturn(0);
5373     break;
5374   case MAT_SUBSET_OFF_PROC_ENTRIES:
5375     mat->subsetoffprocentries = flg;
5376     PetscFunctionReturn(0);
5377   case MAT_NO_OFF_PROC_ZERO_ROWS:
5378     mat->nooffproczerorows = flg;
5379     PetscFunctionReturn(0);
5380     break;
5381   case MAT_SPD:
5382     mat->spd_set = PETSC_TRUE;
5383     mat->spd     = flg;
5384     if (flg) {
5385       mat->symmetric                  = PETSC_TRUE;
5386       mat->structurally_symmetric     = PETSC_TRUE;
5387       mat->symmetric_set              = PETSC_TRUE;
5388       mat->structurally_symmetric_set = PETSC_TRUE;
5389     }
5390     break;
5391   case MAT_SYMMETRIC:
5392     mat->symmetric = flg;
5393     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5394     mat->symmetric_set              = PETSC_TRUE;
5395     mat->structurally_symmetric_set = flg;
5396     break;
5397   case MAT_HERMITIAN:
5398     mat->hermitian = flg;
5399     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5400     mat->hermitian_set              = PETSC_TRUE;
5401     mat->structurally_symmetric_set = flg;
5402     break;
5403   case MAT_STRUCTURALLY_SYMMETRIC:
5404     mat->structurally_symmetric     = flg;
5405     mat->structurally_symmetric_set = PETSC_TRUE;
5406     break;
5407   case MAT_SYMMETRY_ETERNAL:
5408     mat->symmetric_eternal = flg;
5409     break;
5410   default:
5411     break;
5412   }
5413   if (mat->ops->setoption) {
5414     ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr);
5415   }
5416   PetscFunctionReturn(0);
5417 }
5418 
5419 #undef __FUNCT__
5420 #define __FUNCT__ "MatGetOption"
5421 /*@
5422    MatGetOption - Gets a parameter option that has been set for a matrix.
5423 
5424    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5425 
5426    Input Parameters:
5427 +  mat - the matrix
5428 -  option - the option, this only responds to certain options, check the code for which ones
5429 
5430    Output Parameter:
5431 .  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5432 
5433     Notes: Can only be called after MatSetSizes() and MatSetType() have been set.
5434 
5435    Level: intermediate
5436 
5437    Concepts: matrices^setting options
5438 
5439 .seealso:  MatOption, MatSetOption()
5440 
5441 @*/
5442 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg)
5443 {
5444   PetscFunctionBegin;
5445   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5446   PetscValidType(mat,1);
5447 
5448   if (((int) op) <= MAT_OPTION_MIN || ((int) op) >= MAT_OPTION_MAX) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Options %d is out of range",(int)op);
5449   if (!((PetscObject)mat)->type_name) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_TYPENOTSET,"Cannot get options until type and size have been set, see MatSetType() and MatSetSizes()");
5450 
5451   switch (op) {
5452   case MAT_NO_OFF_PROC_ENTRIES:
5453     *flg = mat->nooffprocentries;
5454     break;
5455   case MAT_NO_OFF_PROC_ZERO_ROWS:
5456     *flg = mat->nooffproczerorows;
5457     break;
5458   case MAT_SYMMETRIC:
5459     *flg = mat->symmetric;
5460     break;
5461   case MAT_HERMITIAN:
5462     *flg = mat->hermitian;
5463     break;
5464   case MAT_STRUCTURALLY_SYMMETRIC:
5465     *flg = mat->structurally_symmetric;
5466     break;
5467   case MAT_SYMMETRY_ETERNAL:
5468     *flg = mat->symmetric_eternal;
5469     break;
5470   default:
5471     break;
5472   }
5473   PetscFunctionReturn(0);
5474 }
5475 
5476 #undef __FUNCT__
5477 #define __FUNCT__ "MatZeroEntries"
5478 /*@
5479    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5480    this routine retains the old nonzero structure.
5481 
5482    Logically Collective on Mat
5483 
5484    Input Parameters:
5485 .  mat - the matrix
5486 
5487    Level: intermediate
5488 
5489    Notes: If the matrix was not preallocated then a default, likely poor preallocation will be set in the matrix, so this should be called after the preallocation phase.
5490    See the Performance chapter of the users manual for information on preallocating matrices.
5491 
5492    Concepts: matrices^zeroing
5493 
5494 .seealso: MatZeroRows()
5495 @*/
5496 PetscErrorCode MatZeroEntries(Mat mat)
5497 {
5498   PetscErrorCode ierr;
5499 
5500   PetscFunctionBegin;
5501   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5502   PetscValidType(mat,1);
5503   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5504   if (mat->insertmode != NOT_SET_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for matrices where you have set values but not yet assembled");
5505   if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5506   MatCheckPreallocated(mat,1);
5507 
5508   ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5509   ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
5510   ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5511   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5512 #if defined(PETSC_HAVE_CUSP)
5513   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5514     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5515   }
5516 #elif defined(PETSC_HAVE_VIENNACL)
5517   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5518     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5519   }
5520 #elif defined(PETSC_HAVE_VECCUDA)
5521   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5522     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5523   }
5524 #endif
5525   PetscFunctionReturn(0);
5526 }
5527 
5528 #undef __FUNCT__
5529 #define __FUNCT__ "MatZeroRowsColumns"
5530 /*@C
5531    MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal)
5532    of a set of rows and columns of a matrix.
5533 
5534    Collective on Mat
5535 
5536    Input Parameters:
5537 +  mat - the matrix
5538 .  numRows - the number of rows to remove
5539 .  rows - the global row indices
5540 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5541 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5542 -  b - optional vector of right hand side, that will be adjusted by provided solution
5543 
5544    Notes:
5545    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5546 
5547    The user can set a value in the diagonal entry (or for the AIJ and
5548    row formats can optionally remove the main diagonal entry from the
5549    nonzero structure as well, by passing 0.0 as the final argument).
5550 
5551    For the parallel case, all processes that share the matrix (i.e.,
5552    those in the communicator used for matrix creation) MUST call this
5553    routine, regardless of whether any rows being zeroed are owned by
5554    them.
5555 
5556    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5557    list only rows local to itself).
5558 
5559    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5560 
5561    Level: intermediate
5562 
5563    Concepts: matrices^zeroing rows
5564 
5565 .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumnsIS()
5566 @*/
5567 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5568 {
5569   PetscErrorCode ierr;
5570 
5571   PetscFunctionBegin;
5572   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5573   PetscValidType(mat,1);
5574   if (numRows) PetscValidIntPointer(rows,3);
5575   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5576   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5577   if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5578   MatCheckPreallocated(mat,1);
5579 
5580   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5581   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5582   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5583 #if defined(PETSC_HAVE_CUSP)
5584   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5585     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5586   }
5587 #elif defined(PETSC_HAVE_VIENNACL)
5588   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5589     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5590   }
5591 #elif defined(PETSC_HAVE_VECCUDA)
5592   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5593     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5594   }
5595 #endif
5596   PetscFunctionReturn(0);
5597 }
5598 
5599 #undef __FUNCT__
5600 #define __FUNCT__ "MatZeroRowsColumnsIS"
5601 /*@C
5602    MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
5603    of a set of rows and columns of a matrix.
5604 
5605    Collective on Mat
5606 
5607    Input Parameters:
5608 +  mat - the matrix
5609 .  is - the rows to zero
5610 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5611 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5612 -  b - optional vector of right hand side, that will be adjusted by provided solution
5613 
5614    Notes:
5615    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5616 
5617    The user can set a value in the diagonal entry (or for the AIJ and
5618    row formats can optionally remove the main diagonal entry from the
5619    nonzero structure as well, by passing 0.0 as the final argument).
5620 
5621    For the parallel case, all processes that share the matrix (i.e.,
5622    those in the communicator used for matrix creation) MUST call this
5623    routine, regardless of whether any rows being zeroed are owned by
5624    them.
5625 
5626    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5627    list only rows local to itself).
5628 
5629    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5630 
5631    Level: intermediate
5632 
5633    Concepts: matrices^zeroing rows
5634 
5635 .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumns()
5636 @*/
5637 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5638 {
5639   PetscErrorCode ierr;
5640   PetscInt       numRows;
5641   const PetscInt *rows;
5642 
5643   PetscFunctionBegin;
5644   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5645   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5646   PetscValidType(mat,1);
5647   PetscValidType(is,2);
5648   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5649   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5650   ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5651   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5652   PetscFunctionReturn(0);
5653 }
5654 
5655 #undef __FUNCT__
5656 #define __FUNCT__ "MatZeroRows"
5657 /*@C
5658    MatZeroRows - Zeros all entries (except possibly the main diagonal)
5659    of a set of rows of a matrix.
5660 
5661    Collective on Mat
5662 
5663    Input Parameters:
5664 +  mat - the matrix
5665 .  numRows - the number of rows to remove
5666 .  rows - the global row indices
5667 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5668 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5669 -  b - optional vector of right hand side, that will be adjusted by provided solution
5670 
5671    Notes:
5672    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5673    but does not release memory.  For the dense and block diagonal
5674    formats this does not alter the nonzero structure.
5675 
5676    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5677    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5678    merely zeroed.
5679 
5680    The user can set a value in the diagonal entry (or for the AIJ and
5681    row formats can optionally remove the main diagonal entry from the
5682    nonzero structure as well, by passing 0.0 as the final argument).
5683 
5684    For the parallel case, all processes that share the matrix (i.e.,
5685    those in the communicator used for matrix creation) MUST call this
5686    routine, regardless of whether any rows being zeroed are owned by
5687    them.
5688 
5689    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5690    list only rows local to itself).
5691 
5692    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5693    owns that are to be zeroed. This saves a global synchronization in the implementation.
5694 
5695    Level: intermediate
5696 
5697    Concepts: matrices^zeroing rows
5698 
5699 .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5700 @*/
5701 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5702 {
5703   PetscErrorCode ierr;
5704 
5705   PetscFunctionBegin;
5706   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5707   PetscValidType(mat,1);
5708   if (numRows) PetscValidIntPointer(rows,3);
5709   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5710   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5711   if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5712   MatCheckPreallocated(mat,1);
5713 
5714   ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5715   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5716   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5717 #if defined(PETSC_HAVE_CUSP)
5718   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5719     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5720   }
5721 #elif defined(PETSC_HAVE_VIENNACL)
5722   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5723     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5724   }
5725 #elif defined(PETSC_HAVE_VECCUDA)
5726   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5727     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5728   }
5729 #endif
5730   PetscFunctionReturn(0);
5731 }
5732 
5733 #undef __FUNCT__
5734 #define __FUNCT__ "MatZeroRowsIS"
5735 /*@C
5736    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5737    of a set of rows of a matrix.
5738 
5739    Collective on Mat
5740 
5741    Input Parameters:
5742 +  mat - the matrix
5743 .  is - index set of rows to remove
5744 .  diag - value put in all diagonals of eliminated rows
5745 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5746 -  b - optional vector of right hand side, that will be adjusted by provided solution
5747 
5748    Notes:
5749    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5750    but does not release memory.  For the dense and block diagonal
5751    formats this does not alter the nonzero structure.
5752 
5753    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5754    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5755    merely zeroed.
5756 
5757    The user can set a value in the diagonal entry (or for the AIJ and
5758    row formats can optionally remove the main diagonal entry from the
5759    nonzero structure as well, by passing 0.0 as the final argument).
5760 
5761    For the parallel case, all processes that share the matrix (i.e.,
5762    those in the communicator used for matrix creation) MUST call this
5763    routine, regardless of whether any rows being zeroed are owned by
5764    them.
5765 
5766    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5767    list only rows local to itself).
5768 
5769    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5770    owns that are to be zeroed. This saves a global synchronization in the implementation.
5771 
5772    Level: intermediate
5773 
5774    Concepts: matrices^zeroing rows
5775 
5776 .seealso: MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5777 @*/
5778 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5779 {
5780   PetscInt       numRows;
5781   const PetscInt *rows;
5782   PetscErrorCode ierr;
5783 
5784   PetscFunctionBegin;
5785   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5786   PetscValidType(mat,1);
5787   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5788   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5789   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5790   ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5791   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5792   PetscFunctionReturn(0);
5793 }
5794 
5795 #undef __FUNCT__
5796 #define __FUNCT__ "MatZeroRowsStencil"
5797 /*@C
5798    MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
5799    of a set of rows of a matrix. These rows must be local to the process.
5800 
5801    Collective on Mat
5802 
5803    Input Parameters:
5804 +  mat - the matrix
5805 .  numRows - the number of rows to remove
5806 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
5807 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5808 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5809 -  b - optional vector of right hand side, that will be adjusted by provided solution
5810 
5811    Notes:
5812    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5813    but does not release memory.  For the dense and block diagonal
5814    formats this does not alter the nonzero structure.
5815 
5816    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5817    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5818    merely zeroed.
5819 
5820    The user can set a value in the diagonal entry (or for the AIJ and
5821    row formats can optionally remove the main diagonal entry from the
5822    nonzero structure as well, by passing 0.0 as the final argument).
5823 
5824    For the parallel case, all processes that share the matrix (i.e.,
5825    those in the communicator used for matrix creation) MUST call this
5826    routine, regardless of whether any rows being zeroed are owned by
5827    them.
5828 
5829    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5830    list only rows local to itself).
5831 
5832    The grid coordinates are across the entire grid, not just the local portion
5833 
5834    In Fortran idxm and idxn should be declared as
5835 $     MatStencil idxm(4,m)
5836    and the values inserted using
5837 $    idxm(MatStencil_i,1) = i
5838 $    idxm(MatStencil_j,1) = j
5839 $    idxm(MatStencil_k,1) = k
5840 $    idxm(MatStencil_c,1) = c
5841    etc
5842 
5843    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5844    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5845    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5846    DM_BOUNDARY_PERIODIC boundary type.
5847 
5848    For indices that don't mean anything for your case (like the k index when working in 2d) or the c index when you have
5849    a single value per point) you can skip filling those indices.
5850 
5851    Level: intermediate
5852 
5853    Concepts: matrices^zeroing rows
5854 
5855 .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5856 @*/
5857 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5858 {
5859   PetscInt       dim     = mat->stencil.dim;
5860   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
5861   PetscInt       *dims   = mat->stencil.dims+1;
5862   PetscInt       *starts = mat->stencil.starts;
5863   PetscInt       *dxm    = (PetscInt*) rows;
5864   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
5865   PetscErrorCode ierr;
5866 
5867   PetscFunctionBegin;
5868   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5869   PetscValidType(mat,1);
5870   if (numRows) PetscValidIntPointer(rows,3);
5871 
5872   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
5873   for (i = 0; i < numRows; ++i) {
5874     /* Skip unused dimensions (they are ordered k, j, i, c) */
5875     for (j = 0; j < 3-sdim; ++j) dxm++;
5876     /* Local index in X dir */
5877     tmp = *dxm++ - starts[0];
5878     /* Loop over remaining dimensions */
5879     for (j = 0; j < dim-1; ++j) {
5880       /* If nonlocal, set index to be negative */
5881       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5882       /* Update local index */
5883       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5884     }
5885     /* Skip component slot if necessary */
5886     if (mat->stencil.noc) dxm++;
5887     /* Local row number */
5888     if (tmp >= 0) {
5889       jdxm[numNewRows++] = tmp;
5890     }
5891   }
5892   ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
5893   ierr = PetscFree(jdxm);CHKERRQ(ierr);
5894   PetscFunctionReturn(0);
5895 }
5896 
5897 #undef __FUNCT__
5898 #define __FUNCT__ "MatZeroRowsColumnsStencil"
5899 /*@C
5900    MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal)
5901    of a set of rows and columns of a matrix.
5902 
5903    Collective on Mat
5904 
5905    Input Parameters:
5906 +  mat - the matrix
5907 .  numRows - the number of rows/columns to remove
5908 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
5909 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5910 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5911 -  b - optional vector of right hand side, that will be adjusted by provided solution
5912 
5913    Notes:
5914    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5915    but does not release memory.  For the dense and block diagonal
5916    formats this does not alter the nonzero structure.
5917 
5918    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5919    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5920    merely zeroed.
5921 
5922    The user can set a value in the diagonal entry (or for the AIJ and
5923    row formats can optionally remove the main diagonal entry from the
5924    nonzero structure as well, by passing 0.0 as the final argument).
5925 
5926    For the parallel case, all processes that share the matrix (i.e.,
5927    those in the communicator used for matrix creation) MUST call this
5928    routine, regardless of whether any rows being zeroed are owned by
5929    them.
5930 
5931    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5932    list only rows local to itself, but the row/column numbers are given in local numbering).
5933 
5934    The grid coordinates are across the entire grid, not just the local portion
5935 
5936    In Fortran idxm and idxn should be declared as
5937 $     MatStencil idxm(4,m)
5938    and the values inserted using
5939 $    idxm(MatStencil_i,1) = i
5940 $    idxm(MatStencil_j,1) = j
5941 $    idxm(MatStencil_k,1) = k
5942 $    idxm(MatStencil_c,1) = c
5943    etc
5944 
5945    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5946    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5947    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5948    DM_BOUNDARY_PERIODIC boundary type.
5949 
5950    For indices that don't mean anything for your case (like the k index when working in 2d) or the c index when you have
5951    a single value per point) you can skip filling those indices.
5952 
5953    Level: intermediate
5954 
5955    Concepts: matrices^zeroing rows
5956 
5957 .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5958 @*/
5959 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5960 {
5961   PetscInt       dim     = mat->stencil.dim;
5962   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
5963   PetscInt       *dims   = mat->stencil.dims+1;
5964   PetscInt       *starts = mat->stencil.starts;
5965   PetscInt       *dxm    = (PetscInt*) rows;
5966   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
5967   PetscErrorCode ierr;
5968 
5969   PetscFunctionBegin;
5970   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5971   PetscValidType(mat,1);
5972   if (numRows) PetscValidIntPointer(rows,3);
5973 
5974   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
5975   for (i = 0; i < numRows; ++i) {
5976     /* Skip unused dimensions (they are ordered k, j, i, c) */
5977     for (j = 0; j < 3-sdim; ++j) dxm++;
5978     /* Local index in X dir */
5979     tmp = *dxm++ - starts[0];
5980     /* Loop over remaining dimensions */
5981     for (j = 0; j < dim-1; ++j) {
5982       /* If nonlocal, set index to be negative */
5983       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5984       /* Update local index */
5985       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5986     }
5987     /* Skip component slot if necessary */
5988     if (mat->stencil.noc) dxm++;
5989     /* Local row number */
5990     if (tmp >= 0) {
5991       jdxm[numNewRows++] = tmp;
5992     }
5993   }
5994   ierr = MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
5995   ierr = PetscFree(jdxm);CHKERRQ(ierr);
5996   PetscFunctionReturn(0);
5997 }
5998 
5999 #undef __FUNCT__
6000 #define __FUNCT__ "MatZeroRowsLocal"
6001 /*@C
6002    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
6003    of a set of rows of a matrix; using local numbering of rows.
6004 
6005    Collective on Mat
6006 
6007    Input Parameters:
6008 +  mat - the matrix
6009 .  numRows - the number of rows to remove
6010 .  rows - the global row indices
6011 .  diag - value put in all diagonals of eliminated rows
6012 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6013 -  b - optional vector of right hand side, that will be adjusted by provided solution
6014 
6015    Notes:
6016    Before calling MatZeroRowsLocal(), the user must first set the
6017    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6018 
6019    For the AIJ matrix formats this removes the old nonzero structure,
6020    but does not release memory.  For the dense and block diagonal
6021    formats this does not alter the nonzero structure.
6022 
6023    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6024    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6025    merely zeroed.
6026 
6027    The user can set a value in the diagonal entry (or for the AIJ and
6028    row formats can optionally remove the main diagonal entry from the
6029    nonzero structure as well, by passing 0.0 as the final argument).
6030 
6031    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6032    owns that are to be zeroed. This saves a global synchronization in the implementation.
6033 
6034    Level: intermediate
6035 
6036    Concepts: matrices^zeroing
6037 
6038 .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
6039 @*/
6040 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6041 {
6042   PetscErrorCode ierr;
6043 
6044   PetscFunctionBegin;
6045   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6046   PetscValidType(mat,1);
6047   if (numRows) PetscValidIntPointer(rows,3);
6048   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6049   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6050   MatCheckPreallocated(mat,1);
6051 
6052   if (mat->ops->zerorowslocal) {
6053     ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6054   } else {
6055     IS             is, newis;
6056     const PetscInt *newRows;
6057 
6058     if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6059     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6060     ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr);
6061     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6062     ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6063     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6064     ierr = ISDestroy(&newis);CHKERRQ(ierr);
6065     ierr = ISDestroy(&is);CHKERRQ(ierr);
6066   }
6067   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6068 #if defined(PETSC_HAVE_CUSP)
6069   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
6070     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
6071   }
6072 #elif defined(PETSC_HAVE_VIENNACL)
6073   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
6074     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
6075   }
6076 #elif defined(PETSC_HAVE_VECCUDA)
6077   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
6078     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
6079   }
6080 #endif
6081   PetscFunctionReturn(0);
6082 }
6083 
6084 #undef __FUNCT__
6085 #define __FUNCT__ "MatZeroRowsLocalIS"
6086 /*@C
6087    MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
6088    of a set of rows of a matrix; using local numbering of rows.
6089 
6090    Collective on Mat
6091 
6092    Input Parameters:
6093 +  mat - the matrix
6094 .  is - index set of rows to remove
6095 .  diag - value put in all diagonals of eliminated rows
6096 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6097 -  b - optional vector of right hand side, that will be adjusted by provided solution
6098 
6099    Notes:
6100    Before calling MatZeroRowsLocalIS(), the user must first set the
6101    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6102 
6103    For the AIJ matrix formats this removes the old nonzero structure,
6104    but does not release memory.  For the dense and block diagonal
6105    formats this does not alter the nonzero structure.
6106 
6107    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6108    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6109    merely zeroed.
6110 
6111    The user can set a value in the diagonal entry (or for the AIJ and
6112    row formats can optionally remove the main diagonal entry from the
6113    nonzero structure as well, by passing 0.0 as the final argument).
6114 
6115    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6116    owns that are to be zeroed. This saves a global synchronization in the implementation.
6117 
6118    Level: intermediate
6119 
6120    Concepts: matrices^zeroing
6121 
6122 .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
6123 @*/
6124 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6125 {
6126   PetscErrorCode ierr;
6127   PetscInt       numRows;
6128   const PetscInt *rows;
6129 
6130   PetscFunctionBegin;
6131   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6132   PetscValidType(mat,1);
6133   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6134   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6135   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6136   MatCheckPreallocated(mat,1);
6137 
6138   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6139   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6140   ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6141   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6142   PetscFunctionReturn(0);
6143 }
6144 
6145 #undef __FUNCT__
6146 #define __FUNCT__ "MatZeroRowsColumnsLocal"
6147 /*@C
6148    MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
6149    of a set of rows and columns of a matrix; using local numbering of rows.
6150 
6151    Collective on Mat
6152 
6153    Input Parameters:
6154 +  mat - the matrix
6155 .  numRows - the number of rows to remove
6156 .  rows - the global row indices
6157 .  diag - value put in all diagonals of eliminated rows
6158 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6159 -  b - optional vector of right hand side, that will be adjusted by provided solution
6160 
6161    Notes:
6162    Before calling MatZeroRowsColumnsLocal(), the user must first set the
6163    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6164 
6165    The user can set a value in the diagonal entry (or for the AIJ and
6166    row formats can optionally remove the main diagonal entry from the
6167    nonzero structure as well, by passing 0.0 as the final argument).
6168 
6169    Level: intermediate
6170 
6171    Concepts: matrices^zeroing
6172 
6173 .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
6174 @*/
6175 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6176 {
6177   PetscErrorCode ierr;
6178   IS             is, newis;
6179   const PetscInt *newRows;
6180 
6181   PetscFunctionBegin;
6182   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6183   PetscValidType(mat,1);
6184   if (numRows) PetscValidIntPointer(rows,3);
6185   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6186   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6187   MatCheckPreallocated(mat,1);
6188 
6189   if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6190   ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6191   ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr);
6192   ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6193   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6194   ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6195   ierr = ISDestroy(&newis);CHKERRQ(ierr);
6196   ierr = ISDestroy(&is);CHKERRQ(ierr);
6197   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6198 #if defined(PETSC_HAVE_CUSP)
6199   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
6200     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
6201   }
6202 #elif defined(PETSC_HAVE_VIENNACL)
6203   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
6204     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
6205   }
6206 #elif defined(PETSC_HAVE_VECCUDA)
6207   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
6208     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
6209   }
6210 #endif
6211   PetscFunctionReturn(0);
6212 }
6213 
6214 #undef __FUNCT__
6215 #define __FUNCT__ "MatZeroRowsColumnsLocalIS"
6216 /*@C
6217    MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
6218    of a set of rows and columns of a matrix; using local numbering of rows.
6219 
6220    Collective on Mat
6221 
6222    Input Parameters:
6223 +  mat - the matrix
6224 .  is - index set of rows to remove
6225 .  diag - value put in all diagonals of eliminated rows
6226 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6227 -  b - optional vector of right hand side, that will be adjusted by provided solution
6228 
6229    Notes:
6230    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
6231    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6232 
6233    The user can set a value in the diagonal entry (or for the AIJ and
6234    row formats can optionally remove the main diagonal entry from the
6235    nonzero structure as well, by passing 0.0 as the final argument).
6236 
6237    Level: intermediate
6238 
6239    Concepts: matrices^zeroing
6240 
6241 .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
6242 @*/
6243 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6244 {
6245   PetscErrorCode ierr;
6246   PetscInt       numRows;
6247   const PetscInt *rows;
6248 
6249   PetscFunctionBegin;
6250   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6251   PetscValidType(mat,1);
6252   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6253   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6254   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6255   MatCheckPreallocated(mat,1);
6256 
6257   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6258   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6259   ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6260   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6261   PetscFunctionReturn(0);
6262 }
6263 
6264 #undef __FUNCT__
6265 #define __FUNCT__ "MatGetSize"
6266 /*@
6267    MatGetSize - Returns the numbers of rows and columns in a matrix.
6268 
6269    Not Collective
6270 
6271    Input Parameter:
6272 .  mat - the matrix
6273 
6274    Output Parameters:
6275 +  m - the number of global rows
6276 -  n - the number of global columns
6277 
6278    Note: both output parameters can be NULL on input.
6279 
6280    Level: beginner
6281 
6282    Concepts: matrices^size
6283 
6284 .seealso: MatGetLocalSize()
6285 @*/
6286 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
6287 {
6288   PetscFunctionBegin;
6289   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6290   if (m) *m = mat->rmap->N;
6291   if (n) *n = mat->cmap->N;
6292   PetscFunctionReturn(0);
6293 }
6294 
6295 #undef __FUNCT__
6296 #define __FUNCT__ "MatGetLocalSize"
6297 /*@
6298    MatGetLocalSize - Returns the number of rows and columns in a matrix
6299    stored locally.  This information may be implementation dependent, so
6300    use with care.
6301 
6302    Not Collective
6303 
6304    Input Parameters:
6305 .  mat - the matrix
6306 
6307    Output Parameters:
6308 +  m - the number of local rows
6309 -  n - the number of local columns
6310 
6311    Note: both output parameters can be NULL on input.
6312 
6313    Level: beginner
6314 
6315    Concepts: matrices^local size
6316 
6317 .seealso: MatGetSize()
6318 @*/
6319 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
6320 {
6321   PetscFunctionBegin;
6322   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6323   if (m) PetscValidIntPointer(m,2);
6324   if (n) PetscValidIntPointer(n,3);
6325   if (m) *m = mat->rmap->n;
6326   if (n) *n = mat->cmap->n;
6327   PetscFunctionReturn(0);
6328 }
6329 
6330 #undef __FUNCT__
6331 #define __FUNCT__ "MatGetOwnershipRangeColumn"
6332 /*@
6333    MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6334    this processor. (The columns of the "diagonal block")
6335 
6336    Not Collective, unless matrix has not been allocated, then collective on Mat
6337 
6338    Input Parameters:
6339 .  mat - the matrix
6340 
6341    Output Parameters:
6342 +  m - the global index of the first local column
6343 -  n - one more than the global index of the last local column
6344 
6345    Notes: both output parameters can be NULL on input.
6346 
6347    Level: developer
6348 
6349    Concepts: matrices^column ownership
6350 
6351 .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
6352 
6353 @*/
6354 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
6355 {
6356   PetscFunctionBegin;
6357   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6358   PetscValidType(mat,1);
6359   if (m) PetscValidIntPointer(m,2);
6360   if (n) PetscValidIntPointer(n,3);
6361   MatCheckPreallocated(mat,1);
6362   if (m) *m = mat->cmap->rstart;
6363   if (n) *n = mat->cmap->rend;
6364   PetscFunctionReturn(0);
6365 }
6366 
6367 #undef __FUNCT__
6368 #define __FUNCT__ "MatGetOwnershipRange"
6369 /*@
6370    MatGetOwnershipRange - Returns the range of matrix rows owned by
6371    this processor, assuming that the matrix is laid out with the first
6372    n1 rows on the first processor, the next n2 rows on the second, etc.
6373    For certain parallel layouts this range may not be well defined.
6374 
6375    Not Collective
6376 
6377    Input Parameters:
6378 .  mat - the matrix
6379 
6380    Output Parameters:
6381 +  m - the global index of the first local row
6382 -  n - one more than the global index of the last local row
6383 
6384    Note: Both output parameters can be NULL on input.
6385 $  This function requires that the matrix be preallocated. If you have not preallocated, consider using
6386 $    PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
6387 $  and then MPI_Scan() to calculate prefix sums of the local sizes.
6388 
6389    Level: beginner
6390 
6391    Concepts: matrices^row ownership
6392 
6393 .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()
6394 
6395 @*/
6396 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6397 {
6398   PetscFunctionBegin;
6399   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6400   PetscValidType(mat,1);
6401   if (m) PetscValidIntPointer(m,2);
6402   if (n) PetscValidIntPointer(n,3);
6403   MatCheckPreallocated(mat,1);
6404   if (m) *m = mat->rmap->rstart;
6405   if (n) *n = mat->rmap->rend;
6406   PetscFunctionReturn(0);
6407 }
6408 
6409 #undef __FUNCT__
6410 #define __FUNCT__ "MatGetOwnershipRanges"
6411 /*@C
6412    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6413    each process
6414 
6415    Not Collective, unless matrix has not been allocated, then collective on Mat
6416 
6417    Input Parameters:
6418 .  mat - the matrix
6419 
6420    Output Parameters:
6421 .  ranges - start of each processors portion plus one more than the total length at the end
6422 
6423    Level: beginner
6424 
6425    Concepts: matrices^row ownership
6426 
6427 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
6428 
6429 @*/
6430 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6431 {
6432   PetscErrorCode ierr;
6433 
6434   PetscFunctionBegin;
6435   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6436   PetscValidType(mat,1);
6437   MatCheckPreallocated(mat,1);
6438   ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr);
6439   PetscFunctionReturn(0);
6440 }
6441 
6442 #undef __FUNCT__
6443 #define __FUNCT__ "MatGetOwnershipRangesColumn"
6444 /*@C
6445    MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6446    this processor. (The columns of the "diagonal blocks" for each process)
6447 
6448    Not Collective, unless matrix has not been allocated, then collective on Mat
6449 
6450    Input Parameters:
6451 .  mat - the matrix
6452 
6453    Output Parameters:
6454 .  ranges - start of each processors portion plus one more then the total length at the end
6455 
6456    Level: beginner
6457 
6458    Concepts: matrices^column ownership
6459 
6460 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
6461 
6462 @*/
6463 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6464 {
6465   PetscErrorCode ierr;
6466 
6467   PetscFunctionBegin;
6468   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6469   PetscValidType(mat,1);
6470   MatCheckPreallocated(mat,1);
6471   ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr);
6472   PetscFunctionReturn(0);
6473 }
6474 
6475 #undef __FUNCT__
6476 #define __FUNCT__ "MatGetOwnershipIS"
6477 /*@C
6478    MatGetOwnershipIS - Get row and column ownership as index sets
6479 
6480    Not Collective
6481 
6482    Input Arguments:
6483 .  A - matrix of type Elemental
6484 
6485    Output Arguments:
6486 +  rows - rows in which this process owns elements
6487 .  cols - columns in which this process owns elements
6488 
6489    Level: intermediate
6490 
6491 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL, MatSetValues()
6492 @*/
6493 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6494 {
6495   PetscErrorCode ierr,(*f)(Mat,IS*,IS*);
6496 
6497   PetscFunctionBegin;
6498   MatCheckPreallocated(A,1);
6499   ierr = PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);CHKERRQ(ierr);
6500   if (f) {
6501     ierr = (*f)(A,rows,cols);CHKERRQ(ierr);
6502   } else {   /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6503     if (rows) {ierr = ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);CHKERRQ(ierr);}
6504     if (cols) {ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);CHKERRQ(ierr);}
6505   }
6506   PetscFunctionReturn(0);
6507 }
6508 
6509 #undef __FUNCT__
6510 #define __FUNCT__ "MatILUFactorSymbolic"
6511 /*@C
6512    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6513    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6514    to complete the factorization.
6515 
6516    Collective on Mat
6517 
6518    Input Parameters:
6519 +  mat - the matrix
6520 .  row - row permutation
6521 .  column - column permutation
6522 -  info - structure containing
6523 $      levels - number of levels of fill.
6524 $      expected fill - as ratio of original fill.
6525 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6526                 missing diagonal entries)
6527 
6528    Output Parameters:
6529 .  fact - new matrix that has been symbolically factored
6530 
6531    Notes: See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
6532 
6533    Most users should employ the simplified KSP interface for linear solvers
6534    instead of working directly with matrix algebra routines such as this.
6535    See, e.g., KSPCreate().
6536 
6537    Level: developer
6538 
6539   Concepts: matrices^symbolic LU factorization
6540   Concepts: matrices^factorization
6541   Concepts: LU^symbolic factorization
6542 
6543 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6544           MatGetOrdering(), MatFactorInfo
6545 
6546     Developer Note: fortran interface is not autogenerated as the f90
6547     interface defintion cannot be generated correctly [due to MatFactorInfo]
6548 
6549 @*/
6550 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6551 {
6552   PetscErrorCode ierr;
6553 
6554   PetscFunctionBegin;
6555   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6556   PetscValidType(mat,1);
6557   PetscValidHeaderSpecific(row,IS_CLASSID,2);
6558   PetscValidHeaderSpecific(col,IS_CLASSID,3);
6559   PetscValidPointer(info,4);
6560   PetscValidPointer(fact,5);
6561   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6562   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6563   if (!(fact)->ops->ilufactorsymbolic) {
6564     const MatSolverPackage spackage;
6565     ierr = MatFactorGetSolverPackage(fact,&spackage);CHKERRQ(ierr);
6566     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6567   }
6568   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6569   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6570   MatCheckPreallocated(mat,2);
6571 
6572   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6573   ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
6574   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6575   PetscFunctionReturn(0);
6576 }
6577 
6578 #undef __FUNCT__
6579 #define __FUNCT__ "MatICCFactorSymbolic"
6580 /*@C
6581    MatICCFactorSymbolic - Performs symbolic incomplete
6582    Cholesky factorization for a symmetric matrix.  Use
6583    MatCholeskyFactorNumeric() to complete the factorization.
6584 
6585    Collective on Mat
6586 
6587    Input Parameters:
6588 +  mat - the matrix
6589 .  perm - row and column permutation
6590 -  info - structure containing
6591 $      levels - number of levels of fill.
6592 $      expected fill - as ratio of original fill.
6593 
6594    Output Parameter:
6595 .  fact - the factored matrix
6596 
6597    Notes:
6598    Most users should employ the KSP interface for linear solvers
6599    instead of working directly with matrix algebra routines such as this.
6600    See, e.g., KSPCreate().
6601 
6602    Level: developer
6603 
6604   Concepts: matrices^symbolic incomplete Cholesky factorization
6605   Concepts: matrices^factorization
6606   Concepts: Cholsky^symbolic factorization
6607 
6608 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
6609 
6610     Developer Note: fortran interface is not autogenerated as the f90
6611     interface defintion cannot be generated correctly [due to MatFactorInfo]
6612 
6613 @*/
6614 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6615 {
6616   PetscErrorCode ierr;
6617 
6618   PetscFunctionBegin;
6619   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6620   PetscValidType(mat,1);
6621   PetscValidHeaderSpecific(perm,IS_CLASSID,2);
6622   PetscValidPointer(info,3);
6623   PetscValidPointer(fact,4);
6624   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6625   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6626   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6627   if (!(fact)->ops->iccfactorsymbolic) {
6628     const MatSolverPackage spackage;
6629     ierr = MatFactorGetSolverPackage(fact,&spackage);CHKERRQ(ierr);
6630     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6631   }
6632   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6633   MatCheckPreallocated(mat,2);
6634 
6635   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6636   ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
6637   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6638   PetscFunctionReturn(0);
6639 }
6640 
6641 #undef __FUNCT__
6642 #define __FUNCT__ "MatGetSubMatrices"
6643 /*@C
6644    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
6645    points to an array of valid matrices, they may be reused to store the new
6646    submatrices.
6647 
6648    Collective on Mat
6649 
6650    Input Parameters:
6651 +  mat - the matrix
6652 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6653 .  irow, icol - index sets of rows and columns to extract
6654 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6655 
6656    Output Parameter:
6657 .  submat - the array of submatrices
6658 
6659    Notes:
6660    MatGetSubMatrices() can extract ONLY sequential submatrices
6661    (from both sequential and parallel matrices). Use MatGetSubMatrix()
6662    to extract a parallel submatrix.
6663 
6664    Some matrix types place restrictions on the row and column
6665    indices, such as that they be sorted or that they be equal to each other.
6666 
6667    The index sets may not have duplicate entries.
6668 
6669    When extracting submatrices from a parallel matrix, each processor can
6670    form a different submatrix by setting the rows and columns of its
6671    individual index sets according to the local submatrix desired.
6672 
6673    When finished using the submatrices, the user should destroy
6674    them with MatDestroyMatrices().
6675 
6676    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6677    original matrix has not changed from that last call to MatGetSubMatrices().
6678 
6679    This routine creates the matrices in submat; you should NOT create them before
6680    calling it. It also allocates the array of matrix pointers submat.
6681 
6682    For BAIJ matrices the index sets must respect the block structure, that is if they
6683    request one row/column in a block, they must request all rows/columns that are in
6684    that block. For example, if the block size is 2 you cannot request just row 0 and
6685    column 0.
6686 
6687    Fortran Note:
6688    The Fortran interface is slightly different from that given below; it
6689    requires one to pass in  as submat a Mat (integer) array of size at least m.
6690 
6691    Level: advanced
6692 
6693    Concepts: matrices^accessing submatrices
6694    Concepts: submatrices
6695 
6696 .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6697 @*/
6698 PetscErrorCode MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6699 {
6700   PetscErrorCode ierr;
6701   PetscInt       i;
6702   PetscBool      eq;
6703 
6704   PetscFunctionBegin;
6705   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6706   PetscValidType(mat,1);
6707   if (n) {
6708     PetscValidPointer(irow,3);
6709     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6710     PetscValidPointer(icol,4);
6711     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6712   }
6713   PetscValidPointer(submat,6);
6714   if (n && scall == MAT_REUSE_MATRIX) {
6715     PetscValidPointer(*submat,6);
6716     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6717   }
6718   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6719   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6720   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6721   MatCheckPreallocated(mat,1);
6722 
6723   ierr = PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
6724   ierr = (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6725   ierr = PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
6726   for (i=0; i<n; i++) {
6727     (*submat)[i]->factortype = MAT_FACTOR_NONE;  /* in case in place factorization was previously done on submatrix */
6728     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6729       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6730       if (eq) {
6731         if (mat->symmetric) {
6732           ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6733         } else if (mat->hermitian) {
6734           ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6735         } else if (mat->structurally_symmetric) {
6736           ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6737         }
6738       }
6739     }
6740   }
6741   PetscFunctionReturn(0);
6742 }
6743 
6744 #undef __FUNCT__
6745 #define __FUNCT__ "MatGetSubMatricesMPI"
6746 PetscErrorCode MatGetSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6747 {
6748   PetscErrorCode ierr;
6749   PetscInt       i;
6750   PetscBool      eq;
6751 
6752   PetscFunctionBegin;
6753   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6754   PetscValidType(mat,1);
6755   if (n) {
6756     PetscValidPointer(irow,3);
6757     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6758     PetscValidPointer(icol,4);
6759     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6760   }
6761   PetscValidPointer(submat,6);
6762   if (n && scall == MAT_REUSE_MATRIX) {
6763     PetscValidPointer(*submat,6);
6764     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6765   }
6766   if (!mat->ops->getsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6767   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6768   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6769   MatCheckPreallocated(mat,1);
6770 
6771   ierr = PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
6772   ierr = (*mat->ops->getsubmatricesmpi)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6773   ierr = PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
6774   for (i=0; i<n; i++) {
6775     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6776       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6777       if (eq) {
6778         if (mat->symmetric) {
6779           ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6780         } else if (mat->hermitian) {
6781           ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6782         } else if (mat->structurally_symmetric) {
6783           ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6784         }
6785       }
6786     }
6787   }
6788   PetscFunctionReturn(0);
6789 }
6790 
6791 #undef __FUNCT__
6792 #define __FUNCT__ "MatDestroyMatrices"
6793 /*@C
6794    MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().
6795 
6796    Collective on Mat
6797 
6798    Input Parameters:
6799 +  n - the number of local matrices
6800 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6801                        sequence of MatGetSubMatrices())
6802 
6803    Level: advanced
6804 
6805     Notes: Frees not only the matrices, but also the array that contains the matrices
6806            In Fortran will not free the array.
6807 
6808 .seealso: MatGetSubMatrices()
6809 @*/
6810 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
6811 {
6812   PetscErrorCode ierr;
6813   PetscInt       i;
6814 
6815   PetscFunctionBegin;
6816   if (!*mat) PetscFunctionReturn(0);
6817   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6818   PetscValidPointer(mat,2);
6819   for (i=0; i<n; i++) {
6820     ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr);
6821   }
6822   /* memory is allocated even if n = 0 */
6823   ierr = PetscFree(*mat);CHKERRQ(ierr);
6824   *mat = NULL;
6825   PetscFunctionReturn(0);
6826 }
6827 
6828 #undef __FUNCT__
6829 #define __FUNCT__ "MatGetSeqNonzeroStructure"
6830 /*@C
6831    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
6832 
6833    Collective on Mat
6834 
6835    Input Parameters:
6836 .  mat - the matrix
6837 
6838    Output Parameter:
6839 .  matstruct - the sequential matrix with the nonzero structure of mat
6840 
6841   Level: intermediate
6842 
6843 .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
6844 @*/
6845 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6846 {
6847   PetscErrorCode ierr;
6848 
6849   PetscFunctionBegin;
6850   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6851   PetscValidPointer(matstruct,2);
6852 
6853   PetscValidType(mat,1);
6854   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6855   MatCheckPreallocated(mat,1);
6856 
6857   if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6858   ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
6859   ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr);
6860   ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
6861   PetscFunctionReturn(0);
6862 }
6863 
6864 #undef __FUNCT__
6865 #define __FUNCT__ "MatDestroySeqNonzeroStructure"
6866 /*@C
6867    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
6868 
6869    Collective on Mat
6870 
6871    Input Parameters:
6872 .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
6873                        sequence of MatGetSequentialNonzeroStructure())
6874 
6875    Level: advanced
6876 
6877     Notes: Frees not only the matrices, but also the array that contains the matrices
6878 
6879 .seealso: MatGetSeqNonzeroStructure()
6880 @*/
6881 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
6882 {
6883   PetscErrorCode ierr;
6884 
6885   PetscFunctionBegin;
6886   PetscValidPointer(mat,1);
6887   ierr = MatDestroy(mat);CHKERRQ(ierr);
6888   PetscFunctionReturn(0);
6889 }
6890 
6891 #undef __FUNCT__
6892 #define __FUNCT__ "MatIncreaseOverlap"
6893 /*@
6894    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6895    replaces the index sets by larger ones that represent submatrices with
6896    additional overlap.
6897 
6898    Collective on Mat
6899 
6900    Input Parameters:
6901 +  mat - the matrix
6902 .  n   - the number of index sets
6903 .  is  - the array of index sets (these index sets will changed during the call)
6904 -  ov  - the additional overlap requested
6905 
6906    Options Database:
6907 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
6908 
6909    Level: developer
6910 
6911    Concepts: overlap
6912    Concepts: ASM^computing overlap
6913 
6914 .seealso: MatGetSubMatrices()
6915 @*/
6916 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6917 {
6918   PetscErrorCode ierr;
6919 
6920   PetscFunctionBegin;
6921   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6922   PetscValidType(mat,1);
6923   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6924   if (n) {
6925     PetscValidPointer(is,3);
6926     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
6927   }
6928   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6929   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6930   MatCheckPreallocated(mat,1);
6931 
6932   if (!ov) PetscFunctionReturn(0);
6933   if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6934   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
6935   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
6936   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
6937   PetscFunctionReturn(0);
6938 }
6939 
6940 
6941 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt);
6942 
6943 #undef __FUNCT__
6944 #define __FUNCT__ "MatIncreaseOverlapSplit"
6945 /*@
6946    MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across
6947    a sub communicator, replaces the index sets by larger ones that represent submatrices with
6948    additional overlap.
6949 
6950    Collective on Mat
6951 
6952    Input Parameters:
6953 +  mat - the matrix
6954 .  n   - the number of index sets
6955 .  is  - the array of index sets (these index sets will changed during the call)
6956 -  ov  - the additional overlap requested
6957 
6958    Options Database:
6959 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
6960 
6961    Level: developer
6962 
6963    Concepts: overlap
6964    Concepts: ASM^computing overlap
6965 
6966 .seealso: MatGetSubMatrices()
6967 @*/
6968 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov)
6969 {
6970   PetscInt       i;
6971   PetscErrorCode ierr;
6972 
6973   PetscFunctionBegin;
6974   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6975   PetscValidType(mat,1);
6976   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6977   if (n) {
6978     PetscValidPointer(is,3);
6979     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
6980   }
6981   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6982   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6983   MatCheckPreallocated(mat,1);
6984   if (!ov) PetscFunctionReturn(0);
6985   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
6986   for(i=0; i<n; i++){
6987 	ierr =  MatIncreaseOverlapSplit_Single(mat,&is[i],ov);CHKERRQ(ierr);
6988   }
6989   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
6990   PetscFunctionReturn(0);
6991 }
6992 
6993 
6994 
6995 
6996 #undef __FUNCT__
6997 #define __FUNCT__ "MatGetBlockSize"
6998 /*@
6999    MatGetBlockSize - Returns the matrix block size.
7000 
7001    Not Collective
7002 
7003    Input Parameter:
7004 .  mat - the matrix
7005 
7006    Output Parameter:
7007 .  bs - block size
7008 
7009    Notes:
7010     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7011 
7012    If the block size has not been set yet this routine returns 1.
7013 
7014    Level: intermediate
7015 
7016    Concepts: matrices^block size
7017 
7018 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
7019 @*/
7020 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
7021 {
7022   PetscFunctionBegin;
7023   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7024   PetscValidIntPointer(bs,2);
7025   *bs = PetscAbs(mat->rmap->bs);
7026   PetscFunctionReturn(0);
7027 }
7028 
7029 #undef __FUNCT__
7030 #define __FUNCT__ "MatGetBlockSizes"
7031 /*@
7032    MatGetBlockSizes - Returns the matrix block row and column sizes.
7033 
7034    Not Collective
7035 
7036    Input Parameter:
7037 .  mat - the matrix
7038 
7039    Output Parameter:
7040 .  rbs - row block size
7041 .  cbs - coumn block size
7042 
7043    Notes:
7044     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7045     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7046 
7047    If a block size has not been set yet this routine returns 1.
7048 
7049    Level: intermediate
7050 
7051    Concepts: matrices^block size
7052 
7053 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes()
7054 @*/
7055 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
7056 {
7057   PetscFunctionBegin;
7058   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7059   if (rbs) PetscValidIntPointer(rbs,2);
7060   if (cbs) PetscValidIntPointer(cbs,3);
7061   if (rbs) *rbs = PetscAbs(mat->rmap->bs);
7062   if (cbs) *cbs = PetscAbs(mat->cmap->bs);
7063   PetscFunctionReturn(0);
7064 }
7065 
7066 #undef __FUNCT__
7067 #define __FUNCT__ "MatSetBlockSize"
7068 /*@
7069    MatSetBlockSize - Sets the matrix block size.
7070 
7071    Logically Collective on Mat
7072 
7073    Input Parameters:
7074 +  mat - the matrix
7075 -  bs - block size
7076 
7077    Notes:
7078     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7079 
7080      This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later
7081 
7082    Level: intermediate
7083 
7084    Concepts: matrices^block size
7085 
7086 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes()
7087 @*/
7088 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
7089 {
7090   PetscErrorCode ierr;
7091 
7092   PetscFunctionBegin;
7093   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7094   PetscValidLogicalCollectiveInt(mat,bs,2);
7095   ierr = PetscLayoutSetBlockSize(mat->rmap,bs);CHKERRQ(ierr);
7096   ierr = PetscLayoutSetBlockSize(mat->cmap,bs);CHKERRQ(ierr);
7097   PetscFunctionReturn(0);
7098 }
7099 
7100 #undef __FUNCT__
7101 #define __FUNCT__ "MatSetBlockSizes"
7102 /*@
7103    MatSetBlockSizes - Sets the matrix block row and column sizes.
7104 
7105    Logically Collective on Mat
7106 
7107    Input Parameters:
7108 +  mat - the matrix
7109 -  rbs - row block size
7110 -  cbs - column block size
7111 
7112    Notes:
7113     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7114     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7115 
7116     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later
7117 
7118     The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs().
7119 
7120    Level: intermediate
7121 
7122    Concepts: matrices^block size
7123 
7124 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes()
7125 @*/
7126 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
7127 {
7128   PetscErrorCode ierr;
7129 
7130   PetscFunctionBegin;
7131   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7132   PetscValidLogicalCollectiveInt(mat,rbs,2);
7133   PetscValidLogicalCollectiveInt(mat,cbs,3);
7134   ierr = PetscLayoutSetBlockSize(mat->rmap,rbs);CHKERRQ(ierr);
7135   ierr = PetscLayoutSetBlockSize(mat->cmap,cbs);CHKERRQ(ierr);
7136   PetscFunctionReturn(0);
7137 }
7138 
7139 #undef __FUNCT__
7140 #define __FUNCT__ "MatSetBlockSizesFromMats"
7141 /*@
7142    MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices
7143 
7144    Logically Collective on Mat
7145 
7146    Input Parameters:
7147 +  mat - the matrix
7148 .  fromRow - matrix from which to copy row block size
7149 -  fromCol - matrix from which to copy column block size (can be same as fromRow)
7150 
7151    Level: developer
7152 
7153    Concepts: matrices^block size
7154 
7155 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes()
7156 @*/
7157 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)
7158 {
7159   PetscErrorCode ierr;
7160 
7161   PetscFunctionBegin;
7162   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7163   PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2);
7164   PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3);
7165   if (fromRow->rmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);CHKERRQ(ierr);}
7166   if (fromCol->cmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);CHKERRQ(ierr);}
7167   PetscFunctionReturn(0);
7168 }
7169 
7170 #undef __FUNCT__
7171 #define __FUNCT__ "MatResidual"
7172 /*@
7173    MatResidual - Default routine to calculate the residual.
7174 
7175    Collective on Mat and Vec
7176 
7177    Input Parameters:
7178 +  mat - the matrix
7179 .  b   - the right-hand-side
7180 -  x   - the approximate solution
7181 
7182    Output Parameter:
7183 .  r - location to store the residual
7184 
7185    Level: developer
7186 
7187 .keywords: MG, default, multigrid, residual
7188 
7189 .seealso: PCMGSetResidual()
7190 @*/
7191 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r)
7192 {
7193   PetscErrorCode ierr;
7194 
7195   PetscFunctionBegin;
7196   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7197   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
7198   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
7199   PetscValidHeaderSpecific(r,VEC_CLASSID,4);
7200   PetscValidType(mat,1);
7201   MatCheckPreallocated(mat,1);
7202   ierr  = PetscLogEventBegin(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7203   if (!mat->ops->residual) {
7204     ierr = MatMult(mat,x,r);CHKERRQ(ierr);
7205     ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr);
7206   } else {
7207     ierr  = (*mat->ops->residual)(mat,b,x,r);CHKERRQ(ierr);
7208   }
7209   ierr  = PetscLogEventEnd(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7210   PetscFunctionReturn(0);
7211 }
7212 
7213 #undef __FUNCT__
7214 #define __FUNCT__ "MatGetRowIJ"
7215 /*@C
7216     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
7217 
7218    Collective on Mat
7219 
7220     Input Parameters:
7221 +   mat - the matrix
7222 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
7223 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
7224 -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
7225                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7226                  always used.
7227 
7228     Output Parameters:
7229 +   n - number of rows in the (possibly compressed) matrix
7230 .   ia - the row pointers [of length n+1]
7231 .   ja - the column indices
7232 -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
7233            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
7234 
7235     Level: developer
7236 
7237     Notes: You CANNOT change any of the ia[] or ja[] values.
7238 
7239            Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values
7240 
7241     Fortran Node
7242 
7243            In Fortran use
7244 $           PetscInt ia(1), ja(1)
7245 $           PetscOffset iia, jja
7246 $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
7247 $      Acess the ith and jth entries via ia(iia + i) and ja(jja + j)
7248 $
7249 $          or
7250 $
7251 $           PetscInt, pointer :: ia(:),ja(:)
7252 $    call  MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
7253 $      Acess the ith and jth entries via ia(i) and ja(j)
7254 
7255 
7256 
7257 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
7258 @*/
7259 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7260 {
7261   PetscErrorCode ierr;
7262 
7263   PetscFunctionBegin;
7264   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7265   PetscValidType(mat,1);
7266   PetscValidIntPointer(n,4);
7267   if (ia) PetscValidIntPointer(ia,5);
7268   if (ja) PetscValidIntPointer(ja,6);
7269   PetscValidIntPointer(done,7);
7270   MatCheckPreallocated(mat,1);
7271   if (!mat->ops->getrowij) *done = PETSC_FALSE;
7272   else {
7273     *done = PETSC_TRUE;
7274     ierr  = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7275     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7276     ierr  = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7277   }
7278   PetscFunctionReturn(0);
7279 }
7280 
7281 #undef __FUNCT__
7282 #define __FUNCT__ "MatGetColumnIJ"
7283 /*@C
7284     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
7285 
7286     Collective on Mat
7287 
7288     Input Parameters:
7289 +   mat - the matrix
7290 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7291 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7292                 symmetrized
7293 .   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7294                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7295                  always used.
7296 .   n - number of columns in the (possibly compressed) matrix
7297 .   ia - the column pointers
7298 -   ja - the row indices
7299 
7300     Output Parameters:
7301 .   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
7302 
7303     Note:
7304     This routine zeros out n, ia, and ja. This is to prevent accidental
7305     us of the array after it has been restored. If you pass NULL, it will
7306     not zero the pointers.  Use of ia or ja after MatRestoreColumnIJ() is invalid.
7307 
7308     Level: developer
7309 
7310 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7311 @*/
7312 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7313 {
7314   PetscErrorCode ierr;
7315 
7316   PetscFunctionBegin;
7317   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7318   PetscValidType(mat,1);
7319   PetscValidIntPointer(n,4);
7320   if (ia) PetscValidIntPointer(ia,5);
7321   if (ja) PetscValidIntPointer(ja,6);
7322   PetscValidIntPointer(done,7);
7323   MatCheckPreallocated(mat,1);
7324   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
7325   else {
7326     *done = PETSC_TRUE;
7327     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7328   }
7329   PetscFunctionReturn(0);
7330 }
7331 
7332 #undef __FUNCT__
7333 #define __FUNCT__ "MatRestoreRowIJ"
7334 /*@C
7335     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
7336     MatGetRowIJ().
7337 
7338     Collective on Mat
7339 
7340     Input Parameters:
7341 +   mat - the matrix
7342 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7343 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7344                 symmetrized
7345 .   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7346                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7347                  always used.
7348 .   n - size of (possibly compressed) matrix
7349 .   ia - the row pointers
7350 -   ja - the column indices
7351 
7352     Output Parameters:
7353 .   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7354 
7355     Note:
7356     This routine zeros out n, ia, and ja. This is to prevent accidental
7357     us of the array after it has been restored. If you pass NULL, it will
7358     not zero the pointers.  Use of ia or ja after MatRestoreRowIJ() is invalid.
7359 
7360     Level: developer
7361 
7362 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7363 @*/
7364 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7365 {
7366   PetscErrorCode ierr;
7367 
7368   PetscFunctionBegin;
7369   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7370   PetscValidType(mat,1);
7371   if (ia) PetscValidIntPointer(ia,5);
7372   if (ja) PetscValidIntPointer(ja,6);
7373   PetscValidIntPointer(done,7);
7374   MatCheckPreallocated(mat,1);
7375 
7376   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
7377   else {
7378     *done = PETSC_TRUE;
7379     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7380     if (n)  *n = 0;
7381     if (ia) *ia = NULL;
7382     if (ja) *ja = NULL;
7383   }
7384   PetscFunctionReturn(0);
7385 }
7386 
7387 #undef __FUNCT__
7388 #define __FUNCT__ "MatRestoreColumnIJ"
7389 /*@C
7390     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
7391     MatGetColumnIJ().
7392 
7393     Collective on Mat
7394 
7395     Input Parameters:
7396 +   mat - the matrix
7397 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7398 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7399                 symmetrized
7400 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7401                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7402                  always used.
7403 
7404     Output Parameters:
7405 +   n - size of (possibly compressed) matrix
7406 .   ia - the column pointers
7407 .   ja - the row indices
7408 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7409 
7410     Level: developer
7411 
7412 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
7413 @*/
7414 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7415 {
7416   PetscErrorCode ierr;
7417 
7418   PetscFunctionBegin;
7419   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7420   PetscValidType(mat,1);
7421   if (ia) PetscValidIntPointer(ia,5);
7422   if (ja) PetscValidIntPointer(ja,6);
7423   PetscValidIntPointer(done,7);
7424   MatCheckPreallocated(mat,1);
7425 
7426   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
7427   else {
7428     *done = PETSC_TRUE;
7429     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7430     if (n)  *n = 0;
7431     if (ia) *ia = NULL;
7432     if (ja) *ja = NULL;
7433   }
7434   PetscFunctionReturn(0);
7435 }
7436 
7437 #undef __FUNCT__
7438 #define __FUNCT__ "MatColoringPatch"
7439 /*@C
7440     MatColoringPatch -Used inside matrix coloring routines that
7441     use MatGetRowIJ() and/or MatGetColumnIJ().
7442 
7443     Collective on Mat
7444 
7445     Input Parameters:
7446 +   mat - the matrix
7447 .   ncolors - max color value
7448 .   n   - number of entries in colorarray
7449 -   colorarray - array indicating color for each column
7450 
7451     Output Parameters:
7452 .   iscoloring - coloring generated using colorarray information
7453 
7454     Level: developer
7455 
7456 .seealso: MatGetRowIJ(), MatGetColumnIJ()
7457 
7458 @*/
7459 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7460 {
7461   PetscErrorCode ierr;
7462 
7463   PetscFunctionBegin;
7464   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7465   PetscValidType(mat,1);
7466   PetscValidIntPointer(colorarray,4);
7467   PetscValidPointer(iscoloring,5);
7468   MatCheckPreallocated(mat,1);
7469 
7470   if (!mat->ops->coloringpatch) {
7471     ierr = ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);CHKERRQ(ierr);
7472   } else {
7473     ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
7474   }
7475   PetscFunctionReturn(0);
7476 }
7477 
7478 
7479 #undef __FUNCT__
7480 #define __FUNCT__ "MatSetUnfactored"
7481 /*@
7482    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
7483 
7484    Logically Collective on Mat
7485 
7486    Input Parameter:
7487 .  mat - the factored matrix to be reset
7488 
7489    Notes:
7490    This routine should be used only with factored matrices formed by in-place
7491    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7492    format).  This option can save memory, for example, when solving nonlinear
7493    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7494    ILU(0) preconditioner.
7495 
7496    Note that one can specify in-place ILU(0) factorization by calling
7497 .vb
7498      PCType(pc,PCILU);
7499      PCFactorSeUseInPlace(pc);
7500 .ve
7501    or by using the options -pc_type ilu -pc_factor_in_place
7502 
7503    In-place factorization ILU(0) can also be used as a local
7504    solver for the blocks within the block Jacobi or additive Schwarz
7505    methods (runtime option: -sub_pc_factor_in_place).  See Users-Manual: ch_pc
7506    for details on setting local solver options.
7507 
7508    Most users should employ the simplified KSP interface for linear solvers
7509    instead of working directly with matrix algebra routines such as this.
7510    See, e.g., KSPCreate().
7511 
7512    Level: developer
7513 
7514 .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace()
7515 
7516    Concepts: matrices^unfactored
7517 
7518 @*/
7519 PetscErrorCode MatSetUnfactored(Mat mat)
7520 {
7521   PetscErrorCode ierr;
7522 
7523   PetscFunctionBegin;
7524   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7525   PetscValidType(mat,1);
7526   MatCheckPreallocated(mat,1);
7527   mat->factortype = MAT_FACTOR_NONE;
7528   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
7529   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
7530   PetscFunctionReturn(0);
7531 }
7532 
7533 /*MC
7534     MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.
7535 
7536     Synopsis:
7537     MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7538 
7539     Not collective
7540 
7541     Input Parameter:
7542 .   x - matrix
7543 
7544     Output Parameters:
7545 +   xx_v - the Fortran90 pointer to the array
7546 -   ierr - error code
7547 
7548     Example of Usage:
7549 .vb
7550       PetscScalar, pointer xx_v(:,:)
7551       ....
7552       call MatDenseGetArrayF90(x,xx_v,ierr)
7553       a = xx_v(3)
7554       call MatDenseRestoreArrayF90(x,xx_v,ierr)
7555 .ve
7556 
7557     Level: advanced
7558 
7559 .seealso:  MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90()
7560 
7561     Concepts: matrices^accessing array
7562 
7563 M*/
7564 
7565 /*MC
7566     MatDenseRestoreArrayF90 - Restores a matrix array that has been
7567     accessed with MatDenseGetArrayF90().
7568 
7569     Synopsis:
7570     MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7571 
7572     Not collective
7573 
7574     Input Parameters:
7575 +   x - matrix
7576 -   xx_v - the Fortran90 pointer to the array
7577 
7578     Output Parameter:
7579 .   ierr - error code
7580 
7581     Example of Usage:
7582 .vb
7583        PetscScalar, pointer xx_v(:,:)
7584        ....
7585        call MatDenseGetArrayF90(x,xx_v,ierr)
7586        a = xx_v(3)
7587        call MatDenseRestoreArrayF90(x,xx_v,ierr)
7588 .ve
7589 
7590     Level: advanced
7591 
7592 .seealso:  MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90()
7593 
7594 M*/
7595 
7596 
7597 /*MC
7598     MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.
7599 
7600     Synopsis:
7601     MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7602 
7603     Not collective
7604 
7605     Input Parameter:
7606 .   x - matrix
7607 
7608     Output Parameters:
7609 +   xx_v - the Fortran90 pointer to the array
7610 -   ierr - error code
7611 
7612     Example of Usage:
7613 .vb
7614       PetscScalar, pointer xx_v(:)
7615       ....
7616       call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7617       a = xx_v(3)
7618       call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7619 .ve
7620 
7621     Level: advanced
7622 
7623 .seealso:  MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90()
7624 
7625     Concepts: matrices^accessing array
7626 
7627 M*/
7628 
7629 /*MC
7630     MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7631     accessed with MatSeqAIJGetArrayF90().
7632 
7633     Synopsis:
7634     MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7635 
7636     Not collective
7637 
7638     Input Parameters:
7639 +   x - matrix
7640 -   xx_v - the Fortran90 pointer to the array
7641 
7642     Output Parameter:
7643 .   ierr - error code
7644 
7645     Example of Usage:
7646 .vb
7647        PetscScalar, pointer xx_v(:)
7648        ....
7649        call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7650        a = xx_v(3)
7651        call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7652 .ve
7653 
7654     Level: advanced
7655 
7656 .seealso:  MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90()
7657 
7658 M*/
7659 
7660 
7661 #undef __FUNCT__
7662 #define __FUNCT__ "MatGetSubMatrix"
7663 /*@
7664     MatGetSubMatrix - Gets a single submatrix on the same number of processors
7665                       as the original matrix.
7666 
7667     Collective on Mat
7668 
7669     Input Parameters:
7670 +   mat - the original matrix
7671 .   isrow - parallel IS containing the rows this processor should obtain
7672 .   iscol - parallel IS containing all columns you wish to keep. Each process should list the columns that will be in IT's "diagonal part" in the new matrix.
7673 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7674 
7675     Output Parameter:
7676 .   newmat - the new submatrix, of the same type as the old
7677 
7678     Level: advanced
7679 
7680     Notes:
7681     The submatrix will be able to be multiplied with vectors using the same layout as iscol.
7682 
7683     Some matrix types place restrictions on the row and column indices, such
7684     as that they be sorted or that they be equal to each other.
7685 
7686     The index sets may not have duplicate entries.
7687 
7688       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7689    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
7690    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7691    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
7692    you are finished using it.
7693 
7694     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7695     the input matrix.
7696 
7697     If iscol is NULL then all columns are obtained (not supported in Fortran).
7698 
7699    Example usage:
7700    Consider the following 8x8 matrix with 34 non-zero values, that is
7701    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7702    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7703    as follows:
7704 
7705 .vb
7706             1  2  0  |  0  3  0  |  0  4
7707     Proc0   0  5  6  |  7  0  0  |  8  0
7708             9  0 10  | 11  0  0  | 12  0
7709     -------------------------------------
7710            13  0 14  | 15 16 17  |  0  0
7711     Proc1   0 18  0  | 19 20 21  |  0  0
7712             0  0  0  | 22 23  0  | 24  0
7713     -------------------------------------
7714     Proc2  25 26 27  |  0  0 28  | 29  0
7715            30  0  0  | 31 32 33  |  0 34
7716 .ve
7717 
7718     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is
7719 
7720 .vb
7721             2  0  |  0  3  0  |  0
7722     Proc0   5  6  |  7  0  0  |  8
7723     -------------------------------
7724     Proc1  18  0  | 19 20 21  |  0
7725     -------------------------------
7726     Proc2  26 27  |  0  0 28  | 29
7727             0  0  | 31 32 33  |  0
7728 .ve
7729 
7730 
7731     Concepts: matrices^submatrices
7732 
7733 .seealso: MatGetSubMatrices()
7734 @*/
7735 PetscErrorCode MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7736 {
7737   PetscErrorCode ierr;
7738   PetscMPIInt    size;
7739   Mat            *local;
7740   IS             iscoltmp;
7741 
7742   PetscFunctionBegin;
7743   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7744   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
7745   if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
7746   PetscValidPointer(newmat,5);
7747   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5);
7748   PetscValidType(mat,1);
7749   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7750   if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX");
7751 
7752   MatCheckPreallocated(mat,1);
7753   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
7754 
7755   if (!iscol || isrow == iscol) {
7756     PetscBool   stride;
7757     PetscMPIInt grabentirematrix = 0,grab;
7758     ierr = PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);CHKERRQ(ierr);
7759     if (stride) {
7760       PetscInt first,step,n,rstart,rend;
7761       ierr = ISStrideGetInfo(isrow,&first,&step);CHKERRQ(ierr);
7762       if (step == 1) {
7763         ierr = MatGetOwnershipRange(mat,&rstart,&rend);CHKERRQ(ierr);
7764         if (rstart == first) {
7765           ierr = ISGetLocalSize(isrow,&n);CHKERRQ(ierr);
7766           if (n == rend-rstart) {
7767             grabentirematrix = 1;
7768           }
7769         }
7770       }
7771     }
7772     ierr = MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr);
7773     if (grab) {
7774       ierr = PetscInfo(mat,"Getting entire matrix as submatrix\n");CHKERRQ(ierr);
7775       if (cll == MAT_INITIAL_MATRIX) {
7776         *newmat = mat;
7777         ierr    = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr);
7778       }
7779       PetscFunctionReturn(0);
7780     }
7781   }
7782 
7783   if (!iscol) {
7784     ierr = ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr);
7785   } else {
7786     iscoltmp = iscol;
7787   }
7788 
7789   /* if original matrix is on just one processor then use submatrix generated */
7790   if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7791     ierr = MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
7792     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7793     PetscFunctionReturn(0);
7794   } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) {
7795     ierr    = MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
7796     *newmat = *local;
7797     ierr    = PetscFree(local);CHKERRQ(ierr);
7798     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7799     PetscFunctionReturn(0);
7800   } else if (!mat->ops->getsubmatrix) {
7801     /* Create a new matrix type that implements the operation using the full matrix */
7802     ierr = PetscLogEventBegin(MAT_GetSubMatrix,mat,0,0,0);CHKERRQ(ierr);
7803     switch (cll) {
7804     case MAT_INITIAL_MATRIX:
7805       ierr = MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr);
7806       break;
7807     case MAT_REUSE_MATRIX:
7808       ierr = MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr);
7809       break;
7810     default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7811     }
7812     ierr = PetscLogEventEnd(MAT_GetSubMatrix,mat,0,0,0);CHKERRQ(ierr);
7813     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7814     PetscFunctionReturn(0);
7815   }
7816 
7817   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7818   ierr = PetscLogEventBegin(MAT_GetSubMatrix,mat,0,0,0);CHKERRQ(ierr);
7819   ierr = (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr);
7820   ierr = PetscLogEventEnd(MAT_GetSubMatrix,mat,0,0,0);CHKERRQ(ierr);
7821   if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7822   if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);}
7823   PetscFunctionReturn(0);
7824 }
7825 
7826 #undef __FUNCT__
7827 #define __FUNCT__ "MatStashSetInitialSize"
7828 /*@
7829    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7830    used during the assembly process to store values that belong to
7831    other processors.
7832 
7833    Not Collective
7834 
7835    Input Parameters:
7836 +  mat   - the matrix
7837 .  size  - the initial size of the stash.
7838 -  bsize - the initial size of the block-stash(if used).
7839 
7840    Options Database Keys:
7841 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
7842 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
7843 
7844    Level: intermediate
7845 
7846    Notes:
7847      The block-stash is used for values set with MatSetValuesBlocked() while
7848      the stash is used for values set with MatSetValues()
7849 
7850      Run with the option -info and look for output of the form
7851      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7852      to determine the appropriate value, MM, to use for size and
7853      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7854      to determine the value, BMM to use for bsize
7855 
7856    Concepts: stash^setting matrix size
7857    Concepts: matrices^stash
7858 
7859 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
7860 
7861 @*/
7862 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7863 {
7864   PetscErrorCode ierr;
7865 
7866   PetscFunctionBegin;
7867   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7868   PetscValidType(mat,1);
7869   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
7870   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
7871   PetscFunctionReturn(0);
7872 }
7873 
7874 #undef __FUNCT__
7875 #define __FUNCT__ "MatInterpolateAdd"
7876 /*@
7877    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
7878      the matrix
7879 
7880    Neighbor-wise Collective on Mat
7881 
7882    Input Parameters:
7883 +  mat   - the matrix
7884 .  x,y - the vectors
7885 -  w - where the result is stored
7886 
7887    Level: intermediate
7888 
7889    Notes:
7890     w may be the same vector as y.
7891 
7892     This allows one to use either the restriction or interpolation (its transpose)
7893     matrix to do the interpolation
7894 
7895     Concepts: interpolation
7896 
7897 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7898 
7899 @*/
7900 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7901 {
7902   PetscErrorCode ierr;
7903   PetscInt       M,N,Ny;
7904 
7905   PetscFunctionBegin;
7906   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7907   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7908   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7909   PetscValidHeaderSpecific(w,VEC_CLASSID,4);
7910   PetscValidType(A,1);
7911   MatCheckPreallocated(A,1);
7912   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
7913   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
7914   if (M == Ny) {
7915     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
7916   } else {
7917     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
7918   }
7919   PetscFunctionReturn(0);
7920 }
7921 
7922 #undef __FUNCT__
7923 #define __FUNCT__ "MatInterpolate"
7924 /*@
7925    MatInterpolate - y = A*x or A'*x depending on the shape of
7926      the matrix
7927 
7928    Neighbor-wise Collective on Mat
7929 
7930    Input Parameters:
7931 +  mat   - the matrix
7932 -  x,y - the vectors
7933 
7934    Level: intermediate
7935 
7936    Notes:
7937     This allows one to use either the restriction or interpolation (its transpose)
7938     matrix to do the interpolation
7939 
7940    Concepts: matrices^interpolation
7941 
7942 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7943 
7944 @*/
7945 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
7946 {
7947   PetscErrorCode ierr;
7948   PetscInt       M,N,Ny;
7949 
7950   PetscFunctionBegin;
7951   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7952   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7953   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7954   PetscValidType(A,1);
7955   MatCheckPreallocated(A,1);
7956   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
7957   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
7958   if (M == Ny) {
7959     ierr = MatMult(A,x,y);CHKERRQ(ierr);
7960   } else {
7961     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
7962   }
7963   PetscFunctionReturn(0);
7964 }
7965 
7966 #undef __FUNCT__
7967 #define __FUNCT__ "MatRestrict"
7968 /*@
7969    MatRestrict - y = A*x or A'*x
7970 
7971    Neighbor-wise Collective on Mat
7972 
7973    Input Parameters:
7974 +  mat   - the matrix
7975 -  x,y - the vectors
7976 
7977    Level: intermediate
7978 
7979    Notes:
7980     This allows one to use either the restriction or interpolation (its transpose)
7981     matrix to do the restriction
7982 
7983    Concepts: matrices^restriction
7984 
7985 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
7986 
7987 @*/
7988 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
7989 {
7990   PetscErrorCode ierr;
7991   PetscInt       M,N,Ny;
7992 
7993   PetscFunctionBegin;
7994   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7995   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7996   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7997   PetscValidType(A,1);
7998   MatCheckPreallocated(A,1);
7999 
8000   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8001   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8002   if (M == Ny) {
8003     ierr = MatMult(A,x,y);CHKERRQ(ierr);
8004   } else {
8005     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
8006   }
8007   PetscFunctionReturn(0);
8008 }
8009 
8010 #undef __FUNCT__
8011 #define __FUNCT__ "MatGetNullSpace"
8012 /*@
8013    MatGetNullSpace - retrieves the null space to a matrix.
8014 
8015    Logically Collective on Mat and MatNullSpace
8016 
8017    Input Parameters:
8018 +  mat - the matrix
8019 -  nullsp - the null space object
8020 
8021    Level: developer
8022 
8023    Concepts: null space^attaching to matrix
8024 
8025 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace()
8026 @*/
8027 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
8028 {
8029   PetscFunctionBegin;
8030   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8031   PetscValidType(mat,1);
8032   PetscValidPointer(nullsp,2);
8033   *nullsp = mat->nullsp;
8034   PetscFunctionReturn(0);
8035 }
8036 
8037 #undef __FUNCT__
8038 #define __FUNCT__ "MatSetNullSpace"
8039 /*@
8040    MatSetNullSpace - attaches a null space to a matrix.
8041 
8042    Logically Collective on Mat and MatNullSpace
8043 
8044    Input Parameters:
8045 +  mat - the matrix
8046 -  nullsp - the null space object
8047 
8048    Level: advanced
8049 
8050    Notes:
8051       This null space is used by the linear solvers. Overwrites any previous null space that may have been attached
8052 
8053       For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should
8054       call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense.
8055 
8056       You can remove the null space by calling this routine with an nullsp of NULL
8057 
8058 
8059       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8060    the domain of a matrix A (from R^n to R^m (m rows, n columns) R^n = the direct sum of the null space of A, n(A), + the range of A^T, R(A^T).
8061    Similarly R^m = direct sum n(A^T) + R(A).  Hence the linear system A x = b has a solution only if b in R(A) (or correspondingly b is orthogonal to
8062    n(A^T)) and if x is a solution then x + alpha n(A) is a solution for any alpha. The minimum norm solution is orthogonal to n(A). For problems without a solution
8063    the solution that minimizes the norm of the residual (the least squares solution) can be obtained by solving A x = \hat{b} where \hat{b} is b orthogonalized to the n(A^T).
8064 
8065       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8066 
8067    Concepts: null space^attaching to matrix
8068 
8069 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8070 @*/
8071 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp)
8072 {
8073   PetscErrorCode ierr;
8074 
8075   PetscFunctionBegin;
8076   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8077   PetscValidType(mat,1);
8078   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8079   MatCheckPreallocated(mat,1);
8080   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8081   ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr);
8082   mat->nullsp = nullsp;
8083   PetscFunctionReturn(0);
8084 }
8085 
8086 #undef __FUNCT__
8087 #define __FUNCT__ "MatGetTransposeNullSpace"
8088 /*@
8089    MatGetTransposeNullSpace - retrieves the null space to a matrix.
8090 
8091    Logically Collective on Mat and MatNullSpace
8092 
8093    Input Parameters:
8094 +  mat - the matrix
8095 -  nullsp - the null space object
8096 
8097    Level: developer
8098 
8099    Notes:
8100       This null space is used by solvers. Overwrites any previous null space that may have been attached
8101 
8102    Concepts: null space^attaching to matrix
8103 
8104 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace()
8105 @*/
8106 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp)
8107 {
8108   PetscFunctionBegin;
8109   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8110   PetscValidType(mat,1);
8111   PetscValidPointer(nullsp,2);
8112   *nullsp = mat->transnullsp;
8113   PetscFunctionReturn(0);
8114 }
8115 
8116 #undef __FUNCT__
8117 #define __FUNCT__ "MatSetTransposeNullSpace"
8118 /*@
8119    MatSetTransposeNullSpace - attaches a null space to a matrix.
8120 
8121    Logically Collective on Mat and MatNullSpace
8122 
8123    Input Parameters:
8124 +  mat - the matrix
8125 -  nullsp - the null space object
8126 
8127    Level: advanced
8128 
8129    Notes:
8130       For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) this allows the linear system to be solved in a least squares sense.
8131       You must also call MatSetNullSpace()
8132 
8133 
8134       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8135    the domain of a matrix A (from R^n to R^m (m rows, n columns) R^n = the direct sum of the null space of A, n(A), + the range of A^T, R(A^T).
8136    Similarly R^m = direct sum n(A^T) + R(A).  Hence the linear system A x = b has a solution only if b in R(A) (or correspondingly b is orthogonal to
8137    n(A^T)) and if x is a solution then x + alpha n(A) is a solution for any alpha. The minimum norm solution is orthogonal to n(A). For problems without a solution
8138    the solution that minimizes the norm of the residual (the least squares solution) can be obtained by solving A x = \hat{b} where \hat{b} is b orthogonalized to the n(A^T).
8139 
8140       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8141 
8142    Concepts: null space^attaching to matrix
8143 
8144 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetNullSpace(), MatNullSpaceRemove()
8145 @*/
8146 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp)
8147 {
8148   PetscErrorCode ierr;
8149 
8150   PetscFunctionBegin;
8151   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8152   PetscValidType(mat,1);
8153   PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8154   MatCheckPreallocated(mat,1);
8155   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
8156   ierr = MatNullSpaceDestroy(&mat->transnullsp);CHKERRQ(ierr);
8157   mat->transnullsp = nullsp;
8158   PetscFunctionReturn(0);
8159 }
8160 
8161 #undef __FUNCT__
8162 #define __FUNCT__ "MatSetNearNullSpace"
8163 /*@
8164    MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions
8165         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.
8166 
8167    Logically Collective on Mat and MatNullSpace
8168 
8169    Input Parameters:
8170 +  mat - the matrix
8171 -  nullsp - the null space object
8172 
8173    Level: advanced
8174 
8175    Notes:
8176       Overwrites any previous near null space that may have been attached
8177 
8178       You can remove the null space by calling this routine with an nullsp of NULL
8179 
8180    Concepts: null space^attaching to matrix
8181 
8182 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody()
8183 @*/
8184 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
8185 {
8186   PetscErrorCode ierr;
8187 
8188   PetscFunctionBegin;
8189   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8190   PetscValidType(mat,1);
8191   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8192   MatCheckPreallocated(mat,1);
8193   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8194   ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr);
8195   mat->nearnullsp = nullsp;
8196   PetscFunctionReturn(0);
8197 }
8198 
8199 #undef __FUNCT__
8200 #define __FUNCT__ "MatGetNearNullSpace"
8201 /*@
8202    MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()
8203 
8204    Not Collective
8205 
8206    Input Parameters:
8207 .  mat - the matrix
8208 
8209    Output Parameters:
8210 .  nullsp - the null space object, NULL if not set
8211 
8212    Level: developer
8213 
8214    Concepts: null space^attaching to matrix
8215 
8216 .seealso: MatSetNearNullSpace(), MatGetNullSpace()
8217 @*/
8218 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
8219 {
8220   PetscFunctionBegin;
8221   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8222   PetscValidType(mat,1);
8223   PetscValidPointer(nullsp,2);
8224   MatCheckPreallocated(mat,1);
8225   *nullsp = mat->nearnullsp;
8226   PetscFunctionReturn(0);
8227 }
8228 
8229 #undef __FUNCT__
8230 #define __FUNCT__ "MatICCFactor"
8231 /*@C
8232    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
8233 
8234    Collective on Mat
8235 
8236    Input Parameters:
8237 +  mat - the matrix
8238 .  row - row/column permutation
8239 .  fill - expected fill factor >= 1.0
8240 -  level - level of fill, for ICC(k)
8241 
8242    Notes:
8243    Probably really in-place only when level of fill is zero, otherwise allocates
8244    new space to store factored matrix and deletes previous memory.
8245 
8246    Most users should employ the simplified KSP interface for linear solvers
8247    instead of working directly with matrix algebra routines such as this.
8248    See, e.g., KSPCreate().
8249 
8250    Level: developer
8251 
8252    Concepts: matrices^incomplete Cholesky factorization
8253    Concepts: Cholesky factorization
8254 
8255 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
8256 
8257     Developer Note: fortran interface is not autogenerated as the f90
8258     interface defintion cannot be generated correctly [due to MatFactorInfo]
8259 
8260 @*/
8261 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
8262 {
8263   PetscErrorCode ierr;
8264 
8265   PetscFunctionBegin;
8266   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8267   PetscValidType(mat,1);
8268   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
8269   PetscValidPointer(info,3);
8270   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
8271   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8272   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8273   if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8274   MatCheckPreallocated(mat,1);
8275   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
8276   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8277   PetscFunctionReturn(0);
8278 }
8279 
8280 #undef __FUNCT__
8281 #define __FUNCT__ "MatSetValuesAdifor"
8282 /*@
8283    MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.
8284 
8285    Not Collective
8286 
8287    Input Parameters:
8288 +  mat - the matrix
8289 .  nl - leading dimension of v
8290 -  v - the values compute with ADIFOR
8291 
8292    Level: developer
8293 
8294    Notes:
8295      Must call MatSetColoring() before using this routine. Also this matrix must already
8296      have its nonzero pattern determined.
8297 
8298 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
8299           MatSetValues(), MatSetColoring()
8300 @*/
8301 PetscErrorCode MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
8302 {
8303   PetscErrorCode ierr;
8304 
8305   PetscFunctionBegin;
8306   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8307   PetscValidType(mat,1);
8308   PetscValidPointer(v,3);
8309 
8310   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8311   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
8312   if (!mat->ops->setvaluesadifor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8313   ierr = (*mat->ops->setvaluesadifor)(mat,nl,v);CHKERRQ(ierr);
8314   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
8315   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8316   PetscFunctionReturn(0);
8317 }
8318 
8319 #undef __FUNCT__
8320 #define __FUNCT__ "MatDiagonalScaleLocal"
8321 /*@
8322    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
8323          ghosted ones.
8324 
8325    Not Collective
8326 
8327    Input Parameters:
8328 +  mat - the matrix
8329 -  diag = the diagonal values, including ghost ones
8330 
8331    Level: developer
8332 
8333    Notes: Works only for MPIAIJ and MPIBAIJ matrices
8334 
8335 .seealso: MatDiagonalScale()
8336 @*/
8337 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
8338 {
8339   PetscErrorCode ierr;
8340   PetscMPIInt    size;
8341 
8342   PetscFunctionBegin;
8343   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8344   PetscValidHeaderSpecific(diag,VEC_CLASSID,2);
8345   PetscValidType(mat,1);
8346 
8347   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8348   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8349   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
8350   if (size == 1) {
8351     PetscInt n,m;
8352     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
8353     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
8354     if (m == n) {
8355       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
8356     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
8357   } else {
8358     ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr);
8359   }
8360   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8361   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8362   PetscFunctionReturn(0);
8363 }
8364 
8365 #undef __FUNCT__
8366 #define __FUNCT__ "MatGetInertia"
8367 /*@
8368    MatGetInertia - Gets the inertia from a factored matrix
8369 
8370    Collective on Mat
8371 
8372    Input Parameter:
8373 .  mat - the matrix
8374 
8375    Output Parameters:
8376 +   nneg - number of negative eigenvalues
8377 .   nzero - number of zero eigenvalues
8378 -   npos - number of positive eigenvalues
8379 
8380    Level: advanced
8381 
8382    Notes: Matrix must have been factored by MatCholeskyFactor()
8383 
8384 
8385 @*/
8386 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
8387 {
8388   PetscErrorCode ierr;
8389 
8390   PetscFunctionBegin;
8391   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8392   PetscValidType(mat,1);
8393   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8394   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
8395   if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8396   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
8397   PetscFunctionReturn(0);
8398 }
8399 
8400 /* ----------------------------------------------------------------*/
8401 #undef __FUNCT__
8402 #define __FUNCT__ "MatSolves"
8403 /*@C
8404    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
8405 
8406    Neighbor-wise Collective on Mat and Vecs
8407 
8408    Input Parameters:
8409 +  mat - the factored matrix
8410 -  b - the right-hand-side vectors
8411 
8412    Output Parameter:
8413 .  x - the result vectors
8414 
8415    Notes:
8416    The vectors b and x cannot be the same.  I.e., one cannot
8417    call MatSolves(A,x,x).
8418 
8419    Notes:
8420    Most users should employ the simplified KSP interface for linear solvers
8421    instead of working directly with matrix algebra routines such as this.
8422    See, e.g., KSPCreate().
8423 
8424    Level: developer
8425 
8426    Concepts: matrices^triangular solves
8427 
8428 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
8429 @*/
8430 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
8431 {
8432   PetscErrorCode ierr;
8433 
8434   PetscFunctionBegin;
8435   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8436   PetscValidType(mat,1);
8437   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
8438   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8439   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
8440 
8441   if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8442   MatCheckPreallocated(mat,1);
8443   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8444   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
8445   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8446   PetscFunctionReturn(0);
8447 }
8448 
8449 #undef __FUNCT__
8450 #define __FUNCT__ "MatIsSymmetric"
8451 /*@
8452    MatIsSymmetric - Test whether a matrix is symmetric
8453 
8454    Collective on Mat
8455 
8456    Input Parameter:
8457 +  A - the matrix to test
8458 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
8459 
8460    Output Parameters:
8461 .  flg - the result
8462 
8463    Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
8464 
8465    Level: intermediate
8466 
8467    Concepts: matrix^symmetry
8468 
8469 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
8470 @*/
8471 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
8472 {
8473   PetscErrorCode ierr;
8474 
8475   PetscFunctionBegin;
8476   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8477   PetscValidPointer(flg,2);
8478 
8479   if (!A->symmetric_set) {
8480     if (!A->ops->issymmetric) {
8481       MatType mattype;
8482       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8483       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8484     }
8485     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8486     if (!tol) {
8487       A->symmetric_set = PETSC_TRUE;
8488       A->symmetric     = *flg;
8489       if (A->symmetric) {
8490         A->structurally_symmetric_set = PETSC_TRUE;
8491         A->structurally_symmetric     = PETSC_TRUE;
8492       }
8493     }
8494   } else if (A->symmetric) {
8495     *flg = PETSC_TRUE;
8496   } else if (!tol) {
8497     *flg = PETSC_FALSE;
8498   } else {
8499     if (!A->ops->issymmetric) {
8500       MatType mattype;
8501       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8502       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8503     }
8504     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8505   }
8506   PetscFunctionReturn(0);
8507 }
8508 
8509 #undef __FUNCT__
8510 #define __FUNCT__ "MatIsHermitian"
8511 /*@
8512    MatIsHermitian - Test whether a matrix is Hermitian
8513 
8514    Collective on Mat
8515 
8516    Input Parameter:
8517 +  A - the matrix to test
8518 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
8519 
8520    Output Parameters:
8521 .  flg - the result
8522 
8523    Level: intermediate
8524 
8525    Concepts: matrix^symmetry
8526 
8527 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
8528           MatIsSymmetricKnown(), MatIsSymmetric()
8529 @*/
8530 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
8531 {
8532   PetscErrorCode ierr;
8533 
8534   PetscFunctionBegin;
8535   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8536   PetscValidPointer(flg,2);
8537 
8538   if (!A->hermitian_set) {
8539     if (!A->ops->ishermitian) {
8540       MatType mattype;
8541       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8542       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8543     }
8544     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8545     if (!tol) {
8546       A->hermitian_set = PETSC_TRUE;
8547       A->hermitian     = *flg;
8548       if (A->hermitian) {
8549         A->structurally_symmetric_set = PETSC_TRUE;
8550         A->structurally_symmetric     = PETSC_TRUE;
8551       }
8552     }
8553   } else if (A->hermitian) {
8554     *flg = PETSC_TRUE;
8555   } else if (!tol) {
8556     *flg = PETSC_FALSE;
8557   } else {
8558     if (!A->ops->ishermitian) {
8559       MatType mattype;
8560       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8561       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8562     }
8563     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8564   }
8565   PetscFunctionReturn(0);
8566 }
8567 
8568 #undef __FUNCT__
8569 #define __FUNCT__ "MatIsSymmetricKnown"
8570 /*@
8571    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
8572 
8573    Not Collective
8574 
8575    Input Parameter:
8576 .  A - the matrix to check
8577 
8578    Output Parameters:
8579 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
8580 -  flg - the result
8581 
8582    Level: advanced
8583 
8584    Concepts: matrix^symmetry
8585 
8586    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
8587          if you want it explicitly checked
8588 
8589 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8590 @*/
8591 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8592 {
8593   PetscFunctionBegin;
8594   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8595   PetscValidPointer(set,2);
8596   PetscValidPointer(flg,3);
8597   if (A->symmetric_set) {
8598     *set = PETSC_TRUE;
8599     *flg = A->symmetric;
8600   } else {
8601     *set = PETSC_FALSE;
8602   }
8603   PetscFunctionReturn(0);
8604 }
8605 
8606 #undef __FUNCT__
8607 #define __FUNCT__ "MatIsHermitianKnown"
8608 /*@
8609    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
8610 
8611    Not Collective
8612 
8613    Input Parameter:
8614 .  A - the matrix to check
8615 
8616    Output Parameters:
8617 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8618 -  flg - the result
8619 
8620    Level: advanced
8621 
8622    Concepts: matrix^symmetry
8623 
8624    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8625          if you want it explicitly checked
8626 
8627 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8628 @*/
8629 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8630 {
8631   PetscFunctionBegin;
8632   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8633   PetscValidPointer(set,2);
8634   PetscValidPointer(flg,3);
8635   if (A->hermitian_set) {
8636     *set = PETSC_TRUE;
8637     *flg = A->hermitian;
8638   } else {
8639     *set = PETSC_FALSE;
8640   }
8641   PetscFunctionReturn(0);
8642 }
8643 
8644 #undef __FUNCT__
8645 #define __FUNCT__ "MatIsStructurallySymmetric"
8646 /*@
8647    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
8648 
8649    Collective on Mat
8650 
8651    Input Parameter:
8652 .  A - the matrix to test
8653 
8654    Output Parameters:
8655 .  flg - the result
8656 
8657    Level: intermediate
8658 
8659    Concepts: matrix^symmetry
8660 
8661 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8662 @*/
8663 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
8664 {
8665   PetscErrorCode ierr;
8666 
8667   PetscFunctionBegin;
8668   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8669   PetscValidPointer(flg,2);
8670   if (!A->structurally_symmetric_set) {
8671     if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8672     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
8673 
8674     A->structurally_symmetric_set = PETSC_TRUE;
8675   }
8676   *flg = A->structurally_symmetric;
8677   PetscFunctionReturn(0);
8678 }
8679 
8680 #undef __FUNCT__
8681 #define __FUNCT__ "MatStashGetInfo"
8682 extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
8683 /*@
8684    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8685        to be communicated to other processors during the MatAssemblyBegin/End() process
8686 
8687     Not collective
8688 
8689    Input Parameter:
8690 .   vec - the vector
8691 
8692    Output Parameters:
8693 +   nstash   - the size of the stash
8694 .   reallocs - the number of additional mallocs incurred.
8695 .   bnstash   - the size of the block stash
8696 -   breallocs - the number of additional mallocs incurred.in the block stash
8697 
8698    Level: advanced
8699 
8700 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
8701 
8702 @*/
8703 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8704 {
8705   PetscErrorCode ierr;
8706 
8707   PetscFunctionBegin;
8708   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
8709   ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
8710   PetscFunctionReturn(0);
8711 }
8712 
8713 #undef __FUNCT__
8714 #define __FUNCT__ "MatCreateVecs"
8715 /*@C
8716    MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same
8717      parallel layout
8718 
8719    Collective on Mat
8720 
8721    Input Parameter:
8722 .  mat - the matrix
8723 
8724    Output Parameter:
8725 +   right - (optional) vector that the matrix can be multiplied against
8726 -   left - (optional) vector that the matrix vector product can be stored in
8727 
8728    Notes:
8729     The blocksize of the returned vectors is determined by the row and column block sizes set with MatSetBlockSizes() or the single blocksize (same for both) set by MatSetBlockSize().
8730 
8731   Notes: These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed
8732 
8733   Level: advanced
8734 
8735 .seealso: MatCreate(), VecDestroy()
8736 @*/
8737 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left)
8738 {
8739   PetscErrorCode ierr;
8740 
8741   PetscFunctionBegin;
8742   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8743   PetscValidType(mat,1);
8744   if (mat->ops->getvecs) {
8745     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
8746   } else {
8747     PetscInt rbs,cbs;
8748     ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr);
8749     if (right) {
8750       if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup");
8751       ierr = VecCreate(PetscObjectComm((PetscObject)mat),right);CHKERRQ(ierr);
8752       ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8753       ierr = VecSetBlockSize(*right,cbs);CHKERRQ(ierr);
8754       ierr = VecSetType(*right,VECSTANDARD);CHKERRQ(ierr);
8755       ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr);
8756     }
8757     if (left) {
8758       if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup");
8759       ierr = VecCreate(PetscObjectComm((PetscObject)mat),left);CHKERRQ(ierr);
8760       ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8761       ierr = VecSetBlockSize(*left,rbs);CHKERRQ(ierr);
8762       ierr = VecSetType(*left,VECSTANDARD);CHKERRQ(ierr);
8763       ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr);
8764     }
8765   }
8766   PetscFunctionReturn(0);
8767 }
8768 
8769 #undef __FUNCT__
8770 #define __FUNCT__ "MatFactorInfoInitialize"
8771 /*@C
8772    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8773      with default values.
8774 
8775    Not Collective
8776 
8777    Input Parameters:
8778 .    info - the MatFactorInfo data structure
8779 
8780 
8781    Notes: The solvers are generally used through the KSP and PC objects, for example
8782           PCLU, PCILU, PCCHOLESKY, PCICC
8783 
8784    Level: developer
8785 
8786 .seealso: MatFactorInfo
8787 
8788     Developer Note: fortran interface is not autogenerated as the f90
8789     interface defintion cannot be generated correctly [due to MatFactorInfo]
8790 
8791 @*/
8792 
8793 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
8794 {
8795   PetscErrorCode ierr;
8796 
8797   PetscFunctionBegin;
8798   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
8799   PetscFunctionReturn(0);
8800 }
8801 
8802 #undef __FUNCT__
8803 #define __FUNCT__ "MatFactorSetSchurIS"
8804 /*@
8805    MatFactorSetSchurIS - Set indices corresponding to the Schur complement
8806 
8807    Collective on Mat
8808 
8809    Input Parameters:
8810 +  mat - the factored matrix
8811 -  is - the index set defining the Schur indices (0-based)
8812 
8813    Notes:
8814 
8815    Level: developer
8816 
8817    Concepts:
8818 
8819 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement()
8820 
8821 @*/
8822 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is)
8823 {
8824   PetscErrorCode ierr,(*f)(Mat,IS);
8825 
8826   PetscFunctionBegin;
8827   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8828   PetscValidType(mat,1);
8829   PetscValidHeaderSpecific(is,IS_CLASSID,2);
8830   PetscValidType(is,2);
8831   PetscCheckSameComm(mat,1,is,2);
8832   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
8833   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);CHKERRQ(ierr);
8834   if (!f) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"The selected MatSolverPackage does not support Schur complement computation. You should use MATSOLVERMUMPS or MATSOLVERMKL_PARDISO");
8835   ierr = (*f)(mat,is);CHKERRQ(ierr);
8836   PetscFunctionReturn(0);
8837 }
8838 
8839 #undef __FUNCT__
8840 #define __FUNCT__ "MatFactorCreateSchurComplement"
8841 /*@
8842   MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step
8843 
8844    Logically Collective on Mat
8845 
8846    Input Parameters:
8847 +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
8848 .  *S - location where to return the Schur complement (MATDENSE)
8849 
8850    Notes:
8851    The routine provides a copy of the Schur data stored within solver's data strutures. The caller must destroy the object when it is no longer needed.
8852    If MatFactorInvertSchurComplement has been called, the routine gets back the inverse
8853 
8854    Level: advanced
8855 
8856    References:
8857 
8858 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement()
8859 @*/
8860 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S)
8861 {
8862   PetscErrorCode ierr;
8863 
8864   PetscFunctionBegin;
8865   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8866   ierr = PetscUseMethod(F,"MatFactorCreateSchurComplement_C",(Mat,Mat*),(F,S));CHKERRQ(ierr);
8867   PetscFunctionReturn(0);
8868 }
8869 
8870 #undef __FUNCT__
8871 #define __FUNCT__ "MatFactorGetSchurComplement"
8872 /*@
8873   MatFactorGetSchurComplement - Get a Schur complement matrix object using the current Schur data
8874 
8875    Logically Collective on Mat
8876 
8877    Input Parameters:
8878 +  F - the factored matrix obtained by calling MatGetFactor()
8879 .  *S - location where to return the Schur complement (in MATDENSE format)
8880 
8881    Notes:
8882    Schur complement mode is currently implemented for sequential matrices.
8883    The routine returns a dense matrix pointing to the raw data of the Schur Complement stored within the data strutures of the solver; e.g. if MatFactorInvertSchurComplement has been called, the returned matrix is actually the inverse of the Schur complement.
8884    The caller should call MatFactorRestoreSchurComplement when the object is no longer needed.
8885 
8886    Level: advanced
8887 
8888    References:
8889 
8890 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement()
8891 @*/
8892 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S)
8893 {
8894   PetscErrorCode ierr;
8895 
8896   PetscFunctionBegin;
8897   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8898   ierr = PetscUseMethod(F,"MatFactorGetSchurComplement_C",(Mat,Mat*),(F,S));CHKERRQ(ierr);
8899   PetscFunctionReturn(0);
8900 }
8901 
8902 #undef __FUNCT__
8903 #define __FUNCT__ "MatFactorRestoreSchurComplement"
8904 /*@
8905   MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement
8906 
8907    Logically Collective on Mat
8908 
8909    Input Parameters:
8910 +  F - the factored matrix obtained by calling MatGetFactor()
8911 .  *S - location where the Schur complement is stored
8912 
8913    Notes:
8914 
8915    Level: advanced
8916 
8917    References:
8918 
8919 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement()
8920 @*/
8921 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S)
8922 {
8923   PetscErrorCode ierr;
8924 
8925   PetscFunctionBegin;
8926   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8927   PetscValidHeaderSpecific(*S,MAT_CLASSID,1);
8928   ierr = MatDestroy(S);CHKERRQ(ierr);
8929   PetscFunctionReturn(0);
8930 }
8931 
8932 #undef __FUNCT__
8933 #define __FUNCT__ "MatFactorSolveSchurComplementTranspose"
8934 /*@
8935   MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step
8936 
8937    Logically Collective on Mat
8938 
8939    Input Parameters:
8940 +  F - the factored matrix obtained by calling MatGetFactor()
8941 .  rhs - location where the right hand side of the Schur complement system is stored
8942 -  sol - location where the solution of the Schur complement system has to be returned
8943 
8944    Notes:
8945    The sizes of the vectors should match the size of the Schur complement
8946 
8947    Level: advanced
8948 
8949    References:
8950 
8951 .seealso: MatGetFactor(), MatFactorSetSchurIS()
8952 @*/
8953 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol)
8954 {
8955   PetscErrorCode ierr;
8956 
8957   PetscFunctionBegin;
8958   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8959   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
8960   PetscValidHeaderSpecific(sol,VEC_CLASSID,2);
8961   PetscCheckSameComm(F,1,rhs,2);
8962   PetscCheckSameComm(F,1,sol,3);
8963   ierr = PetscUseMethod(F,"MatFactorSolveSchurComplementTranspose_C",(Mat,Vec,Vec),(F,rhs,sol));CHKERRQ(ierr);
8964   PetscFunctionReturn(0);
8965 }
8966 
8967 #undef __FUNCT__
8968 #define __FUNCT__ "MatFactorSolveSchurComplement"
8969 /*@
8970   MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step
8971 
8972    Logically Collective on Mat
8973 
8974    Input Parameters:
8975 +  F - the factored matrix obtained by calling MatGetFactor()
8976 .  rhs - location where the right hand side of the Schur complement system is stored
8977 -  sol - location where the solution of the Schur complement system has to be returned
8978 
8979    Notes:
8980    The sizes of the vectors should match the size of the Schur complement
8981 
8982    Level: advanced
8983 
8984    References:
8985 
8986 .seealso: MatGetFactor(), MatFactorSetSchurIS()
8987 @*/
8988 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol)
8989 {
8990   PetscErrorCode ierr;
8991 
8992   PetscFunctionBegin;
8993   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8994   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
8995   PetscValidHeaderSpecific(sol,VEC_CLASSID,2);
8996   PetscCheckSameComm(F,1,rhs,2);
8997   PetscCheckSameComm(F,1,sol,3);
8998   ierr = PetscUseMethod(F,"MatFactorSolveSchurComplement_C",(Mat,Vec,Vec),(F,rhs,sol));CHKERRQ(ierr);
8999   PetscFunctionReturn(0);
9000 }
9001 
9002 #undef __FUNCT__
9003 #define __FUNCT__ "MatFactorInvertSchurComplement"
9004 /*@
9005   MatFactorInvertSchurComplement - Invert the raw Schur data computed during the factorization step
9006 
9007    Logically Collective on Mat
9008 
9009    Input Parameters:
9010 +  F - the factored matrix obtained by calling MatGetFactor()
9011 
9012    Notes:
9013 
9014    Level: advanced
9015 
9016    References:
9017 
9018 .seealso: MatGetFactor(), MatFactorSetSchurIS()
9019 @*/
9020 PetscErrorCode MatFactorInvertSchurComplement(Mat F)
9021 {
9022   PetscErrorCode ierr;
9023 
9024   PetscFunctionBegin;
9025   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9026   ierr = PetscUseMethod(F,"MatFactorInvertSchurComplement_C",(Mat),(F));CHKERRQ(ierr);
9027   PetscFunctionReturn(0);
9028 }
9029 
9030 
9031 #undef __FUNCT__
9032 #define __FUNCT__ "MatPtAP"
9033 /*@
9034    MatPtAP - Creates the matrix product C = P^T * A * P
9035 
9036    Neighbor-wise Collective on Mat
9037 
9038    Input Parameters:
9039 +  A - the matrix
9040 .  P - the projection matrix
9041 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9042 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate
9043           if the result is a dense matrix this is irrelevent
9044 
9045    Output Parameters:
9046 .  C - the product matrix
9047 
9048    Notes:
9049    C will be created and must be destroyed by the user with MatDestroy().
9050 
9051    This routine is currently only implemented for pairs of AIJ matrices and classes
9052    which inherit from AIJ.
9053 
9054    Level: intermediate
9055 
9056 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
9057 @*/
9058 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
9059 {
9060   PetscErrorCode ierr;
9061   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9062   PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
9063   PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9064   PetscBool      viatranspose=PETSC_FALSE,viamatmatmatmult=PETSC_FALSE;
9065 
9066   PetscFunctionBegin;
9067   ierr = PetscOptionsGetBool(((PetscObject)A)->options,((PetscObject)A)->prefix,"-matptap_viatranspose",&viatranspose,NULL);CHKERRQ(ierr);
9068   ierr = PetscOptionsGetBool(((PetscObject)A)->options,((PetscObject)A)->prefix,"-matptap_viamatmatmatmult",&viamatmatmatmult,NULL);CHKERRQ(ierr);
9069 
9070   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9071   PetscValidType(A,1);
9072   MatCheckPreallocated(A,1);
9073   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9074   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9075   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9076   PetscValidType(P,2);
9077   MatCheckPreallocated(P,2);
9078   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9079   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9080 
9081   if (A->rmap->N!= A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix A must be square, %D != %D",A->rmap->N,A->cmap->N);
9082   if (P->rmap->N != A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
9083   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9084   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9085 
9086   if (scall == MAT_REUSE_MATRIX) {
9087     PetscValidPointer(*C,5);
9088     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9089     if (viatranspose || viamatmatmatmult) {
9090       Mat Pt;
9091       ierr = MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);CHKERRQ(ierr);
9092       if (viamatmatmatmult) {
9093         ierr = MatMatMatMult(Pt,A,P,scall,fill,C);CHKERRQ(ierr);
9094       } else {
9095         Mat AP;
9096         ierr = MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);CHKERRQ(ierr);
9097         ierr = MatMatMult(Pt,AP,scall,fill,C);CHKERRQ(ierr);
9098         ierr = MatDestroy(&AP);CHKERRQ(ierr);
9099       }
9100       ierr = MatDestroy(&Pt);CHKERRQ(ierr);
9101     } else {
9102       ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9103       ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9104       ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr);
9105       ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9106       ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9107     }
9108     PetscFunctionReturn(0);
9109   }
9110 
9111   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9112   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9113 
9114   fA = A->ops->ptap;
9115   fP = P->ops->ptap;
9116   if (fP == fA) {
9117     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name);
9118     ptap = fA;
9119   } else {
9120     /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
9121     char ptapname[256];
9122     ierr = PetscStrcpy(ptapname,"MatPtAP_");CHKERRQ(ierr);
9123     ierr = PetscStrcat(ptapname,((PetscObject)A)->type_name);CHKERRQ(ierr);
9124     ierr = PetscStrcat(ptapname,"_");CHKERRQ(ierr);
9125     ierr = PetscStrcat(ptapname,((PetscObject)P)->type_name);CHKERRQ(ierr);
9126     ierr = PetscStrcat(ptapname,"_C");CHKERRQ(ierr); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
9127     ierr = PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);CHKERRQ(ierr);
9128     if (!ptap) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatPtAP requires A, %s, to be compatible with P, %s",((PetscObject)A)->type_name,((PetscObject)P)->type_name);
9129   }
9130 
9131   if (viatranspose || viamatmatmatmult) {
9132     Mat Pt;
9133     ierr = MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);CHKERRQ(ierr);
9134     if (viamatmatmatmult) {
9135       ierr = MatMatMatMult(Pt,A,P,scall,fill,C);CHKERRQ(ierr);
9136       ierr = PetscInfo(*C,"MatPtAP via MatMatMatMult\n");CHKERRQ(ierr);
9137     } else {
9138       Mat AP;
9139       ierr = MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);CHKERRQ(ierr);
9140       ierr = MatMatMult(Pt,AP,scall,fill,C);CHKERRQ(ierr);
9141       ierr = MatDestroy(&AP);CHKERRQ(ierr);
9142       ierr = PetscInfo(*C,"MatPtAP via MatTranspose and MatMatMult\n");CHKERRQ(ierr);
9143     }
9144     ierr = MatDestroy(&Pt);CHKERRQ(ierr);
9145   } else {
9146     ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9147     ierr = (*ptap)(A,P,scall,fill,C);CHKERRQ(ierr);
9148     ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9149   }
9150   PetscFunctionReturn(0);
9151 }
9152 
9153 #undef __FUNCT__
9154 #define __FUNCT__ "MatPtAPNumeric"
9155 /*@
9156    MatPtAPNumeric - Computes the matrix product C = P^T * A * P
9157 
9158    Neighbor-wise Collective on Mat
9159 
9160    Input Parameters:
9161 +  A - the matrix
9162 -  P - the projection matrix
9163 
9164    Output Parameters:
9165 .  C - the product matrix
9166 
9167    Notes:
9168    C must have been created by calling MatPtAPSymbolic and must be destroyed by
9169    the user using MatDeatroy().
9170 
9171    This routine is currently only implemented for pairs of AIJ matrices and classes
9172    which inherit from AIJ.  C will be of type MATAIJ.
9173 
9174    Level: intermediate
9175 
9176 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
9177 @*/
9178 PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C)
9179 {
9180   PetscErrorCode ierr;
9181 
9182   PetscFunctionBegin;
9183   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9184   PetscValidType(A,1);
9185   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9186   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9187   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9188   PetscValidType(P,2);
9189   MatCheckPreallocated(P,2);
9190   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9191   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9192   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9193   PetscValidType(C,3);
9194   MatCheckPreallocated(C,3);
9195   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9196   if (P->cmap->N!=C->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->rmap->N);
9197   if (P->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
9198   if (A->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
9199   if (P->cmap->N!=C->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->cmap->N);
9200   MatCheckPreallocated(A,1);
9201 
9202   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9203   ierr = (*C->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr);
9204   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9205   PetscFunctionReturn(0);
9206 }
9207 
9208 #undef __FUNCT__
9209 #define __FUNCT__ "MatPtAPSymbolic"
9210 /*@
9211    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P
9212 
9213    Neighbor-wise Collective on Mat
9214 
9215    Input Parameters:
9216 +  A - the matrix
9217 -  P - the projection matrix
9218 
9219    Output Parameters:
9220 .  C - the (i,j) structure of the product matrix
9221 
9222    Notes:
9223    C will be created and must be destroyed by the user with MatDestroy().
9224 
9225    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9226    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9227    this (i,j) structure by calling MatPtAPNumeric().
9228 
9229    Level: intermediate
9230 
9231 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
9232 @*/
9233 PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
9234 {
9235   PetscErrorCode ierr;
9236 
9237   PetscFunctionBegin;
9238   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9239   PetscValidType(A,1);
9240   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9241   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9242   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9243   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9244   PetscValidType(P,2);
9245   MatCheckPreallocated(P,2);
9246   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9247   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9248   PetscValidPointer(C,3);
9249 
9250   if (P->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
9251   if (A->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
9252   MatCheckPreallocated(A,1);
9253   ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
9254   ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr);
9255   ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
9256 
9257   /* ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); NO! this is not always true -ma */
9258   PetscFunctionReturn(0);
9259 }
9260 
9261 #undef __FUNCT__
9262 #define __FUNCT__ "MatRARt"
9263 /*@
9264    MatRARt - Creates the matrix product C = R * A * R^T
9265 
9266    Neighbor-wise Collective on Mat
9267 
9268    Input Parameters:
9269 +  A - the matrix
9270 .  R - the projection matrix
9271 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9272 -  fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate
9273           if the result is a dense matrix this is irrelevent
9274 
9275    Output Parameters:
9276 .  C - the product matrix
9277 
9278    Notes:
9279    C will be created and must be destroyed by the user with MatDestroy().
9280 
9281    This routine is currently only implemented for pairs of AIJ matrices and classes
9282    which inherit from AIJ.
9283 
9284    Level: intermediate
9285 
9286 .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
9287 @*/
9288 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
9289 {
9290   PetscErrorCode ierr;
9291 
9292   PetscFunctionBegin;
9293   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9294   PetscValidType(A,1);
9295   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9296   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9297   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9298   PetscValidType(R,2);
9299   MatCheckPreallocated(R,2);
9300   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9301   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9302   PetscValidPointer(C,3);
9303   if (R->cmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)R),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N);
9304 
9305   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9306   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9307   MatCheckPreallocated(A,1);
9308 
9309   if (!A->ops->rart) {
9310     MatType mattype;
9311     ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
9312     SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix of type <%s> does not support RARt",mattype);
9313   }
9314   ierr = PetscLogEventBegin(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
9315   ierr = (*A->ops->rart)(A,R,scall,fill,C);CHKERRQ(ierr);
9316   ierr = PetscLogEventEnd(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
9317   PetscFunctionReturn(0);
9318 }
9319 
9320 #undef __FUNCT__
9321 #define __FUNCT__ "MatRARtNumeric"
9322 /*@
9323    MatRARtNumeric - Computes the matrix product C = R * A * R^T
9324 
9325    Neighbor-wise Collective on Mat
9326 
9327    Input Parameters:
9328 +  A - the matrix
9329 -  R - the projection matrix
9330 
9331    Output Parameters:
9332 .  C - the product matrix
9333 
9334    Notes:
9335    C must have been created by calling MatRARtSymbolic and must be destroyed by
9336    the user using MatDestroy().
9337 
9338    This routine is currently only implemented for pairs of AIJ matrices and classes
9339    which inherit from AIJ.  C will be of type MATAIJ.
9340 
9341    Level: intermediate
9342 
9343 .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
9344 @*/
9345 PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C)
9346 {
9347   PetscErrorCode ierr;
9348 
9349   PetscFunctionBegin;
9350   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9351   PetscValidType(A,1);
9352   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9353   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9354   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9355   PetscValidType(R,2);
9356   MatCheckPreallocated(R,2);
9357   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9358   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9359   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9360   PetscValidType(C,3);
9361   MatCheckPreallocated(C,3);
9362   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9363   if (R->rmap->N!=C->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->rmap->N,C->rmap->N);
9364   if (R->cmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N);
9365   if (A->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
9366   if (R->rmap->N!=C->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->rmap->N,C->cmap->N);
9367   MatCheckPreallocated(A,1);
9368 
9369   ierr = PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
9370   ierr = (*A->ops->rartnumeric)(A,R,C);CHKERRQ(ierr);
9371   ierr = PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
9372   PetscFunctionReturn(0);
9373 }
9374 
9375 #undef __FUNCT__
9376 #define __FUNCT__ "MatRARtSymbolic"
9377 /*@
9378    MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T
9379 
9380    Neighbor-wise Collective on Mat
9381 
9382    Input Parameters:
9383 +  A - the matrix
9384 -  R - the projection matrix
9385 
9386    Output Parameters:
9387 .  C - the (i,j) structure of the product matrix
9388 
9389    Notes:
9390    C will be created and must be destroyed by the user with MatDestroy().
9391 
9392    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9393    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9394    this (i,j) structure by calling MatRARtNumeric().
9395 
9396    Level: intermediate
9397 
9398 .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
9399 @*/
9400 PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
9401 {
9402   PetscErrorCode ierr;
9403 
9404   PetscFunctionBegin;
9405   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9406   PetscValidType(A,1);
9407   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9408   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9409   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9410   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9411   PetscValidType(R,2);
9412   MatCheckPreallocated(R,2);
9413   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9414   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9415   PetscValidPointer(C,3);
9416 
9417   if (R->cmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N);
9418   if (A->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
9419   MatCheckPreallocated(A,1);
9420   ierr = PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
9421   ierr = (*A->ops->rartsymbolic)(A,R,fill,C);CHKERRQ(ierr);
9422   ierr = PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
9423 
9424   ierr = MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));CHKERRQ(ierr);
9425   PetscFunctionReturn(0);
9426 }
9427 
9428 #undef __FUNCT__
9429 #define __FUNCT__ "MatMatMult"
9430 /*@
9431    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
9432 
9433    Neighbor-wise Collective on Mat
9434 
9435    Input Parameters:
9436 +  A - the left matrix
9437 .  B - the right matrix
9438 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9439 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
9440           if the result is a dense matrix this is irrelevent
9441 
9442    Output Parameters:
9443 .  C - the product matrix
9444 
9445    Notes:
9446    Unless scall is MAT_REUSE_MATRIX C will be created.
9447 
9448    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9449 
9450    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9451    actually needed.
9452 
9453    If you have many matrices with the same non-zero structure to multiply, you
9454    should either
9455 $   1) use MAT_REUSE_MATRIX in all calls but the first or
9456 $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
9457    In the special case where matrix B (and hence C) are dense you can create the correctly sized matrix C yourself and then call this routine
9458    with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse.
9459 
9460    Level: intermediate
9461 
9462 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(),  MatMatTransposeMult(), MatPtAP()
9463 @*/
9464 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9465 {
9466   PetscErrorCode ierr;
9467   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9468   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9469   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9470 
9471   PetscFunctionBegin;
9472   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9473   PetscValidType(A,1);
9474   MatCheckPreallocated(A,1);
9475   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9476   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9477   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9478   PetscValidType(B,2);
9479   MatCheckPreallocated(B,2);
9480   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9481   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9482   PetscValidPointer(C,3);
9483   if (B->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
9484   if (scall == MAT_REUSE_MATRIX) {
9485     PetscValidPointer(*C,5);
9486     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9487     ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9488     ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9489     ierr = (*(*C)->ops->matmultnumeric)(A,B,*C);CHKERRQ(ierr);
9490     ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9491     ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9492     PetscFunctionReturn(0);
9493   }
9494   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9495   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9496 
9497   fA = A->ops->matmult;
9498   fB = B->ops->matmult;
9499   if (fB == fA) {
9500     if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
9501     mult = fB;
9502   } else {
9503     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9504     char multname[256];
9505     ierr = PetscStrcpy(multname,"MatMatMult_");CHKERRQ(ierr);
9506     ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr);
9507     ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);
9508     ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr);
9509     ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9510     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
9511     if (!mult) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
9512   }
9513   ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9514   ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr);
9515   ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9516   PetscFunctionReturn(0);
9517 }
9518 
9519 #undef __FUNCT__
9520 #define __FUNCT__ "MatMatMultSymbolic"
9521 /*@
9522    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
9523    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().
9524 
9525    Neighbor-wise Collective on Mat
9526 
9527    Input Parameters:
9528 +  A - the left matrix
9529 .  B - the right matrix
9530 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
9531       if C is a dense matrix this is irrelevent
9532 
9533    Output Parameters:
9534 .  C - the product matrix
9535 
9536    Notes:
9537    Unless scall is MAT_REUSE_MATRIX C will be created.
9538 
9539    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9540    actually needed.
9541 
9542    This routine is currently implemented for
9543     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
9544     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9545     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9546 
9547    Level: intermediate
9548 
9549    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
9550      We should incorporate them into PETSc.
9551 
9552 .seealso: MatMatMult(), MatMatMultNumeric()
9553 @*/
9554 PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
9555 {
9556   PetscErrorCode ierr;
9557   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*);
9558   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*);
9559   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL;
9560 
9561   PetscFunctionBegin;
9562   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9563   PetscValidType(A,1);
9564   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9565   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9566 
9567   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9568   PetscValidType(B,2);
9569   MatCheckPreallocated(B,2);
9570   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9571   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9572   PetscValidPointer(C,3);
9573 
9574   if (B->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
9575   if (fill == PETSC_DEFAULT) fill = 2.0;
9576   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9577   MatCheckPreallocated(A,1);
9578 
9579   Asymbolic = A->ops->matmultsymbolic;
9580   Bsymbolic = B->ops->matmultsymbolic;
9581   if (Asymbolic == Bsymbolic) {
9582     if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
9583     symbolic = Bsymbolic;
9584   } else { /* dispatch based on the type of A and B */
9585     char symbolicname[256];
9586     ierr = PetscStrcpy(symbolicname,"MatMatMultSymbolic_");CHKERRQ(ierr);
9587     ierr = PetscStrcat(symbolicname,((PetscObject)A)->type_name);CHKERRQ(ierr);
9588     ierr = PetscStrcat(symbolicname,"_");CHKERRQ(ierr);
9589     ierr = PetscStrcat(symbolicname,((PetscObject)B)->type_name);CHKERRQ(ierr);
9590     ierr = PetscStrcat(symbolicname,"_C");CHKERRQ(ierr);
9591     ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);CHKERRQ(ierr);
9592     if (!symbolic) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatMultSymbolic requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
9593   }
9594   ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9595   ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr);
9596   ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9597   PetscFunctionReturn(0);
9598 }
9599 
9600 #undef __FUNCT__
9601 #define __FUNCT__ "MatMatMultNumeric"
9602 /*@
9603    MatMatMultNumeric - Performs the numeric matrix-matrix product.
9604    Call this routine after first calling MatMatMultSymbolic().
9605 
9606    Neighbor-wise Collective on Mat
9607 
9608    Input Parameters:
9609 +  A - the left matrix
9610 -  B - the right matrix
9611 
9612    Output Parameters:
9613 .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
9614 
9615    Notes:
9616    C must have been created with MatMatMultSymbolic().
9617 
9618    This routine is currently implemented for
9619     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
9620     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9621     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9622 
9623    Level: intermediate
9624 
9625 .seealso: MatMatMult(), MatMatMultSymbolic()
9626 @*/
9627 PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C)
9628 {
9629   PetscErrorCode ierr;
9630 
9631   PetscFunctionBegin;
9632   ierr = MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);CHKERRQ(ierr);
9633   PetscFunctionReturn(0);
9634 }
9635 
9636 #undef __FUNCT__
9637 #define __FUNCT__ "MatMatTransposeMult"
9638 /*@
9639    MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.
9640 
9641    Neighbor-wise Collective on Mat
9642 
9643    Input Parameters:
9644 +  A - the left matrix
9645 .  B - the right matrix
9646 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9647 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9648 
9649    Output Parameters:
9650 .  C - the product matrix
9651 
9652    Notes:
9653    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9654 
9655    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9656 
9657   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9658    actually needed.
9659 
9660    This routine is currently only implemented for pairs of SeqAIJ matrices.  C will be of type MATSEQAIJ.
9661 
9662    Level: intermediate
9663 
9664 .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
9665 @*/
9666 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9667 {
9668   PetscErrorCode ierr;
9669   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9670   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9671 
9672   PetscFunctionBegin;
9673   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9674   PetscValidType(A,1);
9675   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9676   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9677   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9678   PetscValidType(B,2);
9679   MatCheckPreallocated(B,2);
9680   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9681   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9682   PetscValidPointer(C,3);
9683   if (B->cmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, AN %D != BN %D",A->cmap->N,B->cmap->N);
9684   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9685   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9686   MatCheckPreallocated(A,1);
9687 
9688   fA = A->ops->mattransposemult;
9689   if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
9690   fB = B->ops->mattransposemult;
9691   if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
9692   if (fB!=fA) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatTransposeMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
9693 
9694   ierr = PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
9695   if (scall == MAT_INITIAL_MATRIX) {
9696     ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9697     ierr = (*A->ops->mattransposemultsymbolic)(A,B,fill,C);CHKERRQ(ierr);
9698     ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9699   }
9700   ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
9701   ierr = (*A->ops->mattransposemultnumeric)(A,B,*C);CHKERRQ(ierr);
9702   ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
9703   ierr = PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
9704   PetscFunctionReturn(0);
9705 }
9706 
9707 #undef __FUNCT__
9708 #define __FUNCT__ "MatTransposeMatMult"
9709 /*@
9710    MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.
9711 
9712    Neighbor-wise Collective on Mat
9713 
9714    Input Parameters:
9715 +  A - the left matrix
9716 .  B - the right matrix
9717 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9718 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9719 
9720    Output Parameters:
9721 .  C - the product matrix
9722 
9723    Notes:
9724    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9725 
9726    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9727 
9728   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9729    actually needed.
9730 
9731    This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
9732    which inherit from SeqAIJ.  C will be of same type as the input matrices.
9733 
9734    Level: intermediate
9735 
9736 .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
9737 @*/
9738 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9739 {
9740   PetscErrorCode ierr;
9741   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9742   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9743   PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL;
9744 
9745   PetscFunctionBegin;
9746   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9747   PetscValidType(A,1);
9748   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9749   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9750   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9751   PetscValidType(B,2);
9752   MatCheckPreallocated(B,2);
9753   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9754   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9755   PetscValidPointer(C,3);
9756   if (B->rmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->rmap->N);
9757   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9758   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9759   MatCheckPreallocated(A,1);
9760 
9761   fA = A->ops->transposematmult;
9762   fB = B->ops->transposematmult;
9763   if (fB==fA) {
9764     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9765     transposematmult = fA;
9766   } else {
9767     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9768     char multname[256];
9769     ierr = PetscStrcpy(multname,"MatTransposeMatMult_");CHKERRQ(ierr);
9770     ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr);
9771     ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);
9772     ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr);
9773     ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9774     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);CHKERRQ(ierr);
9775     if (!transposematmult) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatTransposeMatMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
9776   }
9777   ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
9778   ierr = (*transposematmult)(A,B,scall,fill,C);CHKERRQ(ierr);
9779   ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
9780   PetscFunctionReturn(0);
9781 }
9782 
9783 #undef __FUNCT__
9784 #define __FUNCT__ "MatMatMatMult"
9785 /*@
9786    MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.
9787 
9788    Neighbor-wise Collective on Mat
9789 
9790    Input Parameters:
9791 +  A - the left matrix
9792 .  B - the middle matrix
9793 .  C - the right matrix
9794 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9795 -  fill - expected fill as ratio of nnz(D)/(nnz(A) + nnz(B)+nnz(C)), use PETSC_DEFAULT if you do not have a good estimate
9796           if the result is a dense matrix this is irrelevent
9797 
9798    Output Parameters:
9799 .  D - the product matrix
9800 
9801    Notes:
9802    Unless scall is MAT_REUSE_MATRIX D will be created.
9803 
9804    MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call
9805 
9806    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9807    actually needed.
9808 
9809    If you have many matrices with the same non-zero structure to multiply, you
9810    should use MAT_REUSE_MATRIX in all calls but the first or
9811 
9812    Level: intermediate
9813 
9814 .seealso: MatMatMult, MatPtAP()
9815 @*/
9816 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
9817 {
9818   PetscErrorCode ierr;
9819   PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9820   PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9821   PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9822   PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9823 
9824   PetscFunctionBegin;
9825   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9826   PetscValidType(A,1);
9827   MatCheckPreallocated(A,1);
9828   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9829   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9830   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9831   PetscValidType(B,2);
9832   MatCheckPreallocated(B,2);
9833   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9834   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9835   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9836   PetscValidPointer(C,3);
9837   MatCheckPreallocated(C,3);
9838   if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9839   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9840   if (B->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
9841   if (C->rmap->N!=B->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",C->rmap->N,B->cmap->N);
9842   if (scall == MAT_REUSE_MATRIX) {
9843     PetscValidPointer(*D,6);
9844     PetscValidHeaderSpecific(*D,MAT_CLASSID,6);
9845     ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9846     ierr = (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
9847     ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9848     PetscFunctionReturn(0);
9849   }
9850   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9851   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9852 
9853   fA = A->ops->matmatmult;
9854   fB = B->ops->matmatmult;
9855   fC = C->ops->matmatmult;
9856   if (fA == fB && fA == fC) {
9857     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9858     mult = fA;
9859   } else {
9860     /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */
9861     char multname[256];
9862     ierr = PetscStrcpy(multname,"MatMatMatMult_");CHKERRQ(ierr);
9863     ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr);
9864     ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);
9865     ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr);
9866     ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);
9867     ierr = PetscStrcat(multname,((PetscObject)C)->type_name);CHKERRQ(ierr);
9868     ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr);
9869     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
9870     if (!mult) SETERRQ3(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatMatMult requires A, %s, to be compatible with B, %s, C, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name,((PetscObject)C)->type_name);
9871   }
9872   ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9873   ierr = (*mult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
9874   ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9875   PetscFunctionReturn(0);
9876 }
9877 
9878 #undef __FUNCT__
9879 #define __FUNCT__ "MatCreateRedundantMatrix"
9880 /*@C
9881    MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
9882 
9883    Collective on Mat
9884 
9885    Input Parameters:
9886 +  mat - the matrix
9887 .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
9888 .  subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used)
9889 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9890 
9891    Output Parameter:
9892 .  matredundant - redundant matrix
9893 
9894    Notes:
9895    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
9896    original matrix has not changed from that last call to MatCreateRedundantMatrix().
9897 
9898    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
9899    calling it.
9900 
9901    Level: advanced
9902 
9903    Concepts: subcommunicator
9904    Concepts: duplicate matrix
9905 
9906 .seealso: MatDestroy()
9907 @*/
9908 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant)
9909 {
9910   PetscErrorCode ierr;
9911   MPI_Comm       comm;
9912   PetscMPIInt    size;
9913   PetscInt       mloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs;
9914   Mat_Redundant  *redund=NULL;
9915   PetscSubcomm   psubcomm=NULL;
9916   MPI_Comm       subcomm_in=subcomm;
9917   Mat            *matseq;
9918   IS             isrow,iscol;
9919   PetscBool      newsubcomm=PETSC_FALSE;
9920 
9921   PetscFunctionBegin;
9922   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
9923   if (size == 1 || nsubcomm == 1) {
9924     if (reuse == MAT_INITIAL_MATRIX) {
9925       ierr = MatDuplicate(mat,MAT_COPY_VALUES,matredundant);CHKERRQ(ierr);
9926     } else {
9927       ierr = MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
9928     }
9929     PetscFunctionReturn(0);
9930   }
9931 
9932   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9933   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
9934     PetscValidPointer(*matredundant,5);
9935     PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5);
9936   }
9937   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9938   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9939   MatCheckPreallocated(mat,1);
9940 
9941   ierr = PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
9942   if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */
9943     /* create psubcomm, then get subcomm */
9944     ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
9945     ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
9946     if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size);
9947 
9948     ierr = PetscSubcommCreate(comm,&psubcomm);CHKERRQ(ierr);
9949     ierr = PetscSubcommSetNumber(psubcomm,nsubcomm);CHKERRQ(ierr);
9950     ierr = PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);CHKERRQ(ierr);
9951     ierr = PetscSubcommSetFromOptions(psubcomm);CHKERRQ(ierr);
9952     ierr = PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);CHKERRQ(ierr);
9953     newsubcomm = PETSC_TRUE;
9954     ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr);
9955   }
9956 
9957   /* get isrow, iscol and a local sequential matrix matseq[0] */
9958   if (reuse == MAT_INITIAL_MATRIX) {
9959     mloc_sub = PETSC_DECIDE;
9960     if (bs < 1) {
9961       ierr = PetscSplitOwnership(subcomm,&mloc_sub,&M);CHKERRQ(ierr);
9962     } else {
9963       ierr = PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);CHKERRQ(ierr);
9964     }
9965     ierr = MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);CHKERRQ(ierr);
9966     rstart = rend - mloc_sub;
9967     ierr = ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);CHKERRQ(ierr);
9968     ierr = ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);CHKERRQ(ierr);
9969   } else { /* reuse == MAT_REUSE_MATRIX */
9970     /* retrieve subcomm */
9971     ierr = PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);CHKERRQ(ierr);
9972     redund = (*matredundant)->redundant;
9973     isrow  = redund->isrow;
9974     iscol  = redund->iscol;
9975     matseq = redund->matseq;
9976   }
9977   ierr = MatGetSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);CHKERRQ(ierr);
9978 
9979   /* get matredundant over subcomm */
9980   if (reuse == MAT_INITIAL_MATRIX) {
9981     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],mloc_sub,reuse,matredundant);CHKERRQ(ierr);
9982 
9983     /* create a supporting struct and attach it to C for reuse */
9984     ierr = PetscNewLog(*matredundant,&redund);CHKERRQ(ierr);
9985     (*matredundant)->redundant = redund;
9986     redund->isrow              = isrow;
9987     redund->iscol              = iscol;
9988     redund->matseq             = matseq;
9989     if (newsubcomm) {
9990       redund->subcomm          = subcomm;
9991     } else {
9992       redund->subcomm          = MPI_COMM_NULL;
9993     }
9994   } else {
9995     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);CHKERRQ(ierr);
9996   }
9997   ierr = PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
9998   PetscFunctionReturn(0);
9999 }
10000 
10001 #undef __FUNCT__
10002 #define __FUNCT__ "MatGetMultiProcBlock"
10003 /*@C
10004    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
10005    a given 'mat' object. Each submatrix can span multiple procs.
10006 
10007    Collective on Mat
10008 
10009    Input Parameters:
10010 +  mat - the matrix
10011 .  subcomm - the subcommunicator obtained by com_split(comm)
10012 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10013 
10014    Output Parameter:
10015 .  subMat - 'parallel submatrices each spans a given subcomm
10016 
10017   Notes:
10018   The submatrix partition across processors is dictated by 'subComm' a
10019   communicator obtained by com_split(comm). The comm_split
10020   is not restriced to be grouped with consecutive original ranks.
10021 
10022   Due the comm_split() usage, the parallel layout of the submatrices
10023   map directly to the layout of the original matrix [wrt the local
10024   row,col partitioning]. So the original 'DiagonalMat' naturally maps
10025   into the 'DiagonalMat' of the subMat, hence it is used directly from
10026   the subMat. However the offDiagMat looses some columns - and this is
10027   reconstructed with MatSetValues()
10028 
10029   Level: advanced
10030 
10031   Concepts: subcommunicator
10032   Concepts: submatrices
10033 
10034 .seealso: MatGetSubMatrices()
10035 @*/
10036 PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
10037 {
10038   PetscErrorCode ierr;
10039   PetscMPIInt    commsize,subCommSize;
10040 
10041   PetscFunctionBegin;
10042   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRQ(ierr);
10043   ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr);
10044   if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
10045 
10046   ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10047   ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr);
10048   ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10049   PetscFunctionReturn(0);
10050 }
10051 
10052 #undef __FUNCT__
10053 #define __FUNCT__ "MatGetLocalSubMatrix"
10054 /*@
10055    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
10056 
10057    Not Collective
10058 
10059    Input Arguments:
10060    mat - matrix to extract local submatrix from
10061    isrow - local row indices for submatrix
10062    iscol - local column indices for submatrix
10063 
10064    Output Arguments:
10065    submat - the submatrix
10066 
10067    Level: intermediate
10068 
10069    Notes:
10070    The submat should be returned with MatRestoreLocalSubMatrix().
10071 
10072    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
10073    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
10074 
10075    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
10076    MatSetValuesBlockedLocal() will also be implemented.
10077 
10078    The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that
10079    matrices obtained with DMCreateMat() generally already have the local to global mapping provided.
10080 
10081 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping()
10082 @*/
10083 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10084 {
10085   PetscErrorCode ierr;
10086 
10087   PetscFunctionBegin;
10088   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10089   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10090   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10091   PetscCheckSameComm(isrow,2,iscol,3);
10092   PetscValidPointer(submat,4);
10093   if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call");
10094 
10095   if (mat->ops->getlocalsubmatrix) {
10096     ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10097   } else {
10098     ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr);
10099   }
10100   PetscFunctionReturn(0);
10101 }
10102 
10103 #undef __FUNCT__
10104 #define __FUNCT__ "MatRestoreLocalSubMatrix"
10105 /*@
10106    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
10107 
10108    Not Collective
10109 
10110    Input Arguments:
10111    mat - matrix to extract local submatrix from
10112    isrow - local row indices for submatrix
10113    iscol - local column indices for submatrix
10114    submat - the submatrix
10115 
10116    Level: intermediate
10117 
10118 .seealso: MatGetLocalSubMatrix()
10119 @*/
10120 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10121 {
10122   PetscErrorCode ierr;
10123 
10124   PetscFunctionBegin;
10125   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10126   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10127   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10128   PetscCheckSameComm(isrow,2,iscol,3);
10129   PetscValidPointer(submat,4);
10130   if (*submat) {
10131     PetscValidHeaderSpecific(*submat,MAT_CLASSID,4);
10132   }
10133 
10134   if (mat->ops->restorelocalsubmatrix) {
10135     ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10136   } else {
10137     ierr = MatDestroy(submat);CHKERRQ(ierr);
10138   }
10139   *submat = NULL;
10140   PetscFunctionReturn(0);
10141 }
10142 
10143 /* --------------------------------------------------------*/
10144 #undef __FUNCT__
10145 #define __FUNCT__ "MatFindZeroDiagonals"
10146 /*@
10147    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no entry in the matrix
10148 
10149    Collective on Mat
10150 
10151    Input Parameter:
10152 .  mat - the matrix
10153 
10154    Output Parameter:
10155 .  is - if any rows have zero diagonals this contains the list of them
10156 
10157    Level: developer
10158 
10159    Concepts: matrix-vector product
10160 
10161 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10162 @*/
10163 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is)
10164 {
10165   PetscErrorCode ierr;
10166 
10167   PetscFunctionBegin;
10168   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10169   PetscValidType(mat,1);
10170   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10171   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10172 
10173   if (!mat->ops->findzerodiagonals) {
10174     Vec                diag;
10175     const PetscScalar *a;
10176     PetscInt          *rows;
10177     PetscInt           rStart, rEnd, r, nrow = 0;
10178 
10179     ierr = MatCreateVecs(mat, &diag, NULL);CHKERRQ(ierr);
10180     ierr = MatGetDiagonal(mat, diag);CHKERRQ(ierr);
10181     ierr = MatGetOwnershipRange(mat, &rStart, &rEnd);CHKERRQ(ierr);
10182     ierr = VecGetArrayRead(diag, &a);CHKERRQ(ierr);
10183     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow;
10184     ierr = PetscMalloc1(nrow, &rows);CHKERRQ(ierr);
10185     nrow = 0;
10186     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart;
10187     ierr = VecRestoreArrayRead(diag, &a);CHKERRQ(ierr);
10188     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10189     ierr = ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);CHKERRQ(ierr);
10190   } else {
10191     ierr = (*mat->ops->findzerodiagonals)(mat, is);CHKERRQ(ierr);
10192   }
10193   PetscFunctionReturn(0);
10194 }
10195 
10196 #undef __FUNCT__
10197 #define __FUNCT__ "MatFindOffBlockDiagonalEntries"
10198 /*@
10199    MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size)
10200 
10201    Collective on Mat
10202 
10203    Input Parameter:
10204 .  mat - the matrix
10205 
10206    Output Parameter:
10207 .  is - contains the list of rows with off block diagonal entries
10208 
10209    Level: developer
10210 
10211    Concepts: matrix-vector product
10212 
10213 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10214 @*/
10215 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is)
10216 {
10217   PetscErrorCode ierr;
10218 
10219   PetscFunctionBegin;
10220   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10221   PetscValidType(mat,1);
10222   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10223   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10224 
10225   if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined");
10226   ierr = (*mat->ops->findoffblockdiagonalentries)(mat,is);CHKERRQ(ierr);
10227   PetscFunctionReturn(0);
10228 }
10229 
10230 #undef __FUNCT__
10231 #define __FUNCT__ "MatInvertBlockDiagonal"
10232 /*@C
10233   MatInvertBlockDiagonal - Inverts the block diagonal entries.
10234 
10235   Collective on Mat
10236 
10237   Input Parameters:
10238 . mat - the matrix
10239 
10240   Output Parameters:
10241 . values - the block inverses in column major order (FORTRAN-like)
10242 
10243    Note:
10244    This routine is not available from Fortran.
10245 
10246   Level: advanced
10247 @*/
10248 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
10249 {
10250   PetscErrorCode ierr;
10251 
10252   PetscFunctionBegin;
10253   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10254   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10255   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10256   if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
10257   ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr);
10258   PetscFunctionReturn(0);
10259 }
10260 
10261 #undef __FUNCT__
10262 #define __FUNCT__ "MatTransposeColoringDestroy"
10263 /*@C
10264     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
10265     via MatTransposeColoringCreate().
10266 
10267     Collective on MatTransposeColoring
10268 
10269     Input Parameter:
10270 .   c - coloring context
10271 
10272     Level: intermediate
10273 
10274 .seealso: MatTransposeColoringCreate()
10275 @*/
10276 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c)
10277 {
10278   PetscErrorCode       ierr;
10279   MatTransposeColoring matcolor=*c;
10280 
10281   PetscFunctionBegin;
10282   if (!matcolor) PetscFunctionReturn(0);
10283   if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; PetscFunctionReturn(0);}
10284 
10285   ierr = PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);CHKERRQ(ierr);
10286   ierr = PetscFree(matcolor->rows);CHKERRQ(ierr);
10287   ierr = PetscFree(matcolor->den2sp);CHKERRQ(ierr);
10288   ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr);
10289   ierr = PetscFree(matcolor->columns);CHKERRQ(ierr);
10290   if (matcolor->brows>0) {
10291     ierr = PetscFree(matcolor->lstart);CHKERRQ(ierr);
10292   }
10293   ierr = PetscHeaderDestroy(c);CHKERRQ(ierr);
10294   PetscFunctionReturn(0);
10295 }
10296 
10297 #undef __FUNCT__
10298 #define __FUNCT__ "MatTransColoringApplySpToDen"
10299 /*@C
10300     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
10301     a MatTransposeColoring context has been created, computes a dense B^T by Apply
10302     MatTransposeColoring to sparse B.
10303 
10304     Collective on MatTransposeColoring
10305 
10306     Input Parameters:
10307 +   B - sparse matrix B
10308 .   Btdense - symbolic dense matrix B^T
10309 -   coloring - coloring context created with MatTransposeColoringCreate()
10310 
10311     Output Parameter:
10312 .   Btdense - dense matrix B^T
10313 
10314     Options Database Keys:
10315 +    -mat_transpose_coloring_view - Activates basic viewing or coloring
10316 .    -mat_transpose_coloring_view_draw - Activates drawing of coloring
10317 -    -mat_transpose_coloring_view_info - Activates viewing of coloring info
10318 
10319     Level: intermediate
10320 
10321 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy()
10322 
10323 .keywords: coloring
10324 @*/
10325 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
10326 {
10327   PetscErrorCode ierr;
10328 
10329   PetscFunctionBegin;
10330   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
10331   PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2);
10332   PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3);
10333 
10334   if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
10335   ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr);
10336   PetscFunctionReturn(0);
10337 }
10338 
10339 #undef __FUNCT__
10340 #define __FUNCT__ "MatTransColoringApplyDenToSp"
10341 /*@C
10342     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
10343     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
10344     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
10345     Csp from Cden.
10346 
10347     Collective on MatTransposeColoring
10348 
10349     Input Parameters:
10350 +   coloring - coloring context created with MatTransposeColoringCreate()
10351 -   Cden - matrix product of a sparse matrix and a dense matrix Btdense
10352 
10353     Output Parameter:
10354 .   Csp - sparse matrix
10355 
10356     Options Database Keys:
10357 +    -mat_multtranspose_coloring_view - Activates basic viewing or coloring
10358 .    -mat_multtranspose_coloring_view_draw - Activates drawing of coloring
10359 -    -mat_multtranspose_coloring_view_info - Activates viewing of coloring info
10360 
10361     Level: intermediate
10362 
10363 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()
10364 
10365 .keywords: coloring
10366 @*/
10367 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
10368 {
10369   PetscErrorCode ierr;
10370 
10371   PetscFunctionBegin;
10372   PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1);
10373   PetscValidHeaderSpecific(Cden,MAT_CLASSID,2);
10374   PetscValidHeaderSpecific(Csp,MAT_CLASSID,3);
10375 
10376   if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
10377   ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr);
10378   PetscFunctionReturn(0);
10379 }
10380 
10381 #undef __FUNCT__
10382 #define __FUNCT__ "MatTransposeColoringCreate"
10383 /*@C
10384    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.
10385 
10386    Collective on Mat
10387 
10388    Input Parameters:
10389 +  mat - the matrix product C
10390 -  iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring()
10391 
10392     Output Parameter:
10393 .   color - the new coloring context
10394 
10395     Level: intermediate
10396 
10397 .seealso: MatTransposeColoringDestroy(), MatTransposeColoringSetFromOptions(), MatTransColoringApplySpToDen(),
10398            MatTransColoringApplyDenToSp(), MatTransposeColoringView(),
10399 @*/
10400 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
10401 {
10402   MatTransposeColoring c;
10403   MPI_Comm             comm;
10404   PetscErrorCode       ierr;
10405 
10406   PetscFunctionBegin;
10407   ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10408   ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
10409   ierr = PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);CHKERRQ(ierr);
10410 
10411   c->ctype = iscoloring->ctype;
10412   if (mat->ops->transposecoloringcreate) {
10413     ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr);
10414   } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type");
10415 
10416   *color = c;
10417   ierr   = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10418   PetscFunctionReturn(0);
10419 }
10420 
10421 #undef __FUNCT__
10422 #define __FUNCT__ "MatGetNonzeroState"
10423 /*@
10424       MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the
10425         matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the
10426         same, otherwise it will be larger
10427 
10428      Not Collective
10429 
10430   Input Parameter:
10431 .    A  - the matrix
10432 
10433   Output Parameter:
10434 .    state - the current state
10435 
10436   Notes: You can only compare states from two different calls to the SAME matrix, you cannot compare calls between
10437          different matrices
10438 
10439   Level: intermediate
10440 
10441 @*/
10442 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state)
10443 {
10444   PetscFunctionBegin;
10445   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10446   *state = mat->nonzerostate;
10447   PetscFunctionReturn(0);
10448 }
10449 
10450 #undef __FUNCT__
10451 #define __FUNCT__ "MatCreateMPIMatConcatenateSeqMat"
10452 /*@
10453       MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential
10454                  matrices from each processor
10455 
10456     Collective on MPI_Comm
10457 
10458    Input Parameters:
10459 +    comm - the communicators the parallel matrix will live on
10460 .    seqmat - the input sequential matrices
10461 .    n - number of local columns (or PETSC_DECIDE)
10462 -    reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10463 
10464    Output Parameter:
10465 .    mpimat - the parallel matrix generated
10466 
10467     Level: advanced
10468 
10469    Notes: The number of columns of the matrix in EACH processor MUST be the same.
10470 
10471 @*/
10472 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat)
10473 {
10474   PetscErrorCode ierr;
10475   PetscMPIInt    size;
10476 
10477   PetscFunctionBegin;
10478   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
10479   if (size == 1) {
10480     if (reuse == MAT_INITIAL_MATRIX) {
10481       ierr = MatDuplicate(seqmat,MAT_COPY_VALUES,mpimat);CHKERRQ(ierr);
10482     } else {
10483       ierr = MatCopy(seqmat,*mpimat,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
10484     }
10485     PetscFunctionReturn(0);
10486   }
10487 
10488   if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name);
10489   ierr = PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10490   ierr = (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);CHKERRQ(ierr);
10491   ierr = PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10492   PetscFunctionReturn(0);
10493 }
10494 
10495 #undef __FUNCT__
10496 #define __FUNCT__ "MatSubdomainsCreateCoalesce"
10497 /*@
10498      MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent
10499                  ranks' ownership ranges.
10500 
10501     Collective on A
10502 
10503    Input Parameters:
10504 +    A   - the matrix to create subdomains from
10505 -    N   - requested number of subdomains
10506 
10507 
10508    Output Parameters:
10509 +    n   - number of subdomains resulting on this rank
10510 -    iss - IS list with indices of subdomains on this rank
10511 
10512     Level: advanced
10513 
10514     Notes: number of subdomains must be smaller than the communicator size
10515 @*/
10516 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[])
10517 {
10518   MPI_Comm        comm,subcomm;
10519   PetscMPIInt     size,rank,color;
10520   PetscInt        rstart,rend,k;
10521   PetscErrorCode  ierr;
10522 
10523   PetscFunctionBegin;
10524   ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr);
10525   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
10526   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
10527   if (N < 1 || N >= (PetscInt)size) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"number of subdomains must be > 0 and < %D, got N = %D",size,N);
10528   *n = 1;
10529   k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */
10530   color = rank/k;
10531   ierr = MPI_Comm_split(comm,color,rank,&subcomm);CHKERRQ(ierr);
10532   ierr = PetscMalloc1(1,iss);CHKERRQ(ierr);
10533   ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
10534   ierr = ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);CHKERRQ(ierr);
10535   ierr = MPI_Comm_free(&subcomm);CHKERRQ(ierr);
10536   PetscFunctionReturn(0);
10537 }
10538