xref: /petsc/src/mat/interface/matrix.c (revision 563ffbab739d96c559dd28f4ad9be3f5bd74c24d)
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_FDColoringSetUp, 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   PetscFunctionBeginHot;
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   PetscFunctionBeginHot;
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   PetscFunctionBeginHot;
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,cbs = mat->cmap->bs;
1655     if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1656       iidxm = buf; iidxn = buf + m*bs;
1657     } else {
1658       ierr  = PetscMalloc2(m*bs,PetscInt,&bufr,n*cbs,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<cbs; j++) {
1668         iidxn[i*cbs+j] = cbs*idxn[i] + j;
1669       }
1670     }
1671     ierr = MatSetValues(mat,m*bs,iidxm,n*cbs,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   PetscFunctionBeginHot;
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   PetscFunctionBeginHot;
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,cbs = mat->cmap->bs;
2114       if (nrow*bs+ncol*cbs <=(PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2115         irowm = buf; icolm = buf + nrow;
2116       } else {
2117         ierr  = PetscMalloc2(nrow*bs,PetscInt,&bufr,ncol*cbs,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<cbs; j++) icolm[i*cbs+j] = icol[i]*cbs+j;
2125       }
2126       ierr = MatSetValuesLocal(mat,nrow*bs,irowm,ncol*cbs,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    If the block size has not been set yet this routine returns -1.
6716 
6717    Level: intermediate
6718 
6719    Concepts: matrices^block size
6720 
6721 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
6722 @*/
6723 PetscErrorCode  MatGetBlockSize(Mat mat,PetscInt *bs)
6724 {
6725   PetscFunctionBegin;
6726   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6727   PetscValidIntPointer(bs,2);
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    If a block size has not been set yet this routine returns -1.
6751 
6752    Level: intermediate
6753 
6754    Concepts: matrices^block size
6755 
6756 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
6757 @*/
6758 PetscErrorCode  MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
6759 {
6760   PetscFunctionBegin;
6761   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6762   if (rbs) PetscValidIntPointer(rbs,2);
6763   if (cbs) PetscValidIntPointer(cbs,3);
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   PetscValidLogicalCollectiveInt(mat,cbs,3);
6830   ierr = PetscLayoutSetBlockSize(mat->rmap,rbs);CHKERRQ(ierr);
6831   ierr = PetscLayoutSetBlockSize(mat->cmap,cbs);CHKERRQ(ierr);
6832   PetscFunctionReturn(0);
6833 }
6834 
6835 #undef __FUNCT__
6836 #define __FUNCT__ "MatResidual"
6837 /*@
6838    MatResidual - Default routine to calculate the residual.
6839 
6840    Collective on Mat and Vec
6841 
6842    Input Parameters:
6843 +  mat - the matrix
6844 .  b   - the right-hand-side
6845 -  x   - the approximate solution
6846 
6847    Output Parameter:
6848 .  r - location to store the residual
6849 
6850    Level: developer
6851 
6852 .keywords: MG, default, multigrid, residual
6853 
6854 .seealso: PCMGSetResidual()
6855 @*/
6856 PetscErrorCode  MatResidual(Mat mat,Vec b,Vec x,Vec r)
6857 {
6858   PetscErrorCode ierr;
6859 
6860   PetscFunctionBegin;
6861   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6862   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
6863   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
6864   PetscValidHeaderSpecific(r,VEC_CLASSID,4);
6865   PetscValidType(mat,1);
6866   MatCheckPreallocated(mat,1);
6867   ierr  = PetscLogEventBegin(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
6868   if (!mat->ops->residual) {
6869     ierr = MatMult(mat,x,r);CHKERRQ(ierr);
6870     ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr);
6871   } else {
6872     ierr  = (*mat->ops->residual)(mat,b,x,r);CHKERRQ(ierr);
6873   }
6874   ierr  = PetscLogEventEnd(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
6875   PetscFunctionReturn(0);
6876 }
6877 
6878 #undef __FUNCT__
6879 #define __FUNCT__ "MatGetRowIJ"
6880 /*@C
6881     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
6882 
6883    Collective on Mat
6884 
6885     Input Parameters:
6886 +   mat - the matrix
6887 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
6888 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
6889 -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
6890                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6891                  always used.
6892 
6893     Output Parameters:
6894 +   n - number of rows in the (possibly compressed) matrix
6895 .   ia - the row pointers [of length n+1]
6896 .   ja - the column indices
6897 -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
6898            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
6899 
6900     Level: developer
6901 
6902     Notes: You CANNOT change any of the ia[] or ja[] values.
6903 
6904            Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values
6905 
6906     Fortran Node
6907 
6908            In Fortran use
6909 $           PetscInt ia(1), ja(1)
6910 $           PetscOffset iia, jja
6911 $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
6912 $
6913 $          or
6914 $
6915 $           PetscScalar, pointer :: xx_v(:)
6916 $    call  MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
6917 
6918 
6919        Acess the ith and jth entries via ia(iia + i) and ja(jja + j)
6920 
6921 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
6922 @*/
6923 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
6924 {
6925   PetscErrorCode ierr;
6926 
6927   PetscFunctionBegin;
6928   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6929   PetscValidType(mat,1);
6930   PetscValidIntPointer(n,4);
6931   if (ia) PetscValidIntPointer(ia,5);
6932   if (ja) PetscValidIntPointer(ja,6);
6933   PetscValidIntPointer(done,7);
6934   MatCheckPreallocated(mat,1);
6935   if (!mat->ops->getrowij) *done = PETSC_FALSE;
6936   else {
6937     *done = PETSC_TRUE;
6938     ierr  = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
6939     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6940     ierr  = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
6941   }
6942   PetscFunctionReturn(0);
6943 }
6944 
6945 #undef __FUNCT__
6946 #define __FUNCT__ "MatGetColumnIJ"
6947 /*@C
6948     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
6949 
6950     Collective on Mat
6951 
6952     Input Parameters:
6953 +   mat - the matrix
6954 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6955 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6956                 symmetrized
6957 .   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6958                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6959                  always used.
6960 .   n - number of columns in the (possibly compressed) matrix
6961 .   ia - the column pointers
6962 -   ja - the row indices
6963 
6964     Output Parameters:
6965 .   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
6966 
6967     Note:
6968     This routine zeros out n, ia, and ja. This is to prevent accidental
6969     us of the array after it has been restored. If you pass NULL, it will
6970     not zero the pointers.  Use of ia or ja after MatRestoreColumnIJ() is invalid.
6971 
6972     Level: developer
6973 
6974 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6975 @*/
6976 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
6977 {
6978   PetscErrorCode ierr;
6979 
6980   PetscFunctionBegin;
6981   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6982   PetscValidType(mat,1);
6983   PetscValidIntPointer(n,4);
6984   if (ia) PetscValidIntPointer(ia,5);
6985   if (ja) PetscValidIntPointer(ja,6);
6986   PetscValidIntPointer(done,7);
6987   MatCheckPreallocated(mat,1);
6988   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
6989   else {
6990     *done = PETSC_TRUE;
6991     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6992   }
6993   PetscFunctionReturn(0);
6994 }
6995 
6996 #undef __FUNCT__
6997 #define __FUNCT__ "MatRestoreRowIJ"
6998 /*@C
6999     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
7000     MatGetRowIJ().
7001 
7002     Collective on Mat
7003 
7004     Input Parameters:
7005 +   mat - the matrix
7006 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7007 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7008                 symmetrized
7009 .   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7010                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7011                  always used.
7012 .   n - size of (possibly compressed) matrix
7013 .   ia - the row pointers
7014 -   ja - the column indices
7015 
7016     Output Parameters:
7017 .   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7018 
7019     Note:
7020     This routine zeros out n, ia, and ja. This is to prevent accidental
7021     us of the array after it has been restored. If you pass NULL, it will
7022     not zero the pointers.  Use of ia or ja after MatRestoreRowIJ() is invalid.
7023 
7024     Level: developer
7025 
7026 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7027 @*/
7028 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7029 {
7030   PetscErrorCode ierr;
7031 
7032   PetscFunctionBegin;
7033   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7034   PetscValidType(mat,1);
7035   if (ia) PetscValidIntPointer(ia,5);
7036   if (ja) PetscValidIntPointer(ja,6);
7037   PetscValidIntPointer(done,7);
7038   MatCheckPreallocated(mat,1);
7039 
7040   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
7041   else {
7042     *done = PETSC_TRUE;
7043     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7044     if (n)  *n = 0;
7045     if (ia) *ia = NULL;
7046     if (ja) *ja = NULL;
7047   }
7048   PetscFunctionReturn(0);
7049 }
7050 
7051 #undef __FUNCT__
7052 #define __FUNCT__ "MatRestoreColumnIJ"
7053 /*@C
7054     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
7055     MatGetColumnIJ().
7056 
7057     Collective on Mat
7058 
7059     Input Parameters:
7060 +   mat - the matrix
7061 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7062 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7063                 symmetrized
7064 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7065                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7066                  always used.
7067 
7068     Output Parameters:
7069 +   n - size of (possibly compressed) matrix
7070 .   ia - the column pointers
7071 .   ja - the row indices
7072 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7073 
7074     Level: developer
7075 
7076 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
7077 @*/
7078 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7079 {
7080   PetscErrorCode ierr;
7081 
7082   PetscFunctionBegin;
7083   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7084   PetscValidType(mat,1);
7085   if (ia) PetscValidIntPointer(ia,5);
7086   if (ja) PetscValidIntPointer(ja,6);
7087   PetscValidIntPointer(done,7);
7088   MatCheckPreallocated(mat,1);
7089 
7090   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
7091   else {
7092     *done = PETSC_TRUE;
7093     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7094     if (n)  *n = 0;
7095     if (ia) *ia = NULL;
7096     if (ja) *ja = NULL;
7097   }
7098   PetscFunctionReturn(0);
7099 }
7100 
7101 #undef __FUNCT__
7102 #define __FUNCT__ "MatColoringPatch"
7103 /*@C
7104     MatColoringPatch -Used inside matrix coloring routines that
7105     use MatGetRowIJ() and/or MatGetColumnIJ().
7106 
7107     Collective on Mat
7108 
7109     Input Parameters:
7110 +   mat - the matrix
7111 .   ncolors - max color value
7112 .   n   - number of entries in colorarray
7113 -   colorarray - array indicating color for each column
7114 
7115     Output Parameters:
7116 .   iscoloring - coloring generated using colorarray information
7117 
7118     Level: developer
7119 
7120 .seealso: MatGetRowIJ(), MatGetColumnIJ()
7121 
7122 @*/
7123 PetscErrorCode  MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7124 {
7125   PetscErrorCode ierr;
7126 
7127   PetscFunctionBegin;
7128   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7129   PetscValidType(mat,1);
7130   PetscValidIntPointer(colorarray,4);
7131   PetscValidPointer(iscoloring,5);
7132   MatCheckPreallocated(mat,1);
7133 
7134   if (!mat->ops->coloringpatch) {
7135     ierr = ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
7136   } else {
7137     ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
7138   }
7139   PetscFunctionReturn(0);
7140 }
7141 
7142 
7143 #undef __FUNCT__
7144 #define __FUNCT__ "MatSetUnfactored"
7145 /*@
7146    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
7147 
7148    Logically Collective on Mat
7149 
7150    Input Parameter:
7151 .  mat - the factored matrix to be reset
7152 
7153    Notes:
7154    This routine should be used only with factored matrices formed by in-place
7155    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7156    format).  This option can save memory, for example, when solving nonlinear
7157    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7158    ILU(0) preconditioner.
7159 
7160    Note that one can specify in-place ILU(0) factorization by calling
7161 .vb
7162      PCType(pc,PCILU);
7163      PCFactorSeUseInPlace(pc);
7164 .ve
7165    or by using the options -pc_type ilu -pc_factor_in_place
7166 
7167    In-place factorization ILU(0) can also be used as a local
7168    solver for the blocks within the block Jacobi or additive Schwarz
7169    methods (runtime option: -sub_pc_factor_in_place).  See the discussion
7170    of these preconditioners in the <a href="../../docs/manual.pdf#ch_pc">PC chapter of the users manual</a> for details on setting
7171    local solver options.
7172 
7173    Most users should employ the simplified KSP interface for linear solvers
7174    instead of working directly with matrix algebra routines such as this.
7175    See, e.g., KSPCreate().
7176 
7177    Level: developer
7178 
7179 .seealso: PCFactorSetUseInPlace()
7180 
7181    Concepts: matrices^unfactored
7182 
7183 @*/
7184 PetscErrorCode  MatSetUnfactored(Mat mat)
7185 {
7186   PetscErrorCode ierr;
7187 
7188   PetscFunctionBegin;
7189   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7190   PetscValidType(mat,1);
7191   MatCheckPreallocated(mat,1);
7192   mat->factortype = MAT_FACTOR_NONE;
7193   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
7194   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
7195   PetscFunctionReturn(0);
7196 }
7197 
7198 /*MC
7199     MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.
7200 
7201     Synopsis:
7202     MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7203 
7204     Not collective
7205 
7206     Input Parameter:
7207 .   x - matrix
7208 
7209     Output Parameters:
7210 +   xx_v - the Fortran90 pointer to the array
7211 -   ierr - error code
7212 
7213     Example of Usage:
7214 .vb
7215       PetscScalar, pointer xx_v(:,:)
7216       ....
7217       call MatDenseGetArrayF90(x,xx_v,ierr)
7218       a = xx_v(3)
7219       call MatDenseRestoreArrayF90(x,xx_v,ierr)
7220 .ve
7221 
7222     Level: advanced
7223 
7224 .seealso:  MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90()
7225 
7226     Concepts: matrices^accessing array
7227 
7228 M*/
7229 
7230 /*MC
7231     MatDenseRestoreArrayF90 - Restores a matrix array that has been
7232     accessed with MatDenseGetArrayF90().
7233 
7234     Synopsis:
7235     MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7236 
7237     Not collective
7238 
7239     Input Parameters:
7240 +   x - matrix
7241 -   xx_v - the Fortran90 pointer to the array
7242 
7243     Output Parameter:
7244 .   ierr - error code
7245 
7246     Example of Usage:
7247 .vb
7248        PetscScalar, pointer xx_v(:)
7249        ....
7250        call MatDenseGetArrayF90(x,xx_v,ierr)
7251        a = xx_v(3)
7252        call MatDenseRestoreArrayF90(x,xx_v,ierr)
7253 .ve
7254 
7255     Level: advanced
7256 
7257 .seealso:  MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90()
7258 
7259 M*/
7260 
7261 
7262 /*MC
7263     MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.
7264 
7265     Synopsis:
7266     MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7267 
7268     Not collective
7269 
7270     Input Parameter:
7271 .   x - matrix
7272 
7273     Output Parameters:
7274 +   xx_v - the Fortran90 pointer to the array
7275 -   ierr - error code
7276 
7277     Example of Usage:
7278 .vb
7279       PetscScalar, pointer xx_v(:,:)
7280       ....
7281       call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7282       a = xx_v(3)
7283       call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7284 .ve
7285 
7286     Level: advanced
7287 
7288 .seealso:  MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90()
7289 
7290     Concepts: matrices^accessing array
7291 
7292 M*/
7293 
7294 /*MC
7295     MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7296     accessed with MatSeqAIJGetArrayF90().
7297 
7298     Synopsis:
7299     MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7300 
7301     Not collective
7302 
7303     Input Parameters:
7304 +   x - matrix
7305 -   xx_v - the Fortran90 pointer to the array
7306 
7307     Output Parameter:
7308 .   ierr - error code
7309 
7310     Example of Usage:
7311 .vb
7312        PetscScalar, pointer xx_v(:)
7313        ....
7314        call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7315        a = xx_v(3)
7316        call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7317 .ve
7318 
7319     Level: advanced
7320 
7321 .seealso:  MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90()
7322 
7323 M*/
7324 
7325 
7326 #undef __FUNCT__
7327 #define __FUNCT__ "MatGetSubMatrix"
7328 /*@
7329     MatGetSubMatrix - Gets a single submatrix on the same number of processors
7330                       as the original matrix.
7331 
7332     Collective on Mat
7333 
7334     Input Parameters:
7335 +   mat - the original matrix
7336 .   isrow - parallel IS containing the rows this processor should obtain
7337 .   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.
7338 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7339 
7340     Output Parameter:
7341 .   newmat - the new submatrix, of the same type as the old
7342 
7343     Level: advanced
7344 
7345     Notes:
7346     The submatrix will be able to be multiplied with vectors using the same layout as iscol.
7347 
7348     The rows in isrow will be sorted into the same order as the original matrix on each process.
7349 
7350       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7351    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
7352    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7353    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
7354    you are finished using it.
7355 
7356     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7357     the input matrix.
7358 
7359     If iscol is NULL then all columns are obtained (not supported in Fortran).
7360 
7361    Example usage:
7362    Consider the following 8x8 matrix with 34 non-zero values, that is
7363    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7364    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7365    as follows:
7366 
7367 .vb
7368             1  2  0  |  0  3  0  |  0  4
7369     Proc0   0  5  6  |  7  0  0  |  8  0
7370             9  0 10  | 11  0  0  | 12  0
7371     -------------------------------------
7372            13  0 14  | 15 16 17  |  0  0
7373     Proc1   0 18  0  | 19 20 21  |  0  0
7374             0  0  0  | 22 23  0  | 24  0
7375     -------------------------------------
7376     Proc2  25 26 27  |  0  0 28  | 29  0
7377            30  0  0  | 31 32 33  |  0 34
7378 .ve
7379 
7380     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is
7381 
7382 .vb
7383             2  0  |  0  3  0  |  0
7384     Proc0   5  6  |  7  0  0  |  8
7385     -------------------------------
7386     Proc1  18  0  | 19 20 21  |  0
7387     -------------------------------
7388     Proc2  26 27  |  0  0 28  | 29
7389             0  0  | 31 32 33  |  0
7390 .ve
7391 
7392 
7393     Concepts: matrices^submatrices
7394 
7395 .seealso: MatGetSubMatrices()
7396 @*/
7397 PetscErrorCode  MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7398 {
7399   PetscErrorCode ierr;
7400   PetscMPIInt    size;
7401   Mat            *local;
7402   IS             iscoltmp;
7403 
7404   PetscFunctionBegin;
7405   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7406   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
7407   if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
7408   PetscValidPointer(newmat,5);
7409   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5);
7410   PetscValidType(mat,1);
7411   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7412   MatCheckPreallocated(mat,1);
7413   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
7414 
7415   if (!iscol) {
7416     ierr = ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr);
7417   } else {
7418     iscoltmp = iscol;
7419   }
7420 
7421   /* if original matrix is on just one processor then use submatrix generated */
7422   if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7423     ierr = MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
7424     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7425     PetscFunctionReturn(0);
7426   } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) {
7427     ierr    = MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
7428     *newmat = *local;
7429     ierr    = PetscFree(local);CHKERRQ(ierr);
7430     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7431     PetscFunctionReturn(0);
7432   } else if (!mat->ops->getsubmatrix) {
7433     /* Create a new matrix type that implements the operation using the full matrix */
7434     switch (cll) {
7435     case MAT_INITIAL_MATRIX:
7436       ierr = MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr);
7437       break;
7438     case MAT_REUSE_MATRIX:
7439       ierr = MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr);
7440       break;
7441     default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7442     }
7443     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7444     PetscFunctionReturn(0);
7445   }
7446 
7447   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7448   ierr = (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr);
7449   if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7450   if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);}
7451   PetscFunctionReturn(0);
7452 }
7453 
7454 #undef __FUNCT__
7455 #define __FUNCT__ "MatStashSetInitialSize"
7456 /*@
7457    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7458    used during the assembly process to store values that belong to
7459    other processors.
7460 
7461    Not Collective
7462 
7463    Input Parameters:
7464 +  mat   - the matrix
7465 .  size  - the initial size of the stash.
7466 -  bsize - the initial size of the block-stash(if used).
7467 
7468    Options Database Keys:
7469 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
7470 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
7471 
7472    Level: intermediate
7473 
7474    Notes:
7475      The block-stash is used for values set with MatSetValuesBlocked() while
7476      the stash is used for values set with MatSetValues()
7477 
7478      Run with the option -info and look for output of the form
7479      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7480      to determine the appropriate value, MM, to use for size and
7481      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7482      to determine the value, BMM to use for bsize
7483 
7484    Concepts: stash^setting matrix size
7485    Concepts: matrices^stash
7486 
7487 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
7488 
7489 @*/
7490 PetscErrorCode  MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7491 {
7492   PetscErrorCode ierr;
7493 
7494   PetscFunctionBegin;
7495   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7496   PetscValidType(mat,1);
7497   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
7498   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
7499   PetscFunctionReturn(0);
7500 }
7501 
7502 #undef __FUNCT__
7503 #define __FUNCT__ "MatInterpolateAdd"
7504 /*@
7505    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
7506      the matrix
7507 
7508    Neighbor-wise Collective on Mat
7509 
7510    Input Parameters:
7511 +  mat   - the matrix
7512 .  x,y - the vectors
7513 -  w - where the result is stored
7514 
7515    Level: intermediate
7516 
7517    Notes:
7518     w may be the same vector as y.
7519 
7520     This allows one to use either the restriction or interpolation (its transpose)
7521     matrix to do the interpolation
7522 
7523     Concepts: interpolation
7524 
7525 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7526 
7527 @*/
7528 PetscErrorCode  MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7529 {
7530   PetscErrorCode ierr;
7531   PetscInt       M,N,Ny;
7532 
7533   PetscFunctionBegin;
7534   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7535   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7536   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7537   PetscValidHeaderSpecific(w,VEC_CLASSID,4);
7538   PetscValidType(A,1);
7539   MatCheckPreallocated(A,1);
7540   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
7541   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
7542   if (M == Ny) {
7543     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
7544   } else {
7545     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
7546   }
7547   PetscFunctionReturn(0);
7548 }
7549 
7550 #undef __FUNCT__
7551 #define __FUNCT__ "MatInterpolate"
7552 /*@
7553    MatInterpolate - y = A*x or A'*x depending on the shape of
7554      the matrix
7555 
7556    Neighbor-wise Collective on Mat
7557 
7558    Input Parameters:
7559 +  mat   - the matrix
7560 -  x,y - the vectors
7561 
7562    Level: intermediate
7563 
7564    Notes:
7565     This allows one to use either the restriction or interpolation (its transpose)
7566     matrix to do the interpolation
7567 
7568    Concepts: matrices^interpolation
7569 
7570 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7571 
7572 @*/
7573 PetscErrorCode  MatInterpolate(Mat A,Vec x,Vec y)
7574 {
7575   PetscErrorCode ierr;
7576   PetscInt       M,N,Ny;
7577 
7578   PetscFunctionBegin;
7579   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7580   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7581   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7582   PetscValidType(A,1);
7583   MatCheckPreallocated(A,1);
7584   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
7585   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
7586   if (M == Ny) {
7587     ierr = MatMult(A,x,y);CHKERRQ(ierr);
7588   } else {
7589     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
7590   }
7591   PetscFunctionReturn(0);
7592 }
7593 
7594 #undef __FUNCT__
7595 #define __FUNCT__ "MatRestrict"
7596 /*@
7597    MatRestrict - y = A*x or A'*x
7598 
7599    Neighbor-wise Collective on Mat
7600 
7601    Input Parameters:
7602 +  mat   - the matrix
7603 -  x,y - the vectors
7604 
7605    Level: intermediate
7606 
7607    Notes:
7608     This allows one to use either the restriction or interpolation (its transpose)
7609     matrix to do the restriction
7610 
7611    Concepts: matrices^restriction
7612 
7613 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
7614 
7615 @*/
7616 PetscErrorCode  MatRestrict(Mat A,Vec x,Vec y)
7617 {
7618   PetscErrorCode ierr;
7619   PetscInt       M,N,Ny;
7620 
7621   PetscFunctionBegin;
7622   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7623   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7624   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7625   PetscValidType(A,1);
7626   MatCheckPreallocated(A,1);
7627 
7628   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
7629   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
7630   if (M == Ny) {
7631     ierr = MatMult(A,x,y);CHKERRQ(ierr);
7632   } else {
7633     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
7634   }
7635   PetscFunctionReturn(0);
7636 }
7637 
7638 #undef __FUNCT__
7639 #define __FUNCT__ "MatGetNullSpace"
7640 /*@
7641    MatGetNullSpace - retrieves the null space to a matrix.
7642 
7643    Logically Collective on Mat and MatNullSpace
7644 
7645    Input Parameters:
7646 +  mat - the matrix
7647 -  nullsp - the null space object
7648 
7649    Level: developer
7650 
7651    Notes:
7652       This null space is used by solvers. Overwrites any previous null space that may have been attached
7653 
7654    Concepts: null space^attaching to matrix
7655 
7656 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace()
7657 @*/
7658 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
7659 {
7660   PetscFunctionBegin;
7661   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7662   PetscValidType(mat,1);
7663   PetscValidPointer(nullsp,2);
7664   *nullsp = mat->nullsp;
7665   PetscFunctionReturn(0);
7666 }
7667 
7668 #undef __FUNCT__
7669 #define __FUNCT__ "MatSetNullSpace"
7670 /*@
7671    MatSetNullSpace - attaches a null space to a matrix.
7672         This null space will be removed from the resulting vector whenever
7673         MatMult() is called
7674 
7675    Logically Collective on Mat and MatNullSpace
7676 
7677    Input Parameters:
7678 +  mat - the matrix
7679 -  nullsp - the null space object
7680 
7681    Level: advanced
7682 
7683    Notes:
7684       This null space is used by solvers. Overwrites any previous null space that may have been attached
7685 
7686    Concepts: null space^attaching to matrix
7687 
7688 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace()
7689 @*/
7690 PetscErrorCode  MatSetNullSpace(Mat mat,MatNullSpace nullsp)
7691 {
7692   PetscErrorCode ierr;
7693 
7694   PetscFunctionBegin;
7695   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7696   PetscValidType(mat,1);
7697   PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
7698   MatCheckPreallocated(mat,1);
7699   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
7700   ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr);
7701 
7702   mat->nullsp = nullsp;
7703   PetscFunctionReturn(0);
7704 }
7705 
7706 #undef __FUNCT__
7707 #define __FUNCT__ "MatSetNearNullSpace"
7708 /*@
7709    MatSetNearNullSpace - attaches a null space to a matrix.
7710         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.
7711 
7712    Logically Collective on Mat and MatNullSpace
7713 
7714    Input Parameters:
7715 +  mat - the matrix
7716 -  nullsp - the null space object
7717 
7718    Level: advanced
7719 
7720    Notes:
7721       Overwrites any previous near null space that may have been attached
7722 
7723    Concepts: null space^attaching to matrix
7724 
7725 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace()
7726 @*/
7727 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
7728 {
7729   PetscErrorCode ierr;
7730 
7731   PetscFunctionBegin;
7732   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7733   PetscValidType(mat,1);
7734   PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
7735   MatCheckPreallocated(mat,1);
7736   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
7737   ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr);
7738 
7739   mat->nearnullsp = nullsp;
7740   PetscFunctionReturn(0);
7741 }
7742 
7743 #undef __FUNCT__
7744 #define __FUNCT__ "MatGetNearNullSpace"
7745 /*@
7746    MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()
7747 
7748    Not Collective
7749 
7750    Input Parameters:
7751 .  mat - the matrix
7752 
7753    Output Parameters:
7754 .  nullsp - the null space object, NULL if not set
7755 
7756    Level: developer
7757 
7758    Concepts: null space^attaching to matrix
7759 
7760 .seealso: MatSetNearNullSpace(), MatGetNullSpace()
7761 @*/
7762 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
7763 {
7764   PetscFunctionBegin;
7765   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7766   PetscValidType(mat,1);
7767   PetscValidPointer(nullsp,2);
7768   MatCheckPreallocated(mat,1);
7769   *nullsp = mat->nearnullsp;
7770   PetscFunctionReturn(0);
7771 }
7772 
7773 #undef __FUNCT__
7774 #define __FUNCT__ "MatICCFactor"
7775 /*@C
7776    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
7777 
7778    Collective on Mat
7779 
7780    Input Parameters:
7781 +  mat - the matrix
7782 .  row - row/column permutation
7783 .  fill - expected fill factor >= 1.0
7784 -  level - level of fill, for ICC(k)
7785 
7786    Notes:
7787    Probably really in-place only when level of fill is zero, otherwise allocates
7788    new space to store factored matrix and deletes previous memory.
7789 
7790    Most users should employ the simplified KSP interface for linear solvers
7791    instead of working directly with matrix algebra routines such as this.
7792    See, e.g., KSPCreate().
7793 
7794    Level: developer
7795 
7796    Concepts: matrices^incomplete Cholesky factorization
7797    Concepts: Cholesky factorization
7798 
7799 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
7800 
7801     Developer Note: fortran interface is not autogenerated as the f90
7802     interface defintion cannot be generated correctly [due to MatFactorInfo]
7803 
7804 @*/
7805 PetscErrorCode  MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
7806 {
7807   PetscErrorCode ierr;
7808 
7809   PetscFunctionBegin;
7810   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7811   PetscValidType(mat,1);
7812   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
7813   PetscValidPointer(info,3);
7814   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
7815   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7816   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7817   if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7818   MatCheckPreallocated(mat,1);
7819   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
7820   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
7821   PetscFunctionReturn(0);
7822 }
7823 
7824 #undef __FUNCT__
7825 #define __FUNCT__ "MatSetValuesAdifor"
7826 /*@
7827    MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.
7828 
7829    Not Collective
7830 
7831    Input Parameters:
7832 +  mat - the matrix
7833 .  nl - leading dimension of v
7834 -  v - the values compute with ADIFOR
7835 
7836    Level: developer
7837 
7838    Notes:
7839      Must call MatSetColoring() before using this routine. Also this matrix must already
7840      have its nonzero pattern determined.
7841 
7842 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7843           MatSetValues(), MatSetColoring()
7844 @*/
7845 PetscErrorCode  MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
7846 {
7847   PetscErrorCode ierr;
7848 
7849   PetscFunctionBegin;
7850   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7851   PetscValidType(mat,1);
7852   PetscValidPointer(v,3);
7853 
7854   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7855   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
7856   if (!mat->ops->setvaluesadifor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7857   ierr = (*mat->ops->setvaluesadifor)(mat,nl,v);CHKERRQ(ierr);
7858   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
7859   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
7860   PetscFunctionReturn(0);
7861 }
7862 
7863 #undef __FUNCT__
7864 #define __FUNCT__ "MatDiagonalScaleLocal"
7865 /*@
7866    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
7867          ghosted ones.
7868 
7869    Not Collective
7870 
7871    Input Parameters:
7872 +  mat - the matrix
7873 -  diag = the diagonal values, including ghost ones
7874 
7875    Level: developer
7876 
7877    Notes: Works only for MPIAIJ and MPIBAIJ matrices
7878 
7879 .seealso: MatDiagonalScale()
7880 @*/
7881 PetscErrorCode  MatDiagonalScaleLocal(Mat mat,Vec diag)
7882 {
7883   PetscErrorCode ierr;
7884   PetscMPIInt    size;
7885 
7886   PetscFunctionBegin;
7887   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7888   PetscValidHeaderSpecific(diag,VEC_CLASSID,2);
7889   PetscValidType(mat,1);
7890 
7891   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7892   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
7893   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
7894   if (size == 1) {
7895     PetscInt n,m;
7896     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
7897     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
7898     if (m == n) {
7899       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
7900     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
7901   } else {
7902     ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr);
7903   }
7904   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
7905   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
7906   PetscFunctionReturn(0);
7907 }
7908 
7909 #undef __FUNCT__
7910 #define __FUNCT__ "MatGetInertia"
7911 /*@
7912    MatGetInertia - Gets the inertia from a factored matrix
7913 
7914    Collective on Mat
7915 
7916    Input Parameter:
7917 .  mat - the matrix
7918 
7919    Output Parameters:
7920 +   nneg - number of negative eigenvalues
7921 .   nzero - number of zero eigenvalues
7922 -   npos - number of positive eigenvalues
7923 
7924    Level: advanced
7925 
7926    Notes: Matrix must have been factored by MatCholeskyFactor()
7927 
7928 
7929 @*/
7930 PetscErrorCode  MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
7931 {
7932   PetscErrorCode ierr;
7933 
7934   PetscFunctionBegin;
7935   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7936   PetscValidType(mat,1);
7937   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7938   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
7939   if (!mat->ops->getinertia) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7940   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
7941   PetscFunctionReturn(0);
7942 }
7943 
7944 /* ----------------------------------------------------------------*/
7945 #undef __FUNCT__
7946 #define __FUNCT__ "MatSolves"
7947 /*@C
7948    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
7949 
7950    Neighbor-wise Collective on Mat and Vecs
7951 
7952    Input Parameters:
7953 +  mat - the factored matrix
7954 -  b - the right-hand-side vectors
7955 
7956    Output Parameter:
7957 .  x - the result vectors
7958 
7959    Notes:
7960    The vectors b and x cannot be the same.  I.e., one cannot
7961    call MatSolves(A,x,x).
7962 
7963    Notes:
7964    Most users should employ the simplified KSP interface for linear solvers
7965    instead of working directly with matrix algebra routines such as this.
7966    See, e.g., KSPCreate().
7967 
7968    Level: developer
7969 
7970    Concepts: matrices^triangular solves
7971 
7972 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
7973 @*/
7974 PetscErrorCode  MatSolves(Mat mat,Vecs b,Vecs x)
7975 {
7976   PetscErrorCode ierr;
7977 
7978   PetscFunctionBegin;
7979   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7980   PetscValidType(mat,1);
7981   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
7982   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7983   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
7984 
7985   if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7986   MatCheckPreallocated(mat,1);
7987   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
7988   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
7989   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
7990   PetscFunctionReturn(0);
7991 }
7992 
7993 #undef __FUNCT__
7994 #define __FUNCT__ "MatIsSymmetric"
7995 /*@
7996    MatIsSymmetric - Test whether a matrix is symmetric
7997 
7998    Collective on Mat
7999 
8000    Input Parameter:
8001 +  A - the matrix to test
8002 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
8003 
8004    Output Parameters:
8005 .  flg - the result
8006 
8007    Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
8008 
8009    Level: intermediate
8010 
8011    Concepts: matrix^symmetry
8012 
8013 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
8014 @*/
8015 PetscErrorCode  MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
8016 {
8017   PetscErrorCode ierr;
8018 
8019   PetscFunctionBegin;
8020   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8021   PetscValidPointer(flg,2);
8022 
8023   if (!A->symmetric_set) {
8024     if (!A->ops->issymmetric) {
8025       MatType mattype;
8026       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8027       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8028     }
8029     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8030     if (!tol) {
8031       A->symmetric_set = PETSC_TRUE;
8032       A->symmetric     = *flg;
8033       if (A->symmetric) {
8034         A->structurally_symmetric_set = PETSC_TRUE;
8035         A->structurally_symmetric     = PETSC_TRUE;
8036       }
8037     }
8038   } else if (A->symmetric) {
8039     *flg = PETSC_TRUE;
8040   } else if (!tol) {
8041     *flg = PETSC_FALSE;
8042   } else {
8043     if (!A->ops->issymmetric) {
8044       MatType mattype;
8045       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8046       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8047     }
8048     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8049   }
8050   PetscFunctionReturn(0);
8051 }
8052 
8053 #undef __FUNCT__
8054 #define __FUNCT__ "MatIsHermitian"
8055 /*@
8056    MatIsHermitian - Test whether a matrix is Hermitian
8057 
8058    Collective on Mat
8059 
8060    Input Parameter:
8061 +  A - the matrix to test
8062 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
8063 
8064    Output Parameters:
8065 .  flg - the result
8066 
8067    Level: intermediate
8068 
8069    Concepts: matrix^symmetry
8070 
8071 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
8072           MatIsSymmetricKnown(), MatIsSymmetric()
8073 @*/
8074 PetscErrorCode  MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
8075 {
8076   PetscErrorCode ierr;
8077 
8078   PetscFunctionBegin;
8079   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8080   PetscValidPointer(flg,2);
8081 
8082   if (!A->hermitian_set) {
8083     if (!A->ops->ishermitian) {
8084       MatType mattype;
8085       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8086       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8087     }
8088     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8089     if (!tol) {
8090       A->hermitian_set = PETSC_TRUE;
8091       A->hermitian     = *flg;
8092       if (A->hermitian) {
8093         A->structurally_symmetric_set = PETSC_TRUE;
8094         A->structurally_symmetric     = PETSC_TRUE;
8095       }
8096     }
8097   } else if (A->hermitian) {
8098     *flg = PETSC_TRUE;
8099   } else if (!tol) {
8100     *flg = PETSC_FALSE;
8101   } else {
8102     if (!A->ops->ishermitian) {
8103       MatType mattype;
8104       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8105       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8106     }
8107     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8108   }
8109   PetscFunctionReturn(0);
8110 }
8111 
8112 #undef __FUNCT__
8113 #define __FUNCT__ "MatIsSymmetricKnown"
8114 /*@
8115    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
8116 
8117    Not Collective
8118 
8119    Input Parameter:
8120 .  A - the matrix to check
8121 
8122    Output Parameters:
8123 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
8124 -  flg - the result
8125 
8126    Level: advanced
8127 
8128    Concepts: matrix^symmetry
8129 
8130    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
8131          if you want it explicitly checked
8132 
8133 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8134 @*/
8135 PetscErrorCode  MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8136 {
8137   PetscFunctionBegin;
8138   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8139   PetscValidPointer(set,2);
8140   PetscValidPointer(flg,3);
8141   if (A->symmetric_set) {
8142     *set = PETSC_TRUE;
8143     *flg = A->symmetric;
8144   } else {
8145     *set = PETSC_FALSE;
8146   }
8147   PetscFunctionReturn(0);
8148 }
8149 
8150 #undef __FUNCT__
8151 #define __FUNCT__ "MatIsHermitianKnown"
8152 /*@
8153    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
8154 
8155    Not Collective
8156 
8157    Input Parameter:
8158 .  A - the matrix to check
8159 
8160    Output Parameters:
8161 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8162 -  flg - the result
8163 
8164    Level: advanced
8165 
8166    Concepts: matrix^symmetry
8167 
8168    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8169          if you want it explicitly checked
8170 
8171 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8172 @*/
8173 PetscErrorCode  MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8174 {
8175   PetscFunctionBegin;
8176   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8177   PetscValidPointer(set,2);
8178   PetscValidPointer(flg,3);
8179   if (A->hermitian_set) {
8180     *set = PETSC_TRUE;
8181     *flg = A->hermitian;
8182   } else {
8183     *set = PETSC_FALSE;
8184   }
8185   PetscFunctionReturn(0);
8186 }
8187 
8188 #undef __FUNCT__
8189 #define __FUNCT__ "MatIsStructurallySymmetric"
8190 /*@
8191    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
8192 
8193    Collective on Mat
8194 
8195    Input Parameter:
8196 .  A - the matrix to test
8197 
8198    Output Parameters:
8199 .  flg - the result
8200 
8201    Level: intermediate
8202 
8203    Concepts: matrix^symmetry
8204 
8205 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8206 @*/
8207 PetscErrorCode  MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
8208 {
8209   PetscErrorCode ierr;
8210 
8211   PetscFunctionBegin;
8212   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8213   PetscValidPointer(flg,2);
8214   if (!A->structurally_symmetric_set) {
8215     if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8216     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
8217 
8218     A->structurally_symmetric_set = PETSC_TRUE;
8219   }
8220   *flg = A->structurally_symmetric;
8221   PetscFunctionReturn(0);
8222 }
8223 
8224 #undef __FUNCT__
8225 #define __FUNCT__ "MatStashGetInfo"
8226 extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
8227 /*@
8228    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8229        to be communicated to other processors during the MatAssemblyBegin/End() process
8230 
8231     Not collective
8232 
8233    Input Parameter:
8234 .   vec - the vector
8235 
8236    Output Parameters:
8237 +   nstash   - the size of the stash
8238 .   reallocs - the number of additional mallocs incurred.
8239 .   bnstash   - the size of the block stash
8240 -   breallocs - the number of additional mallocs incurred.in the block stash
8241 
8242    Level: advanced
8243 
8244 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
8245 
8246 @*/
8247 PetscErrorCode  MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8248 {
8249   PetscErrorCode ierr;
8250 
8251   PetscFunctionBegin;
8252   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
8253   ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
8254   PetscFunctionReturn(0);
8255 }
8256 
8257 #undef __FUNCT__
8258 #define __FUNCT__ "MatGetVecs"
8259 /*@C
8260    MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same
8261      parallel layout
8262 
8263    Collective on Mat
8264 
8265    Input Parameter:
8266 .  mat - the matrix
8267 
8268    Output Parameter:
8269 +   right - (optional) vector that the matrix can be multiplied against
8270 -   left - (optional) vector that the matrix vector product can be stored in
8271 
8272   Level: advanced
8273 
8274 .seealso: MatCreate()
8275 @*/
8276 PetscErrorCode  MatGetVecs(Mat mat,Vec *right,Vec *left)
8277 {
8278   PetscErrorCode ierr;
8279 
8280   PetscFunctionBegin;
8281   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8282   PetscValidType(mat,1);
8283   MatCheckPreallocated(mat,1);
8284   if (mat->ops->getvecs) {
8285     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
8286   } else {
8287     PetscMPIInt size;
8288     ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat), &size);CHKERRQ(ierr);
8289     if (right) {
8290       ierr = VecCreate(PetscObjectComm((PetscObject)mat),right);CHKERRQ(ierr);
8291       ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8292       ierr = VecSetBlockSize(*right,mat->rmap->bs);CHKERRQ(ierr);
8293       ierr = VecSetType(*right,VECSTANDARD);CHKERRQ(ierr);
8294       ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr);
8295     }
8296     if (left) {
8297       ierr = VecCreate(PetscObjectComm((PetscObject)mat),left);CHKERRQ(ierr);
8298       ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8299       ierr = VecSetBlockSize(*left,mat->rmap->bs);CHKERRQ(ierr);
8300       ierr = VecSetType(*left,VECSTANDARD);CHKERRQ(ierr);
8301       ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr);
8302     }
8303   }
8304   PetscFunctionReturn(0);
8305 }
8306 
8307 #undef __FUNCT__
8308 #define __FUNCT__ "MatFactorInfoInitialize"
8309 /*@C
8310    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8311      with default values.
8312 
8313    Not Collective
8314 
8315    Input Parameters:
8316 .    info - the MatFactorInfo data structure
8317 
8318 
8319    Notes: The solvers are generally used through the KSP and PC objects, for example
8320           PCLU, PCILU, PCCHOLESKY, PCICC
8321 
8322    Level: developer
8323 
8324 .seealso: MatFactorInfo
8325 
8326     Developer Note: fortran interface is not autogenerated as the f90
8327     interface defintion cannot be generated correctly [due to MatFactorInfo]
8328 
8329 @*/
8330 
8331 PetscErrorCode  MatFactorInfoInitialize(MatFactorInfo *info)
8332 {
8333   PetscErrorCode ierr;
8334 
8335   PetscFunctionBegin;
8336   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
8337   PetscFunctionReturn(0);
8338 }
8339 
8340 #undef __FUNCT__
8341 #define __FUNCT__ "MatPtAP"
8342 /*@
8343    MatPtAP - Creates the matrix product C = P^T * A * P
8344 
8345    Neighbor-wise Collective on Mat
8346 
8347    Input Parameters:
8348 +  A - the matrix
8349 .  P - the projection matrix
8350 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8351 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P))
8352 
8353    Output Parameters:
8354 .  C - the product matrix
8355 
8356    Notes:
8357    C will be created and must be destroyed by the user with MatDestroy().
8358 
8359    This routine is currently only implemented for pairs of AIJ matrices and classes
8360    which inherit from AIJ.
8361 
8362    Level: intermediate
8363 
8364 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
8365 @*/
8366 PetscErrorCode  MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
8367 {
8368   PetscErrorCode ierr;
8369   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8370   PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
8371   PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
8372   PetscBool      viatranspose=PETSC_FALSE,viamatmatmatmult=PETSC_FALSE;
8373 
8374   PetscFunctionBegin;
8375   ierr = PetscOptionsGetBool(((PetscObject)A)->prefix,"-matptap_viatranspose",&viatranspose,NULL);CHKERRQ(ierr);
8376   ierr = PetscOptionsGetBool(((PetscObject)A)->prefix,"-matptap_viamatmatmatmult",&viamatmatmatmult,NULL);CHKERRQ(ierr);
8377 
8378   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8379   PetscValidType(A,1);
8380   MatCheckPreallocated(A,1);
8381   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8382   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8383   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
8384   PetscValidType(P,2);
8385   MatCheckPreallocated(P,2);
8386   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8387   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8388 
8389   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);
8390   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8391 
8392   if (scall == MAT_REUSE_MATRIX) {
8393     PetscValidPointer(*C,5);
8394     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
8395     if (viatranspose || viamatmatmatmult) {
8396       Mat Pt;
8397       ierr = MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);CHKERRQ(ierr);
8398       if (viamatmatmatmult) {
8399         ierr = MatMatMatMult(Pt,A,P,scall,fill,C);CHKERRQ(ierr);
8400       } else {
8401         Mat AP;
8402         ierr = MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);CHKERRQ(ierr);
8403         ierr = MatMatMult(Pt,AP,scall,fill,C);CHKERRQ(ierr);
8404         ierr = MatDestroy(&AP);CHKERRQ(ierr);
8405       }
8406       ierr = MatDestroy(&Pt);CHKERRQ(ierr);
8407     } else {
8408       ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
8409       ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
8410       ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr);
8411       ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
8412       ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
8413     }
8414     PetscFunctionReturn(0);
8415   }
8416 
8417   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8418   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8419 
8420   fA = A->ops->ptap;
8421   fP = P->ops->ptap;
8422   if (fP == fA) {
8423     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name);
8424     ptap = fA;
8425   } else {
8426     /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
8427     char ptapname[256];
8428     ierr = PetscStrcpy(ptapname,"MatPtAP_");CHKERRQ(ierr);
8429     ierr = PetscStrcat(ptapname,((PetscObject)A)->type_name);CHKERRQ(ierr);
8430     ierr = PetscStrcat(ptapname,"_");CHKERRQ(ierr);
8431     ierr = PetscStrcat(ptapname,((PetscObject)P)->type_name);CHKERRQ(ierr);
8432     ierr = PetscStrcat(ptapname,"_C");CHKERRQ(ierr); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
8433     ierr = PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);CHKERRQ(ierr);
8434     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);
8435   }
8436 
8437   if (viatranspose || viamatmatmatmult) {
8438     Mat Pt;
8439     ierr = MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);CHKERRQ(ierr);
8440     if (viamatmatmatmult) {
8441       ierr = MatMatMatMult(Pt,A,P,scall,fill,C);CHKERRQ(ierr);
8442       ierr = PetscInfo(*C,"MatPtAP via MatMatMatMult\n");CHKERRQ(ierr);
8443     } else {
8444       Mat AP;
8445       ierr = MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);CHKERRQ(ierr);
8446       ierr = MatMatMult(Pt,AP,scall,fill,C);CHKERRQ(ierr);
8447       ierr = MatDestroy(&AP);CHKERRQ(ierr);
8448       ierr = PetscInfo(*C,"MatPtAP via MatTranspose and MatMatMult\n");CHKERRQ(ierr);
8449     }
8450     ierr = MatDestroy(&Pt);CHKERRQ(ierr);
8451   } else {
8452     ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
8453     ierr = (*ptap)(A,P,scall,fill,C);CHKERRQ(ierr);
8454     ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
8455   }
8456   PetscFunctionReturn(0);
8457 }
8458 
8459 #undef __FUNCT__
8460 #define __FUNCT__ "MatPtAPNumeric"
8461 /*@
8462    MatPtAPNumeric - Computes the matrix product C = P^T * A * P
8463 
8464    Neighbor-wise Collective on Mat
8465 
8466    Input Parameters:
8467 +  A - the matrix
8468 -  P - the projection matrix
8469 
8470    Output Parameters:
8471 .  C - the product matrix
8472 
8473    Notes:
8474    C must have been created by calling MatPtAPSymbolic and must be destroyed by
8475    the user using MatDeatroy().
8476 
8477    This routine is currently only implemented for pairs of AIJ matrices and classes
8478    which inherit from AIJ.  C will be of type MATAIJ.
8479 
8480    Level: intermediate
8481 
8482 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
8483 @*/
8484 PetscErrorCode  MatPtAPNumeric(Mat A,Mat P,Mat C)
8485 {
8486   PetscErrorCode ierr;
8487 
8488   PetscFunctionBegin;
8489   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8490   PetscValidType(A,1);
8491   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8492   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8493   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
8494   PetscValidType(P,2);
8495   MatCheckPreallocated(P,2);
8496   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8497   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8498   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
8499   PetscValidType(C,3);
8500   MatCheckPreallocated(C,3);
8501   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8502   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);
8503   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);
8504   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);
8505   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);
8506   MatCheckPreallocated(A,1);
8507 
8508   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
8509   ierr = (*C->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr);
8510   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
8511   PetscFunctionReturn(0);
8512 }
8513 
8514 #undef __FUNCT__
8515 #define __FUNCT__ "MatPtAPSymbolic"
8516 /*@
8517    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P
8518 
8519    Neighbor-wise Collective on Mat
8520 
8521    Input Parameters:
8522 +  A - the matrix
8523 -  P - the projection matrix
8524 
8525    Output Parameters:
8526 .  C - the (i,j) structure of the product matrix
8527 
8528    Notes:
8529    C will be created and must be destroyed by the user with MatDestroy().
8530 
8531    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
8532    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
8533    this (i,j) structure by calling MatPtAPNumeric().
8534 
8535    Level: intermediate
8536 
8537 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
8538 @*/
8539 PetscErrorCode  MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
8540 {
8541   PetscErrorCode ierr;
8542 
8543   PetscFunctionBegin;
8544   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8545   PetscValidType(A,1);
8546   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8547   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8548   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8549   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
8550   PetscValidType(P,2);
8551   MatCheckPreallocated(P,2);
8552   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8553   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8554   PetscValidPointer(C,3);
8555 
8556   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);
8557   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);
8558   MatCheckPreallocated(A,1);
8559   ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
8560   ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr);
8561   ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
8562 
8563   /* ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); NO! this is not always true -ma */
8564   PetscFunctionReturn(0);
8565 }
8566 
8567 #undef __FUNCT__
8568 #define __FUNCT__ "MatRARt"
8569 /*@
8570    MatRARt - Creates the matrix product C = R * A * R^T
8571 
8572    Neighbor-wise Collective on Mat
8573 
8574    Input Parameters:
8575 +  A - the matrix
8576 .  R - the projection matrix
8577 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8578 -  fill - expected fill as ratio of nnz(C)/nnz(A)
8579 
8580    Output Parameters:
8581 .  C - the product matrix
8582 
8583    Notes:
8584    C will be created and must be destroyed by the user with MatDestroy().
8585 
8586    This routine is currently only implemented for pairs of AIJ matrices and classes
8587    which inherit from AIJ.
8588 
8589    Level: intermediate
8590 
8591 .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
8592 @*/
8593 PetscErrorCode  MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
8594 {
8595   PetscErrorCode ierr;
8596 
8597   PetscFunctionBegin;
8598   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8599   PetscValidType(A,1);
8600   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8601   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8602   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
8603   PetscValidType(R,2);
8604   MatCheckPreallocated(R,2);
8605   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8606   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8607   PetscValidPointer(C,3);
8608   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);
8609   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8610   MatCheckPreallocated(A,1);
8611 
8612   if (!A->ops->rart) {
8613     MatType mattype;
8614     ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8615     SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix of type <%s> does not support RARt",mattype);
8616   }
8617   ierr = PetscLogEventBegin(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
8618   ierr = (*A->ops->rart)(A,R,scall,fill,C);CHKERRQ(ierr);
8619   ierr = PetscLogEventEnd(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
8620   PetscFunctionReturn(0);
8621 }
8622 
8623 #undef __FUNCT__
8624 #define __FUNCT__ "MatRARtNumeric"
8625 /*@
8626    MatRARtNumeric - Computes the matrix product C = R * A * R^T
8627 
8628    Neighbor-wise Collective on Mat
8629 
8630    Input Parameters:
8631 +  A - the matrix
8632 -  R - the projection matrix
8633 
8634    Output Parameters:
8635 .  C - the product matrix
8636 
8637    Notes:
8638    C must have been created by calling MatRARtSymbolic and must be destroyed by
8639    the user using MatDeatroy().
8640 
8641    This routine is currently only implemented for pairs of AIJ matrices and classes
8642    which inherit from AIJ.  C will be of type MATAIJ.
8643 
8644    Level: intermediate
8645 
8646 .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
8647 @*/
8648 PetscErrorCode  MatRARtNumeric(Mat A,Mat R,Mat C)
8649 {
8650   PetscErrorCode ierr;
8651 
8652   PetscFunctionBegin;
8653   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8654   PetscValidType(A,1);
8655   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8656   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8657   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
8658   PetscValidType(R,2);
8659   MatCheckPreallocated(R,2);
8660   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8661   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8662   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
8663   PetscValidType(C,3);
8664   MatCheckPreallocated(C,3);
8665   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8666   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);
8667   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);
8668   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);
8669   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);
8670   MatCheckPreallocated(A,1);
8671 
8672   ierr = PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
8673   ierr = (*A->ops->rartnumeric)(A,R,C);CHKERRQ(ierr);
8674   ierr = PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
8675   PetscFunctionReturn(0);
8676 }
8677 
8678 #undef __FUNCT__
8679 #define __FUNCT__ "MatRARtSymbolic"
8680 /*@
8681    MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T
8682 
8683    Neighbor-wise Collective on Mat
8684 
8685    Input Parameters:
8686 +  A - the matrix
8687 -  R - the projection matrix
8688 
8689    Output Parameters:
8690 .  C - the (i,j) structure of the product matrix
8691 
8692    Notes:
8693    C will be created and must be destroyed by the user with MatDestroy().
8694 
8695    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
8696    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
8697    this (i,j) structure by calling MatRARtNumeric().
8698 
8699    Level: intermediate
8700 
8701 .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
8702 @*/
8703 PetscErrorCode  MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
8704 {
8705   PetscErrorCode ierr;
8706 
8707   PetscFunctionBegin;
8708   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8709   PetscValidType(A,1);
8710   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8711   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8712   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8713   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
8714   PetscValidType(R,2);
8715   MatCheckPreallocated(R,2);
8716   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8717   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8718   PetscValidPointer(C,3);
8719 
8720   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);
8721   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);
8722   MatCheckPreallocated(A,1);
8723   ierr = PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
8724   ierr = (*A->ops->rartsymbolic)(A,R,fill,C);CHKERRQ(ierr);
8725   ierr = PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
8726 
8727   ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr);
8728   PetscFunctionReturn(0);
8729 }
8730 
8731 #undef __FUNCT__
8732 #define __FUNCT__ "MatMatMult"
8733 /*@
8734    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
8735 
8736    Neighbor-wise Collective on Mat
8737 
8738    Input Parameters:
8739 +  A - the left matrix
8740 .  B - the right matrix
8741 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8742 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
8743           if the result is a dense matrix this is irrelevent
8744 
8745    Output Parameters:
8746 .  C - the product matrix
8747 
8748    Notes:
8749    Unless scall is MAT_REUSE_MATRIX C will be created.
8750 
8751    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8752 
8753    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8754    actually needed.
8755 
8756    If you have many matrices with the same non-zero structure to multiply, you
8757    should either
8758 $   1) use MAT_REUSE_MATRIX in all calls but the first or
8759 $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
8760 
8761    Level: intermediate
8762 
8763 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(),  MatMatTransposeMult(), MatPtAP()
8764 @*/
8765 PetscErrorCode  MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8766 {
8767   PetscErrorCode ierr;
8768   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8769   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8770   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
8771 
8772   PetscFunctionBegin;
8773   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8774   PetscValidType(A,1);
8775   MatCheckPreallocated(A,1);
8776   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8777   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8778   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8779   PetscValidType(B,2);
8780   MatCheckPreallocated(B,2);
8781   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8782   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8783   PetscValidPointer(C,3);
8784   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);
8785   if (scall == MAT_REUSE_MATRIX) {
8786     PetscValidPointer(*C,5);
8787     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
8788     ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
8789     ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
8790     ierr = (*(*C)->ops->matmultnumeric)(A,B,*C);CHKERRQ(ierr);
8791     ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
8792     ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
8793     PetscFunctionReturn(0);
8794   }
8795   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8796   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8797 
8798   fA = A->ops->matmult;
8799   fB = B->ops->matmult;
8800   if (fB == fA) {
8801     if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
8802     mult = fB;
8803   } else {
8804     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
8805     char multname[256];
8806     ierr = PetscStrcpy(multname,"MatMatMult_");CHKERRQ(ierr);
8807     ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr);
8808     ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);
8809     ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr);
8810     ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
8811     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
8812     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);
8813   }
8814   ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
8815   ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr);
8816   ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
8817   PetscFunctionReturn(0);
8818 }
8819 
8820 #undef __FUNCT__
8821 #define __FUNCT__ "MatMatMultSymbolic"
8822 /*@
8823    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
8824    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().
8825 
8826    Neighbor-wise Collective on Mat
8827 
8828    Input Parameters:
8829 +  A - the left matrix
8830 .  B - the right matrix
8831 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
8832       if C is a dense matrix this is irrelevent
8833 
8834    Output Parameters:
8835 .  C - the product matrix
8836 
8837    Notes:
8838    Unless scall is MAT_REUSE_MATRIX C will be created.
8839 
8840    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8841    actually needed.
8842 
8843    This routine is currently implemented for
8844     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
8845     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8846     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
8847 
8848    Level: intermediate
8849 
8850    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
8851      We should incorporate them into PETSc.
8852 
8853 .seealso: MatMatMult(), MatMatMultNumeric()
8854 @*/
8855 PetscErrorCode  MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
8856 {
8857   PetscErrorCode ierr;
8858   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*);
8859   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*);
8860   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL;
8861 
8862   PetscFunctionBegin;
8863   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8864   PetscValidType(A,1);
8865   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8866   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8867 
8868   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8869   PetscValidType(B,2);
8870   MatCheckPreallocated(B,2);
8871   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8872   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8873   PetscValidPointer(C,3);
8874 
8875   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);
8876   if (fill == PETSC_DEFAULT) fill = 2.0;
8877   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8878   MatCheckPreallocated(A,1);
8879 
8880   Asymbolic = A->ops->matmultsymbolic;
8881   Bsymbolic = B->ops->matmultsymbolic;
8882   if (Asymbolic == Bsymbolic) {
8883     if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
8884     symbolic = Bsymbolic;
8885   } else { /* dispatch based on the type of A and B */
8886     char symbolicname[256];
8887     ierr = PetscStrcpy(symbolicname,"MatMatMultSymbolic_");CHKERRQ(ierr);
8888     ierr = PetscStrcat(symbolicname,((PetscObject)A)->type_name);CHKERRQ(ierr);
8889     ierr = PetscStrcat(symbolicname,"_");CHKERRQ(ierr);
8890     ierr = PetscStrcat(symbolicname,((PetscObject)B)->type_name);CHKERRQ(ierr);
8891     ierr = PetscStrcat(symbolicname,"_C");CHKERRQ(ierr);
8892     ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);CHKERRQ(ierr);
8893     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);
8894   }
8895   ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
8896   ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr);
8897   ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
8898   PetscFunctionReturn(0);
8899 }
8900 
8901 #undef __FUNCT__
8902 #define __FUNCT__ "MatMatMultNumeric"
8903 /*@
8904    MatMatMultNumeric - Performs the numeric matrix-matrix product.
8905    Call this routine after first calling MatMatMultSymbolic().
8906 
8907    Neighbor-wise Collective on Mat
8908 
8909    Input Parameters:
8910 +  A - the left matrix
8911 -  B - the right matrix
8912 
8913    Output Parameters:
8914 .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
8915 
8916    Notes:
8917    C must have been created with MatMatMultSymbolic().
8918 
8919    This routine is currently implemented for
8920     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
8921     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8922     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
8923 
8924    Level: intermediate
8925 
8926 .seealso: MatMatMult(), MatMatMultSymbolic()
8927 @*/
8928 PetscErrorCode  MatMatMultNumeric(Mat A,Mat B,Mat C)
8929 {
8930   PetscErrorCode ierr;
8931 
8932   PetscFunctionBegin;
8933   ierr = MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);CHKERRQ(ierr);
8934   PetscFunctionReturn(0);
8935 }
8936 
8937 #undef __FUNCT__
8938 #define __FUNCT__ "MatMatTransposeMult"
8939 /*@
8940    MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.
8941 
8942    Neighbor-wise Collective on Mat
8943 
8944    Input Parameters:
8945 +  A - the left matrix
8946 .  B - the right matrix
8947 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8948 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
8949 
8950    Output Parameters:
8951 .  C - the product matrix
8952 
8953    Notes:
8954    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
8955 
8956    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8957 
8958   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8959    actually needed.
8960 
8961    This routine is currently only implemented for pairs of SeqAIJ matrices.  C will be of type MATSEQAIJ.
8962 
8963    Level: intermediate
8964 
8965 .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
8966 @*/
8967 PetscErrorCode  MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8968 {
8969   PetscErrorCode ierr;
8970   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8971   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8972 
8973   PetscFunctionBegin;
8974   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8975   PetscValidType(A,1);
8976   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8977   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8978   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8979   PetscValidType(B,2);
8980   MatCheckPreallocated(B,2);
8981   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8982   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8983   PetscValidPointer(C,3);
8984   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);
8985   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8986   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8987   MatCheckPreallocated(A,1);
8988 
8989   fA = A->ops->mattransposemult;
8990   if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
8991   fB = B->ops->mattransposemult;
8992   if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
8993   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);
8994 
8995   ierr = PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
8996   if (scall == MAT_INITIAL_MATRIX) {
8997     ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
8998     ierr = (*A->ops->mattransposemultsymbolic)(A,B,fill,C);CHKERRQ(ierr);
8999     ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9000   }
9001   ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
9002   ierr = (*A->ops->mattransposemultnumeric)(A,B,*C);CHKERRQ(ierr);
9003   ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
9004   ierr = PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
9005   PetscFunctionReturn(0);
9006 }
9007 
9008 #undef __FUNCT__
9009 #define __FUNCT__ "MatTransposeMatMult"
9010 /*@
9011    MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.
9012 
9013    Neighbor-wise Collective on Mat
9014 
9015    Input Parameters:
9016 +  A - the left matrix
9017 .  B - the right matrix
9018 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9019 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9020 
9021    Output Parameters:
9022 .  C - the product matrix
9023 
9024    Notes:
9025    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9026 
9027    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9028 
9029   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9030    actually needed.
9031 
9032    This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
9033    which inherit from SeqAIJ.  C will be of same type as the input matrices.
9034 
9035    Level: intermediate
9036 
9037 .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
9038 @*/
9039 PetscErrorCode  MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9040 {
9041   PetscErrorCode ierr;
9042   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9043   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9044   PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL;
9045 
9046   PetscFunctionBegin;
9047   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9048   PetscValidType(A,1);
9049   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9050   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9051   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9052   PetscValidType(B,2);
9053   MatCheckPreallocated(B,2);
9054   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9055   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9056   PetscValidPointer(C,3);
9057   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);
9058   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9059   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
9060   MatCheckPreallocated(A,1);
9061 
9062   fA = A->ops->transposematmult;
9063   fB = B->ops->transposematmult;
9064   if (fB==fA) {
9065     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9066     transposematmult = fA;
9067   } else {
9068     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9069     char multname[256];
9070     ierr = PetscStrcpy(multname,"MatTransposeMatMult_");CHKERRQ(ierr);
9071     ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr);
9072     ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);
9073     ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr);
9074     ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9075     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);CHKERRQ(ierr);
9076     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);
9077   }
9078   ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
9079   ierr = (*transposematmult)(A,B,scall,fill,C);CHKERRQ(ierr);
9080   ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
9081   PetscFunctionReturn(0);
9082 }
9083 
9084 #undef __FUNCT__
9085 #define __FUNCT__ "MatMatMatMult"
9086 /*@
9087    MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.
9088 
9089    Neighbor-wise Collective on Mat
9090 
9091    Input Parameters:
9092 +  A - the left matrix
9093 .  B - the middle matrix
9094 .  C - the right matrix
9095 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9096 -  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
9097           if the result is a dense matrix this is irrelevent
9098 
9099    Output Parameters:
9100 .  D - the product matrix
9101 
9102    Notes:
9103    Unless scall is MAT_REUSE_MATRIX D will be created.
9104 
9105    MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call
9106 
9107    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9108    actually needed.
9109 
9110    If you have many matrices with the same non-zero structure to multiply, you
9111    should either
9112 $   1) use MAT_REUSE_MATRIX in all calls but the first or
9113 $   2) call MatMatMatMultSymbolic() once and then MatMatMatMultNumeric() for each product needed
9114 
9115    Level: intermediate
9116 
9117 .seealso: MatMatMult, MatPtAP()
9118 @*/
9119 PetscErrorCode  MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
9120 {
9121   PetscErrorCode ierr;
9122   PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9123   PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9124   PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9125   PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9126 
9127   PetscFunctionBegin;
9128   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9129   PetscValidType(A,1);
9130   MatCheckPreallocated(A,1);
9131   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9132   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9133   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9134   PetscValidType(B,2);
9135   MatCheckPreallocated(B,2);
9136   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9137   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9138   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9139   PetscValidPointer(C,3);
9140   MatCheckPreallocated(C,3);
9141   if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9142   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9143   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);
9144   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);
9145   if (scall == MAT_REUSE_MATRIX) {
9146     PetscValidPointer(*D,6);
9147     PetscValidHeaderSpecific(*D,MAT_CLASSID,6);
9148     ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9149     ierr = (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
9150     ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9151     PetscFunctionReturn(0);
9152   }
9153   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9154   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
9155 
9156   fA = A->ops->matmatmult;
9157   fB = B->ops->matmatmult;
9158   fC = C->ops->matmatmult;
9159   if (fA == fB && fA == fC) {
9160     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9161     mult = fA;
9162   } else {
9163     /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */
9164     char multname[256];
9165     ierr = PetscStrcpy(multname,"MatMatMatMult_");CHKERRQ(ierr);
9166     ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr);
9167     ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);
9168     ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr);
9169     ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);
9170     ierr = PetscStrcat(multname,((PetscObject)C)->type_name);CHKERRQ(ierr);
9171     ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr);
9172     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
9173     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);
9174   }
9175   ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9176   ierr = (*mult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
9177   ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9178   PetscFunctionReturn(0);
9179 }
9180 
9181 #undef __FUNCT__
9182 #define __FUNCT__ "MatGetRedundantMatrix"
9183 /*@C
9184    MatGetRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
9185 
9186    Collective on Mat
9187 
9188    Input Parameters:
9189 +  mat - the matrix
9190 .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
9191 .  subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used)
9192 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9193 
9194    Output Parameter:
9195 .  matredundant - redundant matrix
9196 
9197    Notes:
9198    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
9199    original matrix has not changed from that last call to MatGetRedundantMatrix().
9200 
9201    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
9202    calling it.
9203 
9204    Only MPIAIJ matrix is supported.
9205 
9206    Level: advanced
9207 
9208    Concepts: subcommunicator
9209    Concepts: duplicate matrix
9210 
9211 .seealso: MatDestroy()
9212 @*/
9213 PetscErrorCode  MatGetRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant)
9214 {
9215   PetscErrorCode ierr;
9216 
9217   PetscFunctionBegin;
9218   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9219   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
9220     PetscValidPointer(*matredundant,5);
9221     PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5);
9222   }
9223   if (!mat->ops->getredundantmatrix) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
9224   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9225   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9226   MatCheckPreallocated(mat,1);
9227 
9228   ierr = PetscLogEventBegin(MAT_GetRedundantMatrix,mat,0,0,0);CHKERRQ(ierr);
9229   ierr = (*mat->ops->getredundantmatrix)(mat,nsubcomm,subcomm,reuse,matredundant);CHKERRQ(ierr);
9230   ierr = PetscLogEventEnd(MAT_GetRedundantMatrix,mat,0,0,0);CHKERRQ(ierr);
9231   PetscFunctionReturn(0);
9232 }
9233 
9234 #undef __FUNCT__
9235 #define __FUNCT__ "MatGetMultiProcBlock"
9236 /*@C
9237    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
9238    a given 'mat' object. Each submatrix can span multiple procs.
9239 
9240    Collective on Mat
9241 
9242    Input Parameters:
9243 +  mat - the matrix
9244 .  subcomm - the subcommunicator obtained by com_split(comm)
9245 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9246 
9247    Output Parameter:
9248 .  subMat - 'parallel submatrices each spans a given subcomm
9249 
9250   Notes:
9251   The submatrix partition across processors is dictated by 'subComm' a
9252   communicator obtained by com_split(comm). The comm_split
9253   is not restriced to be grouped with consecutive original ranks.
9254 
9255   Due the comm_split() usage, the parallel layout of the submatrices
9256   map directly to the layout of the original matrix [wrt the local
9257   row,col partitioning]. So the original 'DiagonalMat' naturally maps
9258   into the 'DiagonalMat' of the subMat, hence it is used directly from
9259   the subMat. However the offDiagMat looses some columns - and this is
9260   reconstructed with MatSetValues()
9261 
9262   Level: advanced
9263 
9264   Concepts: subcommunicator
9265   Concepts: submatrices
9266 
9267 .seealso: MatGetSubMatrices()
9268 @*/
9269 PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
9270 {
9271   PetscErrorCode ierr;
9272   PetscMPIInt    commsize,subCommSize;
9273 
9274   PetscFunctionBegin;
9275   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRQ(ierr);
9276   ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr);
9277   if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
9278 
9279   ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
9280   ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr);
9281   ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
9282   PetscFunctionReturn(0);
9283 }
9284 
9285 #undef __FUNCT__
9286 #define __FUNCT__ "MatGetLocalSubMatrix"
9287 /*@
9288    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
9289 
9290    Not Collective
9291 
9292    Input Arguments:
9293    mat - matrix to extract local submatrix from
9294    isrow - local row indices for submatrix
9295    iscol - local column indices for submatrix
9296 
9297    Output Arguments:
9298    submat - the submatrix
9299 
9300    Level: intermediate
9301 
9302    Notes:
9303    The submat should be returned with MatRestoreLocalSubMatrix().
9304 
9305    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
9306    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
9307 
9308    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
9309    MatSetValuesBlockedLocal() will also be implemented.
9310 
9311 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef()
9312 @*/
9313 PetscErrorCode  MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9314 {
9315   PetscErrorCode ierr;
9316 
9317   PetscFunctionBegin;
9318   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9319   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
9320   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
9321   PetscCheckSameComm(isrow,2,iscol,3);
9322   PetscValidPointer(submat,4);
9323 
9324   if (mat->ops->getlocalsubmatrix) {
9325     ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
9326   } else {
9327     ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr);
9328   }
9329   PetscFunctionReturn(0);
9330 }
9331 
9332 #undef __FUNCT__
9333 #define __FUNCT__ "MatRestoreLocalSubMatrix"
9334 /*@
9335    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
9336 
9337    Not Collective
9338 
9339    Input Arguments:
9340    mat - matrix to extract local submatrix from
9341    isrow - local row indices for submatrix
9342    iscol - local column indices for submatrix
9343    submat - the submatrix
9344 
9345    Level: intermediate
9346 
9347 .seealso: MatGetLocalSubMatrix()
9348 @*/
9349 PetscErrorCode  MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9350 {
9351   PetscErrorCode ierr;
9352 
9353   PetscFunctionBegin;
9354   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9355   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
9356   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
9357   PetscCheckSameComm(isrow,2,iscol,3);
9358   PetscValidPointer(submat,4);
9359   if (*submat) {
9360     PetscValidHeaderSpecific(*submat,MAT_CLASSID,4);
9361   }
9362 
9363   if (mat->ops->restorelocalsubmatrix) {
9364     ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
9365   } else {
9366     ierr = MatDestroy(submat);CHKERRQ(ierr);
9367   }
9368   *submat = NULL;
9369   PetscFunctionReturn(0);
9370 }
9371 
9372 /* --------------------------------------------------------*/
9373 #undef __FUNCT__
9374 #define __FUNCT__ "MatFindZeroDiagonals"
9375 /*@
9376    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no entry in the matrix
9377 
9378    Collective on Mat
9379 
9380    Input Parameter:
9381 .  mat - the matrix
9382 
9383    Output Parameter:
9384 .  is - if any rows have zero diagonals this contains the list of them
9385 
9386    Level: developer
9387 
9388    Concepts: matrix-vector product
9389 
9390 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
9391 @*/
9392 PetscErrorCode  MatFindZeroDiagonals(Mat mat,IS *is)
9393 {
9394   PetscErrorCode ierr;
9395 
9396   PetscFunctionBegin;
9397   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9398   PetscValidType(mat,1);
9399   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9400   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9401 
9402   if (!mat->ops->findzerodiagonals) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find zero diagonals defined");
9403   ierr = (*mat->ops->findzerodiagonals)(mat,is);CHKERRQ(ierr);
9404   PetscFunctionReturn(0);
9405 }
9406 
9407 #undef __FUNCT__
9408 #define __FUNCT__ "MatInvertBlockDiagonal"
9409 /*@C
9410   MatInvertBlockDiagonal - Inverts the block diagonal entries.
9411 
9412   Collective on Mat
9413 
9414   Input Parameters:
9415 . mat - the matrix
9416 
9417   Output Parameters:
9418 . values - the block inverses in column major order (FORTRAN-like)
9419 
9420    Note:
9421    This routine is not available from Fortran.
9422 
9423   Level: advanced
9424 @*/
9425 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
9426 {
9427   PetscErrorCode ierr;
9428 
9429   PetscFunctionBegin;
9430   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9431   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9432   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9433   if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
9434   ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr);
9435   PetscFunctionReturn(0);
9436 }
9437 
9438 #undef __FUNCT__
9439 #define __FUNCT__ "MatTransposeColoringDestroy"
9440 /*@C
9441     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
9442     via MatTransposeColoringCreate().
9443 
9444     Collective on MatTransposeColoring
9445 
9446     Input Parameter:
9447 .   c - coloring context
9448 
9449     Level: intermediate
9450 
9451 .seealso: MatTransposeColoringCreate()
9452 @*/
9453 PetscErrorCode  MatTransposeColoringDestroy(MatTransposeColoring *c)
9454 {
9455   PetscErrorCode       ierr;
9456   MatTransposeColoring matcolor=*c;
9457 
9458   PetscFunctionBegin;
9459   if (!matcolor) PetscFunctionReturn(0);
9460   if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; PetscFunctionReturn(0);}
9461 
9462   ierr = PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);CHKERRQ(ierr);
9463   ierr = PetscFree(matcolor->rows);CHKERRQ(ierr);
9464   ierr = PetscFree(matcolor->den2sp);CHKERRQ(ierr);
9465   ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr);
9466   ierr = PetscFree(matcolor->columns);CHKERRQ(ierr);
9467   if (matcolor->brows>0) {
9468     ierr = PetscFree(matcolor->lstart);CHKERRQ(ierr);
9469   }
9470   ierr = PetscHeaderDestroy(c);CHKERRQ(ierr);
9471   PetscFunctionReturn(0);
9472 }
9473 
9474 #undef __FUNCT__
9475 #define __FUNCT__ "MatTransColoringApplySpToDen"
9476 /*@C
9477     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
9478     a MatTransposeColoring context has been created, computes a dense B^T by Apply
9479     MatTransposeColoring to sparse B.
9480 
9481     Collective on MatTransposeColoring
9482 
9483     Input Parameters:
9484 +   B - sparse matrix B
9485 .   Btdense - symbolic dense matrix B^T
9486 -   coloring - coloring context created with MatTransposeColoringCreate()
9487 
9488     Output Parameter:
9489 .   Btdense - dense matrix B^T
9490 
9491     Options Database Keys:
9492 +    -mat_transpose_coloring_view - Activates basic viewing or coloring
9493 .    -mat_transpose_coloring_view_draw - Activates drawing of coloring
9494 -    -mat_transpose_coloring_view_info - Activates viewing of coloring info
9495 
9496     Level: intermediate
9497 
9498 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy()
9499 
9500 .keywords: coloring
9501 @*/
9502 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
9503 {
9504   PetscErrorCode ierr;
9505 
9506   PetscFunctionBegin;
9507   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
9508   PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2);
9509   PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3);
9510 
9511   if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
9512   ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr);
9513   PetscFunctionReturn(0);
9514 }
9515 
9516 #undef __FUNCT__
9517 #define __FUNCT__ "MatTransColoringApplyDenToSp"
9518 /*@C
9519     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
9520     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
9521     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
9522     Csp from Cden.
9523 
9524     Collective on MatTransposeColoring
9525 
9526     Input Parameters:
9527 +   coloring - coloring context created with MatTransposeColoringCreate()
9528 -   Cden - matrix product of a sparse matrix and a dense matrix Btdense
9529 
9530     Output Parameter:
9531 .   Csp - sparse matrix
9532 
9533     Options Database Keys:
9534 +    -mat_multtranspose_coloring_view - Activates basic viewing or coloring
9535 .    -mat_multtranspose_coloring_view_draw - Activates drawing of coloring
9536 -    -mat_multtranspose_coloring_view_info - Activates viewing of coloring info
9537 
9538     Level: intermediate
9539 
9540 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()
9541 
9542 .keywords: coloring
9543 @*/
9544 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
9545 {
9546   PetscErrorCode ierr;
9547 
9548   PetscFunctionBegin;
9549   PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1);
9550   PetscValidHeaderSpecific(Cden,MAT_CLASSID,2);
9551   PetscValidHeaderSpecific(Csp,MAT_CLASSID,3);
9552 
9553   if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
9554   ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr);
9555   PetscFunctionReturn(0);
9556 }
9557 
9558 #undef __FUNCT__
9559 #define __FUNCT__ "MatTransposeColoringCreate"
9560 /*@C
9561    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.
9562 
9563    Collective on Mat
9564 
9565    Input Parameters:
9566 +  mat - the matrix product C
9567 -  iscoloring - the coloring of the matrix; usually obtained with MatGetColoring() or DMCreateColoring()
9568 
9569     Output Parameter:
9570 .   color - the new coloring context
9571 
9572     Level: intermediate
9573 
9574 .seealso: MatTransposeColoringDestroy(), MatTransposeColoringSetFromOptions(), MatTransColoringApplySpToDen(),
9575            MatTransColoringApplyDenToSp(), MatTransposeColoringView(),
9576 @*/
9577 PetscErrorCode  MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
9578 {
9579   MatTransposeColoring c;
9580   MPI_Comm             comm;
9581   PetscErrorCode       ierr;
9582 
9583   PetscFunctionBegin;
9584   ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
9585   ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
9586   ierr = PetscHeaderCreate(c,_p_MatTransposeColoring,int,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,0);CHKERRQ(ierr);
9587 
9588   c->ctype = iscoloring->ctype;
9589   if (mat->ops->transposecoloringcreate) {
9590     ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr);
9591   } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type");
9592 
9593   *color = c;
9594   ierr   = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
9595   PetscFunctionReturn(0);
9596 }
9597