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