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