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