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