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