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