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