xref: /petsc/src/mat/interface/matrix.c (revision 809321af93c81e1a5fcb6fabdece67fc11fe4e84)
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   if (mat->rmap->N != mat->cmap->N) SETERRQ(PETSC_ERR_ARG_WRONG,"matrix must be square");
2195   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2196   ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
2197   ierr = (*mat->ops->iludtfactor)(mat,row,col,info,fact);CHKERRQ(ierr);
2198   ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
2199   ierr = PetscObjectStateIncrease((PetscObject)*fact);CHKERRQ(ierr);
2200 
2201   PetscFunctionReturn(0);
2202 }
2203 
2204 #undef __FUNCT__
2205 #define __FUNCT__ "MatLUFactor"
2206 /*@
2207    MatLUFactor - Performs in-place LU factorization of matrix.
2208 
2209    Collective on Mat
2210 
2211    Input Parameters:
2212 +  mat - the matrix
2213 .  row - row permutation
2214 .  col - column permutation
2215 -  info - options for factorization, includes
2216 $          fill - expected fill as ratio of original fill.
2217 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2218 $                   Run with the option -info to determine an optimal value to use
2219 
2220    Notes:
2221    Most users should employ the simplified KSP interface for linear solvers
2222    instead of working directly with matrix algebra routines such as this.
2223    See, e.g., KSPCreate().
2224 
2225    This changes the state of the matrix to a factored matrix; it cannot be used
2226    for example with MatSetValues() unless one first calls MatSetUnfactored().
2227 
2228    Level: developer
2229 
2230    Concepts: matrices^LU factorization
2231 
2232 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2233           MatGetOrdering(), MatSetUnfactored(), MatFactorInfo
2234 
2235 @*/
2236 PetscErrorCode PETSCMAT_DLLEXPORT MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2237 {
2238   PetscErrorCode ierr;
2239 
2240   PetscFunctionBegin;
2241   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2242   if (row) PetscValidHeaderSpecific(row,IS_COOKIE,2);
2243   if (col) PetscValidHeaderSpecific(col,IS_COOKIE,3);
2244   PetscValidPointer(info,4);
2245   PetscValidType(mat,1);
2246   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2247   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2248   if (!mat->ops->lufactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2249   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2250 
2251   ierr = PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
2252   ierr = (*mat->ops->lufactor)(mat,row,col,info);CHKERRQ(ierr);
2253   ierr = PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
2254   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
2255   PetscFunctionReturn(0);
2256 }
2257 
2258 #undef __FUNCT__
2259 #define __FUNCT__ "MatILUFactor"
2260 /*@
2261    MatILUFactor - Performs in-place ILU factorization of matrix.
2262 
2263    Collective on Mat
2264 
2265    Input Parameters:
2266 +  mat - the matrix
2267 .  row - row permutation
2268 .  col - column permutation
2269 -  info - structure containing
2270 $      levels - number of levels of fill.
2271 $      expected fill - as ratio of original fill.
2272 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2273                 missing diagonal entries)
2274 
2275    Notes:
2276    Probably really in-place only when level of fill is zero, otherwise allocates
2277    new space to store factored matrix and deletes previous memory.
2278 
2279    Most users should employ the simplified KSP interface for linear solvers
2280    instead of working directly with matrix algebra routines such as this.
2281    See, e.g., KSPCreate().
2282 
2283    Level: developer
2284 
2285    Concepts: matrices^ILU factorization
2286 
2287 .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
2288 @*/
2289 PetscErrorCode PETSCMAT_DLLEXPORT MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2290 {
2291   PetscErrorCode ierr;
2292 
2293   PetscFunctionBegin;
2294   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2295   if (row) PetscValidHeaderSpecific(row,IS_COOKIE,2);
2296   if (col) PetscValidHeaderSpecific(col,IS_COOKIE,3);
2297   PetscValidPointer(info,4);
2298   PetscValidType(mat,1);
2299   if (mat->rmap->N != mat->cmap->N) SETERRQ(PETSC_ERR_ARG_WRONG,"matrix must be square");
2300   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2301   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2302   if (!mat->ops->ilufactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2303   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2304 
2305   ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
2306   ierr = (*mat->ops->ilufactor)(mat,row,col,info);CHKERRQ(ierr);
2307   ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
2308   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
2309   PetscFunctionReturn(0);
2310 }
2311 
2312 #undef __FUNCT__
2313 #define __FUNCT__ "MatLUFactorSymbolic"
2314 /*@
2315    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
2316    Call this routine before calling MatLUFactorNumeric().
2317 
2318    Collective on Mat
2319 
2320    Input Parameters:
2321 +  fact - the factor matrix obtained with MatGetFactor()
2322 .  mat - the matrix
2323 .  row, col - row and column permutations
2324 -  info - options for factorization, includes
2325 $          fill - expected fill as ratio of original fill.
2326 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2327 $                   Run with the option -info to determine an optimal value to use
2328 
2329 
2330    Notes:
2331    See the users manual for additional information about
2332    choosing the fill factor for better efficiency.
2333 
2334    Most users should employ the simplified KSP interface for linear solvers
2335    instead of working directly with matrix algebra routines such as this.
2336    See, e.g., KSPCreate().
2337 
2338    Level: developer
2339 
2340    Concepts: matrices^LU symbolic factorization
2341 
2342 .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
2343 @*/
2344 PetscErrorCode PETSCMAT_DLLEXPORT MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
2345 {
2346   PetscErrorCode ierr;
2347 
2348   PetscFunctionBegin;
2349   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2350   if (row) PetscValidHeaderSpecific(row,IS_COOKIE,2);
2351   if (col) PetscValidHeaderSpecific(col,IS_COOKIE,3);
2352   PetscValidPointer(info,4);
2353   PetscValidType(mat,1);
2354   PetscValidPointer(fact,5);
2355   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2356   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2357   if (!(fact)->ops->lufactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s  symbolic LU",((PetscObject)mat)->type_name);
2358   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2359 
2360   ierr = PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
2361   ierr = (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
2362   ierr = PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
2363   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
2364   PetscFunctionReturn(0);
2365 }
2366 
2367 #undef __FUNCT__
2368 #define __FUNCT__ "MatLUFactorNumeric"
2369 /*@
2370    MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
2371    Call this routine after first calling MatLUFactorSymbolic().
2372 
2373    Collective on Mat
2374 
2375    Input Parameters:
2376 +  fact - the factor matrix obtained with MatGetFactor()
2377 .  mat - the matrix
2378 -  info - options for factorization
2379 
2380    Notes:
2381    See MatLUFactor() for in-place factorization.  See
2382    MatCholeskyFactorNumeric() for the symmetric, positive definite case.
2383 
2384    Most users should employ the simplified KSP interface for linear solvers
2385    instead of working directly with matrix algebra routines such as this.
2386    See, e.g., KSPCreate().
2387 
2388    Level: developer
2389 
2390    Concepts: matrices^LU numeric factorization
2391 
2392 .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()
2393 @*/
2394 PetscErrorCode PETSCMAT_DLLEXPORT MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
2395 {
2396   PetscErrorCode ierr;
2397 
2398   PetscFunctionBegin;
2399   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2400   PetscValidType(mat,1);
2401   PetscValidPointer(fact,2);
2402   PetscValidHeaderSpecific(fact,MAT_COOKIE,2);
2403   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2404   if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) {
2405     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);
2406   }
2407   if (!(fact)->ops->lufactornumeric) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2408   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2409   ierr = PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
2410   ierr = (fact->ops->lufactornumeric)(fact,mat,info);CHKERRQ(ierr);
2411   ierr = PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
2412 
2413   ierr = MatView_Private(fact);CHKERRQ(ierr);
2414   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
2415   PetscFunctionReturn(0);
2416 }
2417 
2418 #undef __FUNCT__
2419 #define __FUNCT__ "MatCholeskyFactor"
2420 /*@
2421    MatCholeskyFactor - Performs in-place Cholesky factorization of a
2422    symmetric matrix.
2423 
2424    Collective on Mat
2425 
2426    Input Parameters:
2427 +  mat - the matrix
2428 .  perm - row and column permutations
2429 -  f - expected fill as ratio of original fill
2430 
2431    Notes:
2432    See MatLUFactor() for the nonsymmetric case.  See also
2433    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().
2434 
2435    Most users should employ the simplified KSP interface for linear solvers
2436    instead of working directly with matrix algebra routines such as this.
2437    See, e.g., KSPCreate().
2438 
2439    Level: developer
2440 
2441    Concepts: matrices^Cholesky factorization
2442 
2443 .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
2444           MatGetOrdering()
2445 
2446 @*/
2447 PetscErrorCode PETSCMAT_DLLEXPORT MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
2448 {
2449   PetscErrorCode ierr;
2450 
2451   PetscFunctionBegin;
2452   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2453   PetscValidType(mat,1);
2454   PetscValidHeaderSpecific(perm,IS_COOKIE,2);
2455   PetscValidPointer(info,3);
2456   if (mat->rmap->N != mat->cmap->N) SETERRQ(PETSC_ERR_ARG_WRONG,"Matrix must be square");
2457   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2458   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2459   if (!mat->ops->choleskyfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2460   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2461 
2462   ierr = PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
2463   ierr = (*mat->ops->choleskyfactor)(mat,perm,info);CHKERRQ(ierr);
2464   ierr = PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
2465   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
2466   PetscFunctionReturn(0);
2467 }
2468 
2469 #undef __FUNCT__
2470 #define __FUNCT__ "MatCholeskyFactorSymbolic"
2471 /*@
2472    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
2473    of a symmetric matrix.
2474 
2475    Collective on Mat
2476 
2477    Input Parameters:
2478 +  fact - the factor matrix obtained with MatGetFactor()
2479 .  mat - the matrix
2480 .  perm - row and column permutations
2481 -  info - options for factorization, includes
2482 $          fill - expected fill as ratio of original fill.
2483 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2484 $                   Run with the option -info to determine an optimal value to use
2485 
2486    Notes:
2487    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
2488    MatCholeskyFactor() and MatCholeskyFactorNumeric().
2489 
2490    Most users should employ the simplified KSP interface for linear solvers
2491    instead of working directly with matrix algebra routines such as this.
2492    See, e.g., KSPCreate().
2493 
2494    Level: developer
2495 
2496    Concepts: matrices^Cholesky symbolic factorization
2497 
2498 .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
2499           MatGetOrdering()
2500 
2501 @*/
2502 PetscErrorCode PETSCMAT_DLLEXPORT MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
2503 {
2504   PetscErrorCode ierr;
2505 
2506   PetscFunctionBegin;
2507   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2508   PetscValidType(mat,1);
2509   if (perm) PetscValidHeaderSpecific(perm,IS_COOKIE,2);
2510   PetscValidPointer(info,3);
2511   PetscValidPointer(fact,4);
2512   if (mat->rmap->N != mat->cmap->N) SETERRQ(PETSC_ERR_ARG_WRONG,"Matrix must be square");
2513   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2514   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2515   if (!(fact)->ops->choleskyfactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2516   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2517 
2518   ierr = PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
2519   ierr = (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
2520   ierr = PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
2521   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
2522   PetscFunctionReturn(0);
2523 }
2524 
2525 #undef __FUNCT__
2526 #define __FUNCT__ "MatCholeskyFactorNumeric"
2527 /*@
2528    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
2529    of a symmetric matrix. Call this routine after first calling
2530    MatCholeskyFactorSymbolic().
2531 
2532    Collective on Mat
2533 
2534    Input Parameters:
2535 +  fact - the factor matrix obtained with MatGetFactor()
2536 .  mat - the initial matrix
2537 .  info - options for factorization
2538 -  fact - the symbolic factor of mat
2539 
2540 
2541    Notes:
2542    Most users should employ the simplified KSP interface for linear solvers
2543    instead of working directly with matrix algebra routines such as this.
2544    See, e.g., KSPCreate().
2545 
2546    Level: developer
2547 
2548    Concepts: matrices^Cholesky numeric factorization
2549 
2550 .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
2551 @*/
2552 PetscErrorCode PETSCMAT_DLLEXPORT MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
2553 {
2554   PetscErrorCode ierr;
2555 
2556   PetscFunctionBegin;
2557   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2558   PetscValidType(mat,1);
2559   PetscValidPointer(fact,2);
2560   PetscValidHeaderSpecific(fact,MAT_COOKIE,2);
2561   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2562   if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2563   if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) {
2564     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);
2565   }
2566   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2567 
2568   ierr = PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
2569   ierr = (fact->ops->choleskyfactornumeric)(fact,mat,info);CHKERRQ(ierr);
2570   ierr = PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
2571 
2572   ierr = MatView_Private(fact);CHKERRQ(ierr);
2573   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
2574   PetscFunctionReturn(0);
2575 }
2576 
2577 /* ----------------------------------------------------------------*/
2578 #undef __FUNCT__
2579 #define __FUNCT__ "MatSolve"
2580 /*@
2581    MatSolve - Solves A x = b, given a factored matrix.
2582 
2583    Collective on Mat and Vec
2584 
2585    Input Parameters:
2586 +  mat - the factored matrix
2587 -  b - the right-hand-side vector
2588 
2589    Output Parameter:
2590 .  x - the result vector
2591 
2592    Notes:
2593    The vectors b and x cannot be the same.  I.e., one cannot
2594    call MatSolve(A,x,x).
2595 
2596    Notes:
2597    Most users should employ the simplified KSP interface for linear solvers
2598    instead of working directly with matrix algebra routines such as this.
2599    See, e.g., KSPCreate().
2600 
2601    Level: developer
2602 
2603    Concepts: matrices^triangular solves
2604 
2605 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
2606 @*/
2607 PetscErrorCode PETSCMAT_DLLEXPORT MatSolve(Mat mat,Vec b,Vec x)
2608 {
2609   PetscErrorCode ierr;
2610 
2611   PetscFunctionBegin;
2612   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2613   PetscValidType(mat,1);
2614   PetscValidHeaderSpecific(b,VEC_COOKIE,2);
2615   PetscValidHeaderSpecific(x,VEC_COOKIE,3);
2616   PetscCheckSameComm(mat,1,b,2);
2617   PetscCheckSameComm(mat,1,x,3);
2618   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2619   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2620   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);
2621   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);
2622   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);
2623   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
2624   if (!mat->ops->solve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2625   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2626 
2627   ierr = PetscLogEventBegin(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
2628   ierr = (*mat->ops->solve)(mat,b,x);CHKERRQ(ierr);
2629   ierr = PetscLogEventEnd(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
2630   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
2631   PetscFunctionReturn(0);
2632 }
2633 
2634 #undef __FUNCT__
2635 #define __FUNCT__ "MatMatSolve_Basic"
2636 PetscErrorCode PETSCMAT_DLLEXPORT MatMatSolve_Basic(Mat A,Mat B,Mat X)
2637 {
2638   PetscErrorCode ierr;
2639   Vec            b,x;
2640   PetscInt       m,N,i;
2641   PetscScalar    *bb,*xx;
2642 
2643   PetscFunctionBegin;
2644   ierr = MatGetArray(B,&bb);CHKERRQ(ierr);
2645   ierr = MatGetArray(X,&xx);CHKERRQ(ierr);
2646   ierr = MatGetLocalSize(B,&m,PETSC_NULL);CHKERRQ(ierr);  /* number local rows */
2647   ierr = MatGetSize(B,PETSC_NULL,&N);CHKERRQ(ierr);       /* total columns in dense matrix */
2648   ierr = VecCreateMPIWithArray(((PetscObject)A)->comm,m,PETSC_DETERMINE,PETSC_NULL,&b);CHKERRQ(ierr);
2649   ierr = VecCreateMPIWithArray(((PetscObject)A)->comm,m,PETSC_DETERMINE,PETSC_NULL,&x);CHKERRQ(ierr);
2650   for (i=0; i<N; i++) {
2651     ierr = VecPlaceArray(b,bb + i*m);CHKERRQ(ierr);
2652     ierr = VecPlaceArray(x,xx + i*m);CHKERRQ(ierr);
2653     ierr = MatSolve(A,b,x);CHKERRQ(ierr);
2654     ierr = VecResetArray(x);CHKERRQ(ierr);
2655     ierr = VecResetArray(b);CHKERRQ(ierr);
2656   }
2657   ierr = VecDestroy(b);CHKERRQ(ierr);
2658   ierr = VecDestroy(x);CHKERRQ(ierr);
2659   ierr = MatRestoreArray(B,&bb);CHKERRQ(ierr);
2660   ierr = MatRestoreArray(X,&xx);CHKERRQ(ierr);
2661   PetscFunctionReturn(0);
2662 }
2663 
2664 #undef __FUNCT__
2665 #define __FUNCT__ "MatMatSolve"
2666 /*@
2667    MatMatSolve - Solves A X = B, given a factored matrix.
2668 
2669    Collective on Mat
2670 
2671    Input Parameters:
2672 +  mat - the factored matrix
2673 -  B - the right-hand-side matrix  (dense matrix)
2674 
2675    Output Parameter:
2676 .  X - the result matrix (dense matrix)
2677 
2678    Notes:
2679    The matrices b and x cannot be the same.  I.e., one cannot
2680    call MatMatSolve(A,x,x).
2681 
2682    Notes:
2683    Most users should usually employ the simplified KSP interface for linear solvers
2684    instead of working directly with matrix algebra routines such as this.
2685    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
2686    at a time.
2687 
2688    Level: developer
2689 
2690    Concepts: matrices^triangular solves
2691 
2692 .seealso: MatMatSolveAdd(), MatMatSolveTranspose(), MatMatSolveTransposeAdd(), MatLUFactor(), MatCholeskyFactor()
2693 @*/
2694 PetscErrorCode PETSCMAT_DLLEXPORT MatMatSolve(Mat A,Mat B,Mat X)
2695 {
2696   PetscErrorCode ierr;
2697 
2698   PetscFunctionBegin;
2699   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
2700   PetscValidType(A,1);
2701   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
2702   PetscValidHeaderSpecific(X,MAT_COOKIE,3);
2703   PetscCheckSameComm(A,1,B,2);
2704   PetscCheckSameComm(A,1,X,3);
2705   if (X == B) SETERRQ(PETSC_ERR_ARG_IDN,"X and B must be different matrices");
2706   if (!A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2707   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);
2708   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);
2709   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);
2710   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
2711   ierr = MatPreallocated(A);CHKERRQ(ierr);
2712 
2713   ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
2714   if (!A->ops->matsolve) {
2715     ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolve",((PetscObject)A)->type_name);CHKERRQ(ierr);
2716     ierr = MatMatSolve_Basic(A,B,X);CHKERRQ(ierr);
2717   } else {
2718     ierr = (*A->ops->matsolve)(A,B,X);CHKERRQ(ierr);
2719   }
2720   ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
2721   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
2722   PetscFunctionReturn(0);
2723 }
2724 
2725 
2726 #undef __FUNCT__
2727 #define __FUNCT__ "MatForwardSolve"
2728 /* @
2729    MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or
2730                             U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U,
2731 
2732    Collective on Mat and Vec
2733 
2734    Input Parameters:
2735 +  mat - the factored matrix
2736 -  b - the right-hand-side vector
2737 
2738    Output Parameter:
2739 .  x - the result vector
2740 
2741    Notes:
2742    MatSolve() should be used for most applications, as it performs
2743    a forward solve followed by a backward solve.
2744 
2745    The vectors b and x cannot be the same,  i.e., one cannot
2746    call MatForwardSolve(A,x,x).
2747 
2748    For matrix in seqsbaij format with block size larger than 1,
2749    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
2750    MatForwardSolve() solves U^T*D y = b, and
2751    MatBackwardSolve() solves U x = y.
2752    Thus they do not provide a symmetric preconditioner.
2753 
2754    Most users should employ the simplified KSP interface for linear solvers
2755    instead of working directly with matrix algebra routines such as this.
2756    See, e.g., KSPCreate().
2757 
2758    Level: developer
2759 
2760    Concepts: matrices^forward solves
2761 
2762 .seealso: MatSolve(), MatBackwardSolve()
2763 @ */
2764 PetscErrorCode PETSCMAT_DLLEXPORT MatForwardSolve(Mat mat,Vec b,Vec x)
2765 {
2766   PetscErrorCode ierr;
2767 
2768   PetscFunctionBegin;
2769   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2770   PetscValidType(mat,1);
2771   PetscValidHeaderSpecific(b,VEC_COOKIE,2);
2772   PetscValidHeaderSpecific(x,VEC_COOKIE,3);
2773   PetscCheckSameComm(mat,1,b,2);
2774   PetscCheckSameComm(mat,1,x,3);
2775   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2776   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2777   if (!mat->ops->forwardsolve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2778   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);
2779   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);
2780   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);
2781   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2782   ierr = PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
2783   ierr = (*mat->ops->forwardsolve)(mat,b,x);CHKERRQ(ierr);
2784   ierr = PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
2785   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
2786   PetscFunctionReturn(0);
2787 }
2788 
2789 #undef __FUNCT__
2790 #define __FUNCT__ "MatBackwardSolve"
2791 /* @
2792    MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
2793                              D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U,
2794 
2795    Collective on Mat and Vec
2796 
2797    Input Parameters:
2798 +  mat - the factored matrix
2799 -  b - the right-hand-side vector
2800 
2801    Output Parameter:
2802 .  x - the result vector
2803 
2804    Notes:
2805    MatSolve() should be used for most applications, as it performs
2806    a forward solve followed by a backward solve.
2807 
2808    The vectors b and x cannot be the same.  I.e., one cannot
2809    call MatBackwardSolve(A,x,x).
2810 
2811    For matrix in seqsbaij format with block size larger than 1,
2812    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
2813    MatForwardSolve() solves U^T*D y = b, and
2814    MatBackwardSolve() solves U x = y.
2815    Thus they do not provide a symmetric preconditioner.
2816 
2817    Most users should employ the simplified KSP interface for linear solvers
2818    instead of working directly with matrix algebra routines such as this.
2819    See, e.g., KSPCreate().
2820 
2821    Level: developer
2822 
2823    Concepts: matrices^backward solves
2824 
2825 .seealso: MatSolve(), MatForwardSolve()
2826 @ */
2827 PetscErrorCode PETSCMAT_DLLEXPORT MatBackwardSolve(Mat mat,Vec b,Vec x)
2828 {
2829   PetscErrorCode ierr;
2830 
2831   PetscFunctionBegin;
2832   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2833   PetscValidType(mat,1);
2834   PetscValidHeaderSpecific(b,VEC_COOKIE,2);
2835   PetscValidHeaderSpecific(x,VEC_COOKIE,3);
2836   PetscCheckSameComm(mat,1,b,2);
2837   PetscCheckSameComm(mat,1,x,3);
2838   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2839   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2840   if (!mat->ops->backwardsolve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2841   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);
2842   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);
2843   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);
2844   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2845 
2846   ierr = PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
2847   ierr = (*mat->ops->backwardsolve)(mat,b,x);CHKERRQ(ierr);
2848   ierr = PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
2849   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
2850   PetscFunctionReturn(0);
2851 }
2852 
2853 #undef __FUNCT__
2854 #define __FUNCT__ "MatSolveAdd"
2855 /*@
2856    MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
2857 
2858    Collective on Mat and Vec
2859 
2860    Input Parameters:
2861 +  mat - the factored matrix
2862 .  b - the right-hand-side vector
2863 -  y - the vector to be added to
2864 
2865    Output Parameter:
2866 .  x - the result vector
2867 
2868    Notes:
2869    The vectors b and x cannot be the same.  I.e., one cannot
2870    call MatSolveAdd(A,x,y,x).
2871 
2872    Most users should employ the simplified KSP interface for linear solvers
2873    instead of working directly with matrix algebra routines such as this.
2874    See, e.g., KSPCreate().
2875 
2876    Level: developer
2877 
2878    Concepts: matrices^triangular solves
2879 
2880 .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
2881 @*/
2882 PetscErrorCode PETSCMAT_DLLEXPORT MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
2883 {
2884   PetscScalar    one = 1.0;
2885   Vec            tmp;
2886   PetscErrorCode ierr;
2887 
2888   PetscFunctionBegin;
2889   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2890   PetscValidType(mat,1);
2891   PetscValidHeaderSpecific(y,VEC_COOKIE,2);
2892   PetscValidHeaderSpecific(b,VEC_COOKIE,3);
2893   PetscValidHeaderSpecific(x,VEC_COOKIE,4);
2894   PetscCheckSameComm(mat,1,b,2);
2895   PetscCheckSameComm(mat,1,y,2);
2896   PetscCheckSameComm(mat,1,x,3);
2897   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2898   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2899   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);
2900   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);
2901   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);
2902   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);
2903   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);
2904   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2905 
2906   ierr = PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
2907   if (mat->ops->solveadd)  {
2908     ierr = (*mat->ops->solveadd)(mat,b,y,x);CHKERRQ(ierr);
2909   } else {
2910     /* do the solve then the add manually */
2911     if (x != y) {
2912       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
2913       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
2914     } else {
2915       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
2916       ierr = PetscLogObjectParent(mat,tmp);CHKERRQ(ierr);
2917       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
2918       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
2919       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
2920       ierr = VecDestroy(tmp);CHKERRQ(ierr);
2921     }
2922   }
2923   ierr = PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
2924   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
2925   PetscFunctionReturn(0);
2926 }
2927 
2928 #undef __FUNCT__
2929 #define __FUNCT__ "MatSolveTranspose"
2930 /*@
2931    MatSolveTranspose - Solves A' x = b, given a factored matrix.
2932 
2933    Collective on Mat and Vec
2934 
2935    Input Parameters:
2936 +  mat - the factored matrix
2937 -  b - the right-hand-side vector
2938 
2939    Output Parameter:
2940 .  x - the result vector
2941 
2942    Notes:
2943    The vectors b and x cannot be the same.  I.e., one cannot
2944    call MatSolveTranspose(A,x,x).
2945 
2946    Most users should employ the simplified KSP interface for linear solvers
2947    instead of working directly with matrix algebra routines such as this.
2948    See, e.g., KSPCreate().
2949 
2950    Level: developer
2951 
2952    Concepts: matrices^triangular solves
2953 
2954 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
2955 @*/
2956 PetscErrorCode PETSCMAT_DLLEXPORT MatSolveTranspose(Mat mat,Vec b,Vec x)
2957 {
2958   PetscErrorCode ierr;
2959 
2960   PetscFunctionBegin;
2961   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2962   PetscValidType(mat,1);
2963   PetscValidHeaderSpecific(b,VEC_COOKIE,2);
2964   PetscValidHeaderSpecific(x,VEC_COOKIE,3);
2965   PetscCheckSameComm(mat,1,b,2);
2966   PetscCheckSameComm(mat,1,x,3);
2967   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2968   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2969   if (!mat->ops->solvetranspose) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
2970   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);
2971   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);
2972   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2973   ierr = PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
2974   ierr = (*mat->ops->solvetranspose)(mat,b,x);CHKERRQ(ierr);
2975   ierr = PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
2976   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
2977   PetscFunctionReturn(0);
2978 }
2979 
2980 #undef __FUNCT__
2981 #define __FUNCT__ "MatSolveTransposeAdd"
2982 /*@
2983    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
2984                       factored matrix.
2985 
2986    Collective on Mat and Vec
2987 
2988    Input Parameters:
2989 +  mat - the factored matrix
2990 .  b - the right-hand-side vector
2991 -  y - the vector to be added to
2992 
2993    Output Parameter:
2994 .  x - the result vector
2995 
2996    Notes:
2997    The vectors b and x cannot be the same.  I.e., one cannot
2998    call MatSolveTransposeAdd(A,x,y,x).
2999 
3000    Most users should employ the simplified KSP interface for linear solvers
3001    instead of working directly with matrix algebra routines such as this.
3002    See, e.g., KSPCreate().
3003 
3004    Level: developer
3005 
3006    Concepts: matrices^triangular solves
3007 
3008 .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3009 @*/
3010 PetscErrorCode PETSCMAT_DLLEXPORT MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3011 {
3012   PetscScalar    one = 1.0;
3013   PetscErrorCode ierr;
3014   Vec            tmp;
3015 
3016   PetscFunctionBegin;
3017   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3018   PetscValidType(mat,1);
3019   PetscValidHeaderSpecific(y,VEC_COOKIE,2);
3020   PetscValidHeaderSpecific(b,VEC_COOKIE,3);
3021   PetscValidHeaderSpecific(x,VEC_COOKIE,4);
3022   PetscCheckSameComm(mat,1,b,2);
3023   PetscCheckSameComm(mat,1,y,3);
3024   PetscCheckSameComm(mat,1,x,4);
3025   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3026   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3027   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);
3028   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);
3029   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);
3030   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);
3031   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3032 
3033   ierr = PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
3034   if (mat->ops->solvetransposeadd) {
3035     ierr = (*mat->ops->solvetransposeadd)(mat,b,y,x);CHKERRQ(ierr);
3036   } else {
3037     /* do the solve then the add manually */
3038     if (x != y) {
3039       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
3040       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
3041     } else {
3042       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
3043       ierr = PetscLogObjectParent(mat,tmp);CHKERRQ(ierr);
3044       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
3045       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
3046       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
3047       ierr = VecDestroy(tmp);CHKERRQ(ierr);
3048     }
3049   }
3050   ierr = PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
3051   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3052   PetscFunctionReturn(0);
3053 }
3054 /* ----------------------------------------------------------------*/
3055 
3056 #undef __FUNCT__
3057 #define __FUNCT__ "MatRelax"
3058 /*@
3059    MatRelax - Computes relaxation (SOR, Gauss-Seidel) sweeps.
3060 
3061    Collective on Mat and Vec
3062 
3063    Input Parameters:
3064 +  mat - the matrix
3065 .  b - the right hand side
3066 .  omega - the relaxation factor
3067 .  flag - flag indicating the type of SOR (see below)
3068 .  shift -  diagonal shift
3069 .  its - the number of iterations
3070 -  lits - the number of local iterations
3071 
3072    Output Parameters:
3073 .  x - the solution (can contain an initial guess)
3074 
3075    SOR Flags:
3076 .     SOR_FORWARD_SWEEP - forward SOR
3077 .     SOR_BACKWARD_SWEEP - backward SOR
3078 .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3079 .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR
3080 .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
3081 .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3082 .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
3083          upper/lower triangular part of matrix to
3084          vector (with omega)
3085 .     SOR_ZERO_INITIAL_GUESS - zero initial guess
3086 
3087    Notes:
3088    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3089    SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3090    on each processor.
3091 
3092    Application programmers will not generally use MatRelax() directly,
3093    but instead will employ the KSP/PC interface.
3094 
3095    Notes for Advanced Users:
3096    The flags are implemented as bitwise inclusive or operations.
3097    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3098    to specify a zero initial guess for SSOR.
3099 
3100    Most users should employ the simplified KSP interface for linear solvers
3101    instead of working directly with matrix algebra routines such as this.
3102    See, e.g., KSPCreate().
3103 
3104    See also, MatPBRelax(). This routine will automatically call the point block
3105    version if the point version is not available.
3106 
3107    Level: developer
3108 
3109    Concepts: matrices^relaxation
3110    Concepts: matrices^SOR
3111    Concepts: matrices^Gauss-Seidel
3112 
3113 @*/
3114 PetscErrorCode PETSCMAT_DLLEXPORT MatRelax(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3115 {
3116   PetscErrorCode ierr;
3117 
3118   PetscFunctionBegin;
3119   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3120   PetscValidType(mat,1);
3121   PetscValidHeaderSpecific(b,VEC_COOKIE,2);
3122   PetscValidHeaderSpecific(x,VEC_COOKIE,8);
3123   PetscCheckSameComm(mat,1,b,2);
3124   PetscCheckSameComm(mat,1,x,8);
3125   if (!mat->ops->relax && !mat->ops->pbrelax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3126   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3127   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3128   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);
3129   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);
3130   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);
3131   if (its <= 0) SETERRQ1(PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
3132   if (lits <= 0) SETERRQ1(PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
3133 
3134   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3135   ierr = PetscLogEventBegin(MAT_Relax,mat,b,x,0);CHKERRQ(ierr);
3136   if (mat->ops->relax) {
3137     ierr =(*mat->ops->relax)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr);
3138   } else {
3139     ierr =(*mat->ops->pbrelax)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr);
3140   }
3141   ierr = PetscLogEventEnd(MAT_Relax,mat,b,x,0);CHKERRQ(ierr);
3142   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3143   PetscFunctionReturn(0);
3144 }
3145 
3146 #undef __FUNCT__
3147 #define __FUNCT__ "MatPBRelax"
3148 /*@
3149    MatPBRelax - Computes relaxation (SOR, Gauss-Seidel) sweeps.
3150 
3151    Collective on Mat and Vec
3152 
3153    See MatRelax() for usage
3154 
3155    For multi-component PDEs where the Jacobian is stored in a point block format
3156    (with the PETSc BAIJ matrix formats) the relaxation is done one point block at
3157    a time. That is, the small (for example, 4 by 4) blocks along the diagonal are solved
3158    simultaneously (that is a 4 by 4 linear solve is done) to update all the values at a point.
3159 
3160    Level: developer
3161 
3162 @*/
3163 PetscErrorCode PETSCMAT_DLLEXPORT MatPBRelax(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3164 {
3165   PetscErrorCode ierr;
3166 
3167   PetscFunctionBegin;
3168   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3169   PetscValidType(mat,1);
3170   PetscValidHeaderSpecific(b,VEC_COOKIE,2);
3171   PetscValidHeaderSpecific(x,VEC_COOKIE,8);
3172   PetscCheckSameComm(mat,1,b,2);
3173   PetscCheckSameComm(mat,1,x,8);
3174   if (!mat->ops->pbrelax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3175   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3176   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3177   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);
3178   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);
3179   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);
3180   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3181 
3182   ierr = PetscLogEventBegin(MAT_Relax,mat,b,x,0);CHKERRQ(ierr);
3183   ierr =(*mat->ops->pbrelax)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr);
3184   ierr = PetscLogEventEnd(MAT_Relax,mat,b,x,0);CHKERRQ(ierr);
3185   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3186   PetscFunctionReturn(0);
3187 }
3188 
3189 #undef __FUNCT__
3190 #define __FUNCT__ "MatCopy_Basic"
3191 /*
3192       Default matrix copy routine.
3193 */
3194 PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
3195 {
3196   PetscErrorCode    ierr;
3197   PetscInt          i,rstart,rend,nz;
3198   const PetscInt    *cwork;
3199   const PetscScalar *vwork;
3200 
3201   PetscFunctionBegin;
3202   if (B->assembled) {
3203     ierr = MatZeroEntries(B);CHKERRQ(ierr);
3204   }
3205   ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
3206   for (i=rstart; i<rend; i++) {
3207     ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
3208     ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);CHKERRQ(ierr);
3209     ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
3210   }
3211   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3212   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3213   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
3214   PetscFunctionReturn(0);
3215 }
3216 
3217 #undef __FUNCT__
3218 #define __FUNCT__ "MatCopy"
3219 /*@
3220    MatCopy - Copys a matrix to another matrix.
3221 
3222    Collective on Mat
3223 
3224    Input Parameters:
3225 +  A - the matrix
3226 -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
3227 
3228    Output Parameter:
3229 .  B - where the copy is put
3230 
3231    Notes:
3232    If you use SAME_NONZERO_PATTERN then the two matrices had better have the
3233    same nonzero pattern or the routine will crash.
3234 
3235    MatCopy() copies the matrix entries of a matrix to another existing
3236    matrix (after first zeroing the second matrix).  A related routine is
3237    MatConvert(), which first creates a new matrix and then copies the data.
3238 
3239    Level: intermediate
3240 
3241    Concepts: matrices^copying
3242 
3243 .seealso: MatConvert(), MatDuplicate()
3244 
3245 @*/
3246 PetscErrorCode PETSCMAT_DLLEXPORT MatCopy(Mat A,Mat B,MatStructure str)
3247 {
3248   PetscErrorCode ierr;
3249   PetscInt       i;
3250 
3251   PetscFunctionBegin;
3252   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
3253   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
3254   PetscValidType(A,1);
3255   PetscValidType(B,2);
3256   PetscCheckSameComm(A,1,B,2);
3257   ierr = MatPreallocated(B);CHKERRQ(ierr);
3258   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3259   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3260   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);
3261   ierr = MatPreallocated(A);CHKERRQ(ierr);
3262 
3263   ierr = PetscLogEventBegin(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
3264   if (A->ops->copy) {
3265     ierr = (*A->ops->copy)(A,B,str);CHKERRQ(ierr);
3266   } else { /* generic conversion */
3267     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
3268   }
3269   if (A->mapping) {
3270     if (B->mapping) {ierr = ISLocalToGlobalMappingDestroy(B->mapping);CHKERRQ(ierr);B->mapping = 0;}
3271     ierr = MatSetLocalToGlobalMapping(B,A->mapping);CHKERRQ(ierr);
3272   }
3273   if (A->bmapping) {
3274     if (B->bmapping) {ierr = ISLocalToGlobalMappingDestroy(B->bmapping);CHKERRQ(ierr);B->bmapping = 0;}
3275     ierr = MatSetLocalToGlobalMappingBlock(B,A->mapping);CHKERRQ(ierr);
3276   }
3277 
3278   B->stencil.dim = A->stencil.dim;
3279   B->stencil.noc = A->stencil.noc;
3280   for (i=0; i<=A->stencil.dim; i++) {
3281     B->stencil.dims[i]   = A->stencil.dims[i];
3282     B->stencil.starts[i] = A->stencil.starts[i];
3283   }
3284 
3285   ierr = PetscLogEventEnd(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
3286   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
3287   PetscFunctionReturn(0);
3288 }
3289 
3290 #undef __FUNCT__
3291 #define __FUNCT__ "MatConvert"
3292 /*@C
3293    MatConvert - Converts a matrix to another matrix, either of the same
3294    or different type.
3295 
3296    Collective on Mat
3297 
3298    Input Parameters:
3299 +  mat - the matrix
3300 .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
3301    same type as the original matrix.
3302 -  reuse - denotes if the destination matrix is to be created or reused.  Currently
3303    MAT_REUSE_MATRIX is only supported for inplace conversion, otherwise use
3304    MAT_INITIAL_MATRIX.
3305 
3306    Output Parameter:
3307 .  M - pointer to place new matrix
3308 
3309    Notes:
3310    MatConvert() first creates a new matrix and then copies the data from
3311    the first matrix.  A related routine is MatCopy(), which copies the matrix
3312    entries of one matrix to another already existing matrix context.
3313 
3314    Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
3315    the MPI communicator of the generated matrix is always the same as the communicator
3316    of the input matrix.
3317 
3318    Level: intermediate
3319 
3320    Concepts: matrices^converting between storage formats
3321 
3322 .seealso: MatCopy(), MatDuplicate()
3323 @*/
3324 PetscErrorCode PETSCMAT_DLLEXPORT MatConvert(Mat mat, const MatType newtype,MatReuse reuse,Mat *M)
3325 {
3326   PetscErrorCode         ierr;
3327   PetscTruth             sametype,issame,flg;
3328   char                   convname[256],mtype[256];
3329   Mat                    B;
3330 
3331   PetscFunctionBegin;
3332   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3333   PetscValidType(mat,1);
3334   PetscValidPointer(M,3);
3335   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3336   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3337   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3338 
3339   ierr = PetscOptionsGetString(((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);CHKERRQ(ierr);
3340   if (flg) {
3341     newtype = mtype;
3342   }
3343   ierr = PetscTypeCompare((PetscObject)mat,newtype,&sametype);CHKERRQ(ierr);
3344   ierr = PetscStrcmp(newtype,"same",&issame);CHKERRQ(ierr);
3345   if ((reuse == MAT_REUSE_MATRIX) && (mat != *M)) {
3346     SETERRQ(PETSC_ERR_SUP,"MAT_REUSE_MATRIX only supported for in-place conversion currently");
3347   }
3348 
3349   if ((reuse == MAT_REUSE_MATRIX) && (issame || sametype)) PetscFunctionReturn(0);
3350 
3351   if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
3352     ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
3353   } else {
3354     PetscErrorCode (*conv)(Mat, const MatType,MatReuse,Mat*)=PETSC_NULL;
3355     const char     *prefix[3] = {"seq","mpi",""};
3356     PetscInt       i;
3357     /*
3358        Order of precedence:
3359        1) See if a specialized converter is known to the current matrix.
3360        2) See if a specialized converter is known to the desired matrix class.
3361        3) See if a good general converter is registered for the desired class
3362           (as of 6/27/03 only MATMPIADJ falls into this category).
3363        4) See if a good general converter is known for the current matrix.
3364        5) Use a really basic converter.
3365     */
3366 
3367     /* 1) See if a specialized converter is known to the current matrix and the desired class */
3368     for (i=0; i<3; i++) {
3369       ierr = PetscStrcpy(convname,"MatConvert_");CHKERRQ(ierr);
3370       ierr = PetscStrcat(convname,((PetscObject)mat)->type_name);CHKERRQ(ierr);
3371       ierr = PetscStrcat(convname,"_");CHKERRQ(ierr);
3372       ierr = PetscStrcat(convname,prefix[i]);CHKERRQ(ierr);
3373       ierr = PetscStrcat(convname,newtype);CHKERRQ(ierr);
3374       ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
3375       ierr = PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);CHKERRQ(ierr);
3376       if (conv) goto foundconv;
3377     }
3378 
3379     /* 2)  See if a specialized converter is known to the desired matrix class. */
3380     ierr = MatCreate(((PetscObject)mat)->comm,&B);CHKERRQ(ierr);
3381     ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);CHKERRQ(ierr);
3382     ierr = MatSetType(B,newtype);CHKERRQ(ierr);
3383     for (i=0; i<3; i++) {
3384       ierr = PetscStrcpy(convname,"MatConvert_");CHKERRQ(ierr);
3385       ierr = PetscStrcat(convname,((PetscObject)mat)->type_name);CHKERRQ(ierr);
3386       ierr = PetscStrcat(convname,"_");CHKERRQ(ierr);
3387       ierr = PetscStrcat(convname,prefix[i]);CHKERRQ(ierr);
3388       ierr = PetscStrcat(convname,newtype);CHKERRQ(ierr);
3389       ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
3390       ierr = PetscObjectQueryFunction((PetscObject)B,convname,(void (**)(void))&conv);CHKERRQ(ierr);
3391       if (conv) {
3392         ierr = MatDestroy(B);CHKERRQ(ierr);
3393         goto foundconv;
3394       }
3395     }
3396 
3397     /* 3) See if a good general converter is registered for the desired class */
3398     conv = B->ops->convertfrom;
3399     ierr = MatDestroy(B);CHKERRQ(ierr);
3400     if (conv) goto foundconv;
3401 
3402     /* 4) See if a good general converter is known for the current matrix */
3403     if (mat->ops->convert) {
3404       conv = mat->ops->convert;
3405     }
3406     if (conv) goto foundconv;
3407 
3408     /* 5) Use a really basic converter. */
3409     conv = MatConvert_Basic;
3410 
3411     foundconv:
3412     ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
3413     ierr = (*conv)(mat,newtype,reuse,M);CHKERRQ(ierr);
3414     ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
3415   }
3416   ierr = PetscObjectStateIncrease((PetscObject)*M);CHKERRQ(ierr);
3417   PetscFunctionReturn(0);
3418 }
3419 
3420 #undef __FUNCT__
3421 #define __FUNCT__ "MatFactorGetSolverPackage"
3422 /*@C
3423    MatFactorGetSolverPackage - Returns name of the package providing the factorization routines
3424 
3425    Not Collective
3426 
3427    Input Parameter:
3428 .  mat - the matrix, must be a factored matrix
3429 
3430    Output Parameter:
3431 .   type - the string name of the package (do not free this string)
3432 
3433    Notes:
3434       In Fortran you pass in a empty string and the package name will be copied into it.
3435     (Make sure the string is long enough)
3436 
3437    Level: intermediate
3438 
3439 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
3440 @*/
3441 PetscErrorCode PETSCMAT_DLLEXPORT MatFactorGetSolverPackage(Mat mat, const MatSolverPackage *type)
3442 {
3443   PetscErrorCode         ierr;
3444   PetscErrorCode         (*conv)(Mat,const MatSolverPackage*);
3445 
3446   PetscFunctionBegin;
3447   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3448   PetscValidType(mat,1);
3449   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
3450   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverPackage_C",(void (**)(void))&conv);CHKERRQ(ierr);
3451   if (!conv) {
3452     *type = MAT_SOLVER_PETSC;
3453   } else {
3454     ierr = (*conv)(mat,type);CHKERRQ(ierr);
3455   }
3456   PetscFunctionReturn(0);
3457 }
3458 
3459 #undef __FUNCT__
3460 #define __FUNCT__ "MatGetFactor"
3461 /*@C
3462    MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic()
3463 
3464    Collective on Mat
3465 
3466    Input Parameters:
3467 +  mat - the matrix
3468 .  type - name of solver type, for example, spooles, superlu, plapack, petsc (to use PETSc's default)
3469 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
3470 
3471    Output Parameters:
3472 .  f - the factor matrix used with MatXXFactorSymbolic() calls
3473 
3474    Notes:
3475       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
3476      such as pastix, superlu, mumps, spooles etc.
3477 
3478       PETSc must have been config/configure.py to use the external solver, using the option --download-package
3479 
3480    Level: intermediate
3481 
3482 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
3483 @*/
3484 PetscErrorCode PETSCMAT_DLLEXPORT MatGetFactor(Mat mat, const MatSolverPackage type,MatFactorType ftype,Mat *f)
3485 {
3486   PetscErrorCode         ierr;
3487   char                   convname[256];
3488   PetscErrorCode         (*conv)(Mat,MatFactorType,Mat*);
3489 
3490   PetscFunctionBegin;
3491   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3492   PetscValidType(mat,1);
3493 
3494   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3495   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3496 
3497   ierr = PetscStrcpy(convname,"MatGetFactor_");CHKERRQ(ierr);
3498   ierr = PetscStrcat(convname,((PetscObject)mat)->type_name);CHKERRQ(ierr);
3499   ierr = PetscStrcat(convname,"_");CHKERRQ(ierr);
3500   ierr = PetscStrcat(convname,type);CHKERRQ(ierr);
3501   ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
3502   ierr = PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);CHKERRQ(ierr);
3503   if (!conv) {
3504     PetscTruth flag;
3505     ierr = PetscStrcasecmp(MAT_SOLVER_PETSC,type,&flag);CHKERRQ(ierr);
3506     if (flag) {
3507       SETERRQ1(PETSC_ERR_SUP,"Matrix format %s does not have a built-in PETSc direct solver",((PetscObject)mat)->type_name);
3508     } else {
3509       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);
3510     }
3511   }
3512   ierr = (*conv)(mat,ftype,f);CHKERRQ(ierr);
3513   PetscFunctionReturn(0);
3514 }
3515 
3516 #undef __FUNCT__
3517 #define __FUNCT__ "MatGetFactorAvailable"
3518 /*@C
3519    MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type
3520 
3521    Collective on Mat
3522 
3523    Input Parameters:
3524 +  mat - the matrix
3525 .  type - name of solver type, for example, spooles, superlu, plapack, petsc (to use PETSc's default)
3526 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
3527 
3528    Output Parameter:
3529 .    flg - PETSC_TRUE if the factorization is available
3530 
3531    Notes:
3532       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
3533      such as pastix, superlu, mumps, spooles etc.
3534 
3535       PETSc must have been config/configure.py to use the external solver, using the option --download-package
3536 
3537    Level: intermediate
3538 
3539 .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
3540 @*/
3541 PetscErrorCode PETSCMAT_DLLEXPORT MatGetFactorAvailable(Mat mat, const MatSolverPackage type,MatFactorType ftype,PetscTruth *flg)
3542 {
3543   PetscErrorCode         ierr;
3544   char                   convname[256];
3545   PetscErrorCode         (*conv)(Mat,MatFactorType,PetscTruth*);
3546 
3547   PetscFunctionBegin;
3548   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3549   PetscValidType(mat,1);
3550 
3551   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3552   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3553 
3554   ierr = PetscStrcpy(convname,"MatGetFactorAvailable_");CHKERRQ(ierr);
3555   ierr = PetscStrcat(convname,((PetscObject)mat)->type_name);CHKERRQ(ierr);
3556   ierr = PetscStrcat(convname,"_");CHKERRQ(ierr);
3557   ierr = PetscStrcat(convname,type);CHKERRQ(ierr);
3558   ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
3559   ierr = PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);CHKERRQ(ierr);
3560   if (!conv) {
3561     *flg = PETSC_FALSE;
3562   } else {
3563     ierr = (*conv)(mat,ftype,flg);CHKERRQ(ierr);
3564   }
3565   PetscFunctionReturn(0);
3566 }
3567 
3568 
3569 #undef __FUNCT__
3570 #define __FUNCT__ "MatDuplicate"
3571 /*@
3572    MatDuplicate - Duplicates a matrix including the non-zero structure.
3573 
3574    Collective on Mat
3575 
3576    Input Parameters:
3577 +  mat - the matrix
3578 -  op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy nonzero
3579         values as well or not
3580 
3581    Output Parameter:
3582 .  M - pointer to place new matrix
3583 
3584    Level: intermediate
3585 
3586    Concepts: matrices^duplicating
3587 
3588 .seealso: MatCopy(), MatConvert()
3589 @*/
3590 PetscErrorCode PETSCMAT_DLLEXPORT MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
3591 {
3592   PetscErrorCode ierr;
3593   Mat            B;
3594   PetscInt       i;
3595 
3596   PetscFunctionBegin;
3597   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3598   PetscValidType(mat,1);
3599   PetscValidPointer(M,3);
3600   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3601   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3602   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3603 
3604   *M  = 0;
3605   if (!mat->ops->duplicate) {
3606     SETERRQ(PETSC_ERR_SUP,"Not written for this matrix type");
3607   }
3608   ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
3609   ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr);
3610   B = *M;
3611   if (mat->mapping) {
3612     ierr = MatSetLocalToGlobalMapping(B,mat->mapping);CHKERRQ(ierr);
3613   }
3614   if (mat->bmapping) {
3615     ierr = MatSetLocalToGlobalMappingBlock(B,mat->bmapping);CHKERRQ(ierr);
3616   }
3617   ierr = PetscMapCopy(((PetscObject)mat)->comm,mat->rmap,B->rmap);CHKERRQ(ierr);
3618   ierr = PetscMapCopy(((PetscObject)mat)->comm,mat->cmap,B->cmap);CHKERRQ(ierr);
3619 
3620   B->stencil.dim = mat->stencil.dim;
3621   B->stencil.noc = mat->stencil.noc;
3622   for (i=0; i<=mat->stencil.dim; i++) {
3623     B->stencil.dims[i]   = mat->stencil.dims[i];
3624     B->stencil.starts[i] = mat->stencil.starts[i];
3625   }
3626 
3627   ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
3628   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
3629   PetscFunctionReturn(0);
3630 }
3631 
3632 #undef __FUNCT__
3633 #define __FUNCT__ "MatGetDiagonal"
3634 /*@
3635    MatGetDiagonal - Gets the diagonal of a matrix.
3636 
3637    Collective on Mat and Vec
3638 
3639    Input Parameters:
3640 +  mat - the matrix
3641 -  v - the vector for storing the diagonal
3642 
3643    Output Parameter:
3644 .  v - the diagonal of the matrix
3645 
3646    Level: intermediate
3647 
3648    Concepts: matrices^accessing diagonals
3649 
3650 .seealso: MatGetRow(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs()
3651 @*/
3652 PetscErrorCode PETSCMAT_DLLEXPORT MatGetDiagonal(Mat mat,Vec v)
3653 {
3654   PetscErrorCode ierr;
3655 
3656   PetscFunctionBegin;
3657   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3658   PetscValidType(mat,1);
3659   PetscValidHeaderSpecific(v,VEC_COOKIE,2);
3660   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3661   if (!mat->ops->getdiagonal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3662   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3663 
3664   ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr);
3665   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
3666   PetscFunctionReturn(0);
3667 }
3668 
3669 #undef __FUNCT__
3670 #define __FUNCT__ "MatGetRowMin"
3671 /*@
3672    MatGetRowMin - Gets the minimum value (of the real part) of each
3673         row of the matrix
3674 
3675    Collective on Mat and Vec
3676 
3677    Input Parameters:
3678 .  mat - the matrix
3679 
3680    Output Parameter:
3681 +  v - the vector for storing the maximums
3682 -  idx - the indices of the column found for each row (optional)
3683 
3684    Level: intermediate
3685 
3686    Notes: The result of this call are the same as if one converted the matrix to dense format
3687       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
3688 
3689     This code is only implemented for a couple of matrix formats.
3690 
3691    Concepts: matrices^getting row maximums
3692 
3693 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(),
3694           MatGetRowMax()
3695 @*/
3696 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
3697 {
3698   PetscErrorCode ierr;
3699 
3700   PetscFunctionBegin;
3701   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3702   PetscValidType(mat,1);
3703   PetscValidHeaderSpecific(v,VEC_COOKIE,2);
3704   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3705   if (!mat->ops->getrowmax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3706   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3707 
3708   ierr = (*mat->ops->getrowmin)(mat,v,idx);CHKERRQ(ierr);
3709   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
3710   PetscFunctionReturn(0);
3711 }
3712 
3713 #undef __FUNCT__
3714 #define __FUNCT__ "MatGetRowMinAbs"
3715 /*@
3716    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
3717         row of the matrix
3718 
3719    Collective on Mat and Vec
3720 
3721    Input Parameters:
3722 .  mat - the matrix
3723 
3724    Output Parameter:
3725 +  v - the vector for storing the minimums
3726 -  idx - the indices of the column found for each row (optional)
3727 
3728    Level: intermediate
3729 
3730    Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
3731     row is 0 (the first column).
3732 
3733     This code is only implemented for a couple of matrix formats.
3734 
3735    Concepts: matrices^getting row maximums
3736 
3737 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
3738 @*/
3739 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
3740 {
3741   PetscErrorCode ierr;
3742 
3743   PetscFunctionBegin;
3744   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3745   PetscValidType(mat,1);
3746   PetscValidHeaderSpecific(v,VEC_COOKIE,2);
3747   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3748   if (!mat->ops->getrowminabs) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3749   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3750   if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);}
3751 
3752   ierr = (*mat->ops->getrowminabs)(mat,v,idx);CHKERRQ(ierr);
3753   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
3754   PetscFunctionReturn(0);
3755 }
3756 
3757 #undef __FUNCT__
3758 #define __FUNCT__ "MatGetRowMax"
3759 /*@
3760    MatGetRowMax - Gets the maximum value (of the real part) of each
3761         row of the matrix
3762 
3763    Collective on Mat and Vec
3764 
3765    Input Parameters:
3766 .  mat - the matrix
3767 
3768    Output Parameter:
3769 +  v - the vector for storing the maximums
3770 -  idx - the indices of the column found for each row (optional)
3771 
3772    Level: intermediate
3773 
3774    Notes: The result of this call are the same as if one converted the matrix to dense format
3775       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
3776 
3777     This code is only implemented for a couple of matrix formats.
3778 
3779    Concepts: matrices^getting row maximums
3780 
3781 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(), MatGetRowMin()
3782 @*/
3783 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
3784 {
3785   PetscErrorCode ierr;
3786 
3787   PetscFunctionBegin;
3788   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3789   PetscValidType(mat,1);
3790   PetscValidHeaderSpecific(v,VEC_COOKIE,2);
3791   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3792   if (!mat->ops->getrowmax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3793   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3794 
3795   ierr = (*mat->ops->getrowmax)(mat,v,idx);CHKERRQ(ierr);
3796   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
3797   PetscFunctionReturn(0);
3798 }
3799 
3800 #undef __FUNCT__
3801 #define __FUNCT__ "MatGetRowMaxAbs"
3802 /*@
3803    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
3804         row of the matrix
3805 
3806    Collective on Mat and Vec
3807 
3808    Input Parameters:
3809 .  mat - the matrix
3810 
3811    Output Parameter:
3812 +  v - the vector for storing the maximums
3813 -  idx - the indices of the column found for each row (optional)
3814 
3815    Level: intermediate
3816 
3817    Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
3818     row is 0 (the first column).
3819 
3820     This code is only implemented for a couple of matrix formats.
3821 
3822    Concepts: matrices^getting row maximums
3823 
3824 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
3825 @*/
3826 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
3827 {
3828   PetscErrorCode ierr;
3829 
3830   PetscFunctionBegin;
3831   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3832   PetscValidType(mat,1);
3833   PetscValidHeaderSpecific(v,VEC_COOKIE,2);
3834   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3835   if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3836   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3837   if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);}
3838 
3839   ierr = (*mat->ops->getrowmaxabs)(mat,v,idx);CHKERRQ(ierr);
3840   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
3841   PetscFunctionReturn(0);
3842 }
3843 
3844 #undef __FUNCT__
3845 #define __FUNCT__ "MatGetRowSum"
3846 /*@
3847    MatGetRowSum - Gets the sum of each row of the matrix
3848 
3849    Collective on Mat and Vec
3850 
3851    Input Parameters:
3852 .  mat - the matrix
3853 
3854    Output Parameter:
3855 .  v - the vector for storing the maximums
3856 
3857    Level: intermediate
3858 
3859    Notes: This code is slow since it is not currently specialized for different formats
3860 
3861    Concepts: matrices^getting row sums
3862 
3863 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
3864 @*/
3865 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRowSum(Mat mat, Vec v)
3866 {
3867   PetscInt       start, end, row;
3868   PetscScalar   *array;
3869   PetscErrorCode ierr;
3870 
3871   PetscFunctionBegin;
3872   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3873   PetscValidType(mat,1);
3874   PetscValidHeaderSpecific(v,VEC_COOKIE,2);
3875   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3876   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3877   ierr = MatGetOwnershipRange(mat, &start, &end);CHKERRQ(ierr);
3878   ierr = VecGetArray(v, &array);CHKERRQ(ierr);
3879   for(row = start; row < end; ++row) {
3880     PetscInt           ncols, col;
3881     const PetscInt    *cols;
3882     const PetscScalar *vals;
3883 
3884     array[row - start] = 0.0;
3885     ierr = MatGetRow(mat, row, &ncols, &cols, &vals);CHKERRQ(ierr);
3886     for(col = 0; col < ncols; col++) {
3887       array[row - start] += vals[col];
3888     }
3889     ierr = MatRestoreRow(mat, row, &ncols, &cols, &vals);CHKERRQ(ierr);
3890   }
3891   ierr = VecRestoreArray(v, &array);CHKERRQ(ierr);
3892   ierr = PetscObjectStateIncrease((PetscObject) v);CHKERRQ(ierr);
3893   PetscFunctionReturn(0);
3894 }
3895 
3896 #undef __FUNCT__
3897 #define __FUNCT__ "MatTranspose"
3898 /*@
3899    MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
3900 
3901    Collective on Mat
3902 
3903    Input Parameter:
3904 +  mat - the matrix to transpose
3905 -  reuse - store the transpose matrix in the provided B
3906 
3907    Output Parameters:
3908 .  B - the transpose
3909 
3910    Notes:
3911      If you  pass in &mat for B the transpose will be done in place
3912 
3913    Level: intermediate
3914 
3915    Concepts: matrices^transposing
3916 
3917 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose()
3918 @*/
3919 PetscErrorCode PETSCMAT_DLLEXPORT MatTranspose(Mat mat,MatReuse reuse,Mat *B)
3920 {
3921   PetscErrorCode ierr;
3922 
3923   PetscFunctionBegin;
3924   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3925   PetscValidType(mat,1);
3926   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3927   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3928   if (!mat->ops->transpose) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3929   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3930 
3931   ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
3932   ierr = (*mat->ops->transpose)(mat,reuse,B);CHKERRQ(ierr);
3933   ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
3934   if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);}
3935   PetscFunctionReturn(0);
3936 }
3937 
3938 #undef __FUNCT__
3939 #define __FUNCT__ "MatIsTranspose"
3940 /*@
3941    MatIsTranspose - Test whether a matrix is another one's transpose,
3942         or its own, in which case it tests symmetry.
3943 
3944    Collective on Mat
3945 
3946    Input Parameter:
3947 +  A - the matrix to test
3948 -  B - the matrix to test against, this can equal the first parameter
3949 
3950    Output Parameters:
3951 .  flg - the result
3952 
3953    Notes:
3954    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
3955    has a running time of the order of the number of nonzeros; the parallel
3956    test involves parallel copies of the block-offdiagonal parts of the matrix.
3957 
3958    Level: intermediate
3959 
3960    Concepts: matrices^transposing, matrix^symmetry
3961 
3962 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
3963 @*/
3964 PetscErrorCode PETSCMAT_DLLEXPORT MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscTruth *flg)
3965 {
3966   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscTruth*),(*g)(Mat,Mat,PetscReal,PetscTruth*);
3967 
3968   PetscFunctionBegin;
3969   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
3970   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
3971   PetscValidPointer(flg,3);
3972   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",(void (**)(void))&f);CHKERRQ(ierr);
3973   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",(void (**)(void))&g);CHKERRQ(ierr);
3974   if (f && g) {
3975     if (f==g) {
3976       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
3977     } else {
3978       SETERRQ(PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
3979     }
3980   }
3981   PetscFunctionReturn(0);
3982 }
3983 
3984 #undef __FUNCT__
3985 #define __FUNCT__ "MatIsHermitianTranspose"
3986 /*@
3987    MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,
3988 
3989    Collective on Mat
3990 
3991    Input Parameter:
3992 +  A - the matrix to test
3993 -  B - the matrix to test against, this can equal the first parameter
3994 
3995    Output Parameters:
3996 .  flg - the result
3997 
3998    Notes:
3999    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4000    has a running time of the order of the number of nonzeros; the parallel
4001    test involves parallel copies of the block-offdiagonal parts of the matrix.
4002 
4003    Level: intermediate
4004 
4005    Concepts: matrices^transposing, matrix^symmetry
4006 
4007 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
4008 @*/
4009 PetscErrorCode PETSCMAT_DLLEXPORT MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscTruth *flg)
4010 {
4011   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscTruth*),(*g)(Mat,Mat,PetscReal,PetscTruth*);
4012 
4013   PetscFunctionBegin;
4014   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
4015   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
4016   PetscValidPointer(flg,3);
4017   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",(void (**)(void))&f);CHKERRQ(ierr);
4018   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",(void (**)(void))&g);CHKERRQ(ierr);
4019   if (f && g) {
4020     if (f==g) {
4021       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
4022     } else {
4023       SETERRQ(PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
4024     }
4025   }
4026   PetscFunctionReturn(0);
4027 }
4028 
4029 #undef __FUNCT__
4030 #define __FUNCT__ "MatPermute"
4031 /*@
4032    MatPermute - Creates a new matrix with rows and columns permuted from the
4033    original.
4034 
4035    Collective on Mat
4036 
4037    Input Parameters:
4038 +  mat - the matrix to permute
4039 .  row - row permutation, each processor supplies only the permutation for its rows
4040 -  col - column permutation, each processor needs the entire column permutation, that is
4041          this is the same size as the total number of columns in the matrix. It can often
4042          be obtained with ISAllGather() on the row permutation
4043 
4044    Output Parameters:
4045 .  B - the permuted matrix
4046 
4047    Level: advanced
4048 
4049    Concepts: matrices^permuting
4050 
4051 .seealso: MatGetOrdering(), ISAllGather()
4052 
4053 @*/
4054 PetscErrorCode PETSCMAT_DLLEXPORT MatPermute(Mat mat,IS row,IS col,Mat *B)
4055 {
4056   PetscErrorCode ierr;
4057 
4058   PetscFunctionBegin;
4059   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4060   PetscValidType(mat,1);
4061   PetscValidHeaderSpecific(row,IS_COOKIE,2);
4062   PetscValidHeaderSpecific(col,IS_COOKIE,3);
4063   PetscValidPointer(B,4);
4064   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4065   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4066   if (!mat->ops->permute) SETERRQ1(PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
4067   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4068 
4069   ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr);
4070   ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);
4071   PetscFunctionReturn(0);
4072 }
4073 
4074 #undef __FUNCT__
4075 #define __FUNCT__ "MatPermuteSparsify"
4076 /*@
4077   MatPermuteSparsify - Creates a new matrix with rows and columns permuted from the
4078   original and sparsified to the prescribed tolerance.
4079 
4080   Collective on Mat
4081 
4082   Input Parameters:
4083 + A    - The matrix to permute
4084 . band - The half-bandwidth of the sparsified matrix, or PETSC_DECIDE
4085 . frac - The half-bandwidth as a fraction of the total size, or 0.0
4086 . tol  - The drop tolerance
4087 . rowp - The row permutation
4088 - colp - The column permutation
4089 
4090   Output Parameter:
4091 . B    - The permuted, sparsified matrix
4092 
4093   Level: advanced
4094 
4095   Note:
4096   The default behavior (band = PETSC_DECIDE and frac = 0.0) is to
4097   restrict the half-bandwidth of the resulting matrix to 5% of the
4098   total matrix size.
4099 
4100 .keywords: matrix, permute, sparsify
4101 
4102 .seealso: MatGetOrdering(), MatPermute()
4103 @*/
4104 PetscErrorCode PETSCMAT_DLLEXPORT MatPermuteSparsify(Mat A, PetscInt band, PetscReal frac, PetscReal tol, IS rowp, IS colp, Mat *B)
4105 {
4106   IS                irowp, icolp;
4107   const PetscInt    *rows, *cols;
4108   PetscInt          M, N, locRowStart, locRowEnd;
4109   PetscInt          nz, newNz;
4110   const PetscInt    *cwork;
4111   PetscInt          *cnew;
4112   const PetscScalar *vwork;
4113   PetscScalar       *vnew;
4114   PetscInt          bw, issize;
4115   PetscInt          row, locRow, newRow, col, newCol;
4116   PetscErrorCode    ierr;
4117 
4118   PetscFunctionBegin;
4119   PetscValidHeaderSpecific(A,    MAT_COOKIE,1);
4120   PetscValidHeaderSpecific(rowp, IS_COOKIE,5);
4121   PetscValidHeaderSpecific(colp, IS_COOKIE,6);
4122   PetscValidPointer(B,7);
4123   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix");
4124   if (A->factor)     SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
4125   if (!A->ops->permutesparsify) {
4126     ierr = MatGetSize(A, &M, &N);CHKERRQ(ierr);
4127     ierr = MatGetOwnershipRange(A, &locRowStart, &locRowEnd);CHKERRQ(ierr);
4128     ierr = ISGetSize(rowp, &issize);CHKERRQ(ierr);
4129     if (issize != M) SETERRQ2(PETSC_ERR_ARG_WRONG, "Wrong size %D for row permutation, should be %D", issize, M);
4130     ierr = ISGetSize(colp, &issize);CHKERRQ(ierr);
4131     if (issize != N) SETERRQ2(PETSC_ERR_ARG_WRONG, "Wrong size %D for column permutation, should be %D", issize, N);
4132     ierr = ISInvertPermutation(rowp, 0, &irowp);CHKERRQ(ierr);
4133     ierr = ISGetIndices(irowp, &rows);CHKERRQ(ierr);
4134     ierr = ISInvertPermutation(colp, 0, &icolp);CHKERRQ(ierr);
4135     ierr = ISGetIndices(icolp, &cols);CHKERRQ(ierr);
4136     ierr = PetscMalloc(N * sizeof(PetscInt),         &cnew);CHKERRQ(ierr);
4137     ierr = PetscMalloc(N * sizeof(PetscScalar), &vnew);CHKERRQ(ierr);
4138 
4139     /* Setup bandwidth to include */
4140     if (band == PETSC_DECIDE) {
4141       if (frac <= 0.0)
4142         bw = (PetscInt) (M * 0.05);
4143       else
4144         bw = (PetscInt) (M * frac);
4145     } else {
4146       if (band <= 0) SETERRQ(PETSC_ERR_ARG_WRONG, "Bandwidth must be a positive integer");
4147       bw = band;
4148     }
4149 
4150     /* Put values into new matrix */
4151     ierr = MatDuplicate(A, MAT_DO_NOT_COPY_VALUES, B);CHKERRQ(ierr);
4152     for(row = locRowStart, locRow = 0; row < locRowEnd; row++, locRow++) {
4153       ierr = MatGetRow(A, row, &nz, &cwork, &vwork);CHKERRQ(ierr);
4154       newRow   = rows[locRow]+locRowStart;
4155       for(col = 0, newNz = 0; col < nz; col++) {
4156         newCol = cols[cwork[col]];
4157         if ((newCol >= newRow - bw) && (newCol < newRow + bw) && (PetscAbsScalar(vwork[col]) >= tol)) {
4158           cnew[newNz] = newCol;
4159           vnew[newNz] = vwork[col];
4160           newNz++;
4161         }
4162       }
4163       ierr = MatSetValues(*B, 1, &newRow, newNz, cnew, vnew, INSERT_VALUES);CHKERRQ(ierr);
4164       ierr = MatRestoreRow(A, row, &nz, &cwork, &vwork);CHKERRQ(ierr);
4165     }
4166     ierr = PetscFree(cnew);CHKERRQ(ierr);
4167     ierr = PetscFree(vnew);CHKERRQ(ierr);
4168     ierr = MatAssemblyBegin(*B, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4169     ierr = MatAssemblyEnd(*B, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4170     ierr = ISRestoreIndices(irowp, &rows);CHKERRQ(ierr);
4171     ierr = ISRestoreIndices(icolp, &cols);CHKERRQ(ierr);
4172     ierr = ISDestroy(irowp);CHKERRQ(ierr);
4173     ierr = ISDestroy(icolp);CHKERRQ(ierr);
4174   } else {
4175     ierr = (*A->ops->permutesparsify)(A, band, frac, tol, rowp, colp, B);CHKERRQ(ierr);
4176   }
4177   ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);
4178   PetscFunctionReturn(0);
4179 }
4180 
4181 #undef __FUNCT__
4182 #define __FUNCT__ "MatEqual"
4183 /*@
4184    MatEqual - Compares two matrices.
4185 
4186    Collective on Mat
4187 
4188    Input Parameters:
4189 +  A - the first matrix
4190 -  B - the second matrix
4191 
4192    Output Parameter:
4193 .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
4194 
4195    Level: intermediate
4196 
4197    Concepts: matrices^equality between
4198 @*/
4199 PetscErrorCode PETSCMAT_DLLEXPORT MatEqual(Mat A,Mat B,PetscTruth *flg)
4200 {
4201   PetscErrorCode ierr;
4202 
4203   PetscFunctionBegin;
4204   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
4205   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
4206   PetscValidType(A,1);
4207   PetscValidType(B,2);
4208   PetscValidIntPointer(flg,3);
4209   PetscCheckSameComm(A,1,B,2);
4210   ierr = MatPreallocated(B);CHKERRQ(ierr);
4211   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4212   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4213   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);
4214   if (!A->ops->equal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4215   if (!B->ops->equal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4216   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);
4217   ierr = MatPreallocated(A);CHKERRQ(ierr);
4218 
4219   ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr);
4220   PetscFunctionReturn(0);
4221 }
4222 
4223 #undef __FUNCT__
4224 #define __FUNCT__ "MatDiagonalScale"
4225 /*@
4226    MatDiagonalScale - Scales a matrix on the left and right by diagonal
4227    matrices that are stored as vectors.  Either of the two scaling
4228    matrices can be PETSC_NULL.
4229 
4230    Collective on Mat
4231 
4232    Input Parameters:
4233 +  mat - the matrix to be scaled
4234 .  l - the left scaling vector (or PETSC_NULL)
4235 -  r - the right scaling vector (or PETSC_NULL)
4236 
4237    Notes:
4238    MatDiagonalScale() computes A = LAR, where
4239    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
4240 
4241    Level: intermediate
4242 
4243    Concepts: matrices^diagonal scaling
4244    Concepts: diagonal scaling of matrices
4245 
4246 .seealso: MatScale()
4247 @*/
4248 PetscErrorCode PETSCMAT_DLLEXPORT MatDiagonalScale(Mat mat,Vec l,Vec r)
4249 {
4250   PetscErrorCode ierr;
4251 
4252   PetscFunctionBegin;
4253   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4254   PetscValidType(mat,1);
4255   if (!mat->ops->diagonalscale) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4256   if (l) {PetscValidHeaderSpecific(l,VEC_COOKIE,2);PetscCheckSameComm(mat,1,l,2);}
4257   if (r) {PetscValidHeaderSpecific(r,VEC_COOKIE,3);PetscCheckSameComm(mat,1,r,3);}
4258   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4259   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4260   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4261 
4262   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4263   ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr);
4264   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4265   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4266   PetscFunctionReturn(0);
4267 }
4268 
4269 #undef __FUNCT__
4270 #define __FUNCT__ "MatScale"
4271 /*@
4272     MatScale - Scales all elements of a matrix by a given number.
4273 
4274     Collective on Mat
4275 
4276     Input Parameters:
4277 +   mat - the matrix to be scaled
4278 -   a  - the scaling value
4279 
4280     Output Parameter:
4281 .   mat - the scaled matrix
4282 
4283     Level: intermediate
4284 
4285     Concepts: matrices^scaling all entries
4286 
4287 .seealso: MatDiagonalScale()
4288 @*/
4289 PetscErrorCode PETSCMAT_DLLEXPORT MatScale(Mat mat,PetscScalar a)
4290 {
4291   PetscErrorCode ierr;
4292 
4293   PetscFunctionBegin;
4294   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4295   PetscValidType(mat,1);
4296   if (a != 1.0 && !mat->ops->scale) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4297   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4298   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4299   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4300 
4301   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4302   if (a != 1.0) {
4303     ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr);
4304     ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4305   }
4306   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4307   PetscFunctionReturn(0);
4308 }
4309 
4310 #undef __FUNCT__
4311 #define __FUNCT__ "MatNorm"
4312 /*@
4313    MatNorm - Calculates various norms of a matrix.
4314 
4315    Collective on Mat
4316 
4317    Input Parameters:
4318 +  mat - the matrix
4319 -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
4320 
4321    Output Parameters:
4322 .  nrm - the resulting norm
4323 
4324    Level: intermediate
4325 
4326    Concepts: matrices^norm
4327    Concepts: norm^of matrix
4328 @*/
4329 PetscErrorCode PETSCMAT_DLLEXPORT MatNorm(Mat mat,NormType type,PetscReal *nrm)
4330 {
4331   PetscErrorCode ierr;
4332 
4333   PetscFunctionBegin;
4334   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4335   PetscValidType(mat,1);
4336   PetscValidScalarPointer(nrm,3);
4337 
4338   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4339   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4340   if (!mat->ops->norm) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4341   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4342 
4343   ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr);
4344   PetscFunctionReturn(0);
4345 }
4346 
4347 /*
4348      This variable is used to prevent counting of MatAssemblyBegin() that
4349    are called from within a MatAssemblyEnd().
4350 */
4351 static PetscInt MatAssemblyEnd_InUse = 0;
4352 #undef __FUNCT__
4353 #define __FUNCT__ "MatAssemblyBegin"
4354 /*@
4355    MatAssemblyBegin - Begins assembling the matrix.  This routine should
4356    be called after completing all calls to MatSetValues().
4357 
4358    Collective on Mat
4359 
4360    Input Parameters:
4361 +  mat - the matrix
4362 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
4363 
4364    Notes:
4365    MatSetValues() generally caches the values.  The matrix is ready to
4366    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4367    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4368    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4369    using the matrix.
4370 
4371    Level: beginner
4372 
4373    Concepts: matrices^assembling
4374 
4375 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
4376 @*/
4377 PetscErrorCode PETSCMAT_DLLEXPORT MatAssemblyBegin(Mat mat,MatAssemblyType type)
4378 {
4379   PetscErrorCode ierr;
4380 
4381   PetscFunctionBegin;
4382   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4383   PetscValidType(mat,1);
4384   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4385   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
4386   if (mat->assembled) {
4387     mat->was_assembled = PETSC_TRUE;
4388     mat->assembled     = PETSC_FALSE;
4389   }
4390   if (!MatAssemblyEnd_InUse) {
4391     ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
4392     if (mat->ops->assemblybegin){ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
4393     ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
4394   } else {
4395     if (mat->ops->assemblybegin){ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
4396   }
4397   PetscFunctionReturn(0);
4398 }
4399 
4400 #undef __FUNCT__
4401 #define __FUNCT__ "MatAssembed"
4402 /*@
4403    MatAssembled - Indicates if a matrix has been assembled and is ready for
4404      use; for example, in matrix-vector product.
4405 
4406    Collective on Mat
4407 
4408    Input Parameter:
4409 .  mat - the matrix
4410 
4411    Output Parameter:
4412 .  assembled - PETSC_TRUE or PETSC_FALSE
4413 
4414    Level: advanced
4415 
4416    Concepts: matrices^assembled?
4417 
4418 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
4419 @*/
4420 PetscErrorCode PETSCMAT_DLLEXPORT MatAssembled(Mat mat,PetscTruth *assembled)
4421 {
4422   PetscFunctionBegin;
4423   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4424   PetscValidType(mat,1);
4425   PetscValidPointer(assembled,2);
4426   *assembled = mat->assembled;
4427   PetscFunctionReturn(0);
4428 }
4429 
4430 #undef __FUNCT__
4431 #define __FUNCT__ "MatView_Private"
4432 /*
4433     Processes command line options to determine if/how a matrix
4434   is to be viewed. Called by MatAssemblyEnd() and MatLoad().
4435 */
4436 PetscErrorCode MatView_Private(Mat mat)
4437 {
4438   PetscErrorCode    ierr;
4439   PetscTruth        flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE,flg4 = PETSC_FALSE,flg6 = PETSC_FALSE,flg7 = PETSC_FALSE,flg8 = PETSC_FALSE;
4440   static PetscTruth incall = PETSC_FALSE;
4441 #if defined(PETSC_USE_SOCKET_VIEWER)
4442   PetscTruth        flg5 = PETSC_FALSE;
4443 #endif
4444 
4445   PetscFunctionBegin;
4446   if (incall) PetscFunctionReturn(0);
4447   incall = PETSC_TRUE;
4448   ierr = PetscOptionsBegin(((PetscObject)mat)->comm,((PetscObject)mat)->prefix,"Matrix Options","Mat");CHKERRQ(ierr);
4449     ierr = PetscOptionsTruth("-mat_view_info","Information on matrix size","MatView",flg1,&flg1,PETSC_NULL);CHKERRQ(ierr);
4450     ierr = PetscOptionsTruth("-mat_view_info_detailed","Nonzeros in the matrix","MatView",flg2,&flg2,PETSC_NULL);CHKERRQ(ierr);
4451     ierr = PetscOptionsTruth("-mat_view","Print matrix to stdout","MatView",flg3,&flg3,PETSC_NULL);CHKERRQ(ierr);
4452     ierr = PetscOptionsTruth("-mat_view_matlab","Print matrix to stdout in a format Matlab can read","MatView",flg4,&flg4,PETSC_NULL);CHKERRQ(ierr);
4453 #if defined(PETSC_USE_SOCKET_VIEWER)
4454     ierr = PetscOptionsTruth("-mat_view_socket","Send matrix to socket (can be read from matlab)","MatView",flg5,&flg5,PETSC_NULL);CHKERRQ(ierr);
4455 #endif
4456     ierr = PetscOptionsTruth("-mat_view_binary","Save matrix to file in binary format","MatView",flg6,&flg6,PETSC_NULL);CHKERRQ(ierr);
4457     ierr = PetscOptionsTruth("-mat_view_draw","Draw the matrix nonzero structure","MatView",flg7,&flg7,PETSC_NULL);CHKERRQ(ierr);
4458   ierr = PetscOptionsEnd();CHKERRQ(ierr);
4459 
4460   if (flg1) {
4461     PetscViewer viewer;
4462 
4463     ierr = PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);CHKERRQ(ierr);
4464     ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO);CHKERRQ(ierr);
4465     ierr = MatView(mat,viewer);CHKERRQ(ierr);
4466     ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
4467   }
4468   if (flg2) {
4469     PetscViewer viewer;
4470 
4471     ierr = PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);CHKERRQ(ierr);
4472     ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO_DETAIL);CHKERRQ(ierr);
4473     ierr = MatView(mat,viewer);CHKERRQ(ierr);
4474     ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
4475   }
4476   if (flg3) {
4477     PetscViewer viewer;
4478 
4479     ierr = PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);CHKERRQ(ierr);
4480     ierr = MatView(mat,viewer);CHKERRQ(ierr);
4481   }
4482   if (flg4) {
4483     PetscViewer viewer;
4484 
4485     ierr = PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);CHKERRQ(ierr);
4486     ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr);
4487     ierr = MatView(mat,viewer);CHKERRQ(ierr);
4488     ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
4489   }
4490 #if defined(PETSC_USE_SOCKET_VIEWER)
4491   if (flg5) {
4492     ierr = MatView(mat,PETSC_VIEWER_SOCKET_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4493     ierr = PetscViewerFlush(PETSC_VIEWER_SOCKET_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4494   }
4495 #endif
4496   if (flg6) {
4497     ierr = MatView(mat,PETSC_VIEWER_BINARY_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4498     ierr = PetscViewerFlush(PETSC_VIEWER_BINARY_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4499   }
4500   if (flg7) {
4501     ierr = PetscOptionsGetTruth(((PetscObject)mat)->prefix,"-mat_view_contour",&flg8,PETSC_NULL);CHKERRQ(ierr);
4502     if (flg8) {
4503       PetscViewerPushFormat(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm),PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
4504     }
4505     ierr = MatView(mat,PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4506     ierr = PetscViewerFlush(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4507     if (flg8) {
4508       PetscViewerPopFormat(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4509     }
4510   }
4511   incall = PETSC_FALSE;
4512   PetscFunctionReturn(0);
4513 }
4514 
4515 #undef __FUNCT__
4516 #define __FUNCT__ "MatAssemblyEnd"
4517 /*@
4518    MatAssemblyEnd - Completes assembling the matrix.  This routine should
4519    be called after MatAssemblyBegin().
4520 
4521    Collective on Mat
4522 
4523    Input Parameters:
4524 +  mat - the matrix
4525 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
4526 
4527    Options Database Keys:
4528 +  -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly()
4529 .  -mat_view_info_detailed - Prints more detailed info
4530 .  -mat_view - Prints matrix in ASCII format
4531 .  -mat_view_matlab - Prints matrix in Matlab format
4532 .  -mat_view_draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
4533 .  -display <name> - Sets display name (default is host)
4534 .  -draw_pause <sec> - Sets number of seconds to pause after display
4535 .  -mat_view_socket - Sends matrix to socket, can be accessed from Matlab (see users manual)
4536 .  -viewer_socket_machine <machine>
4537 .  -viewer_socket_port <port>
4538 .  -mat_view_binary - save matrix to file in binary format
4539 -  -viewer_binary_filename <name>
4540 
4541    Notes:
4542    MatSetValues() generally caches the values.  The matrix is ready to
4543    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4544    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4545    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4546    using the matrix.
4547 
4548    Level: beginner
4549 
4550 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), MatView(), MatAssembled(), PetscViewerSocketOpen()
4551 @*/
4552 PetscErrorCode PETSCMAT_DLLEXPORT MatAssemblyEnd(Mat mat,MatAssemblyType type)
4553 {
4554   PetscErrorCode  ierr;
4555   static PetscInt inassm = 0;
4556   PetscTruth      flg = PETSC_FALSE;
4557 
4558   PetscFunctionBegin;
4559   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4560   PetscValidType(mat,1);
4561 
4562   inassm++;
4563   MatAssemblyEnd_InUse++;
4564   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
4565     ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
4566     if (mat->ops->assemblyend) {
4567       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
4568     }
4569     ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
4570   } else {
4571     if (mat->ops->assemblyend) {
4572       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
4573     }
4574   }
4575 
4576   /* Flush assembly is not a true assembly */
4577   if (type != MAT_FLUSH_ASSEMBLY) {
4578     mat->assembled  = PETSC_TRUE; mat->num_ass++;
4579   }
4580   mat->insertmode = NOT_SET_VALUES;
4581   MatAssemblyEnd_InUse--;
4582   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4583   if (!mat->symmetric_eternal) {
4584     mat->symmetric_set              = PETSC_FALSE;
4585     mat->hermitian_set              = PETSC_FALSE;
4586     mat->structurally_symmetric_set = PETSC_FALSE;
4587   }
4588   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
4589     ierr = MatView_Private(mat);CHKERRQ(ierr);
4590     ierr = PetscOptionsGetTruth(((PetscObject)mat)->prefix,"-mat_is_symmetric",&flg,PETSC_NULL);CHKERRQ(ierr);
4591     if (flg) {
4592       PetscReal tol = 0.0;
4593       ierr = PetscOptionsGetReal(((PetscObject)mat)->prefix,"-mat_is_symmetric",&tol,PETSC_NULL);CHKERRQ(ierr);
4594       ierr = MatIsSymmetric(mat,tol,&flg);CHKERRQ(ierr);
4595       if (flg) {
4596         ierr = PetscPrintf(((PetscObject)mat)->comm,"Matrix is symmetric (tolerance %G)\n",tol);CHKERRQ(ierr);
4597       } else {
4598         ierr = PetscPrintf(((PetscObject)mat)->comm,"Matrix is not symmetric (tolerance %G)\n",tol);CHKERRQ(ierr);
4599       }
4600     }
4601   }
4602   inassm--;
4603   PetscFunctionReturn(0);
4604 }
4605 
4606 #undef __FUNCT__
4607 #define __FUNCT__ "MatSetOption"
4608 /*@
4609    MatSetOption - Sets a parameter option for a matrix. Some options
4610    may be specific to certain storage formats.  Some options
4611    determine how values will be inserted (or added). Sorted,
4612    row-oriented input will generally assemble the fastest. The default
4613    is row-oriented, nonsorted input.
4614 
4615    Collective on Mat
4616 
4617    Input Parameters:
4618 +  mat - the matrix
4619 .  option - the option, one of those listed below (and possibly others),
4620 -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
4621 
4622   Options Describing Matrix Structure:
4623 +    MAT_SYMMETRIC - symmetric in terms of both structure and value
4624 .    MAT_HERMITIAN - transpose is the complex conjugation
4625 .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
4626 -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
4627                             you set to be kept with all future use of the matrix
4628                             including after MatAssemblyBegin/End() which could
4629                             potentially change the symmetry structure, i.e. you
4630                             KNOW the matrix will ALWAYS have the property you set.
4631 
4632 
4633    Options For Use with MatSetValues():
4634    Insert a logically dense subblock, which can be
4635 .    MAT_ROW_ORIENTED - row-oriented (default)
4636 
4637    Note these options reflect the data you pass in with MatSetValues(); it has
4638    nothing to do with how the data is stored internally in the matrix
4639    data structure.
4640 
4641    When (re)assembling a matrix, we can restrict the input for
4642    efficiency/debugging purposes.  These options include
4643 +    MAT_NEW_NONZERO_LOCATIONS - additional insertions will be
4644         allowed if they generate a new nonzero
4645 .    MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
4646 .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
4647 .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
4648 -    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
4649 
4650    Notes:
4651    Some options are relevant only for particular matrix types and
4652    are thus ignored by others.  Other options are not supported by
4653    certain matrix types and will generate an error message if set.
4654 
4655    If using a Fortran 77 module to compute a matrix, one may need to
4656    use the column-oriented option (or convert to the row-oriented
4657    format).
4658 
4659    MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
4660    that would generate a new entry in the nonzero structure is instead
4661    ignored.  Thus, if memory has not alredy been allocated for this particular
4662    data, then the insertion is ignored. For dense matrices, in which
4663    the entire array is allocated, no entries are ever ignored.
4664    Set after the first MatAssemblyEnd()
4665 
4666    MAT_NEW_NONZERO_LOCATION_ERR indicates that any add or insertion
4667    that would generate a new entry in the nonzero structure instead produces
4668    an error. (Currently supported for AIJ and BAIJ formats only.)
4669    This is a useful flag when using SAME_NONZERO_PATTERN in calling
4670    KSPSetOperators() to ensure that the nonzero pattern truely does
4671    remain unchanged. Set after the first MatAssemblyEnd()
4672 
4673    MAT_NEW_NONZERO_ALLOCATION_ERR indicates that any add or insertion
4674    that would generate a new entry that has not been preallocated will
4675    instead produce an error. (Currently supported for AIJ and BAIJ formats
4676    only.) This is a useful flag when debugging matrix memory preallocation.
4677 
4678    MAT_IGNORE_OFF_PROC_ENTRIES indicates entries destined for
4679    other processors should be dropped, rather than stashed.
4680    This is useful if you know that the "owning" processor is also
4681    always generating the correct matrix entries, so that PETSc need
4682    not transfer duplicate entries generated on another processor.
4683 
4684    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
4685    searches during matrix assembly. When this flag is set, the hash table
4686    is created during the first Matrix Assembly. This hash table is
4687    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
4688    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
4689    should be used with MAT_USE_HASH_TABLE flag. This option is currently
4690    supported by MATMPIBAIJ format only.
4691 
4692    MAT_KEEP_ZEROED_ROWS indicates when MatZeroRows() is called the zeroed entries
4693    are kept in the nonzero structure
4694 
4695    MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
4696    a zero location in the matrix
4697 
4698    MAT_USE_INODES - indicates using inode version of the code - works with AIJ and
4699    ROWBS matrix types
4700 
4701    Level: intermediate
4702 
4703    Concepts: matrices^setting options
4704 
4705 @*/
4706 PetscErrorCode PETSCMAT_DLLEXPORT MatSetOption(Mat mat,MatOption op,PetscTruth flg)
4707 {
4708   PetscErrorCode ierr;
4709 
4710   PetscFunctionBegin;
4711   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4712   PetscValidType(mat,1);
4713   if (((int) op) < 0 || ((int) op) >= NUM_MAT_OPTIONS) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Options %d is out of range",(int)op);
4714   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4715   switch (op) {
4716   case MAT_SYMMETRIC:
4717     mat->symmetric                  = flg;
4718     if (flg) mat->structurally_symmetric     = PETSC_TRUE;
4719     mat->symmetric_set              = PETSC_TRUE;
4720     mat->structurally_symmetric_set = flg;
4721     break;
4722   case MAT_HERMITIAN:
4723     mat->hermitian                  = flg;
4724     if (flg) mat->structurally_symmetric     = PETSC_TRUE;
4725     mat->hermitian_set              = PETSC_TRUE;
4726     mat->structurally_symmetric_set = flg;
4727     break;
4728   case MAT_STRUCTURALLY_SYMMETRIC:
4729     mat->structurally_symmetric     = flg;
4730     mat->structurally_symmetric_set = PETSC_TRUE;
4731     break;
4732   case MAT_SYMMETRY_ETERNAL:
4733     mat->symmetric_eternal          = flg;
4734     break;
4735   default:
4736     break;
4737   }
4738   if (mat->ops->setoption) {
4739     ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr);
4740   }
4741   PetscFunctionReturn(0);
4742 }
4743 
4744 #undef __FUNCT__
4745 #define __FUNCT__ "MatZeroEntries"
4746 /*@
4747    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
4748    this routine retains the old nonzero structure.
4749 
4750    Collective on Mat
4751 
4752    Input Parameters:
4753 .  mat - the matrix
4754 
4755    Level: intermediate
4756 
4757    Concepts: matrices^zeroing
4758 
4759 .seealso: MatZeroRows()
4760 @*/
4761 PetscErrorCode PETSCMAT_DLLEXPORT MatZeroEntries(Mat mat)
4762 {
4763   PetscErrorCode ierr;
4764 
4765   PetscFunctionBegin;
4766   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4767   PetscValidType(mat,1);
4768   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4769   if (mat->insertmode != NOT_SET_VALUES) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for matrices where you have set values but not yet assembled");
4770   if (!mat->ops->zeroentries) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4771   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4772 
4773   ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
4774   ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
4775   ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
4776   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4777   PetscFunctionReturn(0);
4778 }
4779 
4780 #undef __FUNCT__
4781 #define __FUNCT__ "MatZeroRows"
4782 /*@C
4783    MatZeroRows - Zeros all entries (except possibly the main diagonal)
4784    of a set of rows of a matrix.
4785 
4786    Collective on Mat
4787 
4788    Input Parameters:
4789 +  mat - the matrix
4790 .  numRows - the number of rows to remove
4791 .  rows - the global row indices
4792 -  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
4793 
4794    Notes:
4795    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
4796    but does not release memory.  For the dense and block diagonal
4797    formats this does not alter the nonzero structure.
4798 
4799    If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS,PETSC_TRUE) the nonzero structure
4800    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
4801    merely zeroed.
4802 
4803    The user can set a value in the diagonal entry (or for the AIJ and
4804    row formats can optionally remove the main diagonal entry from the
4805    nonzero structure as well, by passing 0.0 as the final argument).
4806 
4807    For the parallel case, all processes that share the matrix (i.e.,
4808    those in the communicator used for matrix creation) MUST call this
4809    routine, regardless of whether any rows being zeroed are owned by
4810    them.
4811 
4812    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
4813    list only rows local to itself).
4814 
4815    Level: intermediate
4816 
4817    Concepts: matrices^zeroing rows
4818 
4819 .seealso: MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
4820 @*/
4821 PetscErrorCode PETSCMAT_DLLEXPORT MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag)
4822 {
4823   PetscErrorCode ierr;
4824 
4825   PetscFunctionBegin;
4826   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4827   PetscValidType(mat,1);
4828   if (numRows) PetscValidIntPointer(rows,3);
4829   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4830   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4831   if (!mat->ops->zerorows) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4832   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4833 
4834   ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag);CHKERRQ(ierr);
4835   ierr = MatView_Private(mat);CHKERRQ(ierr);
4836   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4837   PetscFunctionReturn(0);
4838 }
4839 
4840 #undef __FUNCT__
4841 #define __FUNCT__ "MatZeroRowsIS"
4842 /*@C
4843    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
4844    of a set of rows of a matrix.
4845 
4846    Collective on Mat
4847 
4848    Input Parameters:
4849 +  mat - the matrix
4850 .  is - index set of rows to remove
4851 -  diag - value put in all diagonals of eliminated rows
4852 
4853    Notes:
4854    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
4855    but does not release memory.  For the dense and block diagonal
4856    formats this does not alter the nonzero structure.
4857 
4858    If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS,PETSC_TRUE) the nonzero structure
4859    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
4860    merely zeroed.
4861 
4862    The user can set a value in the diagonal entry (or for the AIJ and
4863    row formats can optionally remove the main diagonal entry from the
4864    nonzero structure as well, by passing 0.0 as the final argument).
4865 
4866    For the parallel case, all processes that share the matrix (i.e.,
4867    those in the communicator used for matrix creation) MUST call this
4868    routine, regardless of whether any rows being zeroed are owned by
4869    them.
4870 
4871    Each processor should list the rows that IT wants zeroed
4872 
4873    Level: intermediate
4874 
4875    Concepts: matrices^zeroing rows
4876 
4877 .seealso: MatZeroRows(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
4878 @*/
4879 PetscErrorCode PETSCMAT_DLLEXPORT MatZeroRowsIS(Mat mat,IS is,PetscScalar diag)
4880 {
4881   PetscInt       numRows;
4882   const PetscInt *rows;
4883   PetscErrorCode ierr;
4884 
4885   PetscFunctionBegin;
4886   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4887   PetscValidType(mat,1);
4888   PetscValidHeaderSpecific(is,IS_COOKIE,2);
4889   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
4890   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
4891   ierr = MatZeroRows(mat,numRows,rows,diag);CHKERRQ(ierr);
4892   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
4893   PetscFunctionReturn(0);
4894 }
4895 
4896 #undef __FUNCT__
4897 #define __FUNCT__ "MatZeroRowsLocal"
4898 /*@C
4899    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
4900    of a set of rows of a matrix; using local numbering of rows.
4901 
4902    Collective on Mat
4903 
4904    Input Parameters:
4905 +  mat - the matrix
4906 .  numRows - the number of rows to remove
4907 .  rows - the global row indices
4908 -  diag - value put in all diagonals of eliminated rows
4909 
4910    Notes:
4911    Before calling MatZeroRowsLocal(), the user must first set the
4912    local-to-global mapping by calling MatSetLocalToGlobalMapping().
4913 
4914    For the AIJ matrix formats this removes the old nonzero structure,
4915    but does not release memory.  For the dense and block diagonal
4916    formats this does not alter the nonzero structure.
4917 
4918    If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS,PETSC_TRUE) the nonzero structure
4919    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
4920    merely zeroed.
4921 
4922    The user can set a value in the diagonal entry (or for the AIJ and
4923    row formats can optionally remove the main diagonal entry from the
4924    nonzero structure as well, by passing 0.0 as the final argument).
4925 
4926    Level: intermediate
4927 
4928    Concepts: matrices^zeroing
4929 
4930 .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
4931 @*/
4932 PetscErrorCode PETSCMAT_DLLEXPORT MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag)
4933 {
4934   PetscErrorCode ierr;
4935 
4936   PetscFunctionBegin;
4937   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4938   PetscValidType(mat,1);
4939   if (numRows) PetscValidIntPointer(rows,3);
4940   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4941   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4942   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4943 
4944   if (mat->ops->zerorowslocal) {
4945     ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag);CHKERRQ(ierr);
4946   } else {
4947     IS             is, newis;
4948     const PetscInt *newRows;
4949 
4950     if (!mat->mapping) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
4951     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,&is);CHKERRQ(ierr);
4952     ierr = ISLocalToGlobalMappingApplyIS(mat->mapping,is,&newis);CHKERRQ(ierr);
4953     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
4954     ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag);CHKERRQ(ierr);
4955     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
4956     ierr = ISDestroy(newis);CHKERRQ(ierr);
4957     ierr = ISDestroy(is);CHKERRQ(ierr);
4958   }
4959   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4960   PetscFunctionReturn(0);
4961 }
4962 
4963 #undef __FUNCT__
4964 #define __FUNCT__ "MatZeroRowsLocalIS"
4965 /*@C
4966    MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
4967    of a set of rows of a matrix; using local numbering of rows.
4968 
4969    Collective on Mat
4970 
4971    Input Parameters:
4972 +  mat - the matrix
4973 .  is - index set of rows to remove
4974 -  diag - value put in all diagonals of eliminated rows
4975 
4976    Notes:
4977    Before calling MatZeroRowsLocalIS(), the user must first set the
4978    local-to-global mapping by calling MatSetLocalToGlobalMapping().
4979 
4980    For the AIJ matrix formats this removes the old nonzero structure,
4981    but does not release memory.  For the dense and block diagonal
4982    formats this does not alter the nonzero structure.
4983 
4984    If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS,PETSC_TRUE) the nonzero structure
4985    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
4986    merely zeroed.
4987 
4988    The user can set a value in the diagonal entry (or for the AIJ and
4989    row formats can optionally remove the main diagonal entry from the
4990    nonzero structure as well, by passing 0.0 as the final argument).
4991 
4992    Level: intermediate
4993 
4994    Concepts: matrices^zeroing
4995 
4996 .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
4997 @*/
4998 PetscErrorCode PETSCMAT_DLLEXPORT MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag)
4999 {
5000   PetscErrorCode ierr;
5001   PetscInt       numRows;
5002   const PetscInt *rows;
5003 
5004   PetscFunctionBegin;
5005   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5006   PetscValidType(mat,1);
5007   PetscValidHeaderSpecific(is,IS_COOKIE,2);
5008   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5009   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5010   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5011 
5012   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5013   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5014   ierr = MatZeroRowsLocal(mat,numRows,rows,diag);CHKERRQ(ierr);
5015   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5016   PetscFunctionReturn(0);
5017 }
5018 
5019 #undef __FUNCT__
5020 #define __FUNCT__ "MatGetSize"
5021 /*@
5022    MatGetSize - Returns the numbers of rows and columns in a matrix.
5023 
5024    Not Collective
5025 
5026    Input Parameter:
5027 .  mat - the matrix
5028 
5029    Output Parameters:
5030 +  m - the number of global rows
5031 -  n - the number of global columns
5032 
5033    Note: both output parameters can be PETSC_NULL on input.
5034 
5035    Level: beginner
5036 
5037    Concepts: matrices^size
5038 
5039 .seealso: MatGetLocalSize()
5040 @*/
5041 PetscErrorCode PETSCMAT_DLLEXPORT MatGetSize(Mat mat,PetscInt *m,PetscInt* n)
5042 {
5043   PetscFunctionBegin;
5044   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5045   if (m) *m = mat->rmap->N;
5046   if (n) *n = mat->cmap->N;
5047   PetscFunctionReturn(0);
5048 }
5049 
5050 #undef __FUNCT__
5051 #define __FUNCT__ "MatGetLocalSize"
5052 /*@
5053    MatGetLocalSize - Returns the number of rows and columns in a matrix
5054    stored locally.  This information may be implementation dependent, so
5055    use with care.
5056 
5057    Not Collective
5058 
5059    Input Parameters:
5060 .  mat - the matrix
5061 
5062    Output Parameters:
5063 +  m - the number of local rows
5064 -  n - the number of local columns
5065 
5066    Note: both output parameters can be PETSC_NULL on input.
5067 
5068    Level: beginner
5069 
5070    Concepts: matrices^local size
5071 
5072 .seealso: MatGetSize()
5073 @*/
5074 PetscErrorCode PETSCMAT_DLLEXPORT MatGetLocalSize(Mat mat,PetscInt *m,PetscInt* n)
5075 {
5076   PetscFunctionBegin;
5077   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5078   if (m) PetscValidIntPointer(m,2);
5079   if (n) PetscValidIntPointer(n,3);
5080   if (m) *m = mat->rmap->n;
5081   if (n) *n = mat->cmap->n;
5082   PetscFunctionReturn(0);
5083 }
5084 
5085 #undef __FUNCT__
5086 #define __FUNCT__ "MatGetOwnershipRangeColumn"
5087 /*@
5088    MatGetOwnershipRangeColumn - Returns the range of matrix columns owned by
5089    this processor.
5090 
5091    Not Collective, unless matrix has not been allocated, then collective on Mat
5092 
5093    Input Parameters:
5094 .  mat - the matrix
5095 
5096    Output Parameters:
5097 +  m - the global index of the first local column
5098 -  n - one more than the global index of the last local column
5099 
5100    Notes: both output parameters can be PETSC_NULL on input.
5101 
5102    Level: developer
5103 
5104    Concepts: matrices^column ownership
5105 
5106 .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
5107 
5108 @*/
5109 PetscErrorCode PETSCMAT_DLLEXPORT MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt* n)
5110 {
5111   PetscErrorCode ierr;
5112 
5113   PetscFunctionBegin;
5114   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5115   PetscValidType(mat,1);
5116   if (m) PetscValidIntPointer(m,2);
5117   if (n) PetscValidIntPointer(n,3);
5118   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5119   if (m) *m = mat->cmap->rstart;
5120   if (n) *n = mat->cmap->rend;
5121   PetscFunctionReturn(0);
5122 }
5123 
5124 #undef __FUNCT__
5125 #define __FUNCT__ "MatGetOwnershipRange"
5126 /*@
5127    MatGetOwnershipRange - Returns the range of matrix rows owned by
5128    this processor, assuming that the matrix is laid out with the first
5129    n1 rows on the first processor, the next n2 rows on the second, etc.
5130    For certain parallel layouts this range may not be well defined.
5131 
5132    Not Collective, unless matrix has not been allocated, then collective on Mat
5133 
5134    Input Parameters:
5135 .  mat - the matrix
5136 
5137    Output Parameters:
5138 +  m - the global index of the first local row
5139 -  n - one more than the global index of the last local row
5140 
5141    Note: both output parameters can be PETSC_NULL on input.
5142 
5143    Level: beginner
5144 
5145    Concepts: matrices^row ownership
5146 
5147 .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
5148 
5149 @*/
5150 PetscErrorCode PETSCMAT_DLLEXPORT MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt* n)
5151 {
5152   PetscErrorCode ierr;
5153 
5154   PetscFunctionBegin;
5155   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5156   PetscValidType(mat,1);
5157   if (m) PetscValidIntPointer(m,2);
5158   if (n) PetscValidIntPointer(n,3);
5159   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5160   if (m) *m = mat->rmap->rstart;
5161   if (n) *n = mat->rmap->rend;
5162   PetscFunctionReturn(0);
5163 }
5164 
5165 #undef __FUNCT__
5166 #define __FUNCT__ "MatGetOwnershipRanges"
5167 /*@C
5168    MatGetOwnershipRanges - Returns the range of matrix rows owned by
5169    each process
5170 
5171    Not Collective, unless matrix has not been allocated, then collective on Mat
5172 
5173    Input Parameters:
5174 .  mat - the matrix
5175 
5176    Output Parameters:
5177 .  ranges - start of each processors portion plus one more then the total length at the end
5178 
5179    Level: beginner
5180 
5181    Concepts: matrices^row ownership
5182 
5183 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
5184 
5185 @*/
5186 PetscErrorCode PETSCMAT_DLLEXPORT MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
5187 {
5188   PetscErrorCode ierr;
5189 
5190   PetscFunctionBegin;
5191   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5192   PetscValidType(mat,1);
5193   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5194   ierr = PetscMapGetRanges(mat->rmap,ranges);CHKERRQ(ierr);
5195   PetscFunctionReturn(0);
5196 }
5197 
5198 #undef __FUNCT__
5199 #define __FUNCT__ "MatGetOwnershipRangesColumn"
5200 /*@C
5201    MatGetOwnershipRangesColumn - Returns the range of local columns for each process
5202 
5203    Not Collective, unless matrix has not been allocated, then collective on Mat
5204 
5205    Input Parameters:
5206 .  mat - the matrix
5207 
5208    Output Parameters:
5209 .  ranges - start of each processors portion plus one more then the total length at the end
5210 
5211    Level: beginner
5212 
5213    Concepts: matrices^column ownership
5214 
5215 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
5216 
5217 @*/
5218 PetscErrorCode PETSCMAT_DLLEXPORT MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
5219 {
5220   PetscErrorCode ierr;
5221 
5222   PetscFunctionBegin;
5223   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5224   PetscValidType(mat,1);
5225   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5226   ierr = PetscMapGetRanges(mat->cmap,ranges);CHKERRQ(ierr);
5227   PetscFunctionReturn(0);
5228 }
5229 
5230 #undef __FUNCT__
5231 #define __FUNCT__ "MatILUFactorSymbolic"
5232 /*@
5233    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
5234    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
5235    to complete the factorization.
5236 
5237    Collective on Mat
5238 
5239    Input Parameters:
5240 +  mat - the matrix
5241 .  row - row permutation
5242 .  column - column permutation
5243 -  info - structure containing
5244 $      levels - number of levels of fill.
5245 $      expected fill - as ratio of original fill.
5246 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
5247                 missing diagonal entries)
5248 
5249    Output Parameters:
5250 .  fact - new matrix that has been symbolically factored
5251 
5252    Notes:
5253    See the users manual for additional information about
5254    choosing the fill factor for better efficiency.
5255 
5256    Most users should employ the simplified KSP interface for linear solvers
5257    instead of working directly with matrix algebra routines such as this.
5258    See, e.g., KSPCreate().
5259 
5260    Level: developer
5261 
5262   Concepts: matrices^symbolic LU factorization
5263   Concepts: matrices^factorization
5264   Concepts: LU^symbolic factorization
5265 
5266 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
5267           MatGetOrdering(), MatFactorInfo
5268 
5269 @*/
5270 PetscErrorCode PETSCMAT_DLLEXPORT MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
5271 {
5272   PetscErrorCode ierr;
5273 
5274   PetscFunctionBegin;
5275   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5276   PetscValidType(mat,1);
5277   PetscValidHeaderSpecific(row,IS_COOKIE,2);
5278   PetscValidHeaderSpecific(col,IS_COOKIE,3);
5279   PetscValidPointer(info,4);
5280   PetscValidPointer(fact,5);
5281   if (info->levels < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
5282   if (info->fill < 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
5283   if (!(fact)->ops->ilufactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s  symbolic ILU",((PetscObject)mat)->type_name);
5284   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5285   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5286   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5287 
5288   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
5289   ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
5290   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
5291   PetscFunctionReturn(0);
5292 }
5293 
5294 #undef __FUNCT__
5295 #define __FUNCT__ "MatICCFactorSymbolic"
5296 /*@
5297    MatICCFactorSymbolic - Performs symbolic incomplete
5298    Cholesky factorization for a symmetric matrix.  Use
5299    MatCholeskyFactorNumeric() to complete the factorization.
5300 
5301    Collective on Mat
5302 
5303    Input Parameters:
5304 +  mat - the matrix
5305 .  perm - row and column permutation
5306 -  info - structure containing
5307 $      levels - number of levels of fill.
5308 $      expected fill - as ratio of original fill.
5309 
5310    Output Parameter:
5311 .  fact - the factored matrix
5312 
5313    Notes:
5314    Most users should employ the KSP interface for linear solvers
5315    instead of working directly with matrix algebra routines such as this.
5316    See, e.g., KSPCreate().
5317 
5318    Level: developer
5319 
5320   Concepts: matrices^symbolic incomplete Cholesky factorization
5321   Concepts: matrices^factorization
5322   Concepts: Cholsky^symbolic factorization
5323 
5324 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
5325 @*/
5326 PetscErrorCode PETSCMAT_DLLEXPORT MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
5327 {
5328   PetscErrorCode ierr;
5329 
5330   PetscFunctionBegin;
5331   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5332   PetscValidType(mat,1);
5333   PetscValidHeaderSpecific(perm,IS_COOKIE,2);
5334   PetscValidPointer(info,3);
5335   PetscValidPointer(fact,4);
5336   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5337   if (info->levels < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
5338   if (info->fill < 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
5339   if (!(fact)->ops->iccfactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s  symbolic ICC",((PetscObject)mat)->type_name);
5340   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5341   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5342 
5343   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
5344   ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
5345   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
5346   PetscFunctionReturn(0);
5347 }
5348 
5349 #undef __FUNCT__
5350 #define __FUNCT__ "MatGetArray"
5351 /*@C
5352    MatGetArray - Returns a pointer to the element values in the matrix.
5353    The result of this routine is dependent on the underlying matrix data
5354    structure, and may not even work for certain matrix types.  You MUST
5355    call MatRestoreArray() when you no longer need to access the array.
5356 
5357    Not Collective
5358 
5359    Input Parameter:
5360 .  mat - the matrix
5361 
5362    Output Parameter:
5363 .  v - the location of the values
5364 
5365 
5366    Fortran Note:
5367    This routine is used differently from Fortran, e.g.,
5368 .vb
5369         Mat         mat
5370         PetscScalar mat_array(1)
5371         PetscOffset i_mat
5372         PetscErrorCode ierr
5373         call MatGetArray(mat,mat_array,i_mat,ierr)
5374 
5375   C  Access first local entry in matrix; note that array is
5376   C  treated as one dimensional
5377         value = mat_array(i_mat + 1)
5378 
5379         [... other code ...]
5380         call MatRestoreArray(mat,mat_array,i_mat,ierr)
5381 .ve
5382 
5383    See the Fortran chapter of the users manual and
5384    petsc/src/mat/examples/tests for details.
5385 
5386    Level: advanced
5387 
5388    Concepts: matrices^access array
5389 
5390 .seealso: MatRestoreArray(), MatGetArrayF90(), MatGetRowIJ()
5391 @*/
5392 PetscErrorCode PETSCMAT_DLLEXPORT MatGetArray(Mat mat,PetscScalar *v[])
5393 {
5394   PetscErrorCode ierr;
5395 
5396   PetscFunctionBegin;
5397   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5398   PetscValidType(mat,1);
5399   PetscValidPointer(v,2);
5400   if (!mat->ops->getarray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5401   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5402   ierr = (*mat->ops->getarray)(mat,v);CHKERRQ(ierr);
5403   CHKMEMQ;
5404   PetscFunctionReturn(0);
5405 }
5406 
5407 #undef __FUNCT__
5408 #define __FUNCT__ "MatRestoreArray"
5409 /*@C
5410    MatRestoreArray - Restores the matrix after MatGetArray() has been called.
5411 
5412    Not Collective
5413 
5414    Input Parameter:
5415 +  mat - the matrix
5416 -  v - the location of the values
5417 
5418    Fortran Note:
5419    This routine is used differently from Fortran, e.g.,
5420 .vb
5421         Mat         mat
5422         PetscScalar mat_array(1)
5423         PetscOffset i_mat
5424         PetscErrorCode ierr
5425         call MatGetArray(mat,mat_array,i_mat,ierr)
5426 
5427   C  Access first local entry in matrix; note that array is
5428   C  treated as one dimensional
5429         value = mat_array(i_mat + 1)
5430 
5431         [... other code ...]
5432         call MatRestoreArray(mat,mat_array,i_mat,ierr)
5433 .ve
5434 
5435    See the Fortran chapter of the users manual and
5436    petsc/src/mat/examples/tests for details
5437 
5438    Level: advanced
5439 
5440 .seealso: MatGetArray(), MatRestoreArrayF90()
5441 @*/
5442 PetscErrorCode PETSCMAT_DLLEXPORT MatRestoreArray(Mat mat,PetscScalar *v[])
5443 {
5444   PetscErrorCode ierr;
5445 
5446   PetscFunctionBegin;
5447   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5448   PetscValidType(mat,1);
5449   PetscValidPointer(v,2);
5450 #if defined(PETSC_USE_DEBUG)
5451   CHKMEMQ;
5452 #endif
5453   if (!mat->ops->restorearray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5454   ierr = (*mat->ops->restorearray)(mat,v);CHKERRQ(ierr);
5455   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5456   PetscFunctionReturn(0);
5457 }
5458 
5459 #undef __FUNCT__
5460 #define __FUNCT__ "MatGetSubMatrices"
5461 /*@C
5462    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
5463    points to an array of valid matrices, they may be reused to store the new
5464    submatrices.
5465 
5466    Collective on Mat
5467 
5468    Input Parameters:
5469 +  mat - the matrix
5470 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
5471 .  irow, icol - index sets of rows and columns to extract
5472 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
5473 
5474    Output Parameter:
5475 .  submat - the array of submatrices
5476 
5477    Notes:
5478    MatGetSubMatrices() can extract ONLY sequential submatrices
5479    (from both sequential and parallel matrices). Use MatGetSubMatrix()
5480    to extract a parallel submatrix.
5481 
5482    When extracting submatrices from a parallel matrix, each processor can
5483    form a different submatrix by setting the rows and columns of its
5484    individual index sets according to the local submatrix desired.
5485 
5486    When finished using the submatrices, the user should destroy
5487    them with MatDestroyMatrices().
5488 
5489    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
5490    original matrix has not changed from that last call to MatGetSubMatrices().
5491 
5492    This routine creates the matrices in submat; you should NOT create them before
5493    calling it. It also allocates the array of matrix pointers submat.
5494 
5495    For BAIJ matrices the index sets must respect the block structure, that is if they
5496    request one row/column in a block, they must request all rows/columns that are in
5497    that block. For example, if the block size is 2 you cannot request just row 0 and
5498    column 0.
5499 
5500    Fortran Note:
5501    The Fortran interface is slightly different from that given below; it
5502    requires one to pass in  as submat a Mat (integer) array of size at least m.
5503 
5504    Level: advanced
5505 
5506    Concepts: matrices^accessing submatrices
5507    Concepts: submatrices
5508 
5509 .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
5510 @*/
5511 PetscErrorCode PETSCMAT_DLLEXPORT MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
5512 {
5513   PetscErrorCode ierr;
5514   PetscInt        i;
5515   PetscTruth      eq;
5516 
5517   PetscFunctionBegin;
5518   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5519   PetscValidType(mat,1);
5520   if (n) {
5521     PetscValidPointer(irow,3);
5522     PetscValidHeaderSpecific(*irow,IS_COOKIE,3);
5523     PetscValidPointer(icol,4);
5524     PetscValidHeaderSpecific(*icol,IS_COOKIE,4);
5525   }
5526   PetscValidPointer(submat,6);
5527   if (n && scall == MAT_REUSE_MATRIX) {
5528     PetscValidPointer(*submat,6);
5529     PetscValidHeaderSpecific(**submat,MAT_COOKIE,6);
5530   }
5531   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5532   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5533   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5534   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5535 
5536   ierr = PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
5537   ierr = (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
5538   ierr = PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
5539   for (i=0; i<n; i++) {
5540     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
5541       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
5542       if (eq) {
5543 	if (mat->symmetric){
5544 	  ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
5545 	} else if (mat->hermitian) {
5546 	  ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
5547 	} else if (mat->structurally_symmetric) {
5548 	  ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
5549 	}
5550       }
5551     }
5552   }
5553   PetscFunctionReturn(0);
5554 }
5555 
5556 #undef __FUNCT__
5557 #define __FUNCT__ "MatDestroyMatrices"
5558 /*@C
5559    MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().
5560 
5561    Collective on Mat
5562 
5563    Input Parameters:
5564 +  n - the number of local matrices
5565 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
5566                        sequence of MatGetSubMatrices())
5567 
5568    Level: advanced
5569 
5570     Notes: Frees not only the matrices, but also the array that contains the matrices
5571            In Fortran will not free the array.
5572 
5573 .seealso: MatGetSubMatrices()
5574 @*/
5575 PetscErrorCode PETSCMAT_DLLEXPORT MatDestroyMatrices(PetscInt n,Mat *mat[])
5576 {
5577   PetscErrorCode ierr;
5578   PetscInt       i;
5579 
5580   PetscFunctionBegin;
5581   if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
5582   PetscValidPointer(mat,2);
5583   for (i=0; i<n; i++) {
5584     ierr = MatDestroy((*mat)[i]);CHKERRQ(ierr);
5585   }
5586   /* memory is allocated even if n = 0 */
5587   ierr = PetscFree(*mat);CHKERRQ(ierr);
5588   PetscFunctionReturn(0);
5589 }
5590 
5591 #undef __FUNCT__
5592 #define __FUNCT__ "MatGetSeqNonzeroStructure"
5593 /*@C
5594    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
5595 
5596    Collective on Mat
5597 
5598    Input Parameters:
5599 .  mat - the matrix
5600 
5601    Output Parameter:
5602 .  matstruct - the sequential matrix with the nonzero structure of mat
5603 
5604   Level: intermediate
5605 
5606 .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
5607 @*/
5608 PetscErrorCode PETSCMAT_DLLEXPORT MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct[])
5609 {
5610   PetscErrorCode ierr;
5611 
5612   PetscFunctionBegin;
5613   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5614   PetscValidPointer(matstruct,2);
5615 
5616   PetscValidType(mat,1);
5617   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5618   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5619 
5620   ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
5621   ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr);
5622   ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
5623   PetscFunctionReturn(0);
5624 }
5625 
5626 #undef __FUNCT__
5627 #define __FUNCT__ "MatDestroySeqNonzeroStructure"
5628 /*@C
5629    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
5630 
5631    Collective on Mat
5632 
5633    Input Parameters:
5634 .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
5635                        sequence of MatGetSequentialNonzeroStructure())
5636 
5637    Level: advanced
5638 
5639     Notes: Frees not only the matrices, but also the array that contains the matrices
5640 
5641 .seealso: MatGetSeqNonzeroStructure()
5642 @*/
5643 PetscErrorCode PETSCMAT_DLLEXPORT MatDestroySeqNonzeroStructure(Mat *mat[])
5644 {
5645   PetscErrorCode ierr;
5646 
5647   PetscFunctionBegin;
5648   PetscValidPointer(mat,1);
5649   ierr = MatDestroyMatrices(1,mat);CHKERRQ(ierr);
5650   PetscFunctionReturn(0);
5651 }
5652 
5653 #undef __FUNCT__
5654 #define __FUNCT__ "MatIncreaseOverlap"
5655 /*@
5656    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
5657    replaces the index sets by larger ones that represent submatrices with
5658    additional overlap.
5659 
5660    Collective on Mat
5661 
5662    Input Parameters:
5663 +  mat - the matrix
5664 .  n   - the number of index sets
5665 .  is  - the array of index sets (these index sets will changed during the call)
5666 -  ov  - the additional overlap requested
5667 
5668    Level: developer
5669 
5670    Concepts: overlap
5671    Concepts: ASM^computing overlap
5672 
5673 .seealso: MatGetSubMatrices()
5674 @*/
5675 PetscErrorCode PETSCMAT_DLLEXPORT MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
5676 {
5677   PetscErrorCode ierr;
5678 
5679   PetscFunctionBegin;
5680   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5681   PetscValidType(mat,1);
5682   if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
5683   if (n) {
5684     PetscValidPointer(is,3);
5685     PetscValidHeaderSpecific(*is,IS_COOKIE,3);
5686   }
5687   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5688   if (mat->factor)     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5689   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5690 
5691   if (!ov) PetscFunctionReturn(0);
5692   if (!mat->ops->increaseoverlap) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5693   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
5694   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
5695   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
5696   PetscFunctionReturn(0);
5697 }
5698 
5699 #undef __FUNCT__
5700 #define __FUNCT__ "MatGetBlockSize"
5701 /*@
5702    MatGetBlockSize - Returns the matrix block size; useful especially for the
5703    block row and block diagonal formats.
5704 
5705    Not Collective
5706 
5707    Input Parameter:
5708 .  mat - the matrix
5709 
5710    Output Parameter:
5711 .  bs - block size
5712 
5713    Notes:
5714    Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ
5715 
5716    Level: intermediate
5717 
5718    Concepts: matrices^block size
5719 
5720 .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ()
5721 @*/
5722 PetscErrorCode PETSCMAT_DLLEXPORT MatGetBlockSize(Mat mat,PetscInt *bs)
5723 {
5724   PetscErrorCode ierr;
5725 
5726   PetscFunctionBegin;
5727   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5728   PetscValidType(mat,1);
5729   PetscValidIntPointer(bs,2);
5730   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5731   *bs = mat->rmap->bs;
5732   PetscFunctionReturn(0);
5733 }
5734 
5735 #undef __FUNCT__
5736 #define __FUNCT__ "MatSetBlockSize"
5737 /*@
5738    MatSetBlockSize - Sets the matrix block size; for many matrix types you
5739      cannot use this and MUST set the blocksize when you preallocate the matrix
5740 
5741    Collective on Mat
5742 
5743    Input Parameters:
5744 +  mat - the matrix
5745 -  bs - block size
5746 
5747    Notes:
5748      Only works for shell and AIJ matrices
5749 
5750    Level: intermediate
5751 
5752    Concepts: matrices^block size
5753 
5754 .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ(), MatGetBlockSize()
5755 @*/
5756 PetscErrorCode PETSCMAT_DLLEXPORT MatSetBlockSize(Mat mat,PetscInt bs)
5757 {
5758   PetscErrorCode ierr;
5759 
5760   PetscFunctionBegin;
5761   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5762   PetscValidType(mat,1);
5763   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5764   if (mat->ops->setblocksize) {
5765     /* XXX should check if (bs < 1) ??? */
5766     ierr = PetscMapSetBlockSize(mat->rmap,bs);CHKERRQ(ierr);
5767     ierr = PetscMapSetBlockSize(mat->cmap,bs);CHKERRQ(ierr);
5768     ierr = (*mat->ops->setblocksize)(mat,bs);CHKERRQ(ierr);
5769   } else {
5770     SETERRQ1(PETSC_ERR_ARG_INCOMP,"Cannot set the blocksize for matrix type %s",((PetscObject)mat)->type_name);
5771   }
5772   PetscFunctionReturn(0);
5773 }
5774 
5775 #undef __FUNCT__
5776 #define __FUNCT__ "MatGetRowIJ"
5777 /*@C
5778     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
5779 
5780    Collective on Mat
5781 
5782     Input Parameters:
5783 +   mat - the matrix
5784 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
5785 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5786                 symmetrized
5787 -   blockcompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
5788                  blockcompressed matrix is desired or not [inode, baij have blockcompressed
5789                  nonzero structure which is different than the full nonzero structure]
5790 
5791     Output Parameters:
5792 +   n - number of rows in the (possibly compressed) matrix
5793 .   ia - the row pointers [of length n+1]
5794 .   ja - the column indices
5795 -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
5796            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
5797 
5798     Level: developer
5799 
5800     Notes: You CANNOT change any of the ia[] or ja[] values.
5801 
5802            Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values
5803 
5804     Fortran Node
5805 
5806            In Fortran use
5807 $           PetscInt ia(1), ja(1)
5808 $           PetscOffset iia, jja
5809 $      call MatGetRowIJ(mat,shift,symmetric,blockcompressed,n,ia,iia,ja,jja,done,ierr)
5810 
5811        Acess the ith and jth entries via ia(iia + i) and ja(jja + j)
5812 
5813 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatGetArray()
5814 @*/
5815 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRowIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth blockcompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5816 {
5817   PetscErrorCode ierr;
5818 
5819   PetscFunctionBegin;
5820   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5821   PetscValidType(mat,1);
5822   PetscValidIntPointer(n,4);
5823   if (ia) PetscValidIntPointer(ia,5);
5824   if (ja) PetscValidIntPointer(ja,6);
5825   PetscValidIntPointer(done,7);
5826   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5827   if (!mat->ops->getrowij) *done = PETSC_FALSE;
5828   else {
5829     *done = PETSC_TRUE;
5830     ierr = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
5831     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,blockcompressed,n,ia,ja,done);CHKERRQ(ierr);
5832     ierr = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
5833   }
5834   PetscFunctionReturn(0);
5835 }
5836 
5837 #undef __FUNCT__
5838 #define __FUNCT__ "MatGetColumnIJ"
5839 /*@C
5840     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
5841 
5842     Collective on Mat
5843 
5844     Input Parameters:
5845 +   mat - the matrix
5846 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
5847 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5848                 symmetrized
5849 -   blockcompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
5850                  blockcompressed matrix is desired or not [inode, baij have blockcompressed
5851                  nonzero structure which is different than the full nonzero structure]
5852 
5853     Output Parameters:
5854 +   n - number of columns in the (possibly compressed) matrix
5855 .   ia - the column pointers
5856 .   ja - the row indices
5857 -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
5858 
5859     Level: developer
5860 
5861 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
5862 @*/
5863 PetscErrorCode PETSCMAT_DLLEXPORT MatGetColumnIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth blockcompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5864 {
5865   PetscErrorCode ierr;
5866 
5867   PetscFunctionBegin;
5868   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5869   PetscValidType(mat,1);
5870   PetscValidIntPointer(n,4);
5871   if (ia) PetscValidIntPointer(ia,5);
5872   if (ja) PetscValidIntPointer(ja,6);
5873   PetscValidIntPointer(done,7);
5874   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5875   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
5876   else {
5877     *done = PETSC_TRUE;
5878     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,blockcompressed,n,ia,ja,done);CHKERRQ(ierr);
5879   }
5880   PetscFunctionReturn(0);
5881 }
5882 
5883 #undef __FUNCT__
5884 #define __FUNCT__ "MatRestoreRowIJ"
5885 /*@C
5886     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
5887     MatGetRowIJ().
5888 
5889     Collective on Mat
5890 
5891     Input Parameters:
5892 +   mat - the matrix
5893 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
5894 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5895                 symmetrized
5896 -   blockcompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
5897                  blockcompressed matrix is desired or not [inode, baij have blockcompressed
5898                  nonzero structure which is different than the full nonzero structure]
5899 
5900     Output Parameters:
5901 +   n - size of (possibly compressed) matrix
5902 .   ia - the row pointers
5903 .   ja - the column indices
5904 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
5905 
5906     Level: developer
5907 
5908 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
5909 @*/
5910 PetscErrorCode PETSCMAT_DLLEXPORT MatRestoreRowIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth blockcompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5911 {
5912   PetscErrorCode ierr;
5913 
5914   PetscFunctionBegin;
5915   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5916   PetscValidType(mat,1);
5917   if (ia) PetscValidIntPointer(ia,5);
5918   if (ja) PetscValidIntPointer(ja,6);
5919   PetscValidIntPointer(done,7);
5920   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5921 
5922   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
5923   else {
5924     *done = PETSC_TRUE;
5925     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,blockcompressed,n,ia,ja,done);CHKERRQ(ierr);
5926   }
5927   PetscFunctionReturn(0);
5928 }
5929 
5930 #undef __FUNCT__
5931 #define __FUNCT__ "MatRestoreColumnIJ"
5932 /*@C
5933     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
5934     MatGetColumnIJ().
5935 
5936     Collective on Mat
5937 
5938     Input Parameters:
5939 +   mat - the matrix
5940 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
5941 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5942                 symmetrized
5943 -   blockcompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
5944                  blockcompressed matrix is desired or not [inode, baij have blockcompressed
5945                  nonzero structure which is different than the full nonzero structure]
5946 
5947     Output Parameters:
5948 +   n - size of (possibly compressed) matrix
5949 .   ia - the column pointers
5950 .   ja - the row indices
5951 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
5952 
5953     Level: developer
5954 
5955 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
5956 @*/
5957 PetscErrorCode PETSCMAT_DLLEXPORT MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth blockcompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5958 {
5959   PetscErrorCode ierr;
5960 
5961   PetscFunctionBegin;
5962   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5963   PetscValidType(mat,1);
5964   if (ia) PetscValidIntPointer(ia,5);
5965   if (ja) PetscValidIntPointer(ja,6);
5966   PetscValidIntPointer(done,7);
5967   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5968 
5969   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
5970   else {
5971     *done = PETSC_TRUE;
5972     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,blockcompressed,n,ia,ja,done);CHKERRQ(ierr);
5973   }
5974   PetscFunctionReturn(0);
5975 }
5976 
5977 #undef __FUNCT__
5978 #define __FUNCT__ "MatColoringPatch"
5979 /*@C
5980     MatColoringPatch -Used inside matrix coloring routines that
5981     use MatGetRowIJ() and/or MatGetColumnIJ().
5982 
5983     Collective on Mat
5984 
5985     Input Parameters:
5986 +   mat - the matrix
5987 .   ncolors - max color value
5988 .   n   - number of entries in colorarray
5989 -   colorarray - array indicating color for each column
5990 
5991     Output Parameters:
5992 .   iscoloring - coloring generated using colorarray information
5993 
5994     Level: developer
5995 
5996 .seealso: MatGetRowIJ(), MatGetColumnIJ()
5997 
5998 @*/
5999 PetscErrorCode PETSCMAT_DLLEXPORT MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
6000 {
6001   PetscErrorCode ierr;
6002 
6003   PetscFunctionBegin;
6004   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6005   PetscValidType(mat,1);
6006   PetscValidIntPointer(colorarray,4);
6007   PetscValidPointer(iscoloring,5);
6008   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6009 
6010   if (!mat->ops->coloringpatch){
6011     ierr = ISColoringCreate(((PetscObject)mat)->comm,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
6012   } else {
6013     ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
6014   }
6015   PetscFunctionReturn(0);
6016 }
6017 
6018 
6019 #undef __FUNCT__
6020 #define __FUNCT__ "MatSetUnfactored"
6021 /*@
6022    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
6023 
6024    Collective on Mat
6025 
6026    Input Parameter:
6027 .  mat - the factored matrix to be reset
6028 
6029    Notes:
6030    This routine should be used only with factored matrices formed by in-place
6031    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
6032    format).  This option can save memory, for example, when solving nonlinear
6033    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
6034    ILU(0) preconditioner.
6035 
6036    Note that one can specify in-place ILU(0) factorization by calling
6037 .vb
6038      PCType(pc,PCILU);
6039      PCFactorSeUseInPlace(pc);
6040 .ve
6041    or by using the options -pc_type ilu -pc_factor_in_place
6042 
6043    In-place factorization ILU(0) can also be used as a local
6044    solver for the blocks within the block Jacobi or additive Schwarz
6045    methods (runtime option: -sub_pc_factor_in_place).  See the discussion
6046    of these preconditioners in the users manual for details on setting
6047    local solver options.
6048 
6049    Most users should employ the simplified KSP interface for linear solvers
6050    instead of working directly with matrix algebra routines such as this.
6051    See, e.g., KSPCreate().
6052 
6053    Level: developer
6054 
6055 .seealso: PCFactorSetUseInPlace()
6056 
6057    Concepts: matrices^unfactored
6058 
6059 @*/
6060 PetscErrorCode PETSCMAT_DLLEXPORT MatSetUnfactored(Mat mat)
6061 {
6062   PetscErrorCode ierr;
6063 
6064   PetscFunctionBegin;
6065   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6066   PetscValidType(mat,1);
6067   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6068   mat->factor = MAT_FACTOR_NONE;
6069   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
6070   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
6071   PetscFunctionReturn(0);
6072 }
6073 
6074 /*MC
6075     MatGetArrayF90 - Accesses a matrix array from Fortran90.
6076 
6077     Synopsis:
6078     MatGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
6079 
6080     Not collective
6081 
6082     Input Parameter:
6083 .   x - matrix
6084 
6085     Output Parameters:
6086 +   xx_v - the Fortran90 pointer to the array
6087 -   ierr - error code
6088 
6089     Example of Usage:
6090 .vb
6091       PetscScalar, pointer xx_v(:)
6092       ....
6093       call MatGetArrayF90(x,xx_v,ierr)
6094       a = xx_v(3)
6095       call MatRestoreArrayF90(x,xx_v,ierr)
6096 .ve
6097 
6098     Notes:
6099     Not yet supported for all F90 compilers
6100 
6101     Level: advanced
6102 
6103 .seealso:  MatRestoreArrayF90(), MatGetArray(), MatRestoreArray()
6104 
6105     Concepts: matrices^accessing array
6106 
6107 M*/
6108 
6109 /*MC
6110     MatRestoreArrayF90 - Restores a matrix array that has been
6111     accessed with MatGetArrayF90().
6112 
6113     Synopsis:
6114     MatRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
6115 
6116     Not collective
6117 
6118     Input Parameters:
6119 +   x - matrix
6120 -   xx_v - the Fortran90 pointer to the array
6121 
6122     Output Parameter:
6123 .   ierr - error code
6124 
6125     Example of Usage:
6126 .vb
6127        PetscScalar, pointer xx_v(:)
6128        ....
6129        call MatGetArrayF90(x,xx_v,ierr)
6130        a = xx_v(3)
6131        call MatRestoreArrayF90(x,xx_v,ierr)
6132 .ve
6133 
6134     Notes:
6135     Not yet supported for all F90 compilers
6136 
6137     Level: advanced
6138 
6139 .seealso:  MatGetArrayF90(), MatGetArray(), MatRestoreArray()
6140 
6141 M*/
6142 
6143 
6144 #undef __FUNCT__
6145 #define __FUNCT__ "MatGetSubMatrix"
6146 /*@
6147     MatGetSubMatrix - Gets a single submatrix on the same number of processors
6148                       as the original matrix.
6149 
6150     Collective on Mat
6151 
6152     Input Parameters:
6153 +   mat - the original matrix
6154 .   isrow - rows this processor should obtain
6155 .   iscol - columns for all processors you wish to keep
6156 .   csize - number of columns "local" to this processor (does nothing for sequential
6157             matrices). This should match the result from VecGetLocalSize(x,...) if you
6158             plan to use the matrix in a A*x; alternatively, you can use PETSC_DECIDE
6159 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6160 
6161     Output Parameter:
6162 .   newmat - the new submatrix, of the same type as the old
6163 
6164     Level: advanced
6165 
6166     Notes: the iscol argument MUST be the same on each processor. You might be
6167     able to create the iscol argument with ISAllGather(). The rows is isrow will be
6168     sorted into the same order as the original matrix.
6169 
6170       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
6171    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
6172    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
6173    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
6174    you are finished using it.
6175 
6176     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
6177     the input matrix.
6178 
6179     If iscol is PETSC_NULL then all columns are obtained (not supported in Fortran), you should
6180     use csize = PETSC_DECIDE also in this case.
6181 
6182     Concepts: matrices^submatrices
6183 
6184 .seealso: MatGetSubMatrices(), ISAllGather()
6185 @*/
6186 PetscErrorCode PETSCMAT_DLLEXPORT MatGetSubMatrix(Mat mat,IS isrow,IS iscol,PetscInt csize,MatReuse cll,Mat *newmat)
6187 {
6188   PetscErrorCode ierr;
6189   PetscMPIInt    size;
6190   Mat            *local;
6191   IS             iscoltmp;
6192 
6193   PetscFunctionBegin;
6194   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6195   PetscValidHeaderSpecific(isrow,IS_COOKIE,2);
6196   if (iscol) PetscValidHeaderSpecific(iscol,IS_COOKIE,3);
6197   PetscValidPointer(newmat,6);
6198   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_COOKIE,6);
6199   PetscValidType(mat,1);
6200   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6201   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6202   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
6203 
6204   if (!iscol) {
6205     if (csize == PETSC_DECIDE) csize = mat->cmap->n;
6206     ierr = ISCreateStride(((PetscObject)mat)->comm,mat->cmap->N,0,1,&iscoltmp);CHKERRQ(ierr);
6207   } else {
6208     iscoltmp = iscol;
6209   }
6210 
6211   /* if original matrix is on just one processor then use submatrix generated */
6212   if (!mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
6213     ierr = MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
6214     if (!iscol) {ierr = ISDestroy(iscoltmp);CHKERRQ(ierr);}
6215     PetscFunctionReturn(0);
6216   } else if (!mat->ops->getsubmatrix && size == 1) {
6217     ierr    = MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
6218     *newmat = *local;
6219     ierr    = PetscFree(local);CHKERRQ(ierr);
6220     if (!iscol) {ierr = ISDestroy(iscoltmp);CHKERRQ(ierr);}
6221     PetscFunctionReturn(0);
6222   }
6223 
6224   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6225   ierr = (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,csize,cll,newmat);CHKERRQ(ierr);
6226   if (!iscol) {ierr = ISDestroy(iscoltmp);CHKERRQ(ierr);}
6227   ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);
6228   PetscFunctionReturn(0);
6229 }
6230 
6231 #undef __FUNCT__
6232 #define __FUNCT__ "MatGetSubMatrixRaw"
6233 /*@
6234     MatGetSubMatrixRaw - Gets a single submatrix on the same number of processors
6235                          as the original matrix.
6236 
6237     Collective on Mat
6238 
6239     Input Parameters:
6240 +   mat - the original matrix
6241 .   nrows - the number of rows this processor should obtain
6242 .   rows - rows this processor should obtain
6243 .   ncols - the number of columns for all processors you wish to keep
6244 .   cols - columns for all processors you wish to keep
6245 .   csize - number of columns "local" to this processor (does nothing for sequential
6246             matrices). This should match the result from VecGetLocalSize(x,...) if you
6247             plan to use the matrix in a A*x; alternatively, you can use PETSC_DECIDE
6248 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6249 
6250     Output Parameter:
6251 .   newmat - the new submatrix, of the same type as the old
6252 
6253     Level: advanced
6254 
6255     Notes: the iscol argument MUST be the same on each processor. You might be
6256     able to create the iscol argument with ISAllGather().
6257 
6258       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
6259    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
6260    to this routine with a mat of the same nonzero structure and with a cll of MAT_REUSE_MATRIX
6261    will reuse the matrix generated the first time.
6262 
6263     Concepts: matrices^submatrices
6264 
6265 .seealso: MatGetSubMatrices(), ISAllGather()
6266 @*/
6267 PetscErrorCode PETSCMAT_DLLEXPORT MatGetSubMatrixRaw(Mat mat,PetscInt nrows,const PetscInt rows[],PetscInt ncols,const PetscInt cols[],PetscInt csize,MatReuse cll,Mat *newmat)
6268 {
6269   IS             isrow, iscol;
6270   PetscErrorCode ierr;
6271 
6272   PetscFunctionBegin;
6273   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6274   PetscValidIntPointer(rows,2);
6275   PetscValidIntPointer(cols,3);
6276   PetscValidPointer(newmat,6);
6277   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_COOKIE,6);
6278   PetscValidType(mat,1);
6279   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6280   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6281   ierr = ISCreateGeneralWithArray(PETSC_COMM_SELF, nrows, (PetscInt *) rows, &isrow);CHKERRQ(ierr);
6282   ierr = ISCreateGeneralWithArray(PETSC_COMM_SELF, ncols, (PetscInt *) cols, &iscol);CHKERRQ(ierr);
6283   ierr = MatGetSubMatrix(mat, isrow, iscol, csize, cll, newmat);CHKERRQ(ierr);
6284   ierr = ISDestroy(isrow);CHKERRQ(ierr);
6285   ierr = ISDestroy(iscol);CHKERRQ(ierr);
6286   PetscFunctionReturn(0);
6287 }
6288 
6289 #undef __FUNCT__
6290 #define __FUNCT__ "MatStashSetInitialSize"
6291 /*@
6292    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
6293    used during the assembly process to store values that belong to
6294    other processors.
6295 
6296    Not Collective
6297 
6298    Input Parameters:
6299 +  mat   - the matrix
6300 .  size  - the initial size of the stash.
6301 -  bsize - the initial size of the block-stash(if used).
6302 
6303    Options Database Keys:
6304 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
6305 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
6306 
6307    Level: intermediate
6308 
6309    Notes:
6310      The block-stash is used for values set with MatSetValuesBlocked() while
6311      the stash is used for values set with MatSetValues()
6312 
6313      Run with the option -info and look for output of the form
6314      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
6315      to determine the appropriate value, MM, to use for size and
6316      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
6317      to determine the value, BMM to use for bsize
6318 
6319    Concepts: stash^setting matrix size
6320    Concepts: matrices^stash
6321 
6322 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
6323 
6324 @*/
6325 PetscErrorCode PETSCMAT_DLLEXPORT MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
6326 {
6327   PetscErrorCode ierr;
6328 
6329   PetscFunctionBegin;
6330   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6331   PetscValidType(mat,1);
6332   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
6333   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
6334   PetscFunctionReturn(0);
6335 }
6336 
6337 #undef __FUNCT__
6338 #define __FUNCT__ "MatInterpolateAdd"
6339 /*@
6340    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
6341      the matrix
6342 
6343    Collective on Mat
6344 
6345    Input Parameters:
6346 +  mat   - the matrix
6347 .  x,y - the vectors
6348 -  w - where the result is stored
6349 
6350    Level: intermediate
6351 
6352    Notes:
6353     w may be the same vector as y.
6354 
6355     This allows one to use either the restriction or interpolation (its transpose)
6356     matrix to do the interpolation
6357 
6358     Concepts: interpolation
6359 
6360 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
6361 
6362 @*/
6363 PetscErrorCode PETSCMAT_DLLEXPORT MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
6364 {
6365   PetscErrorCode ierr;
6366   PetscInt       M,N;
6367 
6368   PetscFunctionBegin;
6369   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6370   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
6371   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
6372   PetscValidHeaderSpecific(w,VEC_COOKIE,4);
6373   PetscValidType(A,1);
6374   ierr = MatPreallocated(A);CHKERRQ(ierr);
6375   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
6376   if (N > M) {
6377     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
6378   } else {
6379     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
6380   }
6381   PetscFunctionReturn(0);
6382 }
6383 
6384 #undef __FUNCT__
6385 #define __FUNCT__ "MatInterpolate"
6386 /*@
6387    MatInterpolate - y = A*x or A'*x depending on the shape of
6388      the matrix
6389 
6390    Collective on Mat
6391 
6392    Input Parameters:
6393 +  mat   - the matrix
6394 -  x,y - the vectors
6395 
6396    Level: intermediate
6397 
6398    Notes:
6399     This allows one to use either the restriction or interpolation (its transpose)
6400     matrix to do the interpolation
6401 
6402    Concepts: matrices^interpolation
6403 
6404 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
6405 
6406 @*/
6407 PetscErrorCode PETSCMAT_DLLEXPORT MatInterpolate(Mat A,Vec x,Vec y)
6408 {
6409   PetscErrorCode ierr;
6410   PetscInt       M,N;
6411 
6412   PetscFunctionBegin;
6413   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6414   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
6415   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
6416   PetscValidType(A,1);
6417   ierr = MatPreallocated(A);CHKERRQ(ierr);
6418   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
6419   if (N > M) {
6420     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
6421   } else {
6422     ierr = MatMult(A,x,y);CHKERRQ(ierr);
6423   }
6424   PetscFunctionReturn(0);
6425 }
6426 
6427 #undef __FUNCT__
6428 #define __FUNCT__ "MatRestrict"
6429 /*@
6430    MatRestrict - y = A*x or A'*x
6431 
6432    Collective on Mat
6433 
6434    Input Parameters:
6435 +  mat   - the matrix
6436 -  x,y - the vectors
6437 
6438    Level: intermediate
6439 
6440    Notes:
6441     This allows one to use either the restriction or interpolation (its transpose)
6442     matrix to do the restriction
6443 
6444    Concepts: matrices^restriction
6445 
6446 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
6447 
6448 @*/
6449 PetscErrorCode PETSCMAT_DLLEXPORT MatRestrict(Mat A,Vec x,Vec y)
6450 {
6451   PetscErrorCode ierr;
6452   PetscInt       M,N;
6453 
6454   PetscFunctionBegin;
6455   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6456   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
6457   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
6458   PetscValidType(A,1);
6459   ierr = MatPreallocated(A);CHKERRQ(ierr);
6460 
6461   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
6462   if (N > M) {
6463     ierr = MatMult(A,x,y);CHKERRQ(ierr);
6464   } else {
6465     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
6466   }
6467   PetscFunctionReturn(0);
6468 }
6469 
6470 #undef __FUNCT__
6471 #define __FUNCT__ "MatNullSpaceAttach"
6472 /*@
6473    MatNullSpaceAttach - attaches a null space to a matrix.
6474         This null space will be removed from the resulting vector whenever
6475         MatMult() is called
6476 
6477    Collective on Mat
6478 
6479    Input Parameters:
6480 +  mat - the matrix
6481 -  nullsp - the null space object
6482 
6483    Level: developer
6484 
6485    Notes:
6486       Overwrites any previous null space that may have been attached
6487 
6488    Concepts: null space^attaching to matrix
6489 
6490 .seealso: MatCreate(), MatNullSpaceCreate()
6491 @*/
6492 PetscErrorCode PETSCMAT_DLLEXPORT MatNullSpaceAttach(Mat mat,MatNullSpace nullsp)
6493 {
6494   PetscErrorCode ierr;
6495 
6496   PetscFunctionBegin;
6497   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6498   PetscValidType(mat,1);
6499   PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_COOKIE,2);
6500   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6501   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
6502   if (mat->nullsp) { ierr = MatNullSpaceDestroy(mat->nullsp);CHKERRQ(ierr); }
6503   mat->nullsp = nullsp;
6504   PetscFunctionReturn(0);
6505 }
6506 
6507 #undef __FUNCT__
6508 #define __FUNCT__ "MatICCFactor"
6509 /*@
6510    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
6511 
6512    Collective on Mat
6513 
6514    Input Parameters:
6515 +  mat - the matrix
6516 .  row - row/column permutation
6517 .  fill - expected fill factor >= 1.0
6518 -  level - level of fill, for ICC(k)
6519 
6520    Notes:
6521    Probably really in-place only when level of fill is zero, otherwise allocates
6522    new space to store factored matrix and deletes previous memory.
6523 
6524    Most users should employ the simplified KSP interface for linear solvers
6525    instead of working directly with matrix algebra routines such as this.
6526    See, e.g., KSPCreate().
6527 
6528    Level: developer
6529 
6530    Concepts: matrices^incomplete Cholesky factorization
6531    Concepts: Cholesky factorization
6532 
6533 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6534 @*/
6535 PetscErrorCode PETSCMAT_DLLEXPORT MatICCFactor(Mat mat,IS row,const MatFactorInfo* info)
6536 {
6537   PetscErrorCode ierr;
6538 
6539   PetscFunctionBegin;
6540   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6541   PetscValidType(mat,1);
6542   if (row) PetscValidHeaderSpecific(row,IS_COOKIE,2);
6543   PetscValidPointer(info,3);
6544   if (mat->rmap->N != mat->cmap->N) SETERRQ(PETSC_ERR_ARG_WRONG,"matrix must be square");
6545   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6546   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6547   if (!mat->ops->iccfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6548   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6549   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
6550   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6551   PetscFunctionReturn(0);
6552 }
6553 
6554 #undef __FUNCT__
6555 #define __FUNCT__ "MatSetValuesAdic"
6556 /*@
6557    MatSetValuesAdic - Sets values computed with ADIC automatic differentiation into a matrix.
6558 
6559    Not Collective
6560 
6561    Input Parameters:
6562 +  mat - the matrix
6563 -  v - the values compute with ADIC
6564 
6565    Level: developer
6566 
6567    Notes:
6568      Must call MatSetColoring() before using this routine. Also this matrix must already
6569      have its nonzero pattern determined.
6570 
6571 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
6572           MatSetValues(), MatSetColoring(), MatSetValuesAdifor()
6573 @*/
6574 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesAdic(Mat mat,void *v)
6575 {
6576   PetscErrorCode ierr;
6577 
6578   PetscFunctionBegin;
6579   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6580   PetscValidType(mat,1);
6581   PetscValidPointer(mat,2);
6582 
6583   if (!mat->assembled) {
6584     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6585   }
6586   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
6587   if (!mat->ops->setvaluesadic) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6588   ierr = (*mat->ops->setvaluesadic)(mat,v);CHKERRQ(ierr);
6589   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
6590   ierr = MatView_Private(mat);CHKERRQ(ierr);
6591   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6592   PetscFunctionReturn(0);
6593 }
6594 
6595 
6596 #undef __FUNCT__
6597 #define __FUNCT__ "MatSetColoring"
6598 /*@
6599    MatSetColoring - Sets a coloring used by calls to MatSetValuesAdic()
6600 
6601    Not Collective
6602 
6603    Input Parameters:
6604 +  mat - the matrix
6605 -  coloring - the coloring
6606 
6607    Level: developer
6608 
6609 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
6610           MatSetValues(), MatSetValuesAdic()
6611 @*/
6612 PetscErrorCode PETSCMAT_DLLEXPORT MatSetColoring(Mat mat,ISColoring coloring)
6613 {
6614   PetscErrorCode ierr;
6615 
6616   PetscFunctionBegin;
6617   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6618   PetscValidType(mat,1);
6619   PetscValidPointer(coloring,2);
6620 
6621   if (!mat->assembled) {
6622     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6623   }
6624   if (!mat->ops->setcoloring) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6625   ierr = (*mat->ops->setcoloring)(mat,coloring);CHKERRQ(ierr);
6626   PetscFunctionReturn(0);
6627 }
6628 
6629 #undef __FUNCT__
6630 #define __FUNCT__ "MatSetValuesAdifor"
6631 /*@
6632    MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.
6633 
6634    Not Collective
6635 
6636    Input Parameters:
6637 +  mat - the matrix
6638 .  nl - leading dimension of v
6639 -  v - the values compute with ADIFOR
6640 
6641    Level: developer
6642 
6643    Notes:
6644      Must call MatSetColoring() before using this routine. Also this matrix must already
6645      have its nonzero pattern determined.
6646 
6647 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
6648           MatSetValues(), MatSetColoring()
6649 @*/
6650 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
6651 {
6652   PetscErrorCode ierr;
6653 
6654   PetscFunctionBegin;
6655   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6656   PetscValidType(mat,1);
6657   PetscValidPointer(v,3);
6658 
6659   if (!mat->assembled) {
6660     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6661   }
6662   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
6663   if (!mat->ops->setvaluesadifor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6664   ierr = (*mat->ops->setvaluesadifor)(mat,nl,v);CHKERRQ(ierr);
6665   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
6666   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6667   PetscFunctionReturn(0);
6668 }
6669 
6670 #undef __FUNCT__
6671 #define __FUNCT__ "MatDiagonalScaleLocal"
6672 /*@
6673    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
6674          ghosted ones.
6675 
6676    Not Collective
6677 
6678    Input Parameters:
6679 +  mat - the matrix
6680 -  diag = the diagonal values, including ghost ones
6681 
6682    Level: developer
6683 
6684    Notes: Works only for MPIAIJ and MPIBAIJ matrices
6685 
6686 .seealso: MatDiagonalScale()
6687 @*/
6688 PetscErrorCode PETSCMAT_DLLEXPORT MatDiagonalScaleLocal(Mat mat,Vec diag)
6689 {
6690   PetscErrorCode ierr;
6691   PetscMPIInt    size;
6692 
6693   PetscFunctionBegin;
6694   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6695   PetscValidHeaderSpecific(diag,VEC_COOKIE,2);
6696   PetscValidType(mat,1);
6697 
6698   if (!mat->assembled) {
6699     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6700   }
6701   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
6702   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
6703   if (size == 1) {
6704     PetscInt n,m;
6705     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
6706     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
6707     if (m == n) {
6708       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
6709     } else {
6710       SETERRQ(PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
6711     }
6712   } else {
6713     PetscErrorCode (*f)(Mat,Vec);
6714     ierr = PetscObjectQueryFunction((PetscObject)mat,"MatDiagonalScaleLocal_C",(void (**)(void))&f);CHKERRQ(ierr);
6715     if (f) {
6716       ierr = (*f)(mat,diag);CHKERRQ(ierr);
6717     } else {
6718       SETERRQ(PETSC_ERR_SUP,"Only supported for MPIAIJ and MPIBAIJ parallel matrices");
6719     }
6720   }
6721   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
6722   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6723   PetscFunctionReturn(0);
6724 }
6725 
6726 #undef __FUNCT__
6727 #define __FUNCT__ "MatGetInertia"
6728 /*@
6729    MatGetInertia - Gets the inertia from a factored matrix
6730 
6731    Collective on Mat
6732 
6733    Input Parameter:
6734 .  mat - the matrix
6735 
6736    Output Parameters:
6737 +   nneg - number of negative eigenvalues
6738 .   nzero - number of zero eigenvalues
6739 -   npos - number of positive eigenvalues
6740 
6741    Level: advanced
6742 
6743    Notes: Matrix must have been factored by MatCholeskyFactor()
6744 
6745 
6746 @*/
6747 PetscErrorCode PETSCMAT_DLLEXPORT MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
6748 {
6749   PetscErrorCode ierr;
6750 
6751   PetscFunctionBegin;
6752   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6753   PetscValidType(mat,1);
6754   if (!mat->factor)    SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
6755   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
6756   if (!mat->ops->getinertia) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6757   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
6758   PetscFunctionReturn(0);
6759 }
6760 
6761 /* ----------------------------------------------------------------*/
6762 #undef __FUNCT__
6763 #define __FUNCT__ "MatSolves"
6764 /*@C
6765    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
6766 
6767    Collective on Mat and Vecs
6768 
6769    Input Parameters:
6770 +  mat - the factored matrix
6771 -  b - the right-hand-side vectors
6772 
6773    Output Parameter:
6774 .  x - the result vectors
6775 
6776    Notes:
6777    The vectors b and x cannot be the same.  I.e., one cannot
6778    call MatSolves(A,x,x).
6779 
6780    Notes:
6781    Most users should employ the simplified KSP interface for linear solvers
6782    instead of working directly with matrix algebra routines such as this.
6783    See, e.g., KSPCreate().
6784 
6785    Level: developer
6786 
6787    Concepts: matrices^triangular solves
6788 
6789 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
6790 @*/
6791 PetscErrorCode PETSCMAT_DLLEXPORT MatSolves(Mat mat,Vecs b,Vecs x)
6792 {
6793   PetscErrorCode ierr;
6794 
6795   PetscFunctionBegin;
6796   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6797   PetscValidType(mat,1);
6798   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
6799   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
6800   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
6801 
6802   if (!mat->ops->solves) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6803   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6804   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
6805   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
6806   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
6807   PetscFunctionReturn(0);
6808 }
6809 
6810 #undef __FUNCT__
6811 #define __FUNCT__ "MatIsSymmetric"
6812 /*@
6813    MatIsSymmetric - Test whether a matrix is symmetric
6814 
6815    Collective on Mat
6816 
6817    Input Parameter:
6818 +  A - the matrix to test
6819 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
6820 
6821    Output Parameters:
6822 .  flg - the result
6823 
6824    Level: intermediate
6825 
6826    Concepts: matrix^symmetry
6827 
6828 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
6829 @*/
6830 PetscErrorCode PETSCMAT_DLLEXPORT MatIsSymmetric(Mat A,PetscReal tol,PetscTruth *flg)
6831 {
6832   PetscErrorCode ierr;
6833 
6834   PetscFunctionBegin;
6835   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6836   PetscValidPointer(flg,2);
6837   if (!A->symmetric_set) {
6838     if (!A->ops->issymmetric) {
6839       const MatType mattype;
6840       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
6841       SETERRQ1(PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
6842     }
6843     ierr = (*A->ops->issymmetric)(A,tol,&A->symmetric);CHKERRQ(ierr);
6844     A->symmetric_set = PETSC_TRUE;
6845     if (A->symmetric) {
6846       A->structurally_symmetric_set = PETSC_TRUE;
6847       A->structurally_symmetric     = PETSC_TRUE;
6848     }
6849   }
6850   *flg = A->symmetric;
6851   PetscFunctionReturn(0);
6852 }
6853 
6854 #undef __FUNCT__
6855 #define __FUNCT__ "MatIsHermitian"
6856 /*@
6857    MatIsHermitian - Test whether a matrix is Hermitian
6858 
6859    Collective on Mat
6860 
6861    Input Parameter:
6862 +  A - the matrix to test
6863 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
6864 
6865    Output Parameters:
6866 .  flg - the result
6867 
6868    Level: intermediate
6869 
6870    Concepts: matrix^symmetry
6871 
6872 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
6873 @*/
6874 PetscErrorCode PETSCMAT_DLLEXPORT MatIsHermitian(Mat A,PetscReal tol,PetscTruth *flg)
6875 {
6876   PetscErrorCode ierr;
6877 
6878   PetscFunctionBegin;
6879   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6880   PetscValidPointer(flg,2);
6881   if (!A->hermitian_set) {
6882     if (!A->ops->ishermitian) {
6883       const MatType mattype;
6884       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
6885       SETERRQ1(PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for Hermitian",mattype);
6886     }
6887     ierr = (*A->ops->ishermitian)(A,tol,&A->hermitian);CHKERRQ(ierr);
6888     A->hermitian_set = PETSC_TRUE;
6889     if (A->hermitian) {
6890       A->structurally_symmetric_set = PETSC_TRUE;
6891       A->structurally_symmetric     = PETSC_TRUE;
6892     }
6893   }
6894   *flg = A->hermitian;
6895   PetscFunctionReturn(0);
6896 }
6897 
6898 #undef __FUNCT__
6899 #define __FUNCT__ "MatIsSymmetricKnown"
6900 /*@
6901    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
6902 
6903    Collective on Mat
6904 
6905    Input Parameter:
6906 .  A - the matrix to check
6907 
6908    Output Parameters:
6909 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
6910 -  flg - the result
6911 
6912    Level: advanced
6913 
6914    Concepts: matrix^symmetry
6915 
6916    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
6917          if you want it explicitly checked
6918 
6919 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
6920 @*/
6921 PetscErrorCode PETSCMAT_DLLEXPORT MatIsSymmetricKnown(Mat A,PetscTruth *set,PetscTruth *flg)
6922 {
6923   PetscFunctionBegin;
6924   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6925   PetscValidPointer(set,2);
6926   PetscValidPointer(flg,3);
6927   if (A->symmetric_set) {
6928     *set = PETSC_TRUE;
6929     *flg = A->symmetric;
6930   } else {
6931     *set = PETSC_FALSE;
6932   }
6933   PetscFunctionReturn(0);
6934 }
6935 
6936 #undef __FUNCT__
6937 #define __FUNCT__ "MatIsHermitianKnown"
6938 /*@
6939    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
6940 
6941    Collective on Mat
6942 
6943    Input Parameter:
6944 .  A - the matrix to check
6945 
6946    Output Parameters:
6947 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
6948 -  flg - the result
6949 
6950    Level: advanced
6951 
6952    Concepts: matrix^symmetry
6953 
6954    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
6955          if you want it explicitly checked
6956 
6957 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
6958 @*/
6959 PetscErrorCode PETSCMAT_DLLEXPORT MatIsHermitianKnown(Mat A,PetscTruth *set,PetscTruth *flg)
6960 {
6961   PetscFunctionBegin;
6962   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6963   PetscValidPointer(set,2);
6964   PetscValidPointer(flg,3);
6965   if (A->hermitian_set) {
6966     *set = PETSC_TRUE;
6967     *flg = A->hermitian;
6968   } else {
6969     *set = PETSC_FALSE;
6970   }
6971   PetscFunctionReturn(0);
6972 }
6973 
6974 #undef __FUNCT__
6975 #define __FUNCT__ "MatIsStructurallySymmetric"
6976 /*@
6977    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
6978 
6979    Collective on Mat
6980 
6981    Input Parameter:
6982 .  A - the matrix to test
6983 
6984    Output Parameters:
6985 .  flg - the result
6986 
6987    Level: intermediate
6988 
6989    Concepts: matrix^symmetry
6990 
6991 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
6992 @*/
6993 PetscErrorCode PETSCMAT_DLLEXPORT MatIsStructurallySymmetric(Mat A,PetscTruth *flg)
6994 {
6995   PetscErrorCode ierr;
6996 
6997   PetscFunctionBegin;
6998   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6999   PetscValidPointer(flg,2);
7000   if (!A->structurally_symmetric_set) {
7001     if (!A->ops->isstructurallysymmetric) SETERRQ(PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
7002     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
7003     A->structurally_symmetric_set = PETSC_TRUE;
7004   }
7005   *flg = A->structurally_symmetric;
7006   PetscFunctionReturn(0);
7007 }
7008 
7009 #undef __FUNCT__
7010 #define __FUNCT__ "MatStashGetInfo"
7011 extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
7012 /*@
7013    MatStashGetInfo - Gets how many values are currently in the vector stash, i.e. need
7014        to be communicated to other processors during the MatAssemblyBegin/End() process
7015 
7016     Not collective
7017 
7018    Input Parameter:
7019 .   vec - the vector
7020 
7021    Output Parameters:
7022 +   nstash   - the size of the stash
7023 .   reallocs - the number of additional mallocs incurred.
7024 .   bnstash   - the size of the block stash
7025 -   breallocs - the number of additional mallocs incurred.in the block stash
7026 
7027    Level: advanced
7028 
7029 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
7030 
7031 @*/
7032 PetscErrorCode PETSCMAT_DLLEXPORT MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
7033 {
7034   PetscErrorCode ierr;
7035   PetscFunctionBegin;
7036   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
7037   ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
7038   PetscFunctionReturn(0);
7039 }
7040 
7041 #undef __FUNCT__
7042 #define __FUNCT__ "MatGetVecs"
7043 /*@C
7044    MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same
7045      parallel layout
7046 
7047    Collective on Mat
7048 
7049    Input Parameter:
7050 .  mat - the matrix
7051 
7052    Output Parameter:
7053 +   right - (optional) vector that the matrix can be multiplied against
7054 -   left - (optional) vector that the matrix vector product can be stored in
7055 
7056   Level: advanced
7057 
7058 .seealso: MatCreate()
7059 @*/
7060 PetscErrorCode PETSCMAT_DLLEXPORT MatGetVecs(Mat mat,Vec *right,Vec *left)
7061 {
7062   PetscErrorCode ierr;
7063 
7064   PetscFunctionBegin;
7065   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
7066   PetscValidType(mat,1);
7067   ierr = MatPreallocated(mat);CHKERRQ(ierr);
7068   if (mat->ops->getvecs) {
7069     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
7070   } else {
7071     PetscMPIInt size;
7072     ierr = MPI_Comm_size(((PetscObject)mat)->comm, &size);CHKERRQ(ierr);
7073     if (right) {
7074       ierr = VecCreate(((PetscObject)mat)->comm,right);CHKERRQ(ierr);
7075       ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
7076       ierr = VecSetBlockSize(*right,mat->rmap->bs);CHKERRQ(ierr);
7077       if (size > 1) {
7078         /* New vectors uses Mat cmap and does not create a new one */
7079 	ierr = PetscMapDestroy((*right)->map);CHKERRQ(ierr);
7080 	(*right)->map = mat->cmap;
7081 	mat->cmap->refcnt++;
7082 
7083         ierr = VecSetType(*right,VECMPI);CHKERRQ(ierr);
7084       } else {ierr = VecSetType(*right,VECSEQ);CHKERRQ(ierr);}
7085     }
7086     if (left) {
7087       ierr = VecCreate(((PetscObject)mat)->comm,left);CHKERRQ(ierr);
7088       ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
7089       ierr = VecSetBlockSize(*left,mat->rmap->bs);CHKERRQ(ierr);
7090       if (size > 1) {
7091         /* New vectors uses Mat rmap and does not create a new one */
7092 	ierr = PetscMapDestroy((*left)->map);CHKERRQ(ierr);
7093 	(*left)->map = mat->rmap;
7094 	mat->rmap->refcnt++;
7095 
7096         ierr = VecSetType(*left,VECMPI);CHKERRQ(ierr);
7097       } else {ierr = VecSetType(*left,VECSEQ);CHKERRQ(ierr);}
7098     }
7099   }
7100   if (mat->mapping) {
7101     if (right) {ierr = VecSetLocalToGlobalMapping(*right,mat->mapping);CHKERRQ(ierr);}
7102     if (left) {ierr = VecSetLocalToGlobalMapping(*left,mat->mapping);CHKERRQ(ierr);}
7103   }
7104   if (mat->bmapping) {
7105     if (right) {ierr = VecSetLocalToGlobalMappingBlock(*right,mat->bmapping);CHKERRQ(ierr);}
7106     if (left) {ierr = VecSetLocalToGlobalMappingBlock(*left,mat->bmapping);CHKERRQ(ierr);}
7107   }
7108   PetscFunctionReturn(0);
7109 }
7110 
7111 #undef __FUNCT__
7112 #define __FUNCT__ "MatFactorInfoInitialize"
7113 /*@
7114    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
7115      with default values.
7116 
7117    Not Collective
7118 
7119    Input Parameters:
7120 .    info - the MatFactorInfo data structure
7121 
7122 
7123    Notes: The solvers are generally used through the KSP and PC objects, for example
7124           PCLU, PCILU, PCCHOLESKY, PCICC
7125 
7126    Level: developer
7127 
7128 .seealso: MatFactorInfo
7129 @*/
7130 
7131 PetscErrorCode PETSCMAT_DLLEXPORT MatFactorInfoInitialize(MatFactorInfo *info)
7132 {
7133   PetscErrorCode ierr;
7134 
7135   PetscFunctionBegin;
7136   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
7137   PetscFunctionReturn(0);
7138 }
7139 
7140 #undef __FUNCT__
7141 #define __FUNCT__ "MatPtAP"
7142 /*@
7143    MatPtAP - Creates the matrix projection C = P^T * A * P
7144 
7145    Collective on Mat
7146 
7147    Input Parameters:
7148 +  A - the matrix
7149 .  P - the projection matrix
7150 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7151 -  fill - expected fill as ratio of nnz(C)/nnz(A)
7152 
7153    Output Parameters:
7154 .  C - the product matrix
7155 
7156    Notes:
7157    C will be created and must be destroyed by the user with MatDestroy().
7158 
7159    This routine is currently only implemented for pairs of AIJ matrices and classes
7160    which inherit from AIJ.
7161 
7162    Level: intermediate
7163 
7164 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult()
7165 @*/
7166 PetscErrorCode PETSCMAT_DLLEXPORT MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
7167 {
7168   PetscErrorCode ierr;
7169 
7170   PetscFunctionBegin;
7171   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
7172   PetscValidType(A,1);
7173   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7174   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7175   PetscValidHeaderSpecific(P,MAT_COOKIE,2);
7176   PetscValidType(P,2);
7177   ierr = MatPreallocated(P);CHKERRQ(ierr);
7178   if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7179   if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7180   PetscValidPointer(C,3);
7181   if (P->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
7182   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
7183   ierr = MatPreallocated(A);CHKERRQ(ierr);
7184 
7185   ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
7186   ierr = (*A->ops->ptap)(A,P,scall,fill,C);CHKERRQ(ierr);
7187   ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
7188 
7189   PetscFunctionReturn(0);
7190 }
7191 
7192 #undef __FUNCT__
7193 #define __FUNCT__ "MatPtAPNumeric"
7194 /*@
7195    MatPtAPNumeric - Computes the matrix projection C = P^T * A * P
7196 
7197    Collective on Mat
7198 
7199    Input Parameters:
7200 +  A - the matrix
7201 -  P - the projection matrix
7202 
7203    Output Parameters:
7204 .  C - the product matrix
7205 
7206    Notes:
7207    C must have been created by calling MatPtAPSymbolic and must be destroyed by
7208    the user using MatDeatroy().
7209 
7210    This routine is currently only implemented for pairs of AIJ matrices and classes
7211    which inherit from AIJ.  C will be of type MATAIJ.
7212 
7213    Level: intermediate
7214 
7215 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
7216 @*/
7217 PetscErrorCode PETSCMAT_DLLEXPORT MatPtAPNumeric(Mat A,Mat P,Mat C)
7218 {
7219   PetscErrorCode ierr;
7220 
7221   PetscFunctionBegin;
7222   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
7223   PetscValidType(A,1);
7224   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7225   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7226   PetscValidHeaderSpecific(P,MAT_COOKIE,2);
7227   PetscValidType(P,2);
7228   ierr = MatPreallocated(P);CHKERRQ(ierr);
7229   if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7230   if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7231   PetscValidHeaderSpecific(C,MAT_COOKIE,3);
7232   PetscValidType(C,3);
7233   ierr = MatPreallocated(C);CHKERRQ(ierr);
7234   if (C->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7235   if (P->cmap->N!=C->rmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->rmap->N);
7236   if (P->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
7237   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);
7238   if (P->cmap->N!=C->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->cmap->N);
7239   ierr = MatPreallocated(A);CHKERRQ(ierr);
7240 
7241   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
7242   ierr = (*A->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr);
7243   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
7244   PetscFunctionReturn(0);
7245 }
7246 
7247 #undef __FUNCT__
7248 #define __FUNCT__ "MatPtAPSymbolic"
7249 /*@
7250    MatPtAPSymbolic - Creates the (i,j) structure of the matrix projection C = P^T * A * P
7251 
7252    Collective on Mat
7253 
7254    Input Parameters:
7255 +  A - the matrix
7256 -  P - the projection matrix
7257 
7258    Output Parameters:
7259 .  C - the (i,j) structure of the product matrix
7260 
7261    Notes:
7262    C will be created and must be destroyed by the user with MatDestroy().
7263 
7264    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
7265    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
7266    this (i,j) structure by calling MatPtAPNumeric().
7267 
7268    Level: intermediate
7269 
7270 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
7271 @*/
7272 PetscErrorCode PETSCMAT_DLLEXPORT MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
7273 {
7274   PetscErrorCode ierr;
7275 
7276   PetscFunctionBegin;
7277   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
7278   PetscValidType(A,1);
7279   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7280   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7281   if (fill <1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
7282   PetscValidHeaderSpecific(P,MAT_COOKIE,2);
7283   PetscValidType(P,2);
7284   ierr = MatPreallocated(P);CHKERRQ(ierr);
7285   if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7286   if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7287   PetscValidPointer(C,3);
7288 
7289   if (P->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
7290   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);
7291   ierr = MatPreallocated(A);CHKERRQ(ierr);
7292   ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
7293   ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr);
7294   ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
7295 
7296   ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr);
7297 
7298   PetscFunctionReturn(0);
7299 }
7300 
7301 #undef __FUNCT__
7302 #define __FUNCT__ "MatMatMult"
7303 /*@
7304    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
7305 
7306    Collective on Mat
7307 
7308    Input Parameters:
7309 +  A - the left matrix
7310 .  B - the right matrix
7311 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7312 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
7313           if the result is a dense matrix this is irrelevent
7314 
7315    Output Parameters:
7316 .  C - the product matrix
7317 
7318    Notes:
7319    Unless scall is MAT_REUSE_MATRIX C will be created.
7320 
7321    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
7322 
7323    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
7324    actually needed.
7325 
7326    If you have many matrices with the same non-zero structure to multiply, you
7327    should either
7328 $   1) use MAT_REUSE_MATRIX in all calls but the first or
7329 $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
7330 
7331    Level: intermediate
7332 
7333 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatPtAP()
7334 @*/
7335 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
7336 {
7337   PetscErrorCode ierr;
7338   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
7339   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
7340   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat *)=PETSC_NULL;
7341 
7342   PetscFunctionBegin;
7343   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
7344   PetscValidType(A,1);
7345   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7346   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7347   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
7348   PetscValidType(B,2);
7349   ierr = MatPreallocated(B);CHKERRQ(ierr);
7350   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7351   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7352   PetscValidPointer(C,3);
7353   if (B->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
7354   if (scall == MAT_REUSE_MATRIX){
7355     PetscValidPointer(*C,5);
7356     PetscValidHeaderSpecific(*C,MAT_COOKIE,5);
7357   }
7358   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
7359   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
7360   ierr = MatPreallocated(A);CHKERRQ(ierr);
7361 
7362   fA = A->ops->matmult;
7363   fB = B->ops->matmult;
7364   if (fB == fA) {
7365     if (!fB) SETERRQ1(PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
7366     mult = fB;
7367   } else {
7368     /* dispatch based on the type of A and B */
7369     char  multname[256];
7370     ierr = PetscStrcpy(multname,"MatMatMult_");CHKERRQ(ierr);
7371     ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr);
7372     ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);
7373     ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr);
7374     ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
7375     ierr = PetscObjectQueryFunction((PetscObject)B,multname,(void (**)(void))&mult);CHKERRQ(ierr);
7376     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);
7377   }
7378   ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
7379   ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr);
7380   ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
7381   PetscFunctionReturn(0);
7382 }
7383 
7384 #undef __FUNCT__
7385 #define __FUNCT__ "MatMatMultSymbolic"
7386 /*@
7387    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
7388    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().
7389 
7390    Collective on Mat
7391 
7392    Input Parameters:
7393 +  A - the left matrix
7394 .  B - the right matrix
7395 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
7396       if C is a dense matrix this is irrelevent
7397 
7398    Output Parameters:
7399 .  C - the product matrix
7400 
7401    Notes:
7402    Unless scall is MAT_REUSE_MATRIX C will be created.
7403 
7404    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
7405    actually needed.
7406 
7407    This routine is currently implemented for
7408     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
7409     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
7410     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
7411 
7412    Level: intermediate
7413 
7414 .seealso: MatMatMult(), MatMatMultNumeric()
7415 @*/
7416 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
7417 {
7418   PetscErrorCode ierr;
7419   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat *);
7420   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat *);
7421   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat *)=PETSC_NULL;
7422 
7423   PetscFunctionBegin;
7424   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
7425   PetscValidType(A,1);
7426   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7427   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7428 
7429   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
7430   PetscValidType(B,2);
7431   ierr = MatPreallocated(B);CHKERRQ(ierr);
7432   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7433   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7434   PetscValidPointer(C,3);
7435 
7436   if (B->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
7437   if (fill == PETSC_DEFAULT) fill = 2.0;
7438   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
7439   ierr = MatPreallocated(A);CHKERRQ(ierr);
7440 
7441   Asymbolic = A->ops->matmultsymbolic;
7442   Bsymbolic = B->ops->matmultsymbolic;
7443   if (Asymbolic == Bsymbolic){
7444     if (!Bsymbolic) SETERRQ1(PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
7445     symbolic = Bsymbolic;
7446   } else { /* dispatch based on the type of A and B */
7447     char  symbolicname[256];
7448     ierr = PetscStrcpy(symbolicname,"MatMatMultSymbolic_");CHKERRQ(ierr);
7449     ierr = PetscStrcat(symbolicname,((PetscObject)A)->type_name);CHKERRQ(ierr);
7450     ierr = PetscStrcat(symbolicname,"_");CHKERRQ(ierr);
7451     ierr = PetscStrcat(symbolicname,((PetscObject)B)->type_name);CHKERRQ(ierr);
7452     ierr = PetscStrcat(symbolicname,"_C");CHKERRQ(ierr);
7453     ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,(void (**)(void))&symbolic);CHKERRQ(ierr);
7454     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);
7455   }
7456   ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
7457   ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr);
7458   ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
7459   PetscFunctionReturn(0);
7460 }
7461 
7462 #undef __FUNCT__
7463 #define __FUNCT__ "MatMatMultNumeric"
7464 /*@
7465    MatMatMultNumeric - Performs the numeric matrix-matrix product.
7466    Call this routine after first calling MatMatMultSymbolic().
7467 
7468    Collective on Mat
7469 
7470    Input Parameters:
7471 +  A - the left matrix
7472 -  B - the right matrix
7473 
7474    Output Parameters:
7475 .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
7476 
7477    Notes:
7478    C must have been created with MatMatMultSymbolic().
7479 
7480    This routine is currently implemented for
7481     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
7482     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
7483     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
7484 
7485    Level: intermediate
7486 
7487 .seealso: MatMatMult(), MatMatMultSymbolic()
7488 @*/
7489 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMultNumeric(Mat A,Mat B,Mat C)
7490 {
7491   PetscErrorCode ierr;
7492   PetscErrorCode (*Anumeric)(Mat,Mat,Mat);
7493   PetscErrorCode (*Bnumeric)(Mat,Mat,Mat);
7494   PetscErrorCode (*numeric)(Mat,Mat,Mat)=PETSC_NULL;
7495 
7496   PetscFunctionBegin;
7497   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
7498   PetscValidType(A,1);
7499   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7500   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7501 
7502   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
7503   PetscValidType(B,2);
7504   ierr = MatPreallocated(B);CHKERRQ(ierr);
7505   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7506   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7507 
7508   PetscValidHeaderSpecific(C,MAT_COOKIE,3);
7509   PetscValidType(C,3);
7510   ierr = MatPreallocated(C);CHKERRQ(ierr);
7511   if (!C->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7512   if (C->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7513 
7514   if (B->cmap->N!=C->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->cmap->N,C->cmap->N);
7515   if (B->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
7516   if (A->rmap->N!=C->rmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",A->rmap->N,C->rmap->N);
7517   ierr = MatPreallocated(A);CHKERRQ(ierr);
7518 
7519   Anumeric = A->ops->matmultnumeric;
7520   Bnumeric = B->ops->matmultnumeric;
7521   if (Anumeric == Bnumeric){
7522     if (!Bnumeric) SETERRQ1(PETSC_ERR_SUP,"MatMatMultNumeric not supported for B of type %s",((PetscObject)B)->type_name);
7523     numeric = Bnumeric;
7524   } else {
7525     char  numericname[256];
7526     ierr = PetscStrcpy(numericname,"MatMatMultNumeric_");CHKERRQ(ierr);
7527     ierr = PetscStrcat(numericname,((PetscObject)A)->type_name);CHKERRQ(ierr);
7528     ierr = PetscStrcat(numericname,"_");CHKERRQ(ierr);
7529     ierr = PetscStrcat(numericname,((PetscObject)B)->type_name);CHKERRQ(ierr);
7530     ierr = PetscStrcat(numericname,"_C");CHKERRQ(ierr);
7531     ierr = PetscObjectQueryFunction((PetscObject)B,numericname,(void (**)(void))&numeric);CHKERRQ(ierr);
7532     if (!numeric)
7533       SETERRQ2(PETSC_ERR_ARG_INCOMP,"MatMatMultNumeric requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
7534   }
7535   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
7536   ierr = (*numeric)(A,B,C);CHKERRQ(ierr);
7537   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
7538   PetscFunctionReturn(0);
7539 }
7540 
7541 #undef __FUNCT__
7542 #define __FUNCT__ "MatMatMultTranspose"
7543 /*@
7544    MatMatMultTranspose - Performs Matrix-Matrix Multiplication C=A^T*B.
7545 
7546    Collective on Mat
7547 
7548    Input Parameters:
7549 +  A - the left matrix
7550 .  B - the right matrix
7551 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7552 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
7553 
7554    Output Parameters:
7555 .  C - the product matrix
7556 
7557    Notes:
7558    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
7559 
7560    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
7561 
7562   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
7563    actually needed.
7564 
7565    This routine is currently only implemented for pairs of SeqAIJ matrices and pairs of SeqDense matrices and classes
7566    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.
7567 
7568    Level: intermediate
7569 
7570 .seealso: MatMatMultTransposeSymbolic(), MatMatMultTransposeNumeric(), MatPtAP()
7571 @*/
7572 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMultTranspose(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
7573 {
7574   PetscErrorCode ierr;
7575   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
7576   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
7577 
7578   PetscFunctionBegin;
7579   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
7580   PetscValidType(A,1);
7581   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7582   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7583   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
7584   PetscValidType(B,2);
7585   ierr = MatPreallocated(B);CHKERRQ(ierr);
7586   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7587   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7588   PetscValidPointer(C,3);
7589   if (B->rmap->N!=A->rmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->rmap->N);
7590   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
7591   ierr = MatPreallocated(A);CHKERRQ(ierr);
7592 
7593   fA = A->ops->matmulttranspose;
7594   if (!fA) SETERRQ1(PETSC_ERR_SUP,"MatMatMultTranspose not supported for A of type %s",((PetscObject)A)->type_name);
7595   fB = B->ops->matmulttranspose;
7596   if (!fB) SETERRQ1(PETSC_ERR_SUP,"MatMatMultTranspose not supported for B of type %s",((PetscObject)B)->type_name);
7597   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);
7598 
7599   ierr = PetscLogEventBegin(MAT_MatMultTranspose,A,B,0,0);CHKERRQ(ierr);
7600   ierr = (*A->ops->matmulttranspose)(A,B,scall,fill,C);CHKERRQ(ierr);
7601   ierr = PetscLogEventEnd(MAT_MatMultTranspose,A,B,0,0);CHKERRQ(ierr);
7602 
7603   PetscFunctionReturn(0);
7604 }
7605 
7606 #undef __FUNCT__
7607 #define __FUNCT__ "MatGetRedundantMatrix"
7608 /*@C
7609    MatGetRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
7610 
7611    Collective on Mat
7612 
7613    Input Parameters:
7614 +  mat - the matrix
7615 .  nsubcomm - the number of subcommunicators (= number of redundant pareallel or sequential matrices)
7616 .  subcomm - MPI communicator split from the communicator where mat resides in
7617 .  mlocal_red - number of local rows of the redundant matrix
7618 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7619 
7620    Output Parameter:
7621 .  matredundant - redundant matrix
7622 
7623    Notes:
7624    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
7625    original matrix has not changed from that last call to MatGetRedundantMatrix().
7626 
7627    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
7628    calling it.
7629 
7630    Only MPIAIJ matrix is supported.
7631 
7632    Level: advanced
7633 
7634    Concepts: subcommunicator
7635    Concepts: duplicate matrix
7636 
7637 .seealso: MatDestroy()
7638 @*/
7639 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,PetscInt mlocal_red,MatReuse reuse,Mat *matredundant)
7640 {
7641   PetscErrorCode ierr;
7642 
7643   PetscFunctionBegin;
7644   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
7645   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
7646     PetscValidPointer(*matredundant,6);
7647     PetscValidHeaderSpecific(*matredundant,MAT_COOKIE,6);
7648   }
7649   if (!mat->ops->getredundantmatrix) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7650   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7651   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7652   ierr = MatPreallocated(mat);CHKERRQ(ierr);
7653 
7654   ierr = PetscLogEventBegin(MAT_GetRedundantMatrix,mat,0,0,0);CHKERRQ(ierr);
7655   ierr = (*mat->ops->getredundantmatrix)(mat,nsubcomm,subcomm,mlocal_red,reuse,matredundant);CHKERRQ(ierr);
7656   ierr = PetscLogEventEnd(MAT_GetRedundantMatrix,mat,0,0,0);CHKERRQ(ierr);
7657   PetscFunctionReturn(0);
7658 }
7659