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