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