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