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