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