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