xref: /petsc/src/mat/interface/matrix.c (revision 4d343eea47f3e457863a63f23fb9efcfef73ea2c)
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 = PetscOptionsHasName(((PetscObject)mat)->prefix,"-mat_is_symmetric",&flg);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 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Cannot set the blocksize for matrix type %s",((PetscObject)mat)->type_name);
6781   PetscFunctionReturn(0);
6782 }
6783 
6784 #undef __FUNCT__
6785 #define __FUNCT__ "MatGetRowIJ"
6786 /*@C
6787     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
6788 
6789    Collective on Mat
6790 
6791     Input Parameters:
6792 +   mat - the matrix
6793 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
6794 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
6795 -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
6796                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6797                  always used.
6798 
6799     Output Parameters:
6800 +   n - number of rows in the (possibly compressed) matrix
6801 .   ia - the row pointers [of length n+1]
6802 .   ja - the column indices
6803 -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
6804            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
6805 
6806     Level: developer
6807 
6808     Notes: You CANNOT change any of the ia[] or ja[] values.
6809 
6810            Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values
6811 
6812     Fortran Node
6813 
6814            In Fortran use
6815 $           PetscInt ia(1), ja(1)
6816 $           PetscOffset iia, jja
6817 $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
6818 $
6819 $          or
6820 $
6821 $           PetscScalar, pointer :: xx_v(:)
6822 $    call  MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
6823 
6824 
6825        Acess the ith and jth entries via ia(iia + i) and ja(jja + j)
6826 
6827 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatGetArray()
6828 @*/
6829 PetscErrorCode  MatGetRowIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6830 {
6831   PetscErrorCode ierr;
6832 
6833   PetscFunctionBegin;
6834   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6835   PetscValidType(mat,1);
6836   PetscValidIntPointer(n,4);
6837   if (ia) PetscValidIntPointer(ia,5);
6838   if (ja) PetscValidIntPointer(ja,6);
6839   PetscValidIntPointer(done,7);
6840   MatCheckPreallocated(mat,1);
6841   if (!mat->ops->getrowij) *done = PETSC_FALSE;
6842   else {
6843     *done = PETSC_TRUE;
6844     ierr = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
6845     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6846     ierr = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
6847   }
6848   PetscFunctionReturn(0);
6849 }
6850 
6851 #undef __FUNCT__
6852 #define __FUNCT__ "MatGetColumnIJ"
6853 /*@C
6854     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
6855 
6856     Collective on Mat
6857 
6858     Input Parameters:
6859 +   mat - the matrix
6860 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6861 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6862                 symmetrized
6863 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6864                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6865                  always used.
6866 
6867     Output Parameters:
6868 +   n - number of columns in the (possibly compressed) matrix
6869 .   ia - the column pointers
6870 .   ja - the row indices
6871 -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
6872 
6873     Level: developer
6874 
6875 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6876 @*/
6877 PetscErrorCode  MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6878 {
6879   PetscErrorCode ierr;
6880 
6881   PetscFunctionBegin;
6882   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6883   PetscValidType(mat,1);
6884   PetscValidIntPointer(n,4);
6885   if (ia) PetscValidIntPointer(ia,5);
6886   if (ja) PetscValidIntPointer(ja,6);
6887   PetscValidIntPointer(done,7);
6888   MatCheckPreallocated(mat,1);
6889   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
6890   else {
6891     *done = PETSC_TRUE;
6892     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6893   }
6894   PetscFunctionReturn(0);
6895 }
6896 
6897 #undef __FUNCT__
6898 #define __FUNCT__ "MatRestoreRowIJ"
6899 /*@C
6900     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
6901     MatGetRowIJ().
6902 
6903     Collective on Mat
6904 
6905     Input Parameters:
6906 +   mat - the matrix
6907 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6908 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6909                 symmetrized
6910 -   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6911                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6912                  always used.
6913 
6914     Output Parameters:
6915 +   n - size of (possibly compressed) matrix
6916 .   ia - the row pointers
6917 .   ja - the column indices
6918 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
6919 
6920     Level: developer
6921 
6922 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6923 @*/
6924 PetscErrorCode  MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6925 {
6926   PetscErrorCode ierr;
6927 
6928   PetscFunctionBegin;
6929   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6930   PetscValidType(mat,1);
6931   if (ia) PetscValidIntPointer(ia,5);
6932   if (ja) PetscValidIntPointer(ja,6);
6933   PetscValidIntPointer(done,7);
6934   MatCheckPreallocated(mat,1);
6935 
6936   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
6937   else {
6938     *done = PETSC_TRUE;
6939     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6940   }
6941   PetscFunctionReturn(0);
6942 }
6943 
6944 #undef __FUNCT__
6945 #define __FUNCT__ "MatRestoreColumnIJ"
6946 /*@C
6947     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
6948     MatGetColumnIJ().
6949 
6950     Collective on Mat
6951 
6952     Input Parameters:
6953 +   mat - the matrix
6954 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6955 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6956                 symmetrized
6957 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6958                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6959                  always used.
6960 
6961     Output Parameters:
6962 +   n - size of (possibly compressed) matrix
6963 .   ia - the column pointers
6964 .   ja - the row indices
6965 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
6966 
6967     Level: developer
6968 
6969 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
6970 @*/
6971 PetscErrorCode  MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6972 {
6973   PetscErrorCode ierr;
6974 
6975   PetscFunctionBegin;
6976   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6977   PetscValidType(mat,1);
6978   if (ia) PetscValidIntPointer(ia,5);
6979   if (ja) PetscValidIntPointer(ja,6);
6980   PetscValidIntPointer(done,7);
6981   MatCheckPreallocated(mat,1);
6982 
6983   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
6984   else {
6985     *done = PETSC_TRUE;
6986     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6987   }
6988   PetscFunctionReturn(0);
6989 }
6990 
6991 #undef __FUNCT__
6992 #define __FUNCT__ "MatColoringPatch"
6993 /*@C
6994     MatColoringPatch -Used inside matrix coloring routines that
6995     use MatGetRowIJ() and/or MatGetColumnIJ().
6996 
6997     Collective on Mat
6998 
6999     Input Parameters:
7000 +   mat - the matrix
7001 .   ncolors - max color value
7002 .   n   - number of entries in colorarray
7003 -   colorarray - array indicating color for each column
7004 
7005     Output Parameters:
7006 .   iscoloring - coloring generated using colorarray information
7007 
7008     Level: developer
7009 
7010 .seealso: MatGetRowIJ(), MatGetColumnIJ()
7011 
7012 @*/
7013 PetscErrorCode  MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7014 {
7015   PetscErrorCode ierr;
7016 
7017   PetscFunctionBegin;
7018   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7019   PetscValidType(mat,1);
7020   PetscValidIntPointer(colorarray,4);
7021   PetscValidPointer(iscoloring,5);
7022   MatCheckPreallocated(mat,1);
7023 
7024   if (!mat->ops->coloringpatch){
7025     ierr = ISColoringCreate(((PetscObject)mat)->comm,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
7026   } else {
7027     ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
7028   }
7029   PetscFunctionReturn(0);
7030 }
7031 
7032 
7033 #undef __FUNCT__
7034 #define __FUNCT__ "MatSetUnfactored"
7035 /*@
7036    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
7037 
7038    Logically Collective on Mat
7039 
7040    Input Parameter:
7041 .  mat - the factored matrix to be reset
7042 
7043    Notes:
7044    This routine should be used only with factored matrices formed by in-place
7045    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7046    format).  This option can save memory, for example, when solving nonlinear
7047    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7048    ILU(0) preconditioner.
7049 
7050    Note that one can specify in-place ILU(0) factorization by calling
7051 .vb
7052      PCType(pc,PCILU);
7053      PCFactorSeUseInPlace(pc);
7054 .ve
7055    or by using the options -pc_type ilu -pc_factor_in_place
7056 
7057    In-place factorization ILU(0) can also be used as a local
7058    solver for the blocks within the block Jacobi or additive Schwarz
7059    methods (runtime option: -sub_pc_factor_in_place).  See the discussion
7060    of these preconditioners in the <a href="../../docs/manual.pdf#ch_pc">PC chapter of the users manual</a> for details on setting
7061    local solver options.
7062 
7063    Most users should employ the simplified KSP interface for linear solvers
7064    instead of working directly with matrix algebra routines such as this.
7065    See, e.g., KSPCreate().
7066 
7067    Level: developer
7068 
7069 .seealso: PCFactorSetUseInPlace()
7070 
7071    Concepts: matrices^unfactored
7072 
7073 @*/
7074 PetscErrorCode  MatSetUnfactored(Mat mat)
7075 {
7076   PetscErrorCode ierr;
7077 
7078   PetscFunctionBegin;
7079   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7080   PetscValidType(mat,1);
7081   MatCheckPreallocated(mat,1);
7082   mat->factortype = MAT_FACTOR_NONE;
7083   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
7084   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
7085   PetscFunctionReturn(0);
7086 }
7087 
7088 /*MC
7089     MatGetArrayF90 - Accesses a matrix array from Fortran90.
7090 
7091     Synopsis:
7092     MatGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7093 
7094     Not collective
7095 
7096     Input Parameter:
7097 .   x - matrix
7098 
7099     Output Parameters:
7100 +   xx_v - the Fortran90 pointer to the array
7101 -   ierr - error code
7102 
7103     Example of Usage:
7104 .vb
7105       PetscScalar, pointer xx_v(:,:)
7106       ....
7107       call MatGetArrayF90(x,xx_v,ierr)
7108       a = xx_v(3)
7109       call MatRestoreArrayF90(x,xx_v,ierr)
7110 .ve
7111 
7112     Notes:
7113     Not yet supported for all F90 compilers
7114 
7115     Level: advanced
7116 
7117 .seealso:  MatRestoreArrayF90(), MatGetArray(), MatRestoreArray()
7118 
7119     Concepts: matrices^accessing array
7120 
7121 M*/
7122 
7123 /*MC
7124     MatRestoreArrayF90 - Restores a matrix array that has been
7125     accessed with MatGetArrayF90().
7126 
7127     Synopsis:
7128     MatRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7129 
7130     Not collective
7131 
7132     Input Parameters:
7133 +   x - matrix
7134 -   xx_v - the Fortran90 pointer to the array
7135 
7136     Output Parameter:
7137 .   ierr - error code
7138 
7139     Example of Usage:
7140 .vb
7141        PetscScalar, pointer xx_v(:)
7142        ....
7143        call MatGetArrayF90(x,xx_v,ierr)
7144        a = xx_v(3)
7145        call MatRestoreArrayF90(x,xx_v,ierr)
7146 .ve
7147 
7148     Notes:
7149     Not yet supported for all F90 compilers
7150 
7151     Level: advanced
7152 
7153 .seealso:  MatGetArrayF90(), MatGetArray(), MatRestoreArray()
7154 
7155 M*/
7156 
7157 
7158 #undef __FUNCT__
7159 #define __FUNCT__ "MatGetSubMatrix"
7160 /*@
7161     MatGetSubMatrix - Gets a single submatrix on the same number of processors
7162                       as the original matrix.
7163 
7164     Collective on Mat
7165 
7166     Input Parameters:
7167 +   mat - the original matrix
7168 .   isrow - parallel IS containing the rows this processor should obtain
7169 .   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.
7170 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7171 
7172     Output Parameter:
7173 .   newmat - the new submatrix, of the same type as the old
7174 
7175     Level: advanced
7176 
7177     Notes:
7178     The submatrix will be able to be multiplied with vectors using the same layout as iscol.
7179 
7180     The rows in isrow will be sorted into the same order as the original matrix on each process.
7181 
7182       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7183    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
7184    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7185    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
7186    you are finished using it.
7187 
7188     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7189     the input matrix.
7190 
7191     If iscol is PETSC_NULL then all columns are obtained (not supported in Fortran).
7192 
7193    Example usage:
7194    Consider the following 8x8 matrix with 34 non-zero values, that is
7195    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7196    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7197    as follows:
7198 
7199 .vb
7200             1  2  0  |  0  3  0  |  0  4
7201     Proc0   0  5  6  |  7  0  0  |  8  0
7202             9  0 10  | 11  0  0  | 12  0
7203     -------------------------------------
7204            13  0 14  | 15 16 17  |  0  0
7205     Proc1   0 18  0  | 19 20 21  |  0  0
7206             0  0  0  | 22 23  0  | 24  0
7207     -------------------------------------
7208     Proc2  25 26 27  |  0  0 28  | 29  0
7209            30  0  0  | 31 32 33  |  0 34
7210 .ve
7211 
7212     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is
7213 
7214 .vb
7215             2  0  |  0  3  0  |  0
7216     Proc0   5  6  |  7  0  0  |  8
7217     -------------------------------
7218     Proc1  18  0  | 19 20 21  |  0
7219     -------------------------------
7220     Proc2  26 27  |  0  0 28  | 29
7221             0  0  | 31 32 33  |  0
7222 .ve
7223 
7224 
7225     Concepts: matrices^submatrices
7226 
7227 .seealso: MatGetSubMatrices()
7228 @*/
7229 PetscErrorCode  MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7230 {
7231   PetscErrorCode ierr;
7232   PetscMPIInt    size;
7233   Mat            *local;
7234   IS             iscoltmp;
7235 
7236   PetscFunctionBegin;
7237   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7238   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
7239   if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
7240   PetscValidPointer(newmat,5);
7241   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5);
7242   PetscValidType(mat,1);
7243   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7244   MatCheckPreallocated(mat,1);
7245   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
7246 
7247   if (!iscol) {
7248     ierr = ISCreateStride(((PetscObject)mat)->comm,mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr);
7249   } else {
7250     iscoltmp = iscol;
7251   }
7252 
7253   /* if original matrix is on just one processor then use submatrix generated */
7254   if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7255     ierr = MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
7256     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7257     PetscFunctionReturn(0);
7258   } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) {
7259     ierr    = MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
7260     *newmat = *local;
7261     ierr    = PetscFree(local);CHKERRQ(ierr);
7262     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7263     PetscFunctionReturn(0);
7264   } else if (!mat->ops->getsubmatrix) {
7265     /* Create a new matrix type that implements the operation using the full matrix */
7266     switch (cll) {
7267       case MAT_INITIAL_MATRIX:
7268         ierr = MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr);
7269         break;
7270       case MAT_REUSE_MATRIX:
7271         ierr = MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr);
7272         break;
7273       default: SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7274     }
7275     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7276     PetscFunctionReturn(0);
7277   }
7278 
7279   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7280   ierr = (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr);
7281   if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7282   if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);}
7283   PetscFunctionReturn(0);
7284 }
7285 
7286 #undef __FUNCT__
7287 #define __FUNCT__ "MatStashSetInitialSize"
7288 /*@
7289    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7290    used during the assembly process to store values that belong to
7291    other processors.
7292 
7293    Not Collective
7294 
7295    Input Parameters:
7296 +  mat   - the matrix
7297 .  size  - the initial size of the stash.
7298 -  bsize - the initial size of the block-stash(if used).
7299 
7300    Options Database Keys:
7301 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
7302 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
7303 
7304    Level: intermediate
7305 
7306    Notes:
7307      The block-stash is used for values set with MatSetValuesBlocked() while
7308      the stash is used for values set with MatSetValues()
7309 
7310      Run with the option -info and look for output of the form
7311      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7312      to determine the appropriate value, MM, to use for size and
7313      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7314      to determine the value, BMM to use for bsize
7315 
7316    Concepts: stash^setting matrix size
7317    Concepts: matrices^stash
7318 
7319 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
7320 
7321 @*/
7322 PetscErrorCode  MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7323 {
7324   PetscErrorCode ierr;
7325 
7326   PetscFunctionBegin;
7327   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7328   PetscValidType(mat,1);
7329   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
7330   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
7331   PetscFunctionReturn(0);
7332 }
7333 
7334 #undef __FUNCT__
7335 #define __FUNCT__ "MatInterpolateAdd"
7336 /*@
7337    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
7338      the matrix
7339 
7340    Neighbor-wise Collective on Mat
7341 
7342    Input Parameters:
7343 +  mat   - the matrix
7344 .  x,y - the vectors
7345 -  w - where the result is stored
7346 
7347    Level: intermediate
7348 
7349    Notes:
7350     w may be the same vector as y.
7351 
7352     This allows one to use either the restriction or interpolation (its transpose)
7353     matrix to do the interpolation
7354 
7355     Concepts: interpolation
7356 
7357 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7358 
7359 @*/
7360 PetscErrorCode  MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7361 {
7362   PetscErrorCode ierr;
7363   PetscInt       M,N,Ny;
7364 
7365   PetscFunctionBegin;
7366   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7367   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7368   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7369   PetscValidHeaderSpecific(w,VEC_CLASSID,4);
7370   PetscValidType(A,1);
7371   MatCheckPreallocated(A,1);
7372   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
7373   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
7374   if (M == Ny) {
7375     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
7376   } else {
7377     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
7378   }
7379   PetscFunctionReturn(0);
7380 }
7381 
7382 #undef __FUNCT__
7383 #define __FUNCT__ "MatInterpolate"
7384 /*@
7385    MatInterpolate - y = A*x or A'*x depending on the shape of
7386      the matrix
7387 
7388    Neighbor-wise Collective on Mat
7389 
7390    Input Parameters:
7391 +  mat   - the matrix
7392 -  x,y - the vectors
7393 
7394    Level: intermediate
7395 
7396    Notes:
7397     This allows one to use either the restriction or interpolation (its transpose)
7398     matrix to do the interpolation
7399 
7400    Concepts: matrices^interpolation
7401 
7402 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7403 
7404 @*/
7405 PetscErrorCode  MatInterpolate(Mat A,Vec x,Vec y)
7406 {
7407   PetscErrorCode ierr;
7408   PetscInt       M,N,Ny;
7409 
7410   PetscFunctionBegin;
7411   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7412   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7413   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7414   PetscValidType(A,1);
7415   MatCheckPreallocated(A,1);
7416   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
7417   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
7418   if (M == Ny) {
7419     ierr = MatMult(A,x,y);CHKERRQ(ierr);
7420   } else {
7421     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
7422   }
7423   PetscFunctionReturn(0);
7424 }
7425 
7426 #undef __FUNCT__
7427 #define __FUNCT__ "MatRestrict"
7428 /*@
7429    MatRestrict - y = A*x or A'*x
7430 
7431    Neighbor-wise Collective on Mat
7432 
7433    Input Parameters:
7434 +  mat   - the matrix
7435 -  x,y - the vectors
7436 
7437    Level: intermediate
7438 
7439    Notes:
7440     This allows one to use either the restriction or interpolation (its transpose)
7441     matrix to do the restriction
7442 
7443    Concepts: matrices^restriction
7444 
7445 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
7446 
7447 @*/
7448 PetscErrorCode  MatRestrict(Mat A,Vec x,Vec y)
7449 {
7450   PetscErrorCode ierr;
7451   PetscInt       M,N,Ny;
7452 
7453   PetscFunctionBegin;
7454   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7455   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7456   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7457   PetscValidType(A,1);
7458   MatCheckPreallocated(A,1);
7459 
7460   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
7461   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
7462   if (M == Ny) {
7463     ierr = MatMult(A,x,y);CHKERRQ(ierr);
7464   } else {
7465     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
7466   }
7467   PetscFunctionReturn(0);
7468 }
7469 
7470 #undef __FUNCT__
7471 #define __FUNCT__ "MatGetNullSpace"
7472 /*@
7473    MatGetNullSpace - retrieves the null space to a matrix.
7474 
7475    Logically Collective on Mat and MatNullSpace
7476 
7477    Input Parameters:
7478 +  mat - the matrix
7479 -  nullsp - the null space object
7480 
7481    Level: developer
7482 
7483    Notes:
7484       This null space is used by solvers. Overwrites any previous null space that may have been attached
7485 
7486    Concepts: null space^attaching to matrix
7487 
7488 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace()
7489 @*/
7490 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
7491 {
7492   PetscFunctionBegin;
7493   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7494   PetscValidType(mat,1);
7495   PetscValidPointer(nullsp,2);
7496   *nullsp = mat->nullsp;
7497   PetscFunctionReturn(0);
7498 }
7499 
7500 #undef __FUNCT__
7501 #define __FUNCT__ "MatSetNullSpace"
7502 /*@
7503    MatSetNullSpace - attaches a null space to a matrix.
7504         This null space will be removed from the resulting vector whenever
7505         MatMult() is called
7506 
7507    Logically Collective on Mat and MatNullSpace
7508 
7509    Input Parameters:
7510 +  mat - the matrix
7511 -  nullsp - the null space object
7512 
7513    Level: developer
7514 
7515    Notes:
7516       This null space is used by solvers. Overwrites any previous null space that may have been attached
7517 
7518    Concepts: null space^attaching to matrix
7519 
7520 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace()
7521 @*/
7522 PetscErrorCode  MatSetNullSpace(Mat mat,MatNullSpace nullsp)
7523 {
7524   PetscErrorCode ierr;
7525 
7526   PetscFunctionBegin;
7527   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7528   PetscValidType(mat,1);
7529   PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
7530   MatCheckPreallocated(mat,1);
7531   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
7532   ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr);
7533   mat->nullsp = nullsp;
7534   PetscFunctionReturn(0);
7535 }
7536 
7537 #undef __FUNCT__
7538 #define __FUNCT__ "MatSetNearNullSpace"
7539 /*@
7540    MatSetNearNullSpace - attaches a null space to a matrix.
7541         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.
7542 
7543    Logically Collective on Mat and MatNullSpace
7544 
7545    Input Parameters:
7546 +  mat - the matrix
7547 -  nullsp - the null space object
7548 
7549    Level: developer
7550 
7551    Notes:
7552       Overwrites any previous near null space that may have been attached
7553 
7554    Concepts: null space^attaching to matrix
7555 
7556 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace()
7557 @*/
7558 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
7559 {
7560   PetscErrorCode ierr;
7561 
7562   PetscFunctionBegin;
7563   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7564   PetscValidType(mat,1);
7565   PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
7566   MatCheckPreallocated(mat,1);
7567   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
7568   ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr);
7569   mat->nearnullsp = nullsp;
7570   PetscFunctionReturn(0);
7571 }
7572 
7573 #undef __FUNCT__
7574 #define __FUNCT__ "MatICCFactor"
7575 /*@C
7576    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
7577 
7578    Collective on Mat
7579 
7580    Input Parameters:
7581 +  mat - the matrix
7582 .  row - row/column permutation
7583 .  fill - expected fill factor >= 1.0
7584 -  level - level of fill, for ICC(k)
7585 
7586    Notes:
7587    Probably really in-place only when level of fill is zero, otherwise allocates
7588    new space to store factored matrix and deletes previous memory.
7589 
7590    Most users should employ the simplified KSP interface for linear solvers
7591    instead of working directly with matrix algebra routines such as this.
7592    See, e.g., KSPCreate().
7593 
7594    Level: developer
7595 
7596    Concepts: matrices^incomplete Cholesky factorization
7597    Concepts: Cholesky factorization
7598 
7599 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
7600 
7601     Developer Note: fortran interface is not autogenerated as the f90
7602     interface defintion cannot be generated correctly [due to MatFactorInfo]
7603 
7604 @*/
7605 PetscErrorCode  MatICCFactor(Mat mat,IS row,const MatFactorInfo* info)
7606 {
7607   PetscErrorCode ierr;
7608 
7609   PetscFunctionBegin;
7610   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7611   PetscValidType(mat,1);
7612   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
7613   PetscValidPointer(info,3);
7614   if (mat->rmap->N != mat->cmap->N) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONG,"matrix must be square");
7615   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7616   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7617   if (!mat->ops->iccfactor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7618   MatCheckPreallocated(mat,1);
7619   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
7620   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
7621   PetscFunctionReturn(0);
7622 }
7623 
7624 #undef __FUNCT__
7625 #define __FUNCT__ "MatSetValuesAdic"
7626 /*@
7627    MatSetValuesAdic - Sets values computed with ADIC automatic differentiation into a matrix.
7628 
7629    Not Collective
7630 
7631    Input Parameters:
7632 +  mat - the matrix
7633 -  v - the values compute with ADIC
7634 
7635    Level: developer
7636 
7637    Notes:
7638      Must call MatSetColoring() before using this routine. Also this matrix must already
7639      have its nonzero pattern determined.
7640 
7641 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7642           MatSetValues(), MatSetColoring(), MatSetValuesAdifor()
7643 @*/
7644 PetscErrorCode  MatSetValuesAdic(Mat mat,void *v)
7645 {
7646   PetscErrorCode ierr;
7647 
7648   PetscFunctionBegin;
7649   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7650   PetscValidType(mat,1);
7651   PetscValidPointer(mat,2);
7652 
7653   if (!mat->assembled) {
7654     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7655   }
7656   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
7657   if (!mat->ops->setvaluesadic) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7658   ierr = (*mat->ops->setvaluesadic)(mat,v);CHKERRQ(ierr);
7659   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
7660   ierr = MatView_Private(mat);CHKERRQ(ierr);
7661   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
7662   PetscFunctionReturn(0);
7663 }
7664 
7665 
7666 #undef __FUNCT__
7667 #define __FUNCT__ "MatSetColoring"
7668 /*@
7669    MatSetColoring - Sets a coloring used by calls to MatSetValuesAdic()
7670 
7671    Not Collective
7672 
7673    Input Parameters:
7674 +  mat - the matrix
7675 -  coloring - the coloring
7676 
7677    Level: developer
7678 
7679 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7680           MatSetValues(), MatSetValuesAdic()
7681 @*/
7682 PetscErrorCode  MatSetColoring(Mat mat,ISColoring coloring)
7683 {
7684   PetscErrorCode ierr;
7685 
7686   PetscFunctionBegin;
7687   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7688   PetscValidType(mat,1);
7689   PetscValidPointer(coloring,2);
7690 
7691   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7692   if (!mat->ops->setcoloring) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7693   ierr = (*mat->ops->setcoloring)(mat,coloring);CHKERRQ(ierr);
7694   PetscFunctionReturn(0);
7695 }
7696 
7697 #undef __FUNCT__
7698 #define __FUNCT__ "MatSetValuesAdifor"
7699 /*@
7700    MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.
7701 
7702    Not Collective
7703 
7704    Input Parameters:
7705 +  mat - the matrix
7706 .  nl - leading dimension of v
7707 -  v - the values compute with ADIFOR
7708 
7709    Level: developer
7710 
7711    Notes:
7712      Must call MatSetColoring() before using this routine. Also this matrix must already
7713      have its nonzero pattern determined.
7714 
7715 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7716           MatSetValues(), MatSetColoring()
7717 @*/
7718 PetscErrorCode  MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
7719 {
7720   PetscErrorCode ierr;
7721 
7722   PetscFunctionBegin;
7723   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7724   PetscValidType(mat,1);
7725   PetscValidPointer(v,3);
7726 
7727   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7728   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
7729   if (!mat->ops->setvaluesadifor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7730   ierr = (*mat->ops->setvaluesadifor)(mat,nl,v);CHKERRQ(ierr);
7731   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
7732   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
7733   PetscFunctionReturn(0);
7734 }
7735 
7736 #undef __FUNCT__
7737 #define __FUNCT__ "MatDiagonalScaleLocal"
7738 /*@
7739    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
7740          ghosted ones.
7741 
7742    Not Collective
7743 
7744    Input Parameters:
7745 +  mat - the matrix
7746 -  diag = the diagonal values, including ghost ones
7747 
7748    Level: developer
7749 
7750    Notes: Works only for MPIAIJ and MPIBAIJ matrices
7751 
7752 .seealso: MatDiagonalScale()
7753 @*/
7754 PetscErrorCode  MatDiagonalScaleLocal(Mat mat,Vec diag)
7755 {
7756   PetscErrorCode ierr;
7757   PetscMPIInt    size;
7758 
7759   PetscFunctionBegin;
7760   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7761   PetscValidHeaderSpecific(diag,VEC_CLASSID,2);
7762   PetscValidType(mat,1);
7763 
7764   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7765   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
7766   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
7767   if (size == 1) {
7768     PetscInt n,m;
7769     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
7770     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
7771     if (m == n) {
7772       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
7773     } else {
7774       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
7775     }
7776   } else {
7777     ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr);
7778   }
7779   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
7780   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
7781   PetscFunctionReturn(0);
7782 }
7783 
7784 #undef __FUNCT__
7785 #define __FUNCT__ "MatGetInertia"
7786 /*@
7787    MatGetInertia - Gets the inertia from a factored matrix
7788 
7789    Collective on Mat
7790 
7791    Input Parameter:
7792 .  mat - the matrix
7793 
7794    Output Parameters:
7795 +   nneg - number of negative eigenvalues
7796 .   nzero - number of zero eigenvalues
7797 -   npos - number of positive eigenvalues
7798 
7799    Level: advanced
7800 
7801    Notes: Matrix must have been factored by MatCholeskyFactor()
7802 
7803 
7804 @*/
7805 PetscErrorCode  MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
7806 {
7807   PetscErrorCode ierr;
7808 
7809   PetscFunctionBegin;
7810   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7811   PetscValidType(mat,1);
7812   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7813   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
7814   if (!mat->ops->getinertia) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7815   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
7816   PetscFunctionReturn(0);
7817 }
7818 
7819 /* ----------------------------------------------------------------*/
7820 #undef __FUNCT__
7821 #define __FUNCT__ "MatSolves"
7822 /*@C
7823    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
7824 
7825    Neighbor-wise Collective on Mat and Vecs
7826 
7827    Input Parameters:
7828 +  mat - the factored matrix
7829 -  b - the right-hand-side vectors
7830 
7831    Output Parameter:
7832 .  x - the result vectors
7833 
7834    Notes:
7835    The vectors b and x cannot be the same.  I.e., one cannot
7836    call MatSolves(A,x,x).
7837 
7838    Notes:
7839    Most users should employ the simplified KSP interface for linear solvers
7840    instead of working directly with matrix algebra routines such as this.
7841    See, e.g., KSPCreate().
7842 
7843    Level: developer
7844 
7845    Concepts: matrices^triangular solves
7846 
7847 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
7848 @*/
7849 PetscErrorCode  MatSolves(Mat mat,Vecs b,Vecs x)
7850 {
7851   PetscErrorCode ierr;
7852 
7853   PetscFunctionBegin;
7854   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7855   PetscValidType(mat,1);
7856   if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
7857   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7858   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
7859 
7860   if (!mat->ops->solves) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7861   MatCheckPreallocated(mat,1);
7862   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
7863   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
7864   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
7865   PetscFunctionReturn(0);
7866 }
7867 
7868 #undef __FUNCT__
7869 #define __FUNCT__ "MatIsSymmetric"
7870 /*@
7871    MatIsSymmetric - Test whether a matrix is symmetric
7872 
7873    Collective on Mat
7874 
7875    Input Parameter:
7876 +  A - the matrix to test
7877 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
7878 
7879    Output Parameters:
7880 .  flg - the result
7881 
7882    Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
7883 
7884    Level: intermediate
7885 
7886    Concepts: matrix^symmetry
7887 
7888 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
7889 @*/
7890 PetscErrorCode  MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
7891 {
7892   PetscErrorCode ierr;
7893 
7894   PetscFunctionBegin;
7895   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7896   PetscValidPointer(flg,2);
7897 
7898   if (!A->symmetric_set) {
7899     if (!A->ops->issymmetric) {
7900       const MatType mattype;
7901       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7902       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7903     }
7904     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
7905     if (!tol) {
7906       A->symmetric_set = PETSC_TRUE;
7907       A->symmetric = *flg;
7908       if (A->symmetric) {
7909 	A->structurally_symmetric_set = PETSC_TRUE;
7910 	A->structurally_symmetric     = PETSC_TRUE;
7911       }
7912     }
7913   } else if (A->symmetric) {
7914     *flg = PETSC_TRUE;
7915   } else if (!tol) {
7916     *flg = PETSC_FALSE;
7917   } else {
7918     if (!A->ops->issymmetric) {
7919       const MatType mattype;
7920       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7921       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7922     }
7923     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
7924   }
7925   PetscFunctionReturn(0);
7926 }
7927 
7928 #undef __FUNCT__
7929 #define __FUNCT__ "MatIsHermitian"
7930 /*@
7931    MatIsHermitian - Test whether a matrix is Hermitian
7932 
7933    Collective on Mat
7934 
7935    Input Parameter:
7936 +  A - the matrix to test
7937 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
7938 
7939    Output Parameters:
7940 .  flg - the result
7941 
7942    Level: intermediate
7943 
7944    Concepts: matrix^symmetry
7945 
7946 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
7947           MatIsSymmetricKnown(), MatIsSymmetric()
7948 @*/
7949 PetscErrorCode  MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
7950 {
7951   PetscErrorCode ierr;
7952 
7953   PetscFunctionBegin;
7954   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7955   PetscValidPointer(flg,2);
7956 
7957   if (!A->hermitian_set) {
7958     if (!A->ops->ishermitian) {
7959       const MatType mattype;
7960       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7961       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7962     }
7963     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
7964     if (!tol) {
7965       A->hermitian_set = PETSC_TRUE;
7966       A->hermitian = *flg;
7967       if (A->hermitian) {
7968 	A->structurally_symmetric_set = PETSC_TRUE;
7969 	A->structurally_symmetric     = PETSC_TRUE;
7970       }
7971     }
7972   } else if (A->hermitian) {
7973     *flg = PETSC_TRUE;
7974   } else if (!tol) {
7975     *flg = PETSC_FALSE;
7976   } else {
7977     if (!A->ops->ishermitian) {
7978       const MatType mattype;
7979       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7980       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7981     }
7982     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
7983   }
7984   PetscFunctionReturn(0);
7985 }
7986 
7987 #undef __FUNCT__
7988 #define __FUNCT__ "MatIsSymmetricKnown"
7989 /*@
7990    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
7991 
7992    Not Collective
7993 
7994    Input Parameter:
7995 .  A - the matrix to check
7996 
7997    Output Parameters:
7998 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
7999 -  flg - the result
8000 
8001    Level: advanced
8002 
8003    Concepts: matrix^symmetry
8004 
8005    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
8006          if you want it explicitly checked
8007 
8008 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8009 @*/
8010 PetscErrorCode  MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8011 {
8012   PetscFunctionBegin;
8013   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8014   PetscValidPointer(set,2);
8015   PetscValidPointer(flg,3);
8016   if (A->symmetric_set) {
8017     *set = PETSC_TRUE;
8018     *flg = A->symmetric;
8019   } else {
8020     *set = PETSC_FALSE;
8021   }
8022   PetscFunctionReturn(0);
8023 }
8024 
8025 #undef __FUNCT__
8026 #define __FUNCT__ "MatIsHermitianKnown"
8027 /*@
8028    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
8029 
8030    Not Collective
8031 
8032    Input Parameter:
8033 .  A - the matrix to check
8034 
8035    Output Parameters:
8036 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8037 -  flg - the result
8038 
8039    Level: advanced
8040 
8041    Concepts: matrix^symmetry
8042 
8043    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8044          if you want it explicitly checked
8045 
8046 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8047 @*/
8048 PetscErrorCode  MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8049 {
8050   PetscFunctionBegin;
8051   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8052   PetscValidPointer(set,2);
8053   PetscValidPointer(flg,3);
8054   if (A->hermitian_set) {
8055     *set = PETSC_TRUE;
8056     *flg = A->hermitian;
8057   } else {
8058     *set = PETSC_FALSE;
8059   }
8060   PetscFunctionReturn(0);
8061 }
8062 
8063 #undef __FUNCT__
8064 #define __FUNCT__ "MatIsStructurallySymmetric"
8065 /*@
8066    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
8067 
8068    Collective on Mat
8069 
8070    Input Parameter:
8071 .  A - the matrix to test
8072 
8073    Output Parameters:
8074 .  flg - the result
8075 
8076    Level: intermediate
8077 
8078    Concepts: matrix^symmetry
8079 
8080 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8081 @*/
8082 PetscErrorCode  MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
8083 {
8084   PetscErrorCode ierr;
8085 
8086   PetscFunctionBegin;
8087   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8088   PetscValidPointer(flg,2);
8089   if (!A->structurally_symmetric_set) {
8090     if (!A->ops->isstructurallysymmetric) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8091     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
8092     A->structurally_symmetric_set = PETSC_TRUE;
8093   }
8094   *flg = A->structurally_symmetric;
8095   PetscFunctionReturn(0);
8096 }
8097 
8098 #undef __FUNCT__
8099 #define __FUNCT__ "MatStashGetInfo"
8100 extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
8101 /*@
8102    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8103        to be communicated to other processors during the MatAssemblyBegin/End() process
8104 
8105     Not collective
8106 
8107    Input Parameter:
8108 .   vec - the vector
8109 
8110    Output Parameters:
8111 +   nstash   - the size of the stash
8112 .   reallocs - the number of additional mallocs incurred.
8113 .   bnstash   - the size of the block stash
8114 -   breallocs - the number of additional mallocs incurred.in the block stash
8115 
8116    Level: advanced
8117 
8118 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
8119 
8120 @*/
8121 PetscErrorCode  MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8122 {
8123   PetscErrorCode ierr;
8124   PetscFunctionBegin;
8125   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
8126   ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
8127   PetscFunctionReturn(0);
8128 }
8129 
8130 #undef __FUNCT__
8131 #define __FUNCT__ "MatGetVecs"
8132 /*@C
8133    MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same
8134      parallel layout
8135 
8136    Collective on Mat
8137 
8138    Input Parameter:
8139 .  mat - the matrix
8140 
8141    Output Parameter:
8142 +   right - (optional) vector that the matrix can be multiplied against
8143 -   left - (optional) vector that the matrix vector product can be stored in
8144 
8145   Level: advanced
8146 
8147 .seealso: MatCreate()
8148 @*/
8149 PetscErrorCode  MatGetVecs(Mat mat,Vec *right,Vec *left)
8150 {
8151   PetscErrorCode ierr;
8152 
8153   PetscFunctionBegin;
8154   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8155   PetscValidType(mat,1);
8156   MatCheckPreallocated(mat,1);
8157   if (mat->ops->getvecs) {
8158     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
8159   } else {
8160     PetscMPIInt size;
8161     ierr = MPI_Comm_size(((PetscObject)mat)->comm, &size);CHKERRQ(ierr);
8162     if (right) {
8163       ierr = VecCreate(((PetscObject)mat)->comm,right);CHKERRQ(ierr);
8164       ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8165       ierr = VecSetBlockSize(*right,mat->rmap->bs);CHKERRQ(ierr);
8166       ierr = VecSetType(*right,VECSTANDARD);CHKERRQ(ierr);
8167       ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr);
8168     }
8169     if (left) {
8170       ierr = VecCreate(((PetscObject)mat)->comm,left);CHKERRQ(ierr);
8171       ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8172       ierr = VecSetBlockSize(*left,mat->rmap->bs);CHKERRQ(ierr);
8173       ierr = VecSetType(*left,VECSTANDARD);CHKERRQ(ierr);
8174       ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr);
8175     }
8176   }
8177   PetscFunctionReturn(0);
8178 }
8179 
8180 #undef __FUNCT__
8181 #define __FUNCT__ "MatFactorInfoInitialize"
8182 /*@C
8183    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8184      with default values.
8185 
8186    Not Collective
8187 
8188    Input Parameters:
8189 .    info - the MatFactorInfo data structure
8190 
8191 
8192    Notes: The solvers are generally used through the KSP and PC objects, for example
8193           PCLU, PCILU, PCCHOLESKY, PCICC
8194 
8195    Level: developer
8196 
8197 .seealso: MatFactorInfo
8198 
8199     Developer Note: fortran interface is not autogenerated as the f90
8200     interface defintion cannot be generated correctly [due to MatFactorInfo]
8201 
8202 @*/
8203 
8204 PetscErrorCode  MatFactorInfoInitialize(MatFactorInfo *info)
8205 {
8206   PetscErrorCode ierr;
8207 
8208   PetscFunctionBegin;
8209   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
8210   PetscFunctionReturn(0);
8211 }
8212 
8213 #undef __FUNCT__
8214 #define __FUNCT__ "MatPtAP"
8215 /*@
8216    MatPtAP - Creates the matrix product C = P^T * A * P
8217 
8218    Neighbor-wise Collective on Mat
8219 
8220    Input Parameters:
8221 +  A - the matrix
8222 .  P - the projection matrix
8223 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8224 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P))
8225 
8226    Output Parameters:
8227 .  C - the product matrix
8228 
8229    Notes:
8230    C will be created and must be destroyed by the user with MatDestroy().
8231 
8232    This routine is currently only implemented for pairs of AIJ matrices and classes
8233    which inherit from AIJ.
8234 
8235    Level: intermediate
8236 
8237 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult()
8238 @*/
8239 PetscErrorCode  MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
8240 {
8241   PetscErrorCode ierr;
8242 
8243   PetscFunctionBegin;
8244   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8245   PetscValidType(A,1);
8246   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8247   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8248   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
8249   PetscValidType(P,2);
8250   MatCheckPreallocated(P,2);
8251   if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8252   if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8253   PetscValidPointer(C,3);
8254   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);
8255   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8256   MatCheckPreallocated(A,1);
8257 
8258   if (!A->ops->ptap) {
8259     const MatType mattype;
8260     ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8261     SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix of type <%s> does not support PtAP",mattype);
8262   }
8263   ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
8264   ierr = (*A->ops->ptap)(A,P,scall,fill,C);CHKERRQ(ierr);
8265   ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
8266   PetscFunctionReturn(0);
8267 }
8268 
8269 #undef __FUNCT__
8270 #define __FUNCT__ "MatPtAPNumeric"
8271 /*@
8272    MatPtAPNumeric - Computes the matrix product C = P^T * A * P
8273 
8274    Neighbor-wise Collective on Mat
8275 
8276    Input Parameters:
8277 +  A - the matrix
8278 -  P - the projection matrix
8279 
8280    Output Parameters:
8281 .  C - the product matrix
8282 
8283    Notes:
8284    C must have been created by calling MatPtAPSymbolic and must be destroyed by
8285    the user using MatDeatroy().
8286 
8287    This routine is currently only implemented for pairs of AIJ matrices and classes
8288    which inherit from AIJ.  C will be of type MATAIJ.
8289 
8290    Level: intermediate
8291 
8292 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
8293 @*/
8294 PetscErrorCode  MatPtAPNumeric(Mat A,Mat P,Mat C)
8295 {
8296   PetscErrorCode ierr;
8297 
8298   PetscFunctionBegin;
8299   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8300   PetscValidType(A,1);
8301   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8302   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8303   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
8304   PetscValidType(P,2);
8305   MatCheckPreallocated(P,2);
8306   if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8307   if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8308   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
8309   PetscValidType(C,3);
8310   MatCheckPreallocated(C,3);
8311   if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8312   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);
8313   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);
8314   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);
8315   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);
8316   MatCheckPreallocated(A,1);
8317 
8318   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
8319   ierr = (*A->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr);
8320   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
8321   PetscFunctionReturn(0);
8322 }
8323 
8324 #undef __FUNCT__
8325 #define __FUNCT__ "MatPtAPSymbolic"
8326 /*@
8327    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P
8328 
8329    Neighbor-wise Collective on Mat
8330 
8331    Input Parameters:
8332 +  A - the matrix
8333 -  P - the projection matrix
8334 
8335    Output Parameters:
8336 .  C - the (i,j) structure of the product matrix
8337 
8338    Notes:
8339    C will be created and must be destroyed by the user with MatDestroy().
8340 
8341    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
8342    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
8343    this (i,j) structure by calling MatPtAPNumeric().
8344 
8345    Level: intermediate
8346 
8347 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
8348 @*/
8349 PetscErrorCode  MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
8350 {
8351   PetscErrorCode ierr;
8352 
8353   PetscFunctionBegin;
8354   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8355   PetscValidType(A,1);
8356   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8357   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8358   if (fill <1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8359   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
8360   PetscValidType(P,2);
8361   MatCheckPreallocated(P,2);
8362   if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8363   if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8364   PetscValidPointer(C,3);
8365 
8366   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);
8367   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);
8368   MatCheckPreallocated(A,1);
8369   ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
8370   ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr);
8371   ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
8372 
8373   ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr);
8374 
8375   PetscFunctionReturn(0);
8376 }
8377 
8378 #undef __FUNCT__
8379 #define __FUNCT__ "MatRARt"
8380 /*@
8381    MatRARt - Creates the matrix product C = R * A * R^T
8382 
8383    Neighbor-wise Collective on Mat
8384 
8385    Input Parameters:
8386 +  A - the matrix
8387 .  R - the projection matrix
8388 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8389 -  fill - expected fill as ratio of nnz(C)/nnz(A)
8390 
8391    Output Parameters:
8392 .  C - the product matrix
8393 
8394    Notes:
8395    C will be created and must be destroyed by the user with MatDestroy().
8396 
8397    This routine is currently only implemented for pairs of AIJ matrices and classes
8398    which inherit from AIJ.
8399 
8400    Level: intermediate
8401 
8402 .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult()
8403 @*/
8404 PetscErrorCode  MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
8405 {
8406   PetscErrorCode ierr;
8407 
8408   PetscFunctionBegin;
8409   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8410   PetscValidType(A,1);
8411   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8412   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8413   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
8414   PetscValidType(R,2);
8415   MatCheckPreallocated(R,2);
8416   if (!R->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8417   if (R->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8418   PetscValidPointer(C,3);
8419   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);
8420   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8421   MatCheckPreallocated(A,1);
8422 
8423   if (!A->ops->rart) {
8424     const MatType mattype;
8425     ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8426     SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix of type <%s> does not support RARt",mattype);
8427   }
8428   ierr = PetscLogEventBegin(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
8429   ierr = (*A->ops->rart)(A,R,scall,fill,C);CHKERRQ(ierr);
8430   ierr = PetscLogEventEnd(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
8431   PetscFunctionReturn(0);
8432 }
8433 
8434 #undef __FUNCT__
8435 #define __FUNCT__ "MatRARtNumeric"
8436 /*@
8437    MatRARtNumeric - Computes the matrix product C = R * A * R^T
8438 
8439    Neighbor-wise Collective on Mat
8440 
8441    Input Parameters:
8442 +  A - the matrix
8443 -  R - the projection matrix
8444 
8445    Output Parameters:
8446 .  C - the product matrix
8447 
8448    Notes:
8449    C must have been created by calling MatRARtSymbolic and must be destroyed by
8450    the user using MatDeatroy().
8451 
8452    This routine is currently only implemented for pairs of AIJ matrices and classes
8453    which inherit from AIJ.  C will be of type MATAIJ.
8454 
8455    Level: intermediate
8456 
8457 .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
8458 @*/
8459 PetscErrorCode  MatRARtNumeric(Mat A,Mat R,Mat C)
8460 {
8461   PetscErrorCode ierr;
8462 
8463   PetscFunctionBegin;
8464   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8465   PetscValidType(A,1);
8466   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8467   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8468   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
8469   PetscValidType(R,2);
8470   MatCheckPreallocated(R,2);
8471   if (!R->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8472   if (R->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8473   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
8474   PetscValidType(C,3);
8475   MatCheckPreallocated(C,3);
8476   if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8477   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);
8478   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);
8479   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);
8480   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);
8481   MatCheckPreallocated(A,1);
8482 
8483   ierr = PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
8484   ierr = (*A->ops->rartnumeric)(A,R,C);CHKERRQ(ierr);
8485   ierr = PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
8486   PetscFunctionReturn(0);
8487 }
8488 
8489 #undef __FUNCT__
8490 #define __FUNCT__ "MatRARtSymbolic"
8491 /*@
8492    MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T
8493 
8494    Neighbor-wise Collective on Mat
8495 
8496    Input Parameters:
8497 +  A - the matrix
8498 -  R - the projection matrix
8499 
8500    Output Parameters:
8501 .  C - the (i,j) structure of the product matrix
8502 
8503    Notes:
8504    C will be created and must be destroyed by the user with MatDestroy().
8505 
8506    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
8507    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
8508    this (i,j) structure by calling MatRARtNumeric().
8509 
8510    Level: intermediate
8511 
8512 .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
8513 @*/
8514 PetscErrorCode  MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
8515 {
8516   PetscErrorCode ierr;
8517 
8518   PetscFunctionBegin;
8519   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8520   PetscValidType(A,1);
8521   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8522   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8523   if (fill <1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8524   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
8525   PetscValidType(R,2);
8526   MatCheckPreallocated(R,2);
8527   if (!R->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8528   if (R->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8529   PetscValidPointer(C,3);
8530 
8531   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);
8532   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);
8533   MatCheckPreallocated(A,1);
8534   ierr = PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
8535   ierr = (*A->ops->rartsymbolic)(A,R,fill,C);CHKERRQ(ierr);
8536   ierr = PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
8537 
8538   ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr);
8539   PetscFunctionReturn(0);
8540 }
8541 
8542 extern PetscErrorCode MatQueryOp(MPI_Comm comm, void (**function)(void), const char op[], PetscInt numArgs, ...);
8543 
8544 #undef __FUNCT__
8545 #define __FUNCT__ "MatMatMult"
8546 /*@
8547    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
8548 
8549    Neighbor-wise Collective on Mat
8550 
8551    Input Parameters:
8552 +  A - the left matrix
8553 .  B - the right matrix
8554 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8555 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
8556           if the result is a dense matrix this is irrelevent
8557 
8558    Output Parameters:
8559 .  C - the product matrix
8560 
8561    Notes:
8562    Unless scall is MAT_REUSE_MATRIX C will be created.
8563 
8564    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8565 
8566    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8567    actually needed.
8568 
8569    If you have many matrices with the same non-zero structure to multiply, you
8570    should either
8571 $   1) use MAT_REUSE_MATRIX in all calls but the first or
8572 $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
8573 
8574    Level: intermediate
8575 
8576 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatPtAP()
8577 @*/
8578 PetscErrorCode  MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8579 {
8580   PetscErrorCode ierr;
8581   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8582   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8583   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat *)=PETSC_NULL;
8584 
8585   PetscFunctionBegin;
8586   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8587   PetscValidType(A,1);
8588   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8589   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8590   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8591   PetscValidType(B,2);
8592   MatCheckPreallocated(B,2);
8593   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8594   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8595   PetscValidPointer(C,3);
8596   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);
8597   if (scall == MAT_REUSE_MATRIX){
8598     PetscValidPointer(*C,5);
8599     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
8600     ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
8601     ierr = (*(*C)->ops->matmult)(A,B,scall,fill,C);CHKERRQ(ierr);
8602     ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
8603   }
8604   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8605   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8606   MatCheckPreallocated(A,1);
8607 
8608   fA = A->ops->matmult;
8609   fB = B->ops->matmult;
8610   if (fB == fA) {
8611     if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
8612     mult = fB;
8613   } else {
8614     /* dispatch based on the type of A and B from their PetscObject's PetscFLists. */
8615     char  multname[256];
8616     ierr = PetscStrcpy(multname,"MatMatMult_");CHKERRQ(ierr);
8617     ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr);
8618     ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);
8619     ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr);
8620     ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
8621     ierr = PetscObjectQueryFunction((PetscObject)B,multname,(void (**)(void))&mult);CHKERRQ(ierr);
8622     if(!mult){
8623       /* dual dispatch using MatQueryOp */
8624       ierr = MatQueryOp(((PetscObject)A)->comm, (PetscVoidFunction*)(&mult), "MatMatMult",2,((PetscObject)A)->type_name,((PetscObject)B)->type_name); CHKERRQ(ierr);
8625       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);
8626     }
8627   }
8628   ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
8629   ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr);
8630   ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
8631   PetscFunctionReturn(0);
8632 }
8633 
8634 #undef __FUNCT__
8635 #define __FUNCT__ "MatMatMultSymbolic"
8636 /*@
8637    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
8638    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().
8639 
8640    Neighbor-wise Collective on Mat
8641 
8642    Input Parameters:
8643 +  A - the left matrix
8644 .  B - the right matrix
8645 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
8646       if C is a dense matrix this is irrelevent
8647 
8648    Output Parameters:
8649 .  C - the product matrix
8650 
8651    Notes:
8652    Unless scall is MAT_REUSE_MATRIX C will be created.
8653 
8654    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8655    actually needed.
8656 
8657    This routine is currently implemented for
8658     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
8659     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8660     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
8661 
8662    Level: intermediate
8663 
8664    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
8665      We should incorporate them into PETSc.
8666 
8667 .seealso: MatMatMult(), MatMatMultNumeric()
8668 @*/
8669 PetscErrorCode  MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
8670 {
8671   PetscErrorCode ierr;
8672   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat *);
8673   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat *);
8674   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat *)=PETSC_NULL;
8675 
8676   PetscFunctionBegin;
8677   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8678   PetscValidType(A,1);
8679   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8680   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8681 
8682   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8683   PetscValidType(B,2);
8684   MatCheckPreallocated(B,2);
8685   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8686   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8687   PetscValidPointer(C,3);
8688 
8689   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);
8690   if (fill == PETSC_DEFAULT) fill = 2.0;
8691   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8692   MatCheckPreallocated(A,1);
8693 
8694   Asymbolic = A->ops->matmultsymbolic;
8695   Bsymbolic = B->ops->matmultsymbolic;
8696   if (Asymbolic == Bsymbolic){
8697     if (!Bsymbolic) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
8698     symbolic = Bsymbolic;
8699   } else { /* dispatch based on the type of A and B */
8700     char  symbolicname[256];
8701     ierr = PetscStrcpy(symbolicname,"MatMatMultSymbolic_");CHKERRQ(ierr);
8702     ierr = PetscStrcat(symbolicname,((PetscObject)A)->type_name);CHKERRQ(ierr);
8703     ierr = PetscStrcat(symbolicname,"_");CHKERRQ(ierr);
8704     ierr = PetscStrcat(symbolicname,((PetscObject)B)->type_name);CHKERRQ(ierr);
8705     ierr = PetscStrcat(symbolicname,"_C");CHKERRQ(ierr);
8706     ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,(void (**)(void))&symbolic);CHKERRQ(ierr);
8707     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);
8708   }
8709   ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
8710   ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr);
8711   ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
8712   PetscFunctionReturn(0);
8713 }
8714 
8715 #undef __FUNCT__
8716 #define __FUNCT__ "MatMatMultNumeric"
8717 /*@
8718    MatMatMultNumeric - Performs the numeric matrix-matrix product.
8719    Call this routine after first calling MatMatMultSymbolic().
8720 
8721    Neighbor-wise Collective on Mat
8722 
8723    Input Parameters:
8724 +  A - the left matrix
8725 -  B - the right matrix
8726 
8727    Output Parameters:
8728 .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
8729 
8730    Notes:
8731    C must have been created with MatMatMultSymbolic().
8732 
8733    This routine is currently implemented for
8734     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
8735     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8736     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
8737 
8738    Level: intermediate
8739 
8740 .seealso: MatMatMult(), MatMatMultSymbolic()
8741 @*/
8742 PetscErrorCode  MatMatMultNumeric(Mat A,Mat B,Mat C)
8743 {
8744   PetscErrorCode ierr;
8745   PetscErrorCode (*Anumeric)(Mat,Mat,Mat);
8746   PetscErrorCode (*Bnumeric)(Mat,Mat,Mat);
8747   PetscErrorCode (*numeric)(Mat,Mat,Mat)=PETSC_NULL;
8748 
8749   PetscFunctionBegin;
8750   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8751   PetscValidType(A,1);
8752   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8753   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8754 
8755   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8756   PetscValidType(B,2);
8757   MatCheckPreallocated(B,2);
8758   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8759   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8760 
8761   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
8762   PetscValidType(C,3);
8763   MatCheckPreallocated(C,3);
8764   if (!C->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8765   if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8766 
8767   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);
8768   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);
8769   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);
8770   MatCheckPreallocated(A,1);
8771 
8772   Anumeric = A->ops->matmultnumeric;
8773   Bnumeric = B->ops->matmultnumeric;
8774   if (Anumeric == Bnumeric){
8775     if (!Bnumeric) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMultNumeric not supported for B of type %s",((PetscObject)B)->type_name);
8776     numeric = Bnumeric;
8777   } else {
8778     char  numericname[256];
8779     ierr = PetscStrcpy(numericname,"MatMatMultNumeric_");CHKERRQ(ierr);
8780     ierr = PetscStrcat(numericname,((PetscObject)A)->type_name);CHKERRQ(ierr);
8781     ierr = PetscStrcat(numericname,"_");CHKERRQ(ierr);
8782     ierr = PetscStrcat(numericname,((PetscObject)B)->type_name);CHKERRQ(ierr);
8783     ierr = PetscStrcat(numericname,"_C");CHKERRQ(ierr);
8784     ierr = PetscObjectQueryFunction((PetscObject)B,numericname,(void (**)(void))&numeric);CHKERRQ(ierr);
8785     if (!numeric)
8786       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);
8787   }
8788   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
8789   ierr = (*numeric)(A,B,C);CHKERRQ(ierr);
8790   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
8791   PetscFunctionReturn(0);
8792 }
8793 
8794 #undef __FUNCT__
8795 #define __FUNCT__ "MatMatTransposeMult"
8796 /*@
8797    MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.
8798 
8799    Neighbor-wise Collective on Mat
8800 
8801    Input Parameters:
8802 +  A - the left matrix
8803 .  B - the right matrix
8804 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8805 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
8806 
8807    Output Parameters:
8808 .  C - the product matrix
8809 
8810    Notes:
8811    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
8812 
8813    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8814 
8815   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8816    actually needed.
8817 
8818    This routine is currently only implemented for pairs of SeqAIJ matrices.  C will be of type MATSEQAIJ.
8819 
8820    Level: intermediate
8821 
8822 .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatPtAP()
8823 @*/
8824 PetscErrorCode  MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8825 {
8826   PetscErrorCode ierr;
8827   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8828   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8829 
8830   PetscFunctionBegin;
8831   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8832   PetscValidType(A,1);
8833   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8834   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8835   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8836   PetscValidType(B,2);
8837   MatCheckPreallocated(B,2);
8838   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8839   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8840   PetscValidPointer(C,3);
8841   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);
8842   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8843   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8844   MatCheckPreallocated(A,1);
8845 
8846   fA = A->ops->mattransposemult;
8847   if (!fA) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
8848   fB = B->ops->mattransposemult;
8849   if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
8850   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);
8851 
8852   if (scall == MAT_INITIAL_MATRIX){
8853     ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
8854     ierr = (*A->ops->mattransposemultsymbolic)(A,B,fill,C);CHKERRQ(ierr);
8855     ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
8856   }
8857   ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
8858   ierr = (*A->ops->mattransposemultnumeric)(A,B,*C);CHKERRQ(ierr);
8859   ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
8860   PetscFunctionReturn(0);
8861 }
8862 
8863 #undef __FUNCT__
8864 #define __FUNCT__ "MatTransposeMatMult"
8865 /*@
8866    MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.
8867 
8868    Neighbor-wise Collective on Mat
8869 
8870    Input Parameters:
8871 +  A - the left matrix
8872 .  B - the right matrix
8873 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8874 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
8875 
8876    Output Parameters:
8877 .  C - the product matrix
8878 
8879    Notes:
8880    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
8881 
8882    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8883 
8884   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8885    actually needed.
8886 
8887    This routine is currently only implemented for pairs of SeqAIJ matrices and pairs of SeqDense matrices and classes
8888    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.
8889 
8890    Level: intermediate
8891 
8892 .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatPtAP()
8893 @*/
8894 PetscErrorCode  MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8895 {
8896   PetscErrorCode ierr;
8897   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8898   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8899   PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*);
8900 
8901   PetscFunctionBegin;
8902   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8903   PetscValidType(A,1);
8904   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8905   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8906   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8907   PetscValidType(B,2);
8908   MatCheckPreallocated(B,2);
8909   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8910   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8911   PetscValidPointer(C,3);
8912   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);
8913   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8914   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8915   MatCheckPreallocated(A,1);
8916 
8917   fA = A->ops->transposematmult;
8918   if (!fA) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
8919   fB = B->ops->transposematmult;
8920   if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatTransposeMatMult not supported for B of type %s",((PetscObject)B)->type_name);
8921   if (fB==fA) {
8922     transposematmult = fA;
8923   }
8924   else {
8925     /* dual dispatch using MatQueryOp */
8926     ierr = MatQueryOp(((PetscObject)A)->comm, (PetscVoidFunction*)(&transposematmult), "MatTansposeMatMult",2,((PetscObject)A)->type_name,((PetscObject)B)->type_name); CHKERRQ(ierr);
8927     if(!transposematmult)
8928       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);
8929   }
8930   ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
8931   ierr = (*transposematmult)(A,B,scall,fill,C);CHKERRQ(ierr);
8932   ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
8933   PetscFunctionReturn(0);
8934 }
8935 
8936 #undef __FUNCT__
8937 #define __FUNCT__ "MatGetRedundantMatrix"
8938 /*@C
8939    MatGetRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
8940 
8941    Collective on Mat
8942 
8943    Input Parameters:
8944 +  mat - the matrix
8945 .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
8946 .  subcomm - MPI communicator split from the communicator where mat resides in
8947 .  mlocal_red - number of local rows of the redundant matrix
8948 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8949 
8950    Output Parameter:
8951 .  matredundant - redundant matrix
8952 
8953    Notes:
8954    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
8955    original matrix has not changed from that last call to MatGetRedundantMatrix().
8956 
8957    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
8958    calling it.
8959 
8960    Only MPIAIJ matrix is supported.
8961 
8962    Level: advanced
8963 
8964    Concepts: subcommunicator
8965    Concepts: duplicate matrix
8966 
8967 .seealso: MatDestroy()
8968 @*/
8969 PetscErrorCode  MatGetRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,PetscInt mlocal_red,MatReuse reuse,Mat *matredundant)
8970 {
8971   PetscErrorCode ierr;
8972 
8973   PetscFunctionBegin;
8974   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8975   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
8976     PetscValidPointer(*matredundant,6);
8977     PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,6);
8978   }
8979   if (!mat->ops->getredundantmatrix) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8980   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8981   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8982   MatCheckPreallocated(mat,1);
8983 
8984   ierr = PetscLogEventBegin(MAT_GetRedundantMatrix,mat,0,0,0);CHKERRQ(ierr);
8985   ierr = (*mat->ops->getredundantmatrix)(mat,nsubcomm,subcomm,mlocal_red,reuse,matredundant);CHKERRQ(ierr);
8986   ierr = PetscLogEventEnd(MAT_GetRedundantMatrix,mat,0,0,0);CHKERRQ(ierr);
8987   PetscFunctionReturn(0);
8988 }
8989 
8990 #undef __FUNCT__
8991 #define __FUNCT__ "MatGetMultiProcBlock"
8992 /*@C
8993    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
8994    a given 'mat' object. Each submatrix can span multiple procs.
8995 
8996    Collective on Mat
8997 
8998    Input Parameters:
8999 +  mat - the matrix
9000 .  subcomm - the subcommunicator obtained by com_split(comm)
9001 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9002 
9003    Output Parameter:
9004 .  subMat - 'parallel submatrices each spans a given subcomm
9005 
9006   Notes:
9007   The submatrix partition across processors is dicated by 'subComm' a
9008   communicator obtained by com_split(comm). The comm_split
9009   is not restriced to be grouped with consequitive original ranks.
9010 
9011   Due the comm_split() usage, the parallel layout of the submatrices
9012   map directly to the layout of the original matrix [wrt the local
9013   row,col partitioning]. So the original 'DiagonalMat' naturally maps
9014   into the 'DiagonalMat' of the subMat, hence it is used directly from
9015   the subMat. However the offDiagMat looses some columns - and this is
9016   reconstructed with MatSetValues()
9017 
9018   Level: advanced
9019 
9020   Concepts: subcommunicator
9021   Concepts: submatrices
9022 
9023 .seealso: MatGetSubMatrices()
9024 @*/
9025 PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat* subMat)
9026 {
9027   PetscErrorCode ierr;
9028   PetscMPIInt    commsize,subCommSize;
9029 
9030   PetscFunctionBegin;
9031   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&commsize);CHKERRQ(ierr);
9032   ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr);
9033   if (subCommSize > commsize) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
9034 
9035   ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
9036   ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr);
9037   ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
9038   PetscFunctionReturn(0);
9039 }
9040 
9041 #undef __FUNCT__
9042 #define __FUNCT__ "MatGetLocalSubMatrix"
9043 /*@
9044    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
9045 
9046    Not Collective
9047 
9048    Input Arguments:
9049    mat - matrix to extract local submatrix from
9050    isrow - local row indices for submatrix
9051    iscol - local column indices for submatrix
9052 
9053    Output Arguments:
9054    submat - the submatrix
9055 
9056    Level: intermediate
9057 
9058    Notes:
9059    The submat should be returned with MatRestoreLocalSubMatrix().
9060 
9061    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
9062    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
9063 
9064    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
9065    MatSetValuesBlockedLocal() will also be implemented.
9066 
9067 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef()
9068 @*/
9069 PetscErrorCode  MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9070 {
9071   PetscErrorCode ierr;
9072 
9073   PetscFunctionBegin;
9074   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9075   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
9076   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
9077   PetscCheckSameComm(isrow,2,iscol,3);
9078   PetscValidPointer(submat,4);
9079 
9080   if (mat->ops->getlocalsubmatrix) {
9081     ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
9082   } else {
9083     ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr);
9084   }
9085   PetscFunctionReturn(0);
9086 }
9087 
9088 #undef __FUNCT__
9089 #define __FUNCT__ "MatRestoreLocalSubMatrix"
9090 /*@
9091    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
9092 
9093    Not Collective
9094 
9095    Input Arguments:
9096    mat - matrix to extract local submatrix from
9097    isrow - local row indices for submatrix
9098    iscol - local column indices for submatrix
9099    submat - the submatrix
9100 
9101    Level: intermediate
9102 
9103 .seealso: MatGetLocalSubMatrix()
9104 @*/
9105 PetscErrorCode  MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9106 {
9107   PetscErrorCode ierr;
9108 
9109   PetscFunctionBegin;
9110   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9111   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
9112   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
9113   PetscCheckSameComm(isrow,2,iscol,3);
9114   PetscValidPointer(submat,4);
9115   if (*submat) {PetscValidHeaderSpecific(*submat,MAT_CLASSID,4);}
9116 
9117   if (mat->ops->restorelocalsubmatrix) {
9118     ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
9119   } else {
9120     ierr = MatDestroy(submat);CHKERRQ(ierr);
9121   }
9122   *submat = PETSC_NULL;
9123   PetscFunctionReturn(0);
9124 }
9125 
9126 /* --------------------------------------------------------*/
9127 #undef __FUNCT__
9128 #define __FUNCT__ "MatFindZeroDiagonals"
9129 /*@
9130    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no entry in the matrix
9131 
9132    Collective on Mat
9133 
9134    Input Parameter:
9135 .  mat - the matrix
9136 
9137    Output Parameter:
9138 .  is - if any rows have zero diagonals this contains the list of them
9139 
9140    Level: developer
9141 
9142    Concepts: matrix-vector product
9143 
9144 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
9145 @*/
9146 PetscErrorCode  MatFindZeroDiagonals(Mat mat,IS *is)
9147 {
9148   PetscErrorCode ierr;
9149 
9150   PetscFunctionBegin;
9151   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9152   PetscValidType(mat,1);
9153   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9154   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9155 
9156   if (!mat->ops->findzerodiagonals) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"This matrix type does not have a find zero diagonals defined");
9157   ierr = (*mat->ops->findzerodiagonals)(mat,is);CHKERRQ(ierr);
9158   PetscFunctionReturn(0);
9159 }
9160 
9161 #undef __FUNCT__
9162 #define __FUNCT__ "MatInvertBlockDiagonal"
9163 /*@
9164   MatInvertBlockDiagonal - Inverts the block diagonal entries.
9165 
9166   Collective on Mat
9167 
9168   Input Parameters:
9169 . mat - the matrix
9170 
9171   Output Parameters:
9172 . values - the block inverses in column major order (FORTRAN-like)
9173 
9174   Level: advanced
9175 @*/
9176 PetscErrorCode  MatInvertBlockDiagonal(Mat mat,PetscScalar **values)
9177 {
9178   PetscErrorCode ierr;
9179 
9180   PetscFunctionBegin;
9181   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9182   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9183   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9184   if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
9185   ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr);
9186   PetscFunctionReturn(0);
9187 }
9188 
9189 #undef __FUNCT__
9190 #define __FUNCT__ "MatTransposeColoringDestroy"
9191 /*@C
9192     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
9193     via MatTransposeColoringCreate().
9194 
9195     Collective on MatTransposeColoring
9196 
9197     Input Parameter:
9198 .   c - coloring context
9199 
9200     Level: intermediate
9201 
9202 .seealso: MatTransposeColoringCreate()
9203 @*/
9204 PetscErrorCode  MatTransposeColoringDestroy(MatTransposeColoring *c)
9205 {
9206   PetscErrorCode       ierr;
9207   MatTransposeColoring matcolor=*c;
9208 
9209   PetscFunctionBegin;
9210   if (!matcolor) PetscFunctionReturn(0);
9211   if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; PetscFunctionReturn(0);}
9212 
9213   ierr = PetscFree(matcolor->ncolumns);CHKERRQ(ierr);
9214   ierr = PetscFree(matcolor->nrows);CHKERRQ(ierr);
9215   ierr = PetscFree(matcolor->colorforrow);CHKERRQ(ierr);
9216   ierr = PetscFree2(matcolor->rows,matcolor->columnsforspidx);CHKERRQ(ierr);
9217   ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr);
9218   ierr = PetscFree(matcolor->columns);CHKERRQ(ierr);
9219   ierr = PetscHeaderDestroy(c);CHKERRQ(ierr);
9220   PetscFunctionReturn(0);
9221 }
9222 
9223 #undef __FUNCT__
9224 #define __FUNCT__ "MatTransColoringApplySpToDen"
9225 /*@C
9226     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
9227     a MatTransposeColoring context has been created, computes a dense B^T by Apply
9228     MatTransposeColoring to sparse B.
9229 
9230     Collective on MatTransposeColoring
9231 
9232     Input Parameters:
9233 +   B - sparse matrix B
9234 .   Btdense - symbolic dense matrix B^T
9235 -   coloring - coloring context created with MatTransposeColoringCreate()
9236 
9237     Output Parameter:
9238 .   Btdense - dense matrix B^T
9239 
9240     Options Database Keys:
9241 +    -mat_transpose_coloring_view - Activates basic viewing or coloring
9242 .    -mat_transpose_coloring_view_draw - Activates drawing of coloring
9243 -    -mat_transpose_coloring_view_info - Activates viewing of coloring info
9244 
9245     Level: intermediate
9246 
9247 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy()
9248 
9249 .keywords: coloring
9250 @*/
9251 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
9252 {
9253   PetscErrorCode ierr;
9254 
9255   PetscFunctionBegin;
9256   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
9257   PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2);
9258   PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3);
9259 
9260   if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
9261   ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr);
9262   PetscFunctionReturn(0);
9263 }
9264 
9265 #undef __FUNCT__
9266 #define __FUNCT__ "MatTransColoringApplyDenToSp"
9267 /*@C
9268     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
9269     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
9270     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
9271     Csp from Cden.
9272 
9273     Collective on MatTransposeColoring
9274 
9275     Input Parameters:
9276 +   coloring - coloring context created with MatTransposeColoringCreate()
9277 -   Cden - matrix product of a sparse matrix and a dense matrix Btdense
9278 
9279     Output Parameter:
9280 .   Csp - sparse matrix
9281 
9282     Options Database Keys:
9283 +    -mat_multtranspose_coloring_view - Activates basic viewing or coloring
9284 .    -mat_multtranspose_coloring_view_draw - Activates drawing of coloring
9285 -    -mat_multtranspose_coloring_view_info - Activates viewing of coloring info
9286 
9287     Level: intermediate
9288 
9289 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()
9290 
9291 .keywords: coloring
9292 @*/
9293 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
9294 {
9295   PetscErrorCode ierr;
9296 
9297   PetscFunctionBegin;
9298   PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1);
9299   PetscValidHeaderSpecific(Cden,MAT_CLASSID,2);
9300   PetscValidHeaderSpecific(Csp,MAT_CLASSID,3);
9301 
9302   if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
9303   ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr);
9304   PetscFunctionReturn(0);
9305 }
9306 
9307 #undef __FUNCT__
9308 #define __FUNCT__ "MatTransposeColoringCreate"
9309 /*@C
9310    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.
9311 
9312    Collective on Mat
9313 
9314    Input Parameters:
9315 +  mat - the matrix product C
9316 -  iscoloring - the coloring of the matrix; usually obtained with MatGetColoring() or DMCreateColoring()
9317 
9318     Output Parameter:
9319 .   color - the new coloring context
9320 
9321     Level: intermediate
9322 
9323 .seealso: MatTransposeColoringDestroy(), MatTransposeColoringSetFromOptions(), MatTransColoringApplySpToDen(),
9324            MatTransColoringApplyDen()ToSp, MatTransposeColoringView(),
9325 @*/
9326 PetscErrorCode  MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
9327 {
9328   MatTransposeColoring  c;
9329   MPI_Comm              comm;
9330   PetscErrorCode        ierr;
9331 
9332   PetscFunctionBegin;
9333   ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
9334   ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
9335   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);
9336 
9337   c->ctype = iscoloring->ctype;
9338   if (mat->ops->transposecoloringcreate) {
9339     ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr);
9340   } else SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Code not yet written for this matrix type");
9341 
9342   *color = c;
9343   ierr = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
9344   PetscFunctionReturn(0);
9345 }
9346