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