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