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