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