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