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