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