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