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