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