xref: /petsc/src/mat/interface/matrix.c (revision 84df9cb40eca90ea9b18a456fab7a4ecc7f6c1a4)
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      Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed.
4344 
4345    Level: intermediate
4346 
4347    Concepts: matrices^transposing
4348 
4349 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4350 @*/
4351 PetscErrorCode  MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4352 {
4353   PetscErrorCode ierr;
4354 
4355   PetscFunctionBegin;
4356   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4357   PetscValidType(mat,1);
4358   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4359   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4360   if (!mat->ops->transpose) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4361   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4362 
4363   ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4364   ierr = (*mat->ops->transpose)(mat,reuse,B);CHKERRQ(ierr);
4365   ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4366   if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);}
4367   PetscFunctionReturn(0);
4368 }
4369 
4370 #undef __FUNCT__
4371 #define __FUNCT__ "MatIsTranspose"
4372 /*@
4373    MatIsTranspose - Test whether a matrix is another one's transpose,
4374         or its own, in which case it tests symmetry.
4375 
4376    Collective on Mat
4377 
4378    Input Parameter:
4379 +  A - the matrix to test
4380 -  B - the matrix to test against, this can equal the first parameter
4381 
4382    Output Parameters:
4383 .  flg - the result
4384 
4385    Notes:
4386    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4387    has a running time of the order of the number of nonzeros; the parallel
4388    test involves parallel copies of the block-offdiagonal parts of the matrix.
4389 
4390    Level: intermediate
4391 
4392    Concepts: matrices^transposing, matrix^symmetry
4393 
4394 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4395 @*/
4396 PetscErrorCode  MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4397 {
4398   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool *),(*g)(Mat,Mat,PetscReal,PetscBool *);
4399 
4400   PetscFunctionBegin;
4401   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4402   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4403   PetscValidPointer(flg,3);
4404   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",(void (**)(void))&f);CHKERRQ(ierr);
4405   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",(void (**)(void))&g);CHKERRQ(ierr);
4406   *flg = PETSC_FALSE;
4407   if (f && g) {
4408     if (f == g) {
4409       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
4410     } else {
4411       SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4412     }
4413   } else {
4414     const MatType mattype;
4415     if (!f) {ierr = MatGetType(A,&mattype);CHKERRQ(ierr);}
4416     else    {ierr = MatGetType(B,&mattype);CHKERRQ(ierr);}
4417     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
4418   }
4419   PetscFunctionReturn(0);
4420 }
4421 
4422 #undef __FUNCT__
4423 #define __FUNCT__ "MatHermitianTranspose"
4424 /*@
4425    MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate.
4426 
4427    Collective on Mat
4428 
4429    Input Parameter:
4430 +  mat - the matrix to transpose and complex conjugate
4431 -  reuse - store the transpose matrix in the provided B
4432 
4433    Output Parameters:
4434 .  B - the Hermitian
4435 
4436    Notes:
4437      If you  pass in &mat for B the Hermitian will be done in place
4438 
4439    Level: intermediate
4440 
4441    Concepts: matrices^transposing, complex conjugatex
4442 
4443 .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4444 @*/
4445 PetscErrorCode  MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
4446 {
4447   PetscErrorCode ierr;
4448 
4449   PetscFunctionBegin;
4450   ierr = MatTranspose(mat,reuse,B);CHKERRQ(ierr);
4451 #if defined(PETSC_USE_COMPLEX)
4452   ierr = MatConjugate(*B);CHKERRQ(ierr);
4453 #endif
4454   PetscFunctionReturn(0);
4455 }
4456 
4457 #undef __FUNCT__
4458 #define __FUNCT__ "MatIsHermitianTranspose"
4459 /*@
4460    MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,
4461 
4462    Collective on Mat
4463 
4464    Input Parameter:
4465 +  A - the matrix to test
4466 -  B - the matrix to test against, this can equal the first parameter
4467 
4468    Output Parameters:
4469 .  flg - the result
4470 
4471    Notes:
4472    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4473    has a running time of the order of the number of nonzeros; the parallel
4474    test involves parallel copies of the block-offdiagonal parts of the matrix.
4475 
4476    Level: intermediate
4477 
4478    Concepts: matrices^transposing, matrix^symmetry
4479 
4480 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
4481 @*/
4482 PetscErrorCode  MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4483 {
4484   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool *),(*g)(Mat,Mat,PetscReal,PetscBool *);
4485 
4486   PetscFunctionBegin;
4487   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4488   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4489   PetscValidPointer(flg,3);
4490   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",(void (**)(void))&f);CHKERRQ(ierr);
4491   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",(void (**)(void))&g);CHKERRQ(ierr);
4492   if (f && g) {
4493     if (f==g) {
4494       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
4495     } else {
4496       SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
4497     }
4498   }
4499   PetscFunctionReturn(0);
4500 }
4501 
4502 #undef __FUNCT__
4503 #define __FUNCT__ "MatPermute"
4504 /*@
4505    MatPermute - Creates a new matrix with rows and columns permuted from the
4506    original.
4507 
4508    Collective on Mat
4509 
4510    Input Parameters:
4511 +  mat - the matrix to permute
4512 .  row - row permutation, each processor supplies only the permutation for its rows
4513 -  col - column permutation, each processor needs the entire column permutation, that is
4514          this is the same size as the total number of columns in the matrix. It can often
4515          be obtained with ISAllGather() on the row permutation
4516 
4517    Output Parameters:
4518 .  B - the permuted matrix
4519 
4520    Level: advanced
4521 
4522    Concepts: matrices^permuting
4523 
4524 .seealso: MatGetOrdering(), ISAllGather()
4525 
4526 @*/
4527 PetscErrorCode  MatPermute(Mat mat,IS row,IS col,Mat *B)
4528 {
4529   PetscErrorCode ierr;
4530 
4531   PetscFunctionBegin;
4532   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4533   PetscValidType(mat,1);
4534   PetscValidHeaderSpecific(row,IS_CLASSID,2);
4535   PetscValidHeaderSpecific(col,IS_CLASSID,3);
4536   PetscValidPointer(B,4);
4537   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4538   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4539   if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
4540   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4541 
4542   ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr);
4543   ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);
4544   PetscFunctionReturn(0);
4545 }
4546 
4547 #undef __FUNCT__
4548 #define __FUNCT__ "MatEqual"
4549 /*@
4550    MatEqual - Compares two matrices.
4551 
4552    Collective on Mat
4553 
4554    Input Parameters:
4555 +  A - the first matrix
4556 -  B - the second matrix
4557 
4558    Output Parameter:
4559 .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
4560 
4561    Level: intermediate
4562 
4563    Concepts: matrices^equality between
4564 @*/
4565 PetscErrorCode  MatEqual(Mat A,Mat B,PetscBool  *flg)
4566 {
4567   PetscErrorCode ierr;
4568 
4569   PetscFunctionBegin;
4570   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4571   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4572   PetscValidType(A,1);
4573   PetscValidType(B,2);
4574   PetscValidIntPointer(flg,3);
4575   PetscCheckSameComm(A,1,B,2);
4576   ierr = MatPreallocated(B);CHKERRQ(ierr);
4577   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4578   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4579   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);
4580   if (!A->ops->equal) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4581   if (!B->ops->equal) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4582   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);
4583   ierr = MatPreallocated(A);CHKERRQ(ierr);
4584 
4585   ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr);
4586   PetscFunctionReturn(0);
4587 }
4588 
4589 #undef __FUNCT__
4590 #define __FUNCT__ "MatDiagonalScale"
4591 /*@
4592    MatDiagonalScale - Scales a matrix on the left and right by diagonal
4593    matrices that are stored as vectors.  Either of the two scaling
4594    matrices can be PETSC_NULL.
4595 
4596    Collective on Mat
4597 
4598    Input Parameters:
4599 +  mat - the matrix to be scaled
4600 .  l - the left scaling vector (or PETSC_NULL)
4601 -  r - the right scaling vector (or PETSC_NULL)
4602 
4603    Notes:
4604    MatDiagonalScale() computes A = LAR, where
4605    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
4606    The L scales the rows of the matrix, the R scales the columns of the matrix.
4607 
4608    Level: intermediate
4609 
4610    Concepts: matrices^diagonal scaling
4611    Concepts: diagonal scaling of matrices
4612 
4613 .seealso: MatScale()
4614 @*/
4615 PetscErrorCode  MatDiagonalScale(Mat mat,Vec l,Vec r)
4616 {
4617   PetscErrorCode ierr;
4618 
4619   PetscFunctionBegin;
4620   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4621   PetscValidType(mat,1);
4622   if (!mat->ops->diagonalscale) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4623   if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);}
4624   if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);}
4625   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4626   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4627   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4628 
4629   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4630   ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr);
4631   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4632   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4633 #if defined(PETSC_HAVE_CUSP)
4634   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4635     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4636   }
4637 #endif
4638   PetscFunctionReturn(0);
4639 }
4640 
4641 #undef __FUNCT__
4642 #define __FUNCT__ "MatScale"
4643 /*@
4644     MatScale - Scales all elements of a matrix by a given number.
4645 
4646     Logically Collective on Mat
4647 
4648     Input Parameters:
4649 +   mat - the matrix to be scaled
4650 -   a  - the scaling value
4651 
4652     Output Parameter:
4653 .   mat - the scaled matrix
4654 
4655     Level: intermediate
4656 
4657     Concepts: matrices^scaling all entries
4658 
4659 .seealso: MatDiagonalScale()
4660 @*/
4661 PetscErrorCode  MatScale(Mat mat,PetscScalar a)
4662 {
4663   PetscErrorCode ierr;
4664 
4665   PetscFunctionBegin;
4666   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4667   PetscValidType(mat,1);
4668   if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4669   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4670   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4671   PetscValidLogicalCollectiveScalar(mat,a,2);
4672   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4673 
4674   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4675   if (a != (PetscScalar)1.0) {
4676     ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr);
4677     ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4678   }
4679   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4680 #if defined(PETSC_HAVE_CUSP)
4681   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4682     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4683   }
4684 #endif
4685   PetscFunctionReturn(0);
4686 }
4687 
4688 #undef __FUNCT__
4689 #define __FUNCT__ "MatNorm"
4690 /*@
4691    MatNorm - Calculates various norms of a matrix.
4692 
4693    Collective on Mat
4694 
4695    Input Parameters:
4696 +  mat - the matrix
4697 -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
4698 
4699    Output Parameters:
4700 .  nrm - the resulting norm
4701 
4702    Level: intermediate
4703 
4704    Concepts: matrices^norm
4705    Concepts: norm^of matrix
4706 @*/
4707 PetscErrorCode  MatNorm(Mat mat,NormType type,PetscReal *nrm)
4708 {
4709   PetscErrorCode ierr;
4710 
4711   PetscFunctionBegin;
4712   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4713   PetscValidType(mat,1);
4714   PetscValidScalarPointer(nrm,3);
4715 
4716   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4717   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4718   if (!mat->ops->norm) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4719   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4720 
4721   ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr);
4722   PetscFunctionReturn(0);
4723 }
4724 
4725 /*
4726      This variable is used to prevent counting of MatAssemblyBegin() that
4727    are called from within a MatAssemblyEnd().
4728 */
4729 static PetscInt MatAssemblyEnd_InUse = 0;
4730 #undef __FUNCT__
4731 #define __FUNCT__ "MatAssemblyBegin"
4732 /*@
4733    MatAssemblyBegin - Begins assembling the matrix.  This routine should
4734    be called after completing all calls to MatSetValues().
4735 
4736    Collective on Mat
4737 
4738    Input Parameters:
4739 +  mat - the matrix
4740 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
4741 
4742    Notes:
4743    MatSetValues() generally caches the values.  The matrix is ready to
4744    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4745    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4746    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4747    using the matrix.
4748 
4749    Level: beginner
4750 
4751    Concepts: matrices^assembling
4752 
4753 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
4754 @*/
4755 PetscErrorCode  MatAssemblyBegin(Mat mat,MatAssemblyType type)
4756 {
4757   PetscErrorCode ierr;
4758 
4759   PetscFunctionBegin;
4760   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4761   PetscValidType(mat,1);
4762   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4763   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
4764   if (mat->assembled) {
4765     mat->was_assembled = PETSC_TRUE;
4766     mat->assembled     = PETSC_FALSE;
4767   }
4768   if (!MatAssemblyEnd_InUse) {
4769     ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
4770     if (mat->ops->assemblybegin){ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
4771     ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
4772   } else {
4773     if (mat->ops->assemblybegin){ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
4774   }
4775   PetscFunctionReturn(0);
4776 }
4777 
4778 #undef __FUNCT__
4779 #define __FUNCT__ "MatAssembled"
4780 /*@
4781    MatAssembled - Indicates if a matrix has been assembled and is ready for
4782      use; for example, in matrix-vector product.
4783 
4784    Not Collective
4785 
4786    Input Parameter:
4787 .  mat - the matrix
4788 
4789    Output Parameter:
4790 .  assembled - PETSC_TRUE or PETSC_FALSE
4791 
4792    Level: advanced
4793 
4794    Concepts: matrices^assembled?
4795 
4796 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
4797 @*/
4798 PetscErrorCode  MatAssembled(Mat mat,PetscBool  *assembled)
4799 {
4800   PetscFunctionBegin;
4801   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4802   PetscValidType(mat,1);
4803   PetscValidPointer(assembled,2);
4804   *assembled = mat->assembled;
4805   PetscFunctionReturn(0);
4806 }
4807 
4808 #undef __FUNCT__
4809 #define __FUNCT__ "MatView_Private"
4810 /*
4811     Processes command line options to determine if/how a matrix
4812   is to be viewed. Called by MatAssemblyEnd() and MatLoad().
4813 */
4814 PetscErrorCode MatView_Private(Mat mat)
4815 {
4816   PetscErrorCode    ierr;
4817   PetscBool         flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE,flg4 = PETSC_FALSE,flg6 = PETSC_FALSE,flg7 = PETSC_FALSE,flg8 = PETSC_FALSE;
4818   static PetscBool  incall = PETSC_FALSE;
4819 #if defined(PETSC_USE_SOCKET_VIEWER)
4820   PetscBool         flg5 = PETSC_FALSE;
4821 #endif
4822 
4823   PetscFunctionBegin;
4824   if (incall) PetscFunctionReturn(0);
4825   incall = PETSC_TRUE;
4826   ierr = PetscObjectOptionsBegin((PetscObject)mat);CHKERRQ(ierr);
4827     ierr = PetscOptionsBool("-mat_view_info","Information on matrix size","MatView",flg1,&flg1,PETSC_NULL);CHKERRQ(ierr);
4828     ierr = PetscOptionsBool("-mat_view_info_detailed","Nonzeros in the matrix","MatView",flg2,&flg2,PETSC_NULL);CHKERRQ(ierr);
4829     ierr = PetscOptionsBool("-mat_view","Print matrix to stdout","MatView",flg3,&flg3,PETSC_NULL);CHKERRQ(ierr);
4830     ierr = PetscOptionsBool("-mat_view_matlab","Print matrix to stdout in a format Matlab can read","MatView",flg4,&flg4,PETSC_NULL);CHKERRQ(ierr);
4831 #if defined(PETSC_USE_SOCKET_VIEWER)
4832     ierr = PetscOptionsBool("-mat_view_socket","Send matrix to socket (can be read from matlab)","MatView",flg5,&flg5,PETSC_NULL);CHKERRQ(ierr);
4833 #endif
4834     ierr = PetscOptionsBool("-mat_view_binary","Save matrix to file in binary format","MatView",flg6,&flg6,PETSC_NULL);CHKERRQ(ierr);
4835     ierr = PetscOptionsBool("-mat_view_draw","Draw the matrix nonzero structure","MatView",flg7,&flg7,PETSC_NULL);CHKERRQ(ierr);
4836   ierr = PetscOptionsEnd();CHKERRQ(ierr);
4837 
4838   if (flg1) {
4839     PetscViewer viewer;
4840 
4841     ierr = PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);CHKERRQ(ierr);
4842     ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO);CHKERRQ(ierr);
4843     ierr = MatView(mat,viewer);CHKERRQ(ierr);
4844     ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
4845   }
4846   if (flg2) {
4847     PetscViewer viewer;
4848 
4849     ierr = PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);CHKERRQ(ierr);
4850     ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO_DETAIL);CHKERRQ(ierr);
4851     ierr = MatView(mat,viewer);CHKERRQ(ierr);
4852     ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
4853   }
4854   if (flg3) {
4855     PetscViewer viewer;
4856 
4857     ierr = PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);CHKERRQ(ierr);
4858     ierr = MatView(mat,viewer);CHKERRQ(ierr);
4859   }
4860   if (flg4) {
4861     PetscViewer viewer;
4862 
4863     ierr = PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);CHKERRQ(ierr);
4864     ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr);
4865     ierr = MatView(mat,viewer);CHKERRQ(ierr);
4866     ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
4867   }
4868 #if defined(PETSC_USE_SOCKET_VIEWER)
4869   if (flg5) {
4870     ierr = MatView(mat,PETSC_VIEWER_SOCKET_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4871     ierr = PetscViewerFlush(PETSC_VIEWER_SOCKET_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4872   }
4873 #endif
4874   if (flg6) {
4875     ierr = MatView(mat,PETSC_VIEWER_BINARY_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4876     ierr = PetscViewerFlush(PETSC_VIEWER_BINARY_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4877   }
4878   if (flg7) {
4879     ierr = PetscOptionsGetBool(((PetscObject)mat)->prefix,"-mat_view_contour",&flg8,PETSC_NULL);CHKERRQ(ierr);
4880     if (flg8) {
4881       PetscViewerPushFormat(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm),PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
4882     }
4883     ierr = MatView(mat,PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4884     ierr = PetscViewerFlush(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4885     if (flg8) {
4886       PetscViewerPopFormat(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4887     }
4888   }
4889   incall = PETSC_FALSE;
4890   PetscFunctionReturn(0);
4891 }
4892 
4893 #undef __FUNCT__
4894 #define __FUNCT__ "MatAssemblyEnd"
4895 /*@
4896    MatAssemblyEnd - Completes assembling the matrix.  This routine should
4897    be called after MatAssemblyBegin().
4898 
4899    Collective on Mat
4900 
4901    Input Parameters:
4902 +  mat - the matrix
4903 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
4904 
4905    Options Database Keys:
4906 +  -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly()
4907 .  -mat_view_info_detailed - Prints more detailed info
4908 .  -mat_view - Prints matrix in ASCII format
4909 .  -mat_view_matlab - Prints matrix in Matlab format
4910 .  -mat_view_draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
4911 .  -display <name> - Sets display name (default is host)
4912 .  -draw_pause <sec> - Sets number of seconds to pause after display
4913 .  -mat_view_socket - Sends matrix to socket, can be accessed from Matlab (See the <a href="../../docs/manual.pdf">users manual</a>)
4914 .  -viewer_socket_machine <machine>
4915 .  -viewer_socket_port <port>
4916 .  -mat_view_binary - save matrix to file in binary format
4917 -  -viewer_binary_filename <name>
4918 
4919    Notes:
4920    MatSetValues() generally caches the values.  The matrix is ready to
4921    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4922    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4923    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4924    using the matrix.
4925 
4926    Level: beginner
4927 
4928 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), MatView(), MatAssembled(), PetscViewerSocketOpen()
4929 @*/
4930 PetscErrorCode  MatAssemblyEnd(Mat mat,MatAssemblyType type)
4931 {
4932   PetscErrorCode  ierr;
4933   static PetscInt inassm = 0;
4934   PetscBool       flg = PETSC_FALSE;
4935 
4936   PetscFunctionBegin;
4937   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4938   PetscValidType(mat,1);
4939 
4940   inassm++;
4941   MatAssemblyEnd_InUse++;
4942   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
4943     ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
4944     if (mat->ops->assemblyend) {
4945       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
4946     }
4947     ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
4948   } else {
4949     if (mat->ops->assemblyend) {
4950       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
4951     }
4952   }
4953 
4954   /* Flush assembly is not a true assembly */
4955   if (type != MAT_FLUSH_ASSEMBLY) {
4956     mat->assembled  = PETSC_TRUE; mat->num_ass++;
4957   }
4958   mat->insertmode = NOT_SET_VALUES;
4959   MatAssemblyEnd_InUse--;
4960   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4961   if (!mat->symmetric_eternal) {
4962     mat->symmetric_set              = PETSC_FALSE;
4963     mat->hermitian_set              = PETSC_FALSE;
4964     mat->structurally_symmetric_set = PETSC_FALSE;
4965   }
4966   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
4967     ierr = MatView_Private(mat);CHKERRQ(ierr);
4968     ierr = PetscOptionsGetBool(((PetscObject)mat)->prefix,"-mat_is_symmetric",&flg,PETSC_NULL);CHKERRQ(ierr);
4969     if (flg) {
4970       PetscReal tol = 0.0;
4971       ierr = PetscOptionsGetReal(((PetscObject)mat)->prefix,"-mat_is_symmetric",&tol,PETSC_NULL);CHKERRQ(ierr);
4972       ierr = MatIsSymmetric(mat,tol,&flg);CHKERRQ(ierr);
4973       if (flg) {
4974         ierr = PetscPrintf(((PetscObject)mat)->comm,"Matrix is symmetric (tolerance %G)\n",tol);CHKERRQ(ierr);
4975       } else {
4976         ierr = PetscPrintf(((PetscObject)mat)->comm,"Matrix is not symmetric (tolerance %G)\n",tol);CHKERRQ(ierr);
4977       }
4978     }
4979   }
4980   inassm--;
4981 #if defined(PETSC_HAVE_CUSP)
4982   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4983     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4984   }
4985 #endif
4986   PetscFunctionReturn(0);
4987 }
4988 
4989 #undef __FUNCT__
4990 #define __FUNCT__ "MatSetOption"
4991 /*@
4992    MatSetOption - Sets a parameter option for a matrix. Some options
4993    may be specific to certain storage formats.  Some options
4994    determine how values will be inserted (or added). Sorted,
4995    row-oriented input will generally assemble the fastest. The default
4996    is row-oriented, nonsorted input.
4997 
4998    Logically Collective on Mat
4999 
5000    Input Parameters:
5001 +  mat - the matrix
5002 .  option - the option, one of those listed below (and possibly others),
5003 -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5004 
5005   Options Describing Matrix Structure:
5006 +    MAT_SPD - symmetric positive definite
5007 -    MAT_SYMMETRIC - symmetric in terms of both structure and value
5008 .    MAT_HERMITIAN - transpose is the complex conjugation
5009 .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5010 -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5011                             you set to be kept with all future use of the matrix
5012                             including after MatAssemblyBegin/End() which could
5013                             potentially change the symmetry structure, i.e. you
5014                             KNOW the matrix will ALWAYS have the property you set.
5015 
5016 
5017    Options For Use with MatSetValues():
5018    Insert a logically dense subblock, which can be
5019 .    MAT_ROW_ORIENTED - row-oriented (default)
5020 
5021    Note these options reflect the data you pass in with MatSetValues(); it has
5022    nothing to do with how the data is stored internally in the matrix
5023    data structure.
5024 
5025    When (re)assembling a matrix, we can restrict the input for
5026    efficiency/debugging purposes.  These options include
5027 +    MAT_NEW_NONZERO_LOCATIONS - additional insertions will be
5028         allowed if they generate a new nonzero
5029 .    MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
5030 .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
5031 .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
5032 .    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
5033 +    MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
5034         any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
5035         performance for very large process counts.
5036 
5037    Notes:
5038    Some options are relevant only for particular matrix types and
5039    are thus ignored by others.  Other options are not supported by
5040    certain matrix types and will generate an error message if set.
5041 
5042    If using a Fortran 77 module to compute a matrix, one may need to
5043    use the column-oriented option (or convert to the row-oriented
5044    format).
5045 
5046    MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
5047    that would generate a new entry in the nonzero structure is instead
5048    ignored.  Thus, if memory has not alredy been allocated for this particular
5049    data, then the insertion is ignored. For dense matrices, in which
5050    the entire array is allocated, no entries are ever ignored.
5051    Set after the first MatAssemblyEnd()
5052 
5053    MAT_NEW_NONZERO_LOCATION_ERR indicates that any add or insertion
5054    that would generate a new entry in the nonzero structure instead produces
5055    an error. (Currently supported for AIJ and BAIJ formats only.)
5056    This is a useful flag when using SAME_NONZERO_PATTERN in calling
5057    KSPSetOperators() to ensure that the nonzero pattern truely does
5058    remain unchanged. Set after the first MatAssemblyEnd()
5059 
5060    MAT_NEW_NONZERO_ALLOCATION_ERR indicates that any add or insertion
5061    that would generate a new entry that has not been preallocated will
5062    instead produce an error. (Currently supported for AIJ and BAIJ formats
5063    only.) This is a useful flag when debugging matrix memory preallocation.
5064 
5065    MAT_IGNORE_OFF_PROC_ENTRIES indicates entries destined for
5066    other processors should be dropped, rather than stashed.
5067    This is useful if you know that the "owning" processor is also
5068    always generating the correct matrix entries, so that PETSc need
5069    not transfer duplicate entries generated on another processor.
5070 
5071    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5072    searches during matrix assembly. When this flag is set, the hash table
5073    is created during the first Matrix Assembly. This hash table is
5074    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5075    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5076    should be used with MAT_USE_HASH_TABLE flag. This option is currently
5077    supported by MATMPIBAIJ format only.
5078 
5079    MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries
5080    are kept in the nonzero structure
5081 
5082    MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
5083    a zero location in the matrix
5084 
5085    MAT_USE_INODES - indicates using inode version of the code - works with AIJ and
5086    ROWBS matrix types
5087 
5088    MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the
5089         zero row routines and thus improves performance for very large process counts.
5090 
5091    MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular
5092         part of the matrix (since they should match the upper triangular part).
5093 
5094    Level: intermediate
5095 
5096    Concepts: matrices^setting options
5097 
5098 @*/
5099 PetscErrorCode  MatSetOption(Mat mat,MatOption op,PetscBool  flg)
5100 {
5101   PetscErrorCode ierr;
5102 
5103   PetscFunctionBegin;
5104   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5105   PetscValidType(mat,1);
5106   PetscValidLogicalCollectiveEnum(mat,op,2);
5107   PetscValidLogicalCollectiveBool(mat,flg,3);
5108 
5109   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);
5110   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()");
5111   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5112   switch (op) {
5113   case MAT_NO_OFF_PROC_ENTRIES:
5114     mat->nooffprocentries                = flg;
5115     PetscFunctionReturn(0);
5116     break;
5117   case MAT_NO_OFF_PROC_ZERO_ROWS:
5118     mat->nooffproczerorows               = flg;
5119     PetscFunctionReturn(0);
5120     break;
5121   case MAT_SPD:
5122     mat->spd_set                         = PETSC_TRUE;
5123     mat->spd                             = flg;
5124     if (flg) {
5125       mat->symmetric                     = PETSC_TRUE;
5126       mat->structurally_symmetric        = PETSC_TRUE;
5127       mat->symmetric_set                 = PETSC_TRUE;
5128       mat->structurally_symmetric_set    = PETSC_TRUE;
5129     }
5130     break;
5131   case MAT_SYMMETRIC:
5132     mat->symmetric                       = flg;
5133     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5134     mat->symmetric_set                   = PETSC_TRUE;
5135     mat->structurally_symmetric_set      = flg;
5136     break;
5137   case MAT_HERMITIAN:
5138     mat->hermitian                       = flg;
5139     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5140     mat->hermitian_set                   = PETSC_TRUE;
5141     mat->structurally_symmetric_set      = flg;
5142     break;
5143   case MAT_STRUCTURALLY_SYMMETRIC:
5144     mat->structurally_symmetric          = flg;
5145     mat->structurally_symmetric_set      = PETSC_TRUE;
5146     break;
5147   case MAT_SYMMETRY_ETERNAL:
5148     mat->symmetric_eternal               = flg;
5149     break;
5150   default:
5151     break;
5152   }
5153   if (mat->ops->setoption) {
5154     ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr);
5155   }
5156   PetscFunctionReturn(0);
5157 }
5158 
5159 #undef __FUNCT__
5160 #define __FUNCT__ "MatZeroEntries"
5161 /*@
5162    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5163    this routine retains the old nonzero structure.
5164 
5165    Logically Collective on Mat
5166 
5167    Input Parameters:
5168 .  mat - the matrix
5169 
5170    Level: intermediate
5171 
5172    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.
5173    See the Performance chapter of the users manual for information on preallocating matrices.
5174 
5175    Concepts: matrices^zeroing
5176 
5177 .seealso: MatZeroRows()
5178 @*/
5179 PetscErrorCode  MatZeroEntries(Mat mat)
5180 {
5181   PetscErrorCode ierr;
5182 
5183   PetscFunctionBegin;
5184   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5185   PetscValidType(mat,1);
5186   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5187   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");
5188   if (!mat->ops->zeroentries) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5189   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5190 
5191   ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5192   ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
5193   ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5194   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5195 #if defined(PETSC_HAVE_CUSP)
5196   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5197     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5198   }
5199 #endif
5200   PetscFunctionReturn(0);
5201 }
5202 
5203 #undef __FUNCT__
5204 #define __FUNCT__ "MatZeroRowsColumns"
5205 /*@C
5206    MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal)
5207    of a set of rows and columns of a matrix.
5208 
5209    Collective on Mat
5210 
5211    Input Parameters:
5212 +  mat - the matrix
5213 .  numRows - the number of rows to remove
5214 .  rows - the global row indices
5215 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5216 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5217 -  b - optional vector of right hand side, that will be adjusted by provided solution
5218 
5219    Notes:
5220    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5221 
5222    The user can set a value in the diagonal entry (or for the AIJ and
5223    row formats can optionally remove the main diagonal entry from the
5224    nonzero structure as well, by passing 0.0 as the final argument).
5225 
5226    For the parallel case, all processes that share the matrix (i.e.,
5227    those in the communicator used for matrix creation) MUST call this
5228    routine, regardless of whether any rows being zeroed are owned by
5229    them.
5230 
5231    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5232    list only rows local to itself).
5233 
5234    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5235 
5236    Level: intermediate
5237 
5238    Concepts: matrices^zeroing rows
5239 
5240 .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumnsIS()
5241 @*/
5242 PetscErrorCode  MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5243 {
5244   PetscErrorCode ierr;
5245 
5246   PetscFunctionBegin;
5247   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5248   PetscValidType(mat,1);
5249   if (numRows) PetscValidIntPointer(rows,3);
5250   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5251   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5252   if (!mat->ops->zerorowscolumns) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5253   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5254 
5255   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5256   ierr = MatView_Private(mat);CHKERRQ(ierr);
5257   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5258 #if defined(PETSC_HAVE_CUSP)
5259   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5260     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5261   }
5262 #endif
5263   PetscFunctionReturn(0);
5264 }
5265 
5266 #undef __FUNCT__
5267 #define __FUNCT__ "MatZeroRowsColumnsIS"
5268 /*@C
5269    MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
5270    of a set of rows and columns of a matrix.
5271 
5272    Collective on Mat
5273 
5274    Input Parameters:
5275 +  mat - the matrix
5276 .  is - the rows to zero
5277 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5278 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5279 -  b - optional vector of right hand side, that will be adjusted by provided solution
5280 
5281    Notes:
5282    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5283 
5284    The user can set a value in the diagonal entry (or for the AIJ and
5285    row formats can optionally remove the main diagonal entry from the
5286    nonzero structure as well, by passing 0.0 as the final argument).
5287 
5288    For the parallel case, all processes that share the matrix (i.e.,
5289    those in the communicator used for matrix creation) MUST call this
5290    routine, regardless of whether any rows being zeroed are owned by
5291    them.
5292 
5293    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5294    list only rows local to itself).
5295 
5296    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5297 
5298    Level: intermediate
5299 
5300    Concepts: matrices^zeroing rows
5301 
5302 .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumns()
5303 @*/
5304 PetscErrorCode  MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5305 {
5306   PetscErrorCode ierr;
5307   PetscInt       numRows;
5308   const PetscInt *rows;
5309 
5310   PetscFunctionBegin;
5311   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5312   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5313   PetscValidType(mat,1);
5314   PetscValidType(is,2);
5315   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5316   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5317   ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5318   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5319   PetscFunctionReturn(0);
5320 }
5321 
5322 #undef __FUNCT__
5323 #define __FUNCT__ "MatZeroRows"
5324 /*@C
5325    MatZeroRows - Zeros all entries (except possibly the main diagonal)
5326    of a set of rows of a matrix.
5327 
5328    Collective on Mat
5329 
5330    Input Parameters:
5331 +  mat - the matrix
5332 .  numRows - the number of rows to remove
5333 .  rows - the global row indices
5334 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5335 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5336 -  b - optional vector of right hand side, that will be adjusted by provided solution
5337 
5338    Notes:
5339    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5340    but does not release memory.  For the dense and block diagonal
5341    formats this does not alter the nonzero structure.
5342 
5343    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5344    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5345    merely zeroed.
5346 
5347    The user can set a value in the diagonal entry (or for the AIJ and
5348    row formats can optionally remove the main diagonal entry from the
5349    nonzero structure as well, by passing 0.0 as the final argument).
5350 
5351    For the parallel case, all processes that share the matrix (i.e.,
5352    those in the communicator used for matrix creation) MUST call this
5353    routine, regardless of whether any rows being zeroed are owned by
5354    them.
5355 
5356    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5357    list only rows local to itself).
5358 
5359    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5360    owns that are to be zeroed. This saves a global synchronization in the implementation.
5361 
5362    Level: intermediate
5363 
5364    Concepts: matrices^zeroing rows
5365 
5366 .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5367 @*/
5368 PetscErrorCode  MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5369 {
5370   PetscErrorCode ierr;
5371 
5372   PetscFunctionBegin;
5373   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5374   PetscValidType(mat,1);
5375   if (numRows) PetscValidIntPointer(rows,3);
5376   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5377   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5378   if (!mat->ops->zerorows) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5379   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5380 
5381   ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5382   ierr = MatView_Private(mat);CHKERRQ(ierr);
5383   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5384 #if defined(PETSC_HAVE_CUSP)
5385   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5386     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5387   }
5388 #endif
5389   PetscFunctionReturn(0);
5390 }
5391 
5392 #undef __FUNCT__
5393 #define __FUNCT__ "MatZeroRowsIS"
5394 /*@C
5395    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5396    of a set of rows of a matrix.
5397 
5398    Collective on Mat
5399 
5400    Input Parameters:
5401 +  mat - the matrix
5402 .  is - index set of rows to remove
5403 .  diag - value put in all diagonals of eliminated rows
5404 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5405 -  b - optional vector of right hand side, that will be adjusted by provided solution
5406 
5407    Notes:
5408    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5409    but does not release memory.  For the dense and block diagonal
5410    formats this does not alter the nonzero structure.
5411 
5412    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5413    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5414    merely zeroed.
5415 
5416    The user can set a value in the diagonal entry (or for the AIJ and
5417    row formats can optionally remove the main diagonal entry from the
5418    nonzero structure as well, by passing 0.0 as the final argument).
5419 
5420    For the parallel case, all processes that share the matrix (i.e.,
5421    those in the communicator used for matrix creation) MUST call this
5422    routine, regardless of whether any rows being zeroed are owned by
5423    them.
5424 
5425    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5426    list only rows local to itself).
5427 
5428    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5429    owns that are to be zeroed. This saves a global synchronization in the implementation.
5430 
5431    Level: intermediate
5432 
5433    Concepts: matrices^zeroing rows
5434 
5435 .seealso: MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5436 @*/
5437 PetscErrorCode  MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5438 {
5439   PetscInt       numRows;
5440   const PetscInt *rows;
5441   PetscErrorCode ierr;
5442 
5443   PetscFunctionBegin;
5444   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5445   PetscValidType(mat,1);
5446   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5447   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5448   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5449   ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5450   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5451   PetscFunctionReturn(0);
5452 }
5453 
5454 #undef __FUNCT__
5455 #define __FUNCT__ "MatZeroRowsStencil"
5456 /*@C
5457    MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
5458    of a set of rows of a matrix. These rows must be local to the process.
5459 
5460    Collective on Mat
5461 
5462    Input Parameters:
5463 +  mat - the matrix
5464 .  numRows - the number of rows to remove
5465 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
5466 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5467 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5468 -  b - optional vector of right hand side, that will be adjusted by provided solution
5469 
5470    Notes:
5471    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5472    but does not release memory.  For the dense and block diagonal
5473    formats this does not alter the nonzero structure.
5474 
5475    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5476    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5477    merely zeroed.
5478 
5479    The user can set a value in the diagonal entry (or for the AIJ and
5480    row formats can optionally remove the main diagonal entry from the
5481    nonzero structure as well, by passing 0.0 as the final argument).
5482 
5483    For the parallel case, all processes that share the matrix (i.e.,
5484    those in the communicator used for matrix creation) MUST call this
5485    routine, regardless of whether any rows being zeroed are owned by
5486    them.
5487 
5488    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5489    list only rows local to itself).
5490 
5491    The grid coordinates are across the entire grid, not just the local portion
5492 
5493    In Fortran idxm and idxn should be declared as
5494 $     MatStencil idxm(4,m)
5495    and the values inserted using
5496 $    idxm(MatStencil_i,1) = i
5497 $    idxm(MatStencil_j,1) = j
5498 $    idxm(MatStencil_k,1) = k
5499 $    idxm(MatStencil_c,1) = c
5500    etc
5501 
5502    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5503    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5504    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5505    DMDA_BOUNDARY_PERIODIC boundary type.
5506 
5507    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
5508    a single value per point) you can skip filling those indices.
5509 
5510    Level: intermediate
5511 
5512    Concepts: matrices^zeroing rows
5513 
5514 .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5515 @*/
5516 PetscErrorCode  MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5517 {
5518   PetscInt       dim    = mat->stencil.dim;
5519   PetscInt       sdim   = dim - (1 - (PetscInt) mat->stencil.noc);
5520   PetscInt      *dims   = mat->stencil.dims+1;
5521   PetscInt      *starts = mat->stencil.starts;
5522   PetscInt      *dxm    = (PetscInt *) rows;
5523   PetscInt      *jdxm, i, j, tmp, numNewRows = 0;
5524   PetscErrorCode ierr;
5525 
5526   PetscFunctionBegin;
5527   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5528   PetscValidType(mat,1);
5529   if (numRows) PetscValidIntPointer(rows,3);
5530 
5531   ierr = PetscMalloc(numRows*sizeof(PetscInt), &jdxm);CHKERRQ(ierr);
5532   for(i = 0; i < numRows; ++i) {
5533     /* Skip unused dimensions (they are ordered k, j, i, c) */
5534     for(j = 0; j < 3-sdim; ++j) dxm++;
5535     /* Local index in X dir */
5536     tmp = *dxm++ - starts[0];
5537     /* Loop over remaining dimensions */
5538     for(j = 0; j < dim-1; ++j) {
5539       /* If nonlocal, set index to be negative */
5540       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5541       /* Update local index */
5542       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5543     }
5544     /* Skip component slot if necessary */
5545     if (mat->stencil.noc) dxm++;
5546     /* Local row number */
5547     if (tmp >= 0) {
5548       jdxm[numNewRows++] = tmp;
5549     }
5550   }
5551   ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
5552   ierr = PetscFree(jdxm);CHKERRQ(ierr);
5553   PetscFunctionReturn(0);
5554 }
5555 
5556 #undef __FUNCT__
5557 #define __FUNCT__ "MatZeroRowsLocal"
5558 /*@C
5559    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
5560    of a set of rows of a matrix; using local numbering of rows.
5561 
5562    Collective on Mat
5563 
5564    Input Parameters:
5565 +  mat - the matrix
5566 .  numRows - the number of rows to remove
5567 .  rows - the global row indices
5568 .  diag - value put in all diagonals of eliminated rows
5569 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5570 -  b - optional vector of right hand side, that will be adjusted by provided solution
5571 
5572    Notes:
5573    Before calling MatZeroRowsLocal(), the user must first set the
5574    local-to-global mapping by calling MatSetLocalToGlobalMapping().
5575 
5576    For the AIJ matrix formats this removes the old nonzero structure,
5577    but does not release memory.  For the dense and block diagonal
5578    formats this does not alter the nonzero structure.
5579 
5580    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5581    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5582    merely zeroed.
5583 
5584    The user can set a value in the diagonal entry (or for the AIJ and
5585    row formats can optionally remove the main diagonal entry from the
5586    nonzero structure as well, by passing 0.0 as the final argument).
5587 
5588    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5589    owns that are to be zeroed. This saves a global synchronization in the implementation.
5590 
5591    Level: intermediate
5592 
5593    Concepts: matrices^zeroing
5594 
5595 .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5596 @*/
5597 PetscErrorCode  MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5598 {
5599   PetscErrorCode ierr;
5600   PetscMPIInt    size;
5601 
5602   PetscFunctionBegin;
5603   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5604   PetscValidType(mat,1);
5605   if (numRows) PetscValidIntPointer(rows,3);
5606   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5607   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5608   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5609 
5610   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
5611   if (mat->ops->zerorowslocal) {
5612     ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5613   } else if (size == 1) {
5614     ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5615   } else {
5616     IS             is, newis;
5617     const PetscInt *newRows;
5618 
5619     if (!mat->rmap->mapping) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5620     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
5621     ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr);
5622     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
5623     ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
5624     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
5625     ierr = ISDestroy(&newis);CHKERRQ(ierr);
5626     ierr = ISDestroy(&is);CHKERRQ(ierr);
5627   }
5628   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5629 #if defined(PETSC_HAVE_CUSP)
5630   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5631     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5632   }
5633 #endif
5634   PetscFunctionReturn(0);
5635 }
5636 
5637 #undef __FUNCT__
5638 #define __FUNCT__ "MatZeroRowsLocalIS"
5639 /*@C
5640    MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
5641    of a set of rows of a matrix; using local numbering of rows.
5642 
5643    Collective on Mat
5644 
5645    Input Parameters:
5646 +  mat - the matrix
5647 .  is - index set of rows to remove
5648 .  diag - value put in all diagonals of eliminated rows
5649 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5650 -  b - optional vector of right hand side, that will be adjusted by provided solution
5651 
5652    Notes:
5653    Before calling MatZeroRowsLocalIS(), the user must first set the
5654    local-to-global mapping by calling MatSetLocalToGlobalMapping().
5655 
5656    For the AIJ matrix formats this removes the old nonzero structure,
5657    but does not release memory.  For the dense and block diagonal
5658    formats this does not alter the nonzero structure.
5659 
5660    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5661    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5662    merely zeroed.
5663 
5664    The user can set a value in the diagonal entry (or for the AIJ and
5665    row formats can optionally remove the main diagonal entry from the
5666    nonzero structure as well, by passing 0.0 as the final argument).
5667 
5668    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5669    owns that are to be zeroed. This saves a global synchronization in the implementation.
5670 
5671    Level: intermediate
5672 
5673    Concepts: matrices^zeroing
5674 
5675 .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5676 @*/
5677 PetscErrorCode  MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5678 {
5679   PetscErrorCode ierr;
5680   PetscInt       numRows;
5681   const PetscInt *rows;
5682 
5683   PetscFunctionBegin;
5684   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5685   PetscValidType(mat,1);
5686   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5687   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5688   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5689   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5690 
5691   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5692   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5693   ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5694   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5695   PetscFunctionReturn(0);
5696 }
5697 
5698 #undef __FUNCT__
5699 #define __FUNCT__ "MatZeroRowsColumnsLocal"
5700 /*@C
5701    MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
5702    of a set of rows and columns of a matrix; using local numbering of rows.
5703 
5704    Collective on Mat
5705 
5706    Input Parameters:
5707 +  mat - the matrix
5708 .  numRows - the number of rows to remove
5709 .  rows - the global row indices
5710 .  diag - value put in all diagonals of eliminated rows
5711 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5712 -  b - optional vector of right hand side, that will be adjusted by provided solution
5713 
5714    Notes:
5715    Before calling MatZeroRowsColumnsLocal(), the user must first set the
5716    local-to-global mapping by calling MatSetLocalToGlobalMapping().
5717 
5718    The user can set a value in the diagonal entry (or for the AIJ and
5719    row formats can optionally remove the main diagonal entry from the
5720    nonzero structure as well, by passing 0.0 as the final argument).
5721 
5722    Level: intermediate
5723 
5724    Concepts: matrices^zeroing
5725 
5726 .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5727 @*/
5728 PetscErrorCode  MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5729 {
5730   PetscErrorCode ierr;
5731   PetscMPIInt    size;
5732 
5733   PetscFunctionBegin;
5734   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5735   PetscValidType(mat,1);
5736   if (numRows) PetscValidIntPointer(rows,3);
5737   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5738   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5739   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5740 
5741   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
5742   if (size == 1) {
5743     ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5744   } else {
5745     IS             is, newis;
5746     const PetscInt *newRows;
5747 
5748     if (!mat->cmap->mapping) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5749     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
5750     ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr);
5751     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
5752     ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
5753     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
5754     ierr = ISDestroy(&newis);CHKERRQ(ierr);
5755     ierr = ISDestroy(&is);CHKERRQ(ierr);
5756   }
5757   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5758 #if defined(PETSC_HAVE_CUSP)
5759   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5760     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5761   }
5762 #endif
5763   PetscFunctionReturn(0);
5764 }
5765 
5766 #undef __FUNCT__
5767 #define __FUNCT__ "MatZeroRowsColumnsLocalIS"
5768 /*@C
5769    MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
5770    of a set of rows and columns of a matrix; using local numbering of rows.
5771 
5772    Collective on Mat
5773 
5774    Input Parameters:
5775 +  mat - the matrix
5776 .  is - index set of rows to remove
5777 .  diag - value put in all diagonals of eliminated rows
5778 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5779 -  b - optional vector of right hand side, that will be adjusted by provided solution
5780 
5781    Notes:
5782    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
5783    local-to-global mapping by calling MatSetLocalToGlobalMapping().
5784 
5785    The user can set a value in the diagonal entry (or for the AIJ and
5786    row formats can optionally remove the main diagonal entry from the
5787    nonzero structure as well, by passing 0.0 as the final argument).
5788 
5789    Level: intermediate
5790 
5791    Concepts: matrices^zeroing
5792 
5793 .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5794 @*/
5795 PetscErrorCode  MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5796 {
5797   PetscErrorCode ierr;
5798   PetscInt       numRows;
5799   const PetscInt *rows;
5800 
5801   PetscFunctionBegin;
5802   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5803   PetscValidType(mat,1);
5804   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5805   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5806   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5807   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5808 
5809   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5810   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5811   ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5812   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5813   PetscFunctionReturn(0);
5814 }
5815 
5816 #undef __FUNCT__
5817 #define __FUNCT__ "MatGetSize"
5818 /*@
5819    MatGetSize - Returns the numbers of rows and columns in a matrix.
5820 
5821    Not Collective
5822 
5823    Input Parameter:
5824 .  mat - the matrix
5825 
5826    Output Parameters:
5827 +  m - the number of global rows
5828 -  n - the number of global columns
5829 
5830    Note: both output parameters can be PETSC_NULL on input.
5831 
5832    Level: beginner
5833 
5834    Concepts: matrices^size
5835 
5836 .seealso: MatGetLocalSize()
5837 @*/
5838 PetscErrorCode  MatGetSize(Mat mat,PetscInt *m,PetscInt* n)
5839 {
5840   PetscFunctionBegin;
5841   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5842   if (m) *m = mat->rmap->N;
5843   if (n) *n = mat->cmap->N;
5844   PetscFunctionReturn(0);
5845 }
5846 
5847 #undef __FUNCT__
5848 #define __FUNCT__ "MatGetLocalSize"
5849 /*@
5850    MatGetLocalSize - Returns the number of rows and columns in a matrix
5851    stored locally.  This information may be implementation dependent, so
5852    use with care.
5853 
5854    Not Collective
5855 
5856    Input Parameters:
5857 .  mat - the matrix
5858 
5859    Output Parameters:
5860 +  m - the number of local rows
5861 -  n - the number of local columns
5862 
5863    Note: both output parameters can be PETSC_NULL on input.
5864 
5865    Level: beginner
5866 
5867    Concepts: matrices^local size
5868 
5869 .seealso: MatGetSize()
5870 @*/
5871 PetscErrorCode  MatGetLocalSize(Mat mat,PetscInt *m,PetscInt* n)
5872 {
5873   PetscFunctionBegin;
5874   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5875   if (m) PetscValidIntPointer(m,2);
5876   if (n) PetscValidIntPointer(n,3);
5877   if (m) *m = mat->rmap->n;
5878   if (n) *n = mat->cmap->n;
5879   PetscFunctionReturn(0);
5880 }
5881 
5882 #undef __FUNCT__
5883 #define __FUNCT__ "MatGetOwnershipRangeColumn"
5884 /*@
5885    MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
5886    this processor. (The columns of the "diagonal block")
5887 
5888    Not Collective, unless matrix has not been allocated, then collective on Mat
5889 
5890    Input Parameters:
5891 .  mat - the matrix
5892 
5893    Output Parameters:
5894 +  m - the global index of the first local column
5895 -  n - one more than the global index of the last local column
5896 
5897    Notes: both output parameters can be PETSC_NULL on input.
5898 
5899    Level: developer
5900 
5901    Concepts: matrices^column ownership
5902 
5903 .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
5904 
5905 @*/
5906 PetscErrorCode  MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt* n)
5907 {
5908   PetscErrorCode ierr;
5909 
5910   PetscFunctionBegin;
5911   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5912   PetscValidType(mat,1);
5913   if (m) PetscValidIntPointer(m,2);
5914   if (n) PetscValidIntPointer(n,3);
5915   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5916   if (m) *m = mat->cmap->rstart;
5917   if (n) *n = mat->cmap->rend;
5918   PetscFunctionReturn(0);
5919 }
5920 
5921 #undef __FUNCT__
5922 #define __FUNCT__ "MatGetOwnershipRange"
5923 /*@
5924    MatGetOwnershipRange - Returns the range of matrix rows owned by
5925    this processor, assuming that the matrix is laid out with the first
5926    n1 rows on the first processor, the next n2 rows on the second, etc.
5927    For certain parallel layouts this range may not be well defined.
5928 
5929    Not Collective, unless matrix has not been allocated, then collective on Mat
5930 
5931    Input Parameters:
5932 .  mat - the matrix
5933 
5934    Output Parameters:
5935 +  m - the global index of the first local row
5936 -  n - one more than the global index of the last local row
5937 
5938    Note: both output parameters can be PETSC_NULL on input.
5939 
5940    Level: beginner
5941 
5942    Concepts: matrices^row ownership
5943 
5944 .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
5945 
5946 @*/
5947 PetscErrorCode  MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt* n)
5948 {
5949   PetscErrorCode ierr;
5950 
5951   PetscFunctionBegin;
5952   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5953   PetscValidType(mat,1);
5954   if (m) PetscValidIntPointer(m,2);
5955   if (n) PetscValidIntPointer(n,3);
5956   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5957   if (m) *m = mat->rmap->rstart;
5958   if (n) *n = mat->rmap->rend;
5959   PetscFunctionReturn(0);
5960 }
5961 
5962 #undef __FUNCT__
5963 #define __FUNCT__ "MatGetOwnershipRanges"
5964 /*@C
5965    MatGetOwnershipRanges - Returns the range of matrix rows owned by
5966    each process
5967 
5968    Not Collective, unless matrix has not been allocated, then collective on Mat
5969 
5970    Input Parameters:
5971 .  mat - the matrix
5972 
5973    Output Parameters:
5974 .  ranges - start of each processors portion plus one more then the total length at the end
5975 
5976    Level: beginner
5977 
5978    Concepts: matrices^row ownership
5979 
5980 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
5981 
5982 @*/
5983 PetscErrorCode  MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
5984 {
5985   PetscErrorCode ierr;
5986 
5987   PetscFunctionBegin;
5988   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5989   PetscValidType(mat,1);
5990   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5991   ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr);
5992   PetscFunctionReturn(0);
5993 }
5994 
5995 #undef __FUNCT__
5996 #define __FUNCT__ "MatGetOwnershipRangesColumn"
5997 /*@C
5998    MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
5999    this processor. (The columns of the "diagonal blocks" for each process)
6000 
6001    Not Collective, unless matrix has not been allocated, then collective on Mat
6002 
6003    Input Parameters:
6004 .  mat - the matrix
6005 
6006    Output Parameters:
6007 .  ranges - start of each processors portion plus one more then the total length at the end
6008 
6009    Level: beginner
6010 
6011    Concepts: matrices^column ownership
6012 
6013 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
6014 
6015 @*/
6016 PetscErrorCode  MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6017 {
6018   PetscErrorCode ierr;
6019 
6020   PetscFunctionBegin;
6021   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6022   PetscValidType(mat,1);
6023   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6024   ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr);
6025   PetscFunctionReturn(0);
6026 }
6027 
6028 #undef __FUNCT__
6029 #define __FUNCT__ "MatILUFactorSymbolic"
6030 /*@C
6031    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6032    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6033    to complete the factorization.
6034 
6035    Collective on Mat
6036 
6037    Input Parameters:
6038 +  mat - the matrix
6039 .  row - row permutation
6040 .  column - column permutation
6041 -  info - structure containing
6042 $      levels - number of levels of fill.
6043 $      expected fill - as ratio of original fill.
6044 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6045                 missing diagonal entries)
6046 
6047    Output Parameters:
6048 .  fact - new matrix that has been symbolically factored
6049 
6050    Notes:
6051    See the <a href="../../docs/manual.pdf">users manual</a>  for additional information about
6052    choosing the fill factor for better efficiency.
6053 
6054    Most users should employ the simplified KSP interface for linear solvers
6055    instead of working directly with matrix algebra routines such as this.
6056    See, e.g., KSPCreate().
6057 
6058    Level: developer
6059 
6060   Concepts: matrices^symbolic LU factorization
6061   Concepts: matrices^factorization
6062   Concepts: LU^symbolic factorization
6063 
6064 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6065           MatGetOrdering(), MatFactorInfo
6066 
6067     Developer Note: fortran interface is not autogenerated as the f90
6068     interface defintion cannot be generated correctly [due to MatFactorInfo]
6069 
6070 @*/
6071 PetscErrorCode  MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6072 {
6073   PetscErrorCode ierr;
6074 
6075   PetscFunctionBegin;
6076   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6077   PetscValidType(mat,1);
6078   PetscValidHeaderSpecific(row,IS_CLASSID,2);
6079   PetscValidHeaderSpecific(col,IS_CLASSID,3);
6080   PetscValidPointer(info,4);
6081   PetscValidPointer(fact,5);
6082   if (info->levels < 0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6083   if (info->fill < 1.0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
6084   if (!(fact)->ops->ilufactorsymbolic) {
6085     const MatSolverPackage spackage;
6086     ierr = MatFactorGetSolverPackage(fact,&spackage);CHKERRQ(ierr);
6087     SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6088   }
6089   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6090   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6091   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6092 
6093   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6094   ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
6095   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6096   PetscFunctionReturn(0);
6097 }
6098 
6099 #undef __FUNCT__
6100 #define __FUNCT__ "MatICCFactorSymbolic"
6101 /*@C
6102    MatICCFactorSymbolic - Performs symbolic incomplete
6103    Cholesky factorization for a symmetric matrix.  Use
6104    MatCholeskyFactorNumeric() to complete the factorization.
6105 
6106    Collective on Mat
6107 
6108    Input Parameters:
6109 +  mat - the matrix
6110 .  perm - row and column permutation
6111 -  info - structure containing
6112 $      levels - number of levels of fill.
6113 $      expected fill - as ratio of original fill.
6114 
6115    Output Parameter:
6116 .  fact - the factored matrix
6117 
6118    Notes:
6119    Most users should employ the KSP interface for linear solvers
6120    instead of working directly with matrix algebra routines such as this.
6121    See, e.g., KSPCreate().
6122 
6123    Level: developer
6124 
6125   Concepts: matrices^symbolic incomplete Cholesky factorization
6126   Concepts: matrices^factorization
6127   Concepts: Cholsky^symbolic factorization
6128 
6129 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
6130 
6131     Developer Note: fortran interface is not autogenerated as the f90
6132     interface defintion cannot be generated correctly [due to MatFactorInfo]
6133 
6134 @*/
6135 PetscErrorCode  MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6136 {
6137   PetscErrorCode ierr;
6138 
6139   PetscFunctionBegin;
6140   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6141   PetscValidType(mat,1);
6142   PetscValidHeaderSpecific(perm,IS_CLASSID,2);
6143   PetscValidPointer(info,3);
6144   PetscValidPointer(fact,4);
6145   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6146   if (info->levels < 0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6147   if (info->fill < 1.0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
6148   if (!(fact)->ops->iccfactorsymbolic) {
6149     const MatSolverPackage spackage;
6150     ierr = MatFactorGetSolverPackage(fact,&spackage);CHKERRQ(ierr);
6151     SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6152   }
6153   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6154   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6155 
6156   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6157   ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
6158   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6159   PetscFunctionReturn(0);
6160 }
6161 
6162 #undef __FUNCT__
6163 #define __FUNCT__ "MatGetArray"
6164 /*@C
6165    MatGetArray - Returns a pointer to the element values in the matrix.
6166    The result of this routine is dependent on the underlying matrix data
6167    structure, and may not even work for certain matrix types.  You MUST
6168    call MatRestoreArray() when you no longer need to access the array.
6169 
6170    Not Collective
6171 
6172    Input Parameter:
6173 .  mat - the matrix
6174 
6175    Output Parameter:
6176 .  v - the location of the values
6177 
6178 
6179    Fortran Note:
6180    This routine is used differently from Fortran, e.g.,
6181 .vb
6182         Mat         mat
6183         PetscScalar mat_array(1)
6184         PetscOffset i_mat
6185         PetscErrorCode ierr
6186         call MatGetArray(mat,mat_array,i_mat,ierr)
6187 
6188   C  Access first local entry in matrix; note that array is
6189   C  treated as one dimensional
6190         value = mat_array(i_mat + 1)
6191 
6192         [... other code ...]
6193         call MatRestoreArray(mat,mat_array,i_mat,ierr)
6194 .ve
6195 
6196    See the <a href="../../docs/manual.pdf#ch_fortran">Fortran chapter of the users manual</a> and
6197    src/mat/examples/tests for details.
6198 
6199    Level: advanced
6200 
6201    Concepts: matrices^access array
6202 
6203 .seealso: MatRestoreArray(), MatGetArrayF90(), MatGetRowIJ()
6204 @*/
6205 PetscErrorCode  MatGetArray(Mat mat,PetscScalar *v[])
6206 {
6207   PetscErrorCode ierr;
6208 
6209   PetscFunctionBegin;
6210   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6211   PetscValidType(mat,1);
6212   PetscValidPointer(v,2);
6213   if (!mat->ops->getarray) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6214   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6215   ierr = (*mat->ops->getarray)(mat,v);CHKERRQ(ierr);
6216   CHKMEMQ;
6217   PetscFunctionReturn(0);
6218 }
6219 
6220 #undef __FUNCT__
6221 #define __FUNCT__ "MatRestoreArray"
6222 /*@C
6223    MatRestoreArray - Restores the matrix after MatGetArray() has been called.
6224 
6225    Not Collective
6226 
6227    Input Parameter:
6228 +  mat - the matrix
6229 -  v - the location of the values
6230 
6231    Fortran Note:
6232    This routine is used differently from Fortran, e.g.,
6233 .vb
6234         Mat         mat
6235         PetscScalar mat_array(1)
6236         PetscOffset i_mat
6237         PetscErrorCode ierr
6238         call MatGetArray(mat,mat_array,i_mat,ierr)
6239 
6240   C  Access first local entry in matrix; note that array is
6241   C  treated as one dimensional
6242         value = mat_array(i_mat + 1)
6243 
6244         [... other code ...]
6245         call MatRestoreArray(mat,mat_array,i_mat,ierr)
6246 .ve
6247 
6248    See the <a href="../../docs/manual.pdf#ch_fortran">Fortran chapter of the users manual</a>
6249    src/mat/examples/tests for details
6250 
6251    Level: advanced
6252 
6253 .seealso: MatGetArray(), MatRestoreArrayF90()
6254 @*/
6255 PetscErrorCode  MatRestoreArray(Mat mat,PetscScalar *v[])
6256 {
6257   PetscErrorCode ierr;
6258 
6259   PetscFunctionBegin;
6260   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6261   PetscValidType(mat,1);
6262   PetscValidPointer(v,2);
6263   CHKMEMQ;
6264   if (!mat->ops->restorearray) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6265   ierr = (*mat->ops->restorearray)(mat,v);CHKERRQ(ierr);
6266   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6267 #if defined(PETSC_HAVE_CUSP)
6268   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
6269     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
6270   }
6271 #endif
6272   PetscFunctionReturn(0);
6273 }
6274 
6275 #undef __FUNCT__
6276 #define __FUNCT__ "MatGetSubMatrices"
6277 /*@C
6278    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
6279    points to an array of valid matrices, they may be reused to store the new
6280    submatrices.
6281 
6282    Collective on Mat
6283 
6284    Input Parameters:
6285 +  mat - the matrix
6286 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6287 .  irow, icol - index sets of rows and columns to extract
6288 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6289 
6290    Output Parameter:
6291 .  submat - the array of submatrices
6292 
6293    Notes:
6294    MatGetSubMatrices() can extract ONLY sequential submatrices
6295    (from both sequential and parallel matrices). Use MatGetSubMatrix()
6296    to extract a parallel submatrix.
6297 
6298    When extracting submatrices from a parallel matrix, each processor can
6299    form a different submatrix by setting the rows and columns of its
6300    individual index sets according to the local submatrix desired.
6301 
6302    When finished using the submatrices, the user should destroy
6303    them with MatDestroyMatrices().
6304 
6305    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6306    original matrix has not changed from that last call to MatGetSubMatrices().
6307 
6308    This routine creates the matrices in submat; you should NOT create them before
6309    calling it. It also allocates the array of matrix pointers submat.
6310 
6311    For BAIJ matrices the index sets must respect the block structure, that is if they
6312    request one row/column in a block, they must request all rows/columns that are in
6313    that block. For example, if the block size is 2 you cannot request just row 0 and
6314    column 0.
6315 
6316    Fortran Note:
6317    The Fortran interface is slightly different from that given below; it
6318    requires one to pass in  as submat a Mat (integer) array of size at least m.
6319 
6320    Level: advanced
6321 
6322    Concepts: matrices^accessing submatrices
6323    Concepts: submatrices
6324 
6325 .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6326 @*/
6327 PetscErrorCode  MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6328 {
6329   PetscErrorCode ierr;
6330   PetscInt        i;
6331   PetscBool       eq;
6332 
6333   PetscFunctionBegin;
6334   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6335   PetscValidType(mat,1);
6336   if (n) {
6337     PetscValidPointer(irow,3);
6338     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6339     PetscValidPointer(icol,4);
6340     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6341   }
6342   PetscValidPointer(submat,6);
6343   if (n && scall == MAT_REUSE_MATRIX) {
6344     PetscValidPointer(*submat,6);
6345     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6346   }
6347   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6348   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6349   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6350   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6351 
6352   ierr = PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
6353   ierr = (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6354   ierr = PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
6355   for (i=0; i<n; i++) {
6356     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6357       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6358       if (eq) {
6359 	if (mat->symmetric){
6360 	  ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6361 	} else if (mat->hermitian) {
6362 	  ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6363 	} else if (mat->structurally_symmetric) {
6364 	  ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6365 	}
6366       }
6367     }
6368   }
6369   PetscFunctionReturn(0);
6370 }
6371 
6372 #undef __FUNCT__
6373 #define __FUNCT__ "MatGetSubMatricesParallel"
6374 PetscErrorCode  MatGetSubMatricesParallel(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6375 {
6376   PetscErrorCode ierr;
6377   PetscInt        i;
6378   PetscBool       eq;
6379 
6380   PetscFunctionBegin;
6381   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6382   PetscValidType(mat,1);
6383   if (n) {
6384     PetscValidPointer(irow,3);
6385     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6386     PetscValidPointer(icol,4);
6387     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6388   }
6389   PetscValidPointer(submat,6);
6390   if (n && scall == MAT_REUSE_MATRIX) {
6391     PetscValidPointer(*submat,6);
6392     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6393   }
6394   if (!mat->ops->getsubmatricesparallel) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6395   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6396   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6397   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6398 
6399   ierr = PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
6400   ierr = (*mat->ops->getsubmatricesparallel)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6401   ierr = PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
6402   for (i=0; i<n; i++) {
6403     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6404       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6405       if (eq) {
6406 	if (mat->symmetric){
6407 	  ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6408 	} else if (mat->hermitian) {
6409 	  ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6410 	} else if (mat->structurally_symmetric) {
6411 	  ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6412 	}
6413       }
6414     }
6415   }
6416   PetscFunctionReturn(0);
6417 }
6418 
6419 #undef __FUNCT__
6420 #define __FUNCT__ "MatDestroyMatrices"
6421 /*@C
6422    MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().
6423 
6424    Collective on Mat
6425 
6426    Input Parameters:
6427 +  n - the number of local matrices
6428 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6429                        sequence of MatGetSubMatrices())
6430 
6431    Level: advanced
6432 
6433     Notes: Frees not only the matrices, but also the array that contains the matrices
6434            In Fortran will not free the array.
6435 
6436 .seealso: MatGetSubMatrices()
6437 @*/
6438 PetscErrorCode  MatDestroyMatrices(PetscInt n,Mat *mat[])
6439 {
6440   PetscErrorCode ierr;
6441   PetscInt       i;
6442 
6443   PetscFunctionBegin;
6444   if (!*mat) PetscFunctionReturn(0);
6445   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6446   PetscValidPointer(mat,2);
6447   for (i=0; i<n; i++) {
6448     ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr);
6449   }
6450   /* memory is allocated even if n = 0 */
6451   ierr = PetscFree(*mat);CHKERRQ(ierr);
6452   *mat = PETSC_NULL;
6453   PetscFunctionReturn(0);
6454 }
6455 
6456 #undef __FUNCT__
6457 #define __FUNCT__ "MatGetSeqNonzeroStructure"
6458 /*@C
6459    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
6460 
6461    Collective on Mat
6462 
6463    Input Parameters:
6464 .  mat - the matrix
6465 
6466    Output Parameter:
6467 .  matstruct - the sequential matrix with the nonzero structure of mat
6468 
6469   Level: intermediate
6470 
6471 .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
6472 @*/
6473 PetscErrorCode  MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6474 {
6475   PetscErrorCode ierr;
6476 
6477   PetscFunctionBegin;
6478   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6479   PetscValidPointer(matstruct,2);
6480 
6481   PetscValidType(mat,1);
6482   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6483   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6484 
6485   if (!mat->ops->getseqnonzerostructure) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6486   ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
6487   ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr);
6488   ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
6489   PetscFunctionReturn(0);
6490 }
6491 
6492 #undef __FUNCT__
6493 #define __FUNCT__ "MatDestroySeqNonzeroStructure"
6494 /*@C
6495    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
6496 
6497    Collective on Mat
6498 
6499    Input Parameters:
6500 .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
6501                        sequence of MatGetSequentialNonzeroStructure())
6502 
6503    Level: advanced
6504 
6505     Notes: Frees not only the matrices, but also the array that contains the matrices
6506 
6507 .seealso: MatGetSeqNonzeroStructure()
6508 @*/
6509 PetscErrorCode  MatDestroySeqNonzeroStructure(Mat *mat)
6510 {
6511   PetscErrorCode ierr;
6512 
6513   PetscFunctionBegin;
6514   PetscValidPointer(mat,1);
6515   ierr = MatDestroy(mat);CHKERRQ(ierr);
6516   PetscFunctionReturn(0);
6517 }
6518 
6519 #undef __FUNCT__
6520 #define __FUNCT__ "MatIncreaseOverlap"
6521 /*@
6522    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6523    replaces the index sets by larger ones that represent submatrices with
6524    additional overlap.
6525 
6526    Collective on Mat
6527 
6528    Input Parameters:
6529 +  mat - the matrix
6530 .  n   - the number of index sets
6531 .  is  - the array of index sets (these index sets will changed during the call)
6532 -  ov  - the additional overlap requested
6533 
6534    Level: developer
6535 
6536    Concepts: overlap
6537    Concepts: ASM^computing overlap
6538 
6539 .seealso: MatGetSubMatrices()
6540 @*/
6541 PetscErrorCode  MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6542 {
6543   PetscErrorCode ierr;
6544 
6545   PetscFunctionBegin;
6546   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6547   PetscValidType(mat,1);
6548   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6549   if (n) {
6550     PetscValidPointer(is,3);
6551     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
6552   }
6553   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6554   if (mat->factortype)     SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6555   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6556 
6557   if (!ov) PetscFunctionReturn(0);
6558   if (!mat->ops->increaseoverlap) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6559   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
6560   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
6561   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
6562   PetscFunctionReturn(0);
6563 }
6564 
6565 #undef __FUNCT__
6566 #define __FUNCT__ "MatGetBlockSize"
6567 /*@
6568    MatGetBlockSize - Returns the matrix block size; useful especially for the
6569    block row and block diagonal formats.
6570 
6571    Not Collective
6572 
6573    Input Parameter:
6574 .  mat - the matrix
6575 
6576    Output Parameter:
6577 .  bs - block size
6578 
6579    Notes:
6580    Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ
6581 
6582    Level: intermediate
6583 
6584    Concepts: matrices^block size
6585 
6586 .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ()
6587 @*/
6588 PetscErrorCode  MatGetBlockSize(Mat mat,PetscInt *bs)
6589 {
6590   PetscErrorCode ierr;
6591 
6592   PetscFunctionBegin;
6593   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6594   PetscValidType(mat,1);
6595   PetscValidIntPointer(bs,2);
6596   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6597   *bs = mat->rmap->bs;
6598   PetscFunctionReturn(0);
6599 }
6600 
6601 #undef __FUNCT__
6602 #define __FUNCT__ "MatSetBlockSize"
6603 /*@
6604    MatSetBlockSize - Sets the matrix block size; for many matrix types you
6605      cannot use this and MUST set the blocksize when you preallocate the matrix
6606 
6607    Logically Collective on Mat
6608 
6609    Input Parameters:
6610 +  mat - the matrix
6611 -  bs - block size
6612 
6613    Notes:
6614      For BAIJ matrices, this just checks that the block size agrees with the BAIJ size,
6615      it is not possible to change BAIJ block sizes after preallocation.
6616 
6617    Level: intermediate
6618 
6619    Concepts: matrices^block size
6620 
6621 .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ(), MatGetBlockSize()
6622 @*/
6623 PetscErrorCode  MatSetBlockSize(Mat mat,PetscInt bs)
6624 {
6625   PetscErrorCode ierr;
6626 
6627   PetscFunctionBegin;
6628   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6629   PetscValidType(mat,1);
6630   PetscValidLogicalCollectiveInt(mat,bs,2);
6631   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6632   if (bs < 1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Block size %D, must be positive",bs);
6633   if (mat->ops->setblocksize) {
6634     ierr = (*mat->ops->setblocksize)(mat,bs);CHKERRQ(ierr);
6635   } else {
6636     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Cannot set the blocksize for matrix type %s",((PetscObject)mat)->type_name);
6637   }
6638   PetscFunctionReturn(0);
6639 }
6640 
6641 #undef __FUNCT__
6642 #define __FUNCT__ "MatGetRowIJ"
6643 /*@C
6644     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
6645 
6646    Collective on Mat
6647 
6648     Input Parameters:
6649 +   mat - the matrix
6650 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
6651 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
6652 -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
6653                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6654                  always used.
6655 
6656     Output Parameters:
6657 +   n - number of rows in the (possibly compressed) matrix
6658 .   ia - the row pointers [of length n+1]
6659 .   ja - the column indices
6660 -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
6661            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
6662 
6663     Level: developer
6664 
6665     Notes: You CANNOT change any of the ia[] or ja[] values.
6666 
6667            Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values
6668 
6669     Fortran Node
6670 
6671            In Fortran use
6672 $           PetscInt ia(1), ja(1)
6673 $           PetscOffset iia, jja
6674 $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
6675 $
6676 $          or
6677 $
6678 $           PetscScalar, pointer :: xx_v(:)
6679 $    call  MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
6680 
6681 
6682        Acess the ith and jth entries via ia(iia + i) and ja(jja + j)
6683 
6684 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatGetArray()
6685 @*/
6686 PetscErrorCode  MatGetRowIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6687 {
6688   PetscErrorCode ierr;
6689 
6690   PetscFunctionBegin;
6691   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6692   PetscValidType(mat,1);
6693   PetscValidIntPointer(n,4);
6694   if (ia) PetscValidIntPointer(ia,5);
6695   if (ja) PetscValidIntPointer(ja,6);
6696   PetscValidIntPointer(done,7);
6697   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6698   if (!mat->ops->getrowij) *done = PETSC_FALSE;
6699   else {
6700     *done = PETSC_TRUE;
6701     ierr = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
6702     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6703     ierr = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
6704   }
6705   PetscFunctionReturn(0);
6706 }
6707 
6708 #undef __FUNCT__
6709 #define __FUNCT__ "MatGetColumnIJ"
6710 /*@C
6711     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
6712 
6713     Collective on Mat
6714 
6715     Input Parameters:
6716 +   mat - the matrix
6717 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6718 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6719                 symmetrized
6720 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6721                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6722                  always used.
6723 
6724     Output Parameters:
6725 +   n - number of columns in the (possibly compressed) matrix
6726 .   ia - the column pointers
6727 .   ja - the row indices
6728 -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
6729 
6730     Level: developer
6731 
6732 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6733 @*/
6734 PetscErrorCode  MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6735 {
6736   PetscErrorCode ierr;
6737 
6738   PetscFunctionBegin;
6739   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6740   PetscValidType(mat,1);
6741   PetscValidIntPointer(n,4);
6742   if (ia) PetscValidIntPointer(ia,5);
6743   if (ja) PetscValidIntPointer(ja,6);
6744   PetscValidIntPointer(done,7);
6745   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6746   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
6747   else {
6748     *done = PETSC_TRUE;
6749     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6750   }
6751   PetscFunctionReturn(0);
6752 }
6753 
6754 #undef __FUNCT__
6755 #define __FUNCT__ "MatRestoreRowIJ"
6756 /*@C
6757     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
6758     MatGetRowIJ().
6759 
6760     Collective on Mat
6761 
6762     Input Parameters:
6763 +   mat - the matrix
6764 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6765 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6766                 symmetrized
6767 -   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6768                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6769                  always used.
6770 
6771     Output Parameters:
6772 +   n - size of (possibly compressed) matrix
6773 .   ia - the row pointers
6774 .   ja - the column indices
6775 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
6776 
6777     Level: developer
6778 
6779 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6780 @*/
6781 PetscErrorCode  MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6782 {
6783   PetscErrorCode ierr;
6784 
6785   PetscFunctionBegin;
6786   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6787   PetscValidType(mat,1);
6788   if (ia) PetscValidIntPointer(ia,5);
6789   if (ja) PetscValidIntPointer(ja,6);
6790   PetscValidIntPointer(done,7);
6791   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6792 
6793   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
6794   else {
6795     *done = PETSC_TRUE;
6796     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6797   }
6798   PetscFunctionReturn(0);
6799 }
6800 
6801 #undef __FUNCT__
6802 #define __FUNCT__ "MatRestoreColumnIJ"
6803 /*@C
6804     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
6805     MatGetColumnIJ().
6806 
6807     Collective on Mat
6808 
6809     Input Parameters:
6810 +   mat - the matrix
6811 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6812 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6813                 symmetrized
6814 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6815                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6816                  always used.
6817 
6818     Output Parameters:
6819 +   n - size of (possibly compressed) matrix
6820 .   ia - the column pointers
6821 .   ja - the row indices
6822 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
6823 
6824     Level: developer
6825 
6826 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
6827 @*/
6828 PetscErrorCode  MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6829 {
6830   PetscErrorCode ierr;
6831 
6832   PetscFunctionBegin;
6833   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6834   PetscValidType(mat,1);
6835   if (ia) PetscValidIntPointer(ia,5);
6836   if (ja) PetscValidIntPointer(ja,6);
6837   PetscValidIntPointer(done,7);
6838   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6839 
6840   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
6841   else {
6842     *done = PETSC_TRUE;
6843     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6844   }
6845   PetscFunctionReturn(0);
6846 }
6847 
6848 #undef __FUNCT__
6849 #define __FUNCT__ "MatColoringPatch"
6850 /*@C
6851     MatColoringPatch -Used inside matrix coloring routines that
6852     use MatGetRowIJ() and/or MatGetColumnIJ().
6853 
6854     Collective on Mat
6855 
6856     Input Parameters:
6857 +   mat - the matrix
6858 .   ncolors - max color value
6859 .   n   - number of entries in colorarray
6860 -   colorarray - array indicating color for each column
6861 
6862     Output Parameters:
6863 .   iscoloring - coloring generated using colorarray information
6864 
6865     Level: developer
6866 
6867 .seealso: MatGetRowIJ(), MatGetColumnIJ()
6868 
6869 @*/
6870 PetscErrorCode  MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
6871 {
6872   PetscErrorCode ierr;
6873 
6874   PetscFunctionBegin;
6875   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6876   PetscValidType(mat,1);
6877   PetscValidIntPointer(colorarray,4);
6878   PetscValidPointer(iscoloring,5);
6879   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6880 
6881   if (!mat->ops->coloringpatch){
6882     ierr = ISColoringCreate(((PetscObject)mat)->comm,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
6883   } else {
6884     ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
6885   }
6886   PetscFunctionReturn(0);
6887 }
6888 
6889 
6890 #undef __FUNCT__
6891 #define __FUNCT__ "MatSetUnfactored"
6892 /*@
6893    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
6894 
6895    Logically Collective on Mat
6896 
6897    Input Parameter:
6898 .  mat - the factored matrix to be reset
6899 
6900    Notes:
6901    This routine should be used only with factored matrices formed by in-place
6902    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
6903    format).  This option can save memory, for example, when solving nonlinear
6904    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
6905    ILU(0) preconditioner.
6906 
6907    Note that one can specify in-place ILU(0) factorization by calling
6908 .vb
6909      PCType(pc,PCILU);
6910      PCFactorSeUseInPlace(pc);
6911 .ve
6912    or by using the options -pc_type ilu -pc_factor_in_place
6913 
6914    In-place factorization ILU(0) can also be used as a local
6915    solver for the blocks within the block Jacobi or additive Schwarz
6916    methods (runtime option: -sub_pc_factor_in_place).  See the discussion
6917    of these preconditioners in the <a href="../../docs/manual.pdf#ch_pc">PC chapter of the users manual</a> for details on setting
6918    local solver options.
6919 
6920    Most users should employ the simplified KSP interface for linear solvers
6921    instead of working directly with matrix algebra routines such as this.
6922    See, e.g., KSPCreate().
6923 
6924    Level: developer
6925 
6926 .seealso: PCFactorSetUseInPlace()
6927 
6928    Concepts: matrices^unfactored
6929 
6930 @*/
6931 PetscErrorCode  MatSetUnfactored(Mat mat)
6932 {
6933   PetscErrorCode ierr;
6934 
6935   PetscFunctionBegin;
6936   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6937   PetscValidType(mat,1);
6938   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6939   mat->factortype = MAT_FACTOR_NONE;
6940   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
6941   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
6942   PetscFunctionReturn(0);
6943 }
6944 
6945 /*MC
6946     MatGetArrayF90 - Accesses a matrix array from Fortran90.
6947 
6948     Synopsis:
6949     MatGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
6950 
6951     Not collective
6952 
6953     Input Parameter:
6954 .   x - matrix
6955 
6956     Output Parameters:
6957 +   xx_v - the Fortran90 pointer to the array
6958 -   ierr - error code
6959 
6960     Example of Usage:
6961 .vb
6962       PetscScalar, pointer xx_v(:,:)
6963       ....
6964       call MatGetArrayF90(x,xx_v,ierr)
6965       a = xx_v(3)
6966       call MatRestoreArrayF90(x,xx_v,ierr)
6967 .ve
6968 
6969     Notes:
6970     Not yet supported for all F90 compilers
6971 
6972     Level: advanced
6973 
6974 .seealso:  MatRestoreArrayF90(), MatGetArray(), MatRestoreArray()
6975 
6976     Concepts: matrices^accessing array
6977 
6978 M*/
6979 
6980 /*MC
6981     MatRestoreArrayF90 - Restores a matrix array that has been
6982     accessed with MatGetArrayF90().
6983 
6984     Synopsis:
6985     MatRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
6986 
6987     Not collective
6988 
6989     Input Parameters:
6990 +   x - matrix
6991 -   xx_v - the Fortran90 pointer to the array
6992 
6993     Output Parameter:
6994 .   ierr - error code
6995 
6996     Example of Usage:
6997 .vb
6998        PetscScalar, pointer xx_v(:)
6999        ....
7000        call MatGetArrayF90(x,xx_v,ierr)
7001        a = xx_v(3)
7002        call MatRestoreArrayF90(x,xx_v,ierr)
7003 .ve
7004 
7005     Notes:
7006     Not yet supported for all F90 compilers
7007 
7008     Level: advanced
7009 
7010 .seealso:  MatGetArrayF90(), MatGetArray(), MatRestoreArray()
7011 
7012 M*/
7013 
7014 
7015 #undef __FUNCT__
7016 #define __FUNCT__ "MatGetSubMatrix"
7017 /*@
7018     MatGetSubMatrix - Gets a single submatrix on the same number of processors
7019                       as the original matrix.
7020 
7021     Collective on Mat
7022 
7023     Input Parameters:
7024 +   mat - the original matrix
7025 .   isrow - parallel IS containing the rows this processor should obtain
7026 .   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.
7027 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7028 
7029     Output Parameter:
7030 .   newmat - the new submatrix, of the same type as the old
7031 
7032     Level: advanced
7033 
7034     Notes:
7035     The submatrix will be able to be multiplied with vectors using the same layout as iscol.
7036 
7037     The rows in isrow will be sorted into the same order as the original matrix on each process.
7038 
7039       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7040    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
7041    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7042    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
7043    you are finished using it.
7044 
7045     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7046     the input matrix.
7047 
7048     If iscol is PETSC_NULL then all columns are obtained (not supported in Fortran).
7049 
7050    Example usage:
7051    Consider the following 8x8 matrix with 34 non-zero values, that is
7052    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7053    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7054    as follows:
7055 
7056 .vb
7057             1  2  0  |  0  3  0  |  0  4
7058     Proc0   0  5  6  |  7  0  0  |  8  0
7059             9  0 10  | 11  0  0  | 12  0
7060     -------------------------------------
7061            13  0 14  | 15 16 17  |  0  0
7062     Proc1   0 18  0  | 19 20 21  |  0  0
7063             0  0  0  | 22 23  0  | 24  0
7064     -------------------------------------
7065     Proc2  25 26 27  |  0  0 28  | 29  0
7066            30  0  0  | 31 32 33  |  0 34
7067 .ve
7068 
7069     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is
7070 
7071 .vb
7072             2  0  |  0  3  0  |  0
7073     Proc0   5  6  |  7  0  0  |  8
7074     -------------------------------
7075     Proc1  18  0  | 19 20 21  |  0
7076     -------------------------------
7077     Proc2  26 27  |  0  0 28  | 29
7078             0  0  | 31 32 33  |  0
7079 .ve
7080 
7081 
7082     Concepts: matrices^submatrices
7083 
7084 .seealso: MatGetSubMatrices()
7085 @*/
7086 PetscErrorCode  MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7087 {
7088   PetscErrorCode ierr;
7089   PetscMPIInt    size;
7090   Mat            *local;
7091   IS             iscoltmp;
7092 
7093   PetscFunctionBegin;
7094   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7095   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
7096   if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
7097   PetscValidPointer(newmat,5);
7098   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5);
7099   PetscValidType(mat,1);
7100   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7101   ierr = MatPreallocated(mat);CHKERRQ(ierr);
7102   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
7103 
7104   if (!iscol) {
7105     ierr = ISCreateStride(((PetscObject)mat)->comm,mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr);
7106   } else {
7107     iscoltmp = iscol;
7108   }
7109 
7110   /* if original matrix is on just one processor then use submatrix generated */
7111   if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7112     ierr = MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
7113     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7114     PetscFunctionReturn(0);
7115   } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) {
7116     ierr    = MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
7117     *newmat = *local;
7118     ierr    = PetscFree(local);CHKERRQ(ierr);
7119     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7120     PetscFunctionReturn(0);
7121   } else if (!mat->ops->getsubmatrix) {
7122     /* Create a new matrix type that implements the operation using the full matrix */
7123     switch (cll) {
7124       case MAT_INITIAL_MATRIX:
7125         ierr = MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr);
7126         break;
7127       case MAT_REUSE_MATRIX:
7128         ierr = MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr);
7129         break;
7130       default: SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7131     }
7132     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7133     PetscFunctionReturn(0);
7134   }
7135 
7136   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7137   ierr = (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr);
7138   if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7139   if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);}
7140   PetscFunctionReturn(0);
7141 }
7142 
7143 #undef __FUNCT__
7144 #define __FUNCT__ "MatStashSetInitialSize"
7145 /*@
7146    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7147    used during the assembly process to store values that belong to
7148    other processors.
7149 
7150    Not Collective
7151 
7152    Input Parameters:
7153 +  mat   - the matrix
7154 .  size  - the initial size of the stash.
7155 -  bsize - the initial size of the block-stash(if used).
7156 
7157    Options Database Keys:
7158 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
7159 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
7160 
7161    Level: intermediate
7162 
7163    Notes:
7164      The block-stash is used for values set with MatSetValuesBlocked() while
7165      the stash is used for values set with MatSetValues()
7166 
7167      Run with the option -info and look for output of the form
7168      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7169      to determine the appropriate value, MM, to use for size and
7170      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7171      to determine the value, BMM to use for bsize
7172 
7173    Concepts: stash^setting matrix size
7174    Concepts: matrices^stash
7175 
7176 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
7177 
7178 @*/
7179 PetscErrorCode  MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7180 {
7181   PetscErrorCode ierr;
7182 
7183   PetscFunctionBegin;
7184   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7185   PetscValidType(mat,1);
7186   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
7187   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
7188   PetscFunctionReturn(0);
7189 }
7190 
7191 #undef __FUNCT__
7192 #define __FUNCT__ "MatInterpolateAdd"
7193 /*@
7194    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
7195      the matrix
7196 
7197    Neighbor-wise Collective on Mat
7198 
7199    Input Parameters:
7200 +  mat   - the matrix
7201 .  x,y - the vectors
7202 -  w - where the result is stored
7203 
7204    Level: intermediate
7205 
7206    Notes:
7207     w may be the same vector as y.
7208 
7209     This allows one to use either the restriction or interpolation (its transpose)
7210     matrix to do the interpolation
7211 
7212     Concepts: interpolation
7213 
7214 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7215 
7216 @*/
7217 PetscErrorCode  MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7218 {
7219   PetscErrorCode ierr;
7220   PetscInt       M,N,Ny;
7221 
7222   PetscFunctionBegin;
7223   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7224   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7225   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7226   PetscValidHeaderSpecific(w,VEC_CLASSID,4);
7227   PetscValidType(A,1);
7228   ierr = MatPreallocated(A);CHKERRQ(ierr);
7229   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
7230   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
7231   if (M == Ny) {
7232     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
7233   } else {
7234     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
7235   }
7236   PetscFunctionReturn(0);
7237 }
7238 
7239 #undef __FUNCT__
7240 #define __FUNCT__ "MatInterpolate"
7241 /*@
7242    MatInterpolate - y = A*x or A'*x depending on the shape of
7243      the matrix
7244 
7245    Neighbor-wise Collective on Mat
7246 
7247    Input Parameters:
7248 +  mat   - the matrix
7249 -  x,y - the vectors
7250 
7251    Level: intermediate
7252 
7253    Notes:
7254     This allows one to use either the restriction or interpolation (its transpose)
7255     matrix to do the interpolation
7256 
7257    Concepts: matrices^interpolation
7258 
7259 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7260 
7261 @*/
7262 PetscErrorCode  MatInterpolate(Mat A,Vec x,Vec y)
7263 {
7264   PetscErrorCode ierr;
7265   PetscInt       M,N,Ny;
7266 
7267   PetscFunctionBegin;
7268   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7269   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7270   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7271   PetscValidType(A,1);
7272   ierr = MatPreallocated(A);CHKERRQ(ierr);
7273   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
7274   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
7275   if (M == Ny) {
7276     ierr = MatMult(A,x,y);CHKERRQ(ierr);
7277   } else {
7278     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
7279   }
7280   PetscFunctionReturn(0);
7281 }
7282 
7283 #undef __FUNCT__
7284 #define __FUNCT__ "MatRestrict"
7285 /*@
7286    MatRestrict - y = A*x or A'*x
7287 
7288    Neighbor-wise Collective on Mat
7289 
7290    Input Parameters:
7291 +  mat   - the matrix
7292 -  x,y - the vectors
7293 
7294    Level: intermediate
7295 
7296    Notes:
7297     This allows one to use either the restriction or interpolation (its transpose)
7298     matrix to do the restriction
7299 
7300    Concepts: matrices^restriction
7301 
7302 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
7303 
7304 @*/
7305 PetscErrorCode  MatRestrict(Mat A,Vec x,Vec y)
7306 {
7307   PetscErrorCode ierr;
7308   PetscInt       M,N,Ny;
7309 
7310   PetscFunctionBegin;
7311   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7312   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7313   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7314   PetscValidType(A,1);
7315   ierr = MatPreallocated(A);CHKERRQ(ierr);
7316 
7317   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
7318   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
7319   if (M == Ny) {
7320     ierr = MatMult(A,x,y);CHKERRQ(ierr);
7321   } else {
7322     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
7323   }
7324   PetscFunctionReturn(0);
7325 }
7326 
7327 #undef __FUNCT__
7328 #define __FUNCT__ "MatSetNullSpace"
7329 /*@
7330    MatSetNullSpace - attaches a null space to a matrix.
7331         This null space will be removed from the resulting vector whenever
7332         MatMult() is called
7333 
7334    Logically Collective on Mat and MatNullSpace
7335 
7336    Input Parameters:
7337 +  mat - the matrix
7338 -  nullsp - the null space object
7339 
7340    Level: developer
7341 
7342    Notes:
7343       Overwrites any previous null space that may have been attached
7344 
7345    Concepts: null space^attaching to matrix
7346 
7347 .seealso: MatCreate(), MatNullSpaceCreate()
7348 @*/
7349 PetscErrorCode  MatSetNullSpace(Mat mat,MatNullSpace nullsp)
7350 {
7351   PetscErrorCode ierr;
7352 
7353   PetscFunctionBegin;
7354   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7355   PetscValidType(mat,1);
7356   PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
7357   ierr = MatPreallocated(mat);CHKERRQ(ierr);
7358   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
7359   if (mat->nullsp) { ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr); }
7360   mat->nullsp = nullsp;
7361   PetscFunctionReturn(0);
7362 }
7363 
7364 #undef __FUNCT__
7365 #define __FUNCT__ "MatICCFactor"
7366 /*@C
7367    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
7368 
7369    Collective on Mat
7370 
7371    Input Parameters:
7372 +  mat - the matrix
7373 .  row - row/column permutation
7374 .  fill - expected fill factor >= 1.0
7375 -  level - level of fill, for ICC(k)
7376 
7377    Notes:
7378    Probably really in-place only when level of fill is zero, otherwise allocates
7379    new space to store factored matrix and deletes previous memory.
7380 
7381    Most users should employ the simplified KSP interface for linear solvers
7382    instead of working directly with matrix algebra routines such as this.
7383    See, e.g., KSPCreate().
7384 
7385    Level: developer
7386 
7387    Concepts: matrices^incomplete Cholesky factorization
7388    Concepts: Cholesky factorization
7389 
7390 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
7391 
7392     Developer Note: fortran interface is not autogenerated as the f90
7393     interface defintion cannot be generated correctly [due to MatFactorInfo]
7394 
7395 @*/
7396 PetscErrorCode  MatICCFactor(Mat mat,IS row,const MatFactorInfo* info)
7397 {
7398   PetscErrorCode ierr;
7399 
7400   PetscFunctionBegin;
7401   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7402   PetscValidType(mat,1);
7403   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
7404   PetscValidPointer(info,3);
7405   if (mat->rmap->N != mat->cmap->N) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONG,"matrix must be square");
7406   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7407   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7408   if (!mat->ops->iccfactor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7409   ierr = MatPreallocated(mat);CHKERRQ(ierr);
7410   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
7411   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
7412   PetscFunctionReturn(0);
7413 }
7414 
7415 #undef __FUNCT__
7416 #define __FUNCT__ "MatSetValuesAdic"
7417 /*@
7418    MatSetValuesAdic - Sets values computed with ADIC automatic differentiation into a matrix.
7419 
7420    Not Collective
7421 
7422    Input Parameters:
7423 +  mat - the matrix
7424 -  v - the values compute with ADIC
7425 
7426    Level: developer
7427 
7428    Notes:
7429      Must call MatSetColoring() before using this routine. Also this matrix must already
7430      have its nonzero pattern determined.
7431 
7432 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7433           MatSetValues(), MatSetColoring(), MatSetValuesAdifor()
7434 @*/
7435 PetscErrorCode  MatSetValuesAdic(Mat mat,void *v)
7436 {
7437   PetscErrorCode ierr;
7438 
7439   PetscFunctionBegin;
7440   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7441   PetscValidType(mat,1);
7442   PetscValidPointer(mat,2);
7443 
7444   if (!mat->assembled) {
7445     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7446   }
7447   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
7448   if (!mat->ops->setvaluesadic) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7449   ierr = (*mat->ops->setvaluesadic)(mat,v);CHKERRQ(ierr);
7450   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
7451   ierr = MatView_Private(mat);CHKERRQ(ierr);
7452   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
7453   PetscFunctionReturn(0);
7454 }
7455 
7456 
7457 #undef __FUNCT__
7458 #define __FUNCT__ "MatSetColoring"
7459 /*@
7460    MatSetColoring - Sets a coloring used by calls to MatSetValuesAdic()
7461 
7462    Not Collective
7463 
7464    Input Parameters:
7465 +  mat - the matrix
7466 -  coloring - the coloring
7467 
7468    Level: developer
7469 
7470 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7471           MatSetValues(), MatSetValuesAdic()
7472 @*/
7473 PetscErrorCode  MatSetColoring(Mat mat,ISColoring coloring)
7474 {
7475   PetscErrorCode ierr;
7476 
7477   PetscFunctionBegin;
7478   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7479   PetscValidType(mat,1);
7480   PetscValidPointer(coloring,2);
7481 
7482   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7483   if (!mat->ops->setcoloring) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7484   ierr = (*mat->ops->setcoloring)(mat,coloring);CHKERRQ(ierr);
7485   PetscFunctionReturn(0);
7486 }
7487 
7488 #undef __FUNCT__
7489 #define __FUNCT__ "MatSetValuesAdifor"
7490 /*@
7491    MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.
7492 
7493    Not Collective
7494 
7495    Input Parameters:
7496 +  mat - the matrix
7497 .  nl - leading dimension of v
7498 -  v - the values compute with ADIFOR
7499 
7500    Level: developer
7501 
7502    Notes:
7503      Must call MatSetColoring() before using this routine. Also this matrix must already
7504      have its nonzero pattern determined.
7505 
7506 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7507           MatSetValues(), MatSetColoring()
7508 @*/
7509 PetscErrorCode  MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
7510 {
7511   PetscErrorCode ierr;
7512 
7513   PetscFunctionBegin;
7514   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7515   PetscValidType(mat,1);
7516   PetscValidPointer(v,3);
7517 
7518   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7519   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
7520   if (!mat->ops->setvaluesadifor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7521   ierr = (*mat->ops->setvaluesadifor)(mat,nl,v);CHKERRQ(ierr);
7522   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
7523   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
7524   PetscFunctionReturn(0);
7525 }
7526 
7527 #undef __FUNCT__
7528 #define __FUNCT__ "MatDiagonalScaleLocal"
7529 /*@
7530    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
7531          ghosted ones.
7532 
7533    Not Collective
7534 
7535    Input Parameters:
7536 +  mat - the matrix
7537 -  diag = the diagonal values, including ghost ones
7538 
7539    Level: developer
7540 
7541    Notes: Works only for MPIAIJ and MPIBAIJ matrices
7542 
7543 .seealso: MatDiagonalScale()
7544 @*/
7545 PetscErrorCode  MatDiagonalScaleLocal(Mat mat,Vec diag)
7546 {
7547   PetscErrorCode ierr;
7548   PetscMPIInt    size;
7549 
7550   PetscFunctionBegin;
7551   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7552   PetscValidHeaderSpecific(diag,VEC_CLASSID,2);
7553   PetscValidType(mat,1);
7554 
7555   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7556   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
7557   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
7558   if (size == 1) {
7559     PetscInt n,m;
7560     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
7561     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
7562     if (m == n) {
7563       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
7564     } else {
7565       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
7566     }
7567   } else {
7568     ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr);
7569   }
7570   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
7571   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
7572   PetscFunctionReturn(0);
7573 }
7574 
7575 #undef __FUNCT__
7576 #define __FUNCT__ "MatGetInertia"
7577 /*@
7578    MatGetInertia - Gets the inertia from a factored matrix
7579 
7580    Collective on Mat
7581 
7582    Input Parameter:
7583 .  mat - the matrix
7584 
7585    Output Parameters:
7586 +   nneg - number of negative eigenvalues
7587 .   nzero - number of zero eigenvalues
7588 -   npos - number of positive eigenvalues
7589 
7590    Level: advanced
7591 
7592    Notes: Matrix must have been factored by MatCholeskyFactor()
7593 
7594 
7595 @*/
7596 PetscErrorCode  MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
7597 {
7598   PetscErrorCode ierr;
7599 
7600   PetscFunctionBegin;
7601   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7602   PetscValidType(mat,1);
7603   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7604   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
7605   if (!mat->ops->getinertia) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7606   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
7607   PetscFunctionReturn(0);
7608 }
7609 
7610 /* ----------------------------------------------------------------*/
7611 #undef __FUNCT__
7612 #define __FUNCT__ "MatSolves"
7613 /*@C
7614    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
7615 
7616    Neighbor-wise Collective on Mat and Vecs
7617 
7618    Input Parameters:
7619 +  mat - the factored matrix
7620 -  b - the right-hand-side vectors
7621 
7622    Output Parameter:
7623 .  x - the result vectors
7624 
7625    Notes:
7626    The vectors b and x cannot be the same.  I.e., one cannot
7627    call MatSolves(A,x,x).
7628 
7629    Notes:
7630    Most users should employ the simplified KSP interface for linear solvers
7631    instead of working directly with matrix algebra routines such as this.
7632    See, e.g., KSPCreate().
7633 
7634    Level: developer
7635 
7636    Concepts: matrices^triangular solves
7637 
7638 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
7639 @*/
7640 PetscErrorCode  MatSolves(Mat mat,Vecs b,Vecs x)
7641 {
7642   PetscErrorCode ierr;
7643 
7644   PetscFunctionBegin;
7645   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7646   PetscValidType(mat,1);
7647   if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
7648   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7649   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
7650 
7651   if (!mat->ops->solves) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7652   ierr = MatPreallocated(mat);CHKERRQ(ierr);
7653   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
7654   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
7655   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
7656   PetscFunctionReturn(0);
7657 }
7658 
7659 #undef __FUNCT__
7660 #define __FUNCT__ "MatIsSymmetric"
7661 /*@
7662    MatIsSymmetric - Test whether a matrix is symmetric
7663 
7664    Collective on Mat
7665 
7666    Input Parameter:
7667 +  A - the matrix to test
7668 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
7669 
7670    Output Parameters:
7671 .  flg - the result
7672 
7673    Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
7674 
7675    Level: intermediate
7676 
7677    Concepts: matrix^symmetry
7678 
7679 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
7680 @*/
7681 PetscErrorCode  MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
7682 {
7683   PetscErrorCode ierr;
7684 
7685   PetscFunctionBegin;
7686   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7687   PetscValidPointer(flg,2);
7688 
7689   if (!A->symmetric_set) {
7690     if (!A->ops->issymmetric) {
7691       const MatType mattype;
7692       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7693       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7694     }
7695     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
7696     if (!tol) {
7697       A->symmetric_set = PETSC_TRUE;
7698       A->symmetric = *flg;
7699       if (A->symmetric) {
7700 	A->structurally_symmetric_set = PETSC_TRUE;
7701 	A->structurally_symmetric     = PETSC_TRUE;
7702       }
7703     }
7704   } else if (A->symmetric) {
7705     *flg = PETSC_TRUE;
7706   } else if (!tol) {
7707     *flg = PETSC_FALSE;
7708   } else {
7709     if (!A->ops->issymmetric) {
7710       const MatType mattype;
7711       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7712       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7713     }
7714     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
7715   }
7716   PetscFunctionReturn(0);
7717 }
7718 
7719 #undef __FUNCT__
7720 #define __FUNCT__ "MatIsHermitian"
7721 /*@
7722    MatIsHermitian - Test whether a matrix is Hermitian
7723 
7724    Collective on Mat
7725 
7726    Input Parameter:
7727 +  A - the matrix to test
7728 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
7729 
7730    Output Parameters:
7731 .  flg - the result
7732 
7733    Level: intermediate
7734 
7735    Concepts: matrix^symmetry
7736 
7737 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
7738           MatIsSymmetricKnown(), MatIsSymmetric()
7739 @*/
7740 PetscErrorCode  MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
7741 {
7742   PetscErrorCode ierr;
7743 
7744   PetscFunctionBegin;
7745   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7746   PetscValidPointer(flg,2);
7747 
7748   if (!A->hermitian_set) {
7749     if (!A->ops->ishermitian) {
7750       const MatType mattype;
7751       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7752       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7753     }
7754     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
7755     if (!tol) {
7756       A->hermitian_set = PETSC_TRUE;
7757       A->hermitian = *flg;
7758       if (A->hermitian) {
7759 	A->structurally_symmetric_set = PETSC_TRUE;
7760 	A->structurally_symmetric     = PETSC_TRUE;
7761       }
7762     }
7763   } else if (A->hermitian) {
7764     *flg = PETSC_TRUE;
7765   } else if (!tol) {
7766     *flg = PETSC_FALSE;
7767   } else {
7768     if (!A->ops->ishermitian) {
7769       const MatType mattype;
7770       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7771       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7772     }
7773     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
7774   }
7775   PetscFunctionReturn(0);
7776 }
7777 
7778 #undef __FUNCT__
7779 #define __FUNCT__ "MatIsSymmetricKnown"
7780 /*@
7781    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
7782 
7783    Not Collective
7784 
7785    Input Parameter:
7786 .  A - the matrix to check
7787 
7788    Output Parameters:
7789 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
7790 -  flg - the result
7791 
7792    Level: advanced
7793 
7794    Concepts: matrix^symmetry
7795 
7796    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
7797          if you want it explicitly checked
7798 
7799 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
7800 @*/
7801 PetscErrorCode  MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
7802 {
7803   PetscFunctionBegin;
7804   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7805   PetscValidPointer(set,2);
7806   PetscValidPointer(flg,3);
7807   if (A->symmetric_set) {
7808     *set = PETSC_TRUE;
7809     *flg = A->symmetric;
7810   } else {
7811     *set = PETSC_FALSE;
7812   }
7813   PetscFunctionReturn(0);
7814 }
7815 
7816 #undef __FUNCT__
7817 #define __FUNCT__ "MatIsHermitianKnown"
7818 /*@
7819    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
7820 
7821    Not Collective
7822 
7823    Input Parameter:
7824 .  A - the matrix to check
7825 
7826    Output Parameters:
7827 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
7828 -  flg - the result
7829 
7830    Level: advanced
7831 
7832    Concepts: matrix^symmetry
7833 
7834    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
7835          if you want it explicitly checked
7836 
7837 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
7838 @*/
7839 PetscErrorCode  MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
7840 {
7841   PetscFunctionBegin;
7842   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7843   PetscValidPointer(set,2);
7844   PetscValidPointer(flg,3);
7845   if (A->hermitian_set) {
7846     *set = PETSC_TRUE;
7847     *flg = A->hermitian;
7848   } else {
7849     *set = PETSC_FALSE;
7850   }
7851   PetscFunctionReturn(0);
7852 }
7853 
7854 #undef __FUNCT__
7855 #define __FUNCT__ "MatIsStructurallySymmetric"
7856 /*@
7857    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
7858 
7859    Collective on Mat
7860 
7861    Input Parameter:
7862 .  A - the matrix to test
7863 
7864    Output Parameters:
7865 .  flg - the result
7866 
7867    Level: intermediate
7868 
7869    Concepts: matrix^symmetry
7870 
7871 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
7872 @*/
7873 PetscErrorCode  MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
7874 {
7875   PetscErrorCode ierr;
7876 
7877   PetscFunctionBegin;
7878   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7879   PetscValidPointer(flg,2);
7880   if (!A->structurally_symmetric_set) {
7881     if (!A->ops->isstructurallysymmetric) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
7882     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
7883     A->structurally_symmetric_set = PETSC_TRUE;
7884   }
7885   *flg = A->structurally_symmetric;
7886   PetscFunctionReturn(0);
7887 }
7888 
7889 #undef __FUNCT__
7890 #define __FUNCT__ "MatStashGetInfo"
7891 extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
7892 /*@
7893    MatStashGetInfo - Gets how many values are currently in the vector stash, i.e. need
7894        to be communicated to other processors during the MatAssemblyBegin/End() process
7895 
7896     Not collective
7897 
7898    Input Parameter:
7899 .   vec - the vector
7900 
7901    Output Parameters:
7902 +   nstash   - the size of the stash
7903 .   reallocs - the number of additional mallocs incurred.
7904 .   bnstash   - the size of the block stash
7905 -   breallocs - the number of additional mallocs incurred.in the block stash
7906 
7907    Level: advanced
7908 
7909 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
7910 
7911 @*/
7912 PetscErrorCode  MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
7913 {
7914   PetscErrorCode ierr;
7915   PetscFunctionBegin;
7916   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
7917   ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
7918   PetscFunctionReturn(0);
7919 }
7920 
7921 #undef __FUNCT__
7922 #define __FUNCT__ "MatGetVecs"
7923 /*@C
7924    MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same
7925      parallel layout
7926 
7927    Collective on Mat
7928 
7929    Input Parameter:
7930 .  mat - the matrix
7931 
7932    Output Parameter:
7933 +   right - (optional) vector that the matrix can be multiplied against
7934 -   left - (optional) vector that the matrix vector product can be stored in
7935 
7936   Level: advanced
7937 
7938 .seealso: MatCreate()
7939 @*/
7940 PetscErrorCode  MatGetVecs(Mat mat,Vec *right,Vec *left)
7941 {
7942   PetscErrorCode ierr;
7943 
7944   PetscFunctionBegin;
7945   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7946   PetscValidType(mat,1);
7947   ierr = MatPreallocated(mat);CHKERRQ(ierr);
7948   if (mat->ops->getvecs) {
7949     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
7950   } else {
7951     PetscMPIInt size;
7952     ierr = MPI_Comm_size(((PetscObject)mat)->comm, &size);CHKERRQ(ierr);
7953     if (right) {
7954       ierr = VecCreate(((PetscObject)mat)->comm,right);CHKERRQ(ierr);
7955       ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
7956       ierr = VecSetBlockSize(*right,mat->rmap->bs);CHKERRQ(ierr);
7957       ierr = VecSetType(*right,VECSTANDARD);CHKERRQ(ierr);
7958       ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr);
7959     }
7960     if (left) {
7961       ierr = VecCreate(((PetscObject)mat)->comm,left);CHKERRQ(ierr);
7962       ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
7963       ierr = VecSetBlockSize(*left,mat->rmap->bs);CHKERRQ(ierr);
7964       ierr = VecSetType(*left,VECSTANDARD);CHKERRQ(ierr);
7965       ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr);
7966     }
7967   }
7968   PetscFunctionReturn(0);
7969 }
7970 
7971 #undef __FUNCT__
7972 #define __FUNCT__ "MatFactorInfoInitialize"
7973 /*@C
7974    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
7975      with default values.
7976 
7977    Not Collective
7978 
7979    Input Parameters:
7980 .    info - the MatFactorInfo data structure
7981 
7982 
7983    Notes: The solvers are generally used through the KSP and PC objects, for example
7984           PCLU, PCILU, PCCHOLESKY, PCICC
7985 
7986    Level: developer
7987 
7988 .seealso: MatFactorInfo
7989 
7990     Developer Note: fortran interface is not autogenerated as the f90
7991     interface defintion cannot be generated correctly [due to MatFactorInfo]
7992 
7993 @*/
7994 
7995 PetscErrorCode  MatFactorInfoInitialize(MatFactorInfo *info)
7996 {
7997   PetscErrorCode ierr;
7998 
7999   PetscFunctionBegin;
8000   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
8001   PetscFunctionReturn(0);
8002 }
8003 
8004 #undef __FUNCT__
8005 #define __FUNCT__ "MatPtAP"
8006 /*@
8007    MatPtAP - Creates the matrix product C = P^T * A * P
8008 
8009    Neighbor-wise Collective on Mat
8010 
8011    Input Parameters:
8012 +  A - the matrix
8013 .  P - the projection matrix
8014 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8015 -  fill - expected fill as ratio of nnz(C)/nnz(A)
8016 
8017    Output Parameters:
8018 .  C - the product matrix
8019 
8020    Notes:
8021    C will be created and must be destroyed by the user with MatDestroy().
8022 
8023    This routine is currently only implemented for pairs of AIJ matrices and classes
8024    which inherit from AIJ.
8025 
8026    Level: intermediate
8027 
8028 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult()
8029 @*/
8030 PetscErrorCode  MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
8031 {
8032   PetscErrorCode ierr;
8033 
8034   PetscFunctionBegin;
8035   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8036   PetscValidType(A,1);
8037   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8038   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8039   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
8040   PetscValidType(P,2);
8041   ierr = MatPreallocated(P);CHKERRQ(ierr);
8042   if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8043   if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8044   PetscValidPointer(C,3);
8045   if (P->rmap->N!=A->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
8046   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8047   ierr = MatPreallocated(A);CHKERRQ(ierr);
8048 
8049   if (!A->ops->ptap) {
8050     const MatType mattype;
8051     ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8052     SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix of type <%s> does not support PtAP",mattype);
8053   }
8054   ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
8055   ierr = (*A->ops->ptap)(A,P,scall,fill,C);CHKERRQ(ierr);
8056   ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
8057 
8058   PetscFunctionReturn(0);
8059 }
8060 
8061 #undef __FUNCT__
8062 #define __FUNCT__ "MatPtAPNumeric"
8063 /*@
8064    MatPtAPNumeric - Computes the matrix product C = P^T * A * P
8065 
8066    Neighbor-wise Collective on Mat
8067 
8068    Input Parameters:
8069 +  A - the matrix
8070 -  P - the projection matrix
8071 
8072    Output Parameters:
8073 .  C - the product matrix
8074 
8075    Notes:
8076    C must have been created by calling MatPtAPSymbolic and must be destroyed by
8077    the user using MatDeatroy().
8078 
8079    This routine is currently only implemented for pairs of AIJ matrices and classes
8080    which inherit from AIJ.  C will be of type MATAIJ.
8081 
8082    Level: intermediate
8083 
8084 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
8085 @*/
8086 PetscErrorCode  MatPtAPNumeric(Mat A,Mat P,Mat C)
8087 {
8088   PetscErrorCode ierr;
8089 
8090   PetscFunctionBegin;
8091   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8092   PetscValidType(A,1);
8093   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8094   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8095   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
8096   PetscValidType(P,2);
8097   ierr = MatPreallocated(P);CHKERRQ(ierr);
8098   if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8099   if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8100   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
8101   PetscValidType(C,3);
8102   ierr = MatPreallocated(C);CHKERRQ(ierr);
8103   if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8104   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);
8105   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);
8106   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);
8107   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);
8108   ierr = MatPreallocated(A);CHKERRQ(ierr);
8109 
8110   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
8111   ierr = (*A->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr);
8112   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
8113   PetscFunctionReturn(0);
8114 }
8115 
8116 #undef __FUNCT__
8117 #define __FUNCT__ "MatPtAPSymbolic"
8118 /*@
8119    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P
8120 
8121    Neighbor-wise Collective on Mat
8122 
8123    Input Parameters:
8124 +  A - the matrix
8125 -  P - the projection matrix
8126 
8127    Output Parameters:
8128 .  C - the (i,j) structure of the product matrix
8129 
8130    Notes:
8131    C will be created and must be destroyed by the user with MatDestroy().
8132 
8133    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
8134    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
8135    this (i,j) structure by calling MatPtAPNumeric().
8136 
8137    Level: intermediate
8138 
8139 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
8140 @*/
8141 PetscErrorCode  MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
8142 {
8143   PetscErrorCode ierr;
8144 
8145   PetscFunctionBegin;
8146   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8147   PetscValidType(A,1);
8148   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8149   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8150   if (fill <1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8151   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
8152   PetscValidType(P,2);
8153   ierr = MatPreallocated(P);CHKERRQ(ierr);
8154   if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8155   if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8156   PetscValidPointer(C,3);
8157 
8158   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);
8159   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);
8160   ierr = MatPreallocated(A);CHKERRQ(ierr);
8161   ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
8162   ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr);
8163   ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
8164 
8165   ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr);
8166 
8167   PetscFunctionReturn(0);
8168 }
8169 
8170 #undef __FUNCT__
8171 #define __FUNCT__ "MatMatMult"
8172 /*@
8173    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
8174 
8175    Neighbor-wise Collective on Mat
8176 
8177    Input Parameters:
8178 +  A - the left matrix
8179 .  B - the right matrix
8180 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8181 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
8182           if the result is a dense matrix this is irrelevent
8183 
8184    Output Parameters:
8185 .  C - the product matrix
8186 
8187    Notes:
8188    Unless scall is MAT_REUSE_MATRIX C will be created.
8189 
8190    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8191 
8192    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8193    actually needed.
8194 
8195    If you have many matrices with the same non-zero structure to multiply, you
8196    should either
8197 $   1) use MAT_REUSE_MATRIX in all calls but the first or
8198 $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
8199 
8200    Level: intermediate
8201 
8202 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatPtAP()
8203 @*/
8204 PetscErrorCode  MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8205 {
8206   PetscErrorCode ierr;
8207   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8208   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8209   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat *)=PETSC_NULL;
8210 
8211   PetscFunctionBegin;
8212   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8213   PetscValidType(A,1);
8214   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8215   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8216   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8217   PetscValidType(B,2);
8218   ierr = MatPreallocated(B);CHKERRQ(ierr);
8219   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8220   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8221   PetscValidPointer(C,3);
8222   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);
8223   if (scall == MAT_REUSE_MATRIX){
8224     PetscValidPointer(*C,5);
8225     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
8226   }
8227   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8228   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8229   ierr = MatPreallocated(A);CHKERRQ(ierr);
8230 
8231   fA = A->ops->matmult;
8232   fB = B->ops->matmult;
8233   if (fB == fA) {
8234     if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
8235     mult = fB;
8236   } else {
8237     /* dispatch based on the type of A and B */
8238     char  multname[256];
8239     ierr = PetscStrcpy(multname,"MatMatMult_");CHKERRQ(ierr);
8240     ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr);
8241     ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);
8242     ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr);
8243     ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
8244     ierr = PetscObjectQueryFunction((PetscObject)B,multname,(void (**)(void))&mult);CHKERRQ(ierr);
8245     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);
8246   }
8247   ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
8248   ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr);
8249   ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
8250   PetscFunctionReturn(0);
8251 }
8252 
8253 #undef __FUNCT__
8254 #define __FUNCT__ "MatMatMultSymbolic"
8255 /*@
8256    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
8257    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().
8258 
8259    Neighbor-wise Collective on Mat
8260 
8261    Input Parameters:
8262 +  A - the left matrix
8263 .  B - the right matrix
8264 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
8265       if C is a dense matrix this is irrelevent
8266 
8267    Output Parameters:
8268 .  C - the product matrix
8269 
8270    Notes:
8271    Unless scall is MAT_REUSE_MATRIX C will be created.
8272 
8273    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8274    actually needed.
8275 
8276    This routine is currently implemented for
8277     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
8278     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8279     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
8280 
8281    Level: intermediate
8282 
8283    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
8284      We should incorporate them into PETSc.
8285 
8286 .seealso: MatMatMult(), MatMatMultNumeric()
8287 @*/
8288 PetscErrorCode  MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
8289 {
8290   PetscErrorCode ierr;
8291   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat *);
8292   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat *);
8293   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat *)=PETSC_NULL;
8294 
8295   PetscFunctionBegin;
8296   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8297   PetscValidType(A,1);
8298   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8299   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8300 
8301   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8302   PetscValidType(B,2);
8303   ierr = MatPreallocated(B);CHKERRQ(ierr);
8304   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8305   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8306   PetscValidPointer(C,3);
8307 
8308   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);
8309   if (fill == PETSC_DEFAULT) fill = 2.0;
8310   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8311   ierr = MatPreallocated(A);CHKERRQ(ierr);
8312 
8313   Asymbolic = A->ops->matmultsymbolic;
8314   Bsymbolic = B->ops->matmultsymbolic;
8315   if (Asymbolic == Bsymbolic){
8316     if (!Bsymbolic) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
8317     symbolic = Bsymbolic;
8318   } else { /* dispatch based on the type of A and B */
8319     char  symbolicname[256];
8320     ierr = PetscStrcpy(symbolicname,"MatMatMultSymbolic_");CHKERRQ(ierr);
8321     ierr = PetscStrcat(symbolicname,((PetscObject)A)->type_name);CHKERRQ(ierr);
8322     ierr = PetscStrcat(symbolicname,"_");CHKERRQ(ierr);
8323     ierr = PetscStrcat(symbolicname,((PetscObject)B)->type_name);CHKERRQ(ierr);
8324     ierr = PetscStrcat(symbolicname,"_C");CHKERRQ(ierr);
8325     ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,(void (**)(void))&symbolic);CHKERRQ(ierr);
8326     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);
8327   }
8328   ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
8329   ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr);
8330   ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
8331   PetscFunctionReturn(0);
8332 }
8333 
8334 #undef __FUNCT__
8335 #define __FUNCT__ "MatMatMultNumeric"
8336 /*@
8337    MatMatMultNumeric - Performs the numeric matrix-matrix product.
8338    Call this routine after first calling MatMatMultSymbolic().
8339 
8340    Neighbor-wise Collective on Mat
8341 
8342    Input Parameters:
8343 +  A - the left matrix
8344 -  B - the right matrix
8345 
8346    Output Parameters:
8347 .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
8348 
8349    Notes:
8350    C must have been created with MatMatMultSymbolic().
8351 
8352    This routine is currently implemented for
8353     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
8354     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8355     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
8356 
8357    Level: intermediate
8358 
8359 .seealso: MatMatMult(), MatMatMultSymbolic()
8360 @*/
8361 PetscErrorCode  MatMatMultNumeric(Mat A,Mat B,Mat C)
8362 {
8363   PetscErrorCode ierr;
8364   PetscErrorCode (*Anumeric)(Mat,Mat,Mat);
8365   PetscErrorCode (*Bnumeric)(Mat,Mat,Mat);
8366   PetscErrorCode (*numeric)(Mat,Mat,Mat)=PETSC_NULL;
8367 
8368   PetscFunctionBegin;
8369   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8370   PetscValidType(A,1);
8371   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8372   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8373 
8374   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8375   PetscValidType(B,2);
8376   ierr = MatPreallocated(B);CHKERRQ(ierr);
8377   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8378   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8379 
8380   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
8381   PetscValidType(C,3);
8382   ierr = MatPreallocated(C);CHKERRQ(ierr);
8383   if (!C->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8384   if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8385 
8386   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);
8387   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);
8388   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);
8389   ierr = MatPreallocated(A);CHKERRQ(ierr);
8390 
8391   Anumeric = A->ops->matmultnumeric;
8392   Bnumeric = B->ops->matmultnumeric;
8393   if (Anumeric == Bnumeric){
8394     if (!Bnumeric) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMultNumeric not supported for B of type %s",((PetscObject)B)->type_name);
8395     numeric = Bnumeric;
8396   } else {
8397     char  numericname[256];
8398     ierr = PetscStrcpy(numericname,"MatMatMultNumeric_");CHKERRQ(ierr);
8399     ierr = PetscStrcat(numericname,((PetscObject)A)->type_name);CHKERRQ(ierr);
8400     ierr = PetscStrcat(numericname,"_");CHKERRQ(ierr);
8401     ierr = PetscStrcat(numericname,((PetscObject)B)->type_name);CHKERRQ(ierr);
8402     ierr = PetscStrcat(numericname,"_C");CHKERRQ(ierr);
8403     ierr = PetscObjectQueryFunction((PetscObject)B,numericname,(void (**)(void))&numeric);CHKERRQ(ierr);
8404     if (!numeric)
8405       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);
8406   }
8407   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
8408   ierr = (*numeric)(A,B,C);CHKERRQ(ierr);
8409   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
8410   PetscFunctionReturn(0);
8411 }
8412 
8413 #undef __FUNCT__
8414 #define __FUNCT__ "MatMatMultTranspose"
8415 /*@
8416    MatMatMultTranspose - Performs Matrix-Matrix Multiplication C=A^T*B.
8417 
8418    Neighbor-wise Collective on Mat
8419 
8420    Input Parameters:
8421 +  A - the left matrix
8422 .  B - the right matrix
8423 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8424 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
8425 
8426    Output Parameters:
8427 .  C - the product matrix
8428 
8429    Notes:
8430    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
8431 
8432    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8433 
8434   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8435    actually needed.
8436 
8437    This routine is currently only implemented for pairs of SeqAIJ matrices and pairs of SeqDense matrices and classes
8438    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.
8439 
8440    Level: intermediate
8441 
8442 .seealso: MatMatMultTransposeSymbolic(), MatMatMultTransposeNumeric(), MatPtAP()
8443 @*/
8444 PetscErrorCode  MatMatMultTranspose(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8445 {
8446   PetscErrorCode ierr;
8447   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8448   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8449 
8450   PetscFunctionBegin;
8451   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8452   PetscValidType(A,1);
8453   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8454   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8455   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8456   PetscValidType(B,2);
8457   ierr = MatPreallocated(B);CHKERRQ(ierr);
8458   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8459   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8460   PetscValidPointer(C,3);
8461   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);
8462   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8463   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8464   ierr = MatPreallocated(A);CHKERRQ(ierr);
8465 
8466   fA = A->ops->matmulttranspose;
8467   if (!fA) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMultTranspose not supported for A of type %s",((PetscObject)A)->type_name);
8468   fB = B->ops->matmulttranspose;
8469   if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMultTranspose not supported for B of type %s",((PetscObject)B)->type_name);
8470   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);
8471 
8472   ierr = PetscLogEventBegin(MAT_MatMultTranspose,A,B,0,0);CHKERRQ(ierr);
8473   ierr = (*A->ops->matmulttranspose)(A,B,scall,fill,C);CHKERRQ(ierr);
8474   ierr = PetscLogEventEnd(MAT_MatMultTranspose,A,B,0,0);CHKERRQ(ierr);
8475 
8476   PetscFunctionReturn(0);
8477 }
8478 
8479 #undef __FUNCT__
8480 #define __FUNCT__ "MatGetRedundantMatrix"
8481 /*@C
8482    MatGetRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
8483 
8484    Collective on Mat
8485 
8486    Input Parameters:
8487 +  mat - the matrix
8488 .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
8489 .  subcomm - MPI communicator split from the communicator where mat resides in
8490 .  mlocal_red - number of local rows of the redundant matrix
8491 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8492 
8493    Output Parameter:
8494 .  matredundant - redundant matrix
8495 
8496    Notes:
8497    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
8498    original matrix has not changed from that last call to MatGetRedundantMatrix().
8499 
8500    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
8501    calling it.
8502 
8503    Only MPIAIJ matrix is supported.
8504 
8505    Level: advanced
8506 
8507    Concepts: subcommunicator
8508    Concepts: duplicate matrix
8509 
8510 .seealso: MatDestroy()
8511 @*/
8512 PetscErrorCode  MatGetRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,PetscInt mlocal_red,MatReuse reuse,Mat *matredundant)
8513 {
8514   PetscErrorCode ierr;
8515 
8516   PetscFunctionBegin;
8517   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8518   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
8519     PetscValidPointer(*matredundant,6);
8520     PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,6);
8521   }
8522   if (!mat->ops->getredundantmatrix) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8523   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8524   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8525   ierr = MatPreallocated(mat);CHKERRQ(ierr);
8526 
8527   ierr = PetscLogEventBegin(MAT_GetRedundantMatrix,mat,0,0,0);CHKERRQ(ierr);
8528   ierr = (*mat->ops->getredundantmatrix)(mat,nsubcomm,subcomm,mlocal_red,reuse,matredundant);CHKERRQ(ierr);
8529   ierr = PetscLogEventEnd(MAT_GetRedundantMatrix,mat,0,0,0);CHKERRQ(ierr);
8530   PetscFunctionReturn(0);
8531 }
8532 
8533 #undef __FUNCT__
8534 #define __FUNCT__ "MatGetMultiProcBlock"
8535 /*@C
8536    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
8537    a given 'mat' object. Each submatrix can span multiple procs.
8538 
8539    Collective on Mat
8540 
8541    Input Parameters:
8542 +  mat - the matrix
8543 -  subcomm - the subcommunicator obtained by com_split(comm)
8544 
8545    Output Parameter:
8546 .  subMat - 'parallel submatrices each spans a given subcomm
8547 
8548   Notes:
8549   The submatrix partition across processors is dicated by 'subComm' a
8550   communicator obtained by com_split(comm). The comm_split
8551   is not restriced to be grouped with consequitive original ranks.
8552 
8553   Due the comm_split() usage, the parallel layout of the submatrices
8554   map directly to the layout of the original matrix [wrt the local
8555   row,col partitioning]. So the original 'DiagonalMat' naturally maps
8556   into the 'DiagonalMat' of the subMat, hence it is used directly from
8557   the subMat. However the offDiagMat looses some columns - and this is
8558   reconstructed with MatSetValues()
8559 
8560   Level: advanced
8561 
8562   Concepts: subcommunicator
8563   Concepts: submatrices
8564 
8565 .seealso: MatGetSubMatrices()
8566 @*/
8567 PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, Mat* subMat)
8568 {
8569   PetscErrorCode ierr;
8570   PetscMPIInt    commsize,subCommSize;
8571 
8572   PetscFunctionBegin;
8573   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&commsize);CHKERRQ(ierr);
8574   ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr);
8575   if (subCommSize > commsize) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
8576 
8577   ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
8578   ierr = (*mat->ops->getmultiprocblock)(mat,subComm,subMat);CHKERRQ(ierr);
8579   ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
8580   PetscFunctionReturn(0);
8581 }
8582 
8583 #undef __FUNCT__
8584 #define __FUNCT__ "MatGetLocalSubMatrix"
8585 /*@
8586    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
8587 
8588    Not Collective
8589 
8590    Input Arguments:
8591    mat - matrix to extract local submatrix from
8592    isrow - local row indices for submatrix
8593    iscol - local column indices for submatrix
8594 
8595    Output Arguments:
8596    submat - the submatrix
8597 
8598    Level: intermediate
8599 
8600    Notes:
8601    The submat should be returned with MatRestoreLocalSubMatrix().
8602 
8603    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
8604    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
8605 
8606    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
8607    MatSetValuesBlockedLocal() will also be implemented.
8608 
8609 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef()
8610 @*/
8611 PetscErrorCode  MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
8612 {
8613   PetscErrorCode ierr;
8614 
8615   PetscFunctionBegin;
8616   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8617   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
8618   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
8619   PetscCheckSameComm(isrow,2,iscol,3);
8620   PetscValidPointer(submat,4);
8621 
8622   if (mat->ops->getlocalsubmatrix) {
8623     ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
8624   } else {
8625     ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr);
8626   }
8627   PetscFunctionReturn(0);
8628 }
8629 
8630 #undef __FUNCT__
8631 #define __FUNCT__ "MatRestoreLocalSubMatrix"
8632 /*@
8633    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
8634 
8635    Not Collective
8636 
8637    Input Arguments:
8638    mat - matrix to extract local submatrix from
8639    isrow - local row indices for submatrix
8640    iscol - local column indices for submatrix
8641    submat - the submatrix
8642 
8643    Level: intermediate
8644 
8645 .seealso: MatGetLocalSubMatrix()
8646 @*/
8647 PetscErrorCode  MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
8648 {
8649   PetscErrorCode ierr;
8650 
8651   PetscFunctionBegin;
8652   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8653   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
8654   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
8655   PetscCheckSameComm(isrow,2,iscol,3);
8656   PetscValidPointer(submat,4);
8657   if (*submat) {PetscValidHeaderSpecific(*submat,MAT_CLASSID,4);}
8658 
8659   if (mat->ops->restorelocalsubmatrix) {
8660     ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
8661   } else {
8662     ierr = MatDestroy(submat);CHKERRQ(ierr);
8663   }
8664   *submat = PETSC_NULL;
8665   PetscFunctionReturn(0);
8666 }
8667 
8668 /* --------------------------------------------------------*/
8669 #undef __FUNCT__
8670 #define __FUNCT__ "MatFindZeroDiagonals"
8671 /*@
8672    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no entry in the matrix
8673 
8674    Collective on Mat
8675 
8676    Input Parameter:
8677 .  mat - the matrix
8678 
8679    Output Parameter:
8680 .  is - if any rows have zero diagonals this contains the list of them
8681 
8682    Level: developer
8683 
8684    Concepts: matrix-vector product
8685 
8686 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
8687 @*/
8688 PetscErrorCode  MatFindZeroDiagonals(Mat mat,IS *is)
8689 {
8690   PetscErrorCode ierr;
8691 
8692   PetscFunctionBegin;
8693   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8694   PetscValidType(mat,1);
8695   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8696   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8697 
8698   if (!mat->ops->findzerodiagonals) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"This matrix type does not have a find zero diagonals defined");
8699   ierr = (*mat->ops->findzerodiagonals)(mat,is);CHKERRQ(ierr);
8700   PetscFunctionReturn(0);
8701 }
8702 
8703 #undef __FUNCT__
8704 #define __FUNCT__ "MatInvertBlockDiagonal"
8705 /*@
8706   MatInvertBlockDiagonal - Inverts the block diagonal entries.
8707 
8708   Collective on Mat
8709 
8710   Input Parameters:
8711 . mat - the matrix
8712 
8713   Output Parameters:
8714 . values - the block inverses in column major order (FORTRAN-like)
8715 
8716   Level: advanced
8717 @*/
8718 PetscErrorCode  MatInvertBlockDiagonal(Mat mat,PetscScalar **values)
8719 {
8720   PetscErrorCode ierr;
8721 
8722   PetscFunctionBegin;
8723   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8724   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8725   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8726   if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
8727   ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr);
8728   PetscFunctionReturn(0);
8729 }
8730