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