xref: /petsc/src/mat/interface/matrix.c (revision ba2548482545e0f93fece6ba834d0f3e4d9b38b3)
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__ "MatGetLocalToGlobalMapping"
1771 /*@
1772    MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping()
1773 
1774    Not Collective
1775 
1776    Input Parameters:
1777 .  A - the matrix
1778 
1779    Output Parameters:
1780 + rmapping - row mapping
1781 - cmapping - column mapping
1782 
1783    Level: advanced
1784 
1785    Concepts: matrices^local to global mapping
1786    Concepts: local to global mapping^for matrices
1787 
1788 .seealso:  MatSetValuesLocal(), MatGetLocalToGlobalMappingBlock()
1789 @*/
1790 PetscErrorCode PETSCMAT_DLLEXPORT MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
1791 {
1792   PetscFunctionBegin;
1793   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
1794   PetscValidType(A,1);
1795   if (rmapping) PetscValidPointer(rmapping,2);
1796   if (cmapping) PetscValidPointer(cmapping,3);
1797   if (rmapping) *rmapping = A->rmapping;
1798   if (cmapping) *cmapping = A->cmapping;
1799   PetscFunctionReturn(0);
1800 }
1801 
1802 #undef __FUNCT__
1803 #define __FUNCT__ "MatGetLocalToGlobalMappingBlock"
1804 /*@
1805    MatGetLocalToGlobalMappingBlock - Gets the local-to-global numbering set by MatSetLocalToGlobalMappingBlock()
1806 
1807    Not Collective
1808 
1809    Input Parameters:
1810 .  A - the matrix
1811 
1812    Output Parameters:
1813 + rmapping - row mapping
1814 - cmapping - column mapping
1815 
1816    Level: advanced
1817 
1818    Concepts: matrices^local to global mapping blocked
1819    Concepts: local to global mapping^for matrices, blocked
1820 
1821 .seealso:  MatSetValuesBlockedLocal(), MatGetLocalToGlobalMapping()
1822 @*/
1823 PetscErrorCode PETSCMAT_DLLEXPORT MatGetLocalToGlobalMappingBlock(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
1824 {
1825   PetscFunctionBegin;
1826   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
1827   PetscValidType(A,1);
1828   if (rmapping) PetscValidPointer(rmapping,2);
1829   if (cmapping) PetscValidPointer(cmapping,3);
1830   if (rmapping) *rmapping = A->rbmapping;
1831   if (cmapping) *cmapping = A->cbmapping;
1832   PetscFunctionReturn(0);
1833 }
1834 
1835 #undef __FUNCT__
1836 #define __FUNCT__ "MatSetValuesLocal"
1837 /*@
1838    MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
1839    using a local ordering of the nodes.
1840 
1841    Not Collective
1842 
1843    Input Parameters:
1844 +  x - the matrix
1845 .  nrow, irow - number of rows and their local indices
1846 .  ncol, icol - number of columns and their local indices
1847 .  y -  a logically two-dimensional array of values
1848 -  addv - either INSERT_VALUES or ADD_VALUES, where
1849    ADD_VALUES adds values to any existing entries, and
1850    INSERT_VALUES replaces existing entries with new values
1851 
1852    Notes:
1853    Before calling MatSetValuesLocal(), the user must first set the
1854    local-to-global mapping by calling MatSetLocalToGlobalMapping().
1855 
1856    Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
1857    options cannot be mixed without intervening calls to the assembly
1858    routines.
1859 
1860    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1861    MUST be called after all calls to MatSetValuesLocal() have been completed.
1862 
1863    Level: intermediate
1864 
1865    Concepts: matrices^putting entries in with local numbering
1866 
1867 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
1868            MatSetValueLocal()
1869 @*/
1870 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
1871 {
1872   PetscErrorCode ierr;
1873   PetscInt       irowm[2048],icolm[2048];
1874 
1875   PetscFunctionBegin;
1876   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1877   PetscValidType(mat,1);
1878   if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */
1879   PetscValidIntPointer(irow,3);
1880   PetscValidIntPointer(icol,5);
1881   PetscValidScalarPointer(y,6);
1882   ierr = MatPreallocated(mat);CHKERRQ(ierr);
1883   if (mat->insertmode == NOT_SET_VALUES) {
1884     mat->insertmode = addv;
1885   }
1886 #if defined(PETSC_USE_DEBUG)
1887   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1888   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);
1889   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1890 #endif
1891 
1892   if (mat->assembled) {
1893     mat->was_assembled = PETSC_TRUE;
1894     mat->assembled     = PETSC_FALSE;
1895   }
1896   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1897   if (!mat->ops->setvalueslocal) {
1898     ierr = ISLocalToGlobalMappingApply(mat->rmapping,nrow,irow,irowm);CHKERRQ(ierr);
1899     ierr = ISLocalToGlobalMappingApply(mat->cmapping,ncol,icol,icolm);CHKERRQ(ierr);
1900     ierr = (*mat->ops->setvalues)(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
1901   } else {
1902     ierr = (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr);
1903   }
1904   mat->same_nonzero = PETSC_FALSE;
1905   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1906 #if defined(PETSC_HAVE_CUDA)
1907   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1908     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1909   }
1910 #endif
1911   PetscFunctionReturn(0);
1912 }
1913 
1914 #undef __FUNCT__
1915 #define __FUNCT__ "MatSetValuesBlockedLocal"
1916 /*@
1917    MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix,
1918    using a local ordering of the nodes a block at a time.
1919 
1920    Not Collective
1921 
1922    Input Parameters:
1923 +  x - the matrix
1924 .  nrow, irow - number of rows and their local indices
1925 .  ncol, icol - number of columns and their local indices
1926 .  y -  a logically two-dimensional array of values
1927 -  addv - either INSERT_VALUES or ADD_VALUES, where
1928    ADD_VALUES adds values to any existing entries, and
1929    INSERT_VALUES replaces existing entries with new values
1930 
1931    Notes:
1932    Before calling MatSetValuesBlockedLocal(), the user must first set the
1933    block size using MatSetBlockSize(), and the local-to-global mapping by
1934    calling MatSetLocalToGlobalMappingBlock(), where the mapping MUST be
1935    set for matrix blocks, not for matrix elements.
1936 
1937    Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
1938    options cannot be mixed without intervening calls to the assembly
1939    routines.
1940 
1941    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1942    MUST be called after all calls to MatSetValuesBlockedLocal() have been completed.
1943 
1944    Level: intermediate
1945 
1946    Concepts: matrices^putting blocked values in with local numbering
1947 
1948 .seealso:  MatSetBlockSize(), MatSetLocalToGlobalMappingBlock(), MatAssemblyBegin(), MatAssemblyEnd(),
1949            MatSetValuesLocal(), MatSetLocalToGlobalMappingBlock(), MatSetValuesBlocked()
1950 @*/
1951 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
1952 {
1953   PetscErrorCode ierr;
1954   PetscInt       irowm[2048],icolm[2048];
1955 
1956   PetscFunctionBegin;
1957   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1958   PetscValidType(mat,1);
1959   if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */
1960   PetscValidIntPointer(irow,3);
1961   PetscValidIntPointer(icol,5);
1962   PetscValidScalarPointer(y,6);
1963   ierr = MatPreallocated(mat);CHKERRQ(ierr);
1964   if (mat->insertmode == NOT_SET_VALUES) {
1965     mat->insertmode = addv;
1966   }
1967 #if defined(PETSC_USE_DEBUG)
1968   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1969   if (nrow > 2048 || ncol > 2048) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Number column/row indices must be <= 2048: are %D %D",nrow,ncol);
1970   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1971 #endif
1972 
1973   if (mat->assembled) {
1974     mat->was_assembled = PETSC_TRUE;
1975     mat->assembled     = PETSC_FALSE;
1976   }
1977   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1978   if (mat->ops->setvaluesblockedlocal) {
1979     ierr = (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr);
1980   } else if (mat->rbmapping && mat->cbmapping) {
1981     ierr = ISLocalToGlobalMappingApply(mat->rbmapping,nrow,irow,irowm);CHKERRQ(ierr);
1982     ierr = ISLocalToGlobalMappingApply(mat->cbmapping,ncol,icol,icolm);CHKERRQ(ierr);
1983     if (mat->ops->setvaluesblocked) {
1984       ierr = (*mat->ops->setvaluesblocked)(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
1985     } else {
1986       PetscInt buf[4096],*ibufm=0,*ibufn=0;
1987       PetscInt i,j,*iirowm,*iicolm,bs=mat->rmap->bs;
1988       if ((nrow+ncol)*bs <= 4096) {
1989         iirowm = buf; iicolm = buf + nrow*bs;
1990       } else {
1991         ierr = PetscMalloc2(nrow*bs,PetscInt,&ibufm,ncol*bs,PetscInt,&ibufn);CHKERRQ(ierr);
1992         iirowm = ibufm; iicolm = ibufn;
1993       }
1994       for (i=0; i<nrow; i++) {
1995         for (j=0; j<bs; j++) {
1996           iirowm[i*bs+j] = bs*irowm[i] + j;
1997         }
1998       }
1999       for (i=0; i<ncol; i++) {
2000         for (j=0; j<bs; j++) {
2001           iicolm[i*bs+j] = bs*icolm[i] + j;
2002         }
2003       }
2004       ierr = MatSetValues(mat,bs*nrow,iirowm,bs*ncol,iicolm,y,addv);CHKERRQ(ierr);
2005       ierr = PetscFree2(ibufm,ibufn);CHKERRQ(ierr);
2006     }
2007   } else {
2008     PetscInt buf[4096],*ibufm=0,*ibufn=0;
2009     PetscInt i,j,*iirowm,*iicolm,bs=mat->rmap->bs;
2010     if ((nrow+ncol)*bs <= 4096) {
2011       iirowm = buf; iicolm = buf + nrow*bs;
2012     } else {
2013       ierr = PetscMalloc2(nrow*bs,PetscInt,&ibufm,ncol*bs,PetscInt,&ibufn);CHKERRQ(ierr);
2014       iirowm = ibufm; iicolm = ibufn;
2015     }
2016     for (i=0; i<nrow; i++) {
2017       for (j=0; j<bs; j++) iirowm[i*bs+j] = irow[i]*bs+j;
2018     }
2019     for (i=0; i<ncol; i++) {
2020       for (j=0; j<bs; j++) iicolm[i*bs+j] = icol[i]*bs+j;
2021     }
2022     ierr = MatSetValuesLocal(mat,nrow*bs,iirowm,ncol*bs,iicolm,y,addv);CHKERRQ(ierr);
2023     ierr = PetscFree2(ibufm,ibufn);CHKERRQ(ierr);
2024   }
2025   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2026 #if defined(PETSC_HAVE_CUDA)
2027   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
2028     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
2029   }
2030 #endif
2031   PetscFunctionReturn(0);
2032 }
2033 
2034 #undef __FUNCT__
2035 #define __FUNCT__ "MatMultDiagonalBlock"
2036 /*@
2037    MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal
2038 
2039    Collective on Mat and Vec
2040 
2041    Input Parameters:
2042 +  mat - the matrix
2043 -  x   - the vector to be multiplied
2044 
2045    Output Parameters:
2046 .  y - the result
2047 
2048    Notes:
2049    The vectors x and y cannot be the same.  I.e., one cannot
2050    call MatMult(A,y,y).
2051 
2052    Level: developer
2053 
2054    Concepts: matrix-vector product
2055 
2056 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2057 @*/
2058 PetscErrorCode PETSCMAT_DLLEXPORT MatMultDiagonalBlock(Mat mat,Vec x,Vec y)
2059 {
2060   PetscErrorCode ierr;
2061 
2062   PetscFunctionBegin;
2063   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2064   PetscValidType(mat,1);
2065   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2066   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2067 
2068   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2069   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2070   if (x == y) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2071   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2072 
2073   if (!mat->ops->multdiagonalblock) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2074   ierr = (*mat->ops->multdiagonalblock)(mat,x,y);CHKERRQ(ierr);
2075   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2076   PetscFunctionReturn(0);
2077 }
2078 
2079 /* --------------------------------------------------------*/
2080 #undef __FUNCT__
2081 #define __FUNCT__ "MatMult"
2082 /*@
2083    MatMult - Computes the matrix-vector product, y = Ax.
2084 
2085    Neighbor-wise Collective on Mat and Vec
2086 
2087    Input Parameters:
2088 +  mat - the matrix
2089 -  x   - the vector to be multiplied
2090 
2091    Output Parameters:
2092 .  y - the result
2093 
2094    Notes:
2095    The vectors x and y cannot be the same.  I.e., one cannot
2096    call MatMult(A,y,y).
2097 
2098    Level: beginner
2099 
2100    Concepts: matrix-vector product
2101 
2102 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2103 @*/
2104 PetscErrorCode PETSCMAT_DLLEXPORT MatMult(Mat mat,Vec x,Vec y)
2105 {
2106   PetscErrorCode ierr;
2107 
2108   PetscFunctionBegin;
2109   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2110   PetscValidType(mat,1);
2111   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2112   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2113 
2114   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2115   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2116   if (x == y) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2117 #ifndef PETSC_HAVE_CONSTRAINTS
2118   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);
2119   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);
2120   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);
2121 #endif
2122   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2123 
2124   if (mat->nullsp) {
2125     ierr = MatNullSpaceRemove(mat->nullsp,x,&x);CHKERRQ(ierr);
2126   }
2127 
2128   if (!mat->ops->mult) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2129   ierr = PetscLogEventBegin(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
2130   ierr = (*mat->ops->mult)(mat,x,y);CHKERRQ(ierr);
2131   ierr = PetscLogEventEnd(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
2132 
2133   if (mat->nullsp) {
2134     ierr = MatNullSpaceRemove(mat->nullsp,y,PETSC_NULL);CHKERRQ(ierr);
2135   }
2136   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2137   PetscFunctionReturn(0);
2138 }
2139 
2140 #undef __FUNCT__
2141 #define __FUNCT__ "MatMultTranspose"
2142 /*@
2143    MatMultTranspose - Computes matrix transpose times a vector.
2144 
2145    Neighbor-wise Collective on Mat and Vec
2146 
2147    Input Parameters:
2148 +  mat - the matrix
2149 -  x   - the vector to be multilplied
2150 
2151    Output Parameters:
2152 .  y - the result
2153 
2154    Notes:
2155    The vectors x and y cannot be the same.  I.e., one cannot
2156    call MatMultTranspose(A,y,y).
2157 
2158    Level: beginner
2159 
2160    Concepts: matrix vector product^transpose
2161 
2162 .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd()
2163 @*/
2164 PetscErrorCode PETSCMAT_DLLEXPORT MatMultTranspose(Mat mat,Vec x,Vec y)
2165 {
2166   PetscErrorCode ierr;
2167 
2168   PetscFunctionBegin;
2169   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2170   PetscValidType(mat,1);
2171   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2172   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2173 
2174   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2175   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2176   if (x == y) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2177 #ifndef PETSC_HAVE_CONSTRAINTS
2178   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);
2179   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);
2180 #endif
2181   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2182 
2183   if (!mat->ops->multtranspose) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"This matrix type does not have a multiply tranpose defined");
2184   ierr = PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
2185   ierr = (*mat->ops->multtranspose)(mat,x,y);CHKERRQ(ierr);
2186   ierr = PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
2187   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2188   PetscFunctionReturn(0);
2189 }
2190 
2191 #undef __FUNCT__
2192 #define __FUNCT__ "MatMultHermitianTranspose"
2193 /*@
2194    MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.
2195 
2196    Neighbor-wise Collective on Mat and Vec
2197 
2198    Input Parameters:
2199 +  mat - the matrix
2200 -  x   - the vector to be multilplied
2201 
2202    Output Parameters:
2203 .  y - the result
2204 
2205    Notes:
2206    The vectors x and y cannot be the same.  I.e., one cannot
2207    call MatMultHermitianTranspose(A,y,y).
2208 
2209    Level: beginner
2210 
2211    Concepts: matrix vector product^transpose
2212 
2213 .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose()
2214 @*/
2215 PetscErrorCode PETSCMAT_DLLEXPORT MatMultHermitianTranspose(Mat mat,Vec x,Vec y)
2216 {
2217   PetscErrorCode ierr;
2218 
2219   PetscFunctionBegin;
2220   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2221   PetscValidType(mat,1);
2222   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2223   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2224 
2225   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2226   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2227   if (x == y) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2228 #ifndef PETSC_HAVE_CONSTRAINTS
2229   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);
2230   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);
2231 #endif
2232   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2233 
2234   if (!mat->ops->multhermitiantranspose) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2235   ierr = PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr);
2236   ierr = (*mat->ops->multhermitiantranspose)(mat,x,y);CHKERRQ(ierr);
2237   ierr = PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr);
2238   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2239   PetscFunctionReturn(0);
2240 }
2241 
2242 #undef __FUNCT__
2243 #define __FUNCT__ "MatMultAdd"
2244 /*@
2245     MatMultAdd -  Computes v3 = v2 + A * v1.
2246 
2247     Neighbor-wise Collective on Mat and Vec
2248 
2249     Input Parameters:
2250 +   mat - the matrix
2251 -   v1, v2 - the vectors
2252 
2253     Output Parameters:
2254 .   v3 - the result
2255 
2256     Notes:
2257     The vectors v1 and v3 cannot be the same.  I.e., one cannot
2258     call MatMultAdd(A,v1,v2,v1).
2259 
2260     Level: beginner
2261 
2262     Concepts: matrix vector product^addition
2263 
2264 .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
2265 @*/
2266 PetscErrorCode PETSCMAT_DLLEXPORT MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2267 {
2268   PetscErrorCode ierr;
2269 
2270   PetscFunctionBegin;
2271   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2272   PetscValidType(mat,1);
2273   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2274   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2275   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2276 
2277   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2278   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2279   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);
2280   /* 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);
2281      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); */
2282   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);
2283   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);
2284   if (v1 == v3) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2285   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2286 
2287   ierr = PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2288   ierr = (*mat->ops->multadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2289   ierr = PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2290   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2291   PetscFunctionReturn(0);
2292 }
2293 
2294 #undef __FUNCT__
2295 #define __FUNCT__ "MatMultTransposeAdd"
2296 /*@
2297    MatMultTransposeAdd - Computes v3 = v2 + A' * v1.
2298 
2299    Neighbor-wise Collective on Mat and Vec
2300 
2301    Input Parameters:
2302 +  mat - the matrix
2303 -  v1, v2 - the vectors
2304 
2305    Output Parameters:
2306 .  v3 - the result
2307 
2308    Notes:
2309    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2310    call MatMultTransposeAdd(A,v1,v2,v1).
2311 
2312    Level: beginner
2313 
2314    Concepts: matrix vector product^transpose and addition
2315 
2316 .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
2317 @*/
2318 PetscErrorCode PETSCMAT_DLLEXPORT MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2319 {
2320   PetscErrorCode ierr;
2321 
2322   PetscFunctionBegin;
2323   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2324   PetscValidType(mat,1);
2325   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2326   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2327   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2328 
2329   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2330   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2331   if (!mat->ops->multtransposeadd) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2332   if (v1 == v3) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2333   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);
2334   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);
2335   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);
2336   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2337 
2338   ierr = PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2339   ierr = (*mat->ops->multtransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2340   ierr = PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2341   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2342   PetscFunctionReturn(0);
2343 }
2344 
2345 #undef __FUNCT__
2346 #define __FUNCT__ "MatMultHermitianTransposeAdd"
2347 /*@
2348    MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1.
2349 
2350    Neighbor-wise Collective on Mat and Vec
2351 
2352    Input Parameters:
2353 +  mat - the matrix
2354 -  v1, v2 - the vectors
2355 
2356    Output Parameters:
2357 .  v3 - the result
2358 
2359    Notes:
2360    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2361    call MatMultHermitianTransposeAdd(A,v1,v2,v1).
2362 
2363    Level: beginner
2364 
2365    Concepts: matrix vector product^transpose and addition
2366 
2367 .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult()
2368 @*/
2369 PetscErrorCode PETSCMAT_DLLEXPORT MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2370 {
2371   PetscErrorCode ierr;
2372 
2373   PetscFunctionBegin;
2374   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2375   PetscValidType(mat,1);
2376   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2377   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2378   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2379 
2380   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2381   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2382   if (!mat->ops->multhermitiantransposeadd) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2383   if (v1 == v3) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2384   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);
2385   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);
2386   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);
2387   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2388 
2389   ierr = PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2390   ierr = (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2391   ierr = PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2392   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2393   PetscFunctionReturn(0);
2394 }
2395 
2396 #undef __FUNCT__
2397 #define __FUNCT__ "MatMultConstrained"
2398 /*@
2399    MatMultConstrained - The inner multiplication routine for a
2400    constrained matrix P^T A P.
2401 
2402    Neighbor-wise Collective on Mat and Vec
2403 
2404    Input Parameters:
2405 +  mat - the matrix
2406 -  x   - the vector to be multilplied
2407 
2408    Output Parameters:
2409 .  y - the result
2410 
2411    Notes:
2412    The vectors x and y cannot be the same.  I.e., one cannot
2413    call MatMult(A,y,y).
2414 
2415    Level: beginner
2416 
2417 .keywords: matrix, multiply, matrix-vector product, constraint
2418 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2419 @*/
2420 PetscErrorCode PETSCMAT_DLLEXPORT MatMultConstrained(Mat mat,Vec x,Vec y)
2421 {
2422   PetscErrorCode ierr;
2423 
2424   PetscFunctionBegin;
2425   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2426   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2427   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2428   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2429   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2430   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2431   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);
2432   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);
2433   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);
2434 
2435   ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2436   ierr = (*mat->ops->multconstrained)(mat,x,y);CHKERRQ(ierr);
2437   ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2438   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2439 
2440   PetscFunctionReturn(0);
2441 }
2442 
2443 #undef __FUNCT__
2444 #define __FUNCT__ "MatMultTransposeConstrained"
2445 /*@
2446    MatMultTransposeConstrained - The inner multiplication routine for a
2447    constrained matrix P^T A^T P.
2448 
2449    Neighbor-wise Collective on Mat and Vec
2450 
2451    Input Parameters:
2452 +  mat - the matrix
2453 -  x   - the vector to be multilplied
2454 
2455    Output Parameters:
2456 .  y - the result
2457 
2458    Notes:
2459    The vectors x and y cannot be the same.  I.e., one cannot
2460    call MatMult(A,y,y).
2461 
2462    Level: beginner
2463 
2464 .keywords: matrix, multiply, matrix-vector product, constraint
2465 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2466 @*/
2467 PetscErrorCode PETSCMAT_DLLEXPORT MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2468 {
2469   PetscErrorCode ierr;
2470 
2471   PetscFunctionBegin;
2472   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2473   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2474   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2475   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2476   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2477   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2478   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);
2479   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);
2480 
2481   ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2482   ierr = (*mat->ops->multtransposeconstrained)(mat,x,y);CHKERRQ(ierr);
2483   ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2484   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2485 
2486   PetscFunctionReturn(0);
2487 }
2488 
2489 #undef __FUNCT__
2490 #define __FUNCT__ "MatGetFactorType"
2491 /*@C
2492    MatGetFactorType - gets the type of factorization it is
2493 
2494    Note Collective
2495    as the flag
2496 
2497    Input Parameters:
2498 .  mat - the matrix
2499 
2500    Output Parameters:
2501 .  t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT
2502 
2503     Level: intermediate
2504 
2505 .seealso:    MatFactorType, MatGetFactor()
2506 @*/
2507 PetscErrorCode PETSCMAT_DLLEXPORT MatGetFactorType(Mat mat,MatFactorType *t)
2508 {
2509   PetscFunctionBegin;
2510   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2511   PetscValidType(mat,1);
2512   *t = mat->factortype;
2513   PetscFunctionReturn(0);
2514 }
2515 
2516 /* ------------------------------------------------------------*/
2517 #undef __FUNCT__
2518 #define __FUNCT__ "MatGetInfo"
2519 /*@C
2520    MatGetInfo - Returns information about matrix storage (number of
2521    nonzeros, memory, etc.).
2522 
2523    Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag
2524 
2525    Input Parameters:
2526 .  mat - the matrix
2527 
2528    Output Parameters:
2529 +  flag - flag indicating the type of parameters to be returned
2530    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2531    MAT_GLOBAL_SUM - sum over all processors)
2532 -  info - matrix information context
2533 
2534    Notes:
2535    The MatInfo context contains a variety of matrix data, including
2536    number of nonzeros allocated and used, number of mallocs during
2537    matrix assembly, etc.  Additional information for factored matrices
2538    is provided (such as the fill ratio, number of mallocs during
2539    factorization, etc.).  Much of this info is printed to PETSC_STDOUT
2540    when using the runtime options
2541 $       -info -mat_view_info
2542 
2543    Example for C/C++ Users:
2544    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2545    data within the MatInfo context.  For example,
2546 .vb
2547       MatInfo info;
2548       Mat     A;
2549       double  mal, nz_a, nz_u;
2550 
2551       MatGetInfo(A,MAT_LOCAL,&info);
2552       mal  = info.mallocs;
2553       nz_a = info.nz_allocated;
2554 .ve
2555 
2556    Example for Fortran Users:
2557    Fortran users should declare info as a double precision
2558    array of dimension MAT_INFO_SIZE, and then extract the parameters
2559    of interest.  See the file ${PETSC_DIR}/include/finclude/petscmat.h
2560    a complete list of parameter names.
2561 .vb
2562       double  precision info(MAT_INFO_SIZE)
2563       double  precision mal, nz_a
2564       Mat     A
2565       integer ierr
2566 
2567       call MatGetInfo(A,MAT_LOCAL,info,ierr)
2568       mal = info(MAT_INFO_MALLOCS)
2569       nz_a = info(MAT_INFO_NZ_ALLOCATED)
2570 .ve
2571 
2572     Level: intermediate
2573 
2574     Concepts: matrices^getting information on
2575 
2576     Developer Note: fortran interface is not autogenerated as the f90
2577     interface defintion cannot be generated correctly [due to MatInfo]
2578 
2579 @*/
2580 PetscErrorCode PETSCMAT_DLLEXPORT MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2581 {
2582   PetscErrorCode ierr;
2583 
2584   PetscFunctionBegin;
2585   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2586   PetscValidType(mat,1);
2587   PetscValidPointer(info,3);
2588   if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2589   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2590   ierr = (*mat->ops->getinfo)(mat,flag,info);CHKERRQ(ierr);
2591   PetscFunctionReturn(0);
2592 }
2593 
2594 /* ----------------------------------------------------------*/
2595 
2596 #undef __FUNCT__
2597 #define __FUNCT__ "MatLUFactor"
2598 /*@C
2599    MatLUFactor - Performs in-place LU factorization of matrix.
2600 
2601    Collective on Mat
2602 
2603    Input Parameters:
2604 +  mat - the matrix
2605 .  row - row permutation
2606 .  col - column permutation
2607 -  info - options for factorization, includes
2608 $          fill - expected fill as ratio of original fill.
2609 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2610 $                   Run with the option -info to determine an optimal value to use
2611 
2612    Notes:
2613    Most users should employ the simplified KSP interface for linear solvers
2614    instead of working directly with matrix algebra routines such as this.
2615    See, e.g., KSPCreate().
2616 
2617    This changes the state of the matrix to a factored matrix; it cannot be used
2618    for example with MatSetValues() unless one first calls MatSetUnfactored().
2619 
2620    Level: developer
2621 
2622    Concepts: matrices^LU factorization
2623 
2624 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2625           MatGetOrdering(), MatSetUnfactored(), MatFactorInfo
2626 
2627     Developer Note: fortran interface is not autogenerated as the f90
2628     interface defintion cannot be generated correctly [due to MatFactorInfo]
2629 
2630 @*/
2631 PetscErrorCode PETSCMAT_DLLEXPORT MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2632 {
2633   PetscErrorCode ierr;
2634 
2635   PetscFunctionBegin;
2636   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2637   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
2638   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
2639   PetscValidPointer(info,4);
2640   PetscValidType(mat,1);
2641   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2642   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2643   if (!mat->ops->lufactor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2644   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2645 
2646   ierr = PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
2647   ierr = (*mat->ops->lufactor)(mat,row,col,info);CHKERRQ(ierr);
2648   ierr = PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
2649   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
2650   PetscFunctionReturn(0);
2651 }
2652 
2653 #undef __FUNCT__
2654 #define __FUNCT__ "MatILUFactor"
2655 /*@C
2656    MatILUFactor - Performs in-place ILU factorization of matrix.
2657 
2658    Collective on Mat
2659 
2660    Input Parameters:
2661 +  mat - the matrix
2662 .  row - row permutation
2663 .  col - column permutation
2664 -  info - structure containing
2665 $      levels - number of levels of fill.
2666 $      expected fill - as ratio of original fill.
2667 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2668                 missing diagonal entries)
2669 
2670    Notes:
2671    Probably really in-place only when level of fill is zero, otherwise allocates
2672    new space to store factored matrix and deletes previous memory.
2673 
2674    Most users should employ the simplified KSP interface for linear solvers
2675    instead of working directly with matrix algebra routines such as this.
2676    See, e.g., KSPCreate().
2677 
2678    Level: developer
2679 
2680    Concepts: matrices^ILU factorization
2681 
2682 .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
2683 
2684     Developer Note: fortran interface is not autogenerated as the f90
2685     interface defintion cannot be generated correctly [due to MatFactorInfo]
2686 
2687 @*/
2688 PetscErrorCode PETSCMAT_DLLEXPORT MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2689 {
2690   PetscErrorCode ierr;
2691 
2692   PetscFunctionBegin;
2693   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2694   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
2695   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
2696   PetscValidPointer(info,4);
2697   PetscValidType(mat,1);
2698   if (mat->rmap->N != mat->cmap->N) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONG,"matrix must be square");
2699   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2700   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2701   if (!mat->ops->ilufactor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2702   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2703 
2704   ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
2705   ierr = (*mat->ops->ilufactor)(mat,row,col,info);CHKERRQ(ierr);
2706   ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
2707   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
2708   PetscFunctionReturn(0);
2709 }
2710 
2711 #undef __FUNCT__
2712 #define __FUNCT__ "MatLUFactorSymbolic"
2713 /*@C
2714    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
2715    Call this routine before calling MatLUFactorNumeric().
2716 
2717    Collective on Mat
2718 
2719    Input Parameters:
2720 +  fact - the factor matrix obtained with MatGetFactor()
2721 .  mat - the matrix
2722 .  row, col - row and column permutations
2723 -  info - options for factorization, includes
2724 $          fill - expected fill as ratio of original fill.
2725 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2726 $                   Run with the option -info to determine an optimal value to use
2727 
2728 
2729    Notes:
2730    See the <a href="../../docs/manual.pdf">users manual</a> for additional information about
2731    choosing the fill factor for better efficiency.
2732 
2733    Most users should employ the simplified KSP interface for linear solvers
2734    instead of working directly with matrix algebra routines such as this.
2735    See, e.g., KSPCreate().
2736 
2737    Level: developer
2738 
2739    Concepts: matrices^LU symbolic factorization
2740 
2741 .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
2742 
2743     Developer Note: fortran interface is not autogenerated as the f90
2744     interface defintion cannot be generated correctly [due to MatFactorInfo]
2745 
2746 @*/
2747 PetscErrorCode PETSCMAT_DLLEXPORT MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
2748 {
2749   PetscErrorCode ierr;
2750 
2751   PetscFunctionBegin;
2752   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2753   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
2754   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
2755   PetscValidPointer(info,4);
2756   PetscValidType(mat,1);
2757   PetscValidPointer(fact,5);
2758   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2759   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2760   if (!(fact)->ops->lufactorsymbolic) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s  symbolic LU",((PetscObject)mat)->type_name);
2761   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2762 
2763   ierr = PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
2764   ierr = (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
2765   ierr = PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
2766   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
2767   PetscFunctionReturn(0);
2768 }
2769 
2770 #undef __FUNCT__
2771 #define __FUNCT__ "MatLUFactorNumeric"
2772 /*@C
2773    MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
2774    Call this routine after first calling MatLUFactorSymbolic().
2775 
2776    Collective on Mat
2777 
2778    Input Parameters:
2779 +  fact - the factor matrix obtained with MatGetFactor()
2780 .  mat - the matrix
2781 -  info - options for factorization
2782 
2783    Notes:
2784    See MatLUFactor() for in-place factorization.  See
2785    MatCholeskyFactorNumeric() for the symmetric, positive definite case.
2786 
2787    Most users should employ the simplified KSP interface for linear solvers
2788    instead of working directly with matrix algebra routines such as this.
2789    See, e.g., KSPCreate().
2790 
2791    Level: developer
2792 
2793    Concepts: matrices^LU numeric factorization
2794 
2795 .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()
2796 
2797     Developer Note: fortran interface is not autogenerated as the f90
2798     interface defintion cannot be generated correctly [due to MatFactorInfo]
2799 
2800 @*/
2801 PetscErrorCode PETSCMAT_DLLEXPORT MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
2802 {
2803   PetscErrorCode ierr;
2804 
2805   PetscFunctionBegin;
2806   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2807   PetscValidType(mat,1);
2808   PetscValidPointer(fact,2);
2809   PetscValidHeaderSpecific(fact,MAT_CLASSID,2);
2810   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2811   if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) {
2812     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);
2813   }
2814   if (!(fact)->ops->lufactornumeric) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name);
2815   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2816   ierr = PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
2817   ierr = (fact->ops->lufactornumeric)(fact,mat,info);CHKERRQ(ierr);
2818   ierr = PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
2819 
2820   ierr = MatView_Private(fact);CHKERRQ(ierr);
2821   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
2822   PetscFunctionReturn(0);
2823 }
2824 
2825 #undef __FUNCT__
2826 #define __FUNCT__ "MatCholeskyFactor"
2827 /*@C
2828    MatCholeskyFactor - Performs in-place Cholesky factorization of a
2829    symmetric matrix.
2830 
2831    Collective on Mat
2832 
2833    Input Parameters:
2834 +  mat - the matrix
2835 .  perm - row and column permutations
2836 -  f - expected fill as ratio of original fill
2837 
2838    Notes:
2839    See MatLUFactor() for the nonsymmetric case.  See also
2840    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().
2841 
2842    Most users should employ the simplified KSP interface for linear solvers
2843    instead of working directly with matrix algebra routines such as this.
2844    See, e.g., KSPCreate().
2845 
2846    Level: developer
2847 
2848    Concepts: matrices^Cholesky factorization
2849 
2850 .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
2851           MatGetOrdering()
2852 
2853     Developer Note: fortran interface is not autogenerated as the f90
2854     interface defintion cannot be generated correctly [due to MatFactorInfo]
2855 
2856 @*/
2857 PetscErrorCode PETSCMAT_DLLEXPORT MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
2858 {
2859   PetscErrorCode ierr;
2860 
2861   PetscFunctionBegin;
2862   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2863   PetscValidType(mat,1);
2864   PetscValidHeaderSpecific(perm,IS_CLASSID,2);
2865   PetscValidPointer(info,3);
2866   if (mat->rmap->N != mat->cmap->N) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONG,"Matrix must be square");
2867   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2868   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2869   if (!mat->ops->choleskyfactor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2870   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2871 
2872   ierr = PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
2873   ierr = (*mat->ops->choleskyfactor)(mat,perm,info);CHKERRQ(ierr);
2874   ierr = PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
2875   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
2876   PetscFunctionReturn(0);
2877 }
2878 
2879 #undef __FUNCT__
2880 #define __FUNCT__ "MatCholeskyFactorSymbolic"
2881 /*@C
2882    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
2883    of a symmetric matrix.
2884 
2885    Collective on Mat
2886 
2887    Input Parameters:
2888 +  fact - the factor matrix obtained with MatGetFactor()
2889 .  mat - the matrix
2890 .  perm - row and column permutations
2891 -  info - options for factorization, includes
2892 $          fill - expected fill as ratio of original fill.
2893 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2894 $                   Run with the option -info to determine an optimal value to use
2895 
2896    Notes:
2897    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
2898    MatCholeskyFactor() and MatCholeskyFactorNumeric().
2899 
2900    Most users should employ the simplified KSP interface for linear solvers
2901    instead of working directly with matrix algebra routines such as this.
2902    See, e.g., KSPCreate().
2903 
2904    Level: developer
2905 
2906    Concepts: matrices^Cholesky symbolic factorization
2907 
2908 .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
2909           MatGetOrdering()
2910 
2911     Developer Note: fortran interface is not autogenerated as the f90
2912     interface defintion cannot be generated correctly [due to MatFactorInfo]
2913 
2914 @*/
2915 PetscErrorCode PETSCMAT_DLLEXPORT MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
2916 {
2917   PetscErrorCode ierr;
2918 
2919   PetscFunctionBegin;
2920   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2921   PetscValidType(mat,1);
2922   if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2);
2923   PetscValidPointer(info,3);
2924   PetscValidPointer(fact,4);
2925   if (mat->rmap->N != mat->cmap->N) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONG,"Matrix must be square");
2926   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2927   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2928   if (!(fact)->ops->choleskyfactorsymbolic) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky",((PetscObject)mat)->type_name);
2929   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2930 
2931   ierr = PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
2932   ierr = (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
2933   ierr = PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
2934   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
2935   PetscFunctionReturn(0);
2936 }
2937 
2938 #undef __FUNCT__
2939 #define __FUNCT__ "MatCholeskyFactorNumeric"
2940 /*@C
2941    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
2942    of a symmetric matrix. Call this routine after first calling
2943    MatCholeskyFactorSymbolic().
2944 
2945    Collective on Mat
2946 
2947    Input Parameters:
2948 +  fact - the factor matrix obtained with MatGetFactor()
2949 .  mat - the initial matrix
2950 .  info - options for factorization
2951 -  fact - the symbolic factor of mat
2952 
2953 
2954    Notes:
2955    Most users should employ the simplified KSP interface for linear solvers
2956    instead of working directly with matrix algebra routines such as this.
2957    See, e.g., KSPCreate().
2958 
2959    Level: developer
2960 
2961    Concepts: matrices^Cholesky numeric factorization
2962 
2963 .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
2964 
2965     Developer Note: fortran interface is not autogenerated as the f90
2966     interface defintion cannot be generated correctly [due to MatFactorInfo]
2967 
2968 @*/
2969 PetscErrorCode PETSCMAT_DLLEXPORT MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
2970 {
2971   PetscErrorCode ierr;
2972 
2973   PetscFunctionBegin;
2974   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2975   PetscValidType(mat,1);
2976   PetscValidPointer(fact,2);
2977   PetscValidHeaderSpecific(fact,MAT_CLASSID,2);
2978   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2979   if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name);
2980   if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) {
2981     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);
2982   }
2983   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2984 
2985   ierr = PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
2986   ierr = (fact->ops->choleskyfactornumeric)(fact,mat,info);CHKERRQ(ierr);
2987   ierr = PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
2988 
2989   ierr = MatView_Private(fact);CHKERRQ(ierr);
2990   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
2991   PetscFunctionReturn(0);
2992 }
2993 
2994 /* ----------------------------------------------------------------*/
2995 #undef __FUNCT__
2996 #define __FUNCT__ "MatSolve"
2997 /*@
2998    MatSolve - Solves A x = b, given a factored matrix.
2999 
3000    Neighbor-wise Collective on Mat and Vec
3001 
3002    Input Parameters:
3003 +  mat - the factored matrix
3004 -  b - the right-hand-side vector
3005 
3006    Output Parameter:
3007 .  x - the result vector
3008 
3009    Notes:
3010    The vectors b and x cannot be the same.  I.e., one cannot
3011    call MatSolve(A,x,x).
3012 
3013    Notes:
3014    Most users should employ the simplified KSP interface for linear solvers
3015    instead of working directly with matrix algebra routines such as this.
3016    See, e.g., KSPCreate().
3017 
3018    Level: developer
3019 
3020    Concepts: matrices^triangular solves
3021 
3022 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
3023 @*/
3024 PetscErrorCode PETSCMAT_DLLEXPORT MatSolve(Mat mat,Vec b,Vec x)
3025 {
3026   PetscErrorCode ierr;
3027 
3028   PetscFunctionBegin;
3029   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3030   PetscValidType(mat,1);
3031   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3032   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3033   PetscCheckSameComm(mat,1,b,2);
3034   PetscCheckSameComm(mat,1,x,3);
3035   if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3036   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3037   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);
3038   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);
3039   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);
3040   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3041   if (!mat->ops->solve) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3042   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3043 
3044   ierr = PetscLogEventBegin(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
3045   ierr = (*mat->ops->solve)(mat,b,x);CHKERRQ(ierr);
3046   ierr = PetscLogEventEnd(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
3047   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3048   PetscFunctionReturn(0);
3049 }
3050 
3051 #undef __FUNCT__
3052 #define __FUNCT__ "MatMatSolve_Basic"
3053 PetscErrorCode PETSCMAT_DLLEXPORT MatMatSolve_Basic(Mat A,Mat B,Mat X)
3054 {
3055   PetscErrorCode ierr;
3056   Vec            b,x;
3057   PetscInt       m,N,i;
3058   PetscScalar    *bb,*xx;
3059 
3060   PetscFunctionBegin;
3061   ierr = MatGetArray(B,&bb);CHKERRQ(ierr);
3062   ierr = MatGetArray(X,&xx);CHKERRQ(ierr);
3063   ierr = MatGetLocalSize(B,&m,PETSC_NULL);CHKERRQ(ierr);  /* number local rows */
3064   ierr = MatGetSize(B,PETSC_NULL,&N);CHKERRQ(ierr);       /* total columns in dense matrix */
3065   ierr = MatGetVecs(A,&x,&b);CHKERRQ(ierr);
3066   for (i=0; i<N; i++) {
3067     ierr = VecPlaceArray(b,bb + i*m);CHKERRQ(ierr);
3068     ierr = VecPlaceArray(x,xx + i*m);CHKERRQ(ierr);
3069     ierr = MatSolve(A,b,x);CHKERRQ(ierr);
3070     ierr = VecResetArray(x);CHKERRQ(ierr);
3071     ierr = VecResetArray(b);CHKERRQ(ierr);
3072   }
3073   ierr = VecDestroy(b);CHKERRQ(ierr);
3074   ierr = VecDestroy(x);CHKERRQ(ierr);
3075   ierr = MatRestoreArray(B,&bb);CHKERRQ(ierr);
3076   ierr = MatRestoreArray(X,&xx);CHKERRQ(ierr);
3077   PetscFunctionReturn(0);
3078 }
3079 
3080 #undef __FUNCT__
3081 #define __FUNCT__ "MatMatSolve"
3082 /*@
3083    MatMatSolve - Solves A X = B, given a factored matrix.
3084 
3085    Neighbor-wise Collective on Mat
3086 
3087    Input Parameters:
3088 +  mat - the factored matrix
3089 -  B - the right-hand-side matrix  (dense matrix)
3090 
3091    Output Parameter:
3092 .  X - the result matrix (dense matrix)
3093 
3094    Notes:
3095    The matrices b and x cannot be the same.  I.e., one cannot
3096    call MatMatSolve(A,x,x).
3097 
3098    Notes:
3099    Most users should usually employ the simplified KSP interface for linear solvers
3100    instead of working directly with matrix algebra routines such as this.
3101    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3102    at a time.
3103 
3104    Level: developer
3105 
3106    Concepts: matrices^triangular solves
3107 
3108 .seealso: MatMatSolveAdd(), MatMatSolveTranspose(), MatMatSolveTransposeAdd(), MatLUFactor(), MatCholeskyFactor()
3109 @*/
3110 PetscErrorCode PETSCMAT_DLLEXPORT MatMatSolve(Mat A,Mat B,Mat X)
3111 {
3112   PetscErrorCode ierr;
3113 
3114   PetscFunctionBegin;
3115   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3116   PetscValidType(A,1);
3117   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3118   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3119   PetscCheckSameComm(A,1,B,2);
3120   PetscCheckSameComm(A,1,X,3);
3121   if (X == B) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3122   if (!A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3123   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);
3124   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);
3125   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);
3126   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3127   ierr = MatPreallocated(A);CHKERRQ(ierr);
3128 
3129   ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3130   if (!A->ops->matsolve) {
3131     ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolve",((PetscObject)A)->type_name);CHKERRQ(ierr);
3132     ierr = MatMatSolve_Basic(A,B,X);CHKERRQ(ierr);
3133   } else {
3134     ierr = (*A->ops->matsolve)(A,B,X);CHKERRQ(ierr);
3135   }
3136   ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3137   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3138   PetscFunctionReturn(0);
3139 }
3140 
3141 
3142 #undef __FUNCT__
3143 #define __FUNCT__ "MatForwardSolve"
3144 /*@
3145    MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or
3146                             U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U,
3147 
3148    Neighbor-wise Collective on Mat and Vec
3149 
3150    Input Parameters:
3151 +  mat - the factored matrix
3152 -  b - the right-hand-side vector
3153 
3154    Output Parameter:
3155 .  x - the result vector
3156 
3157    Notes:
3158    MatSolve() should be used for most applications, as it performs
3159    a forward solve followed by a backward solve.
3160 
3161    The vectors b and x cannot be the same,  i.e., one cannot
3162    call MatForwardSolve(A,x,x).
3163 
3164    For matrix in seqsbaij format with block size larger than 1,
3165    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3166    MatForwardSolve() solves U^T*D y = b, and
3167    MatBackwardSolve() solves U x = y.
3168    Thus they do not provide a symmetric preconditioner.
3169 
3170    Most users should employ the simplified KSP interface for linear solvers
3171    instead of working directly with matrix algebra routines such as this.
3172    See, e.g., KSPCreate().
3173 
3174    Level: developer
3175 
3176    Concepts: matrices^forward solves
3177 
3178 .seealso: MatSolve(), MatBackwardSolve()
3179 @*/
3180 PetscErrorCode PETSCMAT_DLLEXPORT MatForwardSolve(Mat mat,Vec b,Vec x)
3181 {
3182   PetscErrorCode ierr;
3183 
3184   PetscFunctionBegin;
3185   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3186   PetscValidType(mat,1);
3187   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3188   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3189   PetscCheckSameComm(mat,1,b,2);
3190   PetscCheckSameComm(mat,1,x,3);
3191   if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3192   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3193   if (!mat->ops->forwardsolve) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3194   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);
3195   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);
3196   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);
3197   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3198   ierr = PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
3199   ierr = (*mat->ops->forwardsolve)(mat,b,x);CHKERRQ(ierr);
3200   ierr = PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
3201   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3202   PetscFunctionReturn(0);
3203 }
3204 
3205 #undef __FUNCT__
3206 #define __FUNCT__ "MatBackwardSolve"
3207 /*@
3208    MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
3209                              D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U,
3210 
3211    Neighbor-wise Collective on Mat and Vec
3212 
3213    Input Parameters:
3214 +  mat - the factored matrix
3215 -  b - the right-hand-side vector
3216 
3217    Output Parameter:
3218 .  x - the result vector
3219 
3220    Notes:
3221    MatSolve() should be used for most applications, as it performs
3222    a forward solve followed by a backward solve.
3223 
3224    The vectors b and x cannot be the same.  I.e., one cannot
3225    call MatBackwardSolve(A,x,x).
3226 
3227    For matrix in seqsbaij format with block size larger than 1,
3228    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3229    MatForwardSolve() solves U^T*D y = b, and
3230    MatBackwardSolve() solves U x = y.
3231    Thus they do not provide a symmetric preconditioner.
3232 
3233    Most users should employ the simplified KSP interface for linear solvers
3234    instead of working directly with matrix algebra routines such as this.
3235    See, e.g., KSPCreate().
3236 
3237    Level: developer
3238 
3239    Concepts: matrices^backward solves
3240 
3241 .seealso: MatSolve(), MatForwardSolve()
3242 @*/
3243 PetscErrorCode PETSCMAT_DLLEXPORT MatBackwardSolve(Mat mat,Vec b,Vec x)
3244 {
3245   PetscErrorCode ierr;
3246 
3247   PetscFunctionBegin;
3248   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3249   PetscValidType(mat,1);
3250   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3251   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3252   PetscCheckSameComm(mat,1,b,2);
3253   PetscCheckSameComm(mat,1,x,3);
3254   if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3255   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3256   if (!mat->ops->backwardsolve) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3257   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);
3258   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);
3259   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);
3260   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3261 
3262   ierr = PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
3263   ierr = (*mat->ops->backwardsolve)(mat,b,x);CHKERRQ(ierr);
3264   ierr = PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
3265   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3266   PetscFunctionReturn(0);
3267 }
3268 
3269 #undef __FUNCT__
3270 #define __FUNCT__ "MatSolveAdd"
3271 /*@
3272    MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
3273 
3274    Neighbor-wise Collective on Mat and Vec
3275 
3276    Input Parameters:
3277 +  mat - the factored matrix
3278 .  b - the right-hand-side vector
3279 -  y - the vector to be added to
3280 
3281    Output Parameter:
3282 .  x - the result vector
3283 
3284    Notes:
3285    The vectors b and x cannot be the same.  I.e., one cannot
3286    call MatSolveAdd(A,x,y,x).
3287 
3288    Most users should employ the simplified KSP interface for linear solvers
3289    instead of working directly with matrix algebra routines such as this.
3290    See, e.g., KSPCreate().
3291 
3292    Level: developer
3293 
3294    Concepts: matrices^triangular solves
3295 
3296 .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3297 @*/
3298 PetscErrorCode PETSCMAT_DLLEXPORT MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3299 {
3300   PetscScalar    one = 1.0;
3301   Vec            tmp;
3302   PetscErrorCode ierr;
3303 
3304   PetscFunctionBegin;
3305   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3306   PetscValidType(mat,1);
3307   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3308   PetscValidHeaderSpecific(b,VEC_CLASSID,3);
3309   PetscValidHeaderSpecific(x,VEC_CLASSID,4);
3310   PetscCheckSameComm(mat,1,b,2);
3311   PetscCheckSameComm(mat,1,y,2);
3312   PetscCheckSameComm(mat,1,x,3);
3313   if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3314   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3315   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);
3316   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);
3317   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);
3318   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);
3319   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);
3320   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3321 
3322   ierr = PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
3323   if (mat->ops->solveadd)  {
3324     ierr = (*mat->ops->solveadd)(mat,b,y,x);CHKERRQ(ierr);
3325   } else {
3326     /* do the solve then the add manually */
3327     if (x != y) {
3328       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
3329       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
3330     } else {
3331       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
3332       ierr = PetscLogObjectParent(mat,tmp);CHKERRQ(ierr);
3333       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
3334       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
3335       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
3336       ierr = VecDestroy(tmp);CHKERRQ(ierr);
3337     }
3338   }
3339   ierr = PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
3340   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3341   PetscFunctionReturn(0);
3342 }
3343 
3344 #undef __FUNCT__
3345 #define __FUNCT__ "MatSolveTranspose"
3346 /*@
3347    MatSolveTranspose - Solves A' x = b, given a factored matrix.
3348 
3349    Neighbor-wise Collective on Mat and Vec
3350 
3351    Input Parameters:
3352 +  mat - the factored matrix
3353 -  b - the right-hand-side vector
3354 
3355    Output Parameter:
3356 .  x - the result vector
3357 
3358    Notes:
3359    The vectors b and x cannot be the same.  I.e., one cannot
3360    call MatSolveTranspose(A,x,x).
3361 
3362    Most users should employ the simplified KSP interface for linear solvers
3363    instead of working directly with matrix algebra routines such as this.
3364    See, e.g., KSPCreate().
3365 
3366    Level: developer
3367 
3368    Concepts: matrices^triangular solves
3369 
3370 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
3371 @*/
3372 PetscErrorCode PETSCMAT_DLLEXPORT MatSolveTranspose(Mat mat,Vec b,Vec x)
3373 {
3374   PetscErrorCode ierr;
3375 
3376   PetscFunctionBegin;
3377   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3378   PetscValidType(mat,1);
3379   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3380   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3381   PetscCheckSameComm(mat,1,b,2);
3382   PetscCheckSameComm(mat,1,x,3);
3383   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3384   if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3385   if (!mat->ops->solvetranspose) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3386   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);
3387   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);
3388   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3389   ierr = PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
3390   ierr = (*mat->ops->solvetranspose)(mat,b,x);CHKERRQ(ierr);
3391   ierr = PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
3392   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3393   PetscFunctionReturn(0);
3394 }
3395 
3396 #undef __FUNCT__
3397 #define __FUNCT__ "MatSolveTransposeAdd"
3398 /*@
3399    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
3400                       factored matrix.
3401 
3402    Neighbor-wise Collective on Mat and Vec
3403 
3404    Input Parameters:
3405 +  mat - the factored matrix
3406 .  b - the right-hand-side vector
3407 -  y - the vector to be added to
3408 
3409    Output Parameter:
3410 .  x - the result vector
3411 
3412    Notes:
3413    The vectors b and x cannot be the same.  I.e., one cannot
3414    call MatSolveTransposeAdd(A,x,y,x).
3415 
3416    Most users should employ the simplified KSP interface for linear solvers
3417    instead of working directly with matrix algebra routines such as this.
3418    See, e.g., KSPCreate().
3419 
3420    Level: developer
3421 
3422    Concepts: matrices^triangular solves
3423 
3424 .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3425 @*/
3426 PetscErrorCode PETSCMAT_DLLEXPORT MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3427 {
3428   PetscScalar    one = 1.0;
3429   PetscErrorCode ierr;
3430   Vec            tmp;
3431 
3432   PetscFunctionBegin;
3433   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3434   PetscValidType(mat,1);
3435   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3436   PetscValidHeaderSpecific(b,VEC_CLASSID,3);
3437   PetscValidHeaderSpecific(x,VEC_CLASSID,4);
3438   PetscCheckSameComm(mat,1,b,2);
3439   PetscCheckSameComm(mat,1,y,3);
3440   PetscCheckSameComm(mat,1,x,4);
3441   if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3442   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3443   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);
3444   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);
3445   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);
3446   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);
3447   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3448 
3449   ierr = PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
3450   if (mat->ops->solvetransposeadd) {
3451     ierr = (*mat->ops->solvetransposeadd)(mat,b,y,x);CHKERRQ(ierr);
3452   } else {
3453     /* do the solve then the add manually */
3454     if (x != y) {
3455       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
3456       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
3457     } else {
3458       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
3459       ierr = PetscLogObjectParent(mat,tmp);CHKERRQ(ierr);
3460       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
3461       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
3462       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
3463       ierr = VecDestroy(tmp);CHKERRQ(ierr);
3464     }
3465   }
3466   ierr = PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
3467   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3468   PetscFunctionReturn(0);
3469 }
3470 /* ----------------------------------------------------------------*/
3471 
3472 #undef __FUNCT__
3473 #define __FUNCT__ "MatSOR"
3474 /*@
3475    MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps.
3476 
3477    Neighbor-wise Collective on Mat and Vec
3478 
3479    Input Parameters:
3480 +  mat - the matrix
3481 .  b - the right hand side
3482 .  omega - the relaxation factor
3483 .  flag - flag indicating the type of SOR (see below)
3484 .  shift -  diagonal shift
3485 .  its - the number of iterations
3486 -  lits - the number of local iterations
3487 
3488    Output Parameters:
3489 .  x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess)
3490 
3491    SOR Flags:
3492 .     SOR_FORWARD_SWEEP - forward SOR
3493 .     SOR_BACKWARD_SWEEP - backward SOR
3494 .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3495 .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR
3496 .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
3497 .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3498 .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
3499          upper/lower triangular part of matrix to
3500          vector (with omega)
3501 .     SOR_ZERO_INITIAL_GUESS - zero initial guess
3502 
3503    Notes:
3504    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3505    SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3506    on each processor.
3507 
3508    Application programmers will not generally use MatSOR() directly,
3509    but instead will employ the KSP/PC interface.
3510 
3511    Notes: for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing
3512 
3513    Notes for Advanced Users:
3514    The flags are implemented as bitwise inclusive or operations.
3515    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3516    to specify a zero initial guess for SSOR.
3517 
3518    Most users should employ the simplified KSP interface for linear solvers
3519    instead of working directly with matrix algebra routines such as this.
3520    See, e.g., KSPCreate().
3521 
3522    Vectors x and b CANNOT be the same
3523 
3524    Level: developer
3525 
3526    Concepts: matrices^relaxation
3527    Concepts: matrices^SOR
3528    Concepts: matrices^Gauss-Seidel
3529 
3530 @*/
3531 PetscErrorCode PETSCMAT_DLLEXPORT MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3532 {
3533   PetscErrorCode ierr;
3534 
3535   PetscFunctionBegin;
3536   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3537   PetscValidType(mat,1);
3538   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3539   PetscValidHeaderSpecific(x,VEC_CLASSID,8);
3540   PetscCheckSameComm(mat,1,b,2);
3541   PetscCheckSameComm(mat,1,x,8);
3542   if (!mat->ops->sor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3543   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3544   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3545   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);
3546   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);
3547   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);
3548   if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
3549   if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
3550   if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");
3551 
3552   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3553   ierr = PetscLogEventBegin(MAT_SOR,mat,b,x,0);CHKERRQ(ierr);
3554   ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr);
3555   ierr = PetscLogEventEnd(MAT_SOR,mat,b,x,0);CHKERRQ(ierr);
3556   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3557   PetscFunctionReturn(0);
3558 }
3559 
3560 #undef __FUNCT__
3561 #define __FUNCT__ "MatCopy_Basic"
3562 /*
3563       Default matrix copy routine.
3564 */
3565 PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
3566 {
3567   PetscErrorCode    ierr;
3568   PetscInt          i,rstart = 0,rend = 0,nz;
3569   const PetscInt    *cwork;
3570   const PetscScalar *vwork;
3571 
3572   PetscFunctionBegin;
3573   if (B->assembled) {
3574     ierr = MatZeroEntries(B);CHKERRQ(ierr);
3575   }
3576   ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
3577   for (i=rstart; i<rend; i++) {
3578     ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
3579     ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);CHKERRQ(ierr);
3580     ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
3581   }
3582   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3583   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3584   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
3585   PetscFunctionReturn(0);
3586 }
3587 
3588 #undef __FUNCT__
3589 #define __FUNCT__ "MatCopy"
3590 /*@
3591    MatCopy - Copys a matrix to another matrix.
3592 
3593    Collective on Mat
3594 
3595    Input Parameters:
3596 +  A - the matrix
3597 -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
3598 
3599    Output Parameter:
3600 .  B - where the copy is put
3601 
3602    Notes:
3603    If you use SAME_NONZERO_PATTERN then the two matrices had better have the
3604    same nonzero pattern or the routine will crash.
3605 
3606    MatCopy() copies the matrix entries of a matrix to another existing
3607    matrix (after first zeroing the second matrix).  A related routine is
3608    MatConvert(), which first creates a new matrix and then copies the data.
3609 
3610    Level: intermediate
3611 
3612    Concepts: matrices^copying
3613 
3614 .seealso: MatConvert(), MatDuplicate()
3615 
3616 @*/
3617 PetscErrorCode PETSCMAT_DLLEXPORT MatCopy(Mat A,Mat B,MatStructure str)
3618 {
3619   PetscErrorCode ierr;
3620   PetscInt       i;
3621 
3622   PetscFunctionBegin;
3623   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3624   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3625   PetscValidType(A,1);
3626   PetscValidType(B,2);
3627   PetscCheckSameComm(A,1,B,2);
3628   ierr = MatPreallocated(B);CHKERRQ(ierr);
3629   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3630   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3631   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);
3632   ierr = MatPreallocated(A);CHKERRQ(ierr);
3633 
3634   ierr = PetscLogEventBegin(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
3635   if (A->ops->copy) {
3636     ierr = (*A->ops->copy)(A,B,str);CHKERRQ(ierr);
3637   } else { /* generic conversion */
3638     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
3639   }
3640   if (A->rmapping) {
3641     if (B->rmapping) {
3642       ierr = ISLocalToGlobalMappingDestroy(B->rmapping);CHKERRQ(ierr);B->rmapping = 0;
3643       ierr = ISLocalToGlobalMappingDestroy(B->cmapping);CHKERRQ(ierr);B->cmapping = 0;
3644     }
3645     ierr = MatSetLocalToGlobalMapping(B,A->rmapping,A->cmapping);CHKERRQ(ierr);
3646   }
3647   if (A->rbmapping) {
3648     if (B->rbmapping) {
3649       ierr = ISLocalToGlobalMappingDestroy(B->rbmapping);CHKERRQ(ierr);B->rbmapping = 0;
3650       ierr = ISLocalToGlobalMappingDestroy(B->cbmapping);CHKERRQ(ierr);B->cbmapping = 0;
3651     }
3652     ierr = MatSetLocalToGlobalMappingBlock(B,A->rbmapping,A->cbmapping);CHKERRQ(ierr);
3653   }
3654 
3655   B->stencil.dim = A->stencil.dim;
3656   B->stencil.noc = A->stencil.noc;
3657   for (i=0; i<=A->stencil.dim; i++) {
3658     B->stencil.dims[i]   = A->stencil.dims[i];
3659     B->stencil.starts[i] = A->stencil.starts[i];
3660   }
3661 
3662   ierr = PetscLogEventEnd(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
3663   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
3664   PetscFunctionReturn(0);
3665 }
3666 
3667 #undef __FUNCT__
3668 #define __FUNCT__ "MatConvert"
3669 /*@C
3670    MatConvert - Converts a matrix to another matrix, either of the same
3671    or different type.
3672 
3673    Collective on Mat
3674 
3675    Input Parameters:
3676 +  mat - the matrix
3677 .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
3678    same type as the original matrix.
3679 -  reuse - denotes if the destination matrix is to be created or reused.  Currently
3680    MAT_REUSE_MATRIX is only supported for inplace conversion, otherwise use
3681    MAT_INITIAL_MATRIX.
3682 
3683    Output Parameter:
3684 .  M - pointer to place new matrix
3685 
3686    Notes:
3687    MatConvert() first creates a new matrix and then copies the data from
3688    the first matrix.  A related routine is MatCopy(), which copies the matrix
3689    entries of one matrix to another already existing matrix context.
3690 
3691    Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
3692    the MPI communicator of the generated matrix is always the same as the communicator
3693    of the input matrix.
3694 
3695    Level: intermediate
3696 
3697    Concepts: matrices^converting between storage formats
3698 
3699 .seealso: MatCopy(), MatDuplicate()
3700 @*/
3701 PetscErrorCode PETSCMAT_DLLEXPORT MatConvert(Mat mat, const MatType newtype,MatReuse reuse,Mat *M)
3702 {
3703   PetscErrorCode         ierr;
3704   PetscBool              sametype,issame,flg;
3705   char                   convname[256],mtype[256];
3706   Mat                    B;
3707 
3708   PetscFunctionBegin;
3709   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3710   PetscValidType(mat,1);
3711   PetscValidPointer(M,3);
3712   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3713   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3714   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3715 
3716   ierr = PetscOptionsGetString(((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);CHKERRQ(ierr);
3717   if (flg) {
3718     newtype = mtype;
3719   }
3720   ierr = PetscTypeCompare((PetscObject)mat,newtype,&sametype);CHKERRQ(ierr);
3721   ierr = PetscStrcmp(newtype,"same",&issame);CHKERRQ(ierr);
3722   if ((reuse == MAT_REUSE_MATRIX) && (mat != *M)) {
3723     SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"MAT_REUSE_MATRIX only supported for in-place conversion currently");
3724   }
3725 
3726   if ((reuse == MAT_REUSE_MATRIX) && (issame || sametype)) PetscFunctionReturn(0);
3727 
3728   if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
3729     ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
3730   } else {
3731     PetscErrorCode (*conv)(Mat, const MatType,MatReuse,Mat*)=PETSC_NULL;
3732     const char     *prefix[3] = {"seq","mpi",""};
3733     PetscInt       i;
3734     /*
3735        Order of precedence:
3736        1) See if a specialized converter is known to the current matrix.
3737        2) See if a specialized converter is known to the desired matrix class.
3738        3) See if a good general converter is registered for the desired class
3739           (as of 6/27/03 only MATMPIADJ falls into this category).
3740        4) See if a good general converter is known for the current matrix.
3741        5) Use a really basic converter.
3742     */
3743 
3744     /* 1) See if a specialized converter is known to the current matrix and the desired class */
3745     for (i=0; i<3; i++) {
3746       ierr = PetscStrcpy(convname,"MatConvert_");CHKERRQ(ierr);
3747       ierr = PetscStrcat(convname,((PetscObject)mat)->type_name);CHKERRQ(ierr);
3748       ierr = PetscStrcat(convname,"_");CHKERRQ(ierr);
3749       ierr = PetscStrcat(convname,prefix[i]);CHKERRQ(ierr);
3750       ierr = PetscStrcat(convname,newtype);CHKERRQ(ierr);
3751       ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
3752       ierr = PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);CHKERRQ(ierr);
3753       if (conv) goto foundconv;
3754     }
3755 
3756     /* 2)  See if a specialized converter is known to the desired matrix class. */
3757     ierr = MatCreate(((PetscObject)mat)->comm,&B);CHKERRQ(ierr);
3758     ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);CHKERRQ(ierr);
3759     ierr = MatSetType(B,newtype);CHKERRQ(ierr);
3760     for (i=0; i<3; i++) {
3761       ierr = PetscStrcpy(convname,"MatConvert_");CHKERRQ(ierr);
3762       ierr = PetscStrcat(convname,((PetscObject)mat)->type_name);CHKERRQ(ierr);
3763       ierr = PetscStrcat(convname,"_");CHKERRQ(ierr);
3764       ierr = PetscStrcat(convname,prefix[i]);CHKERRQ(ierr);
3765       ierr = PetscStrcat(convname,newtype);CHKERRQ(ierr);
3766       ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
3767       ierr = PetscObjectQueryFunction((PetscObject)B,convname,(void (**)(void))&conv);CHKERRQ(ierr);
3768       if (conv) {
3769         ierr = MatDestroy(B);CHKERRQ(ierr);
3770         goto foundconv;
3771       }
3772     }
3773 
3774     /* 3) See if a good general converter is registered for the desired class */
3775     conv = B->ops->convertfrom;
3776     ierr = MatDestroy(B);CHKERRQ(ierr);
3777     if (conv) goto foundconv;
3778 
3779     /* 4) See if a good general converter is known for the current matrix */
3780     if (mat->ops->convert) {
3781       conv = mat->ops->convert;
3782     }
3783     if (conv) goto foundconv;
3784 
3785     /* 5) Use a really basic converter. */
3786     conv = MatConvert_Basic;
3787 
3788     foundconv:
3789     ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
3790     ierr = (*conv)(mat,newtype,reuse,M);CHKERRQ(ierr);
3791     ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
3792   }
3793   ierr = PetscObjectStateIncrease((PetscObject)*M);CHKERRQ(ierr);
3794   PetscFunctionReturn(0);
3795 }
3796 
3797 #undef __FUNCT__
3798 #define __FUNCT__ "MatFactorGetSolverPackage"
3799 /*@C
3800    MatFactorGetSolverPackage - Returns name of the package providing the factorization routines
3801 
3802    Not Collective
3803 
3804    Input Parameter:
3805 .  mat - the matrix, must be a factored matrix
3806 
3807    Output Parameter:
3808 .   type - the string name of the package (do not free this string)
3809 
3810    Notes:
3811       In Fortran you pass in a empty string and the package name will be copied into it.
3812     (Make sure the string is long enough)
3813 
3814    Level: intermediate
3815 
3816 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
3817 @*/
3818 PetscErrorCode PETSCMAT_DLLEXPORT MatFactorGetSolverPackage(Mat mat, const MatSolverPackage *type)
3819 {
3820   PetscErrorCode         ierr;
3821   PetscErrorCode         (*conv)(Mat,const MatSolverPackage*);
3822 
3823   PetscFunctionBegin;
3824   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3825   PetscValidType(mat,1);
3826   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
3827   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverPackage_C",(void (**)(void))&conv);CHKERRQ(ierr);
3828   if (!conv) {
3829     *type = MATSOLVERPETSC;
3830   } else {
3831     ierr = (*conv)(mat,type);CHKERRQ(ierr);
3832   }
3833   PetscFunctionReturn(0);
3834 }
3835 
3836 #undef __FUNCT__
3837 #define __FUNCT__ "MatGetFactor"
3838 /*@C
3839    MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic()
3840 
3841    Collective on Mat
3842 
3843    Input Parameters:
3844 +  mat - the matrix
3845 .  type - name of solver type, for example, spooles, superlu, plapack, petsc (to use PETSc's default)
3846 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
3847 
3848    Output Parameters:
3849 .  f - the factor matrix used with MatXXFactorSymbolic() calls
3850 
3851    Notes:
3852       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
3853      such as pastix, superlu, mumps, spooles etc.
3854 
3855       PETSc must have been ./configure to use the external solver, using the option --download-package
3856 
3857    Level: intermediate
3858 
3859 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
3860 @*/
3861 PetscErrorCode PETSCMAT_DLLEXPORT MatGetFactor(Mat mat, const MatSolverPackage type,MatFactorType ftype,Mat *f)
3862 {
3863   PetscErrorCode  ierr,(*conv)(Mat,MatFactorType,Mat*);
3864   char            convname[256];
3865 
3866   PetscFunctionBegin;
3867   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3868   PetscValidType(mat,1);
3869 
3870   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3871   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3872 
3873   ierr = PetscStrcpy(convname,"MatGetFactor_");CHKERRQ(ierr);
3874   ierr = PetscStrcat(convname,type);CHKERRQ(ierr);
3875   ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
3876   ierr = PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);CHKERRQ(ierr);
3877   if (!conv) {
3878     PetscBool  flag;
3879     MPI_Comm   comm;
3880 
3881     ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
3882     ierr = PetscStrcasecmp(MATSOLVERPETSC,type,&flag);CHKERRQ(ierr);
3883     if (flag) {
3884       SETERRQ2(comm,PETSC_ERR_SUP,"Matrix format %s does not have a built-in PETSc %s",((PetscObject)mat)->type_name,MatFactorTypes[ftype]);
3885     } else {
3886       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);
3887     }
3888   }
3889   ierr = (*conv)(mat,ftype,f);CHKERRQ(ierr);
3890   PetscFunctionReturn(0);
3891 }
3892 
3893 #undef __FUNCT__
3894 #define __FUNCT__ "MatGetFactorAvailable"
3895 /*@C
3896    MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type
3897 
3898    Not Collective
3899 
3900    Input Parameters:
3901 +  mat - the matrix
3902 .  type - name of solver type, for example, spooles, superlu, plapack, petsc (to use PETSc's default)
3903 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
3904 
3905    Output Parameter:
3906 .    flg - PETSC_TRUE if the factorization is available
3907 
3908    Notes:
3909       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
3910      such as pastix, superlu, mumps, spooles etc.
3911 
3912       PETSc must have been ./configure to use the external solver, using the option --download-package
3913 
3914    Level: intermediate
3915 
3916 .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
3917 @*/
3918 PetscErrorCode PETSCMAT_DLLEXPORT MatGetFactorAvailable(Mat mat, const MatSolverPackage type,MatFactorType ftype,PetscBool  *flg)
3919 {
3920   PetscErrorCode         ierr;
3921   char                   convname[256];
3922   PetscErrorCode         (*conv)(Mat,MatFactorType,PetscBool *);
3923 
3924   PetscFunctionBegin;
3925   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3926   PetscValidType(mat,1);
3927 
3928   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3929   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3930 
3931   ierr = PetscStrcpy(convname,"MatGetFactorAvailable_");CHKERRQ(ierr);
3932   ierr = PetscStrcat(convname,type);CHKERRQ(ierr);
3933   ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
3934   ierr = PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);CHKERRQ(ierr);
3935   if (!conv) {
3936     *flg = PETSC_FALSE;
3937   } else {
3938     ierr = (*conv)(mat,ftype,flg);CHKERRQ(ierr);
3939   }
3940   PetscFunctionReturn(0);
3941 }
3942 
3943 
3944 #undef __FUNCT__
3945 #define __FUNCT__ "MatDuplicate"
3946 /*@
3947    MatDuplicate - Duplicates a matrix including the non-zero structure.
3948 
3949    Collective on Mat
3950 
3951    Input Parameters:
3952 +  mat - the matrix
3953 -  op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy the numerical values in the matrix
3954         MAT_SHARE_NONZERO_PATTERN to share the nonzero patterns with the previous matrix and not copy them.
3955 
3956    Output Parameter:
3957 .  M - pointer to place new matrix
3958 
3959    Level: intermediate
3960 
3961    Concepts: matrices^duplicating
3962 
3963     Notes: You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN.
3964 
3965 .seealso: MatCopy(), MatConvert()
3966 @*/
3967 PetscErrorCode PETSCMAT_DLLEXPORT MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
3968 {
3969   PetscErrorCode ierr;
3970   Mat            B;
3971   PetscInt       i;
3972 
3973   PetscFunctionBegin;
3974   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3975   PetscValidType(mat,1);
3976   PetscValidPointer(M,3);
3977   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3978   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3979   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3980 
3981   *M  = 0;
3982   if (!mat->ops->duplicate) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Not written for this matrix type");
3983   ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
3984   ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr);
3985   B = *M;
3986   if (mat->rmapping) {
3987     ierr = MatSetLocalToGlobalMapping(B,mat->rmapping,mat->cmapping);CHKERRQ(ierr);
3988   }
3989   if (mat->rbmapping) {
3990     ierr = MatSetLocalToGlobalMappingBlock(B,mat->rbmapping,mat->cbmapping);CHKERRQ(ierr);
3991   }
3992   ierr = PetscLayoutCopy(mat->rmap,&B->rmap);CHKERRQ(ierr);
3993   ierr = PetscLayoutCopy(mat->cmap,&B->cmap);CHKERRQ(ierr);
3994 
3995   B->stencil.dim = mat->stencil.dim;
3996   B->stencil.noc = mat->stencil.noc;
3997   for (i=0; i<=mat->stencil.dim; i++) {
3998     B->stencil.dims[i]   = mat->stencil.dims[i];
3999     B->stencil.starts[i] = mat->stencil.starts[i];
4000   }
4001 
4002   B->nooffproczerorows = mat->nooffproczerorows;
4003   B->nooffprocentries  = mat->nooffprocentries;
4004   ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4005   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
4006   PetscFunctionReturn(0);
4007 }
4008 
4009 #undef __FUNCT__
4010 #define __FUNCT__ "MatGetDiagonal"
4011 /*@
4012    MatGetDiagonal - Gets the diagonal of a matrix.
4013 
4014    Logically Collective on Mat and Vec
4015 
4016    Input Parameters:
4017 +  mat - the matrix
4018 -  v - the vector for storing the diagonal
4019 
4020    Output Parameter:
4021 .  v - the diagonal of the matrix
4022 
4023    Level: intermediate
4024 
4025    Concepts: matrices^accessing diagonals
4026 
4027 .seealso: MatGetRow(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs()
4028 @*/
4029 PetscErrorCode PETSCMAT_DLLEXPORT MatGetDiagonal(Mat mat,Vec v)
4030 {
4031   PetscErrorCode ierr;
4032 
4033   PetscFunctionBegin;
4034   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4035   PetscValidType(mat,1);
4036   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4037   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4038   if (!mat->ops->getdiagonal) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4039   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4040 
4041   ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr);
4042   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4043   PetscFunctionReturn(0);
4044 }
4045 
4046 #undef __FUNCT__
4047 #define __FUNCT__ "MatGetRowMin"
4048 /*@
4049    MatGetRowMin - Gets the minimum value (of the real part) of each
4050         row of the matrix
4051 
4052    Logically Collective on Mat and Vec
4053 
4054    Input Parameters:
4055 .  mat - the matrix
4056 
4057    Output Parameter:
4058 +  v - the vector for storing the maximums
4059 -  idx - the indices of the column found for each row (optional)
4060 
4061    Level: intermediate
4062 
4063    Notes: The result of this call are the same as if one converted the matrix to dense format
4064       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4065 
4066     This code is only implemented for a couple of matrix formats.
4067 
4068    Concepts: matrices^getting row maximums
4069 
4070 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(),
4071           MatGetRowMax()
4072 @*/
4073 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4074 {
4075   PetscErrorCode ierr;
4076 
4077   PetscFunctionBegin;
4078   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4079   PetscValidType(mat,1);
4080   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4081   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4082   if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4083   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4084 
4085   ierr = (*mat->ops->getrowmin)(mat,v,idx);CHKERRQ(ierr);
4086   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4087   PetscFunctionReturn(0);
4088 }
4089 
4090 #undef __FUNCT__
4091 #define __FUNCT__ "MatGetRowMinAbs"
4092 /*@
4093    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4094         row of the matrix
4095 
4096    Logically Collective on Mat and Vec
4097 
4098    Input Parameters:
4099 .  mat - the matrix
4100 
4101    Output Parameter:
4102 +  v - the vector for storing the minimums
4103 -  idx - the indices of the column found for each row (optional)
4104 
4105    Level: intermediate
4106 
4107    Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
4108     row is 0 (the first column).
4109 
4110     This code is only implemented for a couple of matrix formats.
4111 
4112    Concepts: matrices^getting row maximums
4113 
4114 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4115 @*/
4116 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4117 {
4118   PetscErrorCode ierr;
4119 
4120   PetscFunctionBegin;
4121   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4122   PetscValidType(mat,1);
4123   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4124   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4125   if (!mat->ops->getrowminabs) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4126   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4127   if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);}
4128 
4129   ierr = (*mat->ops->getrowminabs)(mat,v,idx);CHKERRQ(ierr);
4130   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4131   PetscFunctionReturn(0);
4132 }
4133 
4134 #undef __FUNCT__
4135 #define __FUNCT__ "MatGetRowMax"
4136 /*@
4137    MatGetRowMax - Gets the maximum value (of the real part) of each
4138         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 maximums
4147 -  idx - the indices of the column found for each row (optional)
4148 
4149    Level: intermediate
4150 
4151    Notes: The result of this call are the same as if one converted the matrix to dense format
4152       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4153 
4154     This code is only implemented for a couple of matrix formats.
4155 
4156    Concepts: matrices^getting row maximums
4157 
4158 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4159 @*/
4160 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4161 {
4162   PetscErrorCode ierr;
4163 
4164   PetscFunctionBegin;
4165   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4166   PetscValidType(mat,1);
4167   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4168   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4169   if (!mat->ops->getrowmax) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4170   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4171 
4172   ierr = (*mat->ops->getrowmax)(mat,v,idx);CHKERRQ(ierr);
4173   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4174   PetscFunctionReturn(0);
4175 }
4176 
4177 #undef __FUNCT__
4178 #define __FUNCT__ "MatGetRowMaxAbs"
4179 /*@
4180    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4181         row of the matrix
4182 
4183    Logically Collective on Mat and Vec
4184 
4185    Input Parameters:
4186 .  mat - the matrix
4187 
4188    Output Parameter:
4189 +  v - the vector for storing the maximums
4190 -  idx - the indices of the column found for each row (optional)
4191 
4192    Level: intermediate
4193 
4194    Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
4195     row is 0 (the first column).
4196 
4197     This code is only implemented for a couple of matrix formats.
4198 
4199    Concepts: matrices^getting row maximums
4200 
4201 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4202 @*/
4203 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4204 {
4205   PetscErrorCode ierr;
4206 
4207   PetscFunctionBegin;
4208   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4209   PetscValidType(mat,1);
4210   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4211   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4212   if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4213   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4214   if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);}
4215 
4216   ierr = (*mat->ops->getrowmaxabs)(mat,v,idx);CHKERRQ(ierr);
4217   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4218   PetscFunctionReturn(0);
4219 }
4220 
4221 #undef __FUNCT__
4222 #define __FUNCT__ "MatGetRowSum"
4223 /*@
4224    MatGetRowSum - Gets the sum of each row of the matrix
4225 
4226    Logically Collective on Mat and Vec
4227 
4228    Input Parameters:
4229 .  mat - the matrix
4230 
4231    Output Parameter:
4232 .  v - the vector for storing the sum of rows
4233 
4234    Level: intermediate
4235 
4236    Notes: This code is slow since it is not currently specialized for different formats
4237 
4238    Concepts: matrices^getting row sums
4239 
4240 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4241 @*/
4242 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRowSum(Mat mat, Vec v)
4243 {
4244   PetscInt       start = 0, end = 0, row;
4245   PetscScalar   *array;
4246   PetscErrorCode ierr;
4247 
4248   PetscFunctionBegin;
4249   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4250   PetscValidType(mat,1);
4251   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4252   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4253   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4254   ierr = MatGetOwnershipRange(mat, &start, &end);CHKERRQ(ierr);
4255   ierr = VecGetArray(v, &array);CHKERRQ(ierr);
4256   for(row = start; row < end; ++row) {
4257     PetscInt           ncols, col;
4258     const PetscInt    *cols;
4259     const PetscScalar *vals;
4260 
4261     array[row - start] = 0.0;
4262     ierr = MatGetRow(mat, row, &ncols, &cols, &vals);CHKERRQ(ierr);
4263     for(col = 0; col < ncols; col++) {
4264       array[row - start] += vals[col];
4265     }
4266     ierr = MatRestoreRow(mat, row, &ncols, &cols, &vals);CHKERRQ(ierr);
4267   }
4268   ierr = VecRestoreArray(v, &array);CHKERRQ(ierr);
4269   ierr = PetscObjectStateIncrease((PetscObject) v);CHKERRQ(ierr);
4270   PetscFunctionReturn(0);
4271 }
4272 
4273 #undef __FUNCT__
4274 #define __FUNCT__ "MatTranspose"
4275 /*@
4276    MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
4277 
4278    Collective on Mat
4279 
4280    Input Parameter:
4281 +  mat - the matrix to transpose
4282 -  reuse - store the transpose matrix in the provided B
4283 
4284    Output Parameters:
4285 .  B - the transpose
4286 
4287    Notes:
4288      If you  pass in &mat for B the transpose will be done in place
4289 
4290    Level: intermediate
4291 
4292    Concepts: matrices^transposing
4293 
4294 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4295 @*/
4296 PetscErrorCode PETSCMAT_DLLEXPORT MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4297 {
4298   PetscErrorCode ierr;
4299 
4300   PetscFunctionBegin;
4301   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4302   PetscValidType(mat,1);
4303   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4304   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4305   if (!mat->ops->transpose) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4306   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4307 
4308   ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4309   ierr = (*mat->ops->transpose)(mat,reuse,B);CHKERRQ(ierr);
4310   ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4311   if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);}
4312   PetscFunctionReturn(0);
4313 }
4314 
4315 #undef __FUNCT__
4316 #define __FUNCT__ "MatIsTranspose"
4317 /*@
4318    MatIsTranspose - Test whether a matrix is another one's transpose,
4319         or its own, in which case it tests symmetry.
4320 
4321    Collective on Mat
4322 
4323    Input Parameter:
4324 +  A - the matrix to test
4325 -  B - the matrix to test against, this can equal the first parameter
4326 
4327    Output Parameters:
4328 .  flg - the result
4329 
4330    Notes:
4331    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4332    has a running time of the order of the number of nonzeros; the parallel
4333    test involves parallel copies of the block-offdiagonal parts of the matrix.
4334 
4335    Level: intermediate
4336 
4337    Concepts: matrices^transposing, matrix^symmetry
4338 
4339 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4340 @*/
4341 PetscErrorCode PETSCMAT_DLLEXPORT MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4342 {
4343   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool *),(*g)(Mat,Mat,PetscReal,PetscBool *);
4344 
4345   PetscFunctionBegin;
4346   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4347   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4348   PetscValidPointer(flg,3);
4349   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",(void (**)(void))&f);CHKERRQ(ierr);
4350   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",(void (**)(void))&g);CHKERRQ(ierr);
4351   if (f && g) {
4352     if (f==g) {
4353       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
4354     } else {
4355       SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4356     }
4357   }
4358   PetscFunctionReturn(0);
4359 }
4360 
4361 #undef __FUNCT__
4362 #define __FUNCT__ "MatHermitianTranspose"
4363 /*@
4364    MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate.
4365 
4366    Collective on Mat
4367 
4368    Input Parameter:
4369 +  mat - the matrix to transpose and complex conjugate
4370 -  reuse - store the transpose matrix in the provided B
4371 
4372    Output Parameters:
4373 .  B - the Hermitian
4374 
4375    Notes:
4376      If you  pass in &mat for B the Hermitian will be done in place
4377 
4378    Level: intermediate
4379 
4380    Concepts: matrices^transposing, complex conjugatex
4381 
4382 .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4383 @*/
4384 PetscErrorCode PETSCMAT_DLLEXPORT MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
4385 {
4386   PetscErrorCode ierr;
4387 
4388   PetscFunctionBegin;
4389   ierr = MatTranspose(mat,reuse,B);CHKERRQ(ierr);
4390 #if defined(PETSC_USE_COMPLEX)
4391   ierr = MatConjugate(*B);CHKERRQ(ierr);
4392 #endif
4393   PetscFunctionReturn(0);
4394 }
4395 
4396 #undef __FUNCT__
4397 #define __FUNCT__ "MatIsHermitianTranspose"
4398 /*@
4399    MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,
4400 
4401    Collective on Mat
4402 
4403    Input Parameter:
4404 +  A - the matrix to test
4405 -  B - the matrix to test against, this can equal the first parameter
4406 
4407    Output Parameters:
4408 .  flg - the result
4409 
4410    Notes:
4411    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4412    has a running time of the order of the number of nonzeros; the parallel
4413    test involves parallel copies of the block-offdiagonal parts of the matrix.
4414 
4415    Level: intermediate
4416 
4417    Concepts: matrices^transposing, matrix^symmetry
4418 
4419 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
4420 @*/
4421 PetscErrorCode PETSCMAT_DLLEXPORT MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4422 {
4423   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool *),(*g)(Mat,Mat,PetscReal,PetscBool *);
4424 
4425   PetscFunctionBegin;
4426   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4427   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4428   PetscValidPointer(flg,3);
4429   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",(void (**)(void))&f);CHKERRQ(ierr);
4430   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",(void (**)(void))&g);CHKERRQ(ierr);
4431   if (f && g) {
4432     if (f==g) {
4433       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
4434     } else {
4435       SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
4436     }
4437   }
4438   PetscFunctionReturn(0);
4439 }
4440 
4441 #undef __FUNCT__
4442 #define __FUNCT__ "MatPermute"
4443 /*@
4444    MatPermute - Creates a new matrix with rows and columns permuted from the
4445    original.
4446 
4447    Collective on Mat
4448 
4449    Input Parameters:
4450 +  mat - the matrix to permute
4451 .  row - row permutation, each processor supplies only the permutation for its rows
4452 -  col - column permutation, each processor needs the entire column permutation, that is
4453          this is the same size as the total number of columns in the matrix. It can often
4454          be obtained with ISAllGather() on the row permutation
4455 
4456    Output Parameters:
4457 .  B - the permuted matrix
4458 
4459    Level: advanced
4460 
4461    Concepts: matrices^permuting
4462 
4463 .seealso: MatGetOrdering(), ISAllGather()
4464 
4465 @*/
4466 PetscErrorCode PETSCMAT_DLLEXPORT MatPermute(Mat mat,IS row,IS col,Mat *B)
4467 {
4468   PetscErrorCode ierr;
4469 
4470   PetscFunctionBegin;
4471   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4472   PetscValidType(mat,1);
4473   PetscValidHeaderSpecific(row,IS_CLASSID,2);
4474   PetscValidHeaderSpecific(col,IS_CLASSID,3);
4475   PetscValidPointer(B,4);
4476   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4477   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4478   if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
4479   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4480 
4481   ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr);
4482   ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);
4483   PetscFunctionReturn(0);
4484 }
4485 
4486 #undef __FUNCT__
4487 #define __FUNCT__ "MatPermuteSparsify"
4488 /*@
4489   MatPermuteSparsify - Creates a new matrix with rows and columns permuted from the
4490   original and sparsified to the prescribed tolerance.
4491 
4492   Collective on Mat
4493 
4494   Input Parameters:
4495 + A    - The matrix to permute
4496 . band - The half-bandwidth of the sparsified matrix, or PETSC_DECIDE
4497 . frac - The half-bandwidth as a fraction of the total size, or 0.0
4498 . tol  - The drop tolerance
4499 . rowp - The row permutation
4500 - colp - The column permutation
4501 
4502   Output Parameter:
4503 . B    - The permuted, sparsified matrix
4504 
4505   Level: advanced
4506 
4507   Note:
4508   The default behavior (band = PETSC_DECIDE and frac = 0.0) is to
4509   restrict the half-bandwidth of the resulting matrix to 5% of the
4510   total matrix size.
4511 
4512 .keywords: matrix, permute, sparsify
4513 
4514 .seealso: MatGetOrdering(), MatPermute()
4515 @*/
4516 PetscErrorCode PETSCMAT_DLLEXPORT MatPermuteSparsify(Mat A, PetscInt band, PetscReal frac, PetscReal tol, IS rowp, IS colp, Mat *B)
4517 {
4518   IS                irowp, icolp;
4519   const PetscInt    *rows, *cols;
4520   PetscInt          M, N, locRowStart = 0, locRowEnd = 0;
4521   PetscInt          nz, newNz;
4522   const PetscInt    *cwork;
4523   PetscInt          *cnew;
4524   const PetscScalar *vwork;
4525   PetscScalar       *vnew;
4526   PetscInt          bw, issize;
4527   PetscInt          row, locRow, newRow, col, newCol;
4528   PetscErrorCode    ierr;
4529 
4530   PetscFunctionBegin;
4531   PetscValidHeaderSpecific(A,    MAT_CLASSID,1);
4532   PetscValidHeaderSpecific(rowp, IS_CLASSID,5);
4533   PetscValidHeaderSpecific(colp, IS_CLASSID,6);
4534   PetscValidPointer(B,7);
4535   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix");
4536   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
4537   if (!A->ops->permutesparsify) {
4538     ierr = MatGetSize(A, &M, &N);CHKERRQ(ierr);
4539     ierr = MatGetOwnershipRange(A, &locRowStart, &locRowEnd);CHKERRQ(ierr);
4540     ierr = ISGetSize(rowp, &issize);CHKERRQ(ierr);
4541     if (issize != M) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Wrong size %D for row permutation, should be %D", issize, M);
4542     ierr = ISGetSize(colp, &issize);CHKERRQ(ierr);
4543     if (issize != N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Wrong size %D for column permutation, should be %D", issize, N);
4544     ierr = ISInvertPermutation(rowp, 0, &irowp);CHKERRQ(ierr);
4545     ierr = ISGetIndices(irowp, &rows);CHKERRQ(ierr);
4546     ierr = ISInvertPermutation(colp, 0, &icolp);CHKERRQ(ierr);
4547     ierr = ISGetIndices(icolp, &cols);CHKERRQ(ierr);
4548     ierr = PetscMalloc(N*sizeof(PetscInt),&cnew);CHKERRQ(ierr);
4549     ierr = PetscMalloc(N*sizeof(PetscScalar),&vnew);CHKERRQ(ierr);
4550 
4551     /* Setup bandwidth to include */
4552     if (band == PETSC_DECIDE) {
4553       if (frac <= 0.0)
4554         bw = (PetscInt) (M * 0.05);
4555       else
4556         bw = (PetscInt) (M * frac);
4557     } else {
4558       if (band <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Bandwidth must be a positive integer");
4559       bw = band;
4560     }
4561 
4562     /* Put values into new matrix */
4563     ierr = MatDuplicate(A, MAT_DO_NOT_COPY_VALUES, B);CHKERRQ(ierr);
4564     for(row = locRowStart, locRow = 0; row < locRowEnd; row++, locRow++) {
4565       ierr = MatGetRow(A, row, &nz, &cwork, &vwork);CHKERRQ(ierr);
4566       newRow   = rows[locRow]+locRowStart;
4567       for(col = 0, newNz = 0; col < nz; col++) {
4568         newCol = cols[cwork[col]];
4569         if ((newCol >= newRow - bw) && (newCol < newRow + bw) && (PetscAbsScalar(vwork[col]) >= tol)) {
4570           cnew[newNz] = newCol;
4571           vnew[newNz] = vwork[col];
4572           newNz++;
4573         }
4574       }
4575       ierr = MatSetValues(*B, 1, &newRow, newNz, cnew, vnew, INSERT_VALUES);CHKERRQ(ierr);
4576       ierr = MatRestoreRow(A, row, &nz, &cwork, &vwork);CHKERRQ(ierr);
4577     }
4578     ierr = PetscFree(cnew);CHKERRQ(ierr);
4579     ierr = PetscFree(vnew);CHKERRQ(ierr);
4580     ierr = MatAssemblyBegin(*B, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4581     ierr = MatAssemblyEnd(*B, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4582     ierr = ISRestoreIndices(irowp, &rows);CHKERRQ(ierr);
4583     ierr = ISRestoreIndices(icolp, &cols);CHKERRQ(ierr);
4584     ierr = ISDestroy(irowp);CHKERRQ(ierr);
4585     ierr = ISDestroy(icolp);CHKERRQ(ierr);
4586   } else {
4587     ierr = (*A->ops->permutesparsify)(A, band, frac, tol, rowp, colp, B);CHKERRQ(ierr);
4588   }
4589   ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);
4590   PetscFunctionReturn(0);
4591 }
4592 
4593 #undef __FUNCT__
4594 #define __FUNCT__ "MatEqual"
4595 /*@
4596    MatEqual - Compares two matrices.
4597 
4598    Collective on Mat
4599 
4600    Input Parameters:
4601 +  A - the first matrix
4602 -  B - the second matrix
4603 
4604    Output Parameter:
4605 .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
4606 
4607    Level: intermediate
4608 
4609    Concepts: matrices^equality between
4610 @*/
4611 PetscErrorCode PETSCMAT_DLLEXPORT MatEqual(Mat A,Mat B,PetscBool  *flg)
4612 {
4613   PetscErrorCode ierr;
4614 
4615   PetscFunctionBegin;
4616   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4617   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4618   PetscValidType(A,1);
4619   PetscValidType(B,2);
4620   PetscValidIntPointer(flg,3);
4621   PetscCheckSameComm(A,1,B,2);
4622   ierr = MatPreallocated(B);CHKERRQ(ierr);
4623   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4624   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4625   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);
4626   if (!A->ops->equal) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4627   if (!B->ops->equal) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4628   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);
4629   ierr = MatPreallocated(A);CHKERRQ(ierr);
4630 
4631   ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr);
4632   PetscFunctionReturn(0);
4633 }
4634 
4635 #undef __FUNCT__
4636 #define __FUNCT__ "MatDiagonalScale"
4637 /*@
4638    MatDiagonalScale - Scales a matrix on the left and right by diagonal
4639    matrices that are stored as vectors.  Either of the two scaling
4640    matrices can be PETSC_NULL.
4641 
4642    Collective on Mat
4643 
4644    Input Parameters:
4645 +  mat - the matrix to be scaled
4646 .  l - the left scaling vector (or PETSC_NULL)
4647 -  r - the right scaling vector (or PETSC_NULL)
4648 
4649    Notes:
4650    MatDiagonalScale() computes A = LAR, where
4651    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
4652    The L scales the rows of the matrix, the R scales the columns of the matrix.
4653 
4654    Level: intermediate
4655 
4656    Concepts: matrices^diagonal scaling
4657    Concepts: diagonal scaling of matrices
4658 
4659 .seealso: MatScale()
4660 @*/
4661 PetscErrorCode PETSCMAT_DLLEXPORT MatDiagonalScale(Mat mat,Vec l,Vec r)
4662 {
4663   PetscErrorCode ierr;
4664 
4665   PetscFunctionBegin;
4666   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4667   PetscValidType(mat,1);
4668   if (!mat->ops->diagonalscale) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4669   if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);}
4670   if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);}
4671   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4672   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4673   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4674 
4675   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4676   ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr);
4677   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4678   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4679 #if defined(PETSC_HAVE_CUDA)
4680   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
4681     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
4682   }
4683 #endif
4684   PetscFunctionReturn(0);
4685 }
4686 
4687 #undef __FUNCT__
4688 #define __FUNCT__ "MatScale"
4689 /*@
4690     MatScale - Scales all elements of a matrix by a given number.
4691 
4692     Logically Collective on Mat
4693 
4694     Input Parameters:
4695 +   mat - the matrix to be scaled
4696 -   a  - the scaling value
4697 
4698     Output Parameter:
4699 .   mat - the scaled matrix
4700 
4701     Level: intermediate
4702 
4703     Concepts: matrices^scaling all entries
4704 
4705 .seealso: MatDiagonalScale()
4706 @*/
4707 PetscErrorCode PETSCMAT_DLLEXPORT MatScale(Mat mat,PetscScalar a)
4708 {
4709   PetscErrorCode ierr;
4710 
4711   PetscFunctionBegin;
4712   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4713   PetscValidType(mat,1);
4714   if (a != 1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4715   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4716   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4717   PetscValidLogicalCollectiveScalar(mat,a,2);
4718   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4719 
4720   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4721   if (a != 1.0) {
4722     ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr);
4723     ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4724   }
4725   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4726 #if defined(PETSC_HAVE_CUDA)
4727   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
4728     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
4729   }
4730 #endif
4731   PetscFunctionReturn(0);
4732 }
4733 
4734 #undef __FUNCT__
4735 #define __FUNCT__ "MatNorm"
4736 /*@
4737    MatNorm - Calculates various norms of a matrix.
4738 
4739    Collective on Mat
4740 
4741    Input Parameters:
4742 +  mat - the matrix
4743 -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
4744 
4745    Output Parameters:
4746 .  nrm - the resulting norm
4747 
4748    Level: intermediate
4749 
4750    Concepts: matrices^norm
4751    Concepts: norm^of matrix
4752 @*/
4753 PetscErrorCode PETSCMAT_DLLEXPORT MatNorm(Mat mat,NormType type,PetscReal *nrm)
4754 {
4755   PetscErrorCode ierr;
4756 
4757   PetscFunctionBegin;
4758   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4759   PetscValidType(mat,1);
4760   PetscValidScalarPointer(nrm,3);
4761 
4762   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4763   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4764   if (!mat->ops->norm) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4765   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4766 
4767   ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr);
4768   PetscFunctionReturn(0);
4769 }
4770 
4771 /*
4772      This variable is used to prevent counting of MatAssemblyBegin() that
4773    are called from within a MatAssemblyEnd().
4774 */
4775 static PetscInt MatAssemblyEnd_InUse = 0;
4776 #undef __FUNCT__
4777 #define __FUNCT__ "MatAssemblyBegin"
4778 /*@
4779    MatAssemblyBegin - Begins assembling the matrix.  This routine should
4780    be called after completing all calls to MatSetValues().
4781 
4782    Collective on Mat
4783 
4784    Input Parameters:
4785 +  mat - the matrix
4786 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
4787 
4788    Notes:
4789    MatSetValues() generally caches the values.  The matrix is ready to
4790    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4791    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4792    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4793    using the matrix.
4794 
4795    Level: beginner
4796 
4797    Concepts: matrices^assembling
4798 
4799 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
4800 @*/
4801 PetscErrorCode PETSCMAT_DLLEXPORT MatAssemblyBegin(Mat mat,MatAssemblyType type)
4802 {
4803   PetscErrorCode ierr;
4804 
4805   PetscFunctionBegin;
4806   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4807   PetscValidType(mat,1);
4808   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4809   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
4810   if (mat->assembled) {
4811     mat->was_assembled = PETSC_TRUE;
4812     mat->assembled     = PETSC_FALSE;
4813   }
4814   if (!MatAssemblyEnd_InUse) {
4815     ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
4816     if (mat->ops->assemblybegin){ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
4817     ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
4818   } else {
4819     if (mat->ops->assemblybegin){ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
4820   }
4821   PetscFunctionReturn(0);
4822 }
4823 
4824 #undef __FUNCT__
4825 #define __FUNCT__ "MatAssembled"
4826 /*@
4827    MatAssembled - Indicates if a matrix has been assembled and is ready for
4828      use; for example, in matrix-vector product.
4829 
4830    Not Collective
4831 
4832    Input Parameter:
4833 .  mat - the matrix
4834 
4835    Output Parameter:
4836 .  assembled - PETSC_TRUE or PETSC_FALSE
4837 
4838    Level: advanced
4839 
4840    Concepts: matrices^assembled?
4841 
4842 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
4843 @*/
4844 PetscErrorCode PETSCMAT_DLLEXPORT MatAssembled(Mat mat,PetscBool  *assembled)
4845 {
4846   PetscFunctionBegin;
4847   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4848   PetscValidType(mat,1);
4849   PetscValidPointer(assembled,2);
4850   *assembled = mat->assembled;
4851   PetscFunctionReturn(0);
4852 }
4853 
4854 #undef __FUNCT__
4855 #define __FUNCT__ "MatView_Private"
4856 /*
4857     Processes command line options to determine if/how a matrix
4858   is to be viewed. Called by MatAssemblyEnd() and MatLoad().
4859 */
4860 PetscErrorCode MatView_Private(Mat mat)
4861 {
4862   PetscErrorCode    ierr;
4863   PetscBool         flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE,flg4 = PETSC_FALSE,flg6 = PETSC_FALSE,flg7 = PETSC_FALSE,flg8 = PETSC_FALSE;
4864   static PetscBool  incall = PETSC_FALSE;
4865 #if defined(PETSC_USE_SOCKET_VIEWER)
4866   PetscBool         flg5 = PETSC_FALSE;
4867 #endif
4868 
4869   PetscFunctionBegin;
4870   if (incall) PetscFunctionReturn(0);
4871   incall = PETSC_TRUE;
4872   ierr = PetscOptionsBegin(((PetscObject)mat)->comm,((PetscObject)mat)->prefix,"Matrix Options","Mat");CHKERRQ(ierr);
4873     ierr = PetscOptionsBool("-mat_view_info","Information on matrix size","MatView",flg1,&flg1,PETSC_NULL);CHKERRQ(ierr);
4874     ierr = PetscOptionsBool("-mat_view_info_detailed","Nonzeros in the matrix","MatView",flg2,&flg2,PETSC_NULL);CHKERRQ(ierr);
4875     ierr = PetscOptionsBool("-mat_view","Print matrix to stdout","MatView",flg3,&flg3,PETSC_NULL);CHKERRQ(ierr);
4876     ierr = PetscOptionsBool("-mat_view_matlab","Print matrix to stdout in a format Matlab can read","MatView",flg4,&flg4,PETSC_NULL);CHKERRQ(ierr);
4877 #if defined(PETSC_USE_SOCKET_VIEWER)
4878     ierr = PetscOptionsBool("-mat_view_socket","Send matrix to socket (can be read from matlab)","MatView",flg5,&flg5,PETSC_NULL);CHKERRQ(ierr);
4879 #endif
4880     ierr = PetscOptionsBool("-mat_view_binary","Save matrix to file in binary format","MatView",flg6,&flg6,PETSC_NULL);CHKERRQ(ierr);
4881     ierr = PetscOptionsBool("-mat_view_draw","Draw the matrix nonzero structure","MatView",flg7,&flg7,PETSC_NULL);CHKERRQ(ierr);
4882   ierr = PetscOptionsEnd();CHKERRQ(ierr);
4883 
4884   if (flg1) {
4885     PetscViewer viewer;
4886 
4887     ierr = PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);CHKERRQ(ierr);
4888     ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO);CHKERRQ(ierr);
4889     ierr = MatView(mat,viewer);CHKERRQ(ierr);
4890     ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
4891   }
4892   if (flg2) {
4893     PetscViewer viewer;
4894 
4895     ierr = PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);CHKERRQ(ierr);
4896     ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO_DETAIL);CHKERRQ(ierr);
4897     ierr = MatView(mat,viewer);CHKERRQ(ierr);
4898     ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
4899   }
4900   if (flg3) {
4901     PetscViewer viewer;
4902 
4903     ierr = PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);CHKERRQ(ierr);
4904     ierr = MatView(mat,viewer);CHKERRQ(ierr);
4905   }
4906   if (flg4) {
4907     PetscViewer viewer;
4908 
4909     ierr = PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);CHKERRQ(ierr);
4910     ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr);
4911     ierr = MatView(mat,viewer);CHKERRQ(ierr);
4912     ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
4913   }
4914 #if defined(PETSC_USE_SOCKET_VIEWER)
4915   if (flg5) {
4916     ierr = MatView(mat,PETSC_VIEWER_SOCKET_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4917     ierr = PetscViewerFlush(PETSC_VIEWER_SOCKET_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4918   }
4919 #endif
4920   if (flg6) {
4921     ierr = MatView(mat,PETSC_VIEWER_BINARY_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4922     ierr = PetscViewerFlush(PETSC_VIEWER_BINARY_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4923   }
4924   if (flg7) {
4925     ierr = PetscOptionsGetBool(((PetscObject)mat)->prefix,"-mat_view_contour",&flg8,PETSC_NULL);CHKERRQ(ierr);
4926     if (flg8) {
4927       PetscViewerPushFormat(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm),PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
4928     }
4929     ierr = MatView(mat,PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4930     ierr = PetscViewerFlush(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4931     if (flg8) {
4932       PetscViewerPopFormat(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4933     }
4934   }
4935   incall = PETSC_FALSE;
4936   PetscFunctionReturn(0);
4937 }
4938 
4939 #undef __FUNCT__
4940 #define __FUNCT__ "MatAssemblyEnd"
4941 /*@
4942    MatAssemblyEnd - Completes assembling the matrix.  This routine should
4943    be called after MatAssemblyBegin().
4944 
4945    Collective on Mat
4946 
4947    Input Parameters:
4948 +  mat - the matrix
4949 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
4950 
4951    Options Database Keys:
4952 +  -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly()
4953 .  -mat_view_info_detailed - Prints more detailed info
4954 .  -mat_view - Prints matrix in ASCII format
4955 .  -mat_view_matlab - Prints matrix in Matlab format
4956 .  -mat_view_draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
4957 .  -display <name> - Sets display name (default is host)
4958 .  -draw_pause <sec> - Sets number of seconds to pause after display
4959 .  -mat_view_socket - Sends matrix to socket, can be accessed from Matlab (See the <a href="../../docs/manual.pdf">users manual</a>)
4960 .  -viewer_socket_machine <machine>
4961 .  -viewer_socket_port <port>
4962 .  -mat_view_binary - save matrix to file in binary format
4963 -  -viewer_binary_filename <name>
4964 
4965    Notes:
4966    MatSetValues() generally caches the values.  The matrix is ready to
4967    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4968    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4969    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4970    using the matrix.
4971 
4972    Level: beginner
4973 
4974 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), MatView(), MatAssembled(), PetscViewerSocketOpen()
4975 @*/
4976 PetscErrorCode PETSCMAT_DLLEXPORT MatAssemblyEnd(Mat mat,MatAssemblyType type)
4977 {
4978   PetscErrorCode  ierr;
4979   static PetscInt inassm = 0;
4980   PetscBool       flg = PETSC_FALSE;
4981 
4982   PetscFunctionBegin;
4983   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4984   PetscValidType(mat,1);
4985 
4986   inassm++;
4987   MatAssemblyEnd_InUse++;
4988   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
4989     ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
4990     if (mat->ops->assemblyend) {
4991       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
4992     }
4993     ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
4994   } else {
4995     if (mat->ops->assemblyend) {
4996       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
4997     }
4998   }
4999 
5000   /* Flush assembly is not a true assembly */
5001   if (type != MAT_FLUSH_ASSEMBLY) {
5002     mat->assembled  = PETSC_TRUE; mat->num_ass++;
5003   }
5004   mat->insertmode = NOT_SET_VALUES;
5005   MatAssemblyEnd_InUse--;
5006   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5007   if (!mat->symmetric_eternal) {
5008     mat->symmetric_set              = PETSC_FALSE;
5009     mat->hermitian_set              = PETSC_FALSE;
5010     mat->structurally_symmetric_set = PETSC_FALSE;
5011   }
5012   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
5013     ierr = MatView_Private(mat);CHKERRQ(ierr);
5014     ierr = PetscOptionsGetBool(((PetscObject)mat)->prefix,"-mat_is_symmetric",&flg,PETSC_NULL);CHKERRQ(ierr);
5015     if (flg) {
5016       PetscReal tol = 0.0;
5017       ierr = PetscOptionsGetReal(((PetscObject)mat)->prefix,"-mat_is_symmetric",&tol,PETSC_NULL);CHKERRQ(ierr);
5018       ierr = MatIsSymmetric(mat,tol,&flg);CHKERRQ(ierr);
5019       if (flg) {
5020         ierr = PetscPrintf(((PetscObject)mat)->comm,"Matrix is symmetric (tolerance %G)\n",tol);CHKERRQ(ierr);
5021       } else {
5022         ierr = PetscPrintf(((PetscObject)mat)->comm,"Matrix is not symmetric (tolerance %G)\n",tol);CHKERRQ(ierr);
5023       }
5024     }
5025   }
5026   inassm--;
5027 #if defined(PETSC_HAVE_CUDA)
5028   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5029     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5030   }
5031 #endif
5032   PetscFunctionReturn(0);
5033 }
5034 
5035 #undef __FUNCT__
5036 #define __FUNCT__ "MatSetOption"
5037 /*@
5038    MatSetOption - Sets a parameter option for a matrix. Some options
5039    may be specific to certain storage formats.  Some options
5040    determine how values will be inserted (or added). Sorted,
5041    row-oriented input will generally assemble the fastest. The default
5042    is row-oriented, nonsorted input.
5043 
5044    Logically Collective on Mat
5045 
5046    Input Parameters:
5047 +  mat - the matrix
5048 .  option - the option, one of those listed below (and possibly others),
5049 -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5050 
5051   Options Describing Matrix Structure:
5052 +    MAT_SPD - symmetric positive definite
5053 -    MAT_SYMMETRIC - symmetric in terms of both structure and value
5054 .    MAT_HERMITIAN - transpose is the complex conjugation
5055 .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5056 -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5057                             you set to be kept with all future use of the matrix
5058                             including after MatAssemblyBegin/End() which could
5059                             potentially change the symmetry structure, i.e. you
5060                             KNOW the matrix will ALWAYS have the property you set.
5061 
5062 
5063    Options For Use with MatSetValues():
5064    Insert a logically dense subblock, which can be
5065 .    MAT_ROW_ORIENTED - row-oriented (default)
5066 
5067    Note these options reflect the data you pass in with MatSetValues(); it has
5068    nothing to do with how the data is stored internally in the matrix
5069    data structure.
5070 
5071    When (re)assembling a matrix, we can restrict the input for
5072    efficiency/debugging purposes.  These options include
5073 +    MAT_NEW_NONZERO_LOCATIONS - additional insertions will be
5074         allowed if they generate a new nonzero
5075 .    MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
5076 .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
5077 .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
5078 .    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
5079 +    MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
5080         any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
5081         performance for very large process counts.
5082 
5083    Notes:
5084    Some options are relevant only for particular matrix types and
5085    are thus ignored by others.  Other options are not supported by
5086    certain matrix types and will generate an error message if set.
5087 
5088    If using a Fortran 77 module to compute a matrix, one may need to
5089    use the column-oriented option (or convert to the row-oriented
5090    format).
5091 
5092    MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
5093    that would generate a new entry in the nonzero structure is instead
5094    ignored.  Thus, if memory has not alredy been allocated for this particular
5095    data, then the insertion is ignored. For dense matrices, in which
5096    the entire array is allocated, no entries are ever ignored.
5097    Set after the first MatAssemblyEnd()
5098 
5099    MAT_NEW_NONZERO_LOCATION_ERR indicates that any add or insertion
5100    that would generate a new entry in the nonzero structure instead produces
5101    an error. (Currently supported for AIJ and BAIJ formats only.)
5102    This is a useful flag when using SAME_NONZERO_PATTERN in calling
5103    KSPSetOperators() to ensure that the nonzero pattern truely does
5104    remain unchanged. Set after the first MatAssemblyEnd()
5105 
5106    MAT_NEW_NONZERO_ALLOCATION_ERR indicates that any add or insertion
5107    that would generate a new entry that has not been preallocated will
5108    instead produce an error. (Currently supported for AIJ and BAIJ formats
5109    only.) This is a useful flag when debugging matrix memory preallocation.
5110 
5111    MAT_IGNORE_OFF_PROC_ENTRIES indicates entries destined for
5112    other processors should be dropped, rather than stashed.
5113    This is useful if you know that the "owning" processor is also
5114    always generating the correct matrix entries, so that PETSc need
5115    not transfer duplicate entries generated on another processor.
5116 
5117    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5118    searches during matrix assembly. When this flag is set, the hash table
5119    is created during the first Matrix Assembly. This hash table is
5120    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5121    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5122    should be used with MAT_USE_HASH_TABLE flag. This option is currently
5123    supported by MATMPIBAIJ format only.
5124 
5125    MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries
5126    are kept in the nonzero structure
5127 
5128    MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
5129    a zero location in the matrix
5130 
5131    MAT_USE_INODES - indicates using inode version of the code - works with AIJ and
5132    ROWBS matrix types
5133 
5134   MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the
5135         zero row routines and thus improves performance for very large process counts.
5136 
5137    Level: intermediate
5138 
5139    Concepts: matrices^setting options
5140 
5141 @*/
5142 PetscErrorCode PETSCMAT_DLLEXPORT MatSetOption(Mat mat,MatOption op,PetscBool  flg)
5143 {
5144   PetscErrorCode ierr;
5145 
5146   PetscFunctionBegin;
5147   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5148   PetscValidType(mat,1);
5149   PetscValidLogicalCollectiveEnum(mat,op,2);
5150   PetscValidLogicalCollectiveBool(mat,flg,3);
5151 
5152   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);
5153   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()");
5154   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5155   switch (op) {
5156   case MAT_NO_OFF_PROC_ENTRIES:
5157     mat->nooffprocentries                = flg;
5158     PetscFunctionReturn(0);
5159     break;
5160   case MAT_NO_OFF_PROC_ZERO_ROWS:
5161     mat->nooffproczerorows               = flg;
5162     PetscFunctionReturn(0);
5163     break;
5164   case MAT_SPD:
5165     mat->spd_set                         = PETSC_TRUE;
5166     mat->spd                             = flg;
5167     if (flg) {
5168       mat->symmetric                     = PETSC_TRUE;
5169       mat->structurally_symmetric        = PETSC_TRUE;
5170       mat->symmetric_set                 = PETSC_TRUE;
5171       mat->structurally_symmetric_set    = PETSC_TRUE;
5172     }
5173     break;
5174   case MAT_SYMMETRIC:
5175     mat->symmetric                       = flg;
5176     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5177     mat->symmetric_set                   = PETSC_TRUE;
5178     mat->structurally_symmetric_set      = flg;
5179     break;
5180   case MAT_HERMITIAN:
5181     mat->hermitian                       = flg;
5182     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5183     mat->hermitian_set                   = PETSC_TRUE;
5184     mat->structurally_symmetric_set      = flg;
5185     break;
5186   case MAT_STRUCTURALLY_SYMMETRIC:
5187     mat->structurally_symmetric          = flg;
5188     mat->structurally_symmetric_set      = PETSC_TRUE;
5189     break;
5190   case MAT_SYMMETRY_ETERNAL:
5191     mat->symmetric_eternal               = flg;
5192     break;
5193   default:
5194     break;
5195   }
5196   if (mat->ops->setoption) {
5197     ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr);
5198   }
5199   PetscFunctionReturn(0);
5200 }
5201 
5202 #undef __FUNCT__
5203 #define __FUNCT__ "MatZeroEntries"
5204 /*@
5205    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5206    this routine retains the old nonzero structure.
5207 
5208    Logically Collective on Mat
5209 
5210    Input Parameters:
5211 .  mat - the matrix
5212 
5213    Level: intermediate
5214 
5215    Concepts: matrices^zeroing
5216 
5217 .seealso: MatZeroRows()
5218 @*/
5219 PetscErrorCode PETSCMAT_DLLEXPORT MatZeroEntries(Mat mat)
5220 {
5221   PetscErrorCode ierr;
5222 
5223   PetscFunctionBegin;
5224   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5225   PetscValidType(mat,1);
5226   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5227   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");
5228   if (!mat->ops->zeroentries) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5229   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5230 
5231   ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5232   ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
5233   ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5234   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5235 #if defined(PETSC_HAVE_CUDA)
5236   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5237     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5238   }
5239 #endif
5240   PetscFunctionReturn(0);
5241 }
5242 
5243 #undef __FUNCT__
5244 #define __FUNCT__ "MatZeroRowsColumns"
5245 /*@C
5246    MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal)
5247    of a set of rows and columns of a matrix.
5248 
5249    Collective on Mat
5250 
5251    Input Parameters:
5252 +  mat - the matrix
5253 .  numRows - the number of rows to remove
5254 .  rows - the global row indices
5255 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5256 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5257 -  b - optional vector of right hand side, that will be adjusted by provided solution
5258 
5259    Notes:
5260    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5261 
5262    The user can set a value in the diagonal entry (or for the AIJ and
5263    row formats can optionally remove the main diagonal entry from the
5264    nonzero structure as well, by passing 0.0 as the final argument).
5265 
5266    For the parallel case, all processes that share the matrix (i.e.,
5267    those in the communicator used for matrix creation) MUST call this
5268    routine, regardless of whether any rows being zeroed are owned by
5269    them.
5270 
5271    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5272    list only rows local to itself).
5273 
5274    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5275 
5276    Level: intermediate
5277 
5278    Concepts: matrices^zeroing rows
5279 
5280 .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumnsIS()
5281 @*/
5282 PetscErrorCode PETSCMAT_DLLEXPORT MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5283 {
5284   PetscErrorCode ierr;
5285 
5286   PetscFunctionBegin;
5287   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5288   PetscValidType(mat,1);
5289   if (numRows) PetscValidIntPointer(rows,3);
5290   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5291   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5292   if (!mat->ops->zerorowscolumns) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5293   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5294 
5295   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5296   ierr = MatView_Private(mat);CHKERRQ(ierr);
5297   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5298 #if defined(PETSC_HAVE_CUDA)
5299   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5300     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5301   }
5302 #endif
5303   PetscFunctionReturn(0);
5304 }
5305 
5306 #undef __FUNCT__
5307 #define __FUNCT__ "MatZeroRowsColumnsIS"
5308 /*@C
5309    MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
5310    of a set of rows and columns of a matrix.
5311 
5312    Collective on Mat
5313 
5314    Input Parameters:
5315 +  mat - the matrix
5316 .  is - the rows to zero
5317 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5318 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5319 -  b - optional vector of right hand side, that will be adjusted by provided solution
5320 
5321    Notes:
5322    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5323 
5324    The user can set a value in the diagonal entry (or for the AIJ and
5325    row formats can optionally remove the main diagonal entry from the
5326    nonzero structure as well, by passing 0.0 as the final argument).
5327 
5328    For the parallel case, all processes that share the matrix (i.e.,
5329    those in the communicator used for matrix creation) MUST call this
5330    routine, regardless of whether any rows being zeroed are owned by
5331    them.
5332 
5333    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5334    list only rows local to itself).
5335 
5336    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5337 
5338    Level: intermediate
5339 
5340    Concepts: matrices^zeroing rows
5341 
5342 .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumns()
5343 @*/
5344 PetscErrorCode PETSCMAT_DLLEXPORT MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5345 {
5346   PetscErrorCode ierr;
5347   PetscInt       numRows;
5348   const PetscInt *rows;
5349 
5350   PetscFunctionBegin;
5351   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5352   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5353   PetscValidType(mat,1);
5354   PetscValidType(is,2);
5355   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5356   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5357   ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5358   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5359   PetscFunctionReturn(0);
5360 }
5361 
5362 #undef __FUNCT__
5363 #define __FUNCT__ "MatZeroRows"
5364 /*@C
5365    MatZeroRows - Zeros all entries (except possibly the main diagonal)
5366    of a set of rows of a matrix.
5367 
5368    Collective on Mat
5369 
5370    Input Parameters:
5371 +  mat - the matrix
5372 .  numRows - the number of rows to remove
5373 .  rows - the global row indices
5374 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5375 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5376 -  b - optional vector of right hand side, that will be adjusted by provided solution
5377 
5378    Notes:
5379    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5380    but does not release memory.  For the dense and block diagonal
5381    formats this does not alter the nonzero structure.
5382 
5383    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5384    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5385    merely zeroed.
5386 
5387    The user can set a value in the diagonal entry (or for the AIJ and
5388    row formats can optionally remove the main diagonal entry from the
5389    nonzero structure as well, by passing 0.0 as the final argument).
5390 
5391    For the parallel case, all processes that share the matrix (i.e.,
5392    those in the communicator used for matrix creation) MUST call this
5393    routine, regardless of whether any rows being zeroed are owned by
5394    them.
5395 
5396    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5397    list only rows local to itself).
5398 
5399    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5400    owns that are to be zeroed. This saves a global synchronization in the implementation.
5401 
5402    Level: intermediate
5403 
5404    Concepts: matrices^zeroing rows
5405 
5406 .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5407 @*/
5408 PetscErrorCode PETSCMAT_DLLEXPORT MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5409 {
5410   PetscErrorCode ierr;
5411 
5412   PetscFunctionBegin;
5413   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5414   PetscValidType(mat,1);
5415   if (numRows) PetscValidIntPointer(rows,3);
5416   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5417   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5418   if (!mat->ops->zerorows) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5419   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5420 
5421   ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5422   ierr = MatView_Private(mat);CHKERRQ(ierr);
5423   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5424 #if defined(PETSC_HAVE_CUDA)
5425   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5426     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5427   }
5428 #endif
5429   PetscFunctionReturn(0);
5430 }
5431 
5432 #undef __FUNCT__
5433 #define __FUNCT__ "MatZeroRowsIS"
5434 /*@C
5435    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5436    of a set of rows of a matrix.
5437 
5438    Collective on Mat
5439 
5440    Input Parameters:
5441 +  mat - the matrix
5442 .  is - index set of rows to remove
5443 .  diag - value put in all diagonals of eliminated rows
5444 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5445 -  b - optional vector of right hand side, that will be adjusted by provided solution
5446 
5447    Notes:
5448    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5449    but does not release memory.  For the dense and block diagonal
5450    formats this does not alter the nonzero structure.
5451 
5452    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5453    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5454    merely zeroed.
5455 
5456    The user can set a value in the diagonal entry (or for the AIJ and
5457    row formats can optionally remove the main diagonal entry from the
5458    nonzero structure as well, by passing 0.0 as the final argument).
5459 
5460    For the parallel case, all processes that share the matrix (i.e.,
5461    those in the communicator used for matrix creation) MUST call this
5462    routine, regardless of whether any rows being zeroed are owned by
5463    them.
5464 
5465    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5466    list only rows local to itself).
5467 
5468    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5469    owns that are to be zeroed. This saves a global synchronization in the implementation.
5470 
5471    Level: intermediate
5472 
5473    Concepts: matrices^zeroing rows
5474 
5475 .seealso: MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5476 @*/
5477 PetscErrorCode PETSCMAT_DLLEXPORT MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5478 {
5479   PetscInt       numRows;
5480   const PetscInt *rows;
5481   PetscErrorCode ierr;
5482 
5483   PetscFunctionBegin;
5484   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5485   PetscValidType(mat,1);
5486   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5487   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5488   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5489   ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5490   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5491   PetscFunctionReturn(0);
5492 }
5493 
5494 #undef __FUNCT__
5495 #define __FUNCT__ "MatZeroRowsStencil"
5496 /*@C
5497    MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
5498    of a set of rows of a matrix. These rows must be local to the process.
5499 
5500    Collective on Mat
5501 
5502    Input Parameters:
5503 +  mat - the matrix
5504 .  numRows - the number of rows to remove
5505 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
5506 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5507 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5508 -  b - optional vector of right hand side, that will be adjusted by provided solution
5509 
5510    Notes:
5511    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5512    but does not release memory.  For the dense and block diagonal
5513    formats this does not alter the nonzero structure.
5514 
5515    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5516    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5517    merely zeroed.
5518 
5519    The user can set a value in the diagonal entry (or for the AIJ and
5520    row formats can optionally remove the main diagonal entry from the
5521    nonzero structure as well, by passing 0.0 as the final argument).
5522 
5523    For the parallel case, all processes that share the matrix (i.e.,
5524    those in the communicator used for matrix creation) MUST call this
5525    routine, regardless of whether any rows being zeroed are owned by
5526    them.
5527 
5528    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5529    list only rows local to itself).
5530 
5531    The grid coordinates are across the entire grid, not just the local portion
5532 
5533    In Fortran idxm and idxn should be declared as
5534 $     MatStencil idxm(4,m)
5535    and the values inserted using
5536 $    idxm(MatStencil_i,1) = i
5537 $    idxm(MatStencil_j,1) = j
5538 $    idxm(MatStencil_k,1) = k
5539 $    idxm(MatStencil_c,1) = c
5540    etc
5541 
5542    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5543    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5544    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for the DMDA_NONPERIODIC
5545    wrap.
5546 
5547    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
5548    a single value per point) you can skip filling those indices.
5549 
5550    Level: intermediate
5551 
5552    Concepts: matrices^zeroing rows
5553 
5554 .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5555 @*/
5556 PetscErrorCode PETSCMAT_DLLEXPORT MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5557 {
5558   PetscInt       dim    = mat->stencil.dim;
5559   PetscInt       sdim   = dim - (1 - (PetscInt) mat->stencil.noc);
5560   PetscInt      *dims   = mat->stencil.dims+1;
5561   PetscInt      *starts = mat->stencil.starts;
5562   PetscInt      *dxm    = (PetscInt *) rows;
5563   PetscInt      *jdxm, i, j, tmp, numNewRows = 0;
5564   PetscErrorCode ierr;
5565 
5566   PetscFunctionBegin;
5567   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5568   PetscValidType(mat,1);
5569   if (numRows) PetscValidIntPointer(rows,3);
5570 
5571   ierr = PetscMalloc(numRows * sizeof(PetscInt), &jdxm);CHKERRQ(ierr);
5572   for(i = 0; i < numRows; ++i) {
5573     /* Skip unused dimensions (they are ordered k, j, i, c) */
5574     for(j = 0; j < 3-sdim; ++j) dxm++;
5575     /* Local index in X dir */
5576     tmp = *dxm++ - starts[0];
5577     /* Loop over remaining dimensions */
5578     for(j = 0; j < dim-1; ++j) {
5579       /* If nonlocal, set index to be negative */
5580       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5581       /* Update local index */
5582       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5583     }
5584     /* Skip component slot if necessary */
5585     if (mat->stencil.noc) dxm++;
5586     /* Local row number */
5587     if (tmp >= 0) {
5588       jdxm[numNewRows++] = tmp;
5589     }
5590   }
5591   ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
5592   ierr = PetscFree(jdxm);CHKERRQ(ierr);
5593   PetscFunctionReturn(0);
5594 }
5595 
5596 #undef __FUNCT__
5597 #define __FUNCT__ "MatZeroRowsLocal"
5598 /*@C
5599    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
5600    of a set of rows of a matrix; using local numbering of rows.
5601 
5602    Collective on Mat
5603 
5604    Input Parameters:
5605 +  mat - the matrix
5606 .  numRows - the number of rows to remove
5607 .  rows - the global row indices
5608 .  diag - value put in all diagonals of eliminated rows
5609 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5610 -  b - optional vector of right hand side, that will be adjusted by provided solution
5611 
5612    Notes:
5613    Before calling MatZeroRowsLocal(), the user must first set the
5614    local-to-global mapping by calling MatSetLocalToGlobalMapping().
5615 
5616    For the AIJ matrix formats this removes the old nonzero structure,
5617    but does not release memory.  For the dense and block diagonal
5618    formats this does not alter the nonzero structure.
5619 
5620    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5621    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5622    merely zeroed.
5623 
5624    The user can set a value in the diagonal entry (or for the AIJ and
5625    row formats can optionally remove the main diagonal entry from the
5626    nonzero structure as well, by passing 0.0 as the final argument).
5627 
5628    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5629    owns that are to be zeroed. This saves a global synchronization in the implementation.
5630 
5631    Level: intermediate
5632 
5633    Concepts: matrices^zeroing
5634 
5635 .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5636 @*/
5637 PetscErrorCode PETSCMAT_DLLEXPORT MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5638 {
5639   PetscErrorCode ierr;
5640   PetscMPIInt    size;
5641 
5642   PetscFunctionBegin;
5643   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5644   PetscValidType(mat,1);
5645   if (numRows) PetscValidIntPointer(rows,3);
5646   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5647   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5648   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5649 
5650   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
5651   if (mat->ops->zerorowslocal) {
5652     ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5653   } else if (size == 1) {
5654     ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5655   } else {
5656     IS             is, newis;
5657     const PetscInt *newRows;
5658 
5659     if (!mat->rmapping) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5660     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
5661     ierr = ISLocalToGlobalMappingApplyIS(mat->rmapping,is,&newis);CHKERRQ(ierr);
5662     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
5663     ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
5664     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
5665     ierr = ISDestroy(newis);CHKERRQ(ierr);
5666     ierr = ISDestroy(is);CHKERRQ(ierr);
5667   }
5668   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5669 #if defined(PETSC_HAVE_CUDA)
5670   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5671     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5672   }
5673 #endif
5674   PetscFunctionReturn(0);
5675 }
5676 
5677 #undef __FUNCT__
5678 #define __FUNCT__ "MatZeroRowsLocalIS"
5679 /*@C
5680    MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
5681    of a set of rows of a matrix; using local numbering of rows.
5682 
5683    Collective on Mat
5684 
5685    Input Parameters:
5686 +  mat - the matrix
5687 .  is - index set of rows to remove
5688 .  diag - value put in all diagonals of eliminated rows
5689 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5690 -  b - optional vector of right hand side, that will be adjusted by provided solution
5691 
5692    Notes:
5693    Before calling MatZeroRowsLocalIS(), the user must first set the
5694    local-to-global mapping by calling MatSetLocalToGlobalMapping().
5695 
5696    For the AIJ matrix formats this removes the old nonzero structure,
5697    but does not release memory.  For the dense and block diagonal
5698    formats this does not alter the nonzero structure.
5699 
5700    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5701    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5702    merely zeroed.
5703 
5704    The user can set a value in the diagonal entry (or for the AIJ and
5705    row formats can optionally remove the main diagonal entry from the
5706    nonzero structure as well, by passing 0.0 as the final argument).
5707 
5708    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5709    owns that are to be zeroed. This saves a global synchronization in the implementation.
5710 
5711    Level: intermediate
5712 
5713    Concepts: matrices^zeroing
5714 
5715 .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5716 @*/
5717 PetscErrorCode PETSCMAT_DLLEXPORT MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5718 {
5719   PetscErrorCode ierr;
5720   PetscInt       numRows;
5721   const PetscInt *rows;
5722 
5723   PetscFunctionBegin;
5724   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5725   PetscValidType(mat,1);
5726   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5727   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5728   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5729   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5730 
5731   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5732   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5733   ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5734   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5735   PetscFunctionReturn(0);
5736 }
5737 
5738 #undef __FUNCT__
5739 #define __FUNCT__ "MatZeroRowsColumnsLocal"
5740 /*@C
5741    MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
5742    of a set of rows and columns of a matrix; using local numbering of rows.
5743 
5744    Collective on Mat
5745 
5746    Input Parameters:
5747 +  mat - the matrix
5748 .  numRows - the number of rows to remove
5749 .  rows - the global row indices
5750 .  diag - value put in all diagonals of eliminated rows
5751 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5752 -  b - optional vector of right hand side, that will be adjusted by provided solution
5753 
5754    Notes:
5755    Before calling MatZeroRowsColumnsLocal(), the user must first set the
5756    local-to-global mapping by calling MatSetLocalToGlobalMapping().
5757 
5758    The user can set a value in the diagonal entry (or for the AIJ and
5759    row formats can optionally remove the main diagonal entry from the
5760    nonzero structure as well, by passing 0.0 as the final argument).
5761 
5762    Level: intermediate
5763 
5764    Concepts: matrices^zeroing
5765 
5766 .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5767 @*/
5768 PetscErrorCode PETSCMAT_DLLEXPORT MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5769 {
5770   PetscErrorCode ierr;
5771   PetscMPIInt    size;
5772 
5773   PetscFunctionBegin;
5774   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5775   PetscValidType(mat,1);
5776   if (numRows) PetscValidIntPointer(rows,3);
5777   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5778   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5779   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5780 
5781   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
5782   if (size == 1) {
5783     ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5784   } else {
5785     IS             is, newis;
5786     const PetscInt *newRows;
5787 
5788     if (!mat->cmapping) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5789     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
5790     ierr = ISLocalToGlobalMappingApplyIS(mat->cmapping,is,&newis);CHKERRQ(ierr);
5791     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
5792     ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
5793     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
5794     ierr = ISDestroy(newis);CHKERRQ(ierr);
5795     ierr = ISDestroy(is);CHKERRQ(ierr);
5796   }
5797   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5798 #if defined(PETSC_HAVE_CUDA)
5799   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5800     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5801   }
5802 #endif
5803   PetscFunctionReturn(0);
5804 }
5805 
5806 #undef __FUNCT__
5807 #define __FUNCT__ "MatZeroRowsColumnsLocalIS"
5808 /*@C
5809    MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
5810    of a set of rows and columns of a matrix; using local numbering of rows.
5811 
5812    Collective on Mat
5813 
5814    Input Parameters:
5815 +  mat - the matrix
5816 .  is - index set of rows to remove
5817 .  diag - value put in all diagonals of eliminated rows
5818 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5819 -  b - optional vector of right hand side, that will be adjusted by provided solution
5820 
5821    Notes:
5822    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
5823    local-to-global mapping by calling MatSetLocalToGlobalMapping().
5824 
5825    The user can set a value in the diagonal entry (or for the AIJ and
5826    row formats can optionally remove the main diagonal entry from the
5827    nonzero structure as well, by passing 0.0 as the final argument).
5828 
5829    Level: intermediate
5830 
5831    Concepts: matrices^zeroing
5832 
5833 .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5834 @*/
5835 PetscErrorCode PETSCMAT_DLLEXPORT MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5836 {
5837   PetscErrorCode ierr;
5838   PetscInt       numRows;
5839   const PetscInt *rows;
5840 
5841   PetscFunctionBegin;
5842   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5843   PetscValidType(mat,1);
5844   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5845   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5846   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5847   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5848 
5849   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5850   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5851   ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5852   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5853   PetscFunctionReturn(0);
5854 }
5855 
5856 #undef __FUNCT__
5857 #define __FUNCT__ "MatGetSize"
5858 /*@
5859    MatGetSize - Returns the numbers of rows and columns in a matrix.
5860 
5861    Not Collective
5862 
5863    Input Parameter:
5864 .  mat - the matrix
5865 
5866    Output Parameters:
5867 +  m - the number of global rows
5868 -  n - the number of global columns
5869 
5870    Note: both output parameters can be PETSC_NULL on input.
5871 
5872    Level: beginner
5873 
5874    Concepts: matrices^size
5875 
5876 .seealso: MatGetLocalSize()
5877 @*/
5878 PetscErrorCode PETSCMAT_DLLEXPORT MatGetSize(Mat mat,PetscInt *m,PetscInt* n)
5879 {
5880   PetscFunctionBegin;
5881   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5882   if (m) *m = mat->rmap->N;
5883   if (n) *n = mat->cmap->N;
5884   PetscFunctionReturn(0);
5885 }
5886 
5887 #undef __FUNCT__
5888 #define __FUNCT__ "MatGetLocalSize"
5889 /*@
5890    MatGetLocalSize - Returns the number of rows and columns in a matrix
5891    stored locally.  This information may be implementation dependent, so
5892    use with care.
5893 
5894    Not Collective
5895 
5896    Input Parameters:
5897 .  mat - the matrix
5898 
5899    Output Parameters:
5900 +  m - the number of local rows
5901 -  n - the number of local columns
5902 
5903    Note: both output parameters can be PETSC_NULL on input.
5904 
5905    Level: beginner
5906 
5907    Concepts: matrices^local size
5908 
5909 .seealso: MatGetSize()
5910 @*/
5911 PetscErrorCode PETSCMAT_DLLEXPORT MatGetLocalSize(Mat mat,PetscInt *m,PetscInt* n)
5912 {
5913   PetscFunctionBegin;
5914   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5915   if (m) PetscValidIntPointer(m,2);
5916   if (n) PetscValidIntPointer(n,3);
5917   if (m) *m = mat->rmap->n;
5918   if (n) *n = mat->cmap->n;
5919   PetscFunctionReturn(0);
5920 }
5921 
5922 #undef __FUNCT__
5923 #define __FUNCT__ "MatGetOwnershipRangeColumn"
5924 /*@
5925    MatGetOwnershipRangeColumn - Returns the range of matrix columns owned by
5926    this processor.
5927 
5928    Not Collective, unless matrix has not been allocated, then collective on Mat
5929 
5930    Input Parameters:
5931 .  mat - the matrix
5932 
5933    Output Parameters:
5934 +  m - the global index of the first local column
5935 -  n - one more than the global index of the last local column
5936 
5937    Notes: both output parameters can be PETSC_NULL on input.
5938 
5939    Level: developer
5940 
5941    Concepts: matrices^column ownership
5942 
5943 .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
5944 
5945 @*/
5946 PetscErrorCode PETSCMAT_DLLEXPORT MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt* n)
5947 {
5948   PetscErrorCode ierr;
5949 
5950   PetscFunctionBegin;
5951   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5952   PetscValidType(mat,1);
5953   if (m) PetscValidIntPointer(m,2);
5954   if (n) PetscValidIntPointer(n,3);
5955   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5956   if (m) *m = mat->cmap->rstart;
5957   if (n) *n = mat->cmap->rend;
5958   PetscFunctionReturn(0);
5959 }
5960 
5961 #undef __FUNCT__
5962 #define __FUNCT__ "MatGetOwnershipRange"
5963 /*@
5964    MatGetOwnershipRange - Returns the range of matrix rows owned by
5965    this processor, assuming that the matrix is laid out with the first
5966    n1 rows on the first processor, the next n2 rows on the second, etc.
5967    For certain parallel layouts this range may not be well defined.
5968 
5969    Not Collective, unless matrix has not been allocated, then collective on Mat
5970 
5971    Input Parameters:
5972 .  mat - the matrix
5973 
5974    Output Parameters:
5975 +  m - the global index of the first local row
5976 -  n - one more than the global index of the last local row
5977 
5978    Note: both output parameters can be PETSC_NULL on input.
5979 
5980    Level: beginner
5981 
5982    Concepts: matrices^row ownership
5983 
5984 .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
5985 
5986 @*/
5987 PetscErrorCode PETSCMAT_DLLEXPORT MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt* n)
5988 {
5989   PetscErrorCode ierr;
5990 
5991   PetscFunctionBegin;
5992   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5993   PetscValidType(mat,1);
5994   if (m) PetscValidIntPointer(m,2);
5995   if (n) PetscValidIntPointer(n,3);
5996   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5997   if (m) *m = mat->rmap->rstart;
5998   if (n) *n = mat->rmap->rend;
5999   PetscFunctionReturn(0);
6000 }
6001 
6002 #undef __FUNCT__
6003 #define __FUNCT__ "MatGetOwnershipRanges"
6004 /*@C
6005    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6006    each process
6007 
6008    Not Collective, unless matrix has not been allocated, then collective on Mat
6009 
6010    Input Parameters:
6011 .  mat - the matrix
6012 
6013    Output Parameters:
6014 .  ranges - start of each processors portion plus one more then the total length at the end
6015 
6016    Level: beginner
6017 
6018    Concepts: matrices^row ownership
6019 
6020 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
6021 
6022 @*/
6023 PetscErrorCode PETSCMAT_DLLEXPORT MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6024 {
6025   PetscErrorCode ierr;
6026 
6027   PetscFunctionBegin;
6028   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6029   PetscValidType(mat,1);
6030   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6031   ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr);
6032   PetscFunctionReturn(0);
6033 }
6034 
6035 #undef __FUNCT__
6036 #define __FUNCT__ "MatGetOwnershipRangesColumn"
6037 /*@C
6038    MatGetOwnershipRangesColumn - Returns the range of local columns for each process
6039 
6040    Not Collective, unless matrix has not been allocated, then collective on Mat
6041 
6042    Input Parameters:
6043 .  mat - the matrix
6044 
6045    Output Parameters:
6046 .  ranges - start of each processors portion plus one more then the total length at the end
6047 
6048    Level: beginner
6049 
6050    Concepts: matrices^column ownership
6051 
6052 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
6053 
6054 @*/
6055 PetscErrorCode PETSCMAT_DLLEXPORT MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6056 {
6057   PetscErrorCode ierr;
6058 
6059   PetscFunctionBegin;
6060   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6061   PetscValidType(mat,1);
6062   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6063   ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr);
6064   PetscFunctionReturn(0);
6065 }
6066 
6067 #undef __FUNCT__
6068 #define __FUNCT__ "MatILUFactorSymbolic"
6069 /*@C
6070    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6071    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6072    to complete the factorization.
6073 
6074    Collective on Mat
6075 
6076    Input Parameters:
6077 +  mat - the matrix
6078 .  row - row permutation
6079 .  column - column permutation
6080 -  info - structure containing
6081 $      levels - number of levels of fill.
6082 $      expected fill - as ratio of original fill.
6083 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6084                 missing diagonal entries)
6085 
6086    Output Parameters:
6087 .  fact - new matrix that has been symbolically factored
6088 
6089    Notes:
6090    See the <a href="../../docs/manual.pdf">users manual</a>  for additional information about
6091    choosing the fill factor for better efficiency.
6092 
6093    Most users should employ the simplified KSP interface for linear solvers
6094    instead of working directly with matrix algebra routines such as this.
6095    See, e.g., KSPCreate().
6096 
6097    Level: developer
6098 
6099   Concepts: matrices^symbolic LU factorization
6100   Concepts: matrices^factorization
6101   Concepts: LU^symbolic factorization
6102 
6103 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6104           MatGetOrdering(), MatFactorInfo
6105 
6106     Developer Note: fortran interface is not autogenerated as the f90
6107     interface defintion cannot be generated correctly [due to MatFactorInfo]
6108 
6109 @*/
6110 PetscErrorCode PETSCMAT_DLLEXPORT MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6111 {
6112   PetscErrorCode ierr;
6113 
6114   PetscFunctionBegin;
6115   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6116   PetscValidType(mat,1);
6117   PetscValidHeaderSpecific(row,IS_CLASSID,2);
6118   PetscValidHeaderSpecific(col,IS_CLASSID,3);
6119   PetscValidPointer(info,4);
6120   PetscValidPointer(fact,5);
6121   if (info->levels < 0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6122   if (info->fill < 1.0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
6123   if (!(fact)->ops->ilufactorsymbolic) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s  symbolic ILU",((PetscObject)mat)->type_name);
6124   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6125   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6126   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6127 
6128   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6129   ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
6130   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6131   PetscFunctionReturn(0);
6132 }
6133 
6134 #undef __FUNCT__
6135 #define __FUNCT__ "MatICCFactorSymbolic"
6136 /*@C
6137    MatICCFactorSymbolic - Performs symbolic incomplete
6138    Cholesky factorization for a symmetric matrix.  Use
6139    MatCholeskyFactorNumeric() to complete the factorization.
6140 
6141    Collective on Mat
6142 
6143    Input Parameters:
6144 +  mat - the matrix
6145 .  perm - row and column permutation
6146 -  info - structure containing
6147 $      levels - number of levels of fill.
6148 $      expected fill - as ratio of original fill.
6149 
6150    Output Parameter:
6151 .  fact - the factored matrix
6152 
6153    Notes:
6154    Most users should employ the KSP interface for linear solvers
6155    instead of working directly with matrix algebra routines such as this.
6156    See, e.g., KSPCreate().
6157 
6158    Level: developer
6159 
6160   Concepts: matrices^symbolic incomplete Cholesky factorization
6161   Concepts: matrices^factorization
6162   Concepts: Cholsky^symbolic factorization
6163 
6164 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
6165 
6166     Developer Note: fortran interface is not autogenerated as the f90
6167     interface defintion cannot be generated correctly [due to MatFactorInfo]
6168 
6169 @*/
6170 PetscErrorCode PETSCMAT_DLLEXPORT MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6171 {
6172   PetscErrorCode ierr;
6173 
6174   PetscFunctionBegin;
6175   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6176   PetscValidType(mat,1);
6177   PetscValidHeaderSpecific(perm,IS_CLASSID,2);
6178   PetscValidPointer(info,3);
6179   PetscValidPointer(fact,4);
6180   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6181   if (info->levels < 0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6182   if (info->fill < 1.0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
6183   if (!(fact)->ops->iccfactorsymbolic) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s  symbolic ICC",((PetscObject)mat)->type_name);
6184   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6185   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6186 
6187   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6188   ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
6189   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6190   PetscFunctionReturn(0);
6191 }
6192 
6193 #undef __FUNCT__
6194 #define __FUNCT__ "MatGetArray"
6195 /*@C
6196    MatGetArray - Returns a pointer to the element values in the matrix.
6197    The result of this routine is dependent on the underlying matrix data
6198    structure, and may not even work for certain matrix types.  You MUST
6199    call MatRestoreArray() when you no longer need to access the array.
6200 
6201    Not Collective
6202 
6203    Input Parameter:
6204 .  mat - the matrix
6205 
6206    Output Parameter:
6207 .  v - the location of the values
6208 
6209 
6210    Fortran Note:
6211    This routine is used differently from Fortran, e.g.,
6212 .vb
6213         Mat         mat
6214         PetscScalar mat_array(1)
6215         PetscOffset i_mat
6216         PetscErrorCode ierr
6217         call MatGetArray(mat,mat_array,i_mat,ierr)
6218 
6219   C  Access first local entry in matrix; note that array is
6220   C  treated as one dimensional
6221         value = mat_array(i_mat + 1)
6222 
6223         [... other code ...]
6224         call MatRestoreArray(mat,mat_array,i_mat,ierr)
6225 .ve
6226 
6227    See the <a href="../../docs/manual.pdf#ch_fortran">Fortran chapter of the users manual</a> and
6228    src/mat/examples/tests for details.
6229 
6230    Level: advanced
6231 
6232    Concepts: matrices^access array
6233 
6234 .seealso: MatRestoreArray(), MatGetArrayF90(), MatGetRowIJ()
6235 @*/
6236 PetscErrorCode PETSCMAT_DLLEXPORT MatGetArray(Mat mat,PetscScalar *v[])
6237 {
6238   PetscErrorCode ierr;
6239 
6240   PetscFunctionBegin;
6241   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6242   PetscValidType(mat,1);
6243   PetscValidPointer(v,2);
6244   if (!mat->ops->getarray) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6245   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6246   ierr = (*mat->ops->getarray)(mat,v);CHKERRQ(ierr);
6247   CHKMEMQ;
6248   PetscFunctionReturn(0);
6249 }
6250 
6251 #undef __FUNCT__
6252 #define __FUNCT__ "MatRestoreArray"
6253 /*@C
6254    MatRestoreArray - Restores the matrix after MatGetArray() has been called.
6255 
6256    Not Collective
6257 
6258    Input Parameter:
6259 +  mat - the matrix
6260 -  v - the location of the values
6261 
6262    Fortran Note:
6263    This routine is used differently from Fortran, e.g.,
6264 .vb
6265         Mat         mat
6266         PetscScalar mat_array(1)
6267         PetscOffset i_mat
6268         PetscErrorCode ierr
6269         call MatGetArray(mat,mat_array,i_mat,ierr)
6270 
6271   C  Access first local entry in matrix; note that array is
6272   C  treated as one dimensional
6273         value = mat_array(i_mat + 1)
6274 
6275         [... other code ...]
6276         call MatRestoreArray(mat,mat_array,i_mat,ierr)
6277 .ve
6278 
6279    See the <a href="../../docs/manual.pdf#ch_fortran">Fortran chapter of the users manual</a>
6280    src/mat/examples/tests for details
6281 
6282    Level: advanced
6283 
6284 .seealso: MatGetArray(), MatRestoreArrayF90()
6285 @*/
6286 PetscErrorCode PETSCMAT_DLLEXPORT MatRestoreArray(Mat mat,PetscScalar *v[])
6287 {
6288   PetscErrorCode ierr;
6289 
6290   PetscFunctionBegin;
6291   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6292   PetscValidType(mat,1);
6293   PetscValidPointer(v,2);
6294 #if defined(PETSC_USE_DEBUG)
6295   CHKMEMQ;
6296 #endif
6297   if (!mat->ops->restorearray) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6298   ierr = (*mat->ops->restorearray)(mat,v);CHKERRQ(ierr);
6299   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6300 #if defined(PETSC_HAVE_CUDA)
6301   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
6302     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
6303   }
6304 #endif
6305   PetscFunctionReturn(0);
6306 }
6307 
6308 #undef __FUNCT__
6309 #define __FUNCT__ "MatGetSubMatrices"
6310 /*@C
6311    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
6312    points to an array of valid matrices, they may be reused to store the new
6313    submatrices.
6314 
6315    Collective on Mat
6316 
6317    Input Parameters:
6318 +  mat - the matrix
6319 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6320 .  irow, icol - index sets of rows and columns to extract
6321 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6322 
6323    Output Parameter:
6324 .  submat - the array of submatrices
6325 
6326    Notes:
6327    MatGetSubMatrices() can extract ONLY sequential submatrices
6328    (from both sequential and parallel matrices). Use MatGetSubMatrix()
6329    to extract a parallel submatrix.
6330 
6331    When extracting submatrices from a parallel matrix, each processor can
6332    form a different submatrix by setting the rows and columns of its
6333    individual index sets according to the local submatrix desired.
6334 
6335    When finished using the submatrices, the user should destroy
6336    them with MatDestroyMatrices().
6337 
6338    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6339    original matrix has not changed from that last call to MatGetSubMatrices().
6340 
6341    This routine creates the matrices in submat; you should NOT create them before
6342    calling it. It also allocates the array of matrix pointers submat.
6343 
6344    For BAIJ matrices the index sets must respect the block structure, that is if they
6345    request one row/column in a block, they must request all rows/columns that are in
6346    that block. For example, if the block size is 2 you cannot request just row 0 and
6347    column 0.
6348 
6349    Fortran Note:
6350    The Fortran interface is slightly different from that given below; it
6351    requires one to pass in  as submat a Mat (integer) array of size at least m.
6352 
6353    Level: advanced
6354 
6355    Concepts: matrices^accessing submatrices
6356    Concepts: submatrices
6357 
6358 .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6359 @*/
6360 PetscErrorCode PETSCMAT_DLLEXPORT MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6361 {
6362   PetscErrorCode ierr;
6363   PetscInt        i;
6364   PetscBool       eq;
6365 
6366   PetscFunctionBegin;
6367   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6368   PetscValidType(mat,1);
6369   if (n) {
6370     PetscValidPointer(irow,3);
6371     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6372     PetscValidPointer(icol,4);
6373     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6374   }
6375   PetscValidPointer(submat,6);
6376   if (n && scall == MAT_REUSE_MATRIX) {
6377     PetscValidPointer(*submat,6);
6378     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6379   }
6380   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6381   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6382   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6383   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6384 
6385   ierr = PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
6386   ierr = (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6387   ierr = PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
6388   for (i=0; i<n; i++) {
6389     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6390       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6391       if (eq) {
6392 	if (mat->symmetric){
6393 	  ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6394 	} else if (mat->hermitian) {
6395 	  ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6396 	} else if (mat->structurally_symmetric) {
6397 	  ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6398 	}
6399       }
6400     }
6401   }
6402   PetscFunctionReturn(0);
6403 }
6404 
6405 #undef __FUNCT__
6406 #define __FUNCT__ "MatGetSubMatricesParallel"
6407 PetscErrorCode PETSCMAT_DLLEXPORT MatGetSubMatricesParallel(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6408 {
6409   PetscErrorCode ierr;
6410   PetscInt        i;
6411   PetscBool       eq;
6412 
6413   PetscFunctionBegin;
6414   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6415   PetscValidType(mat,1);
6416   if (n) {
6417     PetscValidPointer(irow,3);
6418     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6419     PetscValidPointer(icol,4);
6420     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6421   }
6422   PetscValidPointer(submat,6);
6423   if (n && scall == MAT_REUSE_MATRIX) {
6424     PetscValidPointer(*submat,6);
6425     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6426   }
6427   if (!mat->ops->getsubmatricesparallel) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6428   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6429   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6430   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6431 
6432   ierr = PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
6433   ierr = (*mat->ops->getsubmatricesparallel)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6434   ierr = PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
6435   for (i=0; i<n; i++) {
6436     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6437       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6438       if (eq) {
6439 	if (mat->symmetric){
6440 	  ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6441 	} else if (mat->hermitian) {
6442 	  ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6443 	} else if (mat->structurally_symmetric) {
6444 	  ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6445 	}
6446       }
6447     }
6448   }
6449   PetscFunctionReturn(0);
6450 }
6451 
6452 #undef __FUNCT__
6453 #define __FUNCT__ "MatDestroyMatrices"
6454 /*@C
6455    MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().
6456 
6457    Collective on Mat
6458 
6459    Input Parameters:
6460 +  n - the number of local matrices
6461 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6462                        sequence of MatGetSubMatrices())
6463 
6464    Level: advanced
6465 
6466     Notes: Frees not only the matrices, but also the array that contains the matrices
6467            In Fortran will not free the array.
6468 
6469 .seealso: MatGetSubMatrices()
6470 @*/
6471 PetscErrorCode PETSCMAT_DLLEXPORT MatDestroyMatrices(PetscInt n,Mat *mat[])
6472 {
6473   PetscErrorCode ierr;
6474   PetscInt       i;
6475 
6476   PetscFunctionBegin;
6477   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6478   PetscValidPointer(mat,2);
6479   for (i=0; i<n; i++) {
6480     ierr = MatDestroy((*mat)[i]);CHKERRQ(ierr);
6481   }
6482   /* memory is allocated even if n = 0 */
6483   ierr = PetscFree(*mat);CHKERRQ(ierr);
6484   PetscFunctionReturn(0);
6485 }
6486 
6487 #undef __FUNCT__
6488 #define __FUNCT__ "MatGetSeqNonzeroStructure"
6489 /*@C
6490    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
6491 
6492    Collective on Mat
6493 
6494    Input Parameters:
6495 .  mat - the matrix
6496 
6497    Output Parameter:
6498 .  matstruct - the sequential matrix with the nonzero structure of mat
6499 
6500   Level: intermediate
6501 
6502 .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
6503 @*/
6504 PetscErrorCode PETSCMAT_DLLEXPORT MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6505 {
6506   PetscErrorCode ierr;
6507 
6508   PetscFunctionBegin;
6509   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6510   PetscValidPointer(matstruct,2);
6511 
6512   PetscValidType(mat,1);
6513   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6514   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6515 
6516   if (!mat->ops->getseqnonzerostructure) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6517   ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
6518   ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr);
6519   ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
6520   PetscFunctionReturn(0);
6521 }
6522 
6523 #undef __FUNCT__
6524 #define __FUNCT__ "MatDestroySeqNonzeroStructure"
6525 /*@C
6526    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
6527 
6528    Collective on Mat
6529 
6530    Input Parameters:
6531 .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
6532                        sequence of MatGetSequentialNonzeroStructure())
6533 
6534    Level: advanced
6535 
6536     Notes: Frees not only the matrices, but also the array that contains the matrices
6537 
6538 .seealso: MatGetSeqNonzeroStructure()
6539 @*/
6540 PetscErrorCode PETSCMAT_DLLEXPORT MatDestroySeqNonzeroStructure(Mat *mat)
6541 {
6542   PetscErrorCode ierr;
6543 
6544   PetscFunctionBegin;
6545   PetscValidPointer(mat,1);
6546   ierr = MatDestroy(*mat);CHKERRQ(ierr);
6547   PetscFunctionReturn(0);
6548 }
6549 
6550 #undef __FUNCT__
6551 #define __FUNCT__ "MatIncreaseOverlap"
6552 /*@
6553    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6554    replaces the index sets by larger ones that represent submatrices with
6555    additional overlap.
6556 
6557    Collective on Mat
6558 
6559    Input Parameters:
6560 +  mat - the matrix
6561 .  n   - the number of index sets
6562 .  is  - the array of index sets (these index sets will changed during the call)
6563 -  ov  - the additional overlap requested
6564 
6565    Level: developer
6566 
6567    Concepts: overlap
6568    Concepts: ASM^computing overlap
6569 
6570 .seealso: MatGetSubMatrices()
6571 @*/
6572 PetscErrorCode PETSCMAT_DLLEXPORT MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6573 {
6574   PetscErrorCode ierr;
6575 
6576   PetscFunctionBegin;
6577   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6578   PetscValidType(mat,1);
6579   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6580   if (n) {
6581     PetscValidPointer(is,3);
6582     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
6583   }
6584   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6585   if (mat->factortype)     SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6586   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6587 
6588   if (!ov) PetscFunctionReturn(0);
6589   if (!mat->ops->increaseoverlap) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6590   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
6591   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
6592   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
6593   PetscFunctionReturn(0);
6594 }
6595 
6596 #undef __FUNCT__
6597 #define __FUNCT__ "MatGetBlockSize"
6598 /*@
6599    MatGetBlockSize - Returns the matrix block size; useful especially for the
6600    block row and block diagonal formats.
6601 
6602    Not Collective
6603 
6604    Input Parameter:
6605 .  mat - the matrix
6606 
6607    Output Parameter:
6608 .  bs - block size
6609 
6610    Notes:
6611    Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ
6612 
6613    Level: intermediate
6614 
6615    Concepts: matrices^block size
6616 
6617 .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ()
6618 @*/
6619 PetscErrorCode PETSCMAT_DLLEXPORT MatGetBlockSize(Mat mat,PetscInt *bs)
6620 {
6621   PetscErrorCode ierr;
6622 
6623   PetscFunctionBegin;
6624   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6625   PetscValidType(mat,1);
6626   PetscValidIntPointer(bs,2);
6627   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6628   *bs = mat->rmap->bs;
6629   PetscFunctionReturn(0);
6630 }
6631 
6632 #undef __FUNCT__
6633 #define __FUNCT__ "MatSetBlockSize"
6634 /*@
6635    MatSetBlockSize - Sets the matrix block size; for many matrix types you
6636      cannot use this and MUST set the blocksize when you preallocate the matrix
6637 
6638    Logically Collective on Mat
6639 
6640    Input Parameters:
6641 +  mat - the matrix
6642 -  bs - block size
6643 
6644    Notes:
6645      For BAIJ matrices, this just checks that the block size agrees with the BAIJ size,
6646      it is not possible to change BAIJ block sizes after preallocation.
6647 
6648    Level: intermediate
6649 
6650    Concepts: matrices^block size
6651 
6652 .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ(), MatGetBlockSize()
6653 @*/
6654 PetscErrorCode PETSCMAT_DLLEXPORT MatSetBlockSize(Mat mat,PetscInt bs)
6655 {
6656   PetscErrorCode ierr;
6657 
6658   PetscFunctionBegin;
6659   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6660   PetscValidType(mat,1);
6661   PetscValidLogicalCollectiveInt(mat,bs,2);
6662   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6663   if (bs < 1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Block size %D, must be positive",bs);
6664   if (mat->ops->setblocksize) {
6665     ierr = (*mat->ops->setblocksize)(mat,bs);CHKERRQ(ierr);
6666   } else {
6667     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Cannot set the blocksize for matrix type %s",((PetscObject)mat)->type_name);
6668   }
6669   PetscFunctionReturn(0);
6670 }
6671 
6672 #undef __FUNCT__
6673 #define __FUNCT__ "MatGetRowIJ"
6674 /*@C
6675     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
6676 
6677    Collective on Mat
6678 
6679     Input Parameters:
6680 +   mat - the matrix
6681 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
6682 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6683                 symmetrized
6684 -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
6685                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6686                  always used.
6687 
6688     Output Parameters:
6689 +   n - number of rows in the (possibly compressed) matrix
6690 .   ia - the row pointers [of length n+1]
6691 .   ja - the column indices
6692 -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
6693            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
6694 
6695     Level: developer
6696 
6697     Notes: You CANNOT change any of the ia[] or ja[] values.
6698 
6699            Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values
6700 
6701     Fortran Node
6702 
6703            In Fortran use
6704 $           PetscInt ia(1), ja(1)
6705 $           PetscOffset iia, jja
6706 $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
6707 $
6708 $          or
6709 $
6710 $           PetscScalar, pointer :: xx_v(:)
6711 $    call  MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
6712 
6713 
6714        Acess the ith and jth entries via ia(iia + i) and ja(jja + j)
6715 
6716 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatGetArray()
6717 @*/
6718 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRowIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6719 {
6720   PetscErrorCode ierr;
6721 
6722   PetscFunctionBegin;
6723   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6724   PetscValidType(mat,1);
6725   PetscValidIntPointer(n,4);
6726   if (ia) PetscValidIntPointer(ia,5);
6727   if (ja) PetscValidIntPointer(ja,6);
6728   PetscValidIntPointer(done,7);
6729   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6730   if (!mat->ops->getrowij) *done = PETSC_FALSE;
6731   else {
6732     *done = PETSC_TRUE;
6733     ierr = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
6734     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6735     ierr = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
6736   }
6737   PetscFunctionReturn(0);
6738 }
6739 
6740 #undef __FUNCT__
6741 #define __FUNCT__ "MatGetColumnIJ"
6742 /*@C
6743     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
6744 
6745     Collective on Mat
6746 
6747     Input Parameters:
6748 +   mat - the matrix
6749 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6750 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6751                 symmetrized
6752 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6753                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6754                  always used.
6755 
6756     Output Parameters:
6757 +   n - number of columns in the (possibly compressed) matrix
6758 .   ia - the column pointers
6759 .   ja - the row indices
6760 -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
6761 
6762     Level: developer
6763 
6764 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6765 @*/
6766 PetscErrorCode PETSCMAT_DLLEXPORT MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6767 {
6768   PetscErrorCode ierr;
6769 
6770   PetscFunctionBegin;
6771   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6772   PetscValidType(mat,1);
6773   PetscValidIntPointer(n,4);
6774   if (ia) PetscValidIntPointer(ia,5);
6775   if (ja) PetscValidIntPointer(ja,6);
6776   PetscValidIntPointer(done,7);
6777   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6778   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
6779   else {
6780     *done = PETSC_TRUE;
6781     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6782   }
6783   PetscFunctionReturn(0);
6784 }
6785 
6786 #undef __FUNCT__
6787 #define __FUNCT__ "MatRestoreRowIJ"
6788 /*@C
6789     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
6790     MatGetRowIJ().
6791 
6792     Collective on Mat
6793 
6794     Input Parameters:
6795 +   mat - the matrix
6796 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6797 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6798                 symmetrized
6799 -   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6800                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6801                  always used.
6802 
6803     Output Parameters:
6804 +   n - size of (possibly compressed) matrix
6805 .   ia - the row pointers
6806 .   ja - the column indices
6807 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
6808 
6809     Level: developer
6810 
6811 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6812 @*/
6813 PetscErrorCode PETSCMAT_DLLEXPORT MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6814 {
6815   PetscErrorCode ierr;
6816 
6817   PetscFunctionBegin;
6818   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6819   PetscValidType(mat,1);
6820   if (ia) PetscValidIntPointer(ia,5);
6821   if (ja) PetscValidIntPointer(ja,6);
6822   PetscValidIntPointer(done,7);
6823   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6824 
6825   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
6826   else {
6827     *done = PETSC_TRUE;
6828     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6829   }
6830   PetscFunctionReturn(0);
6831 }
6832 
6833 #undef __FUNCT__
6834 #define __FUNCT__ "MatRestoreColumnIJ"
6835 /*@C
6836     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
6837     MatGetColumnIJ().
6838 
6839     Collective on Mat
6840 
6841     Input Parameters:
6842 +   mat - the matrix
6843 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6844 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6845                 symmetrized
6846 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6847                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6848                  always used.
6849 
6850     Output Parameters:
6851 +   n - size of (possibly compressed) matrix
6852 .   ia - the column pointers
6853 .   ja - the row indices
6854 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
6855 
6856     Level: developer
6857 
6858 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
6859 @*/
6860 PetscErrorCode PETSCMAT_DLLEXPORT MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6861 {
6862   PetscErrorCode ierr;
6863 
6864   PetscFunctionBegin;
6865   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6866   PetscValidType(mat,1);
6867   if (ia) PetscValidIntPointer(ia,5);
6868   if (ja) PetscValidIntPointer(ja,6);
6869   PetscValidIntPointer(done,7);
6870   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6871 
6872   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
6873   else {
6874     *done = PETSC_TRUE;
6875     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6876   }
6877   PetscFunctionReturn(0);
6878 }
6879 
6880 #undef __FUNCT__
6881 #define __FUNCT__ "MatColoringPatch"
6882 /*@C
6883     MatColoringPatch -Used inside matrix coloring routines that
6884     use MatGetRowIJ() and/or MatGetColumnIJ().
6885 
6886     Collective on Mat
6887 
6888     Input Parameters:
6889 +   mat - the matrix
6890 .   ncolors - max color value
6891 .   n   - number of entries in colorarray
6892 -   colorarray - array indicating color for each column
6893 
6894     Output Parameters:
6895 .   iscoloring - coloring generated using colorarray information
6896 
6897     Level: developer
6898 
6899 .seealso: MatGetRowIJ(), MatGetColumnIJ()
6900 
6901 @*/
6902 PetscErrorCode PETSCMAT_DLLEXPORT MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
6903 {
6904   PetscErrorCode ierr;
6905 
6906   PetscFunctionBegin;
6907   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6908   PetscValidType(mat,1);
6909   PetscValidIntPointer(colorarray,4);
6910   PetscValidPointer(iscoloring,5);
6911   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6912 
6913   if (!mat->ops->coloringpatch){
6914     ierr = ISColoringCreate(((PetscObject)mat)->comm,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
6915   } else {
6916     ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
6917   }
6918   PetscFunctionReturn(0);
6919 }
6920 
6921 
6922 #undef __FUNCT__
6923 #define __FUNCT__ "MatSetUnfactored"
6924 /*@
6925    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
6926 
6927    Logically Collective on Mat
6928 
6929    Input Parameter:
6930 .  mat - the factored matrix to be reset
6931 
6932    Notes:
6933    This routine should be used only with factored matrices formed by in-place
6934    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
6935    format).  This option can save memory, for example, when solving nonlinear
6936    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
6937    ILU(0) preconditioner.
6938 
6939    Note that one can specify in-place ILU(0) factorization by calling
6940 .vb
6941      PCType(pc,PCILU);
6942      PCFactorSeUseInPlace(pc);
6943 .ve
6944    or by using the options -pc_type ilu -pc_factor_in_place
6945 
6946    In-place factorization ILU(0) can also be used as a local
6947    solver for the blocks within the block Jacobi or additive Schwarz
6948    methods (runtime option: -sub_pc_factor_in_place).  See the discussion
6949    of these preconditioners in the <a href="../../docs/manual.pdf#ch_pc">PC chapter of the users manual</a> for details on setting
6950    local solver options.
6951 
6952    Most users should employ the simplified KSP interface for linear solvers
6953    instead of working directly with matrix algebra routines such as this.
6954    See, e.g., KSPCreate().
6955 
6956    Level: developer
6957 
6958 .seealso: PCFactorSetUseInPlace()
6959 
6960    Concepts: matrices^unfactored
6961 
6962 @*/
6963 PetscErrorCode PETSCMAT_DLLEXPORT MatSetUnfactored(Mat mat)
6964 {
6965   PetscErrorCode ierr;
6966 
6967   PetscFunctionBegin;
6968   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6969   PetscValidType(mat,1);
6970   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6971   mat->factortype = MAT_FACTOR_NONE;
6972   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
6973   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
6974   PetscFunctionReturn(0);
6975 }
6976 
6977 /*MC
6978     MatGetArrayF90 - Accesses a matrix array from Fortran90.
6979 
6980     Synopsis:
6981     MatGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
6982 
6983     Not collective
6984 
6985     Input Parameter:
6986 .   x - matrix
6987 
6988     Output Parameters:
6989 +   xx_v - the Fortran90 pointer to the array
6990 -   ierr - error code
6991 
6992     Example of Usage:
6993 .vb
6994       PetscScalar, pointer xx_v(:)
6995       ....
6996       call MatGetArrayF90(x,xx_v,ierr)
6997       a = xx_v(3)
6998       call MatRestoreArrayF90(x,xx_v,ierr)
6999 .ve
7000 
7001     Notes:
7002     Not yet supported for all F90 compilers
7003 
7004     Level: advanced
7005 
7006 .seealso:  MatRestoreArrayF90(), MatGetArray(), MatRestoreArray()
7007 
7008     Concepts: matrices^accessing array
7009 
7010 M*/
7011 
7012 /*MC
7013     MatRestoreArrayF90 - Restores a matrix array that has been
7014     accessed with MatGetArrayF90().
7015 
7016     Synopsis:
7017     MatRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7018 
7019     Not collective
7020 
7021     Input Parameters:
7022 +   x - matrix
7023 -   xx_v - the Fortran90 pointer to the array
7024 
7025     Output Parameter:
7026 .   ierr - error code
7027 
7028     Example of Usage:
7029 .vb
7030        PetscScalar, pointer xx_v(:)
7031        ....
7032        call MatGetArrayF90(x,xx_v,ierr)
7033        a = xx_v(3)
7034        call MatRestoreArrayF90(x,xx_v,ierr)
7035 .ve
7036 
7037     Notes:
7038     Not yet supported for all F90 compilers
7039 
7040     Level: advanced
7041 
7042 .seealso:  MatGetArrayF90(), MatGetArray(), MatRestoreArray()
7043 
7044 M*/
7045 
7046 
7047 #undef __FUNCT__
7048 #define __FUNCT__ "MatGetSubMatrix"
7049 /*@
7050     MatGetSubMatrix - Gets a single submatrix on the same number of processors
7051                       as the original matrix.
7052 
7053     Collective on Mat
7054 
7055     Input Parameters:
7056 +   mat - the original matrix
7057 .   isrow - parallel IS containing the rows this processor should obtain
7058 .   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.
7059 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7060 
7061     Output Parameter:
7062 .   newmat - the new submatrix, of the same type as the old
7063 
7064     Level: advanced
7065 
7066     Notes:
7067     The submatrix will be able to be multiplied with vectors using the same layout as iscol.
7068 
7069     The rows in isrow will be sorted into the same order as the original matrix on each process.
7070 
7071       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7072    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
7073    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7074    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
7075    you are finished using it.
7076 
7077     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7078     the input matrix.
7079 
7080     If iscol is PETSC_NULL then all columns are obtained (not supported in Fortran).
7081 
7082    Example usage:
7083    Consider the following 8x8 matrix with 34 non-zero values, that is
7084    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7085    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7086    as follows:
7087 
7088 .vb
7089             1  2  0  |  0  3  0  |  0  4
7090     Proc0   0  5  6  |  7  0  0  |  8  0
7091             9  0 10  | 11  0  0  | 12  0
7092     -------------------------------------
7093            13  0 14  | 15 16 17  |  0  0
7094     Proc1   0 18  0  | 19 20 21  |  0  0
7095             0  0  0  | 22 23  0  | 24  0
7096     -------------------------------------
7097     Proc2  25 26 27  |  0  0 28  | 29  0
7098            30  0  0  | 31 32 33  |  0 34
7099 .ve
7100 
7101     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is
7102 
7103 .vb
7104             2  0  |  0  3  0  |  0
7105     Proc0   5  6  |  7  0  0  |  8
7106     -------------------------------
7107     Proc1  18  0  | 19 20 21  |  0
7108     -------------------------------
7109     Proc2  26 27  |  0  0 28  | 29
7110             0  0  | 31 32 33  |  0
7111 .ve
7112 
7113 
7114     Concepts: matrices^submatrices
7115 
7116 .seealso: MatGetSubMatrices()
7117 @*/
7118 PetscErrorCode PETSCMAT_DLLEXPORT MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7119 {
7120   PetscErrorCode ierr;
7121   PetscMPIInt    size;
7122   Mat            *local;
7123   IS             iscoltmp;
7124 
7125   PetscFunctionBegin;
7126   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7127   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
7128   if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
7129   PetscValidPointer(newmat,5);
7130   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5);
7131   PetscValidType(mat,1);
7132   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7133   ierr = MatPreallocated(mat);CHKERRQ(ierr);
7134   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
7135 
7136   if (!iscol) {
7137     ierr = ISCreateStride(((PetscObject)mat)->comm,mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr);
7138   } else {
7139     iscoltmp = iscol;
7140   }
7141 
7142   /* if original matrix is on just one processor then use submatrix generated */
7143   if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7144     ierr = MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
7145     if (!iscol) {ierr = ISDestroy(iscoltmp);CHKERRQ(ierr);}
7146     PetscFunctionReturn(0);
7147   } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) {
7148     ierr    = MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
7149     *newmat = *local;
7150     ierr    = PetscFree(local);CHKERRQ(ierr);
7151     if (!iscol) {ierr = ISDestroy(iscoltmp);CHKERRQ(ierr);}
7152     PetscFunctionReturn(0);
7153   } else if (!mat->ops->getsubmatrix) {
7154     /* Create a new matrix type that implements the operation using the full matrix */
7155     switch (cll) {
7156       case MAT_INITIAL_MATRIX:
7157         ierr = MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr);
7158         break;
7159       case MAT_REUSE_MATRIX:
7160         ierr = MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr);
7161         break;
7162       default: SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7163     }
7164     if (!iscol) {ierr = ISDestroy(iscoltmp);CHKERRQ(ierr);}
7165     PetscFunctionReturn(0);
7166   }
7167 
7168   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7169   ierr = (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr);
7170   if (!iscol) {ierr = ISDestroy(iscoltmp);CHKERRQ(ierr);}
7171   ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);
7172   PetscFunctionReturn(0);
7173 }
7174 
7175 #undef __FUNCT__
7176 #define __FUNCT__ "MatStashSetInitialSize"
7177 /*@
7178    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7179    used during the assembly process to store values that belong to
7180    other processors.
7181 
7182    Not Collective
7183 
7184    Input Parameters:
7185 +  mat   - the matrix
7186 .  size  - the initial size of the stash.
7187 -  bsize - the initial size of the block-stash(if used).
7188 
7189    Options Database Keys:
7190 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
7191 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
7192 
7193    Level: intermediate
7194 
7195    Notes:
7196      The block-stash is used for values set with MatSetValuesBlocked() while
7197      the stash is used for values set with MatSetValues()
7198 
7199      Run with the option -info and look for output of the form
7200      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7201      to determine the appropriate value, MM, to use for size and
7202      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7203      to determine the value, BMM to use for bsize
7204 
7205    Concepts: stash^setting matrix size
7206    Concepts: matrices^stash
7207 
7208 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
7209 
7210 @*/
7211 PetscErrorCode PETSCMAT_DLLEXPORT MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7212 {
7213   PetscErrorCode ierr;
7214 
7215   PetscFunctionBegin;
7216   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7217   PetscValidType(mat,1);
7218   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
7219   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
7220   PetscFunctionReturn(0);
7221 }
7222 
7223 #undef __FUNCT__
7224 #define __FUNCT__ "MatInterpolateAdd"
7225 /*@
7226    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
7227      the matrix
7228 
7229    Neighbor-wise Collective on Mat
7230 
7231    Input Parameters:
7232 +  mat   - the matrix
7233 .  x,y - the vectors
7234 -  w - where the result is stored
7235 
7236    Level: intermediate
7237 
7238    Notes:
7239     w may be the same vector as y.
7240 
7241     This allows one to use either the restriction or interpolation (its transpose)
7242     matrix to do the interpolation
7243 
7244     Concepts: interpolation
7245 
7246 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7247 
7248 @*/
7249 PetscErrorCode PETSCMAT_DLLEXPORT MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7250 {
7251   PetscErrorCode ierr;
7252   PetscInt       M,N;
7253 
7254   PetscFunctionBegin;
7255   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7256   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7257   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7258   PetscValidHeaderSpecific(w,VEC_CLASSID,4);
7259   PetscValidType(A,1);
7260   ierr = MatPreallocated(A);CHKERRQ(ierr);
7261   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
7262   if (N > M) {
7263     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
7264   } else {
7265     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
7266   }
7267   PetscFunctionReturn(0);
7268 }
7269 
7270 #undef __FUNCT__
7271 #define __FUNCT__ "MatInterpolate"
7272 /*@
7273    MatInterpolate - y = A*x or A'*x depending on the shape of
7274      the matrix
7275 
7276    Neighbor-wise Collective on Mat
7277 
7278    Input Parameters:
7279 +  mat   - the matrix
7280 -  x,y - the vectors
7281 
7282    Level: intermediate
7283 
7284    Notes:
7285     This allows one to use either the restriction or interpolation (its transpose)
7286     matrix to do the interpolation
7287 
7288    Concepts: matrices^interpolation
7289 
7290 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7291 
7292 @*/
7293 PetscErrorCode PETSCMAT_DLLEXPORT MatInterpolate(Mat A,Vec x,Vec y)
7294 {
7295   PetscErrorCode ierr;
7296   PetscInt       M,N;
7297 
7298   PetscFunctionBegin;
7299   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7300   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7301   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7302   PetscValidType(A,1);
7303   ierr = MatPreallocated(A);CHKERRQ(ierr);
7304   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
7305   if (N > M) {
7306     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
7307   } else {
7308     ierr = MatMult(A,x,y);CHKERRQ(ierr);
7309   }
7310   PetscFunctionReturn(0);
7311 }
7312 
7313 #undef __FUNCT__
7314 #define __FUNCT__ "MatRestrict"
7315 /*@
7316    MatRestrict - y = A*x or A'*x
7317 
7318    Neighbor-wise Collective on Mat
7319 
7320    Input Parameters:
7321 +  mat   - the matrix
7322 -  x,y - the vectors
7323 
7324    Level: intermediate
7325 
7326    Notes:
7327     This allows one to use either the restriction or interpolation (its transpose)
7328     matrix to do the restriction
7329 
7330    Concepts: matrices^restriction
7331 
7332 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
7333 
7334 @*/
7335 PetscErrorCode PETSCMAT_DLLEXPORT MatRestrict(Mat A,Vec x,Vec y)
7336 {
7337   PetscErrorCode ierr;
7338   PetscInt       M,N;
7339 
7340   PetscFunctionBegin;
7341   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7342   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7343   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7344   PetscValidType(A,1);
7345   ierr = MatPreallocated(A);CHKERRQ(ierr);
7346 
7347   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
7348   if (N > M) {
7349     ierr = MatMult(A,x,y);CHKERRQ(ierr);
7350   } else {
7351     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
7352   }
7353   PetscFunctionReturn(0);
7354 }
7355 
7356 #undef __FUNCT__
7357 #define __FUNCT__ "MatNullSpaceAttach"
7358 /*@
7359    MatNullSpaceAttach - attaches a null space to a matrix.
7360         This null space will be removed from the resulting vector whenever
7361         MatMult() is called
7362 
7363    Logically Collective on Mat and MatNullSpace
7364 
7365    Input Parameters:
7366 +  mat - the matrix
7367 -  nullsp - the null space object
7368 
7369    Level: developer
7370 
7371    Notes:
7372       Overwrites any previous null space that may have been attached
7373 
7374    Concepts: null space^attaching to matrix
7375 
7376 .seealso: MatCreate(), MatNullSpaceCreate()
7377 @*/
7378 PetscErrorCode PETSCMAT_DLLEXPORT MatNullSpaceAttach(Mat mat,MatNullSpace nullsp)
7379 {
7380   PetscErrorCode ierr;
7381 
7382   PetscFunctionBegin;
7383   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7384   PetscValidType(mat,1);
7385   PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
7386   ierr = MatPreallocated(mat);CHKERRQ(ierr);
7387   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
7388   if (mat->nullsp) { ierr = MatNullSpaceDestroy(mat->nullsp);CHKERRQ(ierr); }
7389   mat->nullsp = nullsp;
7390   PetscFunctionReturn(0);
7391 }
7392 
7393 #undef __FUNCT__
7394 #define __FUNCT__ "MatICCFactor"
7395 /*@C
7396    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
7397 
7398    Collective on Mat
7399 
7400    Input Parameters:
7401 +  mat - the matrix
7402 .  row - row/column permutation
7403 .  fill - expected fill factor >= 1.0
7404 -  level - level of fill, for ICC(k)
7405 
7406    Notes:
7407    Probably really in-place only when level of fill is zero, otherwise allocates
7408    new space to store factored matrix and deletes previous memory.
7409 
7410    Most users should employ the simplified KSP interface for linear solvers
7411    instead of working directly with matrix algebra routines such as this.
7412    See, e.g., KSPCreate().
7413 
7414    Level: developer
7415 
7416    Concepts: matrices^incomplete Cholesky factorization
7417    Concepts: Cholesky factorization
7418 
7419 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
7420 
7421     Developer Note: fortran interface is not autogenerated as the f90
7422     interface defintion cannot be generated correctly [due to MatFactorInfo]
7423 
7424 @*/
7425 PetscErrorCode PETSCMAT_DLLEXPORT MatICCFactor(Mat mat,IS row,const MatFactorInfo* info)
7426 {
7427   PetscErrorCode ierr;
7428 
7429   PetscFunctionBegin;
7430   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7431   PetscValidType(mat,1);
7432   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
7433   PetscValidPointer(info,3);
7434   if (mat->rmap->N != mat->cmap->N) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONG,"matrix must be square");
7435   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7436   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7437   if (!mat->ops->iccfactor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7438   ierr = MatPreallocated(mat);CHKERRQ(ierr);
7439   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
7440   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
7441   PetscFunctionReturn(0);
7442 }
7443 
7444 #undef __FUNCT__
7445 #define __FUNCT__ "MatSetValuesAdic"
7446 /*@
7447    MatSetValuesAdic - Sets values computed with ADIC automatic differentiation into a matrix.
7448 
7449    Not Collective
7450 
7451    Input Parameters:
7452 +  mat - the matrix
7453 -  v - the values compute with ADIC
7454 
7455    Level: developer
7456 
7457    Notes:
7458      Must call MatSetColoring() before using this routine. Also this matrix must already
7459      have its nonzero pattern determined.
7460 
7461 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7462           MatSetValues(), MatSetColoring(), MatSetValuesAdifor()
7463 @*/
7464 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesAdic(Mat mat,void *v)
7465 {
7466   PetscErrorCode ierr;
7467 
7468   PetscFunctionBegin;
7469   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7470   PetscValidType(mat,1);
7471   PetscValidPointer(mat,2);
7472 
7473   if (!mat->assembled) {
7474     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7475   }
7476   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
7477   if (!mat->ops->setvaluesadic) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7478   ierr = (*mat->ops->setvaluesadic)(mat,v);CHKERRQ(ierr);
7479   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
7480   ierr = MatView_Private(mat);CHKERRQ(ierr);
7481   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
7482   PetscFunctionReturn(0);
7483 }
7484 
7485 
7486 #undef __FUNCT__
7487 #define __FUNCT__ "MatSetColoring"
7488 /*@
7489    MatSetColoring - Sets a coloring used by calls to MatSetValuesAdic()
7490 
7491    Not Collective
7492 
7493    Input Parameters:
7494 +  mat - the matrix
7495 -  coloring - the coloring
7496 
7497    Level: developer
7498 
7499 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7500           MatSetValues(), MatSetValuesAdic()
7501 @*/
7502 PetscErrorCode PETSCMAT_DLLEXPORT MatSetColoring(Mat mat,ISColoring coloring)
7503 {
7504   PetscErrorCode ierr;
7505 
7506   PetscFunctionBegin;
7507   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7508   PetscValidType(mat,1);
7509   PetscValidPointer(coloring,2);
7510 
7511   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7512   if (!mat->ops->setcoloring) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7513   ierr = (*mat->ops->setcoloring)(mat,coloring);CHKERRQ(ierr);
7514   PetscFunctionReturn(0);
7515 }
7516 
7517 #undef __FUNCT__
7518 #define __FUNCT__ "MatSetValuesAdifor"
7519 /*@
7520    MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.
7521 
7522    Not Collective
7523 
7524    Input Parameters:
7525 +  mat - the matrix
7526 .  nl - leading dimension of v
7527 -  v - the values compute with ADIFOR
7528 
7529    Level: developer
7530 
7531    Notes:
7532      Must call MatSetColoring() before using this routine. Also this matrix must already
7533      have its nonzero pattern determined.
7534 
7535 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7536           MatSetValues(), MatSetColoring()
7537 @*/
7538 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
7539 {
7540   PetscErrorCode ierr;
7541 
7542   PetscFunctionBegin;
7543   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7544   PetscValidType(mat,1);
7545   PetscValidPointer(v,3);
7546 
7547   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7548   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
7549   if (!mat->ops->setvaluesadifor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7550   ierr = (*mat->ops->setvaluesadifor)(mat,nl,v);CHKERRQ(ierr);
7551   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
7552   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
7553   PetscFunctionReturn(0);
7554 }
7555 
7556 #undef __FUNCT__
7557 #define __FUNCT__ "MatDiagonalScaleLocal"
7558 /*@
7559    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
7560          ghosted ones.
7561 
7562    Not Collective
7563 
7564    Input Parameters:
7565 +  mat - the matrix
7566 -  diag = the diagonal values, including ghost ones
7567 
7568    Level: developer
7569 
7570    Notes: Works only for MPIAIJ and MPIBAIJ matrices
7571 
7572 .seealso: MatDiagonalScale()
7573 @*/
7574 PetscErrorCode PETSCMAT_DLLEXPORT MatDiagonalScaleLocal(Mat mat,Vec diag)
7575 {
7576   PetscErrorCode ierr;
7577   PetscMPIInt    size;
7578 
7579   PetscFunctionBegin;
7580   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7581   PetscValidHeaderSpecific(diag,VEC_CLASSID,2);
7582   PetscValidType(mat,1);
7583 
7584   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7585   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
7586   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
7587   if (size == 1) {
7588     PetscInt n,m;
7589     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
7590     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
7591     if (m == n) {
7592       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
7593     } else {
7594       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
7595     }
7596   } else {
7597     ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr);
7598   }
7599   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
7600   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
7601   PetscFunctionReturn(0);
7602 }
7603 
7604 #undef __FUNCT__
7605 #define __FUNCT__ "MatGetInertia"
7606 /*@
7607    MatGetInertia - Gets the inertia from a factored matrix
7608 
7609    Collective on Mat
7610 
7611    Input Parameter:
7612 .  mat - the matrix
7613 
7614    Output Parameters:
7615 +   nneg - number of negative eigenvalues
7616 .   nzero - number of zero eigenvalues
7617 -   npos - number of positive eigenvalues
7618 
7619    Level: advanced
7620 
7621    Notes: Matrix must have been factored by MatCholeskyFactor()
7622 
7623 
7624 @*/
7625 PetscErrorCode PETSCMAT_DLLEXPORT MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
7626 {
7627   PetscErrorCode ierr;
7628 
7629   PetscFunctionBegin;
7630   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7631   PetscValidType(mat,1);
7632   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7633   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
7634   if (!mat->ops->getinertia) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7635   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
7636   PetscFunctionReturn(0);
7637 }
7638 
7639 /* ----------------------------------------------------------------*/
7640 #undef __FUNCT__
7641 #define __FUNCT__ "MatSolves"
7642 /*@C
7643    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
7644 
7645    Neighbor-wise Collective on Mat and Vecs
7646 
7647    Input Parameters:
7648 +  mat - the factored matrix
7649 -  b - the right-hand-side vectors
7650 
7651    Output Parameter:
7652 .  x - the result vectors
7653 
7654    Notes:
7655    The vectors b and x cannot be the same.  I.e., one cannot
7656    call MatSolves(A,x,x).
7657 
7658    Notes:
7659    Most users should employ the simplified KSP interface for linear solvers
7660    instead of working directly with matrix algebra routines such as this.
7661    See, e.g., KSPCreate().
7662 
7663    Level: developer
7664 
7665    Concepts: matrices^triangular solves
7666 
7667 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
7668 @*/
7669 PetscErrorCode PETSCMAT_DLLEXPORT MatSolves(Mat mat,Vecs b,Vecs x)
7670 {
7671   PetscErrorCode ierr;
7672 
7673   PetscFunctionBegin;
7674   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7675   PetscValidType(mat,1);
7676   if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
7677   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7678   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
7679 
7680   if (!mat->ops->solves) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7681   ierr = MatPreallocated(mat);CHKERRQ(ierr);
7682   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
7683   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
7684   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
7685   PetscFunctionReturn(0);
7686 }
7687 
7688 #undef __FUNCT__
7689 #define __FUNCT__ "MatIsSymmetric"
7690 /*@
7691    MatIsSymmetric - Test whether a matrix is symmetric
7692 
7693    Collective on Mat
7694 
7695    Input Parameter:
7696 +  A - the matrix to test
7697 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
7698 
7699    Output Parameters:
7700 .  flg - the result
7701 
7702    Level: intermediate
7703 
7704    Concepts: matrix^symmetry
7705 
7706 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
7707 @*/
7708 PetscErrorCode PETSCMAT_DLLEXPORT MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
7709 {
7710   PetscErrorCode ierr;
7711 
7712   PetscFunctionBegin;
7713   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7714   PetscValidPointer(flg,2);
7715 
7716   if (!A->symmetric_set) {
7717     if (!A->ops->issymmetric) {
7718       const MatType mattype;
7719       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7720       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7721     }
7722     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
7723     if (!tol) {
7724       A->symmetric_set = PETSC_TRUE;
7725       A->symmetric = *flg;
7726       if (A->symmetric) {
7727 	A->structurally_symmetric_set = PETSC_TRUE;
7728 	A->structurally_symmetric     = PETSC_TRUE;
7729       }
7730     }
7731   } else if (A->symmetric) {
7732     *flg = PETSC_TRUE;
7733   } else if (!tol) {
7734     *flg = PETSC_FALSE;
7735   } else {
7736     if (!A->ops->issymmetric) {
7737       const MatType mattype;
7738       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7739       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7740     }
7741     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
7742   }
7743   PetscFunctionReturn(0);
7744 }
7745 
7746 #undef __FUNCT__
7747 #define __FUNCT__ "MatIsHermitian"
7748 /*@
7749    MatIsHermitian - Test whether a matrix is Hermitian
7750 
7751    Collective on Mat
7752 
7753    Input Parameter:
7754 +  A - the matrix to test
7755 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
7756 
7757    Output Parameters:
7758 .  flg - the result
7759 
7760    Level: intermediate
7761 
7762    Concepts: matrix^symmetry
7763 
7764 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
7765 @*/
7766 PetscErrorCode PETSCMAT_DLLEXPORT MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
7767 {
7768   PetscErrorCode ierr;
7769 
7770   PetscFunctionBegin;
7771   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7772   PetscValidPointer(flg,2);
7773 
7774   if (!A->hermitian_set) {
7775     if (!A->ops->ishermitian) {
7776       const MatType mattype;
7777       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7778       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7779     }
7780     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
7781     if (!tol) {
7782       A->hermitian_set = PETSC_TRUE;
7783       A->hermitian = *flg;
7784       if (A->hermitian) {
7785 	A->structurally_symmetric_set = PETSC_TRUE;
7786 	A->structurally_symmetric     = PETSC_TRUE;
7787       }
7788     }
7789   } else if (A->hermitian) {
7790     *flg = PETSC_TRUE;
7791   } else if (!tol) {
7792     *flg = PETSC_FALSE;
7793   } else {
7794     if (!A->ops->ishermitian) {
7795       const MatType mattype;
7796       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7797       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7798     }
7799     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
7800   }
7801   PetscFunctionReturn(0);
7802 }
7803 
7804 #undef __FUNCT__
7805 #define __FUNCT__ "MatIsSymmetricKnown"
7806 /*@
7807    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
7808 
7809    Not Collective
7810 
7811    Input Parameter:
7812 .  A - the matrix to check
7813 
7814    Output Parameters:
7815 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
7816 -  flg - the result
7817 
7818    Level: advanced
7819 
7820    Concepts: matrix^symmetry
7821 
7822    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
7823          if you want it explicitly checked
7824 
7825 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
7826 @*/
7827 PetscErrorCode PETSCMAT_DLLEXPORT MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
7828 {
7829   PetscFunctionBegin;
7830   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7831   PetscValidPointer(set,2);
7832   PetscValidPointer(flg,3);
7833   if (A->symmetric_set) {
7834     *set = PETSC_TRUE;
7835     *flg = A->symmetric;
7836   } else {
7837     *set = PETSC_FALSE;
7838   }
7839   PetscFunctionReturn(0);
7840 }
7841 
7842 #undef __FUNCT__
7843 #define __FUNCT__ "MatIsHermitianKnown"
7844 /*@
7845    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
7846 
7847    Not Collective
7848 
7849    Input Parameter:
7850 .  A - the matrix to check
7851 
7852    Output Parameters:
7853 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
7854 -  flg - the result
7855 
7856    Level: advanced
7857 
7858    Concepts: matrix^symmetry
7859 
7860    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
7861          if you want it explicitly checked
7862 
7863 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
7864 @*/
7865 PetscErrorCode PETSCMAT_DLLEXPORT MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
7866 {
7867   PetscFunctionBegin;
7868   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7869   PetscValidPointer(set,2);
7870   PetscValidPointer(flg,3);
7871   if (A->hermitian_set) {
7872     *set = PETSC_TRUE;
7873     *flg = A->hermitian;
7874   } else {
7875     *set = PETSC_FALSE;
7876   }
7877   PetscFunctionReturn(0);
7878 }
7879 
7880 #undef __FUNCT__
7881 #define __FUNCT__ "MatIsStructurallySymmetric"
7882 /*@
7883    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
7884 
7885    Collective on Mat
7886 
7887    Input Parameter:
7888 .  A - the matrix to test
7889 
7890    Output Parameters:
7891 .  flg - the result
7892 
7893    Level: intermediate
7894 
7895    Concepts: matrix^symmetry
7896 
7897 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
7898 @*/
7899 PetscErrorCode PETSCMAT_DLLEXPORT MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
7900 {
7901   PetscErrorCode ierr;
7902 
7903   PetscFunctionBegin;
7904   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7905   PetscValidPointer(flg,2);
7906   if (!A->structurally_symmetric_set) {
7907     if (!A->ops->isstructurallysymmetric) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
7908     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
7909     A->structurally_symmetric_set = PETSC_TRUE;
7910   }
7911   *flg = A->structurally_symmetric;
7912   PetscFunctionReturn(0);
7913 }
7914 
7915 #undef __FUNCT__
7916 #define __FUNCT__ "MatStashGetInfo"
7917 extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
7918 /*@
7919    MatStashGetInfo - Gets how many values are currently in the vector stash, i.e. need
7920        to be communicated to other processors during the MatAssemblyBegin/End() process
7921 
7922     Not collective
7923 
7924    Input Parameter:
7925 .   vec - the vector
7926 
7927    Output Parameters:
7928 +   nstash   - the size of the stash
7929 .   reallocs - the number of additional mallocs incurred.
7930 .   bnstash   - the size of the block stash
7931 -   breallocs - the number of additional mallocs incurred.in the block stash
7932 
7933    Level: advanced
7934 
7935 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
7936 
7937 @*/
7938 PetscErrorCode PETSCMAT_DLLEXPORT MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
7939 {
7940   PetscErrorCode ierr;
7941   PetscFunctionBegin;
7942   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
7943   ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
7944   PetscFunctionReturn(0);
7945 }
7946 
7947 #undef __FUNCT__
7948 #define __FUNCT__ "MatGetVecs"
7949 /*@C
7950    MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same
7951      parallel layout
7952 
7953    Collective on Mat
7954 
7955    Input Parameter:
7956 .  mat - the matrix
7957 
7958    Output Parameter:
7959 +   right - (optional) vector that the matrix can be multiplied against
7960 -   left - (optional) vector that the matrix vector product can be stored in
7961 
7962   Level: advanced
7963 
7964 .seealso: MatCreate()
7965 @*/
7966 PetscErrorCode PETSCMAT_DLLEXPORT MatGetVecs(Mat mat,Vec *right,Vec *left)
7967 {
7968   PetscErrorCode ierr;
7969 
7970   PetscFunctionBegin;
7971   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7972   PetscValidType(mat,1);
7973   ierr = MatPreallocated(mat);CHKERRQ(ierr);
7974   if (mat->ops->getvecs) {
7975     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
7976   } else {
7977     PetscMPIInt size;
7978     ierr = MPI_Comm_size(((PetscObject)mat)->comm, &size);CHKERRQ(ierr);
7979     if (right) {
7980       ierr = VecCreate(((PetscObject)mat)->comm,right);CHKERRQ(ierr);
7981       ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
7982       ierr = VecSetBlockSize(*right,mat->rmap->bs);CHKERRQ(ierr);
7983       if (size > 1) {
7984         /* New vectors uses Mat cmap and does not create a new one */
7985 	ierr = PetscLayoutDestroy((*right)->map);CHKERRQ(ierr);
7986 	(*right)->map = mat->cmap;
7987 	mat->cmap->refcnt++;
7988 
7989         ierr = VecSetType(*right,VECMPI);CHKERRQ(ierr);
7990       } else {ierr = VecSetType(*right,VECSEQ);CHKERRQ(ierr);}
7991     }
7992     if (left) {
7993       ierr = VecCreate(((PetscObject)mat)->comm,left);CHKERRQ(ierr);
7994       ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
7995       ierr = VecSetBlockSize(*left,mat->rmap->bs);CHKERRQ(ierr);
7996       if (size > 1) {
7997         /* New vectors uses Mat rmap and does not create a new one */
7998 	ierr = PetscLayoutDestroy((*left)->map);CHKERRQ(ierr);
7999 	(*left)->map = mat->rmap;
8000 	mat->rmap->refcnt++;
8001 
8002         ierr = VecSetType(*left,VECMPI);CHKERRQ(ierr);
8003       } else {ierr = VecSetType(*left,VECSEQ);CHKERRQ(ierr);}
8004     }
8005   }
8006   if (mat->rmapping) {
8007     if (right) {ierr = VecSetLocalToGlobalMapping(*right,mat->cmapping);CHKERRQ(ierr);}
8008     if (left) {ierr = VecSetLocalToGlobalMapping(*left,mat->rmapping);CHKERRQ(ierr);}
8009   }
8010   if (mat->rbmapping) {
8011     if (right) {ierr = VecSetLocalToGlobalMappingBlock(*right,mat->cbmapping);CHKERRQ(ierr);}
8012     if (left) {ierr = VecSetLocalToGlobalMappingBlock(*left,mat->rbmapping);CHKERRQ(ierr);}
8013   }
8014   PetscFunctionReturn(0);
8015 }
8016 
8017 #undef __FUNCT__
8018 #define __FUNCT__ "MatFactorInfoInitialize"
8019 /*@C
8020    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8021      with default values.
8022 
8023    Not Collective
8024 
8025    Input Parameters:
8026 .    info - the MatFactorInfo data structure
8027 
8028 
8029    Notes: The solvers are generally used through the KSP and PC objects, for example
8030           PCLU, PCILU, PCCHOLESKY, PCICC
8031 
8032    Level: developer
8033 
8034 .seealso: MatFactorInfo
8035 
8036     Developer Note: fortran interface is not autogenerated as the f90
8037     interface defintion cannot be generated correctly [due to MatFactorInfo]
8038 
8039 @*/
8040 
8041 PetscErrorCode PETSCMAT_DLLEXPORT MatFactorInfoInitialize(MatFactorInfo *info)
8042 {
8043   PetscErrorCode ierr;
8044 
8045   PetscFunctionBegin;
8046   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
8047   PetscFunctionReturn(0);
8048 }
8049 
8050 #undef __FUNCT__
8051 #define __FUNCT__ "MatPtAP"
8052 /*@
8053    MatPtAP - Creates the matrix product C = P^T * A * P
8054 
8055    Neighbor-wise Collective on Mat
8056 
8057    Input Parameters:
8058 +  A - the matrix
8059 .  P - the projection matrix
8060 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8061 -  fill - expected fill as ratio of nnz(C)/nnz(A)
8062 
8063    Output Parameters:
8064 .  C - the product matrix
8065 
8066    Notes:
8067    C will be created and must be destroyed by the user with MatDestroy().
8068 
8069    This routine is currently only implemented for pairs of AIJ matrices and classes
8070    which inherit from AIJ.
8071 
8072    Level: intermediate
8073 
8074 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult()
8075 @*/
8076 PetscErrorCode PETSCMAT_DLLEXPORT MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
8077 {
8078   PetscErrorCode ierr;
8079 
8080   PetscFunctionBegin;
8081   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8082   PetscValidType(A,1);
8083   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8084   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8085   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
8086   PetscValidType(P,2);
8087   ierr = MatPreallocated(P);CHKERRQ(ierr);
8088   if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8089   if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8090   PetscValidPointer(C,3);
8091   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);
8092   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8093   ierr = MatPreallocated(A);CHKERRQ(ierr);
8094 
8095   if (!A->ops->ptap) {
8096     const MatType mattype;
8097     ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8098     SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix of type <%s> does not support PtAP",mattype);
8099   }
8100   ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
8101   ierr = (*A->ops->ptap)(A,P,scall,fill,C);CHKERRQ(ierr);
8102   ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
8103 
8104   PetscFunctionReturn(0);
8105 }
8106 
8107 #undef __FUNCT__
8108 #define __FUNCT__ "MatPtAPNumeric"
8109 /*@
8110    MatPtAPNumeric - Computes the matrix product C = P^T * A * P
8111 
8112    Neighbor-wise Collective on Mat
8113 
8114    Input Parameters:
8115 +  A - the matrix
8116 -  P - the projection matrix
8117 
8118    Output Parameters:
8119 .  C - the product matrix
8120 
8121    Notes:
8122    C must have been created by calling MatPtAPSymbolic and must be destroyed by
8123    the user using MatDeatroy().
8124 
8125    This routine is currently only implemented for pairs of AIJ matrices and classes
8126    which inherit from AIJ.  C will be of type MATAIJ.
8127 
8128    Level: intermediate
8129 
8130 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
8131 @*/
8132 PetscErrorCode PETSCMAT_DLLEXPORT MatPtAPNumeric(Mat A,Mat P,Mat C)
8133 {
8134   PetscErrorCode ierr;
8135 
8136   PetscFunctionBegin;
8137   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8138   PetscValidType(A,1);
8139   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8140   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8141   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
8142   PetscValidType(P,2);
8143   ierr = MatPreallocated(P);CHKERRQ(ierr);
8144   if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8145   if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8146   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
8147   PetscValidType(C,3);
8148   ierr = MatPreallocated(C);CHKERRQ(ierr);
8149   if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8150   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);
8151   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);
8152   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);
8153   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);
8154   ierr = MatPreallocated(A);CHKERRQ(ierr);
8155 
8156   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
8157   ierr = (*A->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr);
8158   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
8159   PetscFunctionReturn(0);
8160 }
8161 
8162 #undef __FUNCT__
8163 #define __FUNCT__ "MatPtAPSymbolic"
8164 /*@
8165    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P
8166 
8167    Neighbor-wise Collective on Mat
8168 
8169    Input Parameters:
8170 +  A - the matrix
8171 -  P - the projection matrix
8172 
8173    Output Parameters:
8174 .  C - the (i,j) structure of the product matrix
8175 
8176    Notes:
8177    C will be created and must be destroyed by the user with MatDestroy().
8178 
8179    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
8180    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
8181    this (i,j) structure by calling MatPtAPNumeric().
8182 
8183    Level: intermediate
8184 
8185 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
8186 @*/
8187 PetscErrorCode PETSCMAT_DLLEXPORT MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
8188 {
8189   PetscErrorCode ierr;
8190 
8191   PetscFunctionBegin;
8192   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8193   PetscValidType(A,1);
8194   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8195   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8196   if (fill <1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8197   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
8198   PetscValidType(P,2);
8199   ierr = MatPreallocated(P);CHKERRQ(ierr);
8200   if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8201   if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8202   PetscValidPointer(C,3);
8203 
8204   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);
8205   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);
8206   ierr = MatPreallocated(A);CHKERRQ(ierr);
8207   ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
8208   ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr);
8209   ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
8210 
8211   ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr);
8212 
8213   PetscFunctionReturn(0);
8214 }
8215 
8216 #undef __FUNCT__
8217 #define __FUNCT__ "MatMatMult"
8218 /*@
8219    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
8220 
8221    Neighbor-wise Collective on Mat
8222 
8223    Input Parameters:
8224 +  A - the left matrix
8225 .  B - the right matrix
8226 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8227 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
8228           if the result is a dense matrix this is irrelevent
8229 
8230    Output Parameters:
8231 .  C - the product matrix
8232 
8233    Notes:
8234    Unless scall is MAT_REUSE_MATRIX C will be created.
8235 
8236    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8237 
8238    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8239    actually needed.
8240 
8241    If you have many matrices with the same non-zero structure to multiply, you
8242    should either
8243 $   1) use MAT_REUSE_MATRIX in all calls but the first or
8244 $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
8245 
8246    Level: intermediate
8247 
8248 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatPtAP()
8249 @*/
8250 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8251 {
8252   PetscErrorCode ierr;
8253   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8254   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8255   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat *)=PETSC_NULL;
8256 
8257   PetscFunctionBegin;
8258   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8259   PetscValidType(A,1);
8260   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8261   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8262   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8263   PetscValidType(B,2);
8264   ierr = MatPreallocated(B);CHKERRQ(ierr);
8265   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8266   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8267   PetscValidPointer(C,3);
8268   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);
8269   if (scall == MAT_REUSE_MATRIX){
8270     PetscValidPointer(*C,5);
8271     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
8272   }
8273   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8274   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8275   ierr = MatPreallocated(A);CHKERRQ(ierr);
8276 
8277   fA = A->ops->matmult;
8278   fB = B->ops->matmult;
8279   if (fB == fA) {
8280     if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
8281     mult = fB;
8282   } else {
8283     /* dispatch based on the type of A and B */
8284     char  multname[256];
8285     ierr = PetscStrcpy(multname,"MatMatMult_");CHKERRQ(ierr);
8286     ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr);
8287     ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);
8288     ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr);
8289     ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
8290     ierr = PetscObjectQueryFunction((PetscObject)B,multname,(void (**)(void))&mult);CHKERRQ(ierr);
8291     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);
8292   }
8293   ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
8294   ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr);
8295   ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
8296   PetscFunctionReturn(0);
8297 }
8298 
8299 #undef __FUNCT__
8300 #define __FUNCT__ "MatMatMultSymbolic"
8301 /*@
8302    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
8303    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().
8304 
8305    Neighbor-wise Collective on Mat
8306 
8307    Input Parameters:
8308 +  A - the left matrix
8309 .  B - the right matrix
8310 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
8311       if C is a dense matrix this is irrelevent
8312 
8313    Output Parameters:
8314 .  C - the product matrix
8315 
8316    Notes:
8317    Unless scall is MAT_REUSE_MATRIX C will be created.
8318 
8319    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8320    actually needed.
8321 
8322    This routine is currently implemented for
8323     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
8324     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8325     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
8326 
8327    Level: intermediate
8328 
8329    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
8330      We should incorporate them into PETSc.
8331 
8332 .seealso: MatMatMult(), MatMatMultNumeric()
8333 @*/
8334 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
8335 {
8336   PetscErrorCode ierr;
8337   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat *);
8338   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat *);
8339   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat *)=PETSC_NULL;
8340 
8341   PetscFunctionBegin;
8342   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8343   PetscValidType(A,1);
8344   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8345   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8346 
8347   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8348   PetscValidType(B,2);
8349   ierr = MatPreallocated(B);CHKERRQ(ierr);
8350   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8351   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8352   PetscValidPointer(C,3);
8353 
8354   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);
8355   if (fill == PETSC_DEFAULT) fill = 2.0;
8356   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8357   ierr = MatPreallocated(A);CHKERRQ(ierr);
8358 
8359   Asymbolic = A->ops->matmultsymbolic;
8360   Bsymbolic = B->ops->matmultsymbolic;
8361   if (Asymbolic == Bsymbolic){
8362     if (!Bsymbolic) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
8363     symbolic = Bsymbolic;
8364   } else { /* dispatch based on the type of A and B */
8365     char  symbolicname[256];
8366     ierr = PetscStrcpy(symbolicname,"MatMatMultSymbolic_");CHKERRQ(ierr);
8367     ierr = PetscStrcat(symbolicname,((PetscObject)A)->type_name);CHKERRQ(ierr);
8368     ierr = PetscStrcat(symbolicname,"_");CHKERRQ(ierr);
8369     ierr = PetscStrcat(symbolicname,((PetscObject)B)->type_name);CHKERRQ(ierr);
8370     ierr = PetscStrcat(symbolicname,"_C");CHKERRQ(ierr);
8371     ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,(void (**)(void))&symbolic);CHKERRQ(ierr);
8372     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);
8373   }
8374   ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
8375   ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr);
8376   ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
8377   PetscFunctionReturn(0);
8378 }
8379 
8380 #undef __FUNCT__
8381 #define __FUNCT__ "MatMatMultNumeric"
8382 /*@
8383    MatMatMultNumeric - Performs the numeric matrix-matrix product.
8384    Call this routine after first calling MatMatMultSymbolic().
8385 
8386    Neighbor-wise Collective on Mat
8387 
8388    Input Parameters:
8389 +  A - the left matrix
8390 -  B - the right matrix
8391 
8392    Output Parameters:
8393 .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
8394 
8395    Notes:
8396    C must have been created with MatMatMultSymbolic().
8397 
8398    This routine is currently implemented for
8399     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
8400     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8401     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
8402 
8403    Level: intermediate
8404 
8405 .seealso: MatMatMult(), MatMatMultSymbolic()
8406 @*/
8407 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMultNumeric(Mat A,Mat B,Mat C)
8408 {
8409   PetscErrorCode ierr;
8410   PetscErrorCode (*Anumeric)(Mat,Mat,Mat);
8411   PetscErrorCode (*Bnumeric)(Mat,Mat,Mat);
8412   PetscErrorCode (*numeric)(Mat,Mat,Mat)=PETSC_NULL;
8413 
8414   PetscFunctionBegin;
8415   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8416   PetscValidType(A,1);
8417   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8418   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8419 
8420   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8421   PetscValidType(B,2);
8422   ierr = MatPreallocated(B);CHKERRQ(ierr);
8423   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8424   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8425 
8426   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
8427   PetscValidType(C,3);
8428   ierr = MatPreallocated(C);CHKERRQ(ierr);
8429   if (!C->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8430   if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8431 
8432   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);
8433   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);
8434   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);
8435   ierr = MatPreallocated(A);CHKERRQ(ierr);
8436 
8437   Anumeric = A->ops->matmultnumeric;
8438   Bnumeric = B->ops->matmultnumeric;
8439   if (Anumeric == Bnumeric){
8440     if (!Bnumeric) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMultNumeric not supported for B of type %s",((PetscObject)B)->type_name);
8441     numeric = Bnumeric;
8442   } else {
8443     char  numericname[256];
8444     ierr = PetscStrcpy(numericname,"MatMatMultNumeric_");CHKERRQ(ierr);
8445     ierr = PetscStrcat(numericname,((PetscObject)A)->type_name);CHKERRQ(ierr);
8446     ierr = PetscStrcat(numericname,"_");CHKERRQ(ierr);
8447     ierr = PetscStrcat(numericname,((PetscObject)B)->type_name);CHKERRQ(ierr);
8448     ierr = PetscStrcat(numericname,"_C");CHKERRQ(ierr);
8449     ierr = PetscObjectQueryFunction((PetscObject)B,numericname,(void (**)(void))&numeric);CHKERRQ(ierr);
8450     if (!numeric)
8451       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);
8452   }
8453   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
8454   ierr = (*numeric)(A,B,C);CHKERRQ(ierr);
8455   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
8456   PetscFunctionReturn(0);
8457 }
8458 
8459 #undef __FUNCT__
8460 #define __FUNCT__ "MatMatMultTranspose"
8461 /*@
8462    MatMatMultTranspose - Performs Matrix-Matrix Multiplication C=A^T*B.
8463 
8464    Neighbor-wise Collective on Mat
8465 
8466    Input Parameters:
8467 +  A - the left matrix
8468 .  B - the right matrix
8469 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8470 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
8471 
8472    Output Parameters:
8473 .  C - the product matrix
8474 
8475    Notes:
8476    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
8477 
8478    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8479 
8480   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8481    actually needed.
8482 
8483    This routine is currently only implemented for pairs of SeqAIJ matrices and pairs of SeqDense matrices and classes
8484    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.
8485 
8486    Level: intermediate
8487 
8488 .seealso: MatMatMultTransposeSymbolic(), MatMatMultTransposeNumeric(), MatPtAP()
8489 @*/
8490 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMultTranspose(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8491 {
8492   PetscErrorCode ierr;
8493   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8494   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8495 
8496   PetscFunctionBegin;
8497   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8498   PetscValidType(A,1);
8499   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8500   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8501   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8502   PetscValidType(B,2);
8503   ierr = MatPreallocated(B);CHKERRQ(ierr);
8504   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8505   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8506   PetscValidPointer(C,3);
8507   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);
8508   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8509   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8510   ierr = MatPreallocated(A);CHKERRQ(ierr);
8511 
8512   fA = A->ops->matmulttranspose;
8513   if (!fA) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMultTranspose not supported for A of type %s",((PetscObject)A)->type_name);
8514   fB = B->ops->matmulttranspose;
8515   if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMultTranspose not supported for B of type %s",((PetscObject)B)->type_name);
8516   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);
8517 
8518   ierr = PetscLogEventBegin(MAT_MatMultTranspose,A,B,0,0);CHKERRQ(ierr);
8519   ierr = (*A->ops->matmulttranspose)(A,B,scall,fill,C);CHKERRQ(ierr);
8520   ierr = PetscLogEventEnd(MAT_MatMultTranspose,A,B,0,0);CHKERRQ(ierr);
8521 
8522   PetscFunctionReturn(0);
8523 }
8524 
8525 #undef __FUNCT__
8526 #define __FUNCT__ "MatGetRedundantMatrix"
8527 /*@C
8528    MatGetRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
8529 
8530    Collective on Mat
8531 
8532    Input Parameters:
8533 +  mat - the matrix
8534 .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
8535 .  subcomm - MPI communicator split from the communicator where mat resides in
8536 .  mlocal_red - number of local rows of the redundant matrix
8537 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8538 
8539    Output Parameter:
8540 .  matredundant - redundant matrix
8541 
8542    Notes:
8543    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
8544    original matrix has not changed from that last call to MatGetRedundantMatrix().
8545 
8546    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
8547    calling it.
8548 
8549    Only MPIAIJ matrix is supported.
8550 
8551    Level: advanced
8552 
8553    Concepts: subcommunicator
8554    Concepts: duplicate matrix
8555 
8556 .seealso: MatDestroy()
8557 @*/
8558 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,PetscInt mlocal_red,MatReuse reuse,Mat *matredundant)
8559 {
8560   PetscErrorCode ierr;
8561 
8562   PetscFunctionBegin;
8563   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8564   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
8565     PetscValidPointer(*matredundant,6);
8566     PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,6);
8567   }
8568   if (!mat->ops->getredundantmatrix) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8569   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8570   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8571   ierr = MatPreallocated(mat);CHKERRQ(ierr);
8572 
8573   ierr = PetscLogEventBegin(MAT_GetRedundantMatrix,mat,0,0,0);CHKERRQ(ierr);
8574   ierr = (*mat->ops->getredundantmatrix)(mat,nsubcomm,subcomm,mlocal_red,reuse,matredundant);CHKERRQ(ierr);
8575   ierr = PetscLogEventEnd(MAT_GetRedundantMatrix,mat,0,0,0);CHKERRQ(ierr);
8576   PetscFunctionReturn(0);
8577 }
8578 
8579 #undef __FUNCT__
8580 #define __FUNCT__ "MatGetMultiProcBlock"
8581 /*@C
8582    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
8583    a given 'mat' object. Each submatrix can span multiple procs.
8584 
8585    Collective on Mat
8586 
8587    Input Parameters:
8588 +  mat - the matrix
8589 -  subcomm - the subcommunicator obtained by com_split(comm)
8590 
8591    Output Parameter:
8592 .  subMat - 'parallel submatrices each spans a given subcomm
8593 
8594   Notes:
8595   The submatrix partition across processors is dicated by 'subComm' a
8596   communicator obtained by com_split(comm). The comm_split
8597   is not restriced to be grouped with consequitive original ranks.
8598 
8599   Due the comm_split() usage, the parallel layout of the submatrices
8600   map directly to the layout of the original matrix [wrt the local
8601   row,col partitioning]. So the original 'DiagonalMat' naturally maps
8602   into the 'DiagonalMat' of the subMat, hence it is used directly from
8603   the subMat. However the offDiagMat looses some columns - and this is
8604   reconstructed with MatSetValues()
8605 
8606   Level: advanced
8607 
8608   Concepts: subcommunicator
8609   Concepts: submatrices
8610 
8611 .seealso: MatGetSubMatrices()
8612 @*/
8613 PetscErrorCode  PETSCMAT_DLLEXPORT MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, Mat* subMat)
8614 {
8615   PetscErrorCode ierr;
8616   PetscMPIInt    commsize,subCommSize;
8617 
8618   PetscFunctionBegin;
8619   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&commsize);CHKERRQ(ierr);
8620   ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr);
8621   if (subCommSize > commsize) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
8622 
8623   ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
8624   ierr = (*mat->ops->getmultiprocblock)(mat,subComm,subMat);CHKERRQ(ierr);
8625   ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
8626   PetscFunctionReturn(0);
8627 }
8628 
8629 #undef __FUNCT__
8630 #define __FUNCT__ "MatGetLocalSubMatrix"
8631 /*@
8632    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
8633 
8634    Not Collective
8635 
8636    Input Arguments:
8637    mat - matrix to extract local submatrix from
8638    isrow - local row indices for submatrix
8639    iscol - local column indices for submatrix
8640 
8641    Output Arguments:
8642    submat - the submatrix
8643 
8644    Level: intermediate
8645 
8646    Notes:
8647    The submat should be returned with MatRestoreLocalSubMatrix().
8648 
8649    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
8650    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
8651 
8652    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
8653    MatSetValuesBlockedLocal() will also be implemented.
8654 
8655 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef()
8656 @*/
8657 PetscErrorCode PETSCMAT_DLLEXPORT MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
8658 {
8659   PetscErrorCode ierr;
8660 
8661   PetscFunctionBegin;
8662   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8663   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
8664   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
8665   PetscCheckSameComm(isrow,2,iscol,3);
8666   PetscValidPointer(submat,4);
8667 
8668   if (mat->ops->getlocalsubmatrix) {
8669     ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
8670   } else {
8671     ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr);
8672   }
8673   PetscFunctionReturn(0);
8674 }
8675 
8676 #undef __FUNCT__
8677 #define __FUNCT__ "MatRestoreLocalSubMatrix"
8678 /*@
8679    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
8680 
8681    Not Collective
8682 
8683    Input Arguments:
8684    mat - matrix to extract local submatrix from
8685    isrow - local row indices for submatrix
8686    iscol - local column indices for submatrix
8687    submat - the submatrix
8688 
8689    Level: intermediate
8690 
8691 .seealso: MatGetLocalSubMatrix()
8692 @*/
8693 PetscErrorCode PETSCMAT_DLLEXPORT MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
8694 {
8695   PetscErrorCode ierr;
8696 
8697   PetscFunctionBegin;
8698   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8699   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
8700   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
8701   PetscCheckSameComm(isrow,2,iscol,3);
8702   PetscValidPointer(submat,4);
8703   if (*submat) {PetscValidHeaderSpecific(*submat,MAT_CLASSID,4);}
8704 
8705   if (mat->ops->restorelocalsubmatrix) {
8706     ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
8707   } else {
8708     ierr = MatDestroy(*submat);CHKERRQ(ierr);
8709   }
8710   *submat = PETSC_NULL;
8711   PetscFunctionReturn(0);
8712 }
8713