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