xref: /petsc/src/mat/interface/matrix.c (revision 5d4cbb4e3d04d144604f832291a7ad3563495787)
1 
2 /*
3    This is where the abstract matrix operations are defined
4 */
5 
6 #include <private/matimpl.h>        /*I "petscmat.h" I*/
7 #include <private/vecimpl.h>
8 
9 /* Logging support */
10 PetscClassId  MAT_CLASSID;
11 PetscClassId  MAT_FDCOLORING_CLASSID;
12 
13 PetscLogEvent  MAT_Mult, MAT_Mults, MAT_MultConstrained, MAT_MultAdd, MAT_MultTranspose;
14 PetscLogEvent  MAT_MultTransposeConstrained, MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve;
15 PetscLogEvent  MAT_SolveTransposeAdd, MAT_SOR, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic;
16 PetscLogEvent  MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor;
17 PetscLogEvent  MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin;
18 PetscLogEvent  MAT_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetRowIJ, MAT_GetSubMatrices, MAT_GetColoring, MAT_GetOrdering, MAT_GetRedundantMatrix, MAT_GetSeqNonzeroStructure;
19 PetscLogEvent  MAT_IncreaseOverlap, MAT_Partitioning, MAT_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate;
20 PetscLogEvent  MAT_FDColoringApply,MAT_Transpose,MAT_FDColoringFunction;
21 PetscLogEvent  MAT_MatMult, MAT_MatMultSymbolic, MAT_MatMultNumeric;
22 PetscLogEvent  MAT_PtAP, MAT_PtAPSymbolic, MAT_PtAPNumeric;
23 PetscLogEvent  MAT_MatMultTranspose, MAT_MatMultTransposeSymbolic, MAT_MatMultTransposeNumeric;
24 PetscLogEvent  MAT_MultHermitianTranspose,MAT_MultHermitianTransposeAdd;
25 PetscLogEvent  MAT_Getsymtranspose, MAT_Getsymtransreduced, MAT_Transpose_SeqAIJ, MAT_GetBrowsOfAcols;
26 PetscLogEvent  MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym;
27 PetscLogEvent  MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure;
28 PetscLogEvent  MAT_GetMultiProcBlock;
29 PetscLogEvent  MAT_CUSPCopyToGPU;
30 
31 /* nasty global values for MatSetValue() */
32 PetscInt     MatSetValue_Row = 0;
33 PetscInt     MatSetValue_Column = 0;
34 PetscScalar  MatSetValue_Value = 0.0;
35 
36 const char *const MatFactorTypes[] = {"NONE","LU","CHOLESKY","ILU","ICC","ILUDT","MatFactorType","MAT_FACTOR_",0};
37 
38 #undef __FUNCT__
39 #define __FUNCT__ "MatFindNonzeroRows"
40 /*@C
41       MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix
42 
43   Input Parameter:
44 .    A  - the matrix
45 
46   Output Parameter:
47 .    keptrows - the rows that are not completely zero
48 
49  @*/
50 PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows)
51 {
52   PetscErrorCode    ierr;
53 
54   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
55   PetscValidType(mat,1);
56   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
57   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
58   if (!mat->ops->findnonzerorows) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Not coded for this matrix type");
59   ierr = (*mat->ops->findnonzerorows)(mat,keptrows);CHKERRQ(ierr);
60   PetscFunctionReturn(0);
61 }
62 
63 #undef __FUNCT__
64 #define __FUNCT__ "MatGetDiagonalBlock"
65 /*@
66    MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling
67 
68    Not Collective
69 
70    Input Parameters:
71 .  mat - the matrix
72 
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    Concepts: matrices^zeroing
5112 
5113 .seealso: MatZeroRows()
5114 @*/
5115 PetscErrorCode  MatZeroEntries(Mat mat)
5116 {
5117   PetscErrorCode ierr;
5118 
5119   PetscFunctionBegin;
5120   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5121   PetscValidType(mat,1);
5122   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5123   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");
5124   if (!mat->ops->zeroentries) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5125   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5126 
5127   ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5128   ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
5129   ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5130   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5131 #if defined(PETSC_HAVE_CUSP)
5132   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5133     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5134   }
5135 #endif
5136   PetscFunctionReturn(0);
5137 }
5138 
5139 #undef __FUNCT__
5140 #define __FUNCT__ "MatZeroRowsColumns"
5141 /*@C
5142    MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal)
5143    of a set of rows and columns of a matrix.
5144 
5145    Collective on Mat
5146 
5147    Input Parameters:
5148 +  mat - the matrix
5149 .  numRows - the number of rows to remove
5150 .  rows - the global row indices
5151 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5152 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5153 -  b - optional vector of right hand side, that will be adjusted by provided solution
5154 
5155    Notes:
5156    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5157 
5158    The user can set a value in the diagonal entry (or for the AIJ and
5159    row formats can optionally remove the main diagonal entry from the
5160    nonzero structure as well, by passing 0.0 as the final argument).
5161 
5162    For the parallel case, all processes that share the matrix (i.e.,
5163    those in the communicator used for matrix creation) MUST call this
5164    routine, regardless of whether any rows being zeroed are owned by
5165    them.
5166 
5167    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5168    list only rows local to itself).
5169 
5170    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5171 
5172    Level: intermediate
5173 
5174    Concepts: matrices^zeroing rows
5175 
5176 .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumnsIS()
5177 @*/
5178 PetscErrorCode  MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5179 {
5180   PetscErrorCode ierr;
5181 
5182   PetscFunctionBegin;
5183   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5184   PetscValidType(mat,1);
5185   if (numRows) PetscValidIntPointer(rows,3);
5186   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5187   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5188   if (!mat->ops->zerorowscolumns) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5189   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5190 
5191   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5192   ierr = MatView_Private(mat);CHKERRQ(ierr);
5193   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5194 #if defined(PETSC_HAVE_CUSP)
5195   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5196     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5197   }
5198 #endif
5199   PetscFunctionReturn(0);
5200 }
5201 
5202 #undef __FUNCT__
5203 #define __FUNCT__ "MatZeroRowsColumnsIS"
5204 /*@C
5205    MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
5206    of a set of rows and columns of a matrix.
5207 
5208    Collective on Mat
5209 
5210    Input Parameters:
5211 +  mat - the matrix
5212 .  is - the rows to zero
5213 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5214 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5215 -  b - optional vector of right hand side, that will be adjusted by provided solution
5216 
5217    Notes:
5218    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5219 
5220    The user can set a value in the diagonal entry (or for the AIJ and
5221    row formats can optionally remove the main diagonal entry from the
5222    nonzero structure as well, by passing 0.0 as the final argument).
5223 
5224    For the parallel case, all processes that share the matrix (i.e.,
5225    those in the communicator used for matrix creation) MUST call this
5226    routine, regardless of whether any rows being zeroed are owned by
5227    them.
5228 
5229    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5230    list only rows local to itself).
5231 
5232    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5233 
5234    Level: intermediate
5235 
5236    Concepts: matrices^zeroing rows
5237 
5238 .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumns()
5239 @*/
5240 PetscErrorCode  MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5241 {
5242   PetscErrorCode ierr;
5243   PetscInt       numRows;
5244   const PetscInt *rows;
5245 
5246   PetscFunctionBegin;
5247   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5248   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5249   PetscValidType(mat,1);
5250   PetscValidType(is,2);
5251   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5252   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5253   ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5254   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5255   PetscFunctionReturn(0);
5256 }
5257 
5258 #undef __FUNCT__
5259 #define __FUNCT__ "MatZeroRows"
5260 /*@C
5261    MatZeroRows - Zeros all entries (except possibly the main diagonal)
5262    of a set of rows of a matrix.
5263 
5264    Collective on Mat
5265 
5266    Input Parameters:
5267 +  mat - the matrix
5268 .  numRows - the number of rows to remove
5269 .  rows - the global row indices
5270 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5271 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5272 -  b - optional vector of right hand side, that will be adjusted by provided solution
5273 
5274    Notes:
5275    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5276    but does not release memory.  For the dense and block diagonal
5277    formats this does not alter the nonzero structure.
5278 
5279    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5280    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5281    merely zeroed.
5282 
5283    The user can set a value in the diagonal entry (or for the AIJ and
5284    row formats can optionally remove the main diagonal entry from the
5285    nonzero structure as well, by passing 0.0 as the final argument).
5286 
5287    For the parallel case, all processes that share the matrix (i.e.,
5288    those in the communicator used for matrix creation) MUST call this
5289    routine, regardless of whether any rows being zeroed are owned by
5290    them.
5291 
5292    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5293    list only rows local to itself).
5294 
5295    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5296    owns that are to be zeroed. This saves a global synchronization in the implementation.
5297 
5298    Level: intermediate
5299 
5300    Concepts: matrices^zeroing rows
5301 
5302 .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5303 @*/
5304 PetscErrorCode  MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5305 {
5306   PetscErrorCode ierr;
5307 
5308   PetscFunctionBegin;
5309   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5310   PetscValidType(mat,1);
5311   if (numRows) PetscValidIntPointer(rows,3);
5312   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5313   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5314   if (!mat->ops->zerorows) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5315   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5316 
5317   ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5318   ierr = MatView_Private(mat);CHKERRQ(ierr);
5319   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5320 #if defined(PETSC_HAVE_CUSP)
5321   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5322     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5323   }
5324 #endif
5325   PetscFunctionReturn(0);
5326 }
5327 
5328 #undef __FUNCT__
5329 #define __FUNCT__ "MatZeroRowsIS"
5330 /*@C
5331    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5332    of a set of rows of a matrix.
5333 
5334    Collective on Mat
5335 
5336    Input Parameters:
5337 +  mat - the matrix
5338 .  is - index set of rows to remove
5339 .  diag - value put in all diagonals of eliminated rows
5340 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5341 -  b - optional vector of right hand side, that will be adjusted by provided solution
5342 
5343    Notes:
5344    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5345    but does not release memory.  For the dense and block diagonal
5346    formats this does not alter the nonzero structure.
5347 
5348    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5349    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5350    merely zeroed.
5351 
5352    The user can set a value in the diagonal entry (or for the AIJ and
5353    row formats can optionally remove the main diagonal entry from the
5354    nonzero structure as well, by passing 0.0 as the final argument).
5355 
5356    For the parallel case, all processes that share the matrix (i.e.,
5357    those in the communicator used for matrix creation) MUST call this
5358    routine, regardless of whether any rows being zeroed are owned by
5359    them.
5360 
5361    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5362    list only rows local to itself).
5363 
5364    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5365    owns that are to be zeroed. This saves a global synchronization in the implementation.
5366 
5367    Level: intermediate
5368 
5369    Concepts: matrices^zeroing rows
5370 
5371 .seealso: MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5372 @*/
5373 PetscErrorCode  MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5374 {
5375   PetscInt       numRows;
5376   const PetscInt *rows;
5377   PetscErrorCode ierr;
5378 
5379   PetscFunctionBegin;
5380   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5381   PetscValidType(mat,1);
5382   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5383   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5384   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5385   ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5386   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5387   PetscFunctionReturn(0);
5388 }
5389 
5390 #undef __FUNCT__
5391 #define __FUNCT__ "MatZeroRowsStencil"
5392 /*@C
5393    MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
5394    of a set of rows of a matrix. These rows must be local to the process.
5395 
5396    Collective on Mat
5397 
5398    Input Parameters:
5399 +  mat - the matrix
5400 .  numRows - the number of rows to remove
5401 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
5402 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5403 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5404 -  b - optional vector of right hand side, that will be adjusted by provided solution
5405 
5406    Notes:
5407    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5408    but does not release memory.  For the dense and block diagonal
5409    formats this does not alter the nonzero structure.
5410 
5411    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5412    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5413    merely zeroed.
5414 
5415    The user can set a value in the diagonal entry (or for the AIJ and
5416    row formats can optionally remove the main diagonal entry from the
5417    nonzero structure as well, by passing 0.0 as the final argument).
5418 
5419    For the parallel case, all processes that share the matrix (i.e.,
5420    those in the communicator used for matrix creation) MUST call this
5421    routine, regardless of whether any rows being zeroed are owned by
5422    them.
5423 
5424    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5425    list only rows local to itself).
5426 
5427    The grid coordinates are across the entire grid, not just the local portion
5428 
5429    In Fortran idxm and idxn should be declared as
5430 $     MatStencil idxm(4,m)
5431    and the values inserted using
5432 $    idxm(MatStencil_i,1) = i
5433 $    idxm(MatStencil_j,1) = j
5434 $    idxm(MatStencil_k,1) = k
5435 $    idxm(MatStencil_c,1) = c
5436    etc
5437 
5438    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5439    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5440    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5441    DMDA_BOUNDARY_PERIODIC boundary type.
5442 
5443    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
5444    a single value per point) you can skip filling those indices.
5445 
5446    Level: intermediate
5447 
5448    Concepts: matrices^zeroing rows
5449 
5450 .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5451 @*/
5452 PetscErrorCode  MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5453 {
5454   PetscInt       dim    = mat->stencil.dim;
5455   PetscInt       sdim   = dim - (1 - (PetscInt) mat->stencil.noc);
5456   PetscInt      *dims   = mat->stencil.dims+1;
5457   PetscInt      *starts = mat->stencil.starts;
5458   PetscInt      *dxm    = (PetscInt *) rows;
5459   PetscInt      *jdxm, i, j, tmp, numNewRows = 0;
5460   PetscErrorCode ierr;
5461 
5462   PetscFunctionBegin;
5463   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5464   PetscValidType(mat,1);
5465   if (numRows) PetscValidIntPointer(rows,3);
5466 
5467   ierr = PetscMalloc(numRows*sizeof(PetscInt), &jdxm);CHKERRQ(ierr);
5468   for(i = 0; i < numRows; ++i) {
5469     /* Skip unused dimensions (they are ordered k, j, i, c) */
5470     for(j = 0; j < 3-sdim; ++j) dxm++;
5471     /* Local index in X dir */
5472     tmp = *dxm++ - starts[0];
5473     /* Loop over remaining dimensions */
5474     for(j = 0; j < dim-1; ++j) {
5475       /* If nonlocal, set index to be negative */
5476       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5477       /* Update local index */
5478       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5479     }
5480     /* Skip component slot if necessary */
5481     if (mat->stencil.noc) dxm++;
5482     /* Local row number */
5483     if (tmp >= 0) {
5484       jdxm[numNewRows++] = tmp;
5485     }
5486   }
5487   ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
5488   ierr = PetscFree(jdxm);CHKERRQ(ierr);
5489   PetscFunctionReturn(0);
5490 }
5491 
5492 #undef __FUNCT__
5493 #define __FUNCT__ "MatZeroRowsLocal"
5494 /*@C
5495    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
5496    of a set of rows of a matrix; using local numbering of rows.
5497 
5498    Collective on Mat
5499 
5500    Input Parameters:
5501 +  mat - the matrix
5502 .  numRows - the number of rows to remove
5503 .  rows - the global row indices
5504 .  diag - value put in all diagonals of eliminated rows
5505 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5506 -  b - optional vector of right hand side, that will be adjusted by provided solution
5507 
5508    Notes:
5509    Before calling MatZeroRowsLocal(), the user must first set the
5510    local-to-global mapping by calling MatSetLocalToGlobalMapping().
5511 
5512    For the AIJ matrix formats this removes the old nonzero structure,
5513    but does not release memory.  For the dense and block diagonal
5514    formats this does not alter the nonzero structure.
5515 
5516    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5517    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5518    merely zeroed.
5519 
5520    The user can set a value in the diagonal entry (or for the AIJ and
5521    row formats can optionally remove the main diagonal entry from the
5522    nonzero structure as well, by passing 0.0 as the final argument).
5523 
5524    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5525    owns that are to be zeroed. This saves a global synchronization in the implementation.
5526 
5527    Level: intermediate
5528 
5529    Concepts: matrices^zeroing
5530 
5531 .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5532 @*/
5533 PetscErrorCode  MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5534 {
5535   PetscErrorCode ierr;
5536   PetscMPIInt    size;
5537 
5538   PetscFunctionBegin;
5539   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5540   PetscValidType(mat,1);
5541   if (numRows) PetscValidIntPointer(rows,3);
5542   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5543   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5544   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5545 
5546   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
5547   if (mat->ops->zerorowslocal) {
5548     ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5549   } else if (size == 1) {
5550     ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5551   } else {
5552     IS             is, newis;
5553     const PetscInt *newRows;
5554 
5555     if (!mat->rmap->mapping) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5556     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
5557     ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr);
5558     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
5559     ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
5560     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
5561     ierr = ISDestroy(&newis);CHKERRQ(ierr);
5562     ierr = ISDestroy(&is);CHKERRQ(ierr);
5563   }
5564   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5565 #if defined(PETSC_HAVE_CUSP)
5566   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5567     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5568   }
5569 #endif
5570   PetscFunctionReturn(0);
5571 }
5572 
5573 #undef __FUNCT__
5574 #define __FUNCT__ "MatZeroRowsLocalIS"
5575 /*@C
5576    MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
5577    of a set of rows of a matrix; using local numbering of rows.
5578 
5579    Collective on Mat
5580 
5581    Input Parameters:
5582 +  mat - the matrix
5583 .  is - index set of rows to remove
5584 .  diag - value put in all diagonals of eliminated rows
5585 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5586 -  b - optional vector of right hand side, that will be adjusted by provided solution
5587 
5588    Notes:
5589    Before calling MatZeroRowsLocalIS(), the user must first set the
5590    local-to-global mapping by calling MatSetLocalToGlobalMapping().
5591 
5592    For the AIJ matrix formats this removes the old nonzero structure,
5593    but does not release memory.  For the dense and block diagonal
5594    formats this does not alter the nonzero structure.
5595 
5596    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5597    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5598    merely zeroed.
5599 
5600    The user can set a value in the diagonal entry (or for the AIJ and
5601    row formats can optionally remove the main diagonal entry from the
5602    nonzero structure as well, by passing 0.0 as the final argument).
5603 
5604    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5605    owns that are to be zeroed. This saves a global synchronization in the implementation.
5606 
5607    Level: intermediate
5608 
5609    Concepts: matrices^zeroing
5610 
5611 .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5612 @*/
5613 PetscErrorCode  MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5614 {
5615   PetscErrorCode ierr;
5616   PetscInt       numRows;
5617   const PetscInt *rows;
5618 
5619   PetscFunctionBegin;
5620   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5621   PetscValidType(mat,1);
5622   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5623   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5624   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5625   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5626 
5627   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5628   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5629   ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5630   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5631   PetscFunctionReturn(0);
5632 }
5633 
5634 #undef __FUNCT__
5635 #define __FUNCT__ "MatZeroRowsColumnsLocal"
5636 /*@C
5637    MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
5638    of a set of rows and columns of a matrix; using local numbering of rows.
5639 
5640    Collective on Mat
5641 
5642    Input Parameters:
5643 +  mat - the matrix
5644 .  numRows - the number of rows to remove
5645 .  rows - the global row indices
5646 .  diag - value put in all diagonals of eliminated rows
5647 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5648 -  b - optional vector of right hand side, that will be adjusted by provided solution
5649 
5650    Notes:
5651    Before calling MatZeroRowsColumnsLocal(), the user must first set the
5652    local-to-global mapping by calling MatSetLocalToGlobalMapping().
5653 
5654    The user can set a value in the diagonal entry (or for the AIJ and
5655    row formats can optionally remove the main diagonal entry from the
5656    nonzero structure as well, by passing 0.0 as the final argument).
5657 
5658    Level: intermediate
5659 
5660    Concepts: matrices^zeroing
5661 
5662 .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5663 @*/
5664 PetscErrorCode  MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5665 {
5666   PetscErrorCode ierr;
5667   PetscMPIInt    size;
5668 
5669   PetscFunctionBegin;
5670   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5671   PetscValidType(mat,1);
5672   if (numRows) PetscValidIntPointer(rows,3);
5673   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5674   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5675   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5676 
5677   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
5678   if (size == 1) {
5679     ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5680   } else {
5681     IS             is, newis;
5682     const PetscInt *newRows;
5683 
5684     if (!mat->cmap->mapping) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5685     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
5686     ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr);
5687     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
5688     ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
5689     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
5690     ierr = ISDestroy(&newis);CHKERRQ(ierr);
5691     ierr = ISDestroy(&is);CHKERRQ(ierr);
5692   }
5693   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5694 #if defined(PETSC_HAVE_CUSP)
5695   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5696     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5697   }
5698 #endif
5699   PetscFunctionReturn(0);
5700 }
5701 
5702 #undef __FUNCT__
5703 #define __FUNCT__ "MatZeroRowsColumnsLocalIS"
5704 /*@C
5705    MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
5706    of a set of rows and columns of a matrix; using local numbering of rows.
5707 
5708    Collective on Mat
5709 
5710    Input Parameters:
5711 +  mat - the matrix
5712 .  is - index set of rows to remove
5713 .  diag - value put in all diagonals of eliminated rows
5714 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5715 -  b - optional vector of right hand side, that will be adjusted by provided solution
5716 
5717    Notes:
5718    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
5719    local-to-global mapping by calling MatSetLocalToGlobalMapping().
5720 
5721    The user can set a value in the diagonal entry (or for the AIJ and
5722    row formats can optionally remove the main diagonal entry from the
5723    nonzero structure as well, by passing 0.0 as the final argument).
5724 
5725    Level: intermediate
5726 
5727    Concepts: matrices^zeroing
5728 
5729 .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5730 @*/
5731 PetscErrorCode  MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5732 {
5733   PetscErrorCode ierr;
5734   PetscInt       numRows;
5735   const PetscInt *rows;
5736 
5737   PetscFunctionBegin;
5738   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5739   PetscValidType(mat,1);
5740   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5741   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5742   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5743   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5744 
5745   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5746   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5747   ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5748   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5749   PetscFunctionReturn(0);
5750 }
5751 
5752 #undef __FUNCT__
5753 #define __FUNCT__ "MatGetSize"
5754 /*@
5755    MatGetSize - Returns the numbers of rows and columns in a matrix.
5756 
5757    Not Collective
5758 
5759    Input Parameter:
5760 .  mat - the matrix
5761 
5762    Output Parameters:
5763 +  m - the number of global rows
5764 -  n - the number of global columns
5765 
5766    Note: both output parameters can be PETSC_NULL on input.
5767 
5768    Level: beginner
5769 
5770    Concepts: matrices^size
5771 
5772 .seealso: MatGetLocalSize()
5773 @*/
5774 PetscErrorCode  MatGetSize(Mat mat,PetscInt *m,PetscInt* n)
5775 {
5776   PetscFunctionBegin;
5777   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5778   if (m) *m = mat->rmap->N;
5779   if (n) *n = mat->cmap->N;
5780   PetscFunctionReturn(0);
5781 }
5782 
5783 #undef __FUNCT__
5784 #define __FUNCT__ "MatGetLocalSize"
5785 /*@
5786    MatGetLocalSize - Returns the number of rows and columns in a matrix
5787    stored locally.  This information may be implementation dependent, so
5788    use with care.
5789 
5790    Not Collective
5791 
5792    Input Parameters:
5793 .  mat - the matrix
5794 
5795    Output Parameters:
5796 +  m - the number of local rows
5797 -  n - the number of local columns
5798 
5799    Note: both output parameters can be PETSC_NULL on input.
5800 
5801    Level: beginner
5802 
5803    Concepts: matrices^local size
5804 
5805 .seealso: MatGetSize()
5806 @*/
5807 PetscErrorCode  MatGetLocalSize(Mat mat,PetscInt *m,PetscInt* n)
5808 {
5809   PetscFunctionBegin;
5810   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5811   if (m) PetscValidIntPointer(m,2);
5812   if (n) PetscValidIntPointer(n,3);
5813   if (m) *m = mat->rmap->n;
5814   if (n) *n = mat->cmap->n;
5815   PetscFunctionReturn(0);
5816 }
5817 
5818 #undef __FUNCT__
5819 #define __FUNCT__ "MatGetOwnershipRangeColumn"
5820 /*@
5821    MatGetOwnershipRangeColumn - Returns the range of matrix columns owned by
5822    this processor.
5823 
5824    Not Collective, unless matrix has not been allocated, then collective on Mat
5825 
5826    Input Parameters:
5827 .  mat - the matrix
5828 
5829    Output Parameters:
5830 +  m - the global index of the first local column
5831 -  n - one more than the global index of the last local column
5832 
5833    Notes: both output parameters can be PETSC_NULL on input.
5834 
5835    Level: developer
5836 
5837    Concepts: matrices^column ownership
5838 
5839 .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
5840 
5841 @*/
5842 PetscErrorCode  MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt* n)
5843 {
5844   PetscErrorCode ierr;
5845 
5846   PetscFunctionBegin;
5847   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5848   PetscValidType(mat,1);
5849   if (m) PetscValidIntPointer(m,2);
5850   if (n) PetscValidIntPointer(n,3);
5851   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5852   if (m) *m = mat->cmap->rstart;
5853   if (n) *n = mat->cmap->rend;
5854   PetscFunctionReturn(0);
5855 }
5856 
5857 #undef __FUNCT__
5858 #define __FUNCT__ "MatGetOwnershipRange"
5859 /*@
5860    MatGetOwnershipRange - Returns the range of matrix rows owned by
5861    this processor, assuming that the matrix is laid out with the first
5862    n1 rows on the first processor, the next n2 rows on the second, etc.
5863    For certain parallel layouts this range may not be well defined.
5864 
5865    Not Collective, unless matrix has not been allocated, then collective on Mat
5866 
5867    Input Parameters:
5868 .  mat - the matrix
5869 
5870    Output Parameters:
5871 +  m - the global index of the first local row
5872 -  n - one more than the global index of the last local row
5873 
5874    Note: both output parameters can be PETSC_NULL on input.
5875 
5876    Level: beginner
5877 
5878    Concepts: matrices^row ownership
5879 
5880 .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
5881 
5882 @*/
5883 PetscErrorCode  MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt* n)
5884 {
5885   PetscErrorCode ierr;
5886 
5887   PetscFunctionBegin;
5888   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5889   PetscValidType(mat,1);
5890   if (m) PetscValidIntPointer(m,2);
5891   if (n) PetscValidIntPointer(n,3);
5892   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5893   if (m) *m = mat->rmap->rstart;
5894   if (n) *n = mat->rmap->rend;
5895   PetscFunctionReturn(0);
5896 }
5897 
5898 #undef __FUNCT__
5899 #define __FUNCT__ "MatGetOwnershipRanges"
5900 /*@C
5901    MatGetOwnershipRanges - Returns the range of matrix rows owned by
5902    each process
5903 
5904    Not Collective, unless matrix has not been allocated, then collective on Mat
5905 
5906    Input Parameters:
5907 .  mat - the matrix
5908 
5909    Output Parameters:
5910 .  ranges - start of each processors portion plus one more then the total length at the end
5911 
5912    Level: beginner
5913 
5914    Concepts: matrices^row ownership
5915 
5916 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
5917 
5918 @*/
5919 PetscErrorCode  MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
5920 {
5921   PetscErrorCode ierr;
5922 
5923   PetscFunctionBegin;
5924   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5925   PetscValidType(mat,1);
5926   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5927   ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr);
5928   PetscFunctionReturn(0);
5929 }
5930 
5931 #undef __FUNCT__
5932 #define __FUNCT__ "MatGetOwnershipRangesColumn"
5933 /*@C
5934    MatGetOwnershipRangesColumn - Returns the range of local columns for each process
5935 
5936    Not Collective, unless matrix has not been allocated, then collective on Mat
5937 
5938    Input Parameters:
5939 .  mat - the matrix
5940 
5941    Output Parameters:
5942 .  ranges - start of each processors portion plus one more then the total length at the end
5943 
5944    Level: beginner
5945 
5946    Concepts: matrices^column ownership
5947 
5948 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
5949 
5950 @*/
5951 PetscErrorCode  MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
5952 {
5953   PetscErrorCode ierr;
5954 
5955   PetscFunctionBegin;
5956   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5957   PetscValidType(mat,1);
5958   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5959   ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr);
5960   PetscFunctionReturn(0);
5961 }
5962 
5963 #undef __FUNCT__
5964 #define __FUNCT__ "MatILUFactorSymbolic"
5965 /*@C
5966    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
5967    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
5968    to complete the factorization.
5969 
5970    Collective on Mat
5971 
5972    Input Parameters:
5973 +  mat - the matrix
5974 .  row - row permutation
5975 .  column - column permutation
5976 -  info - structure containing
5977 $      levels - number of levels of fill.
5978 $      expected fill - as ratio of original fill.
5979 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
5980                 missing diagonal entries)
5981 
5982    Output Parameters:
5983 .  fact - new matrix that has been symbolically factored
5984 
5985    Notes:
5986    See the <a href="../../docs/manual.pdf">users manual</a>  for additional information about
5987    choosing the fill factor for better efficiency.
5988 
5989    Most users should employ the simplified KSP interface for linear solvers
5990    instead of working directly with matrix algebra routines such as this.
5991    See, e.g., KSPCreate().
5992 
5993    Level: developer
5994 
5995   Concepts: matrices^symbolic LU factorization
5996   Concepts: matrices^factorization
5997   Concepts: LU^symbolic factorization
5998 
5999 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6000           MatGetOrdering(), MatFactorInfo
6001 
6002     Developer Note: fortran interface is not autogenerated as the f90
6003     interface defintion cannot be generated correctly [due to MatFactorInfo]
6004 
6005 @*/
6006 PetscErrorCode  MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6007 {
6008   PetscErrorCode ierr;
6009 
6010   PetscFunctionBegin;
6011   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6012   PetscValidType(mat,1);
6013   PetscValidHeaderSpecific(row,IS_CLASSID,2);
6014   PetscValidHeaderSpecific(col,IS_CLASSID,3);
6015   PetscValidPointer(info,4);
6016   PetscValidPointer(fact,5);
6017   if (info->levels < 0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6018   if (info->fill < 1.0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
6019   if (!(fact)->ops->ilufactorsymbolic) {
6020     const MatSolverPackage spackage;
6021     ierr = MatFactorGetSolverPackage(fact,&spackage);CHKERRQ(ierr);
6022     SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6023   }
6024   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6025   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6026   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6027 
6028   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6029   ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
6030   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6031   PetscFunctionReturn(0);
6032 }
6033 
6034 #undef __FUNCT__
6035 #define __FUNCT__ "MatICCFactorSymbolic"
6036 /*@C
6037    MatICCFactorSymbolic - Performs symbolic incomplete
6038    Cholesky factorization for a symmetric matrix.  Use
6039    MatCholeskyFactorNumeric() to complete the factorization.
6040 
6041    Collective on Mat
6042 
6043    Input Parameters:
6044 +  mat - the matrix
6045 .  perm - row and column permutation
6046 -  info - structure containing
6047 $      levels - number of levels of fill.
6048 $      expected fill - as ratio of original fill.
6049 
6050    Output Parameter:
6051 .  fact - the factored matrix
6052 
6053    Notes:
6054    Most users should employ the KSP interface for linear solvers
6055    instead of working directly with matrix algebra routines such as this.
6056    See, e.g., KSPCreate().
6057 
6058    Level: developer
6059 
6060   Concepts: matrices^symbolic incomplete Cholesky factorization
6061   Concepts: matrices^factorization
6062   Concepts: Cholsky^symbolic factorization
6063 
6064 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
6065 
6066     Developer Note: fortran interface is not autogenerated as the f90
6067     interface defintion cannot be generated correctly [due to MatFactorInfo]
6068 
6069 @*/
6070 PetscErrorCode  MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6071 {
6072   PetscErrorCode ierr;
6073 
6074   PetscFunctionBegin;
6075   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6076   PetscValidType(mat,1);
6077   PetscValidHeaderSpecific(perm,IS_CLASSID,2);
6078   PetscValidPointer(info,3);
6079   PetscValidPointer(fact,4);
6080   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6081   if (info->levels < 0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6082   if (info->fill < 1.0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
6083   if (!(fact)->ops->iccfactorsymbolic) {
6084     const MatSolverPackage spackage;
6085     ierr = MatFactorGetSolverPackage(fact,&spackage);CHKERRQ(ierr);
6086     SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6087   }
6088   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6089   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6090 
6091   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6092   ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
6093   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6094   PetscFunctionReturn(0);
6095 }
6096 
6097 #undef __FUNCT__
6098 #define __FUNCT__ "MatGetArray"
6099 /*@C
6100    MatGetArray - Returns a pointer to the element values in the matrix.
6101    The result of this routine is dependent on the underlying matrix data
6102    structure, and may not even work for certain matrix types.  You MUST
6103    call MatRestoreArray() when you no longer need to access the array.
6104 
6105    Not Collective
6106 
6107    Input Parameter:
6108 .  mat - the matrix
6109 
6110    Output Parameter:
6111 .  v - the location of the values
6112 
6113 
6114    Fortran Note:
6115    This routine is used differently from Fortran, e.g.,
6116 .vb
6117         Mat         mat
6118         PetscScalar mat_array(1)
6119         PetscOffset i_mat
6120         PetscErrorCode ierr
6121         call MatGetArray(mat,mat_array,i_mat,ierr)
6122 
6123   C  Access first local entry in matrix; note that array is
6124   C  treated as one dimensional
6125         value = mat_array(i_mat + 1)
6126 
6127         [... other code ...]
6128         call MatRestoreArray(mat,mat_array,i_mat,ierr)
6129 .ve
6130 
6131    See the <a href="../../docs/manual.pdf#ch_fortran">Fortran chapter of the users manual</a> and
6132    src/mat/examples/tests for details.
6133 
6134    Level: advanced
6135 
6136    Concepts: matrices^access array
6137 
6138 .seealso: MatRestoreArray(), MatGetArrayF90(), MatGetRowIJ()
6139 @*/
6140 PetscErrorCode  MatGetArray(Mat mat,PetscScalar *v[])
6141 {
6142   PetscErrorCode ierr;
6143 
6144   PetscFunctionBegin;
6145   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6146   PetscValidType(mat,1);
6147   PetscValidPointer(v,2);
6148   if (!mat->ops->getarray) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6149   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6150   ierr = (*mat->ops->getarray)(mat,v);CHKERRQ(ierr);
6151   CHKMEMQ;
6152   PetscFunctionReturn(0);
6153 }
6154 
6155 #undef __FUNCT__
6156 #define __FUNCT__ "MatRestoreArray"
6157 /*@C
6158    MatRestoreArray - Restores the matrix after MatGetArray() has been called.
6159 
6160    Not Collective
6161 
6162    Input Parameter:
6163 +  mat - the matrix
6164 -  v - the location of the values
6165 
6166    Fortran Note:
6167    This routine is used differently from Fortran, e.g.,
6168 .vb
6169         Mat         mat
6170         PetscScalar mat_array(1)
6171         PetscOffset i_mat
6172         PetscErrorCode ierr
6173         call MatGetArray(mat,mat_array,i_mat,ierr)
6174 
6175   C  Access first local entry in matrix; note that array is
6176   C  treated as one dimensional
6177         value = mat_array(i_mat + 1)
6178 
6179         [... other code ...]
6180         call MatRestoreArray(mat,mat_array,i_mat,ierr)
6181 .ve
6182 
6183    See the <a href="../../docs/manual.pdf#ch_fortran">Fortran chapter of the users manual</a>
6184    src/mat/examples/tests for details
6185 
6186    Level: advanced
6187 
6188 .seealso: MatGetArray(), MatRestoreArrayF90()
6189 @*/
6190 PetscErrorCode  MatRestoreArray(Mat mat,PetscScalar *v[])
6191 {
6192   PetscErrorCode ierr;
6193 
6194   PetscFunctionBegin;
6195   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6196   PetscValidType(mat,1);
6197   PetscValidPointer(v,2);
6198 #if defined(PETSC_USE_DEBUG)
6199   CHKMEMQ;
6200 #endif
6201   if (!mat->ops->restorearray) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6202   ierr = (*mat->ops->restorearray)(mat,v);CHKERRQ(ierr);
6203   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6204 #if defined(PETSC_HAVE_CUSP)
6205   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
6206     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
6207   }
6208 #endif
6209   PetscFunctionReturn(0);
6210 }
6211 
6212 #undef __FUNCT__
6213 #define __FUNCT__ "MatGetSubMatrices"
6214 /*@C
6215    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
6216    points to an array of valid matrices, they may be reused to store the new
6217    submatrices.
6218 
6219    Collective on Mat
6220 
6221    Input Parameters:
6222 +  mat - the matrix
6223 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6224 .  irow, icol - index sets of rows and columns to extract
6225 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6226 
6227    Output Parameter:
6228 .  submat - the array of submatrices
6229 
6230    Notes:
6231    MatGetSubMatrices() can extract ONLY sequential submatrices
6232    (from both sequential and parallel matrices). Use MatGetSubMatrix()
6233    to extract a parallel submatrix.
6234 
6235    When extracting submatrices from a parallel matrix, each processor can
6236    form a different submatrix by setting the rows and columns of its
6237    individual index sets according to the local submatrix desired.
6238 
6239    When finished using the submatrices, the user should destroy
6240    them with MatDestroyMatrices().
6241 
6242    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6243    original matrix has not changed from that last call to MatGetSubMatrices().
6244 
6245    This routine creates the matrices in submat; you should NOT create them before
6246    calling it. It also allocates the array of matrix pointers submat.
6247 
6248    For BAIJ matrices the index sets must respect the block structure, that is if they
6249    request one row/column in a block, they must request all rows/columns that are in
6250    that block. For example, if the block size is 2 you cannot request just row 0 and
6251    column 0.
6252 
6253    Fortran Note:
6254    The Fortran interface is slightly different from that given below; it
6255    requires one to pass in  as submat a Mat (integer) array of size at least m.
6256 
6257    Level: advanced
6258 
6259    Concepts: matrices^accessing submatrices
6260    Concepts: submatrices
6261 
6262 .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6263 @*/
6264 PetscErrorCode  MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6265 {
6266   PetscErrorCode ierr;
6267   PetscInt        i;
6268   PetscBool       eq;
6269 
6270   PetscFunctionBegin;
6271   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6272   PetscValidType(mat,1);
6273   if (n) {
6274     PetscValidPointer(irow,3);
6275     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6276     PetscValidPointer(icol,4);
6277     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6278   }
6279   PetscValidPointer(submat,6);
6280   if (n && scall == MAT_REUSE_MATRIX) {
6281     PetscValidPointer(*submat,6);
6282     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6283   }
6284   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6285   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6286   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6287   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6288 
6289   ierr = PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
6290   ierr = (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6291   ierr = PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
6292   for (i=0; i<n; i++) {
6293     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6294       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6295       if (eq) {
6296 	if (mat->symmetric){
6297 	  ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6298 	} else if (mat->hermitian) {
6299 	  ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6300 	} else if (mat->structurally_symmetric) {
6301 	  ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6302 	}
6303       }
6304     }
6305   }
6306   PetscFunctionReturn(0);
6307 }
6308 
6309 #undef __FUNCT__
6310 #define __FUNCT__ "MatGetSubMatricesParallel"
6311 PetscErrorCode  MatGetSubMatricesParallel(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6312 {
6313   PetscErrorCode ierr;
6314   PetscInt        i;
6315   PetscBool       eq;
6316 
6317   PetscFunctionBegin;
6318   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6319   PetscValidType(mat,1);
6320   if (n) {
6321     PetscValidPointer(irow,3);
6322     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6323     PetscValidPointer(icol,4);
6324     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6325   }
6326   PetscValidPointer(submat,6);
6327   if (n && scall == MAT_REUSE_MATRIX) {
6328     PetscValidPointer(*submat,6);
6329     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6330   }
6331   if (!mat->ops->getsubmatricesparallel) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6332   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6333   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6334   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6335 
6336   ierr = PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
6337   ierr = (*mat->ops->getsubmatricesparallel)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6338   ierr = PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
6339   for (i=0; i<n; i++) {
6340     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6341       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6342       if (eq) {
6343 	if (mat->symmetric){
6344 	  ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6345 	} else if (mat->hermitian) {
6346 	  ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6347 	} else if (mat->structurally_symmetric) {
6348 	  ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6349 	}
6350       }
6351     }
6352   }
6353   PetscFunctionReturn(0);
6354 }
6355 
6356 #undef __FUNCT__
6357 #define __FUNCT__ "MatDestroyMatrices"
6358 /*@C
6359    MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().
6360 
6361    Collective on Mat
6362 
6363    Input Parameters:
6364 +  n - the number of local matrices
6365 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6366                        sequence of MatGetSubMatrices())
6367 
6368    Level: advanced
6369 
6370     Notes: Frees not only the matrices, but also the array that contains the matrices
6371            In Fortran will not free the array.
6372 
6373 .seealso: MatGetSubMatrices()
6374 @*/
6375 PetscErrorCode  MatDestroyMatrices(PetscInt n,Mat *mat[])
6376 {
6377   PetscErrorCode ierr;
6378   PetscInt       i;
6379 
6380   PetscFunctionBegin;
6381   if (!*mat) PetscFunctionReturn(0);
6382   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6383   PetscValidPointer(mat,2);
6384   for (i=0; i<n; i++) {
6385     ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr);
6386   }
6387   /* memory is allocated even if n = 0 */
6388   ierr = PetscFree(*mat);CHKERRQ(ierr);
6389   *mat = PETSC_NULL;
6390   PetscFunctionReturn(0);
6391 }
6392 
6393 #undef __FUNCT__
6394 #define __FUNCT__ "MatGetSeqNonzeroStructure"
6395 /*@C
6396    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
6397 
6398    Collective on Mat
6399 
6400    Input Parameters:
6401 .  mat - the matrix
6402 
6403    Output Parameter:
6404 .  matstruct - the sequential matrix with the nonzero structure of mat
6405 
6406   Level: intermediate
6407 
6408 .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
6409 @*/
6410 PetscErrorCode  MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6411 {
6412   PetscErrorCode ierr;
6413 
6414   PetscFunctionBegin;
6415   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6416   PetscValidPointer(matstruct,2);
6417 
6418   PetscValidType(mat,1);
6419   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6420   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6421 
6422   if (!mat->ops->getseqnonzerostructure) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6423   ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
6424   ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr);
6425   ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
6426   PetscFunctionReturn(0);
6427 }
6428 
6429 #undef __FUNCT__
6430 #define __FUNCT__ "MatDestroySeqNonzeroStructure"
6431 /*@C
6432    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
6433 
6434    Collective on Mat
6435 
6436    Input Parameters:
6437 .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
6438                        sequence of MatGetSequentialNonzeroStructure())
6439 
6440    Level: advanced
6441 
6442     Notes: Frees not only the matrices, but also the array that contains the matrices
6443 
6444 .seealso: MatGetSeqNonzeroStructure()
6445 @*/
6446 PetscErrorCode  MatDestroySeqNonzeroStructure(Mat *mat)
6447 {
6448   PetscErrorCode ierr;
6449 
6450   PetscFunctionBegin;
6451   PetscValidPointer(mat,1);
6452   ierr = MatDestroy(mat);CHKERRQ(ierr);
6453   PetscFunctionReturn(0);
6454 }
6455 
6456 #undef __FUNCT__
6457 #define __FUNCT__ "MatIncreaseOverlap"
6458 /*@
6459    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6460    replaces the index sets by larger ones that represent submatrices with
6461    additional overlap.
6462 
6463    Collective on Mat
6464 
6465    Input Parameters:
6466 +  mat - the matrix
6467 .  n   - the number of index sets
6468 .  is  - the array of index sets (these index sets will changed during the call)
6469 -  ov  - the additional overlap requested
6470 
6471    Level: developer
6472 
6473    Concepts: overlap
6474    Concepts: ASM^computing overlap
6475 
6476 .seealso: MatGetSubMatrices()
6477 @*/
6478 PetscErrorCode  MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6479 {
6480   PetscErrorCode ierr;
6481 
6482   PetscFunctionBegin;
6483   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6484   PetscValidType(mat,1);
6485   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6486   if (n) {
6487     PetscValidPointer(is,3);
6488     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
6489   }
6490   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6491   if (mat->factortype)     SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6492   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6493 
6494   if (!ov) PetscFunctionReturn(0);
6495   if (!mat->ops->increaseoverlap) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6496   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
6497   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
6498   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
6499   PetscFunctionReturn(0);
6500 }
6501 
6502 #undef __FUNCT__
6503 #define __FUNCT__ "MatGetBlockSize"
6504 /*@
6505    MatGetBlockSize - Returns the matrix block size; useful especially for the
6506    block row and block diagonal formats.
6507 
6508    Not Collective
6509 
6510    Input Parameter:
6511 .  mat - the matrix
6512 
6513    Output Parameter:
6514 .  bs - block size
6515 
6516    Notes:
6517    Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ
6518 
6519    Level: intermediate
6520 
6521    Concepts: matrices^block size
6522 
6523 .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ()
6524 @*/
6525 PetscErrorCode  MatGetBlockSize(Mat mat,PetscInt *bs)
6526 {
6527   PetscErrorCode ierr;
6528 
6529   PetscFunctionBegin;
6530   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6531   PetscValidType(mat,1);
6532   PetscValidIntPointer(bs,2);
6533   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6534   *bs = mat->rmap->bs;
6535   PetscFunctionReturn(0);
6536 }
6537 
6538 #undef __FUNCT__
6539 #define __FUNCT__ "MatSetBlockSize"
6540 /*@
6541    MatSetBlockSize - Sets the matrix block size; for many matrix types you
6542      cannot use this and MUST set the blocksize when you preallocate the matrix
6543 
6544    Logically Collective on Mat
6545 
6546    Input Parameters:
6547 +  mat - the matrix
6548 -  bs - block size
6549 
6550    Notes:
6551      For BAIJ matrices, this just checks that the block size agrees with the BAIJ size,
6552      it is not possible to change BAIJ block sizes after preallocation.
6553 
6554    Level: intermediate
6555 
6556    Concepts: matrices^block size
6557 
6558 .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ(), MatGetBlockSize()
6559 @*/
6560 PetscErrorCode  MatSetBlockSize(Mat mat,PetscInt bs)
6561 {
6562   PetscErrorCode ierr;
6563 
6564   PetscFunctionBegin;
6565   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6566   PetscValidType(mat,1);
6567   PetscValidLogicalCollectiveInt(mat,bs,2);
6568   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6569   if (bs < 1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Block size %D, must be positive",bs);
6570   if (mat->ops->setblocksize) {
6571     ierr = (*mat->ops->setblocksize)(mat,bs);CHKERRQ(ierr);
6572   } else {
6573     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Cannot set the blocksize for matrix type %s",((PetscObject)mat)->type_name);
6574   }
6575   PetscFunctionReturn(0);
6576 }
6577 
6578 #undef __FUNCT__
6579 #define __FUNCT__ "MatGetRowIJ"
6580 /*@C
6581     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
6582 
6583    Collective on Mat
6584 
6585     Input Parameters:
6586 +   mat - the matrix
6587 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
6588 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
6589 -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
6590                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6591                  always used.
6592 
6593     Output Parameters:
6594 +   n - number of rows in the (possibly compressed) matrix
6595 .   ia - the row pointers [of length n+1]
6596 .   ja - the column indices
6597 -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
6598            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
6599 
6600     Level: developer
6601 
6602     Notes: You CANNOT change any of the ia[] or ja[] values.
6603 
6604            Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values
6605 
6606     Fortran Node
6607 
6608            In Fortran use
6609 $           PetscInt ia(1), ja(1)
6610 $           PetscOffset iia, jja
6611 $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
6612 $
6613 $          or
6614 $
6615 $           PetscScalar, pointer :: xx_v(:)
6616 $    call  MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
6617 
6618 
6619        Acess the ith and jth entries via ia(iia + i) and ja(jja + j)
6620 
6621 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatGetArray()
6622 @*/
6623 PetscErrorCode  MatGetRowIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6624 {
6625   PetscErrorCode ierr;
6626 
6627   PetscFunctionBegin;
6628   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6629   PetscValidType(mat,1);
6630   PetscValidIntPointer(n,4);
6631   if (ia) PetscValidIntPointer(ia,5);
6632   if (ja) PetscValidIntPointer(ja,6);
6633   PetscValidIntPointer(done,7);
6634   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6635   if (!mat->ops->getrowij) *done = PETSC_FALSE;
6636   else {
6637     *done = PETSC_TRUE;
6638     ierr = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
6639     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6640     ierr = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
6641   }
6642   PetscFunctionReturn(0);
6643 }
6644 
6645 #undef __FUNCT__
6646 #define __FUNCT__ "MatGetColumnIJ"
6647 /*@C
6648     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
6649 
6650     Collective on Mat
6651 
6652     Input Parameters:
6653 +   mat - the matrix
6654 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6655 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6656                 symmetrized
6657 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6658                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6659                  always used.
6660 
6661     Output Parameters:
6662 +   n - number of columns in the (possibly compressed) matrix
6663 .   ia - the column pointers
6664 .   ja - the row indices
6665 -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
6666 
6667     Level: developer
6668 
6669 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6670 @*/
6671 PetscErrorCode  MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6672 {
6673   PetscErrorCode ierr;
6674 
6675   PetscFunctionBegin;
6676   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6677   PetscValidType(mat,1);
6678   PetscValidIntPointer(n,4);
6679   if (ia) PetscValidIntPointer(ia,5);
6680   if (ja) PetscValidIntPointer(ja,6);
6681   PetscValidIntPointer(done,7);
6682   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6683   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
6684   else {
6685     *done = PETSC_TRUE;
6686     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6687   }
6688   PetscFunctionReturn(0);
6689 }
6690 
6691 #undef __FUNCT__
6692 #define __FUNCT__ "MatRestoreRowIJ"
6693 /*@C
6694     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
6695     MatGetRowIJ().
6696 
6697     Collective on Mat
6698 
6699     Input Parameters:
6700 +   mat - the matrix
6701 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6702 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6703                 symmetrized
6704 -   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6705                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6706                  always used.
6707 
6708     Output Parameters:
6709 +   n - size of (possibly compressed) matrix
6710 .   ia - the row pointers
6711 .   ja - the column indices
6712 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
6713 
6714     Level: developer
6715 
6716 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6717 @*/
6718 PetscErrorCode  MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6719 {
6720   PetscErrorCode ierr;
6721 
6722   PetscFunctionBegin;
6723   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6724   PetscValidType(mat,1);
6725   if (ia) PetscValidIntPointer(ia,5);
6726   if (ja) PetscValidIntPointer(ja,6);
6727   PetscValidIntPointer(done,7);
6728   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6729 
6730   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
6731   else {
6732     *done = PETSC_TRUE;
6733     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6734   }
6735   PetscFunctionReturn(0);
6736 }
6737 
6738 #undef __FUNCT__
6739 #define __FUNCT__ "MatRestoreColumnIJ"
6740 /*@C
6741     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
6742     MatGetColumnIJ().
6743 
6744     Collective on Mat
6745 
6746     Input Parameters:
6747 +   mat - the matrix
6748 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6749 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6750                 symmetrized
6751 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6752                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6753                  always used.
6754 
6755     Output Parameters:
6756 +   n - size of (possibly compressed) matrix
6757 .   ia - the column pointers
6758 .   ja - the row indices
6759 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
6760 
6761     Level: developer
6762 
6763 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
6764 @*/
6765 PetscErrorCode  MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6766 {
6767   PetscErrorCode ierr;
6768 
6769   PetscFunctionBegin;
6770   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6771   PetscValidType(mat,1);
6772   if (ia) PetscValidIntPointer(ia,5);
6773   if (ja) PetscValidIntPointer(ja,6);
6774   PetscValidIntPointer(done,7);
6775   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6776 
6777   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
6778   else {
6779     *done = PETSC_TRUE;
6780     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6781   }
6782   PetscFunctionReturn(0);
6783 }
6784 
6785 #undef __FUNCT__
6786 #define __FUNCT__ "MatColoringPatch"
6787 /*@C
6788     MatColoringPatch -Used inside matrix coloring routines that
6789     use MatGetRowIJ() and/or MatGetColumnIJ().
6790 
6791     Collective on Mat
6792 
6793     Input Parameters:
6794 +   mat - the matrix
6795 .   ncolors - max color value
6796 .   n   - number of entries in colorarray
6797 -   colorarray - array indicating color for each column
6798 
6799     Output Parameters:
6800 .   iscoloring - coloring generated using colorarray information
6801 
6802     Level: developer
6803 
6804 .seealso: MatGetRowIJ(), MatGetColumnIJ()
6805 
6806 @*/
6807 PetscErrorCode  MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
6808 {
6809   PetscErrorCode ierr;
6810 
6811   PetscFunctionBegin;
6812   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6813   PetscValidType(mat,1);
6814   PetscValidIntPointer(colorarray,4);
6815   PetscValidPointer(iscoloring,5);
6816   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6817 
6818   if (!mat->ops->coloringpatch){
6819     ierr = ISColoringCreate(((PetscObject)mat)->comm,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
6820   } else {
6821     ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
6822   }
6823   PetscFunctionReturn(0);
6824 }
6825 
6826 
6827 #undef __FUNCT__
6828 #define __FUNCT__ "MatSetUnfactored"
6829 /*@
6830    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
6831 
6832    Logically Collective on Mat
6833 
6834    Input Parameter:
6835 .  mat - the factored matrix to be reset
6836 
6837    Notes:
6838    This routine should be used only with factored matrices formed by in-place
6839    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
6840    format).  This option can save memory, for example, when solving nonlinear
6841    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
6842    ILU(0) preconditioner.
6843 
6844    Note that one can specify in-place ILU(0) factorization by calling
6845 .vb
6846      PCType(pc,PCILU);
6847      PCFactorSeUseInPlace(pc);
6848 .ve
6849    or by using the options -pc_type ilu -pc_factor_in_place
6850 
6851    In-place factorization ILU(0) can also be used as a local
6852    solver for the blocks within the block Jacobi or additive Schwarz
6853    methods (runtime option: -sub_pc_factor_in_place).  See the discussion
6854    of these preconditioners in the <a href="../../docs/manual.pdf#ch_pc">PC chapter of the users manual</a> for details on setting
6855    local solver options.
6856 
6857    Most users should employ the simplified KSP interface for linear solvers
6858    instead of working directly with matrix algebra routines such as this.
6859    See, e.g., KSPCreate().
6860 
6861    Level: developer
6862 
6863 .seealso: PCFactorSetUseInPlace()
6864 
6865    Concepts: matrices^unfactored
6866 
6867 @*/
6868 PetscErrorCode  MatSetUnfactored(Mat mat)
6869 {
6870   PetscErrorCode ierr;
6871 
6872   PetscFunctionBegin;
6873   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6874   PetscValidType(mat,1);
6875   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6876   mat->factortype = MAT_FACTOR_NONE;
6877   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
6878   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
6879   PetscFunctionReturn(0);
6880 }
6881 
6882 /*MC
6883     MatGetArrayF90 - Accesses a matrix array from Fortran90.
6884 
6885     Synopsis:
6886     MatGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
6887 
6888     Not collective
6889 
6890     Input Parameter:
6891 .   x - matrix
6892 
6893     Output Parameters:
6894 +   xx_v - the Fortran90 pointer to the array
6895 -   ierr - error code
6896 
6897     Example of Usage:
6898 .vb
6899       PetscScalar, pointer xx_v(:,:)
6900       ....
6901       call MatGetArrayF90(x,xx_v,ierr)
6902       a = xx_v(3)
6903       call MatRestoreArrayF90(x,xx_v,ierr)
6904 .ve
6905 
6906     Notes:
6907     Not yet supported for all F90 compilers
6908 
6909     Level: advanced
6910 
6911 .seealso:  MatRestoreArrayF90(), MatGetArray(), MatRestoreArray()
6912 
6913     Concepts: matrices^accessing array
6914 
6915 M*/
6916 
6917 /*MC
6918     MatRestoreArrayF90 - Restores a matrix array that has been
6919     accessed with MatGetArrayF90().
6920 
6921     Synopsis:
6922     MatRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
6923 
6924     Not collective
6925 
6926     Input Parameters:
6927 +   x - matrix
6928 -   xx_v - the Fortran90 pointer to the array
6929 
6930     Output Parameter:
6931 .   ierr - error code
6932 
6933     Example of Usage:
6934 .vb
6935        PetscScalar, pointer xx_v(:)
6936        ....
6937        call MatGetArrayF90(x,xx_v,ierr)
6938        a = xx_v(3)
6939        call MatRestoreArrayF90(x,xx_v,ierr)
6940 .ve
6941 
6942     Notes:
6943     Not yet supported for all F90 compilers
6944 
6945     Level: advanced
6946 
6947 .seealso:  MatGetArrayF90(), MatGetArray(), MatRestoreArray()
6948 
6949 M*/
6950 
6951 
6952 #undef __FUNCT__
6953 #define __FUNCT__ "MatGetSubMatrix"
6954 /*@
6955     MatGetSubMatrix - Gets a single submatrix on the same number of processors
6956                       as the original matrix.
6957 
6958     Collective on Mat
6959 
6960     Input Parameters:
6961 +   mat - the original matrix
6962 .   isrow - parallel IS containing the rows this processor should obtain
6963 .   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.
6964 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6965 
6966     Output Parameter:
6967 .   newmat - the new submatrix, of the same type as the old
6968 
6969     Level: advanced
6970 
6971     Notes:
6972     The submatrix will be able to be multiplied with vectors using the same layout as iscol.
6973 
6974     The rows in isrow will be sorted into the same order as the original matrix on each process.
6975 
6976       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
6977    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
6978    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
6979    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
6980    you are finished using it.
6981 
6982     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
6983     the input matrix.
6984 
6985     If iscol is PETSC_NULL then all columns are obtained (not supported in Fortran).
6986 
6987    Example usage:
6988    Consider the following 8x8 matrix with 34 non-zero values, that is
6989    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
6990    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
6991    as follows:
6992 
6993 .vb
6994             1  2  0  |  0  3  0  |  0  4
6995     Proc0   0  5  6  |  7  0  0  |  8  0
6996             9  0 10  | 11  0  0  | 12  0
6997     -------------------------------------
6998            13  0 14  | 15 16 17  |  0  0
6999     Proc1   0 18  0  | 19 20 21  |  0  0
7000             0  0  0  | 22 23  0  | 24  0
7001     -------------------------------------
7002     Proc2  25 26 27  |  0  0 28  | 29  0
7003            30  0  0  | 31 32 33  |  0 34
7004 .ve
7005 
7006     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is
7007 
7008 .vb
7009             2  0  |  0  3  0  |  0
7010     Proc0   5  6  |  7  0  0  |  8
7011     -------------------------------
7012     Proc1  18  0  | 19 20 21  |  0
7013     -------------------------------
7014     Proc2  26 27  |  0  0 28  | 29
7015             0  0  | 31 32 33  |  0
7016 .ve
7017 
7018 
7019     Concepts: matrices^submatrices
7020 
7021 .seealso: MatGetSubMatrices()
7022 @*/
7023 PetscErrorCode  MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7024 {
7025   PetscErrorCode ierr;
7026   PetscMPIInt    size;
7027   Mat            *local;
7028   IS             iscoltmp;
7029 
7030   PetscFunctionBegin;
7031   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7032   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
7033   if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
7034   PetscValidPointer(newmat,5);
7035   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5);
7036   PetscValidType(mat,1);
7037   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7038   ierr = MatPreallocated(mat);CHKERRQ(ierr);
7039   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
7040 
7041   if (!iscol) {
7042     ierr = ISCreateStride(((PetscObject)mat)->comm,mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr);
7043   } else {
7044     iscoltmp = iscol;
7045   }
7046 
7047   /* if original matrix is on just one processor then use submatrix generated */
7048   if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7049     ierr = MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
7050     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7051     PetscFunctionReturn(0);
7052   } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) {
7053     ierr    = MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
7054     *newmat = *local;
7055     ierr    = PetscFree(local);CHKERRQ(ierr);
7056     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7057     PetscFunctionReturn(0);
7058   } else if (!mat->ops->getsubmatrix) {
7059     /* Create a new matrix type that implements the operation using the full matrix */
7060     switch (cll) {
7061       case MAT_INITIAL_MATRIX:
7062         ierr = MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr);
7063         break;
7064       case MAT_REUSE_MATRIX:
7065         ierr = MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr);
7066         break;
7067       default: SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7068     }
7069     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7070     PetscFunctionReturn(0);
7071   }
7072 
7073   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7074   ierr = (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr);
7075   if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7076   if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);}
7077   PetscFunctionReturn(0);
7078 }
7079 
7080 #undef __FUNCT__
7081 #define __FUNCT__ "MatStashSetInitialSize"
7082 /*@
7083    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7084    used during the assembly process to store values that belong to
7085    other processors.
7086 
7087    Not Collective
7088 
7089    Input Parameters:
7090 +  mat   - the matrix
7091 .  size  - the initial size of the stash.
7092 -  bsize - the initial size of the block-stash(if used).
7093 
7094    Options Database Keys:
7095 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
7096 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
7097 
7098    Level: intermediate
7099 
7100    Notes:
7101      The block-stash is used for values set with MatSetValuesBlocked() while
7102      the stash is used for values set with MatSetValues()
7103 
7104      Run with the option -info and look for output of the form
7105      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7106      to determine the appropriate value, MM, to use for size and
7107      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7108      to determine the value, BMM to use for bsize
7109 
7110    Concepts: stash^setting matrix size
7111    Concepts: matrices^stash
7112 
7113 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
7114 
7115 @*/
7116 PetscErrorCode  MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7117 {
7118   PetscErrorCode ierr;
7119 
7120   PetscFunctionBegin;
7121   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7122   PetscValidType(mat,1);
7123   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
7124   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
7125   PetscFunctionReturn(0);
7126 }
7127 
7128 #undef __FUNCT__
7129 #define __FUNCT__ "MatInterpolateAdd"
7130 /*@
7131    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
7132      the matrix
7133 
7134    Neighbor-wise Collective on Mat
7135 
7136    Input Parameters:
7137 +  mat   - the matrix
7138 .  x,y - the vectors
7139 -  w - where the result is stored
7140 
7141    Level: intermediate
7142 
7143    Notes:
7144     w may be the same vector as y.
7145 
7146     This allows one to use either the restriction or interpolation (its transpose)
7147     matrix to do the interpolation
7148 
7149     Concepts: interpolation
7150 
7151 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7152 
7153 @*/
7154 PetscErrorCode  MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7155 {
7156   PetscErrorCode ierr;
7157   PetscInt       M,N,Ny;
7158 
7159   PetscFunctionBegin;
7160   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7161   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7162   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7163   PetscValidHeaderSpecific(w,VEC_CLASSID,4);
7164   PetscValidType(A,1);
7165   ierr = MatPreallocated(A);CHKERRQ(ierr);
7166   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
7167   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
7168   if (M == Ny) {
7169     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
7170   } else {
7171     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
7172   }
7173   PetscFunctionReturn(0);
7174 }
7175 
7176 #undef __FUNCT__
7177 #define __FUNCT__ "MatInterpolate"
7178 /*@
7179    MatInterpolate - y = A*x or A'*x depending on the shape of
7180      the matrix
7181 
7182    Neighbor-wise Collective on Mat
7183 
7184    Input Parameters:
7185 +  mat   - the matrix
7186 -  x,y - the vectors
7187 
7188    Level: intermediate
7189 
7190    Notes:
7191     This allows one to use either the restriction or interpolation (its transpose)
7192     matrix to do the interpolation
7193 
7194    Concepts: matrices^interpolation
7195 
7196 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7197 
7198 @*/
7199 PetscErrorCode  MatInterpolate(Mat A,Vec x,Vec y)
7200 {
7201   PetscErrorCode ierr;
7202   PetscInt       M,N,Ny;
7203 
7204   PetscFunctionBegin;
7205   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7206   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7207   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7208   PetscValidType(A,1);
7209   ierr = MatPreallocated(A);CHKERRQ(ierr);
7210   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
7211   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
7212   if (M == Ny) {
7213     ierr = MatMult(A,x,y);CHKERRQ(ierr);
7214   } else {
7215     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
7216   }
7217   PetscFunctionReturn(0);
7218 }
7219 
7220 #undef __FUNCT__
7221 #define __FUNCT__ "MatRestrict"
7222 /*@
7223    MatRestrict - y = A*x or A'*x
7224 
7225    Neighbor-wise Collective on Mat
7226 
7227    Input Parameters:
7228 +  mat   - the matrix
7229 -  x,y - the vectors
7230 
7231    Level: intermediate
7232 
7233    Notes:
7234     This allows one to use either the restriction or interpolation (its transpose)
7235     matrix to do the restriction
7236 
7237    Concepts: matrices^restriction
7238 
7239 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
7240 
7241 @*/
7242 PetscErrorCode  MatRestrict(Mat A,Vec x,Vec y)
7243 {
7244   PetscErrorCode ierr;
7245   PetscInt       M,N,Ny;
7246 
7247   PetscFunctionBegin;
7248   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7249   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7250   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7251   PetscValidType(A,1);
7252   ierr = MatPreallocated(A);CHKERRQ(ierr);
7253 
7254   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
7255   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
7256   if (M == Ny) {
7257     ierr = MatMult(A,x,y);CHKERRQ(ierr);
7258   } else {
7259     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
7260   }
7261   PetscFunctionReturn(0);
7262 }
7263 
7264 #undef __FUNCT__
7265 #define __FUNCT__ "MatNullSpaceAttach"
7266 /*@
7267    MatNullSpaceAttach - attaches a null space to a matrix.
7268         This null space will be removed from the resulting vector whenever
7269         MatMult() is called
7270 
7271    Logically Collective on Mat and MatNullSpace
7272 
7273    Input Parameters:
7274 +  mat - the matrix
7275 -  nullsp - the null space object
7276 
7277    Level: developer
7278 
7279    Notes:
7280       Overwrites any previous null space that may have been attached
7281 
7282    Concepts: null space^attaching to matrix
7283 
7284 .seealso: MatCreate(), MatNullSpaceCreate()
7285 @*/
7286 PetscErrorCode  MatNullSpaceAttach(Mat mat,MatNullSpace nullsp)
7287 {
7288   PetscErrorCode ierr;
7289 
7290   PetscFunctionBegin;
7291   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7292   PetscValidType(mat,1);
7293   PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
7294   ierr = MatPreallocated(mat);CHKERRQ(ierr);
7295   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
7296   if (mat->nullsp) { ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr); }
7297   mat->nullsp = nullsp;
7298   PetscFunctionReturn(0);
7299 }
7300 
7301 #undef __FUNCT__
7302 #define __FUNCT__ "MatICCFactor"
7303 /*@C
7304    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
7305 
7306    Collective on Mat
7307 
7308    Input Parameters:
7309 +  mat - the matrix
7310 .  row - row/column permutation
7311 .  fill - expected fill factor >= 1.0
7312 -  level - level of fill, for ICC(k)
7313 
7314    Notes:
7315    Probably really in-place only when level of fill is zero, otherwise allocates
7316    new space to store factored matrix and deletes previous memory.
7317 
7318    Most users should employ the simplified KSP interface for linear solvers
7319    instead of working directly with matrix algebra routines such as this.
7320    See, e.g., KSPCreate().
7321 
7322    Level: developer
7323 
7324    Concepts: matrices^incomplete Cholesky factorization
7325    Concepts: Cholesky factorization
7326 
7327 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
7328 
7329     Developer Note: fortran interface is not autogenerated as the f90
7330     interface defintion cannot be generated correctly [due to MatFactorInfo]
7331 
7332 @*/
7333 PetscErrorCode  MatICCFactor(Mat mat,IS row,const MatFactorInfo* info)
7334 {
7335   PetscErrorCode ierr;
7336 
7337   PetscFunctionBegin;
7338   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7339   PetscValidType(mat,1);
7340   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
7341   PetscValidPointer(info,3);
7342   if (mat->rmap->N != mat->cmap->N) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONG,"matrix must be square");
7343   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7344   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7345   if (!mat->ops->iccfactor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7346   ierr = MatPreallocated(mat);CHKERRQ(ierr);
7347   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
7348   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
7349   PetscFunctionReturn(0);
7350 }
7351 
7352 #undef __FUNCT__
7353 #define __FUNCT__ "MatSetValuesAdic"
7354 /*@
7355    MatSetValuesAdic - Sets values computed with ADIC automatic differentiation into a matrix.
7356 
7357    Not Collective
7358 
7359    Input Parameters:
7360 +  mat - the matrix
7361 -  v - the values compute with ADIC
7362 
7363    Level: developer
7364 
7365    Notes:
7366      Must call MatSetColoring() before using this routine. Also this matrix must already
7367      have its nonzero pattern determined.
7368 
7369 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7370           MatSetValues(), MatSetColoring(), MatSetValuesAdifor()
7371 @*/
7372 PetscErrorCode  MatSetValuesAdic(Mat mat,void *v)
7373 {
7374   PetscErrorCode ierr;
7375 
7376   PetscFunctionBegin;
7377   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7378   PetscValidType(mat,1);
7379   PetscValidPointer(mat,2);
7380 
7381   if (!mat->assembled) {
7382     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7383   }
7384   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
7385   if (!mat->ops->setvaluesadic) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7386   ierr = (*mat->ops->setvaluesadic)(mat,v);CHKERRQ(ierr);
7387   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
7388   ierr = MatView_Private(mat);CHKERRQ(ierr);
7389   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
7390   PetscFunctionReturn(0);
7391 }
7392 
7393 
7394 #undef __FUNCT__
7395 #define __FUNCT__ "MatSetColoring"
7396 /*@
7397    MatSetColoring - Sets a coloring used by calls to MatSetValuesAdic()
7398 
7399    Not Collective
7400 
7401    Input Parameters:
7402 +  mat - the matrix
7403 -  coloring - the coloring
7404 
7405    Level: developer
7406 
7407 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7408           MatSetValues(), MatSetValuesAdic()
7409 @*/
7410 PetscErrorCode  MatSetColoring(Mat mat,ISColoring coloring)
7411 {
7412   PetscErrorCode ierr;
7413 
7414   PetscFunctionBegin;
7415   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7416   PetscValidType(mat,1);
7417   PetscValidPointer(coloring,2);
7418 
7419   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7420   if (!mat->ops->setcoloring) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7421   ierr = (*mat->ops->setcoloring)(mat,coloring);CHKERRQ(ierr);
7422   PetscFunctionReturn(0);
7423 }
7424 
7425 #undef __FUNCT__
7426 #define __FUNCT__ "MatSetValuesAdifor"
7427 /*@
7428    MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.
7429 
7430    Not Collective
7431 
7432    Input Parameters:
7433 +  mat - the matrix
7434 .  nl - leading dimension of v
7435 -  v - the values compute with ADIFOR
7436 
7437    Level: developer
7438 
7439    Notes:
7440      Must call MatSetColoring() before using this routine. Also this matrix must already
7441      have its nonzero pattern determined.
7442 
7443 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7444           MatSetValues(), MatSetColoring()
7445 @*/
7446 PetscErrorCode  MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
7447 {
7448   PetscErrorCode ierr;
7449 
7450   PetscFunctionBegin;
7451   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7452   PetscValidType(mat,1);
7453   PetscValidPointer(v,3);
7454 
7455   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7456   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
7457   if (!mat->ops->setvaluesadifor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7458   ierr = (*mat->ops->setvaluesadifor)(mat,nl,v);CHKERRQ(ierr);
7459   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
7460   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
7461   PetscFunctionReturn(0);
7462 }
7463 
7464 #undef __FUNCT__
7465 #define __FUNCT__ "MatDiagonalScaleLocal"
7466 /*@
7467    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
7468          ghosted ones.
7469 
7470    Not Collective
7471 
7472    Input Parameters:
7473 +  mat - the matrix
7474 -  diag = the diagonal values, including ghost ones
7475 
7476    Level: developer
7477 
7478    Notes: Works only for MPIAIJ and MPIBAIJ matrices
7479 
7480 .seealso: MatDiagonalScale()
7481 @*/
7482 PetscErrorCode  MatDiagonalScaleLocal(Mat mat,Vec diag)
7483 {
7484   PetscErrorCode ierr;
7485   PetscMPIInt    size;
7486 
7487   PetscFunctionBegin;
7488   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7489   PetscValidHeaderSpecific(diag,VEC_CLASSID,2);
7490   PetscValidType(mat,1);
7491 
7492   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7493   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
7494   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
7495   if (size == 1) {
7496     PetscInt n,m;
7497     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
7498     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
7499     if (m == n) {
7500       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
7501     } else {
7502       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
7503     }
7504   } else {
7505     ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr);
7506   }
7507   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
7508   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
7509   PetscFunctionReturn(0);
7510 }
7511 
7512 #undef __FUNCT__
7513 #define __FUNCT__ "MatGetInertia"
7514 /*@
7515    MatGetInertia - Gets the inertia from a factored matrix
7516 
7517    Collective on Mat
7518 
7519    Input Parameter:
7520 .  mat - the matrix
7521 
7522    Output Parameters:
7523 +   nneg - number of negative eigenvalues
7524 .   nzero - number of zero eigenvalues
7525 -   npos - number of positive eigenvalues
7526 
7527    Level: advanced
7528 
7529    Notes: Matrix must have been factored by MatCholeskyFactor()
7530 
7531 
7532 @*/
7533 PetscErrorCode  MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
7534 {
7535   PetscErrorCode ierr;
7536 
7537   PetscFunctionBegin;
7538   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7539   PetscValidType(mat,1);
7540   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7541   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
7542   if (!mat->ops->getinertia) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7543   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
7544   PetscFunctionReturn(0);
7545 }
7546 
7547 /* ----------------------------------------------------------------*/
7548 #undef __FUNCT__
7549 #define __FUNCT__ "MatSolves"
7550 /*@C
7551    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
7552 
7553    Neighbor-wise Collective on Mat and Vecs
7554 
7555    Input Parameters:
7556 +  mat - the factored matrix
7557 -  b - the right-hand-side vectors
7558 
7559    Output Parameter:
7560 .  x - the result vectors
7561 
7562    Notes:
7563    The vectors b and x cannot be the same.  I.e., one cannot
7564    call MatSolves(A,x,x).
7565 
7566    Notes:
7567    Most users should employ the simplified KSP interface for linear solvers
7568    instead of working directly with matrix algebra routines such as this.
7569    See, e.g., KSPCreate().
7570 
7571    Level: developer
7572 
7573    Concepts: matrices^triangular solves
7574 
7575 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
7576 @*/
7577 PetscErrorCode  MatSolves(Mat mat,Vecs b,Vecs x)
7578 {
7579   PetscErrorCode ierr;
7580 
7581   PetscFunctionBegin;
7582   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7583   PetscValidType(mat,1);
7584   if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
7585   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7586   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
7587 
7588   if (!mat->ops->solves) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7589   ierr = MatPreallocated(mat);CHKERRQ(ierr);
7590   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
7591   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
7592   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
7593   PetscFunctionReturn(0);
7594 }
7595 
7596 #undef __FUNCT__
7597 #define __FUNCT__ "MatIsSymmetric"
7598 /*@
7599    MatIsSymmetric - Test whether a matrix is symmetric
7600 
7601    Collective on Mat
7602 
7603    Input Parameter:
7604 +  A - the matrix to test
7605 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
7606 
7607    Output Parameters:
7608 .  flg - the result
7609 
7610    Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
7611 
7612    Level: intermediate
7613 
7614    Concepts: matrix^symmetry
7615 
7616 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
7617 @*/
7618 PetscErrorCode  MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
7619 {
7620   PetscErrorCode ierr;
7621 
7622   PetscFunctionBegin;
7623   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7624   PetscValidPointer(flg,2);
7625 
7626   if (!A->symmetric_set) {
7627     if (!A->ops->issymmetric) {
7628       const MatType mattype;
7629       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7630       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7631     }
7632     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
7633     if (!tol) {
7634       A->symmetric_set = PETSC_TRUE;
7635       A->symmetric = *flg;
7636       if (A->symmetric) {
7637 	A->structurally_symmetric_set = PETSC_TRUE;
7638 	A->structurally_symmetric     = PETSC_TRUE;
7639       }
7640     }
7641   } else if (A->symmetric) {
7642     *flg = PETSC_TRUE;
7643   } else if (!tol) {
7644     *flg = PETSC_FALSE;
7645   } else {
7646     if (!A->ops->issymmetric) {
7647       const MatType mattype;
7648       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7649       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7650     }
7651     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
7652   }
7653   PetscFunctionReturn(0);
7654 }
7655 
7656 #undef __FUNCT__
7657 #define __FUNCT__ "MatIsHermitian"
7658 /*@
7659    MatIsHermitian - Test whether a matrix is Hermitian
7660 
7661    Collective on Mat
7662 
7663    Input Parameter:
7664 +  A - the matrix to test
7665 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
7666 
7667    Output Parameters:
7668 .  flg - the result
7669 
7670    Level: intermediate
7671 
7672    Concepts: matrix^symmetry
7673 
7674 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
7675           MatIsSymmetricKnown(), MatIsSymmetric()
7676 @*/
7677 PetscErrorCode  MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
7678 {
7679   PetscErrorCode ierr;
7680 
7681   PetscFunctionBegin;
7682   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7683   PetscValidPointer(flg,2);
7684 
7685   if (!A->hermitian_set) {
7686     if (!A->ops->ishermitian) {
7687       const MatType mattype;
7688       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7689       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7690     }
7691     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
7692     if (!tol) {
7693       A->hermitian_set = PETSC_TRUE;
7694       A->hermitian = *flg;
7695       if (A->hermitian) {
7696 	A->structurally_symmetric_set = PETSC_TRUE;
7697 	A->structurally_symmetric     = PETSC_TRUE;
7698       }
7699     }
7700   } else if (A->hermitian) {
7701     *flg = PETSC_TRUE;
7702   } else if (!tol) {
7703     *flg = PETSC_FALSE;
7704   } else {
7705     if (!A->ops->ishermitian) {
7706       const MatType mattype;
7707       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7708       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7709     }
7710     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
7711   }
7712   PetscFunctionReturn(0);
7713 }
7714 
7715 #undef __FUNCT__
7716 #define __FUNCT__ "MatIsSymmetricKnown"
7717 /*@
7718    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
7719 
7720    Not Collective
7721 
7722    Input Parameter:
7723 .  A - the matrix to check
7724 
7725    Output Parameters:
7726 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
7727 -  flg - the result
7728 
7729    Level: advanced
7730 
7731    Concepts: matrix^symmetry
7732 
7733    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
7734          if you want it explicitly checked
7735 
7736 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
7737 @*/
7738 PetscErrorCode  MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
7739 {
7740   PetscFunctionBegin;
7741   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7742   PetscValidPointer(set,2);
7743   PetscValidPointer(flg,3);
7744   if (A->symmetric_set) {
7745     *set = PETSC_TRUE;
7746     *flg = A->symmetric;
7747   } else {
7748     *set = PETSC_FALSE;
7749   }
7750   PetscFunctionReturn(0);
7751 }
7752 
7753 #undef __FUNCT__
7754 #define __FUNCT__ "MatIsHermitianKnown"
7755 /*@
7756    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
7757 
7758    Not Collective
7759 
7760    Input Parameter:
7761 .  A - the matrix to check
7762 
7763    Output Parameters:
7764 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
7765 -  flg - the result
7766 
7767    Level: advanced
7768 
7769    Concepts: matrix^symmetry
7770 
7771    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
7772          if you want it explicitly checked
7773 
7774 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
7775 @*/
7776 PetscErrorCode  MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
7777 {
7778   PetscFunctionBegin;
7779   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7780   PetscValidPointer(set,2);
7781   PetscValidPointer(flg,3);
7782   if (A->hermitian_set) {
7783     *set = PETSC_TRUE;
7784     *flg = A->hermitian;
7785   } else {
7786     *set = PETSC_FALSE;
7787   }
7788   PetscFunctionReturn(0);
7789 }
7790 
7791 #undef __FUNCT__
7792 #define __FUNCT__ "MatIsStructurallySymmetric"
7793 /*@
7794    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
7795 
7796    Collective on Mat
7797 
7798    Input Parameter:
7799 .  A - the matrix to test
7800 
7801    Output Parameters:
7802 .  flg - the result
7803 
7804    Level: intermediate
7805 
7806    Concepts: matrix^symmetry
7807 
7808 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
7809 @*/
7810 PetscErrorCode  MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
7811 {
7812   PetscErrorCode ierr;
7813 
7814   PetscFunctionBegin;
7815   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7816   PetscValidPointer(flg,2);
7817   if (!A->structurally_symmetric_set) {
7818     if (!A->ops->isstructurallysymmetric) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
7819     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
7820     A->structurally_symmetric_set = PETSC_TRUE;
7821   }
7822   *flg = A->structurally_symmetric;
7823   PetscFunctionReturn(0);
7824 }
7825 
7826 #undef __FUNCT__
7827 #define __FUNCT__ "MatStashGetInfo"
7828 extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
7829 /*@
7830    MatStashGetInfo - Gets how many values are currently in the vector stash, i.e. need
7831        to be communicated to other processors during the MatAssemblyBegin/End() process
7832 
7833     Not collective
7834 
7835    Input Parameter:
7836 .   vec - the vector
7837 
7838    Output Parameters:
7839 +   nstash   - the size of the stash
7840 .   reallocs - the number of additional mallocs incurred.
7841 .   bnstash   - the size of the block stash
7842 -   breallocs - the number of additional mallocs incurred.in the block stash
7843 
7844    Level: advanced
7845 
7846 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
7847 
7848 @*/
7849 PetscErrorCode  MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
7850 {
7851   PetscErrorCode ierr;
7852   PetscFunctionBegin;
7853   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
7854   ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
7855   PetscFunctionReturn(0);
7856 }
7857 
7858 #undef __FUNCT__
7859 #define __FUNCT__ "MatGetVecs"
7860 /*@C
7861    MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same
7862      parallel layout
7863 
7864    Collective on Mat
7865 
7866    Input Parameter:
7867 .  mat - the matrix
7868 
7869    Output Parameter:
7870 +   right - (optional) vector that the matrix can be multiplied against
7871 -   left - (optional) vector that the matrix vector product can be stored in
7872 
7873   Level: advanced
7874 
7875 .seealso: MatCreate()
7876 @*/
7877 PetscErrorCode  MatGetVecs(Mat mat,Vec *right,Vec *left)
7878 {
7879   PetscErrorCode ierr;
7880 
7881   PetscFunctionBegin;
7882   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7883   PetscValidType(mat,1);
7884   ierr = MatPreallocated(mat);CHKERRQ(ierr);
7885   if (mat->ops->getvecs) {
7886     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
7887   } else {
7888     PetscMPIInt size;
7889     ierr = MPI_Comm_size(((PetscObject)mat)->comm, &size);CHKERRQ(ierr);
7890     if (right) {
7891       ierr = VecCreate(((PetscObject)mat)->comm,right);CHKERRQ(ierr);
7892       ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
7893       ierr = VecSetBlockSize(*right,mat->rmap->bs);CHKERRQ(ierr);
7894       ierr = VecSetType(*right,VECSTANDARD);CHKERRQ(ierr);
7895       ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr);
7896     }
7897     if (left) {
7898       ierr = VecCreate(((PetscObject)mat)->comm,left);CHKERRQ(ierr);
7899       ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
7900       ierr = VecSetBlockSize(*left,mat->rmap->bs);CHKERRQ(ierr);
7901       ierr = VecSetType(*left,VECSTANDARD);CHKERRQ(ierr);
7902       ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr);
7903     }
7904   }
7905   PetscFunctionReturn(0);
7906 }
7907 
7908 #undef __FUNCT__
7909 #define __FUNCT__ "MatFactorInfoInitialize"
7910 /*@C
7911    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
7912      with default values.
7913 
7914    Not Collective
7915 
7916    Input Parameters:
7917 .    info - the MatFactorInfo data structure
7918 
7919 
7920    Notes: The solvers are generally used through the KSP and PC objects, for example
7921           PCLU, PCILU, PCCHOLESKY, PCICC
7922 
7923    Level: developer
7924 
7925 .seealso: MatFactorInfo
7926 
7927     Developer Note: fortran interface is not autogenerated as the f90
7928     interface defintion cannot be generated correctly [due to MatFactorInfo]
7929 
7930 @*/
7931 
7932 PetscErrorCode  MatFactorInfoInitialize(MatFactorInfo *info)
7933 {
7934   PetscErrorCode ierr;
7935 
7936   PetscFunctionBegin;
7937   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
7938   PetscFunctionReturn(0);
7939 }
7940 
7941 #undef __FUNCT__
7942 #define __FUNCT__ "MatPtAP"
7943 /*@
7944    MatPtAP - Creates the matrix product C = P^T * A * P
7945 
7946    Neighbor-wise Collective on Mat
7947 
7948    Input Parameters:
7949 +  A - the matrix
7950 .  P - the projection matrix
7951 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7952 -  fill - expected fill as ratio of nnz(C)/nnz(A)
7953 
7954    Output Parameters:
7955 .  C - the product matrix
7956 
7957    Notes:
7958    C will be created and must be destroyed by the user with MatDestroy().
7959 
7960    This routine is currently only implemented for pairs of AIJ matrices and classes
7961    which inherit from AIJ.
7962 
7963    Level: intermediate
7964 
7965 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult()
7966 @*/
7967 PetscErrorCode  MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
7968 {
7969   PetscErrorCode ierr;
7970 
7971   PetscFunctionBegin;
7972   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7973   PetscValidType(A,1);
7974   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7975   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7976   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
7977   PetscValidType(P,2);
7978   ierr = MatPreallocated(P);CHKERRQ(ierr);
7979   if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7980   if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7981   PetscValidPointer(C,3);
7982   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);
7983   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
7984   ierr = MatPreallocated(A);CHKERRQ(ierr);
7985 
7986   if (!A->ops->ptap) {
7987     const MatType mattype;
7988     ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7989     SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix of type <%s> does not support PtAP",mattype);
7990   }
7991   ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
7992   ierr = (*A->ops->ptap)(A,P,scall,fill,C);CHKERRQ(ierr);
7993   ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
7994 
7995   PetscFunctionReturn(0);
7996 }
7997 
7998 #undef __FUNCT__
7999 #define __FUNCT__ "MatPtAPNumeric"
8000 /*@
8001    MatPtAPNumeric - Computes the matrix product C = P^T * A * P
8002 
8003    Neighbor-wise Collective on Mat
8004 
8005    Input Parameters:
8006 +  A - the matrix
8007 -  P - the projection matrix
8008 
8009    Output Parameters:
8010 .  C - the product matrix
8011 
8012    Notes:
8013    C must have been created by calling MatPtAPSymbolic and must be destroyed by
8014    the user using MatDeatroy().
8015 
8016    This routine is currently only implemented for pairs of AIJ matrices and classes
8017    which inherit from AIJ.  C will be of type MATAIJ.
8018 
8019    Level: intermediate
8020 
8021 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
8022 @*/
8023 PetscErrorCode  MatPtAPNumeric(Mat A,Mat P,Mat C)
8024 {
8025   PetscErrorCode ierr;
8026 
8027   PetscFunctionBegin;
8028   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8029   PetscValidType(A,1);
8030   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8031   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8032   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
8033   PetscValidType(P,2);
8034   ierr = MatPreallocated(P);CHKERRQ(ierr);
8035   if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8036   if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8037   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
8038   PetscValidType(C,3);
8039   ierr = MatPreallocated(C);CHKERRQ(ierr);
8040   if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8041   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);
8042   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);
8043   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);
8044   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);
8045   ierr = MatPreallocated(A);CHKERRQ(ierr);
8046 
8047   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
8048   ierr = (*A->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr);
8049   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
8050   PetscFunctionReturn(0);
8051 }
8052 
8053 #undef __FUNCT__
8054 #define __FUNCT__ "MatPtAPSymbolic"
8055 /*@
8056    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P
8057 
8058    Neighbor-wise Collective on Mat
8059 
8060    Input Parameters:
8061 +  A - the matrix
8062 -  P - the projection matrix
8063 
8064    Output Parameters:
8065 .  C - the (i,j) structure of the product matrix
8066 
8067    Notes:
8068    C will be created and must be destroyed by the user with MatDestroy().
8069 
8070    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
8071    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
8072    this (i,j) structure by calling MatPtAPNumeric().
8073 
8074    Level: intermediate
8075 
8076 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
8077 @*/
8078 PetscErrorCode  MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
8079 {
8080   PetscErrorCode ierr;
8081 
8082   PetscFunctionBegin;
8083   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8084   PetscValidType(A,1);
8085   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8086   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8087   if (fill <1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8088   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
8089   PetscValidType(P,2);
8090   ierr = MatPreallocated(P);CHKERRQ(ierr);
8091   if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8092   if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8093   PetscValidPointer(C,3);
8094 
8095   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);
8096   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);
8097   ierr = MatPreallocated(A);CHKERRQ(ierr);
8098   ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
8099   ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr);
8100   ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
8101 
8102   ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr);
8103 
8104   PetscFunctionReturn(0);
8105 }
8106 
8107 #undef __FUNCT__
8108 #define __FUNCT__ "MatMatMult"
8109 /*@
8110    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
8111 
8112    Neighbor-wise Collective on Mat
8113 
8114    Input Parameters:
8115 +  A - the left matrix
8116 .  B - the right matrix
8117 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8118 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
8119           if the result is a dense matrix this is irrelevent
8120 
8121    Output Parameters:
8122 .  C - the product matrix
8123 
8124    Notes:
8125    Unless scall is MAT_REUSE_MATRIX C will be created.
8126 
8127    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8128 
8129    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8130    actually needed.
8131 
8132    If you have many matrices with the same non-zero structure to multiply, you
8133    should either
8134 $   1) use MAT_REUSE_MATRIX in all calls but the first or
8135 $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
8136 
8137    Level: intermediate
8138 
8139 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatPtAP()
8140 @*/
8141 PetscErrorCode  MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8142 {
8143   PetscErrorCode ierr;
8144   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8145   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8146   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat *)=PETSC_NULL;
8147 
8148   PetscFunctionBegin;
8149   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8150   PetscValidType(A,1);
8151   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8152   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8153   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8154   PetscValidType(B,2);
8155   ierr = MatPreallocated(B);CHKERRQ(ierr);
8156   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8157   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8158   PetscValidPointer(C,3);
8159   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);
8160   if (scall == MAT_REUSE_MATRIX){
8161     PetscValidPointer(*C,5);
8162     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
8163   }
8164   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8165   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8166   ierr = MatPreallocated(A);CHKERRQ(ierr);
8167 
8168   fA = A->ops->matmult;
8169   fB = B->ops->matmult;
8170   if (fB == fA) {
8171     if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
8172     mult = fB;
8173   } else {
8174     /* dispatch based on the type of A and B */
8175     char  multname[256];
8176     ierr = PetscStrcpy(multname,"MatMatMult_");CHKERRQ(ierr);
8177     ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr);
8178     ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);
8179     ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr);
8180     ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
8181     ierr = PetscObjectQueryFunction((PetscObject)B,multname,(void (**)(void))&mult);CHKERRQ(ierr);
8182     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);
8183   }
8184   ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
8185   ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr);
8186   ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
8187   PetscFunctionReturn(0);
8188 }
8189 
8190 #undef __FUNCT__
8191 #define __FUNCT__ "MatMatMultSymbolic"
8192 /*@
8193    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
8194    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().
8195 
8196    Neighbor-wise Collective on Mat
8197 
8198    Input Parameters:
8199 +  A - the left matrix
8200 .  B - the right matrix
8201 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
8202       if C is a dense matrix this is irrelevent
8203 
8204    Output Parameters:
8205 .  C - the product matrix
8206 
8207    Notes:
8208    Unless scall is MAT_REUSE_MATRIX C will be created.
8209 
8210    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8211    actually needed.
8212 
8213    This routine is currently implemented for
8214     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
8215     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8216     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
8217 
8218    Level: intermediate
8219 
8220    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
8221      We should incorporate them into PETSc.
8222 
8223 .seealso: MatMatMult(), MatMatMultNumeric()
8224 @*/
8225 PetscErrorCode  MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
8226 {
8227   PetscErrorCode ierr;
8228   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat *);
8229   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat *);
8230   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat *)=PETSC_NULL;
8231 
8232   PetscFunctionBegin;
8233   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8234   PetscValidType(A,1);
8235   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8236   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8237 
8238   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8239   PetscValidType(B,2);
8240   ierr = MatPreallocated(B);CHKERRQ(ierr);
8241   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8242   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8243   PetscValidPointer(C,3);
8244 
8245   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);
8246   if (fill == PETSC_DEFAULT) fill = 2.0;
8247   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8248   ierr = MatPreallocated(A);CHKERRQ(ierr);
8249 
8250   Asymbolic = A->ops->matmultsymbolic;
8251   Bsymbolic = B->ops->matmultsymbolic;
8252   if (Asymbolic == Bsymbolic){
8253     if (!Bsymbolic) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
8254     symbolic = Bsymbolic;
8255   } else { /* dispatch based on the type of A and B */
8256     char  symbolicname[256];
8257     ierr = PetscStrcpy(symbolicname,"MatMatMultSymbolic_");CHKERRQ(ierr);
8258     ierr = PetscStrcat(symbolicname,((PetscObject)A)->type_name);CHKERRQ(ierr);
8259     ierr = PetscStrcat(symbolicname,"_");CHKERRQ(ierr);
8260     ierr = PetscStrcat(symbolicname,((PetscObject)B)->type_name);CHKERRQ(ierr);
8261     ierr = PetscStrcat(symbolicname,"_C");CHKERRQ(ierr);
8262     ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,(void (**)(void))&symbolic);CHKERRQ(ierr);
8263     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);
8264   }
8265   ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
8266   ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr);
8267   ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
8268   PetscFunctionReturn(0);
8269 }
8270 
8271 #undef __FUNCT__
8272 #define __FUNCT__ "MatMatMultNumeric"
8273 /*@
8274    MatMatMultNumeric - Performs the numeric matrix-matrix product.
8275    Call this routine after first calling MatMatMultSymbolic().
8276 
8277    Neighbor-wise Collective on Mat
8278 
8279    Input Parameters:
8280 +  A - the left matrix
8281 -  B - the right matrix
8282 
8283    Output Parameters:
8284 .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
8285 
8286    Notes:
8287    C must have been created with MatMatMultSymbolic().
8288 
8289    This routine is currently implemented for
8290     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
8291     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8292     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
8293 
8294    Level: intermediate
8295 
8296 .seealso: MatMatMult(), MatMatMultSymbolic()
8297 @*/
8298 PetscErrorCode  MatMatMultNumeric(Mat A,Mat B,Mat C)
8299 {
8300   PetscErrorCode ierr;
8301   PetscErrorCode (*Anumeric)(Mat,Mat,Mat);
8302   PetscErrorCode (*Bnumeric)(Mat,Mat,Mat);
8303   PetscErrorCode (*numeric)(Mat,Mat,Mat)=PETSC_NULL;
8304 
8305   PetscFunctionBegin;
8306   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8307   PetscValidType(A,1);
8308   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8309   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8310 
8311   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8312   PetscValidType(B,2);
8313   ierr = MatPreallocated(B);CHKERRQ(ierr);
8314   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8315   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8316 
8317   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
8318   PetscValidType(C,3);
8319   ierr = MatPreallocated(C);CHKERRQ(ierr);
8320   if (!C->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8321   if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8322 
8323   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);
8324   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);
8325   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);
8326   ierr = MatPreallocated(A);CHKERRQ(ierr);
8327 
8328   Anumeric = A->ops->matmultnumeric;
8329   Bnumeric = B->ops->matmultnumeric;
8330   if (Anumeric == Bnumeric){
8331     if (!Bnumeric) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMultNumeric not supported for B of type %s",((PetscObject)B)->type_name);
8332     numeric = Bnumeric;
8333   } else {
8334     char  numericname[256];
8335     ierr = PetscStrcpy(numericname,"MatMatMultNumeric_");CHKERRQ(ierr);
8336     ierr = PetscStrcat(numericname,((PetscObject)A)->type_name);CHKERRQ(ierr);
8337     ierr = PetscStrcat(numericname,"_");CHKERRQ(ierr);
8338     ierr = PetscStrcat(numericname,((PetscObject)B)->type_name);CHKERRQ(ierr);
8339     ierr = PetscStrcat(numericname,"_C");CHKERRQ(ierr);
8340     ierr = PetscObjectQueryFunction((PetscObject)B,numericname,(void (**)(void))&numeric);CHKERRQ(ierr);
8341     if (!numeric)
8342       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);
8343   }
8344   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
8345   ierr = (*numeric)(A,B,C);CHKERRQ(ierr);
8346   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
8347   PetscFunctionReturn(0);
8348 }
8349 
8350 #undef __FUNCT__
8351 #define __FUNCT__ "MatMatMultTranspose"
8352 /*@
8353    MatMatMultTranspose - Performs Matrix-Matrix Multiplication C=A^T*B.
8354 
8355    Neighbor-wise Collective on Mat
8356 
8357    Input Parameters:
8358 +  A - the left matrix
8359 .  B - the right matrix
8360 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8361 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
8362 
8363    Output Parameters:
8364 .  C - the product matrix
8365 
8366    Notes:
8367    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
8368 
8369    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8370 
8371   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8372    actually needed.
8373 
8374    This routine is currently only implemented for pairs of SeqAIJ matrices and pairs of SeqDense matrices and classes
8375    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.
8376 
8377    Level: intermediate
8378 
8379 .seealso: MatMatMultTransposeSymbolic(), MatMatMultTransposeNumeric(), MatPtAP()
8380 @*/
8381 PetscErrorCode  MatMatMultTranspose(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8382 {
8383   PetscErrorCode ierr;
8384   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8385   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8386 
8387   PetscFunctionBegin;
8388   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8389   PetscValidType(A,1);
8390   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8391   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8392   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8393   PetscValidType(B,2);
8394   ierr = MatPreallocated(B);CHKERRQ(ierr);
8395   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8396   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8397   PetscValidPointer(C,3);
8398   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);
8399   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8400   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8401   ierr = MatPreallocated(A);CHKERRQ(ierr);
8402 
8403   fA = A->ops->matmulttranspose;
8404   if (!fA) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMultTranspose not supported for A of type %s",((PetscObject)A)->type_name);
8405   fB = B->ops->matmulttranspose;
8406   if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMultTranspose not supported for B of type %s",((PetscObject)B)->type_name);
8407   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);
8408 
8409   ierr = PetscLogEventBegin(MAT_MatMultTranspose,A,B,0,0);CHKERRQ(ierr);
8410   ierr = (*A->ops->matmulttranspose)(A,B,scall,fill,C);CHKERRQ(ierr);
8411   ierr = PetscLogEventEnd(MAT_MatMultTranspose,A,B,0,0);CHKERRQ(ierr);
8412 
8413   PetscFunctionReturn(0);
8414 }
8415 
8416 #undef __FUNCT__
8417 #define __FUNCT__ "MatGetRedundantMatrix"
8418 /*@C
8419    MatGetRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
8420 
8421    Collective on Mat
8422 
8423    Input Parameters:
8424 +  mat - the matrix
8425 .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
8426 .  subcomm - MPI communicator split from the communicator where mat resides in
8427 .  mlocal_red - number of local rows of the redundant matrix
8428 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8429 
8430    Output Parameter:
8431 .  matredundant - redundant matrix
8432 
8433    Notes:
8434    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
8435    original matrix has not changed from that last call to MatGetRedundantMatrix().
8436 
8437    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
8438    calling it.
8439 
8440    Only MPIAIJ matrix is supported.
8441 
8442    Level: advanced
8443 
8444    Concepts: subcommunicator
8445    Concepts: duplicate matrix
8446 
8447 .seealso: MatDestroy()
8448 @*/
8449 PetscErrorCode  MatGetRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,PetscInt mlocal_red,MatReuse reuse,Mat *matredundant)
8450 {
8451   PetscErrorCode ierr;
8452 
8453   PetscFunctionBegin;
8454   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8455   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
8456     PetscValidPointer(*matredundant,6);
8457     PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,6);
8458   }
8459   if (!mat->ops->getredundantmatrix) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8460   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8461   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8462   ierr = MatPreallocated(mat);CHKERRQ(ierr);
8463 
8464   ierr = PetscLogEventBegin(MAT_GetRedundantMatrix,mat,0,0,0);CHKERRQ(ierr);
8465   ierr = (*mat->ops->getredundantmatrix)(mat,nsubcomm,subcomm,mlocal_red,reuse,matredundant);CHKERRQ(ierr);
8466   ierr = PetscLogEventEnd(MAT_GetRedundantMatrix,mat,0,0,0);CHKERRQ(ierr);
8467   PetscFunctionReturn(0);
8468 }
8469 
8470 #undef __FUNCT__
8471 #define __FUNCT__ "MatGetMultiProcBlock"
8472 /*@C
8473    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
8474    a given 'mat' object. Each submatrix can span multiple procs.
8475 
8476    Collective on Mat
8477 
8478    Input Parameters:
8479 +  mat - the matrix
8480 -  subcomm - the subcommunicator obtained by com_split(comm)
8481 
8482    Output Parameter:
8483 .  subMat - 'parallel submatrices each spans a given subcomm
8484 
8485   Notes:
8486   The submatrix partition across processors is dicated by 'subComm' a
8487   communicator obtained by com_split(comm). The comm_split
8488   is not restriced to be grouped with consequitive original ranks.
8489 
8490   Due the comm_split() usage, the parallel layout of the submatrices
8491   map directly to the layout of the original matrix [wrt the local
8492   row,col partitioning]. So the original 'DiagonalMat' naturally maps
8493   into the 'DiagonalMat' of the subMat, hence it is used directly from
8494   the subMat. However the offDiagMat looses some columns - and this is
8495   reconstructed with MatSetValues()
8496 
8497   Level: advanced
8498 
8499   Concepts: subcommunicator
8500   Concepts: submatrices
8501 
8502 .seealso: MatGetSubMatrices()
8503 @*/
8504 PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, Mat* subMat)
8505 {
8506   PetscErrorCode ierr;
8507   PetscMPIInt    commsize,subCommSize;
8508 
8509   PetscFunctionBegin;
8510   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&commsize);CHKERRQ(ierr);
8511   ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr);
8512   if (subCommSize > commsize) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
8513 
8514   ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
8515   ierr = (*mat->ops->getmultiprocblock)(mat,subComm,subMat);CHKERRQ(ierr);
8516   ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
8517   PetscFunctionReturn(0);
8518 }
8519 
8520 #undef __FUNCT__
8521 #define __FUNCT__ "MatGetLocalSubMatrix"
8522 /*@
8523    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
8524 
8525    Not Collective
8526 
8527    Input Arguments:
8528    mat - matrix to extract local submatrix from
8529    isrow - local row indices for submatrix
8530    iscol - local column indices for submatrix
8531 
8532    Output Arguments:
8533    submat - the submatrix
8534 
8535    Level: intermediate
8536 
8537    Notes:
8538    The submat should be returned with MatRestoreLocalSubMatrix().
8539 
8540    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
8541    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
8542 
8543    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
8544    MatSetValuesBlockedLocal() will also be implemented.
8545 
8546 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef()
8547 @*/
8548 PetscErrorCode  MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
8549 {
8550   PetscErrorCode ierr;
8551 
8552   PetscFunctionBegin;
8553   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8554   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
8555   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
8556   PetscCheckSameComm(isrow,2,iscol,3);
8557   PetscValidPointer(submat,4);
8558 
8559   if (mat->ops->getlocalsubmatrix) {
8560     ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
8561   } else {
8562     ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr);
8563   }
8564   PetscFunctionReturn(0);
8565 }
8566 
8567 #undef __FUNCT__
8568 #define __FUNCT__ "MatRestoreLocalSubMatrix"
8569 /*@
8570    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
8571 
8572    Not Collective
8573 
8574    Input Arguments:
8575    mat - matrix to extract local submatrix from
8576    isrow - local row indices for submatrix
8577    iscol - local column indices for submatrix
8578    submat - the submatrix
8579 
8580    Level: intermediate
8581 
8582 .seealso: MatGetLocalSubMatrix()
8583 @*/
8584 PetscErrorCode  MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
8585 {
8586   PetscErrorCode ierr;
8587 
8588   PetscFunctionBegin;
8589   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8590   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
8591   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
8592   PetscCheckSameComm(isrow,2,iscol,3);
8593   PetscValidPointer(submat,4);
8594   if (*submat) {PetscValidHeaderSpecific(*submat,MAT_CLASSID,4);}
8595 
8596   if (mat->ops->restorelocalsubmatrix) {
8597     ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
8598   } else {
8599     ierr = MatDestroy(submat);CHKERRQ(ierr);
8600   }
8601   *submat = PETSC_NULL;
8602   PetscFunctionReturn(0);
8603 }
8604 
8605 /* --------------------------------------------------------*/
8606 #undef __FUNCT__
8607 #define __FUNCT__ "MatFindZeroDiagonals"
8608 /*@
8609    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no entry in the matrix
8610 
8611    Collective on Mat
8612 
8613    Input Parameter:
8614 .  mat - the matrix
8615 
8616    Output Parameter:
8617 .  is - if any rows have zero diagonals this contains the list of them
8618 
8619    Level: developer
8620 
8621    Concepts: matrix-vector product
8622 
8623 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
8624 @*/
8625 PetscErrorCode  MatFindZeroDiagonals(Mat mat,IS *is)
8626 {
8627   PetscErrorCode ierr;
8628 
8629   PetscFunctionBegin;
8630   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8631   PetscValidType(mat,1);
8632   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8633   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8634 
8635   if (!mat->ops->findzerodiagonals) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"This matrix type does not have a find zero diagonals defined");
8636   ierr = (*mat->ops->findzerodiagonals)(mat,is);CHKERRQ(ierr);
8637   PetscFunctionReturn(0);
8638 }
8639