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