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