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