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