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