xref: /petsc/src/mat/interface/matrix.c (revision 112444f445afd2ff3b13d8a223b16527a1e55859)
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 users manual)
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 users manual 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 users manual)
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.
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;
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     for(j = 0; j < 3-sdim; ++j) dxm++;
5250     tmp = *dxm++ - starts[0];
5251     for(j = 0; j < dim-1; ++j) {
5252       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5253       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5254     }
5255     if (mat->stencil.noc) dxm++;
5256     jdxm[i] = tmp;
5257   }
5258   ierr = MatZeroRowsLocal(mat,numRows,jdxm,diag);CHKERRQ(ierr);
5259   ierr = PetscFree(jdxm);CHKERRQ(ierr);
5260   PetscFunctionReturn(0);
5261 }
5262 
5263 #undef __FUNCT__
5264 #define __FUNCT__ "MatZeroRowsLocal"
5265 /*@C
5266    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
5267    of a set of rows of a matrix; using local numbering of rows.
5268 
5269    Logically Collective on Mat
5270 
5271    Input Parameters:
5272 +  mat - the matrix
5273 .  numRows - the number of rows to remove
5274 .  rows - the global row indices
5275 -  diag - value put in all diagonals of eliminated rows
5276 
5277    Notes:
5278    Before calling MatZeroRowsLocal(), the user must first set the
5279    local-to-global mapping by calling MatSetLocalToGlobalMapping().
5280 
5281    For the AIJ matrix formats this removes the old nonzero structure,
5282    but does not release memory.  For the dense and block diagonal
5283    formats this does not alter the nonzero structure.
5284 
5285    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5286    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5287    merely zeroed.
5288 
5289    The user can set a value in the diagonal entry (or for the AIJ and
5290    row formats can optionally remove the main diagonal entry from the
5291    nonzero structure as well, by passing 0.0 as the final argument).
5292 
5293    Level: intermediate
5294 
5295    Concepts: matrices^zeroing
5296 
5297 .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5298 @*/
5299 PetscErrorCode PETSCMAT_DLLEXPORT MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag)
5300 {
5301   PetscErrorCode ierr;
5302 
5303   PetscFunctionBegin;
5304   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5305   PetscValidType(mat,1);
5306   if (numRows) PetscValidIntPointer(rows,3);
5307   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5308   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5309   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5310 
5311   if (mat->ops->zerorowslocal) {
5312     ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag);CHKERRQ(ierr);
5313   } else {
5314     IS             is, newis;
5315     const PetscInt *newRows;
5316 
5317     if (!mat->mapping) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5318     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,&is);CHKERRQ(ierr);
5319     ierr = ISLocalToGlobalMappingApplyIS(mat->mapping,is,&newis);CHKERRQ(ierr);
5320     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
5321     ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag);CHKERRQ(ierr);
5322     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
5323     ierr = ISDestroy(newis);CHKERRQ(ierr);
5324     ierr = ISDestroy(is);CHKERRQ(ierr);
5325   }
5326   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5327   PetscFunctionReturn(0);
5328 }
5329 
5330 #undef __FUNCT__
5331 #define __FUNCT__ "MatZeroRowsLocalIS"
5332 /*@C
5333    MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
5334    of a set of rows of a matrix; using local numbering of rows.
5335 
5336    Logically Collective on Mat
5337 
5338    Input Parameters:
5339 +  mat - the matrix
5340 .  is - index set of rows to remove
5341 -  diag - value put in all diagonals of eliminated rows
5342 
5343    Notes:
5344    Before calling MatZeroRowsLocalIS(), the user must first set the
5345    local-to-global mapping by calling MatSetLocalToGlobalMapping().
5346 
5347    For the AIJ matrix formats this removes the old nonzero structure,
5348    but does not release memory.  For the dense and block diagonal
5349    formats this does not alter the nonzero structure.
5350 
5351    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5352    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5353    merely zeroed.
5354 
5355    The user can set a value in the diagonal entry (or for the AIJ and
5356    row formats can optionally remove the main diagonal entry from the
5357    nonzero structure as well, by passing 0.0 as the final argument).
5358 
5359    Level: intermediate
5360 
5361    Concepts: matrices^zeroing
5362 
5363 .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5364 @*/
5365 PetscErrorCode PETSCMAT_DLLEXPORT MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag)
5366 {
5367   PetscErrorCode ierr;
5368   PetscInt       numRows;
5369   const PetscInt *rows;
5370 
5371   PetscFunctionBegin;
5372   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5373   PetscValidType(mat,1);
5374   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5375   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5376   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5377   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5378 
5379   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5380   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5381   ierr = MatZeroRowsLocal(mat,numRows,rows,diag);CHKERRQ(ierr);
5382   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5383   PetscFunctionReturn(0);
5384 }
5385 
5386 #undef __FUNCT__
5387 #define __FUNCT__ "MatGetSize"
5388 /*@
5389    MatGetSize - Returns the numbers of rows and columns in a matrix.
5390 
5391    Not Collective
5392 
5393    Input Parameter:
5394 .  mat - the matrix
5395 
5396    Output Parameters:
5397 +  m - the number of global rows
5398 -  n - the number of global columns
5399 
5400    Note: both output parameters can be PETSC_NULL on input.
5401 
5402    Level: beginner
5403 
5404    Concepts: matrices^size
5405 
5406 .seealso: MatGetLocalSize()
5407 @*/
5408 PetscErrorCode PETSCMAT_DLLEXPORT MatGetSize(Mat mat,PetscInt *m,PetscInt* n)
5409 {
5410   PetscFunctionBegin;
5411   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5412   if (m) *m = mat->rmap->N;
5413   if (n) *n = mat->cmap->N;
5414   PetscFunctionReturn(0);
5415 }
5416 
5417 #undef __FUNCT__
5418 #define __FUNCT__ "MatGetLocalSize"
5419 /*@
5420    MatGetLocalSize - Returns the number of rows and columns in a matrix
5421    stored locally.  This information may be implementation dependent, so
5422    use with care.
5423 
5424    Not Collective
5425 
5426    Input Parameters:
5427 .  mat - the matrix
5428 
5429    Output Parameters:
5430 +  m - the number of local rows
5431 -  n - the number of local columns
5432 
5433    Note: both output parameters can be PETSC_NULL on input.
5434 
5435    Level: beginner
5436 
5437    Concepts: matrices^local size
5438 
5439 .seealso: MatGetSize()
5440 @*/
5441 PetscErrorCode PETSCMAT_DLLEXPORT MatGetLocalSize(Mat mat,PetscInt *m,PetscInt* n)
5442 {
5443   PetscFunctionBegin;
5444   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5445   if (m) PetscValidIntPointer(m,2);
5446   if (n) PetscValidIntPointer(n,3);
5447   if (m) *m = mat->rmap->n;
5448   if (n) *n = mat->cmap->n;
5449   PetscFunctionReturn(0);
5450 }
5451 
5452 #undef __FUNCT__
5453 #define __FUNCT__ "MatGetOwnershipRangeColumn"
5454 /*@
5455    MatGetOwnershipRangeColumn - Returns the range of matrix columns owned by
5456    this processor.
5457 
5458    Not Collective, unless matrix has not been allocated, then collective on Mat
5459 
5460    Input Parameters:
5461 .  mat - the matrix
5462 
5463    Output Parameters:
5464 +  m - the global index of the first local column
5465 -  n - one more than the global index of the last local column
5466 
5467    Notes: both output parameters can be PETSC_NULL on input.
5468 
5469    Level: developer
5470 
5471    Concepts: matrices^column ownership
5472 
5473 .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
5474 
5475 @*/
5476 PetscErrorCode PETSCMAT_DLLEXPORT MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt* n)
5477 {
5478   PetscErrorCode ierr;
5479 
5480   PetscFunctionBegin;
5481   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5482   PetscValidType(mat,1);
5483   if (m) PetscValidIntPointer(m,2);
5484   if (n) PetscValidIntPointer(n,3);
5485   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5486   if (m) *m = mat->cmap->rstart;
5487   if (n) *n = mat->cmap->rend;
5488   PetscFunctionReturn(0);
5489 }
5490 
5491 #undef __FUNCT__
5492 #define __FUNCT__ "MatGetOwnershipRange"
5493 /*@
5494    MatGetOwnershipRange - Returns the range of matrix rows owned by
5495    this processor, assuming that the matrix is laid out with the first
5496    n1 rows on the first processor, the next n2 rows on the second, etc.
5497    For certain parallel layouts this range may not be well defined.
5498 
5499    Not Collective, unless matrix has not been allocated, then collective on Mat
5500 
5501    Input Parameters:
5502 .  mat - the matrix
5503 
5504    Output Parameters:
5505 +  m - the global index of the first local row
5506 -  n - one more than the global index of the last local row
5507 
5508    Note: both output parameters can be PETSC_NULL on input.
5509 
5510    Level: beginner
5511 
5512    Concepts: matrices^row ownership
5513 
5514 .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
5515 
5516 @*/
5517 PetscErrorCode PETSCMAT_DLLEXPORT MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt* n)
5518 {
5519   PetscErrorCode ierr;
5520 
5521   PetscFunctionBegin;
5522   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5523   PetscValidType(mat,1);
5524   if (m) PetscValidIntPointer(m,2);
5525   if (n) PetscValidIntPointer(n,3);
5526   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5527   if (m) *m = mat->rmap->rstart;
5528   if (n) *n = mat->rmap->rend;
5529   PetscFunctionReturn(0);
5530 }
5531 
5532 #undef __FUNCT__
5533 #define __FUNCT__ "MatGetOwnershipRanges"
5534 /*@C
5535    MatGetOwnershipRanges - Returns the range of matrix rows owned by
5536    each process
5537 
5538    Not Collective, unless matrix has not been allocated, then collective on Mat
5539 
5540    Input Parameters:
5541 .  mat - the matrix
5542 
5543    Output Parameters:
5544 .  ranges - start of each processors portion plus one more then the total length at the end
5545 
5546    Level: beginner
5547 
5548    Concepts: matrices^row ownership
5549 
5550 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
5551 
5552 @*/
5553 PetscErrorCode PETSCMAT_DLLEXPORT MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
5554 {
5555   PetscErrorCode ierr;
5556 
5557   PetscFunctionBegin;
5558   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5559   PetscValidType(mat,1);
5560   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5561   ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr);
5562   PetscFunctionReturn(0);
5563 }
5564 
5565 #undef __FUNCT__
5566 #define __FUNCT__ "MatGetOwnershipRangesColumn"
5567 /*@C
5568    MatGetOwnershipRangesColumn - Returns the range of local columns for each process
5569 
5570    Not Collective, unless matrix has not been allocated, then collective on Mat
5571 
5572    Input Parameters:
5573 .  mat - the matrix
5574 
5575    Output Parameters:
5576 .  ranges - start of each processors portion plus one more then the total length at the end
5577 
5578    Level: beginner
5579 
5580    Concepts: matrices^column ownership
5581 
5582 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
5583 
5584 @*/
5585 PetscErrorCode PETSCMAT_DLLEXPORT MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
5586 {
5587   PetscErrorCode ierr;
5588 
5589   PetscFunctionBegin;
5590   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5591   PetscValidType(mat,1);
5592   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5593   ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr);
5594   PetscFunctionReturn(0);
5595 }
5596 
5597 #undef __FUNCT__
5598 #define __FUNCT__ "MatILUFactorSymbolic"
5599 /*@C
5600    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
5601    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
5602    to complete the factorization.
5603 
5604    Collective on Mat
5605 
5606    Input Parameters:
5607 +  mat - the matrix
5608 .  row - row permutation
5609 .  column - column permutation
5610 -  info - structure containing
5611 $      levels - number of levels of fill.
5612 $      expected fill - as ratio of original fill.
5613 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
5614                 missing diagonal entries)
5615 
5616    Output Parameters:
5617 .  fact - new matrix that has been symbolically factored
5618 
5619    Notes:
5620    See the users manual for additional information about
5621    choosing the fill factor for better efficiency.
5622 
5623    Most users should employ the simplified KSP interface for linear solvers
5624    instead of working directly with matrix algebra routines such as this.
5625    See, e.g., KSPCreate().
5626 
5627    Level: developer
5628 
5629   Concepts: matrices^symbolic LU factorization
5630   Concepts: matrices^factorization
5631   Concepts: LU^symbolic factorization
5632 
5633 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
5634           MatGetOrdering(), MatFactorInfo
5635 
5636     Developer Note: fortran interface is not autogenerated as the f90
5637     interface defintion cannot be generated correctly [due to MatFactorInfo]
5638 
5639 @*/
5640 PetscErrorCode PETSCMAT_DLLEXPORT MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
5641 {
5642   PetscErrorCode ierr;
5643 
5644   PetscFunctionBegin;
5645   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5646   PetscValidType(mat,1);
5647   PetscValidHeaderSpecific(row,IS_CLASSID,2);
5648   PetscValidHeaderSpecific(col,IS_CLASSID,3);
5649   PetscValidPointer(info,4);
5650   PetscValidPointer(fact,5);
5651   if (info->levels < 0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
5652   if (info->fill < 1.0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
5653   if (!(fact)->ops->ilufactorsymbolic) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s  symbolic ILU",((PetscObject)mat)->type_name);
5654   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5655   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5656   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5657 
5658   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
5659   ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
5660   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
5661   PetscFunctionReturn(0);
5662 }
5663 
5664 #undef __FUNCT__
5665 #define __FUNCT__ "MatICCFactorSymbolic"
5666 /*@C
5667    MatICCFactorSymbolic - Performs symbolic incomplete
5668    Cholesky factorization for a symmetric matrix.  Use
5669    MatCholeskyFactorNumeric() to complete the factorization.
5670 
5671    Collective on Mat
5672 
5673    Input Parameters:
5674 +  mat - the matrix
5675 .  perm - row and column permutation
5676 -  info - structure containing
5677 $      levels - number of levels of fill.
5678 $      expected fill - as ratio of original fill.
5679 
5680    Output Parameter:
5681 .  fact - the factored matrix
5682 
5683    Notes:
5684    Most users should employ the KSP interface for linear solvers
5685    instead of working directly with matrix algebra routines such as this.
5686    See, e.g., KSPCreate().
5687 
5688    Level: developer
5689 
5690   Concepts: matrices^symbolic incomplete Cholesky factorization
5691   Concepts: matrices^factorization
5692   Concepts: Cholsky^symbolic factorization
5693 
5694 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
5695 
5696     Developer Note: fortran interface is not autogenerated as the f90
5697     interface defintion cannot be generated correctly [due to MatFactorInfo]
5698 
5699 @*/
5700 PetscErrorCode PETSCMAT_DLLEXPORT MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
5701 {
5702   PetscErrorCode ierr;
5703 
5704   PetscFunctionBegin;
5705   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5706   PetscValidType(mat,1);
5707   PetscValidHeaderSpecific(perm,IS_CLASSID,2);
5708   PetscValidPointer(info,3);
5709   PetscValidPointer(fact,4);
5710   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5711   if (info->levels < 0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
5712   if (info->fill < 1.0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
5713   if (!(fact)->ops->iccfactorsymbolic) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s  symbolic ICC",((PetscObject)mat)->type_name);
5714   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5715   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5716 
5717   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
5718   ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
5719   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
5720   PetscFunctionReturn(0);
5721 }
5722 
5723 #undef __FUNCT__
5724 #define __FUNCT__ "MatGetArray"
5725 /*@C
5726    MatGetArray - Returns a pointer to the element values in the matrix.
5727    The result of this routine is dependent on the underlying matrix data
5728    structure, and may not even work for certain matrix types.  You MUST
5729    call MatRestoreArray() when you no longer need to access the array.
5730 
5731    Not Collective
5732 
5733    Input Parameter:
5734 .  mat - the matrix
5735 
5736    Output Parameter:
5737 .  v - the location of the values
5738 
5739 
5740    Fortran Note:
5741    This routine is used differently from Fortran, e.g.,
5742 .vb
5743         Mat         mat
5744         PetscScalar mat_array(1)
5745         PetscOffset i_mat
5746         PetscErrorCode ierr
5747         call MatGetArray(mat,mat_array,i_mat,ierr)
5748 
5749   C  Access first local entry in matrix; note that array is
5750   C  treated as one dimensional
5751         value = mat_array(i_mat + 1)
5752 
5753         [... other code ...]
5754         call MatRestoreArray(mat,mat_array,i_mat,ierr)
5755 .ve
5756 
5757    See the Fortran chapter of the users manual and
5758    petsc/src/mat/examples/tests for details.
5759 
5760    Level: advanced
5761 
5762    Concepts: matrices^access array
5763 
5764 .seealso: MatRestoreArray(), MatGetArrayF90(), MatGetRowIJ()
5765 @*/
5766 PetscErrorCode PETSCMAT_DLLEXPORT MatGetArray(Mat mat,PetscScalar *v[])
5767 {
5768   PetscErrorCode ierr;
5769 
5770   PetscFunctionBegin;
5771   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5772   PetscValidType(mat,1);
5773   PetscValidPointer(v,2);
5774   if (!mat->ops->getarray) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5775   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5776   ierr = (*mat->ops->getarray)(mat,v);CHKERRQ(ierr);
5777   CHKMEMQ;
5778   PetscFunctionReturn(0);
5779 }
5780 
5781 #undef __FUNCT__
5782 #define __FUNCT__ "MatRestoreArray"
5783 /*@C
5784    MatRestoreArray - Restores the matrix after MatGetArray() has been called.
5785 
5786    Not Collective
5787 
5788    Input Parameter:
5789 +  mat - the matrix
5790 -  v - the location of the values
5791 
5792    Fortran Note:
5793    This routine is used differently from Fortran, e.g.,
5794 .vb
5795         Mat         mat
5796         PetscScalar mat_array(1)
5797         PetscOffset i_mat
5798         PetscErrorCode ierr
5799         call MatGetArray(mat,mat_array,i_mat,ierr)
5800 
5801   C  Access first local entry in matrix; note that array is
5802   C  treated as one dimensional
5803         value = mat_array(i_mat + 1)
5804 
5805         [... other code ...]
5806         call MatRestoreArray(mat,mat_array,i_mat,ierr)
5807 .ve
5808 
5809    See the Fortran chapter of the users manual and
5810    petsc/src/mat/examples/tests for details
5811 
5812    Level: advanced
5813 
5814 .seealso: MatGetArray(), MatRestoreArrayF90()
5815 @*/
5816 PetscErrorCode PETSCMAT_DLLEXPORT MatRestoreArray(Mat mat,PetscScalar *v[])
5817 {
5818   PetscErrorCode ierr;
5819 
5820   PetscFunctionBegin;
5821   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5822   PetscValidType(mat,1);
5823   PetscValidPointer(v,2);
5824 #if defined(PETSC_USE_DEBUG)
5825   CHKMEMQ;
5826 #endif
5827   if (!mat->ops->restorearray) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5828   ierr = (*mat->ops->restorearray)(mat,v);CHKERRQ(ierr);
5829   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5830   PetscFunctionReturn(0);
5831 }
5832 
5833 #undef __FUNCT__
5834 #define __FUNCT__ "MatGetSubMatrices"
5835 /*@C
5836    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
5837    points to an array of valid matrices, they may be reused to store the new
5838    submatrices.
5839 
5840    Collective on Mat
5841 
5842    Input Parameters:
5843 +  mat - the matrix
5844 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
5845 .  irow, icol - index sets of rows and columns to extract
5846 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
5847 
5848    Output Parameter:
5849 .  submat - the array of submatrices
5850 
5851    Notes:
5852    MatGetSubMatrices() can extract ONLY sequential submatrices
5853    (from both sequential and parallel matrices). Use MatGetSubMatrix()
5854    to extract a parallel submatrix.
5855 
5856    When extracting submatrices from a parallel matrix, each processor can
5857    form a different submatrix by setting the rows and columns of its
5858    individual index sets according to the local submatrix desired.
5859 
5860    When finished using the submatrices, the user should destroy
5861    them with MatDestroyMatrices().
5862 
5863    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
5864    original matrix has not changed from that last call to MatGetSubMatrices().
5865 
5866    This routine creates the matrices in submat; you should NOT create them before
5867    calling it. It also allocates the array of matrix pointers submat.
5868 
5869    For BAIJ matrices the index sets must respect the block structure, that is if they
5870    request one row/column in a block, they must request all rows/columns that are in
5871    that block. For example, if the block size is 2 you cannot request just row 0 and
5872    column 0.
5873 
5874    Fortran Note:
5875    The Fortran interface is slightly different from that given below; it
5876    requires one to pass in  as submat a Mat (integer) array of size at least m.
5877 
5878    Level: advanced
5879 
5880    Concepts: matrices^accessing submatrices
5881    Concepts: submatrices
5882 
5883 .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
5884 @*/
5885 PetscErrorCode PETSCMAT_DLLEXPORT MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
5886 {
5887   PetscErrorCode ierr;
5888   PetscInt        i;
5889   PetscTruth      eq;
5890 
5891   PetscFunctionBegin;
5892   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5893   PetscValidType(mat,1);
5894   if (n) {
5895     PetscValidPointer(irow,3);
5896     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
5897     PetscValidPointer(icol,4);
5898     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
5899   }
5900   PetscValidPointer(submat,6);
5901   if (n && scall == MAT_REUSE_MATRIX) {
5902     PetscValidPointer(*submat,6);
5903     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
5904   }
5905   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5906   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5907   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5908   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5909 
5910   ierr = PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
5911   ierr = (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
5912   ierr = PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
5913   for (i=0; i<n; i++) {
5914     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
5915       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
5916       if (eq) {
5917 	if (mat->symmetric){
5918 	  ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
5919 	} else if (mat->hermitian) {
5920 	  ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
5921 	} else if (mat->structurally_symmetric) {
5922 	  ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
5923 	}
5924       }
5925     }
5926   }
5927   PetscFunctionReturn(0);
5928 }
5929 
5930 #undef __FUNCT__
5931 #define __FUNCT__ "MatDestroyMatrices"
5932 /*@C
5933    MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().
5934 
5935    Collective on Mat
5936 
5937    Input Parameters:
5938 +  n - the number of local matrices
5939 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
5940                        sequence of MatGetSubMatrices())
5941 
5942    Level: advanced
5943 
5944     Notes: Frees not only the matrices, but also the array that contains the matrices
5945            In Fortran will not free the array.
5946 
5947 .seealso: MatGetSubMatrices()
5948 @*/
5949 PetscErrorCode PETSCMAT_DLLEXPORT MatDestroyMatrices(PetscInt n,Mat *mat[])
5950 {
5951   PetscErrorCode ierr;
5952   PetscInt       i;
5953 
5954   PetscFunctionBegin;
5955   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
5956   PetscValidPointer(mat,2);
5957   for (i=0; i<n; i++) {
5958     ierr = MatDestroy((*mat)[i]);CHKERRQ(ierr);
5959   }
5960   /* memory is allocated even if n = 0 */
5961   ierr = PetscFree(*mat);CHKERRQ(ierr);
5962   PetscFunctionReturn(0);
5963 }
5964 
5965 #undef __FUNCT__
5966 #define __FUNCT__ "MatGetSeqNonzeroStructure"
5967 /*@C
5968    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
5969 
5970    Collective on Mat
5971 
5972    Input Parameters:
5973 .  mat - the matrix
5974 
5975    Output Parameter:
5976 .  matstruct - the sequential matrix with the nonzero structure of mat
5977 
5978   Level: intermediate
5979 
5980 .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
5981 @*/
5982 PetscErrorCode PETSCMAT_DLLEXPORT MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
5983 {
5984   PetscErrorCode ierr;
5985 
5986   PetscFunctionBegin;
5987   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5988   PetscValidPointer(matstruct,2);
5989 
5990   PetscValidType(mat,1);
5991   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5992   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5993 
5994   if (!mat->ops->getseqnonzerostructure) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
5995   ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
5996   ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr);
5997   ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
5998   PetscFunctionReturn(0);
5999 }
6000 
6001 #undef __FUNCT__
6002 #define __FUNCT__ "MatDestroySeqNonzeroStructure"
6003 /*@C
6004    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
6005 
6006    Collective on Mat
6007 
6008    Input Parameters:
6009 .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
6010                        sequence of MatGetSequentialNonzeroStructure())
6011 
6012    Level: advanced
6013 
6014     Notes: Frees not only the matrices, but also the array that contains the matrices
6015 
6016 .seealso: MatGetSeqNonzeroStructure()
6017 @*/
6018 PetscErrorCode PETSCMAT_DLLEXPORT MatDestroySeqNonzeroStructure(Mat *mat)
6019 {
6020   PetscErrorCode ierr;
6021 
6022   PetscFunctionBegin;
6023   PetscValidPointer(mat,1);
6024   ierr = MatDestroy(*mat);CHKERRQ(ierr);
6025   PetscFunctionReturn(0);
6026 }
6027 
6028 #undef __FUNCT__
6029 #define __FUNCT__ "MatIncreaseOverlap"
6030 /*@
6031    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6032    replaces the index sets by larger ones that represent submatrices with
6033    additional overlap.
6034 
6035    Collective on Mat
6036 
6037    Input Parameters:
6038 +  mat - the matrix
6039 .  n   - the number of index sets
6040 .  is  - the array of index sets (these index sets will changed during the call)
6041 -  ov  - the additional overlap requested
6042 
6043    Level: developer
6044 
6045    Concepts: overlap
6046    Concepts: ASM^computing overlap
6047 
6048 .seealso: MatGetSubMatrices()
6049 @*/
6050 PetscErrorCode PETSCMAT_DLLEXPORT MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6051 {
6052   PetscErrorCode ierr;
6053 
6054   PetscFunctionBegin;
6055   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6056   PetscValidType(mat,1);
6057   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6058   if (n) {
6059     PetscValidPointer(is,3);
6060     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
6061   }
6062   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6063   if (mat->factortype)     SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6064   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6065 
6066   if (!ov) PetscFunctionReturn(0);
6067   if (!mat->ops->increaseoverlap) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6068   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
6069   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
6070   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
6071   PetscFunctionReturn(0);
6072 }
6073 
6074 #undef __FUNCT__
6075 #define __FUNCT__ "MatGetBlockSize"
6076 /*@
6077    MatGetBlockSize - Returns the matrix block size; useful especially for the
6078    block row and block diagonal formats.
6079 
6080    Not Collective
6081 
6082    Input Parameter:
6083 .  mat - the matrix
6084 
6085    Output Parameter:
6086 .  bs - block size
6087 
6088    Notes:
6089    Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ
6090 
6091    Level: intermediate
6092 
6093    Concepts: matrices^block size
6094 
6095 .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ()
6096 @*/
6097 PetscErrorCode PETSCMAT_DLLEXPORT MatGetBlockSize(Mat mat,PetscInt *bs)
6098 {
6099   PetscErrorCode ierr;
6100 
6101   PetscFunctionBegin;
6102   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6103   PetscValidType(mat,1);
6104   PetscValidIntPointer(bs,2);
6105   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6106   *bs = mat->rmap->bs;
6107   PetscFunctionReturn(0);
6108 }
6109 
6110 #undef __FUNCT__
6111 #define __FUNCT__ "MatSetBlockSize"
6112 /*@
6113    MatSetBlockSize - Sets the matrix block size; for many matrix types you
6114      cannot use this and MUST set the blocksize when you preallocate the matrix
6115 
6116    Logically Collective on Mat
6117 
6118    Input Parameters:
6119 +  mat - the matrix
6120 -  bs - block size
6121 
6122    Notes:
6123      For BAIJ matrices, this just checks that the block size agrees with the BAIJ size,
6124      it is not possible to change BAIJ block sizes after preallocation.
6125 
6126    Level: intermediate
6127 
6128    Concepts: matrices^block size
6129 
6130 .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ(), MatGetBlockSize()
6131 @*/
6132 PetscErrorCode PETSCMAT_DLLEXPORT MatSetBlockSize(Mat mat,PetscInt bs)
6133 {
6134   PetscErrorCode ierr;
6135 
6136   PetscFunctionBegin;
6137   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6138   PetscValidType(mat,1);
6139   PetscValidLogicalCollectiveInt(mat,bs,2);
6140   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6141   if (bs < 1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Block size %d, must be positive",bs);
6142   if (mat->ops->setblocksize) {
6143     ierr = (*mat->ops->setblocksize)(mat,bs);CHKERRQ(ierr);
6144   } else {
6145     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Cannot set the blocksize for matrix type %s",((PetscObject)mat)->type_name);
6146   }
6147   PetscFunctionReturn(0);
6148 }
6149 
6150 #undef __FUNCT__
6151 #define __FUNCT__ "MatGetRowIJ"
6152 /*@C
6153     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
6154 
6155    Collective on Mat
6156 
6157     Input Parameters:
6158 +   mat - the matrix
6159 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
6160 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6161                 symmetrized
6162 -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
6163                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6164                  always used.
6165 
6166     Output Parameters:
6167 +   n - number of rows in the (possibly compressed) matrix
6168 .   ia - the row pointers [of length n+1]
6169 .   ja - the column indices
6170 -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
6171            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
6172 
6173     Level: developer
6174 
6175     Notes: You CANNOT change any of the ia[] or ja[] values.
6176 
6177            Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values
6178 
6179     Fortran Node
6180 
6181            In Fortran use
6182 $           PetscInt ia(1), ja(1)
6183 $           PetscOffset iia, jja
6184 $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
6185 $
6186 $          or
6187 $
6188 $           PetscScalar, pointer :: xx_v(:)
6189 $    call  MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
6190 
6191 
6192        Acess the ith and jth entries via ia(iia + i) and ja(jja + j)
6193 
6194 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatGetArray()
6195 @*/
6196 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRowIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
6197 {
6198   PetscErrorCode ierr;
6199 
6200   PetscFunctionBegin;
6201   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6202   PetscValidType(mat,1);
6203   PetscValidIntPointer(n,4);
6204   if (ia) PetscValidIntPointer(ia,5);
6205   if (ja) PetscValidIntPointer(ja,6);
6206   PetscValidIntPointer(done,7);
6207   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6208   if (!mat->ops->getrowij) *done = PETSC_FALSE;
6209   else {
6210     *done = PETSC_TRUE;
6211     ierr = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
6212     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6213     ierr = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
6214   }
6215   PetscFunctionReturn(0);
6216 }
6217 
6218 #undef __FUNCT__
6219 #define __FUNCT__ "MatGetColumnIJ"
6220 /*@C
6221     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
6222 
6223     Collective on Mat
6224 
6225     Input Parameters:
6226 +   mat - the matrix
6227 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6228 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6229                 symmetrized
6230 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6231                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6232                  always used.
6233 
6234     Output Parameters:
6235 +   n - number of columns in the (possibly compressed) matrix
6236 .   ia - the column pointers
6237 .   ja - the row indices
6238 -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
6239 
6240     Level: developer
6241 
6242 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6243 @*/
6244 PetscErrorCode PETSCMAT_DLLEXPORT MatGetColumnIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
6245 {
6246   PetscErrorCode ierr;
6247 
6248   PetscFunctionBegin;
6249   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6250   PetscValidType(mat,1);
6251   PetscValidIntPointer(n,4);
6252   if (ia) PetscValidIntPointer(ia,5);
6253   if (ja) PetscValidIntPointer(ja,6);
6254   PetscValidIntPointer(done,7);
6255   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6256   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
6257   else {
6258     *done = PETSC_TRUE;
6259     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6260   }
6261   PetscFunctionReturn(0);
6262 }
6263 
6264 #undef __FUNCT__
6265 #define __FUNCT__ "MatRestoreRowIJ"
6266 /*@C
6267     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
6268     MatGetRowIJ().
6269 
6270     Collective on Mat
6271 
6272     Input Parameters:
6273 +   mat - the matrix
6274 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6275 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6276                 symmetrized
6277 -   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6278                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6279                  always used.
6280 
6281     Output Parameters:
6282 +   n - size of (possibly compressed) matrix
6283 .   ia - the row pointers
6284 .   ja - the column indices
6285 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
6286 
6287     Level: developer
6288 
6289 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6290 @*/
6291 PetscErrorCode PETSCMAT_DLLEXPORT MatRestoreRowIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
6292 {
6293   PetscErrorCode ierr;
6294 
6295   PetscFunctionBegin;
6296   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6297   PetscValidType(mat,1);
6298   if (ia) PetscValidIntPointer(ia,5);
6299   if (ja) PetscValidIntPointer(ja,6);
6300   PetscValidIntPointer(done,7);
6301   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6302 
6303   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
6304   else {
6305     *done = PETSC_TRUE;
6306     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6307   }
6308   PetscFunctionReturn(0);
6309 }
6310 
6311 #undef __FUNCT__
6312 #define __FUNCT__ "MatRestoreColumnIJ"
6313 /*@C
6314     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
6315     MatGetColumnIJ().
6316 
6317     Collective on Mat
6318 
6319     Input Parameters:
6320 +   mat - the matrix
6321 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6322 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6323                 symmetrized
6324 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6325                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6326                  always used.
6327 
6328     Output Parameters:
6329 +   n - size of (possibly compressed) matrix
6330 .   ia - the column pointers
6331 .   ja - the row indices
6332 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
6333 
6334     Level: developer
6335 
6336 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
6337 @*/
6338 PetscErrorCode PETSCMAT_DLLEXPORT MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
6339 {
6340   PetscErrorCode ierr;
6341 
6342   PetscFunctionBegin;
6343   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6344   PetscValidType(mat,1);
6345   if (ia) PetscValidIntPointer(ia,5);
6346   if (ja) PetscValidIntPointer(ja,6);
6347   PetscValidIntPointer(done,7);
6348   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6349 
6350   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
6351   else {
6352     *done = PETSC_TRUE;
6353     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6354   }
6355   PetscFunctionReturn(0);
6356 }
6357 
6358 #undef __FUNCT__
6359 #define __FUNCT__ "MatColoringPatch"
6360 /*@C
6361     MatColoringPatch -Used inside matrix coloring routines that
6362     use MatGetRowIJ() and/or MatGetColumnIJ().
6363 
6364     Collective on Mat
6365 
6366     Input Parameters:
6367 +   mat - the matrix
6368 .   ncolors - max color value
6369 .   n   - number of entries in colorarray
6370 -   colorarray - array indicating color for each column
6371 
6372     Output Parameters:
6373 .   iscoloring - coloring generated using colorarray information
6374 
6375     Level: developer
6376 
6377 .seealso: MatGetRowIJ(), MatGetColumnIJ()
6378 
6379 @*/
6380 PetscErrorCode PETSCMAT_DLLEXPORT MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
6381 {
6382   PetscErrorCode ierr;
6383 
6384   PetscFunctionBegin;
6385   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6386   PetscValidType(mat,1);
6387   PetscValidIntPointer(colorarray,4);
6388   PetscValidPointer(iscoloring,5);
6389   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6390 
6391   if (!mat->ops->coloringpatch){
6392     ierr = ISColoringCreate(((PetscObject)mat)->comm,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
6393   } else {
6394     ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
6395   }
6396   PetscFunctionReturn(0);
6397 }
6398 
6399 
6400 #undef __FUNCT__
6401 #define __FUNCT__ "MatSetUnfactored"
6402 /*@
6403    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
6404 
6405    Logically Collective on Mat
6406 
6407    Input Parameter:
6408 .  mat - the factored matrix to be reset
6409 
6410    Notes:
6411    This routine should be used only with factored matrices formed by in-place
6412    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
6413    format).  This option can save memory, for example, when solving nonlinear
6414    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
6415    ILU(0) preconditioner.
6416 
6417    Note that one can specify in-place ILU(0) factorization by calling
6418 .vb
6419      PCType(pc,PCILU);
6420      PCFactorSeUseInPlace(pc);
6421 .ve
6422    or by using the options -pc_type ilu -pc_factor_in_place
6423 
6424    In-place factorization ILU(0) can also be used as a local
6425    solver for the blocks within the block Jacobi or additive Schwarz
6426    methods (runtime option: -sub_pc_factor_in_place).  See the discussion
6427    of these preconditioners in the users manual for details on setting
6428    local solver options.
6429 
6430    Most users should employ the simplified KSP interface for linear solvers
6431    instead of working directly with matrix algebra routines such as this.
6432    See, e.g., KSPCreate().
6433 
6434    Level: developer
6435 
6436 .seealso: PCFactorSetUseInPlace()
6437 
6438    Concepts: matrices^unfactored
6439 
6440 @*/
6441 PetscErrorCode PETSCMAT_DLLEXPORT MatSetUnfactored(Mat mat)
6442 {
6443   PetscErrorCode ierr;
6444 
6445   PetscFunctionBegin;
6446   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6447   PetscValidType(mat,1);
6448   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6449   mat->factortype = MAT_FACTOR_NONE;
6450   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
6451   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
6452   PetscFunctionReturn(0);
6453 }
6454 
6455 /*MC
6456     MatGetArrayF90 - Accesses a matrix array from Fortran90.
6457 
6458     Synopsis:
6459     MatGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
6460 
6461     Not collective
6462 
6463     Input Parameter:
6464 .   x - matrix
6465 
6466     Output Parameters:
6467 +   xx_v - the Fortran90 pointer to the array
6468 -   ierr - error code
6469 
6470     Example of Usage:
6471 .vb
6472       PetscScalar, pointer xx_v(:)
6473       ....
6474       call MatGetArrayF90(x,xx_v,ierr)
6475       a = xx_v(3)
6476       call MatRestoreArrayF90(x,xx_v,ierr)
6477 .ve
6478 
6479     Notes:
6480     Not yet supported for all F90 compilers
6481 
6482     Level: advanced
6483 
6484 .seealso:  MatRestoreArrayF90(), MatGetArray(), MatRestoreArray()
6485 
6486     Concepts: matrices^accessing array
6487 
6488 M*/
6489 
6490 /*MC
6491     MatRestoreArrayF90 - Restores a matrix array that has been
6492     accessed with MatGetArrayF90().
6493 
6494     Synopsis:
6495     MatRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
6496 
6497     Not collective
6498 
6499     Input Parameters:
6500 +   x - matrix
6501 -   xx_v - the Fortran90 pointer to the array
6502 
6503     Output Parameter:
6504 .   ierr - error code
6505 
6506     Example of Usage:
6507 .vb
6508        PetscScalar, pointer xx_v(:)
6509        ....
6510        call MatGetArrayF90(x,xx_v,ierr)
6511        a = xx_v(3)
6512        call MatRestoreArrayF90(x,xx_v,ierr)
6513 .ve
6514 
6515     Notes:
6516     Not yet supported for all F90 compilers
6517 
6518     Level: advanced
6519 
6520 .seealso:  MatGetArrayF90(), MatGetArray(), MatRestoreArray()
6521 
6522 M*/
6523 
6524 
6525 #undef __FUNCT__
6526 #define __FUNCT__ "MatGetSubMatrix"
6527 /*@
6528     MatGetSubMatrix - Gets a single submatrix on the same number of processors
6529                       as the original matrix.
6530 
6531     Collective on Mat
6532 
6533     Input Parameters:
6534 +   mat - the original matrix
6535 .   isrow - parallel IS containing the rows this processor should obtain
6536 .   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.
6537 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6538 
6539     Output Parameter:
6540 .   newmat - the new submatrix, of the same type as the old
6541 
6542     Level: advanced
6543 
6544     Notes:
6545     The submatrix will be able to be multiplied with vectors using the same layout as iscol.
6546 
6547     The rows in isrow will be sorted into the same order as the original matrix on each process.
6548 
6549       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
6550    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
6551    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
6552    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
6553    you are finished using it.
6554 
6555     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
6556     the input matrix.
6557 
6558     If iscol is PETSC_NULL then all columns are obtained (not supported in Fortran).
6559 
6560    Example usage:
6561    Consider the following 8x8 matrix with 34 non-zero values, that is
6562    assembled across 3 processors. Lets assume that proc0 owns 3 rows,
6563    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
6564    as follows:
6565 
6566 .vb
6567             1  2  0  |  0  3  0  |  0  4
6568     Proc0   0  5  6  |  7  0  0  |  8  0
6569             9  0 10  | 11  0  0  | 12  0
6570     -------------------------------------
6571            13  0 14  | 15 16 17  |  0  0
6572     Proc1   0 18  0  | 19 20 21  |  0  0
6573             0  0  0  | 22 23  0  | 24  0
6574     -------------------------------------
6575     Proc2  25 26 27  |  0  0 28  | 29  0
6576            30  0  0  | 31 32 33  |  0 34
6577 .ve
6578 
6579     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is
6580 
6581 .vb
6582             2  0  |  0  3  0  |  0
6583     Proc0   5  6  |  7  0  0  |  8
6584     -------------------------------
6585     Proc1  18  0  | 19 20 21  |  0
6586     -------------------------------
6587     Proc2  26 27  |  0  0 28  | 29
6588             0  0  | 31 32 33  |  0
6589 .ve
6590 
6591 
6592     Concepts: matrices^submatrices
6593 
6594 .seealso: MatGetSubMatrices()
6595 @*/
6596 PetscErrorCode PETSCMAT_DLLEXPORT MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
6597 {
6598   PetscErrorCode ierr;
6599   PetscMPIInt    size;
6600   Mat            *local;
6601   IS             iscoltmp;
6602 
6603   PetscFunctionBegin;
6604   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6605   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
6606   if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
6607   PetscValidPointer(newmat,5);
6608   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5);
6609   PetscValidType(mat,1);
6610   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6611   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6612   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
6613 
6614   if (!iscol) {
6615     ierr = ISCreateStride(((PetscObject)mat)->comm,mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr);
6616   } else {
6617     iscoltmp = iscol;
6618   }
6619 
6620   /* if original matrix is on just one processor then use submatrix generated */
6621   if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
6622     ierr = MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
6623     if (!iscol) {ierr = ISDestroy(iscoltmp);CHKERRQ(ierr);}
6624     PetscFunctionReturn(0);
6625   } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) {
6626     ierr    = MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
6627     *newmat = *local;
6628     ierr    = PetscFree(local);CHKERRQ(ierr);
6629     if (!iscol) {ierr = ISDestroy(iscoltmp);CHKERRQ(ierr);}
6630     PetscFunctionReturn(0);
6631   } else if (!mat->ops->getsubmatrix) {
6632     /* Create a new matrix type that implements the operation using the full matrix */
6633     switch (cll) {
6634       case MAT_INITIAL_MATRIX:
6635         ierr = MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr);
6636         break;
6637       case MAT_REUSE_MATRIX:
6638         ierr = MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr);
6639         break;
6640       default: SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
6641     }
6642     if (!iscol) {ierr = ISDestroy(iscoltmp);CHKERRQ(ierr);}
6643     PetscFunctionReturn(0);
6644   }
6645 
6646   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6647   ierr = (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr);
6648   if (!iscol) {ierr = ISDestroy(iscoltmp);CHKERRQ(ierr);}
6649   ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);
6650   PetscFunctionReturn(0);
6651 }
6652 
6653 #undef __FUNCT__
6654 #define __FUNCT__ "MatStashSetInitialSize"
6655 /*@
6656    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
6657    used during the assembly process to store values that belong to
6658    other processors.
6659 
6660    Not Collective
6661 
6662    Input Parameters:
6663 +  mat   - the matrix
6664 .  size  - the initial size of the stash.
6665 -  bsize - the initial size of the block-stash(if used).
6666 
6667    Options Database Keys:
6668 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
6669 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
6670 
6671    Level: intermediate
6672 
6673    Notes:
6674      The block-stash is used for values set with MatSetValuesBlocked() while
6675      the stash is used for values set with MatSetValues()
6676 
6677      Run with the option -info and look for output of the form
6678      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
6679      to determine the appropriate value, MM, to use for size and
6680      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
6681      to determine the value, BMM to use for bsize
6682 
6683    Concepts: stash^setting matrix size
6684    Concepts: matrices^stash
6685 
6686 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
6687 
6688 @*/
6689 PetscErrorCode PETSCMAT_DLLEXPORT MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
6690 {
6691   PetscErrorCode ierr;
6692 
6693   PetscFunctionBegin;
6694   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6695   PetscValidType(mat,1);
6696   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
6697   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
6698   PetscFunctionReturn(0);
6699 }
6700 
6701 #undef __FUNCT__
6702 #define __FUNCT__ "MatInterpolateAdd"
6703 /*@
6704    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
6705      the matrix
6706 
6707    Neighbor-wise Collective on Mat
6708 
6709    Input Parameters:
6710 +  mat   - the matrix
6711 .  x,y - the vectors
6712 -  w - where the result is stored
6713 
6714    Level: intermediate
6715 
6716    Notes:
6717     w may be the same vector as y.
6718 
6719     This allows one to use either the restriction or interpolation (its transpose)
6720     matrix to do the interpolation
6721 
6722     Concepts: interpolation
6723 
6724 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
6725 
6726 @*/
6727 PetscErrorCode PETSCMAT_DLLEXPORT MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
6728 {
6729   PetscErrorCode ierr;
6730   PetscInt       M,N;
6731 
6732   PetscFunctionBegin;
6733   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
6734   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
6735   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
6736   PetscValidHeaderSpecific(w,VEC_CLASSID,4);
6737   PetscValidType(A,1);
6738   ierr = MatPreallocated(A);CHKERRQ(ierr);
6739   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
6740   if (N > M) {
6741     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
6742   } else {
6743     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
6744   }
6745   PetscFunctionReturn(0);
6746 }
6747 
6748 #undef __FUNCT__
6749 #define __FUNCT__ "MatInterpolate"
6750 /*@
6751    MatInterpolate - y = A*x or A'*x depending on the shape of
6752      the matrix
6753 
6754    Neighbor-wise Collective on Mat
6755 
6756    Input Parameters:
6757 +  mat   - the matrix
6758 -  x,y - the vectors
6759 
6760    Level: intermediate
6761 
6762    Notes:
6763     This allows one to use either the restriction or interpolation (its transpose)
6764     matrix to do the interpolation
6765 
6766    Concepts: matrices^interpolation
6767 
6768 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
6769 
6770 @*/
6771 PetscErrorCode PETSCMAT_DLLEXPORT MatInterpolate(Mat A,Vec x,Vec y)
6772 {
6773   PetscErrorCode ierr;
6774   PetscInt       M,N;
6775 
6776   PetscFunctionBegin;
6777   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
6778   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
6779   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
6780   PetscValidType(A,1);
6781   ierr = MatPreallocated(A);CHKERRQ(ierr);
6782   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
6783   if (N > M) {
6784     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
6785   } else {
6786     ierr = MatMult(A,x,y);CHKERRQ(ierr);
6787   }
6788   PetscFunctionReturn(0);
6789 }
6790 
6791 #undef __FUNCT__
6792 #define __FUNCT__ "MatRestrict"
6793 /*@
6794    MatRestrict - y = A*x or A'*x
6795 
6796    Neighbor-wise Collective on Mat
6797 
6798    Input Parameters:
6799 +  mat   - the matrix
6800 -  x,y - the vectors
6801 
6802    Level: intermediate
6803 
6804    Notes:
6805     This allows one to use either the restriction or interpolation (its transpose)
6806     matrix to do the restriction
6807 
6808    Concepts: matrices^restriction
6809 
6810 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
6811 
6812 @*/
6813 PetscErrorCode PETSCMAT_DLLEXPORT MatRestrict(Mat A,Vec x,Vec y)
6814 {
6815   PetscErrorCode ierr;
6816   PetscInt       M,N;
6817 
6818   PetscFunctionBegin;
6819   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
6820   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
6821   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
6822   PetscValidType(A,1);
6823   ierr = MatPreallocated(A);CHKERRQ(ierr);
6824 
6825   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
6826   if (N > M) {
6827     ierr = MatMult(A,x,y);CHKERRQ(ierr);
6828   } else {
6829     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
6830   }
6831   PetscFunctionReturn(0);
6832 }
6833 
6834 #undef __FUNCT__
6835 #define __FUNCT__ "MatNullSpaceAttach"
6836 /*@
6837    MatNullSpaceAttach - attaches a null space to a matrix.
6838         This null space will be removed from the resulting vector whenever
6839         MatMult() is called
6840 
6841    Logically Collective on Mat and MatNullSpace
6842 
6843    Input Parameters:
6844 +  mat - the matrix
6845 -  nullsp - the null space object
6846 
6847    Level: developer
6848 
6849    Notes:
6850       Overwrites any previous null space that may have been attached
6851 
6852    Concepts: null space^attaching to matrix
6853 
6854 .seealso: MatCreate(), MatNullSpaceCreate()
6855 @*/
6856 PetscErrorCode PETSCMAT_DLLEXPORT MatNullSpaceAttach(Mat mat,MatNullSpace nullsp)
6857 {
6858   PetscErrorCode ierr;
6859 
6860   PetscFunctionBegin;
6861   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6862   PetscValidType(mat,1);
6863   PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
6864   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6865   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
6866   if (mat->nullsp) { ierr = MatNullSpaceDestroy(mat->nullsp);CHKERRQ(ierr); }
6867   mat->nullsp = nullsp;
6868   PetscFunctionReturn(0);
6869 }
6870 
6871 #undef __FUNCT__
6872 #define __FUNCT__ "MatICCFactor"
6873 /*@C
6874    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
6875 
6876    Collective on Mat
6877 
6878    Input Parameters:
6879 +  mat - the matrix
6880 .  row - row/column permutation
6881 .  fill - expected fill factor >= 1.0
6882 -  level - level of fill, for ICC(k)
6883 
6884    Notes:
6885    Probably really in-place only when level of fill is zero, otherwise allocates
6886    new space to store factored matrix and deletes previous memory.
6887 
6888    Most users should employ the simplified KSP interface for linear solvers
6889    instead of working directly with matrix algebra routines such as this.
6890    See, e.g., KSPCreate().
6891 
6892    Level: developer
6893 
6894    Concepts: matrices^incomplete Cholesky factorization
6895    Concepts: Cholesky factorization
6896 
6897 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6898 
6899     Developer Note: fortran interface is not autogenerated as the f90
6900     interface defintion cannot be generated correctly [due to MatFactorInfo]
6901 
6902 @*/
6903 PetscErrorCode PETSCMAT_DLLEXPORT MatICCFactor(Mat mat,IS row,const MatFactorInfo* info)
6904 {
6905   PetscErrorCode ierr;
6906 
6907   PetscFunctionBegin;
6908   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6909   PetscValidType(mat,1);
6910   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
6911   PetscValidPointer(info,3);
6912   if (mat->rmap->N != mat->cmap->N) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONG,"matrix must be square");
6913   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6914   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6915   if (!mat->ops->iccfactor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6916   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6917   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
6918   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6919   PetscFunctionReturn(0);
6920 }
6921 
6922 #undef __FUNCT__
6923 #define __FUNCT__ "MatSetValuesAdic"
6924 /*@
6925    MatSetValuesAdic - Sets values computed with ADIC automatic differentiation into a matrix.
6926 
6927    Not Collective
6928 
6929    Input Parameters:
6930 +  mat - the matrix
6931 -  v - the values compute with ADIC
6932 
6933    Level: developer
6934 
6935    Notes:
6936      Must call MatSetColoring() before using this routine. Also this matrix must already
6937      have its nonzero pattern determined.
6938 
6939 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
6940           MatSetValues(), MatSetColoring(), MatSetValuesAdifor()
6941 @*/
6942 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesAdic(Mat mat,void *v)
6943 {
6944   PetscErrorCode ierr;
6945 
6946   PetscFunctionBegin;
6947   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6948   PetscValidType(mat,1);
6949   PetscValidPointer(mat,2);
6950 
6951   if (!mat->assembled) {
6952     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6953   }
6954   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
6955   if (!mat->ops->setvaluesadic) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6956   ierr = (*mat->ops->setvaluesadic)(mat,v);CHKERRQ(ierr);
6957   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
6958   ierr = MatView_Private(mat);CHKERRQ(ierr);
6959   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6960   PetscFunctionReturn(0);
6961 }
6962 
6963 
6964 #undef __FUNCT__
6965 #define __FUNCT__ "MatSetColoring"
6966 /*@
6967    MatSetColoring - Sets a coloring used by calls to MatSetValuesAdic()
6968 
6969    Not Collective
6970 
6971    Input Parameters:
6972 +  mat - the matrix
6973 -  coloring - the coloring
6974 
6975    Level: developer
6976 
6977 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
6978           MatSetValues(), MatSetValuesAdic()
6979 @*/
6980 PetscErrorCode PETSCMAT_DLLEXPORT MatSetColoring(Mat mat,ISColoring coloring)
6981 {
6982   PetscErrorCode ierr;
6983 
6984   PetscFunctionBegin;
6985   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6986   PetscValidType(mat,1);
6987   PetscValidPointer(coloring,2);
6988 
6989   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6990   if (!mat->ops->setcoloring) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6991   ierr = (*mat->ops->setcoloring)(mat,coloring);CHKERRQ(ierr);
6992   PetscFunctionReturn(0);
6993 }
6994 
6995 #undef __FUNCT__
6996 #define __FUNCT__ "MatSetValuesAdifor"
6997 /*@
6998    MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.
6999 
7000    Not Collective
7001 
7002    Input Parameters:
7003 +  mat - the matrix
7004 .  nl - leading dimension of v
7005 -  v - the values compute with ADIFOR
7006 
7007    Level: developer
7008 
7009    Notes:
7010      Must call MatSetColoring() before using this routine. Also this matrix must already
7011      have its nonzero pattern determined.
7012 
7013 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7014           MatSetValues(), MatSetColoring()
7015 @*/
7016 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
7017 {
7018   PetscErrorCode ierr;
7019 
7020   PetscFunctionBegin;
7021   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7022   PetscValidType(mat,1);
7023   PetscValidPointer(v,3);
7024 
7025   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7026   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
7027   if (!mat->ops->setvaluesadifor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7028   ierr = (*mat->ops->setvaluesadifor)(mat,nl,v);CHKERRQ(ierr);
7029   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
7030   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
7031   PetscFunctionReturn(0);
7032 }
7033 
7034 #undef __FUNCT__
7035 #define __FUNCT__ "MatDiagonalScaleLocal"
7036 /*@
7037    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
7038          ghosted ones.
7039 
7040    Not Collective
7041 
7042    Input Parameters:
7043 +  mat - the matrix
7044 -  diag = the diagonal values, including ghost ones
7045 
7046    Level: developer
7047 
7048    Notes: Works only for MPIAIJ and MPIBAIJ matrices
7049 
7050 .seealso: MatDiagonalScale()
7051 @*/
7052 PetscErrorCode PETSCMAT_DLLEXPORT MatDiagonalScaleLocal(Mat mat,Vec diag)
7053 {
7054   PetscErrorCode ierr;
7055   PetscMPIInt    size;
7056 
7057   PetscFunctionBegin;
7058   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7059   PetscValidHeaderSpecific(diag,VEC_CLASSID,2);
7060   PetscValidType(mat,1);
7061 
7062   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7063   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
7064   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
7065   if (size == 1) {
7066     PetscInt n,m;
7067     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
7068     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
7069     if (m == n) {
7070       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
7071     } else {
7072       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
7073     }
7074   } else {
7075     PetscErrorCode (*f)(Mat,Vec);
7076     ierr = PetscObjectQueryFunction((PetscObject)mat,"MatDiagonalScaleLocal_C",(void (**)(void))&f);CHKERRQ(ierr);
7077     if (f) {
7078       ierr = (*f)(mat,diag);CHKERRQ(ierr);
7079     } else {
7080       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for MPIAIJ and MPIBAIJ parallel matrices");
7081     }
7082   }
7083   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
7084   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
7085   PetscFunctionReturn(0);
7086 }
7087 
7088 #undef __FUNCT__
7089 #define __FUNCT__ "MatGetInertia"
7090 /*@
7091    MatGetInertia - Gets the inertia from a factored matrix
7092 
7093    Collective on Mat
7094 
7095    Input Parameter:
7096 .  mat - the matrix
7097 
7098    Output Parameters:
7099 +   nneg - number of negative eigenvalues
7100 .   nzero - number of zero eigenvalues
7101 -   npos - number of positive eigenvalues
7102 
7103    Level: advanced
7104 
7105    Notes: Matrix must have been factored by MatCholeskyFactor()
7106 
7107 
7108 @*/
7109 PetscErrorCode PETSCMAT_DLLEXPORT MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
7110 {
7111   PetscErrorCode ierr;
7112 
7113   PetscFunctionBegin;
7114   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7115   PetscValidType(mat,1);
7116   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7117   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
7118   if (!mat->ops->getinertia) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7119   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
7120   PetscFunctionReturn(0);
7121 }
7122 
7123 /* ----------------------------------------------------------------*/
7124 #undef __FUNCT__
7125 #define __FUNCT__ "MatSolves"
7126 /*@C
7127    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
7128 
7129    Neighbor-wise Collective on Mat and Vecs
7130 
7131    Input Parameters:
7132 +  mat - the factored matrix
7133 -  b - the right-hand-side vectors
7134 
7135    Output Parameter:
7136 .  x - the result vectors
7137 
7138    Notes:
7139    The vectors b and x cannot be the same.  I.e., one cannot
7140    call MatSolves(A,x,x).
7141 
7142    Notes:
7143    Most users should employ the simplified KSP interface for linear solvers
7144    instead of working directly with matrix algebra routines such as this.
7145    See, e.g., KSPCreate().
7146 
7147    Level: developer
7148 
7149    Concepts: matrices^triangular solves
7150 
7151 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
7152 @*/
7153 PetscErrorCode PETSCMAT_DLLEXPORT MatSolves(Mat mat,Vecs b,Vecs x)
7154 {
7155   PetscErrorCode ierr;
7156 
7157   PetscFunctionBegin;
7158   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7159   PetscValidType(mat,1);
7160   if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
7161   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7162   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
7163 
7164   if (!mat->ops->solves) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7165   ierr = MatPreallocated(mat);CHKERRQ(ierr);
7166   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
7167   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
7168   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
7169   PetscFunctionReturn(0);
7170 }
7171 
7172 #undef __FUNCT__
7173 #define __FUNCT__ "MatIsSymmetric"
7174 /*@
7175    MatIsSymmetric - Test whether a matrix is symmetric
7176 
7177    Collective on Mat
7178 
7179    Input Parameter:
7180 +  A - the matrix to test
7181 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
7182 
7183    Output Parameters:
7184 .  flg - the result
7185 
7186    Level: intermediate
7187 
7188    Concepts: matrix^symmetry
7189 
7190 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
7191 @*/
7192 PetscErrorCode PETSCMAT_DLLEXPORT MatIsSymmetric(Mat A,PetscReal tol,PetscTruth *flg)
7193 {
7194   PetscErrorCode ierr;
7195 
7196   PetscFunctionBegin;
7197   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7198   PetscValidPointer(flg,2);
7199 
7200   if (!A->symmetric_set) {
7201     if (!A->ops->issymmetric) {
7202       const MatType mattype;
7203       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7204       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7205     }
7206     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
7207     if (!tol) {
7208       A->symmetric_set = PETSC_TRUE;
7209       A->symmetric = *flg;
7210       if (A->symmetric) {
7211 	A->structurally_symmetric_set = PETSC_TRUE;
7212 	A->structurally_symmetric     = PETSC_TRUE;
7213       }
7214     }
7215   } else if (A->symmetric) {
7216     *flg = PETSC_TRUE;
7217   } else if (!tol) {
7218     *flg = PETSC_FALSE;
7219   } else {
7220     if (!A->ops->issymmetric) {
7221       const MatType mattype;
7222       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7223       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7224     }
7225     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
7226   }
7227   PetscFunctionReturn(0);
7228 }
7229 
7230 #undef __FUNCT__
7231 #define __FUNCT__ "MatIsHermitian"
7232 /*@
7233    MatIsHermitian - Test whether a matrix is Hermitian
7234 
7235    Collective on Mat
7236 
7237    Input Parameter:
7238 +  A - the matrix to test
7239 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
7240 
7241    Output Parameters:
7242 .  flg - the result
7243 
7244    Level: intermediate
7245 
7246    Concepts: matrix^symmetry
7247 
7248 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
7249 @*/
7250 PetscErrorCode PETSCMAT_DLLEXPORT MatIsHermitian(Mat A,PetscReal tol,PetscTruth *flg)
7251 {
7252   PetscErrorCode ierr;
7253 
7254   PetscFunctionBegin;
7255   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7256   PetscValidPointer(flg,2);
7257 
7258   if (!A->hermitian_set) {
7259     if (!A->ops->ishermitian) {
7260       const MatType mattype;
7261       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7262       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7263     }
7264     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
7265     if (!tol) {
7266       A->hermitian_set = PETSC_TRUE;
7267       A->hermitian = *flg;
7268       if (A->hermitian) {
7269 	A->structurally_symmetric_set = PETSC_TRUE;
7270 	A->structurally_symmetric     = PETSC_TRUE;
7271       }
7272     }
7273   } else if (A->hermitian) {
7274     *flg = PETSC_TRUE;
7275   } else if (!tol) {
7276     *flg = PETSC_FALSE;
7277   } else {
7278     if (!A->ops->ishermitian) {
7279       const MatType mattype;
7280       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7281       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7282     }
7283     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
7284   }
7285   PetscFunctionReturn(0);
7286 }
7287 
7288 #undef __FUNCT__
7289 #define __FUNCT__ "MatIsSymmetricKnown"
7290 /*@
7291    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
7292 
7293    Not Collective
7294 
7295    Input Parameter:
7296 .  A - the matrix to check
7297 
7298    Output Parameters:
7299 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
7300 -  flg - the result
7301 
7302    Level: advanced
7303 
7304    Concepts: matrix^symmetry
7305 
7306    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
7307          if you want it explicitly checked
7308 
7309 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
7310 @*/
7311 PetscErrorCode PETSCMAT_DLLEXPORT MatIsSymmetricKnown(Mat A,PetscTruth *set,PetscTruth *flg)
7312 {
7313   PetscFunctionBegin;
7314   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7315   PetscValidPointer(set,2);
7316   PetscValidPointer(flg,3);
7317   if (A->symmetric_set) {
7318     *set = PETSC_TRUE;
7319     *flg = A->symmetric;
7320   } else {
7321     *set = PETSC_FALSE;
7322   }
7323   PetscFunctionReturn(0);
7324 }
7325 
7326 #undef __FUNCT__
7327 #define __FUNCT__ "MatIsHermitianKnown"
7328 /*@
7329    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
7330 
7331    Not Collective
7332 
7333    Input Parameter:
7334 .  A - the matrix to check
7335 
7336    Output Parameters:
7337 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
7338 -  flg - the result
7339 
7340    Level: advanced
7341 
7342    Concepts: matrix^symmetry
7343 
7344    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
7345          if you want it explicitly checked
7346 
7347 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
7348 @*/
7349 PetscErrorCode PETSCMAT_DLLEXPORT MatIsHermitianKnown(Mat A,PetscTruth *set,PetscTruth *flg)
7350 {
7351   PetscFunctionBegin;
7352   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7353   PetscValidPointer(set,2);
7354   PetscValidPointer(flg,3);
7355   if (A->hermitian_set) {
7356     *set = PETSC_TRUE;
7357     *flg = A->hermitian;
7358   } else {
7359     *set = PETSC_FALSE;
7360   }
7361   PetscFunctionReturn(0);
7362 }
7363 
7364 #undef __FUNCT__
7365 #define __FUNCT__ "MatIsStructurallySymmetric"
7366 /*@
7367    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
7368 
7369    Collective on Mat
7370 
7371    Input Parameter:
7372 .  A - the matrix to test
7373 
7374    Output Parameters:
7375 .  flg - the result
7376 
7377    Level: intermediate
7378 
7379    Concepts: matrix^symmetry
7380 
7381 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
7382 @*/
7383 PetscErrorCode PETSCMAT_DLLEXPORT MatIsStructurallySymmetric(Mat A,PetscTruth *flg)
7384 {
7385   PetscErrorCode ierr;
7386 
7387   PetscFunctionBegin;
7388   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7389   PetscValidPointer(flg,2);
7390   if (!A->structurally_symmetric_set) {
7391     if (!A->ops->isstructurallysymmetric) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
7392     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
7393     A->structurally_symmetric_set = PETSC_TRUE;
7394   }
7395   *flg = A->structurally_symmetric;
7396   PetscFunctionReturn(0);
7397 }
7398 
7399 #undef __FUNCT__
7400 #define __FUNCT__ "MatStashGetInfo"
7401 extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
7402 /*@
7403    MatStashGetInfo - Gets how many values are currently in the vector stash, i.e. need
7404        to be communicated to other processors during the MatAssemblyBegin/End() process
7405 
7406     Not collective
7407 
7408    Input Parameter:
7409 .   vec - the vector
7410 
7411    Output Parameters:
7412 +   nstash   - the size of the stash
7413 .   reallocs - the number of additional mallocs incurred.
7414 .   bnstash   - the size of the block stash
7415 -   breallocs - the number of additional mallocs incurred.in the block stash
7416 
7417    Level: advanced
7418 
7419 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
7420 
7421 @*/
7422 PetscErrorCode PETSCMAT_DLLEXPORT MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
7423 {
7424   PetscErrorCode ierr;
7425   PetscFunctionBegin;
7426   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
7427   ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
7428   PetscFunctionReturn(0);
7429 }
7430 
7431 #undef __FUNCT__
7432 #define __FUNCT__ "MatGetVecs"
7433 /*@C
7434    MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same
7435      parallel layout
7436 
7437    Collective on Mat
7438 
7439    Input Parameter:
7440 .  mat - the matrix
7441 
7442    Output Parameter:
7443 +   right - (optional) vector that the matrix can be multiplied against
7444 -   left - (optional) vector that the matrix vector product can be stored in
7445 
7446   Level: advanced
7447 
7448 .seealso: MatCreate()
7449 @*/
7450 PetscErrorCode PETSCMAT_DLLEXPORT MatGetVecs(Mat mat,Vec *right,Vec *left)
7451 {
7452   PetscErrorCode ierr;
7453 
7454   PetscFunctionBegin;
7455   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7456   PetscValidType(mat,1);
7457   ierr = MatPreallocated(mat);CHKERRQ(ierr);
7458   if (mat->ops->getvecs) {
7459     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
7460   } else {
7461     PetscMPIInt size;
7462     ierr = MPI_Comm_size(((PetscObject)mat)->comm, &size);CHKERRQ(ierr);
7463     if (right) {
7464       ierr = VecCreate(((PetscObject)mat)->comm,right);CHKERRQ(ierr);
7465       ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
7466       ierr = VecSetBlockSize(*right,mat->rmap->bs);CHKERRQ(ierr);
7467       if (size > 1) {
7468         /* New vectors uses Mat cmap and does not create a new one */
7469 	ierr = PetscLayoutDestroy((*right)->map);CHKERRQ(ierr);
7470 	(*right)->map = mat->cmap;
7471 	mat->cmap->refcnt++;
7472 
7473         ierr = VecSetType(*right,VECMPI);CHKERRQ(ierr);
7474       } else {ierr = VecSetType(*right,VECSEQ);CHKERRQ(ierr);}
7475     }
7476     if (left) {
7477       ierr = VecCreate(((PetscObject)mat)->comm,left);CHKERRQ(ierr);
7478       ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
7479       ierr = VecSetBlockSize(*left,mat->rmap->bs);CHKERRQ(ierr);
7480       if (size > 1) {
7481         /* New vectors uses Mat rmap and does not create a new one */
7482 	ierr = PetscLayoutDestroy((*left)->map);CHKERRQ(ierr);
7483 	(*left)->map = mat->rmap;
7484 	mat->rmap->refcnt++;
7485 
7486         ierr = VecSetType(*left,VECMPI);CHKERRQ(ierr);
7487       } else {ierr = VecSetType(*left,VECSEQ);CHKERRQ(ierr);}
7488     }
7489   }
7490   if (mat->mapping) {
7491     if (right) {ierr = VecSetLocalToGlobalMapping(*right,mat->mapping);CHKERRQ(ierr);}
7492     if (left) {ierr = VecSetLocalToGlobalMapping(*left,mat->mapping);CHKERRQ(ierr);}
7493   }
7494   if (mat->bmapping) {
7495     if (right) {ierr = VecSetLocalToGlobalMappingBlock(*right,mat->bmapping);CHKERRQ(ierr);}
7496     if (left) {ierr = VecSetLocalToGlobalMappingBlock(*left,mat->bmapping);CHKERRQ(ierr);}
7497   }
7498   PetscFunctionReturn(0);
7499 }
7500 
7501 #undef __FUNCT__
7502 #define __FUNCT__ "MatFactorInfoInitialize"
7503 /*@C
7504    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
7505      with default values.
7506 
7507    Not Collective
7508 
7509    Input Parameters:
7510 .    info - the MatFactorInfo data structure
7511 
7512 
7513    Notes: The solvers are generally used through the KSP and PC objects, for example
7514           PCLU, PCILU, PCCHOLESKY, PCICC
7515 
7516    Level: developer
7517 
7518 .seealso: MatFactorInfo
7519 
7520     Developer Note: fortran interface is not autogenerated as the f90
7521     interface defintion cannot be generated correctly [due to MatFactorInfo]
7522 
7523 @*/
7524 
7525 PetscErrorCode PETSCMAT_DLLEXPORT MatFactorInfoInitialize(MatFactorInfo *info)
7526 {
7527   PetscErrorCode ierr;
7528 
7529   PetscFunctionBegin;
7530   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
7531   PetscFunctionReturn(0);
7532 }
7533 
7534 #undef __FUNCT__
7535 #define __FUNCT__ "MatPtAP"
7536 /*@
7537    MatPtAP - Creates the matrix product C = P^T * A * P
7538 
7539    Neighbor-wise Collective on Mat
7540 
7541    Input Parameters:
7542 +  A - the matrix
7543 .  P - the projection matrix
7544 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7545 -  fill - expected fill as ratio of nnz(C)/nnz(A)
7546 
7547    Output Parameters:
7548 .  C - the product matrix
7549 
7550    Notes:
7551    C will be created and must be destroyed by the user with MatDestroy().
7552 
7553    This routine is currently only implemented for pairs of AIJ matrices and classes
7554    which inherit from AIJ.
7555 
7556    Level: intermediate
7557 
7558 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult()
7559 @*/
7560 PetscErrorCode PETSCMAT_DLLEXPORT MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
7561 {
7562   PetscErrorCode ierr;
7563 
7564   PetscFunctionBegin;
7565   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7566   PetscValidType(A,1);
7567   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7568   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7569   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
7570   PetscValidType(P,2);
7571   ierr = MatPreallocated(P);CHKERRQ(ierr);
7572   if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7573   if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7574   PetscValidPointer(C,3);
7575   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);
7576   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
7577   ierr = MatPreallocated(A);CHKERRQ(ierr);
7578 
7579   if (!A->ops->ptap) {
7580     const MatType mattype;
7581     ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7582     SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix of type <%s> does not support PtAP",mattype);
7583   }
7584   ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
7585   ierr = (*A->ops->ptap)(A,P,scall,fill,C);CHKERRQ(ierr);
7586   ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
7587 
7588   PetscFunctionReturn(0);
7589 }
7590 
7591 #undef __FUNCT__
7592 #define __FUNCT__ "MatPtAPNumeric"
7593 /*@
7594    MatPtAPNumeric - Computes the matrix product C = P^T * A * P
7595 
7596    Neighbor-wise Collective on Mat
7597 
7598    Input Parameters:
7599 +  A - the matrix
7600 -  P - the projection matrix
7601 
7602    Output Parameters:
7603 .  C - the product matrix
7604 
7605    Notes:
7606    C must have been created by calling MatPtAPSymbolic and must be destroyed by
7607    the user using MatDeatroy().
7608 
7609    This routine is currently only implemented for pairs of AIJ matrices and classes
7610    which inherit from AIJ.  C will be of type MATAIJ.
7611 
7612    Level: intermediate
7613 
7614 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
7615 @*/
7616 PetscErrorCode PETSCMAT_DLLEXPORT MatPtAPNumeric(Mat A,Mat P,Mat C)
7617 {
7618   PetscErrorCode ierr;
7619 
7620   PetscFunctionBegin;
7621   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7622   PetscValidType(A,1);
7623   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7624   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7625   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
7626   PetscValidType(P,2);
7627   ierr = MatPreallocated(P);CHKERRQ(ierr);
7628   if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7629   if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7630   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
7631   PetscValidType(C,3);
7632   ierr = MatPreallocated(C);CHKERRQ(ierr);
7633   if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7634   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);
7635   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);
7636   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);
7637   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);
7638   ierr = MatPreallocated(A);CHKERRQ(ierr);
7639 
7640   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
7641   ierr = (*A->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr);
7642   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
7643   PetscFunctionReturn(0);
7644 }
7645 
7646 #undef __FUNCT__
7647 #define __FUNCT__ "MatPtAPSymbolic"
7648 /*@
7649    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P
7650 
7651    Neighbor-wise Collective on Mat
7652 
7653    Input Parameters:
7654 +  A - the matrix
7655 -  P - the projection matrix
7656 
7657    Output Parameters:
7658 .  C - the (i,j) structure of the product matrix
7659 
7660    Notes:
7661    C will be created and must be destroyed by the user with MatDestroy().
7662 
7663    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
7664    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
7665    this (i,j) structure by calling MatPtAPNumeric().
7666 
7667    Level: intermediate
7668 
7669 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
7670 @*/
7671 PetscErrorCode PETSCMAT_DLLEXPORT MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
7672 {
7673   PetscErrorCode ierr;
7674 
7675   PetscFunctionBegin;
7676   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7677   PetscValidType(A,1);
7678   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7679   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7680   if (fill <1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
7681   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
7682   PetscValidType(P,2);
7683   ierr = MatPreallocated(P);CHKERRQ(ierr);
7684   if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7685   if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7686   PetscValidPointer(C,3);
7687 
7688   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);
7689   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);
7690   ierr = MatPreallocated(A);CHKERRQ(ierr);
7691   ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
7692   ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr);
7693   ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
7694 
7695   ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr);
7696 
7697   PetscFunctionReturn(0);
7698 }
7699 
7700 #undef __FUNCT__
7701 #define __FUNCT__ "MatMatMult"
7702 /*@
7703    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
7704 
7705    Neighbor-wise Collective on Mat
7706 
7707    Input Parameters:
7708 +  A - the left matrix
7709 .  B - the right matrix
7710 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7711 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
7712           if the result is a dense matrix this is irrelevent
7713 
7714    Output Parameters:
7715 .  C - the product matrix
7716 
7717    Notes:
7718    Unless scall is MAT_REUSE_MATRIX C will be created.
7719 
7720    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
7721 
7722    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
7723    actually needed.
7724 
7725    If you have many matrices with the same non-zero structure to multiply, you
7726    should either
7727 $   1) use MAT_REUSE_MATRIX in all calls but the first or
7728 $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
7729 
7730    Level: intermediate
7731 
7732 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatPtAP()
7733 @*/
7734 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
7735 {
7736   PetscErrorCode ierr;
7737   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
7738   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
7739   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat *)=PETSC_NULL;
7740 
7741   PetscFunctionBegin;
7742   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7743   PetscValidType(A,1);
7744   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7745   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7746   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
7747   PetscValidType(B,2);
7748   ierr = MatPreallocated(B);CHKERRQ(ierr);
7749   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7750   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7751   PetscValidPointer(C,3);
7752   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);
7753   if (scall == MAT_REUSE_MATRIX){
7754     PetscValidPointer(*C,5);
7755     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
7756   }
7757   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
7758   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
7759   ierr = MatPreallocated(A);CHKERRQ(ierr);
7760 
7761   fA = A->ops->matmult;
7762   fB = B->ops->matmult;
7763   if (fB == fA) {
7764     if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
7765     mult = fB;
7766   } else {
7767     /* dispatch based on the type of A and B */
7768     char  multname[256];
7769     ierr = PetscStrcpy(multname,"MatMatMult_");CHKERRQ(ierr);
7770     ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr);
7771     ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);
7772     ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr);
7773     ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
7774     ierr = PetscObjectQueryFunction((PetscObject)B,multname,(void (**)(void))&mult);CHKERRQ(ierr);
7775     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);
7776   }
7777   ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
7778   ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr);
7779   ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
7780   PetscFunctionReturn(0);
7781 }
7782 
7783 #undef __FUNCT__
7784 #define __FUNCT__ "MatMatMultSymbolic"
7785 /*@
7786    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
7787    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().
7788 
7789    Neighbor-wise Collective on Mat
7790 
7791    Input Parameters:
7792 +  A - the left matrix
7793 .  B - the right matrix
7794 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
7795       if C is a dense matrix this is irrelevent
7796 
7797    Output Parameters:
7798 .  C - the product matrix
7799 
7800    Notes:
7801    Unless scall is MAT_REUSE_MATRIX C will be created.
7802 
7803    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
7804    actually needed.
7805 
7806    This routine is currently implemented for
7807     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
7808     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
7809     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
7810 
7811    Level: intermediate
7812 
7813    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
7814      We should incorporate them into PETSc.
7815 
7816 .seealso: MatMatMult(), MatMatMultNumeric()
7817 @*/
7818 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
7819 {
7820   PetscErrorCode ierr;
7821   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat *);
7822   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat *);
7823   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat *)=PETSC_NULL;
7824 
7825   PetscFunctionBegin;
7826   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7827   PetscValidType(A,1);
7828   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7829   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7830 
7831   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
7832   PetscValidType(B,2);
7833   ierr = MatPreallocated(B);CHKERRQ(ierr);
7834   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7835   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7836   PetscValidPointer(C,3);
7837 
7838   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);
7839   if (fill == PETSC_DEFAULT) fill = 2.0;
7840   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
7841   ierr = MatPreallocated(A);CHKERRQ(ierr);
7842 
7843   Asymbolic = A->ops->matmultsymbolic;
7844   Bsymbolic = B->ops->matmultsymbolic;
7845   if (Asymbolic == Bsymbolic){
7846     if (!Bsymbolic) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
7847     symbolic = Bsymbolic;
7848   } else { /* dispatch based on the type of A and B */
7849     char  symbolicname[256];
7850     ierr = PetscStrcpy(symbolicname,"MatMatMultSymbolic_");CHKERRQ(ierr);
7851     ierr = PetscStrcat(symbolicname,((PetscObject)A)->type_name);CHKERRQ(ierr);
7852     ierr = PetscStrcat(symbolicname,"_");CHKERRQ(ierr);
7853     ierr = PetscStrcat(symbolicname,((PetscObject)B)->type_name);CHKERRQ(ierr);
7854     ierr = PetscStrcat(symbolicname,"_C");CHKERRQ(ierr);
7855     ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,(void (**)(void))&symbolic);CHKERRQ(ierr);
7856     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);
7857   }
7858   ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
7859   ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr);
7860   ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
7861   PetscFunctionReturn(0);
7862 }
7863 
7864 #undef __FUNCT__
7865 #define __FUNCT__ "MatMatMultNumeric"
7866 /*@
7867    MatMatMultNumeric - Performs the numeric matrix-matrix product.
7868    Call this routine after first calling MatMatMultSymbolic().
7869 
7870    Neighbor-wise Collective on Mat
7871 
7872    Input Parameters:
7873 +  A - the left matrix
7874 -  B - the right matrix
7875 
7876    Output Parameters:
7877 .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
7878 
7879    Notes:
7880    C must have been created with MatMatMultSymbolic().
7881 
7882    This routine is currently implemented for
7883     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
7884     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
7885     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
7886 
7887    Level: intermediate
7888 
7889 .seealso: MatMatMult(), MatMatMultSymbolic()
7890 @*/
7891 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMultNumeric(Mat A,Mat B,Mat C)
7892 {
7893   PetscErrorCode ierr;
7894   PetscErrorCode (*Anumeric)(Mat,Mat,Mat);
7895   PetscErrorCode (*Bnumeric)(Mat,Mat,Mat);
7896   PetscErrorCode (*numeric)(Mat,Mat,Mat)=PETSC_NULL;
7897 
7898   PetscFunctionBegin;
7899   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7900   PetscValidType(A,1);
7901   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7902   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7903 
7904   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
7905   PetscValidType(B,2);
7906   ierr = MatPreallocated(B);CHKERRQ(ierr);
7907   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7908   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7909 
7910   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
7911   PetscValidType(C,3);
7912   ierr = MatPreallocated(C);CHKERRQ(ierr);
7913   if (!C->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7914   if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7915 
7916   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);
7917   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);
7918   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);
7919   ierr = MatPreallocated(A);CHKERRQ(ierr);
7920 
7921   Anumeric = A->ops->matmultnumeric;
7922   Bnumeric = B->ops->matmultnumeric;
7923   if (Anumeric == Bnumeric){
7924     if (!Bnumeric) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMultNumeric not supported for B of type %s",((PetscObject)B)->type_name);
7925     numeric = Bnumeric;
7926   } else {
7927     char  numericname[256];
7928     ierr = PetscStrcpy(numericname,"MatMatMultNumeric_");CHKERRQ(ierr);
7929     ierr = PetscStrcat(numericname,((PetscObject)A)->type_name);CHKERRQ(ierr);
7930     ierr = PetscStrcat(numericname,"_");CHKERRQ(ierr);
7931     ierr = PetscStrcat(numericname,((PetscObject)B)->type_name);CHKERRQ(ierr);
7932     ierr = PetscStrcat(numericname,"_C");CHKERRQ(ierr);
7933     ierr = PetscObjectQueryFunction((PetscObject)B,numericname,(void (**)(void))&numeric);CHKERRQ(ierr);
7934     if (!numeric)
7935       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);
7936   }
7937   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
7938   ierr = (*numeric)(A,B,C);CHKERRQ(ierr);
7939   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
7940   PetscFunctionReturn(0);
7941 }
7942 
7943 #undef __FUNCT__
7944 #define __FUNCT__ "MatMatMultTranspose"
7945 /*@
7946    MatMatMultTranspose - Performs Matrix-Matrix Multiplication C=A^T*B.
7947 
7948    Neighbor-wise Collective on Mat
7949 
7950    Input Parameters:
7951 +  A - the left matrix
7952 .  B - the right matrix
7953 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7954 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
7955 
7956    Output Parameters:
7957 .  C - the product matrix
7958 
7959    Notes:
7960    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
7961 
7962    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
7963 
7964   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
7965    actually needed.
7966 
7967    This routine is currently only implemented for pairs of SeqAIJ matrices and pairs of SeqDense matrices and classes
7968    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.
7969 
7970    Level: intermediate
7971 
7972 .seealso: MatMatMultTransposeSymbolic(), MatMatMultTransposeNumeric(), MatPtAP()
7973 @*/
7974 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMultTranspose(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
7975 {
7976   PetscErrorCode ierr;
7977   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
7978   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
7979 
7980   PetscFunctionBegin;
7981   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7982   PetscValidType(A,1);
7983   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7984   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7985   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
7986   PetscValidType(B,2);
7987   ierr = MatPreallocated(B);CHKERRQ(ierr);
7988   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7989   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7990   PetscValidPointer(C,3);
7991   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);
7992   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
7993   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
7994   ierr = MatPreallocated(A);CHKERRQ(ierr);
7995 
7996   fA = A->ops->matmulttranspose;
7997   if (!fA) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMultTranspose not supported for A of type %s",((PetscObject)A)->type_name);
7998   fB = B->ops->matmulttranspose;
7999   if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMultTranspose not supported for B of type %s",((PetscObject)B)->type_name);
8000   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);
8001 
8002   ierr = PetscLogEventBegin(MAT_MatMultTranspose,A,B,0,0);CHKERRQ(ierr);
8003   ierr = (*A->ops->matmulttranspose)(A,B,scall,fill,C);CHKERRQ(ierr);
8004   ierr = PetscLogEventEnd(MAT_MatMultTranspose,A,B,0,0);CHKERRQ(ierr);
8005 
8006   PetscFunctionReturn(0);
8007 }
8008 
8009 #undef __FUNCT__
8010 #define __FUNCT__ "MatGetRedundantMatrix"
8011 /*@C
8012    MatGetRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
8013 
8014    Collective on Mat
8015 
8016    Input Parameters:
8017 +  mat - the matrix
8018 .  nsubcomm - the number of subcommunicators (= number of redundant pareallel or sequential matrices)
8019 .  subcomm - MPI communicator split from the communicator where mat resides in
8020 .  mlocal_red - number of local rows of the redundant matrix
8021 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8022 
8023    Output Parameter:
8024 .  matredundant - redundant matrix
8025 
8026    Notes:
8027    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
8028    original matrix has not changed from that last call to MatGetRedundantMatrix().
8029 
8030    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
8031    calling it.
8032 
8033    Only MPIAIJ matrix is supported.
8034 
8035    Level: advanced
8036 
8037    Concepts: subcommunicator
8038    Concepts: duplicate matrix
8039 
8040 .seealso: MatDestroy()
8041 @*/
8042 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,PetscInt mlocal_red,MatReuse reuse,Mat *matredundant)
8043 {
8044   PetscErrorCode ierr;
8045 
8046   PetscFunctionBegin;
8047   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8048   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
8049     PetscValidPointer(*matredundant,6);
8050     PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,6);
8051   }
8052   if (!mat->ops->getredundantmatrix) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8053   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8054   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8055   ierr = MatPreallocated(mat);CHKERRQ(ierr);
8056 
8057   ierr = PetscLogEventBegin(MAT_GetRedundantMatrix,mat,0,0,0);CHKERRQ(ierr);
8058   ierr = (*mat->ops->getredundantmatrix)(mat,nsubcomm,subcomm,mlocal_red,reuse,matredundant);CHKERRQ(ierr);
8059   ierr = PetscLogEventEnd(MAT_GetRedundantMatrix,mat,0,0,0);CHKERRQ(ierr);
8060   PetscFunctionReturn(0);
8061 }
8062