xref: /petsc/src/mat/interface/matrix.c (revision 8370ee3b0cabe4fc747f6e7e660d1b382033c84c)
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 #if defined(PETSC_USE_DEBUG)
6202   CHKMEMQ;
6203 #endif
6204   if (!mat->ops->restorearray) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6205   ierr = (*mat->ops->restorearray)(mat,v);CHKERRQ(ierr);
6206   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6207 #if defined(PETSC_HAVE_CUSP)
6208   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
6209     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
6210   }
6211 #endif
6212   PetscFunctionReturn(0);
6213 }
6214 
6215 #undef __FUNCT__
6216 #define __FUNCT__ "MatGetSubMatrices"
6217 /*@C
6218    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
6219    points to an array of valid matrices, they may be reused to store the new
6220    submatrices.
6221 
6222    Collective on Mat
6223 
6224    Input Parameters:
6225 +  mat - the matrix
6226 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6227 .  irow, icol - index sets of rows and columns to extract
6228 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6229 
6230    Output Parameter:
6231 .  submat - the array of submatrices
6232 
6233    Notes:
6234    MatGetSubMatrices() can extract ONLY sequential submatrices
6235    (from both sequential and parallel matrices). Use MatGetSubMatrix()
6236    to extract a parallel submatrix.
6237 
6238    When extracting submatrices from a parallel matrix, each processor can
6239    form a different submatrix by setting the rows and columns of its
6240    individual index sets according to the local submatrix desired.
6241 
6242    When finished using the submatrices, the user should destroy
6243    them with MatDestroyMatrices().
6244 
6245    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6246    original matrix has not changed from that last call to MatGetSubMatrices().
6247 
6248    This routine creates the matrices in submat; you should NOT create them before
6249    calling it. It also allocates the array of matrix pointers submat.
6250 
6251    For BAIJ matrices the index sets must respect the block structure, that is if they
6252    request one row/column in a block, they must request all rows/columns that are in
6253    that block. For example, if the block size is 2 you cannot request just row 0 and
6254    column 0.
6255 
6256    Fortran Note:
6257    The Fortran interface is slightly different from that given below; it
6258    requires one to pass in  as submat a Mat (integer) array of size at least m.
6259 
6260    Level: advanced
6261 
6262    Concepts: matrices^accessing submatrices
6263    Concepts: submatrices
6264 
6265 .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6266 @*/
6267 PetscErrorCode  MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6268 {
6269   PetscErrorCode ierr;
6270   PetscInt        i;
6271   PetscBool       eq;
6272 
6273   PetscFunctionBegin;
6274   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6275   PetscValidType(mat,1);
6276   if (n) {
6277     PetscValidPointer(irow,3);
6278     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6279     PetscValidPointer(icol,4);
6280     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6281   }
6282   PetscValidPointer(submat,6);
6283   if (n && scall == MAT_REUSE_MATRIX) {
6284     PetscValidPointer(*submat,6);
6285     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6286   }
6287   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6288   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6289   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6290   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6291 
6292   ierr = PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
6293   ierr = (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6294   ierr = PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
6295   for (i=0; i<n; i++) {
6296     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6297       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6298       if (eq) {
6299 	if (mat->symmetric){
6300 	  ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6301 	} else if (mat->hermitian) {
6302 	  ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6303 	} else if (mat->structurally_symmetric) {
6304 	  ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6305 	}
6306       }
6307     }
6308   }
6309   PetscFunctionReturn(0);
6310 }
6311 
6312 #undef __FUNCT__
6313 #define __FUNCT__ "MatGetSubMatricesParallel"
6314 PetscErrorCode  MatGetSubMatricesParallel(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6315 {
6316   PetscErrorCode ierr;
6317   PetscInt        i;
6318   PetscBool       eq;
6319 
6320   PetscFunctionBegin;
6321   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6322   PetscValidType(mat,1);
6323   if (n) {
6324     PetscValidPointer(irow,3);
6325     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6326     PetscValidPointer(icol,4);
6327     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6328   }
6329   PetscValidPointer(submat,6);
6330   if (n && scall == MAT_REUSE_MATRIX) {
6331     PetscValidPointer(*submat,6);
6332     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6333   }
6334   if (!mat->ops->getsubmatricesparallel) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6335   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6336   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6337   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6338 
6339   ierr = PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
6340   ierr = (*mat->ops->getsubmatricesparallel)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6341   ierr = PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
6342   for (i=0; i<n; i++) {
6343     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6344       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6345       if (eq) {
6346 	if (mat->symmetric){
6347 	  ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6348 	} else if (mat->hermitian) {
6349 	  ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6350 	} else if (mat->structurally_symmetric) {
6351 	  ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6352 	}
6353       }
6354     }
6355   }
6356   PetscFunctionReturn(0);
6357 }
6358 
6359 #undef __FUNCT__
6360 #define __FUNCT__ "MatDestroyMatrices"
6361 /*@C
6362    MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().
6363 
6364    Collective on Mat
6365 
6366    Input Parameters:
6367 +  n - the number of local matrices
6368 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6369                        sequence of MatGetSubMatrices())
6370 
6371    Level: advanced
6372 
6373     Notes: Frees not only the matrices, but also the array that contains the matrices
6374            In Fortran will not free the array.
6375 
6376 .seealso: MatGetSubMatrices()
6377 @*/
6378 PetscErrorCode  MatDestroyMatrices(PetscInt n,Mat *mat[])
6379 {
6380   PetscErrorCode ierr;
6381   PetscInt       i;
6382 
6383   PetscFunctionBegin;
6384   if (!*mat) PetscFunctionReturn(0);
6385   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6386   PetscValidPointer(mat,2);
6387   for (i=0; i<n; i++) {
6388     ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr);
6389   }
6390   /* memory is allocated even if n = 0 */
6391   ierr = PetscFree(*mat);CHKERRQ(ierr);
6392   *mat = PETSC_NULL;
6393   PetscFunctionReturn(0);
6394 }
6395 
6396 #undef __FUNCT__
6397 #define __FUNCT__ "MatGetSeqNonzeroStructure"
6398 /*@C
6399    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
6400 
6401    Collective on Mat
6402 
6403    Input Parameters:
6404 .  mat - the matrix
6405 
6406    Output Parameter:
6407 .  matstruct - the sequential matrix with the nonzero structure of mat
6408 
6409   Level: intermediate
6410 
6411 .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
6412 @*/
6413 PetscErrorCode  MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6414 {
6415   PetscErrorCode ierr;
6416 
6417   PetscFunctionBegin;
6418   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6419   PetscValidPointer(matstruct,2);
6420 
6421   PetscValidType(mat,1);
6422   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6423   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6424 
6425   if (!mat->ops->getseqnonzerostructure) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6426   ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
6427   ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr);
6428   ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
6429   PetscFunctionReturn(0);
6430 }
6431 
6432 #undef __FUNCT__
6433 #define __FUNCT__ "MatDestroySeqNonzeroStructure"
6434 /*@C
6435    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
6436 
6437    Collective on Mat
6438 
6439    Input Parameters:
6440 .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
6441                        sequence of MatGetSequentialNonzeroStructure())
6442 
6443    Level: advanced
6444 
6445     Notes: Frees not only the matrices, but also the array that contains the matrices
6446 
6447 .seealso: MatGetSeqNonzeroStructure()
6448 @*/
6449 PetscErrorCode  MatDestroySeqNonzeroStructure(Mat *mat)
6450 {
6451   PetscErrorCode ierr;
6452 
6453   PetscFunctionBegin;
6454   PetscValidPointer(mat,1);
6455   ierr = MatDestroy(mat);CHKERRQ(ierr);
6456   PetscFunctionReturn(0);
6457 }
6458 
6459 #undef __FUNCT__
6460 #define __FUNCT__ "MatIncreaseOverlap"
6461 /*@
6462    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6463    replaces the index sets by larger ones that represent submatrices with
6464    additional overlap.
6465 
6466    Collective on Mat
6467 
6468    Input Parameters:
6469 +  mat - the matrix
6470 .  n   - the number of index sets
6471 .  is  - the array of index sets (these index sets will changed during the call)
6472 -  ov  - the additional overlap requested
6473 
6474    Level: developer
6475 
6476    Concepts: overlap
6477    Concepts: ASM^computing overlap
6478 
6479 .seealso: MatGetSubMatrices()
6480 @*/
6481 PetscErrorCode  MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6482 {
6483   PetscErrorCode ierr;
6484 
6485   PetscFunctionBegin;
6486   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6487   PetscValidType(mat,1);
6488   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6489   if (n) {
6490     PetscValidPointer(is,3);
6491     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
6492   }
6493   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6494   if (mat->factortype)     SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6495   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6496 
6497   if (!ov) PetscFunctionReturn(0);
6498   if (!mat->ops->increaseoverlap) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6499   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
6500   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
6501   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
6502   PetscFunctionReturn(0);
6503 }
6504 
6505 #undef __FUNCT__
6506 #define __FUNCT__ "MatGetBlockSize"
6507 /*@
6508    MatGetBlockSize - Returns the matrix block size; useful especially for the
6509    block row and block diagonal formats.
6510 
6511    Not Collective
6512 
6513    Input Parameter:
6514 .  mat - the matrix
6515 
6516    Output Parameter:
6517 .  bs - block size
6518 
6519    Notes:
6520    Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ
6521 
6522    Level: intermediate
6523 
6524    Concepts: matrices^block size
6525 
6526 .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ()
6527 @*/
6528 PetscErrorCode  MatGetBlockSize(Mat mat,PetscInt *bs)
6529 {
6530   PetscErrorCode ierr;
6531 
6532   PetscFunctionBegin;
6533   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6534   PetscValidType(mat,1);
6535   PetscValidIntPointer(bs,2);
6536   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6537   *bs = mat->rmap->bs;
6538   PetscFunctionReturn(0);
6539 }
6540 
6541 #undef __FUNCT__
6542 #define __FUNCT__ "MatSetBlockSize"
6543 /*@
6544    MatSetBlockSize - Sets the matrix block size; for many matrix types you
6545      cannot use this and MUST set the blocksize when you preallocate the matrix
6546 
6547    Logically Collective on Mat
6548 
6549    Input Parameters:
6550 +  mat - the matrix
6551 -  bs - block size
6552 
6553    Notes:
6554      For BAIJ matrices, this just checks that the block size agrees with the BAIJ size,
6555      it is not possible to change BAIJ block sizes after preallocation.
6556 
6557    Level: intermediate
6558 
6559    Concepts: matrices^block size
6560 
6561 .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ(), MatGetBlockSize()
6562 @*/
6563 PetscErrorCode  MatSetBlockSize(Mat mat,PetscInt bs)
6564 {
6565   PetscErrorCode ierr;
6566 
6567   PetscFunctionBegin;
6568   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6569   PetscValidType(mat,1);
6570   PetscValidLogicalCollectiveInt(mat,bs,2);
6571   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6572   if (bs < 1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Block size %D, must be positive",bs);
6573   if (mat->ops->setblocksize) {
6574     ierr = (*mat->ops->setblocksize)(mat,bs);CHKERRQ(ierr);
6575   } else {
6576     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Cannot set the blocksize for matrix type %s",((PetscObject)mat)->type_name);
6577   }
6578   PetscFunctionReturn(0);
6579 }
6580 
6581 #undef __FUNCT__
6582 #define __FUNCT__ "MatGetRowIJ"
6583 /*@C
6584     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
6585 
6586    Collective on Mat
6587 
6588     Input Parameters:
6589 +   mat - the matrix
6590 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
6591 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
6592 -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
6593                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6594                  always used.
6595 
6596     Output Parameters:
6597 +   n - number of rows in the (possibly compressed) matrix
6598 .   ia - the row pointers [of length n+1]
6599 .   ja - the column indices
6600 -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
6601            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
6602 
6603     Level: developer
6604 
6605     Notes: You CANNOT change any of the ia[] or ja[] values.
6606 
6607            Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values
6608 
6609     Fortran Node
6610 
6611            In Fortran use
6612 $           PetscInt ia(1), ja(1)
6613 $           PetscOffset iia, jja
6614 $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
6615 $
6616 $          or
6617 $
6618 $           PetscScalar, pointer :: xx_v(:)
6619 $    call  MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
6620 
6621 
6622        Acess the ith and jth entries via ia(iia + i) and ja(jja + j)
6623 
6624 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatGetArray()
6625 @*/
6626 PetscErrorCode  MatGetRowIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6627 {
6628   PetscErrorCode ierr;
6629 
6630   PetscFunctionBegin;
6631   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6632   PetscValidType(mat,1);
6633   PetscValidIntPointer(n,4);
6634   if (ia) PetscValidIntPointer(ia,5);
6635   if (ja) PetscValidIntPointer(ja,6);
6636   PetscValidIntPointer(done,7);
6637   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6638   if (!mat->ops->getrowij) *done = PETSC_FALSE;
6639   else {
6640     *done = PETSC_TRUE;
6641     ierr = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
6642     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6643     ierr = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
6644   }
6645   PetscFunctionReturn(0);
6646 }
6647 
6648 #undef __FUNCT__
6649 #define __FUNCT__ "MatGetColumnIJ"
6650 /*@C
6651     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
6652 
6653     Collective on Mat
6654 
6655     Input Parameters:
6656 +   mat - the matrix
6657 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6658 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6659                 symmetrized
6660 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6661                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6662                  always used.
6663 
6664     Output Parameters:
6665 +   n - number of columns in the (possibly compressed) matrix
6666 .   ia - the column pointers
6667 .   ja - the row indices
6668 -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
6669 
6670     Level: developer
6671 
6672 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6673 @*/
6674 PetscErrorCode  MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6675 {
6676   PetscErrorCode ierr;
6677 
6678   PetscFunctionBegin;
6679   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6680   PetscValidType(mat,1);
6681   PetscValidIntPointer(n,4);
6682   if (ia) PetscValidIntPointer(ia,5);
6683   if (ja) PetscValidIntPointer(ja,6);
6684   PetscValidIntPointer(done,7);
6685   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6686   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
6687   else {
6688     *done = PETSC_TRUE;
6689     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6690   }
6691   PetscFunctionReturn(0);
6692 }
6693 
6694 #undef __FUNCT__
6695 #define __FUNCT__ "MatRestoreRowIJ"
6696 /*@C
6697     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
6698     MatGetRowIJ().
6699 
6700     Collective on Mat
6701 
6702     Input Parameters:
6703 +   mat - the matrix
6704 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6705 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6706                 symmetrized
6707 -   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6708                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6709                  always used.
6710 
6711     Output Parameters:
6712 +   n - size of (possibly compressed) matrix
6713 .   ia - the row pointers
6714 .   ja - the column indices
6715 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
6716 
6717     Level: developer
6718 
6719 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6720 @*/
6721 PetscErrorCode  MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6722 {
6723   PetscErrorCode ierr;
6724 
6725   PetscFunctionBegin;
6726   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6727   PetscValidType(mat,1);
6728   if (ia) PetscValidIntPointer(ia,5);
6729   if (ja) PetscValidIntPointer(ja,6);
6730   PetscValidIntPointer(done,7);
6731   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6732 
6733   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
6734   else {
6735     *done = PETSC_TRUE;
6736     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6737   }
6738   PetscFunctionReturn(0);
6739 }
6740 
6741 #undef __FUNCT__
6742 #define __FUNCT__ "MatRestoreColumnIJ"
6743 /*@C
6744     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
6745     MatGetColumnIJ().
6746 
6747     Collective on Mat
6748 
6749     Input Parameters:
6750 +   mat - the matrix
6751 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6752 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6753                 symmetrized
6754 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6755                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6756                  always used.
6757 
6758     Output Parameters:
6759 +   n - size of (possibly compressed) matrix
6760 .   ia - the column pointers
6761 .   ja - the row indices
6762 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
6763 
6764     Level: developer
6765 
6766 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
6767 @*/
6768 PetscErrorCode  MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6769 {
6770   PetscErrorCode ierr;
6771 
6772   PetscFunctionBegin;
6773   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6774   PetscValidType(mat,1);
6775   if (ia) PetscValidIntPointer(ia,5);
6776   if (ja) PetscValidIntPointer(ja,6);
6777   PetscValidIntPointer(done,7);
6778   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6779 
6780   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
6781   else {
6782     *done = PETSC_TRUE;
6783     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6784   }
6785   PetscFunctionReturn(0);
6786 }
6787 
6788 #undef __FUNCT__
6789 #define __FUNCT__ "MatColoringPatch"
6790 /*@C
6791     MatColoringPatch -Used inside matrix coloring routines that
6792     use MatGetRowIJ() and/or MatGetColumnIJ().
6793 
6794     Collective on Mat
6795 
6796     Input Parameters:
6797 +   mat - the matrix
6798 .   ncolors - max color value
6799 .   n   - number of entries in colorarray
6800 -   colorarray - array indicating color for each column
6801 
6802     Output Parameters:
6803 .   iscoloring - coloring generated using colorarray information
6804 
6805     Level: developer
6806 
6807 .seealso: MatGetRowIJ(), MatGetColumnIJ()
6808 
6809 @*/
6810 PetscErrorCode  MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
6811 {
6812   PetscErrorCode ierr;
6813 
6814   PetscFunctionBegin;
6815   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6816   PetscValidType(mat,1);
6817   PetscValidIntPointer(colorarray,4);
6818   PetscValidPointer(iscoloring,5);
6819   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6820 
6821   if (!mat->ops->coloringpatch){
6822     ierr = ISColoringCreate(((PetscObject)mat)->comm,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
6823   } else {
6824     ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
6825   }
6826   PetscFunctionReturn(0);
6827 }
6828 
6829 
6830 #undef __FUNCT__
6831 #define __FUNCT__ "MatSetUnfactored"
6832 /*@
6833    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
6834 
6835    Logically Collective on Mat
6836 
6837    Input Parameter:
6838 .  mat - the factored matrix to be reset
6839 
6840    Notes:
6841    This routine should be used only with factored matrices formed by in-place
6842    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
6843    format).  This option can save memory, for example, when solving nonlinear
6844    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
6845    ILU(0) preconditioner.
6846 
6847    Note that one can specify in-place ILU(0) factorization by calling
6848 .vb
6849      PCType(pc,PCILU);
6850      PCFactorSeUseInPlace(pc);
6851 .ve
6852    or by using the options -pc_type ilu -pc_factor_in_place
6853 
6854    In-place factorization ILU(0) can also be used as a local
6855    solver for the blocks within the block Jacobi or additive Schwarz
6856    methods (runtime option: -sub_pc_factor_in_place).  See the discussion
6857    of these preconditioners in the <a href="../../docs/manual.pdf#ch_pc">PC chapter of the users manual</a> for details on setting
6858    local solver options.
6859 
6860    Most users should employ the simplified KSP interface for linear solvers
6861    instead of working directly with matrix algebra routines such as this.
6862    See, e.g., KSPCreate().
6863 
6864    Level: developer
6865 
6866 .seealso: PCFactorSetUseInPlace()
6867 
6868    Concepts: matrices^unfactored
6869 
6870 @*/
6871 PetscErrorCode  MatSetUnfactored(Mat mat)
6872 {
6873   PetscErrorCode ierr;
6874 
6875   PetscFunctionBegin;
6876   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6877   PetscValidType(mat,1);
6878   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6879   mat->factortype = MAT_FACTOR_NONE;
6880   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
6881   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
6882   PetscFunctionReturn(0);
6883 }
6884 
6885 /*MC
6886     MatGetArrayF90 - Accesses a matrix array from Fortran90.
6887 
6888     Synopsis:
6889     MatGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
6890 
6891     Not collective
6892 
6893     Input Parameter:
6894 .   x - matrix
6895 
6896     Output Parameters:
6897 +   xx_v - the Fortran90 pointer to the array
6898 -   ierr - error code
6899 
6900     Example of Usage:
6901 .vb
6902       PetscScalar, pointer xx_v(:,:)
6903       ....
6904       call MatGetArrayF90(x,xx_v,ierr)
6905       a = xx_v(3)
6906       call MatRestoreArrayF90(x,xx_v,ierr)
6907 .ve
6908 
6909     Notes:
6910     Not yet supported for all F90 compilers
6911 
6912     Level: advanced
6913 
6914 .seealso:  MatRestoreArrayF90(), MatGetArray(), MatRestoreArray()
6915 
6916     Concepts: matrices^accessing array
6917 
6918 M*/
6919 
6920 /*MC
6921     MatRestoreArrayF90 - Restores a matrix array that has been
6922     accessed with MatGetArrayF90().
6923 
6924     Synopsis:
6925     MatRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
6926 
6927     Not collective
6928 
6929     Input Parameters:
6930 +   x - matrix
6931 -   xx_v - the Fortran90 pointer to the array
6932 
6933     Output Parameter:
6934 .   ierr - error code
6935 
6936     Example of Usage:
6937 .vb
6938        PetscScalar, pointer xx_v(:)
6939        ....
6940        call MatGetArrayF90(x,xx_v,ierr)
6941        a = xx_v(3)
6942        call MatRestoreArrayF90(x,xx_v,ierr)
6943 .ve
6944 
6945     Notes:
6946     Not yet supported for all F90 compilers
6947 
6948     Level: advanced
6949 
6950 .seealso:  MatGetArrayF90(), MatGetArray(), MatRestoreArray()
6951 
6952 M*/
6953 
6954 
6955 #undef __FUNCT__
6956 #define __FUNCT__ "MatGetSubMatrix"
6957 /*@
6958     MatGetSubMatrix - Gets a single submatrix on the same number of processors
6959                       as the original matrix.
6960 
6961     Collective on Mat
6962 
6963     Input Parameters:
6964 +   mat - the original matrix
6965 .   isrow - parallel IS containing the rows this processor should obtain
6966 .   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.
6967 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6968 
6969     Output Parameter:
6970 .   newmat - the new submatrix, of the same type as the old
6971 
6972     Level: advanced
6973 
6974     Notes:
6975     The submatrix will be able to be multiplied with vectors using the same layout as iscol.
6976 
6977     The rows in isrow will be sorted into the same order as the original matrix on each process.
6978 
6979       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
6980    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
6981    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
6982    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
6983    you are finished using it.
6984 
6985     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
6986     the input matrix.
6987 
6988     If iscol is PETSC_NULL then all columns are obtained (not supported in Fortran).
6989 
6990    Example usage:
6991    Consider the following 8x8 matrix with 34 non-zero values, that is
6992    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
6993    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
6994    as follows:
6995 
6996 .vb
6997             1  2  0  |  0  3  0  |  0  4
6998     Proc0   0  5  6  |  7  0  0  |  8  0
6999             9  0 10  | 11  0  0  | 12  0
7000     -------------------------------------
7001            13  0 14  | 15 16 17  |  0  0
7002     Proc1   0 18  0  | 19 20 21  |  0  0
7003             0  0  0  | 22 23  0  | 24  0
7004     -------------------------------------
7005     Proc2  25 26 27  |  0  0 28  | 29  0
7006            30  0  0  | 31 32 33  |  0 34
7007 .ve
7008 
7009     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is
7010 
7011 .vb
7012             2  0  |  0  3  0  |  0
7013     Proc0   5  6  |  7  0  0  |  8
7014     -------------------------------
7015     Proc1  18  0  | 19 20 21  |  0
7016     -------------------------------
7017     Proc2  26 27  |  0  0 28  | 29
7018             0  0  | 31 32 33  |  0
7019 .ve
7020 
7021 
7022     Concepts: matrices^submatrices
7023 
7024 .seealso: MatGetSubMatrices()
7025 @*/
7026 PetscErrorCode  MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7027 {
7028   PetscErrorCode ierr;
7029   PetscMPIInt    size;
7030   Mat            *local;
7031   IS             iscoltmp;
7032 
7033   PetscFunctionBegin;
7034   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7035   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
7036   if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
7037   PetscValidPointer(newmat,5);
7038   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5);
7039   PetscValidType(mat,1);
7040   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7041   ierr = MatPreallocated(mat);CHKERRQ(ierr);
7042   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
7043 
7044   if (!iscol) {
7045     ierr = ISCreateStride(((PetscObject)mat)->comm,mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr);
7046   } else {
7047     iscoltmp = iscol;
7048   }
7049 
7050   /* if original matrix is on just one processor then use submatrix generated */
7051   if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7052     ierr = MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
7053     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7054     PetscFunctionReturn(0);
7055   } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) {
7056     ierr    = MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
7057     *newmat = *local;
7058     ierr    = PetscFree(local);CHKERRQ(ierr);
7059     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7060     PetscFunctionReturn(0);
7061   } else if (!mat->ops->getsubmatrix) {
7062     /* Create a new matrix type that implements the operation using the full matrix */
7063     switch (cll) {
7064       case MAT_INITIAL_MATRIX:
7065         ierr = MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr);
7066         break;
7067       case MAT_REUSE_MATRIX:
7068         ierr = MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr);
7069         break;
7070       default: SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7071     }
7072     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7073     PetscFunctionReturn(0);
7074   }
7075 
7076   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7077   ierr = (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr);
7078   if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7079   if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);}
7080   PetscFunctionReturn(0);
7081 }
7082 
7083 #undef __FUNCT__
7084 #define __FUNCT__ "MatStashSetInitialSize"
7085 /*@
7086    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7087    used during the assembly process to store values that belong to
7088    other processors.
7089 
7090    Not Collective
7091 
7092    Input Parameters:
7093 +  mat   - the matrix
7094 .  size  - the initial size of the stash.
7095 -  bsize - the initial size of the block-stash(if used).
7096 
7097    Options Database Keys:
7098 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
7099 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
7100 
7101    Level: intermediate
7102 
7103    Notes:
7104      The block-stash is used for values set with MatSetValuesBlocked() while
7105      the stash is used for values set with MatSetValues()
7106 
7107      Run with the option -info and look for output of the form
7108      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7109      to determine the appropriate value, MM, to use for size and
7110      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7111      to determine the value, BMM to use for bsize
7112 
7113    Concepts: stash^setting matrix size
7114    Concepts: matrices^stash
7115 
7116 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
7117 
7118 @*/
7119 PetscErrorCode  MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7120 {
7121   PetscErrorCode ierr;
7122 
7123   PetscFunctionBegin;
7124   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7125   PetscValidType(mat,1);
7126   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
7127   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
7128   PetscFunctionReturn(0);
7129 }
7130 
7131 #undef __FUNCT__
7132 #define __FUNCT__ "MatInterpolateAdd"
7133 /*@
7134    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
7135      the matrix
7136 
7137    Neighbor-wise Collective on Mat
7138 
7139    Input Parameters:
7140 +  mat   - the matrix
7141 .  x,y - the vectors
7142 -  w - where the result is stored
7143 
7144    Level: intermediate
7145 
7146    Notes:
7147     w may be the same vector as y.
7148 
7149     This allows one to use either the restriction or interpolation (its transpose)
7150     matrix to do the interpolation
7151 
7152     Concepts: interpolation
7153 
7154 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7155 
7156 @*/
7157 PetscErrorCode  MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7158 {
7159   PetscErrorCode ierr;
7160   PetscInt       M,N,Ny;
7161 
7162   PetscFunctionBegin;
7163   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7164   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7165   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7166   PetscValidHeaderSpecific(w,VEC_CLASSID,4);
7167   PetscValidType(A,1);
7168   ierr = MatPreallocated(A);CHKERRQ(ierr);
7169   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
7170   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
7171   if (M == Ny) {
7172     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
7173   } else {
7174     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
7175   }
7176   PetscFunctionReturn(0);
7177 }
7178 
7179 #undef __FUNCT__
7180 #define __FUNCT__ "MatInterpolate"
7181 /*@
7182    MatInterpolate - y = A*x or A'*x depending on the shape of
7183      the matrix
7184 
7185    Neighbor-wise Collective on Mat
7186 
7187    Input Parameters:
7188 +  mat   - the matrix
7189 -  x,y - the vectors
7190 
7191    Level: intermediate
7192 
7193    Notes:
7194     This allows one to use either the restriction or interpolation (its transpose)
7195     matrix to do the interpolation
7196 
7197    Concepts: matrices^interpolation
7198 
7199 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7200 
7201 @*/
7202 PetscErrorCode  MatInterpolate(Mat A,Vec x,Vec y)
7203 {
7204   PetscErrorCode ierr;
7205   PetscInt       M,N,Ny;
7206 
7207   PetscFunctionBegin;
7208   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7209   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7210   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7211   PetscValidType(A,1);
7212   ierr = MatPreallocated(A);CHKERRQ(ierr);
7213   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
7214   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
7215   if (M == Ny) {
7216     ierr = MatMult(A,x,y);CHKERRQ(ierr);
7217   } else {
7218     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
7219   }
7220   PetscFunctionReturn(0);
7221 }
7222 
7223 #undef __FUNCT__
7224 #define __FUNCT__ "MatRestrict"
7225 /*@
7226    MatRestrict - y = A*x or A'*x
7227 
7228    Neighbor-wise Collective on Mat
7229 
7230    Input Parameters:
7231 +  mat   - the matrix
7232 -  x,y - the vectors
7233 
7234    Level: intermediate
7235 
7236    Notes:
7237     This allows one to use either the restriction or interpolation (its transpose)
7238     matrix to do the restriction
7239 
7240    Concepts: matrices^restriction
7241 
7242 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
7243 
7244 @*/
7245 PetscErrorCode  MatRestrict(Mat A,Vec x,Vec y)
7246 {
7247   PetscErrorCode ierr;
7248   PetscInt       M,N,Ny;
7249 
7250   PetscFunctionBegin;
7251   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7252   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7253   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7254   PetscValidType(A,1);
7255   ierr = MatPreallocated(A);CHKERRQ(ierr);
7256 
7257   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
7258   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
7259   if (M == Ny) {
7260     ierr = MatMult(A,x,y);CHKERRQ(ierr);
7261   } else {
7262     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
7263   }
7264   PetscFunctionReturn(0);
7265 }
7266 
7267 #undef __FUNCT__
7268 #define __FUNCT__ "MatNullSpaceAttach"
7269 /*@
7270    MatNullSpaceAttach - attaches a null space to a matrix.
7271         This null space will be removed from the resulting vector whenever
7272         MatMult() is called
7273 
7274    Logically Collective on Mat and MatNullSpace
7275 
7276    Input Parameters:
7277 +  mat - the matrix
7278 -  nullsp - the null space object
7279 
7280    Level: developer
7281 
7282    Notes:
7283       Overwrites any previous null space that may have been attached
7284 
7285    Concepts: null space^attaching to matrix
7286 
7287 .seealso: MatCreate(), MatNullSpaceCreate()
7288 @*/
7289 PetscErrorCode  MatNullSpaceAttach(Mat mat,MatNullSpace nullsp)
7290 {
7291   PetscErrorCode ierr;
7292 
7293   PetscFunctionBegin;
7294   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7295   PetscValidType(mat,1);
7296   PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
7297   ierr = MatPreallocated(mat);CHKERRQ(ierr);
7298   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
7299   if (mat->nullsp) { ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr); }
7300   mat->nullsp = nullsp;
7301   PetscFunctionReturn(0);
7302 }
7303 
7304 #undef __FUNCT__
7305 #define __FUNCT__ "MatICCFactor"
7306 /*@C
7307    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
7308 
7309    Collective on Mat
7310 
7311    Input Parameters:
7312 +  mat - the matrix
7313 .  row - row/column permutation
7314 .  fill - expected fill factor >= 1.0
7315 -  level - level of fill, for ICC(k)
7316 
7317    Notes:
7318    Probably really in-place only when level of fill is zero, otherwise allocates
7319    new space to store factored matrix and deletes previous memory.
7320 
7321    Most users should employ the simplified KSP interface for linear solvers
7322    instead of working directly with matrix algebra routines such as this.
7323    See, e.g., KSPCreate().
7324 
7325    Level: developer
7326 
7327    Concepts: matrices^incomplete Cholesky factorization
7328    Concepts: Cholesky factorization
7329 
7330 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
7331 
7332     Developer Note: fortran interface is not autogenerated as the f90
7333     interface defintion cannot be generated correctly [due to MatFactorInfo]
7334 
7335 @*/
7336 PetscErrorCode  MatICCFactor(Mat mat,IS row,const MatFactorInfo* info)
7337 {
7338   PetscErrorCode ierr;
7339 
7340   PetscFunctionBegin;
7341   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7342   PetscValidType(mat,1);
7343   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
7344   PetscValidPointer(info,3);
7345   if (mat->rmap->N != mat->cmap->N) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONG,"matrix must be square");
7346   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7347   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7348   if (!mat->ops->iccfactor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7349   ierr = MatPreallocated(mat);CHKERRQ(ierr);
7350   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
7351   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
7352   PetscFunctionReturn(0);
7353 }
7354 
7355 #undef __FUNCT__
7356 #define __FUNCT__ "MatSetValuesAdic"
7357 /*@
7358    MatSetValuesAdic - Sets values computed with ADIC automatic differentiation into a matrix.
7359 
7360    Not Collective
7361 
7362    Input Parameters:
7363 +  mat - the matrix
7364 -  v - the values compute with ADIC
7365 
7366    Level: developer
7367 
7368    Notes:
7369      Must call MatSetColoring() before using this routine. Also this matrix must already
7370      have its nonzero pattern determined.
7371 
7372 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7373           MatSetValues(), MatSetColoring(), MatSetValuesAdifor()
7374 @*/
7375 PetscErrorCode  MatSetValuesAdic(Mat mat,void *v)
7376 {
7377   PetscErrorCode ierr;
7378 
7379   PetscFunctionBegin;
7380   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7381   PetscValidType(mat,1);
7382   PetscValidPointer(mat,2);
7383 
7384   if (!mat->assembled) {
7385     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7386   }
7387   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
7388   if (!mat->ops->setvaluesadic) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7389   ierr = (*mat->ops->setvaluesadic)(mat,v);CHKERRQ(ierr);
7390   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
7391   ierr = MatView_Private(mat);CHKERRQ(ierr);
7392   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
7393   PetscFunctionReturn(0);
7394 }
7395 
7396 
7397 #undef __FUNCT__
7398 #define __FUNCT__ "MatSetColoring"
7399 /*@
7400    MatSetColoring - Sets a coloring used by calls to MatSetValuesAdic()
7401 
7402    Not Collective
7403 
7404    Input Parameters:
7405 +  mat - the matrix
7406 -  coloring - the coloring
7407 
7408    Level: developer
7409 
7410 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7411           MatSetValues(), MatSetValuesAdic()
7412 @*/
7413 PetscErrorCode  MatSetColoring(Mat mat,ISColoring coloring)
7414 {
7415   PetscErrorCode ierr;
7416 
7417   PetscFunctionBegin;
7418   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7419   PetscValidType(mat,1);
7420   PetscValidPointer(coloring,2);
7421 
7422   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7423   if (!mat->ops->setcoloring) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7424   ierr = (*mat->ops->setcoloring)(mat,coloring);CHKERRQ(ierr);
7425   PetscFunctionReturn(0);
7426 }
7427 
7428 #undef __FUNCT__
7429 #define __FUNCT__ "MatSetValuesAdifor"
7430 /*@
7431    MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.
7432 
7433    Not Collective
7434 
7435    Input Parameters:
7436 +  mat - the matrix
7437 .  nl - leading dimension of v
7438 -  v - the values compute with ADIFOR
7439 
7440    Level: developer
7441 
7442    Notes:
7443      Must call MatSetColoring() before using this routine. Also this matrix must already
7444      have its nonzero pattern determined.
7445 
7446 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7447           MatSetValues(), MatSetColoring()
7448 @*/
7449 PetscErrorCode  MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
7450 {
7451   PetscErrorCode ierr;
7452 
7453   PetscFunctionBegin;
7454   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7455   PetscValidType(mat,1);
7456   PetscValidPointer(v,3);
7457 
7458   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7459   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
7460   if (!mat->ops->setvaluesadifor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7461   ierr = (*mat->ops->setvaluesadifor)(mat,nl,v);CHKERRQ(ierr);
7462   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
7463   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
7464   PetscFunctionReturn(0);
7465 }
7466 
7467 #undef __FUNCT__
7468 #define __FUNCT__ "MatDiagonalScaleLocal"
7469 /*@
7470    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
7471          ghosted ones.
7472 
7473    Not Collective
7474 
7475    Input Parameters:
7476 +  mat - the matrix
7477 -  diag = the diagonal values, including ghost ones
7478 
7479    Level: developer
7480 
7481    Notes: Works only for MPIAIJ and MPIBAIJ matrices
7482 
7483 .seealso: MatDiagonalScale()
7484 @*/
7485 PetscErrorCode  MatDiagonalScaleLocal(Mat mat,Vec diag)
7486 {
7487   PetscErrorCode ierr;
7488   PetscMPIInt    size;
7489 
7490   PetscFunctionBegin;
7491   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7492   PetscValidHeaderSpecific(diag,VEC_CLASSID,2);
7493   PetscValidType(mat,1);
7494 
7495   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7496   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
7497   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
7498   if (size == 1) {
7499     PetscInt n,m;
7500     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
7501     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
7502     if (m == n) {
7503       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
7504     } else {
7505       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
7506     }
7507   } else {
7508     ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr);
7509   }
7510   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
7511   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
7512   PetscFunctionReturn(0);
7513 }
7514 
7515 #undef __FUNCT__
7516 #define __FUNCT__ "MatGetInertia"
7517 /*@
7518    MatGetInertia - Gets the inertia from a factored matrix
7519 
7520    Collective on Mat
7521 
7522    Input Parameter:
7523 .  mat - the matrix
7524 
7525    Output Parameters:
7526 +   nneg - number of negative eigenvalues
7527 .   nzero - number of zero eigenvalues
7528 -   npos - number of positive eigenvalues
7529 
7530    Level: advanced
7531 
7532    Notes: Matrix must have been factored by MatCholeskyFactor()
7533 
7534 
7535 @*/
7536 PetscErrorCode  MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
7537 {
7538   PetscErrorCode ierr;
7539 
7540   PetscFunctionBegin;
7541   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7542   PetscValidType(mat,1);
7543   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7544   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
7545   if (!mat->ops->getinertia) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7546   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
7547   PetscFunctionReturn(0);
7548 }
7549 
7550 /* ----------------------------------------------------------------*/
7551 #undef __FUNCT__
7552 #define __FUNCT__ "MatSolves"
7553 /*@C
7554    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
7555 
7556    Neighbor-wise Collective on Mat and Vecs
7557 
7558    Input Parameters:
7559 +  mat - the factored matrix
7560 -  b - the right-hand-side vectors
7561 
7562    Output Parameter:
7563 .  x - the result vectors
7564 
7565    Notes:
7566    The vectors b and x cannot be the same.  I.e., one cannot
7567    call MatSolves(A,x,x).
7568 
7569    Notes:
7570    Most users should employ the simplified KSP interface for linear solvers
7571    instead of working directly with matrix algebra routines such as this.
7572    See, e.g., KSPCreate().
7573 
7574    Level: developer
7575 
7576    Concepts: matrices^triangular solves
7577 
7578 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
7579 @*/
7580 PetscErrorCode  MatSolves(Mat mat,Vecs b,Vecs x)
7581 {
7582   PetscErrorCode ierr;
7583 
7584   PetscFunctionBegin;
7585   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7586   PetscValidType(mat,1);
7587   if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
7588   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7589   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
7590 
7591   if (!mat->ops->solves) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7592   ierr = MatPreallocated(mat);CHKERRQ(ierr);
7593   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
7594   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
7595   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
7596   PetscFunctionReturn(0);
7597 }
7598 
7599 #undef __FUNCT__
7600 #define __FUNCT__ "MatIsSymmetric"
7601 /*@
7602    MatIsSymmetric - Test whether a matrix is symmetric
7603 
7604    Collective on Mat
7605 
7606    Input Parameter:
7607 +  A - the matrix to test
7608 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
7609 
7610    Output Parameters:
7611 .  flg - the result
7612 
7613    Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
7614 
7615    Level: intermediate
7616 
7617    Concepts: matrix^symmetry
7618 
7619 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
7620 @*/
7621 PetscErrorCode  MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
7622 {
7623   PetscErrorCode ierr;
7624 
7625   PetscFunctionBegin;
7626   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7627   PetscValidPointer(flg,2);
7628 
7629   if (!A->symmetric_set) {
7630     if (!A->ops->issymmetric) {
7631       const MatType mattype;
7632       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7633       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7634     }
7635     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
7636     if (!tol) {
7637       A->symmetric_set = PETSC_TRUE;
7638       A->symmetric = *flg;
7639       if (A->symmetric) {
7640 	A->structurally_symmetric_set = PETSC_TRUE;
7641 	A->structurally_symmetric     = PETSC_TRUE;
7642       }
7643     }
7644   } else if (A->symmetric) {
7645     *flg = PETSC_TRUE;
7646   } else if (!tol) {
7647     *flg = PETSC_FALSE;
7648   } else {
7649     if (!A->ops->issymmetric) {
7650       const MatType mattype;
7651       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7652       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7653     }
7654     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
7655   }
7656   PetscFunctionReturn(0);
7657 }
7658 
7659 #undef __FUNCT__
7660 #define __FUNCT__ "MatIsHermitian"
7661 /*@
7662    MatIsHermitian - Test whether a matrix is Hermitian
7663 
7664    Collective on Mat
7665 
7666    Input Parameter:
7667 +  A - the matrix to test
7668 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
7669 
7670    Output Parameters:
7671 .  flg - the result
7672 
7673    Level: intermediate
7674 
7675    Concepts: matrix^symmetry
7676 
7677 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
7678           MatIsSymmetricKnown(), MatIsSymmetric()
7679 @*/
7680 PetscErrorCode  MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
7681 {
7682   PetscErrorCode ierr;
7683 
7684   PetscFunctionBegin;
7685   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7686   PetscValidPointer(flg,2);
7687 
7688   if (!A->hermitian_set) {
7689     if (!A->ops->ishermitian) {
7690       const MatType mattype;
7691       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7692       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7693     }
7694     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
7695     if (!tol) {
7696       A->hermitian_set = PETSC_TRUE;
7697       A->hermitian = *flg;
7698       if (A->hermitian) {
7699 	A->structurally_symmetric_set = PETSC_TRUE;
7700 	A->structurally_symmetric     = PETSC_TRUE;
7701       }
7702     }
7703   } else if (A->hermitian) {
7704     *flg = PETSC_TRUE;
7705   } else if (!tol) {
7706     *flg = PETSC_FALSE;
7707   } else {
7708     if (!A->ops->ishermitian) {
7709       const MatType mattype;
7710       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7711       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7712     }
7713     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
7714   }
7715   PetscFunctionReturn(0);
7716 }
7717 
7718 #undef __FUNCT__
7719 #define __FUNCT__ "MatIsSymmetricKnown"
7720 /*@
7721    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
7722 
7723    Not Collective
7724 
7725    Input Parameter:
7726 .  A - the matrix to check
7727 
7728    Output Parameters:
7729 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
7730 -  flg - the result
7731 
7732    Level: advanced
7733 
7734    Concepts: matrix^symmetry
7735 
7736    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
7737          if you want it explicitly checked
7738 
7739 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
7740 @*/
7741 PetscErrorCode  MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
7742 {
7743   PetscFunctionBegin;
7744   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7745   PetscValidPointer(set,2);
7746   PetscValidPointer(flg,3);
7747   if (A->symmetric_set) {
7748     *set = PETSC_TRUE;
7749     *flg = A->symmetric;
7750   } else {
7751     *set = PETSC_FALSE;
7752   }
7753   PetscFunctionReturn(0);
7754 }
7755 
7756 #undef __FUNCT__
7757 #define __FUNCT__ "MatIsHermitianKnown"
7758 /*@
7759    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
7760 
7761    Not Collective
7762 
7763    Input Parameter:
7764 .  A - the matrix to check
7765 
7766    Output Parameters:
7767 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
7768 -  flg - the result
7769 
7770    Level: advanced
7771 
7772    Concepts: matrix^symmetry
7773 
7774    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
7775          if you want it explicitly checked
7776 
7777 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
7778 @*/
7779 PetscErrorCode  MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
7780 {
7781   PetscFunctionBegin;
7782   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7783   PetscValidPointer(set,2);
7784   PetscValidPointer(flg,3);
7785   if (A->hermitian_set) {
7786     *set = PETSC_TRUE;
7787     *flg = A->hermitian;
7788   } else {
7789     *set = PETSC_FALSE;
7790   }
7791   PetscFunctionReturn(0);
7792 }
7793 
7794 #undef __FUNCT__
7795 #define __FUNCT__ "MatIsStructurallySymmetric"
7796 /*@
7797    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
7798 
7799    Collective on Mat
7800 
7801    Input Parameter:
7802 .  A - the matrix to test
7803 
7804    Output Parameters:
7805 .  flg - the result
7806 
7807    Level: intermediate
7808 
7809    Concepts: matrix^symmetry
7810 
7811 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
7812 @*/
7813 PetscErrorCode  MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
7814 {
7815   PetscErrorCode ierr;
7816 
7817   PetscFunctionBegin;
7818   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7819   PetscValidPointer(flg,2);
7820   if (!A->structurally_symmetric_set) {
7821     if (!A->ops->isstructurallysymmetric) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
7822     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
7823     A->structurally_symmetric_set = PETSC_TRUE;
7824   }
7825   *flg = A->structurally_symmetric;
7826   PetscFunctionReturn(0);
7827 }
7828 
7829 #undef __FUNCT__
7830 #define __FUNCT__ "MatStashGetInfo"
7831 extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
7832 /*@
7833    MatStashGetInfo - Gets how many values are currently in the vector stash, i.e. need
7834        to be communicated to other processors during the MatAssemblyBegin/End() process
7835 
7836     Not collective
7837 
7838    Input Parameter:
7839 .   vec - the vector
7840 
7841    Output Parameters:
7842 +   nstash   - the size of the stash
7843 .   reallocs - the number of additional mallocs incurred.
7844 .   bnstash   - the size of the block stash
7845 -   breallocs - the number of additional mallocs incurred.in the block stash
7846 
7847    Level: advanced
7848 
7849 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
7850 
7851 @*/
7852 PetscErrorCode  MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
7853 {
7854   PetscErrorCode ierr;
7855   PetscFunctionBegin;
7856   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
7857   ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
7858   PetscFunctionReturn(0);
7859 }
7860 
7861 #undef __FUNCT__
7862 #define __FUNCT__ "MatGetVecs"
7863 /*@C
7864    MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same
7865      parallel layout
7866 
7867    Collective on Mat
7868 
7869    Input Parameter:
7870 .  mat - the matrix
7871 
7872    Output Parameter:
7873 +   right - (optional) vector that the matrix can be multiplied against
7874 -   left - (optional) vector that the matrix vector product can be stored in
7875 
7876   Level: advanced
7877 
7878 .seealso: MatCreate()
7879 @*/
7880 PetscErrorCode  MatGetVecs(Mat mat,Vec *right,Vec *left)
7881 {
7882   PetscErrorCode ierr;
7883 
7884   PetscFunctionBegin;
7885   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7886   PetscValidType(mat,1);
7887   ierr = MatPreallocated(mat);CHKERRQ(ierr);
7888   if (mat->ops->getvecs) {
7889     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
7890   } else {
7891     PetscMPIInt size;
7892     ierr = MPI_Comm_size(((PetscObject)mat)->comm, &size);CHKERRQ(ierr);
7893     if (right) {
7894       ierr = VecCreate(((PetscObject)mat)->comm,right);CHKERRQ(ierr);
7895       ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
7896       ierr = VecSetBlockSize(*right,mat->rmap->bs);CHKERRQ(ierr);
7897       ierr = VecSetType(*right,VECSTANDARD);CHKERRQ(ierr);
7898       ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr);
7899     }
7900     if (left) {
7901       ierr = VecCreate(((PetscObject)mat)->comm,left);CHKERRQ(ierr);
7902       ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
7903       ierr = VecSetBlockSize(*left,mat->rmap->bs);CHKERRQ(ierr);
7904       ierr = VecSetType(*left,VECSTANDARD);CHKERRQ(ierr);
7905       ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr);
7906     }
7907   }
7908   PetscFunctionReturn(0);
7909 }
7910 
7911 #undef __FUNCT__
7912 #define __FUNCT__ "MatFactorInfoInitialize"
7913 /*@C
7914    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
7915      with default values.
7916 
7917    Not Collective
7918 
7919    Input Parameters:
7920 .    info - the MatFactorInfo data structure
7921 
7922 
7923    Notes: The solvers are generally used through the KSP and PC objects, for example
7924           PCLU, PCILU, PCCHOLESKY, PCICC
7925 
7926    Level: developer
7927 
7928 .seealso: MatFactorInfo
7929 
7930     Developer Note: fortran interface is not autogenerated as the f90
7931     interface defintion cannot be generated correctly [due to MatFactorInfo]
7932 
7933 @*/
7934 
7935 PetscErrorCode  MatFactorInfoInitialize(MatFactorInfo *info)
7936 {
7937   PetscErrorCode ierr;
7938 
7939   PetscFunctionBegin;
7940   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
7941   PetscFunctionReturn(0);
7942 }
7943 
7944 #undef __FUNCT__
7945 #define __FUNCT__ "MatPtAP"
7946 /*@
7947    MatPtAP - Creates the matrix product C = P^T * A * P
7948 
7949    Neighbor-wise Collective on Mat
7950 
7951    Input Parameters:
7952 +  A - the matrix
7953 .  P - the projection matrix
7954 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7955 -  fill - expected fill as ratio of nnz(C)/nnz(A)
7956 
7957    Output Parameters:
7958 .  C - the product matrix
7959 
7960    Notes:
7961    C will be created and must be destroyed by the user with MatDestroy().
7962 
7963    This routine is currently only implemented for pairs of AIJ matrices and classes
7964    which inherit from AIJ.
7965 
7966    Level: intermediate
7967 
7968 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult()
7969 @*/
7970 PetscErrorCode  MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
7971 {
7972   PetscErrorCode ierr;
7973 
7974   PetscFunctionBegin;
7975   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7976   PetscValidType(A,1);
7977   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7978   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7979   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
7980   PetscValidType(P,2);
7981   ierr = MatPreallocated(P);CHKERRQ(ierr);
7982   if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7983   if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7984   PetscValidPointer(C,3);
7985   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);
7986   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
7987   ierr = MatPreallocated(A);CHKERRQ(ierr);
7988 
7989   if (!A->ops->ptap) {
7990     const MatType mattype;
7991     ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7992     SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix of type <%s> does not support PtAP",mattype);
7993   }
7994   ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
7995   ierr = (*A->ops->ptap)(A,P,scall,fill,C);CHKERRQ(ierr);
7996   ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
7997 
7998   PetscFunctionReturn(0);
7999 }
8000 
8001 #undef __FUNCT__
8002 #define __FUNCT__ "MatPtAPNumeric"
8003 /*@
8004    MatPtAPNumeric - Computes the matrix product C = P^T * A * P
8005 
8006    Neighbor-wise Collective on Mat
8007 
8008    Input Parameters:
8009 +  A - the matrix
8010 -  P - the projection matrix
8011 
8012    Output Parameters:
8013 .  C - the product matrix
8014 
8015    Notes:
8016    C must have been created by calling MatPtAPSymbolic and must be destroyed by
8017    the user using MatDeatroy().
8018 
8019    This routine is currently only implemented for pairs of AIJ matrices and classes
8020    which inherit from AIJ.  C will be of type MATAIJ.
8021 
8022    Level: intermediate
8023 
8024 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
8025 @*/
8026 PetscErrorCode  MatPtAPNumeric(Mat A,Mat P,Mat C)
8027 {
8028   PetscErrorCode ierr;
8029 
8030   PetscFunctionBegin;
8031   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8032   PetscValidType(A,1);
8033   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8034   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8035   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
8036   PetscValidType(P,2);
8037   ierr = MatPreallocated(P);CHKERRQ(ierr);
8038   if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8039   if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8040   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
8041   PetscValidType(C,3);
8042   ierr = MatPreallocated(C);CHKERRQ(ierr);
8043   if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8044   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);
8045   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);
8046   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);
8047   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);
8048   ierr = MatPreallocated(A);CHKERRQ(ierr);
8049 
8050   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
8051   ierr = (*A->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr);
8052   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
8053   PetscFunctionReturn(0);
8054 }
8055 
8056 #undef __FUNCT__
8057 #define __FUNCT__ "MatPtAPSymbolic"
8058 /*@
8059    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P
8060 
8061    Neighbor-wise Collective on Mat
8062 
8063    Input Parameters:
8064 +  A - the matrix
8065 -  P - the projection matrix
8066 
8067    Output Parameters:
8068 .  C - the (i,j) structure of the product matrix
8069 
8070    Notes:
8071    C will be created and must be destroyed by the user with MatDestroy().
8072 
8073    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
8074    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
8075    this (i,j) structure by calling MatPtAPNumeric().
8076 
8077    Level: intermediate
8078 
8079 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
8080 @*/
8081 PetscErrorCode  MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
8082 {
8083   PetscErrorCode ierr;
8084 
8085   PetscFunctionBegin;
8086   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8087   PetscValidType(A,1);
8088   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8089   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8090   if (fill <1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8091   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
8092   PetscValidType(P,2);
8093   ierr = MatPreallocated(P);CHKERRQ(ierr);
8094   if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8095   if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8096   PetscValidPointer(C,3);
8097 
8098   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);
8099   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);
8100   ierr = MatPreallocated(A);CHKERRQ(ierr);
8101   ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
8102   ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr);
8103   ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
8104 
8105   ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr);
8106 
8107   PetscFunctionReturn(0);
8108 }
8109 
8110 #undef __FUNCT__
8111 #define __FUNCT__ "MatMatMult"
8112 /*@
8113    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
8114 
8115    Neighbor-wise Collective on Mat
8116 
8117    Input Parameters:
8118 +  A - the left matrix
8119 .  B - the right matrix
8120 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8121 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
8122           if the result is a dense matrix this is irrelevent
8123 
8124    Output Parameters:
8125 .  C - the product matrix
8126 
8127    Notes:
8128    Unless scall is MAT_REUSE_MATRIX C will be created.
8129 
8130    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8131 
8132    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8133    actually needed.
8134 
8135    If you have many matrices with the same non-zero structure to multiply, you
8136    should either
8137 $   1) use MAT_REUSE_MATRIX in all calls but the first or
8138 $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
8139 
8140    Level: intermediate
8141 
8142 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatPtAP()
8143 @*/
8144 PetscErrorCode  MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8145 {
8146   PetscErrorCode ierr;
8147   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8148   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8149   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat *)=PETSC_NULL;
8150 
8151   PetscFunctionBegin;
8152   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8153   PetscValidType(A,1);
8154   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8155   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8156   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8157   PetscValidType(B,2);
8158   ierr = MatPreallocated(B);CHKERRQ(ierr);
8159   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8160   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8161   PetscValidPointer(C,3);
8162   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);
8163   if (scall == MAT_REUSE_MATRIX){
8164     PetscValidPointer(*C,5);
8165     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
8166   }
8167   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8168   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8169   ierr = MatPreallocated(A);CHKERRQ(ierr);
8170 
8171   fA = A->ops->matmult;
8172   fB = B->ops->matmult;
8173   if (fB == fA) {
8174     if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
8175     mult = fB;
8176   } else {
8177     /* dispatch based on the type of A and B */
8178     char  multname[256];
8179     ierr = PetscStrcpy(multname,"MatMatMult_");CHKERRQ(ierr);
8180     ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr);
8181     ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);
8182     ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr);
8183     ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
8184     ierr = PetscObjectQueryFunction((PetscObject)B,multname,(void (**)(void))&mult);CHKERRQ(ierr);
8185     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);
8186   }
8187   ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
8188   ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr);
8189   ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
8190   PetscFunctionReturn(0);
8191 }
8192 
8193 #undef __FUNCT__
8194 #define __FUNCT__ "MatMatMultSymbolic"
8195 /*@
8196    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
8197    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().
8198 
8199    Neighbor-wise Collective on Mat
8200 
8201    Input Parameters:
8202 +  A - the left matrix
8203 .  B - the right matrix
8204 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
8205       if C is a dense matrix this is irrelevent
8206 
8207    Output Parameters:
8208 .  C - the product matrix
8209 
8210    Notes:
8211    Unless scall is MAT_REUSE_MATRIX C will be created.
8212 
8213    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8214    actually needed.
8215 
8216    This routine is currently implemented for
8217     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
8218     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8219     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
8220 
8221    Level: intermediate
8222 
8223    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
8224      We should incorporate them into PETSc.
8225 
8226 .seealso: MatMatMult(), MatMatMultNumeric()
8227 @*/
8228 PetscErrorCode  MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
8229 {
8230   PetscErrorCode ierr;
8231   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat *);
8232   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat *);
8233   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat *)=PETSC_NULL;
8234 
8235   PetscFunctionBegin;
8236   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8237   PetscValidType(A,1);
8238   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8239   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8240 
8241   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8242   PetscValidType(B,2);
8243   ierr = MatPreallocated(B);CHKERRQ(ierr);
8244   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8245   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8246   PetscValidPointer(C,3);
8247 
8248   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);
8249   if (fill == PETSC_DEFAULT) fill = 2.0;
8250   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8251   ierr = MatPreallocated(A);CHKERRQ(ierr);
8252 
8253   Asymbolic = A->ops->matmultsymbolic;
8254   Bsymbolic = B->ops->matmultsymbolic;
8255   if (Asymbolic == Bsymbolic){
8256     if (!Bsymbolic) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
8257     symbolic = Bsymbolic;
8258   } else { /* dispatch based on the type of A and B */
8259     char  symbolicname[256];
8260     ierr = PetscStrcpy(symbolicname,"MatMatMultSymbolic_");CHKERRQ(ierr);
8261     ierr = PetscStrcat(symbolicname,((PetscObject)A)->type_name);CHKERRQ(ierr);
8262     ierr = PetscStrcat(symbolicname,"_");CHKERRQ(ierr);
8263     ierr = PetscStrcat(symbolicname,((PetscObject)B)->type_name);CHKERRQ(ierr);
8264     ierr = PetscStrcat(symbolicname,"_C");CHKERRQ(ierr);
8265     ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,(void (**)(void))&symbolic);CHKERRQ(ierr);
8266     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);
8267   }
8268   ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
8269   ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr);
8270   ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
8271   PetscFunctionReturn(0);
8272 }
8273 
8274 #undef __FUNCT__
8275 #define __FUNCT__ "MatMatMultNumeric"
8276 /*@
8277    MatMatMultNumeric - Performs the numeric matrix-matrix product.
8278    Call this routine after first calling MatMatMultSymbolic().
8279 
8280    Neighbor-wise Collective on Mat
8281 
8282    Input Parameters:
8283 +  A - the left matrix
8284 -  B - the right matrix
8285 
8286    Output Parameters:
8287 .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
8288 
8289    Notes:
8290    C must have been created with MatMatMultSymbolic().
8291 
8292    This routine is currently implemented for
8293     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
8294     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8295     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
8296 
8297    Level: intermediate
8298 
8299 .seealso: MatMatMult(), MatMatMultSymbolic()
8300 @*/
8301 PetscErrorCode  MatMatMultNumeric(Mat A,Mat B,Mat C)
8302 {
8303   PetscErrorCode ierr;
8304   PetscErrorCode (*Anumeric)(Mat,Mat,Mat);
8305   PetscErrorCode (*Bnumeric)(Mat,Mat,Mat);
8306   PetscErrorCode (*numeric)(Mat,Mat,Mat)=PETSC_NULL;
8307 
8308   PetscFunctionBegin;
8309   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8310   PetscValidType(A,1);
8311   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8312   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8313 
8314   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8315   PetscValidType(B,2);
8316   ierr = MatPreallocated(B);CHKERRQ(ierr);
8317   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8318   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8319 
8320   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
8321   PetscValidType(C,3);
8322   ierr = MatPreallocated(C);CHKERRQ(ierr);
8323   if (!C->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8324   if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8325 
8326   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);
8327   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);
8328   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);
8329   ierr = MatPreallocated(A);CHKERRQ(ierr);
8330 
8331   Anumeric = A->ops->matmultnumeric;
8332   Bnumeric = B->ops->matmultnumeric;
8333   if (Anumeric == Bnumeric){
8334     if (!Bnumeric) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMultNumeric not supported for B of type %s",((PetscObject)B)->type_name);
8335     numeric = Bnumeric;
8336   } else {
8337     char  numericname[256];
8338     ierr = PetscStrcpy(numericname,"MatMatMultNumeric_");CHKERRQ(ierr);
8339     ierr = PetscStrcat(numericname,((PetscObject)A)->type_name);CHKERRQ(ierr);
8340     ierr = PetscStrcat(numericname,"_");CHKERRQ(ierr);
8341     ierr = PetscStrcat(numericname,((PetscObject)B)->type_name);CHKERRQ(ierr);
8342     ierr = PetscStrcat(numericname,"_C");CHKERRQ(ierr);
8343     ierr = PetscObjectQueryFunction((PetscObject)B,numericname,(void (**)(void))&numeric);CHKERRQ(ierr);
8344     if (!numeric)
8345       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);
8346   }
8347   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
8348   ierr = (*numeric)(A,B,C);CHKERRQ(ierr);
8349   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
8350   PetscFunctionReturn(0);
8351 }
8352 
8353 #undef __FUNCT__
8354 #define __FUNCT__ "MatMatMultTranspose"
8355 /*@
8356    MatMatMultTranspose - Performs Matrix-Matrix Multiplication C=A^T*B.
8357 
8358    Neighbor-wise Collective on Mat
8359 
8360    Input Parameters:
8361 +  A - the left matrix
8362 .  B - the right matrix
8363 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8364 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
8365 
8366    Output Parameters:
8367 .  C - the product matrix
8368 
8369    Notes:
8370    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
8371 
8372    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8373 
8374   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8375    actually needed.
8376 
8377    This routine is currently only implemented for pairs of SeqAIJ matrices and pairs of SeqDense matrices and classes
8378    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.
8379 
8380    Level: intermediate
8381 
8382 .seealso: MatMatMultTransposeSymbolic(), MatMatMultTransposeNumeric(), MatPtAP()
8383 @*/
8384 PetscErrorCode  MatMatMultTranspose(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8385 {
8386   PetscErrorCode ierr;
8387   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8388   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8389 
8390   PetscFunctionBegin;
8391   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8392   PetscValidType(A,1);
8393   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8394   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8395   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8396   PetscValidType(B,2);
8397   ierr = MatPreallocated(B);CHKERRQ(ierr);
8398   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8399   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8400   PetscValidPointer(C,3);
8401   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);
8402   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8403   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8404   ierr = MatPreallocated(A);CHKERRQ(ierr);
8405 
8406   fA = A->ops->matmulttranspose;
8407   if (!fA) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMultTranspose not supported for A of type %s",((PetscObject)A)->type_name);
8408   fB = B->ops->matmulttranspose;
8409   if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMultTranspose not supported for B of type %s",((PetscObject)B)->type_name);
8410   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);
8411 
8412   ierr = PetscLogEventBegin(MAT_MatMultTranspose,A,B,0,0);CHKERRQ(ierr);
8413   ierr = (*A->ops->matmulttranspose)(A,B,scall,fill,C);CHKERRQ(ierr);
8414   ierr = PetscLogEventEnd(MAT_MatMultTranspose,A,B,0,0);CHKERRQ(ierr);
8415 
8416   PetscFunctionReturn(0);
8417 }
8418 
8419 #undef __FUNCT__
8420 #define __FUNCT__ "MatGetRedundantMatrix"
8421 /*@C
8422    MatGetRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
8423 
8424    Collective on Mat
8425 
8426    Input Parameters:
8427 +  mat - the matrix
8428 .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
8429 .  subcomm - MPI communicator split from the communicator where mat resides in
8430 .  mlocal_red - number of local rows of the redundant matrix
8431 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8432 
8433    Output Parameter:
8434 .  matredundant - redundant matrix
8435 
8436    Notes:
8437    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
8438    original matrix has not changed from that last call to MatGetRedundantMatrix().
8439 
8440    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
8441    calling it.
8442 
8443    Only MPIAIJ matrix is supported.
8444 
8445    Level: advanced
8446 
8447    Concepts: subcommunicator
8448    Concepts: duplicate matrix
8449 
8450 .seealso: MatDestroy()
8451 @*/
8452 PetscErrorCode  MatGetRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,PetscInt mlocal_red,MatReuse reuse,Mat *matredundant)
8453 {
8454   PetscErrorCode ierr;
8455 
8456   PetscFunctionBegin;
8457   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8458   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
8459     PetscValidPointer(*matredundant,6);
8460     PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,6);
8461   }
8462   if (!mat->ops->getredundantmatrix) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8463   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8464   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8465   ierr = MatPreallocated(mat);CHKERRQ(ierr);
8466 
8467   ierr = PetscLogEventBegin(MAT_GetRedundantMatrix,mat,0,0,0);CHKERRQ(ierr);
8468   ierr = (*mat->ops->getredundantmatrix)(mat,nsubcomm,subcomm,mlocal_red,reuse,matredundant);CHKERRQ(ierr);
8469   ierr = PetscLogEventEnd(MAT_GetRedundantMatrix,mat,0,0,0);CHKERRQ(ierr);
8470   PetscFunctionReturn(0);
8471 }
8472 
8473 #undef __FUNCT__
8474 #define __FUNCT__ "MatGetMultiProcBlock"
8475 /*@C
8476    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
8477    a given 'mat' object. Each submatrix can span multiple procs.
8478 
8479    Collective on Mat
8480 
8481    Input Parameters:
8482 +  mat - the matrix
8483 -  subcomm - the subcommunicator obtained by com_split(comm)
8484 
8485    Output Parameter:
8486 .  subMat - 'parallel submatrices each spans a given subcomm
8487 
8488   Notes:
8489   The submatrix partition across processors is dicated by 'subComm' a
8490   communicator obtained by com_split(comm). The comm_split
8491   is not restriced to be grouped with consequitive original ranks.
8492 
8493   Due the comm_split() usage, the parallel layout of the submatrices
8494   map directly to the layout of the original matrix [wrt the local
8495   row,col partitioning]. So the original 'DiagonalMat' naturally maps
8496   into the 'DiagonalMat' of the subMat, hence it is used directly from
8497   the subMat. However the offDiagMat looses some columns - and this is
8498   reconstructed with MatSetValues()
8499 
8500   Level: advanced
8501 
8502   Concepts: subcommunicator
8503   Concepts: submatrices
8504 
8505 .seealso: MatGetSubMatrices()
8506 @*/
8507 PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, Mat* subMat)
8508 {
8509   PetscErrorCode ierr;
8510   PetscMPIInt    commsize,subCommSize;
8511 
8512   PetscFunctionBegin;
8513   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&commsize);CHKERRQ(ierr);
8514   ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr);
8515   if (subCommSize > commsize) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
8516 
8517   ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
8518   ierr = (*mat->ops->getmultiprocblock)(mat,subComm,subMat);CHKERRQ(ierr);
8519   ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
8520   PetscFunctionReturn(0);
8521 }
8522 
8523 #undef __FUNCT__
8524 #define __FUNCT__ "MatGetLocalSubMatrix"
8525 /*@
8526    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
8527 
8528    Not Collective
8529 
8530    Input Arguments:
8531    mat - matrix to extract local submatrix from
8532    isrow - local row indices for submatrix
8533    iscol - local column indices for submatrix
8534 
8535    Output Arguments:
8536    submat - the submatrix
8537 
8538    Level: intermediate
8539 
8540    Notes:
8541    The submat should be returned with MatRestoreLocalSubMatrix().
8542 
8543    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
8544    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
8545 
8546    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
8547    MatSetValuesBlockedLocal() will also be implemented.
8548 
8549 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef()
8550 @*/
8551 PetscErrorCode  MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
8552 {
8553   PetscErrorCode ierr;
8554 
8555   PetscFunctionBegin;
8556   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8557   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
8558   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
8559   PetscCheckSameComm(isrow,2,iscol,3);
8560   PetscValidPointer(submat,4);
8561 
8562   if (mat->ops->getlocalsubmatrix) {
8563     ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
8564   } else {
8565     ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr);
8566   }
8567   PetscFunctionReturn(0);
8568 }
8569 
8570 #undef __FUNCT__
8571 #define __FUNCT__ "MatRestoreLocalSubMatrix"
8572 /*@
8573    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
8574 
8575    Not Collective
8576 
8577    Input Arguments:
8578    mat - matrix to extract local submatrix from
8579    isrow - local row indices for submatrix
8580    iscol - local column indices for submatrix
8581    submat - the submatrix
8582 
8583    Level: intermediate
8584 
8585 .seealso: MatGetLocalSubMatrix()
8586 @*/
8587 PetscErrorCode  MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
8588 {
8589   PetscErrorCode ierr;
8590 
8591   PetscFunctionBegin;
8592   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8593   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
8594   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
8595   PetscCheckSameComm(isrow,2,iscol,3);
8596   PetscValidPointer(submat,4);
8597   if (*submat) {PetscValidHeaderSpecific(*submat,MAT_CLASSID,4);}
8598 
8599   if (mat->ops->restorelocalsubmatrix) {
8600     ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
8601   } else {
8602     ierr = MatDestroy(submat);CHKERRQ(ierr);
8603   }
8604   *submat = PETSC_NULL;
8605   PetscFunctionReturn(0);
8606 }
8607 
8608 /* --------------------------------------------------------*/
8609 #undef __FUNCT__
8610 #define __FUNCT__ "MatFindZeroDiagonals"
8611 /*@
8612    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no entry in the matrix
8613 
8614    Collective on Mat
8615 
8616    Input Parameter:
8617 .  mat - the matrix
8618 
8619    Output Parameter:
8620 .  is - if any rows have zero diagonals this contains the list of them
8621 
8622    Level: developer
8623 
8624    Concepts: matrix-vector product
8625 
8626 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
8627 @*/
8628 PetscErrorCode  MatFindZeroDiagonals(Mat mat,IS *is)
8629 {
8630   PetscErrorCode ierr;
8631 
8632   PetscFunctionBegin;
8633   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8634   PetscValidType(mat,1);
8635   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8636   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8637 
8638   if (!mat->ops->findzerodiagonals) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"This matrix type does not have a find zero diagonals defined");
8639   ierr = (*mat->ops->findzerodiagonals)(mat,is);CHKERRQ(ierr);
8640   PetscFunctionReturn(0);
8641 }
8642