xref: /petsc/src/mat/interface/matrix.c (revision 04d7464b71f14a73adf7cb3f664404cc6936f6d1)
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    ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the
4735    same flag of MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY for all processes. Thus you CANNOT locally change from ADD_VALUES to INSERT_VALUES, that is
4736    a global collective operation requring all processes that share the matrix.
4737 
4738    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
4739    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
4740    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
4741 
4742    Level: beginner
4743 
4744    Concepts: matrices^assembling
4745 
4746 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
4747 @*/
4748 PetscErrorCode  MatAssemblyBegin(Mat mat,MatAssemblyType type)
4749 {
4750   PetscErrorCode ierr;
4751 
4752   PetscFunctionBegin;
4753   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4754   PetscValidType(mat,1);
4755   MatCheckPreallocated(mat,1);
4756   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
4757   if (mat->assembled) {
4758     mat->was_assembled = PETSC_TRUE;
4759     mat->assembled     = PETSC_FALSE;
4760   }
4761   if (!MatAssemblyEnd_InUse) {
4762     ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
4763     if (mat->ops->assemblybegin) {ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
4764     ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
4765   } else {
4766     if (mat->ops->assemblybegin) {ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
4767   }
4768   PetscFunctionReturn(0);
4769 }
4770 
4771 #undef __FUNCT__
4772 #define __FUNCT__ "MatAssembled"
4773 /*@
4774    MatAssembled - Indicates if a matrix has been assembled and is ready for
4775      use; for example, in matrix-vector product.
4776 
4777    Not Collective
4778 
4779    Input Parameter:
4780 .  mat - the matrix
4781 
4782    Output Parameter:
4783 .  assembled - PETSC_TRUE or PETSC_FALSE
4784 
4785    Level: advanced
4786 
4787    Concepts: matrices^assembled?
4788 
4789 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
4790 @*/
4791 PetscErrorCode  MatAssembled(Mat mat,PetscBool  *assembled)
4792 {
4793   PetscFunctionBegin;
4794   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4795   PetscValidType(mat,1);
4796   PetscValidPointer(assembled,2);
4797   *assembled = mat->assembled;
4798   PetscFunctionReturn(0);
4799 }
4800 
4801 #undef __FUNCT__
4802 #define __FUNCT__ "MatView_Private"
4803 /*
4804     Processes command line options to determine if/how a matrix
4805   is to be viewed. Called by MatAssemblyEnd() and MatLoad().
4806 */
4807 PetscErrorCode MatView_Private(Mat mat)
4808 {
4809   PetscErrorCode   ierr;
4810   PetscBool        flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE,flg4 = PETSC_FALSE,flg6 = PETSC_FALSE,flg7 = PETSC_FALSE,flg8 = PETSC_FALSE;
4811   static PetscBool incall = PETSC_FALSE;
4812 #if defined(PETSC_USE_SOCKET_VIEWER)
4813   PetscBool        flg5 = PETSC_FALSE;
4814 #endif
4815 
4816   PetscFunctionBegin;
4817   if (incall) PetscFunctionReturn(0);
4818   incall = PETSC_TRUE;
4819   ierr = PetscObjectOptionsBegin((PetscObject)mat);CHKERRQ(ierr);
4820     ierr = PetscOptionsBool("-mat_view_info","Information on matrix size","MatView",flg1,&flg1,PETSC_NULL);CHKERRQ(ierr);
4821     ierr = PetscOptionsBool("-mat_view_info_detailed","Nonzeros in the matrix","MatView",flg2,&flg2,PETSC_NULL);CHKERRQ(ierr);
4822     ierr = PetscOptionsBool("-mat_view","Print matrix to stdout","MatView",flg3,&flg3,PETSC_NULL);CHKERRQ(ierr);
4823     ierr = PetscOptionsBool("-mat_view_matlab","Print matrix to stdout in a format Matlab can read","MatView",flg4,&flg4,PETSC_NULL);CHKERRQ(ierr);
4824 #if defined(PETSC_USE_SOCKET_VIEWER)
4825     ierr = PetscOptionsBool("-mat_view_socket","Send matrix to socket (can be read from matlab)","MatView",flg5,&flg5,PETSC_NULL);CHKERRQ(ierr);
4826 #endif
4827     ierr = PetscOptionsBool("-mat_view_binary","Save matrix to file in binary format","MatView",flg6,&flg6,PETSC_NULL);CHKERRQ(ierr);
4828     ierr = PetscOptionsBool("-mat_view_draw","Draw the matrix nonzero structure","MatView",flg7,&flg7,PETSC_NULL);CHKERRQ(ierr);
4829   ierr = PetscOptionsEnd();CHKERRQ(ierr);
4830 
4831   if (flg1) {
4832     PetscViewer viewer;
4833 
4834     ierr = PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);CHKERRQ(ierr);
4835     ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO);CHKERRQ(ierr);
4836     ierr = MatView(mat,viewer);CHKERRQ(ierr);
4837     ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
4838   }
4839   if (flg2) {
4840     PetscViewer viewer;
4841 
4842     ierr = PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);CHKERRQ(ierr);
4843     ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO_DETAIL);CHKERRQ(ierr);
4844     ierr = MatView(mat,viewer);CHKERRQ(ierr);
4845     ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
4846   }
4847   if (flg3) {
4848     PetscViewer viewer;
4849 
4850     ierr = PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);CHKERRQ(ierr);
4851     ierr = MatView(mat,viewer);CHKERRQ(ierr);
4852   }
4853   if (flg4) {
4854     PetscViewer viewer;
4855 
4856     ierr = PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);CHKERRQ(ierr);
4857     ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr);
4858     ierr = MatView(mat,viewer);CHKERRQ(ierr);
4859     ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
4860   }
4861 #if defined(PETSC_USE_SOCKET_VIEWER)
4862   if (flg5) {
4863     ierr = MatView(mat,PETSC_VIEWER_SOCKET_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4864     ierr = PetscViewerFlush(PETSC_VIEWER_SOCKET_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4865   }
4866 #endif
4867   if (flg6) {
4868     ierr = MatView(mat,PETSC_VIEWER_BINARY_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4869     ierr = PetscViewerFlush(PETSC_VIEWER_BINARY_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4870   }
4871   if (flg7) {
4872     ierr = PetscOptionsGetBool(((PetscObject)mat)->prefix,"-mat_view_contour",&flg8,PETSC_NULL);CHKERRQ(ierr);
4873     if (flg8) {
4874       PetscViewerPushFormat(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm),PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
4875     }
4876     ierr = MatView(mat,PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4877     ierr = PetscViewerFlush(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4878     if (flg8) {
4879       PetscViewerPopFormat(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4880     }
4881   }
4882   incall = PETSC_FALSE;
4883   PetscFunctionReturn(0);
4884 }
4885 
4886 #undef __FUNCT__
4887 #define __FUNCT__ "MatAssemblyEnd"
4888 /*@
4889    MatAssemblyEnd - Completes assembling the matrix.  This routine should
4890    be called after MatAssemblyBegin().
4891 
4892    Collective on Mat
4893 
4894    Input Parameters:
4895 +  mat - the matrix
4896 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
4897 
4898    Options Database Keys:
4899 +  -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly()
4900 .  -mat_view_info_detailed - Prints more detailed info
4901 .  -mat_view - Prints matrix in ASCII format
4902 .  -mat_view_matlab - Prints matrix in Matlab format
4903 .  -mat_view_draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
4904 .  -display <name> - Sets display name (default is host)
4905 .  -draw_pause <sec> - Sets number of seconds to pause after display
4906 .  -mat_view_socket - Sends matrix to socket, can be accessed from Matlab (See the <a href="../../docs/manual.pdf">users manual</a>)
4907 .  -viewer_socket_machine <machine>
4908 .  -viewer_socket_port <port>
4909 .  -mat_view_binary - save matrix to file in binary format
4910 -  -viewer_binary_filename <name>
4911 
4912    Notes:
4913    MatSetValues() generally caches the values.  The matrix is ready to
4914    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4915    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4916    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4917    using the matrix.
4918 
4919    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
4920    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
4921    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
4922 
4923    Level: beginner
4924 
4925 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
4926 @*/
4927 PetscErrorCode  MatAssemblyEnd(Mat mat,MatAssemblyType type)
4928 {
4929   PetscErrorCode  ierr;
4930   static PetscInt inassm = 0;
4931   PetscBool       flg = PETSC_FALSE;
4932 
4933   PetscFunctionBegin;
4934   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4935   PetscValidType(mat,1);
4936 
4937   inassm++;
4938   MatAssemblyEnd_InUse++;
4939   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
4940     ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
4941     if (mat->ops->assemblyend) {
4942       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
4943     }
4944     ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
4945   } else {
4946     if (mat->ops->assemblyend) {
4947       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
4948     }
4949   }
4950 
4951   /* Flush assembly is not a true assembly */
4952   if (type != MAT_FLUSH_ASSEMBLY) {
4953     mat->assembled  = PETSC_TRUE; mat->num_ass++;
4954   }
4955   mat->insertmode = NOT_SET_VALUES;
4956   MatAssemblyEnd_InUse--;
4957   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4958   if (!mat->symmetric_eternal) {
4959     mat->symmetric_set              = PETSC_FALSE;
4960     mat->hermitian_set              = PETSC_FALSE;
4961     mat->structurally_symmetric_set = PETSC_FALSE;
4962   }
4963 #if defined(PETSC_HAVE_CUSP)
4964   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4965     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4966   }
4967 #endif
4968   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
4969     ierr = MatView_Private(mat);CHKERRQ(ierr);
4970     ierr = PetscOptionsHasName(((PetscObject)mat)->prefix,"-mat_is_symmetric",&flg);CHKERRQ(ierr);
4971     if (flg) {
4972       PetscReal tol = 0.0;
4973       ierr = PetscOptionsGetReal(((PetscObject)mat)->prefix,"-mat_is_symmetric",&tol,PETSC_NULL);CHKERRQ(ierr);
4974       ierr = MatIsSymmetric(mat,tol,&flg);CHKERRQ(ierr);
4975       if (flg) {
4976         ierr = PetscPrintf(((PetscObject)mat)->comm,"Matrix is symmetric (tolerance %G)\n",tol);CHKERRQ(ierr);
4977       } else {
4978         ierr = PetscPrintf(((PetscObject)mat)->comm,"Matrix is not symmetric (tolerance %G)\n",tol);CHKERRQ(ierr);
4979       }
4980     }
4981     if (mat->nullsp) {
4982       ierr = PetscOptionsGetBool(PETSC_NULL,"-mat_null_space_test",&flg,PETSC_NULL);CHKERRQ(ierr);
4983       if (flg) {
4984         ierr = MatNullSpaceTest(mat->nullsp,mat,PETSC_NULL);CHKERRQ(ierr);
4985       }
4986     }
4987   }
4988   inassm--;
4989   PetscFunctionReturn(0);
4990 }
4991 
4992 #undef __FUNCT__
4993 #define __FUNCT__ "MatSetOption"
4994 /*@
4995    MatSetOption - Sets a parameter option for a matrix. Some options
4996    may be specific to certain storage formats.  Some options
4997    determine how values will be inserted (or added). Sorted,
4998    row-oriented input will generally assemble the fastest. The default
4999    is row-oriented.
5000 
5001    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5002 
5003    Input Parameters:
5004 +  mat - the matrix
5005 .  option - the option, one of those listed below (and possibly others),
5006 -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5007 
5008   Options Describing Matrix Structure:
5009 +    MAT_SPD - symmetric positive definite
5010 -    MAT_SYMMETRIC - symmetric in terms of both structure and value
5011 .    MAT_HERMITIAN - transpose is the complex conjugation
5012 .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5013 -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5014                             you set to be kept with all future use of the matrix
5015                             including after MatAssemblyBegin/End() which could
5016                             potentially change the symmetry structure, i.e. you
5017                             KNOW the matrix will ALWAYS have the property you set.
5018 
5019 
5020    Options For Use with MatSetValues():
5021    Insert a logically dense subblock, which can be
5022 .    MAT_ROW_ORIENTED - row-oriented (default)
5023 
5024    Note these options reflect the data you pass in with MatSetValues(); it has
5025    nothing to do with how the data is stored internally in the matrix
5026    data structure.
5027 
5028    When (re)assembling a matrix, we can restrict the input for
5029    efficiency/debugging purposes.  These options include
5030 +    MAT_NEW_NONZERO_LOCATIONS - additional insertions will be
5031         allowed if they generate a new nonzero
5032 .    MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
5033 .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
5034 .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
5035 .    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
5036 +    MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
5037         any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
5038         performance for very large process counts.
5039 
5040    Notes:
5041    Some options are relevant only for particular matrix types and
5042    are thus ignored by others.  Other options are not supported by
5043    certain matrix types and will generate an error message if set.
5044 
5045    If using a Fortran 77 module to compute a matrix, one may need to
5046    use the column-oriented option (or convert to the row-oriented
5047    format).
5048 
5049    MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
5050    that would generate a new entry in the nonzero structure is instead
5051    ignored.  Thus, if memory has not alredy been allocated for this particular
5052    data, then the insertion is ignored. For dense matrices, in which
5053    the entire array is allocated, no entries are ever ignored.
5054    Set after the first MatAssemblyEnd()
5055 
5056    MAT_NEW_NONZERO_LOCATION_ERR indicates that any add or insertion
5057    that would generate a new entry in the nonzero structure instead produces
5058    an error. (Currently supported for AIJ and BAIJ formats only.)
5059    This is a useful flag when using SAME_NONZERO_PATTERN in calling
5060    KSPSetOperators() to ensure that the nonzero pattern truely does
5061    remain unchanged. Set after the first MatAssemblyEnd()
5062 
5063    MAT_NEW_NONZERO_ALLOCATION_ERR indicates that any add or insertion
5064    that would generate a new entry that has not been preallocated will
5065    instead produce an error. (Currently supported for AIJ and BAIJ formats
5066    only.) This is a useful flag when debugging matrix memory preallocation.
5067 
5068    MAT_IGNORE_OFF_PROC_ENTRIES indicates entries destined for
5069    other processors should be dropped, rather than stashed.
5070    This is useful if you know that the "owning" processor is also
5071    always generating the correct matrix entries, so that PETSc need
5072    not transfer duplicate entries generated on another processor.
5073 
5074    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5075    searches during matrix assembly. When this flag is set, the hash table
5076    is created during the first Matrix Assembly. This hash table is
5077    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5078    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5079    should be used with MAT_USE_HASH_TABLE flag. This option is currently
5080    supported by MATMPIBAIJ format only.
5081 
5082    MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries
5083    are kept in the nonzero structure
5084 
5085    MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
5086    a zero location in the matrix
5087 
5088    MAT_USE_INODES - indicates using inode version of the code - works with AIJ and
5089    ROWBS matrix types
5090 
5091    MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the
5092         zero row routines and thus improves performance for very large process counts.
5093 
5094    MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular
5095         part of the matrix (since they should match the upper triangular part).
5096 
5097    Notes: Can only be called after MatSetSizes() and MatSetType() have been set.
5098 
5099    Level: intermediate
5100 
5101    Concepts: matrices^setting options
5102 
5103 .seealso:  MatOption, Mat
5104 
5105 @*/
5106 PetscErrorCode  MatSetOption(Mat mat,MatOption op,PetscBool  flg)
5107 {
5108   PetscErrorCode ierr;
5109 
5110   PetscFunctionBegin;
5111   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5112   PetscValidType(mat,1);
5113   if (op > 0) PetscValidLogicalCollectiveEnum(mat,op,2);
5114   PetscValidLogicalCollectiveBool(mat,flg,3);
5115 
5116   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);
5117   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()");
5118 
5119   switch (op) {
5120   case MAT_NO_OFF_PROC_ENTRIES:
5121     mat->nooffprocentries                = flg;
5122     PetscFunctionReturn(0);
5123     break;
5124   case MAT_NO_OFF_PROC_ZERO_ROWS:
5125     mat->nooffproczerorows               = flg;
5126     PetscFunctionReturn(0);
5127     break;
5128   case MAT_SPD:
5129     mat->spd_set                         = PETSC_TRUE;
5130     mat->spd                             = flg;
5131     if (flg) {
5132       mat->symmetric                     = PETSC_TRUE;
5133       mat->structurally_symmetric        = PETSC_TRUE;
5134       mat->symmetric_set                 = PETSC_TRUE;
5135       mat->structurally_symmetric_set    = PETSC_TRUE;
5136     }
5137     break;
5138   case MAT_SYMMETRIC:
5139     mat->symmetric                       = flg;
5140     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5141     mat->symmetric_set                   = PETSC_TRUE;
5142     mat->structurally_symmetric_set      = flg;
5143     break;
5144   case MAT_HERMITIAN:
5145     mat->hermitian                       = flg;
5146     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5147     mat->hermitian_set                   = PETSC_TRUE;
5148     mat->structurally_symmetric_set      = flg;
5149     break;
5150   case MAT_STRUCTURALLY_SYMMETRIC:
5151     mat->structurally_symmetric          = flg;
5152     mat->structurally_symmetric_set      = PETSC_TRUE;
5153     break;
5154   case MAT_SYMMETRY_ETERNAL:
5155     mat->symmetric_eternal               = flg;
5156     break;
5157   default:
5158     break;
5159   }
5160   if (mat->ops->setoption) {
5161     ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr);
5162   }
5163   PetscFunctionReturn(0);
5164 }
5165 
5166 #undef __FUNCT__
5167 #define __FUNCT__ "MatZeroEntries"
5168 /*@
5169    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5170    this routine retains the old nonzero structure.
5171 
5172    Logically Collective on Mat
5173 
5174    Input Parameters:
5175 .  mat - the matrix
5176 
5177    Level: intermediate
5178 
5179    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.
5180    See the Performance chapter of the users manual for information on preallocating matrices.
5181 
5182    Concepts: matrices^zeroing
5183 
5184 .seealso: MatZeroRows()
5185 @*/
5186 PetscErrorCode  MatZeroEntries(Mat mat)
5187 {
5188   PetscErrorCode ierr;
5189 
5190   PetscFunctionBegin;
5191   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5192   PetscValidType(mat,1);
5193   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5194   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");
5195   if (!mat->ops->zeroentries) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5196   MatCheckPreallocated(mat,1);
5197 
5198   ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5199   ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
5200   ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5201   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5202 #if defined(PETSC_HAVE_CUSP)
5203   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5204     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5205   }
5206 #endif
5207   PetscFunctionReturn(0);
5208 }
5209 
5210 #undef __FUNCT__
5211 #define __FUNCT__ "MatZeroRowsColumns"
5212 /*@C
5213    MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal)
5214    of a set of rows and columns of a matrix.
5215 
5216    Collective on Mat
5217 
5218    Input Parameters:
5219 +  mat - the matrix
5220 .  numRows - the number of rows to remove
5221 .  rows - the global row indices
5222 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5223 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5224 -  b - optional vector of right hand side, that will be adjusted by provided solution
5225 
5226    Notes:
5227    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5228 
5229    The user can set a value in the diagonal entry (or for the AIJ and
5230    row formats can optionally remove the main diagonal entry from the
5231    nonzero structure as well, by passing 0.0 as the final argument).
5232 
5233    For the parallel case, all processes that share the matrix (i.e.,
5234    those in the communicator used for matrix creation) MUST call this
5235    routine, regardless of whether any rows being zeroed are owned by
5236    them.
5237 
5238    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5239    list only rows local to itself).
5240 
5241    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5242 
5243    Level: intermediate
5244 
5245    Concepts: matrices^zeroing rows
5246 
5247 .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumnsIS()
5248 @*/
5249 PetscErrorCode  MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5250 {
5251   PetscErrorCode ierr;
5252 
5253   PetscFunctionBegin;
5254   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5255   PetscValidType(mat,1);
5256   if (numRows) PetscValidIntPointer(rows,3);
5257   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5258   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5259   if (!mat->ops->zerorowscolumns) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5260   MatCheckPreallocated(mat,1);
5261 
5262   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5263   ierr = MatView_Private(mat);CHKERRQ(ierr);
5264   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5265 #if defined(PETSC_HAVE_CUSP)
5266   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5267     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5268   }
5269 #endif
5270   PetscFunctionReturn(0);
5271 }
5272 
5273 #undef __FUNCT__
5274 #define __FUNCT__ "MatZeroRowsColumnsIS"
5275 /*@C
5276    MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
5277    of a set of rows and columns of a matrix.
5278 
5279    Collective on Mat
5280 
5281    Input Parameters:
5282 +  mat - the matrix
5283 .  is - the rows to zero
5284 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5285 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5286 -  b - optional vector of right hand side, that will be adjusted by provided solution
5287 
5288    Notes:
5289    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5290 
5291    The user can set a value in the diagonal entry (or for the AIJ and
5292    row formats can optionally remove the main diagonal entry from the
5293    nonzero structure as well, by passing 0.0 as the final argument).
5294 
5295    For the parallel case, all processes that share the matrix (i.e.,
5296    those in the communicator used for matrix creation) MUST call this
5297    routine, regardless of whether any rows being zeroed are owned by
5298    them.
5299 
5300    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5301    list only rows local to itself).
5302 
5303    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5304 
5305    Level: intermediate
5306 
5307    Concepts: matrices^zeroing rows
5308 
5309 .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumns()
5310 @*/
5311 PetscErrorCode  MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5312 {
5313   PetscErrorCode ierr;
5314   PetscInt       numRows;
5315   const PetscInt *rows;
5316 
5317   PetscFunctionBegin;
5318   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5319   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5320   PetscValidType(mat,1);
5321   PetscValidType(is,2);
5322   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5323   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5324   ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5325   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5326   PetscFunctionReturn(0);
5327 }
5328 
5329 #undef __FUNCT__
5330 #define __FUNCT__ "MatZeroRows"
5331 /*@C
5332    MatZeroRows - Zeros all entries (except possibly the main diagonal)
5333    of a set of rows of a matrix.
5334 
5335    Collective on Mat
5336 
5337    Input Parameters:
5338 +  mat - the matrix
5339 .  numRows - the number of rows to remove
5340 .  rows - the global row indices
5341 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5342 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5343 -  b - optional vector of right hand side, that will be adjusted by provided solution
5344 
5345    Notes:
5346    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5347    but does not release memory.  For the dense and block diagonal
5348    formats this does not alter the nonzero structure.
5349 
5350    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5351    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5352    merely zeroed.
5353 
5354    The user can set a value in the diagonal entry (or for the AIJ and
5355    row formats can optionally remove the main diagonal entry from the
5356    nonzero structure as well, by passing 0.0 as the final argument).
5357 
5358    For the parallel case, all processes that share the matrix (i.e.,
5359    those in the communicator used for matrix creation) MUST call this
5360    routine, regardless of whether any rows being zeroed are owned by
5361    them.
5362 
5363    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5364    list only rows local to itself).
5365 
5366    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5367    owns that are to be zeroed. This saves a global synchronization in the implementation.
5368 
5369    Level: intermediate
5370 
5371    Concepts: matrices^zeroing rows
5372 
5373 .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5374 @*/
5375 PetscErrorCode  MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5376 {
5377   PetscErrorCode ierr;
5378 
5379   PetscFunctionBegin;
5380   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5381   PetscValidType(mat,1);
5382   if (numRows) PetscValidIntPointer(rows,3);
5383   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5384   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5385   if (!mat->ops->zerorows) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5386   MatCheckPreallocated(mat,1);
5387 
5388   ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5389   ierr = MatView_Private(mat);CHKERRQ(ierr);
5390   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5391 #if defined(PETSC_HAVE_CUSP)
5392   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5393     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5394   }
5395 #endif
5396   PetscFunctionReturn(0);
5397 }
5398 
5399 #undef __FUNCT__
5400 #define __FUNCT__ "MatZeroRowsIS"
5401 /*@C
5402    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5403    of a set of rows of a matrix.
5404 
5405    Collective on Mat
5406 
5407    Input Parameters:
5408 +  mat - the matrix
5409 .  is - index set of rows to remove
5410 .  diag - value put in all diagonals of eliminated rows
5411 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5412 -  b - optional vector of right hand side, that will be adjusted by provided solution
5413 
5414    Notes:
5415    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5416    but does not release memory.  For the dense and block diagonal
5417    formats this does not alter the nonzero structure.
5418 
5419    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5420    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5421    merely zeroed.
5422 
5423    The user can set a value in the diagonal entry (or for the AIJ and
5424    row formats can optionally remove the main diagonal entry from the
5425    nonzero structure as well, by passing 0.0 as the final argument).
5426 
5427    For the parallel case, all processes that share the matrix (i.e.,
5428    those in the communicator used for matrix creation) MUST call this
5429    routine, regardless of whether any rows being zeroed are owned by
5430    them.
5431 
5432    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5433    list only rows local to itself).
5434 
5435    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5436    owns that are to be zeroed. This saves a global synchronization in the implementation.
5437 
5438    Level: intermediate
5439 
5440    Concepts: matrices^zeroing rows
5441 
5442 .seealso: MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5443 @*/
5444 PetscErrorCode  MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5445 {
5446   PetscInt       numRows;
5447   const PetscInt *rows;
5448   PetscErrorCode ierr;
5449 
5450   PetscFunctionBegin;
5451   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5452   PetscValidType(mat,1);
5453   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5454   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5455   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5456   ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5457   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5458   PetscFunctionReturn(0);
5459 }
5460 
5461 #undef __FUNCT__
5462 #define __FUNCT__ "MatZeroRowsStencil"
5463 /*@C
5464    MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
5465    of a set of rows of a matrix. These rows must be local to the process.
5466 
5467    Collective on Mat
5468 
5469    Input Parameters:
5470 +  mat - the matrix
5471 .  numRows - the number of rows to remove
5472 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
5473 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5474 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5475 -  b - optional vector of right hand side, that will be adjusted by provided solution
5476 
5477    Notes:
5478    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5479    but does not release memory.  For the dense and block diagonal
5480    formats this does not alter the nonzero structure.
5481 
5482    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5483    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5484    merely zeroed.
5485 
5486    The user can set a value in the diagonal entry (or for the AIJ and
5487    row formats can optionally remove the main diagonal entry from the
5488    nonzero structure as well, by passing 0.0 as the final argument).
5489 
5490    For the parallel case, all processes that share the matrix (i.e.,
5491    those in the communicator used for matrix creation) MUST call this
5492    routine, regardless of whether any rows being zeroed are owned by
5493    them.
5494 
5495    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5496    list only rows local to itself).
5497 
5498    The grid coordinates are across the entire grid, not just the local portion
5499 
5500    In Fortran idxm and idxn should be declared as
5501 $     MatStencil idxm(4,m)
5502    and the values inserted using
5503 $    idxm(MatStencil_i,1) = i
5504 $    idxm(MatStencil_j,1) = j
5505 $    idxm(MatStencil_k,1) = k
5506 $    idxm(MatStencil_c,1) = c
5507    etc
5508 
5509    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5510    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5511    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5512    DMDA_BOUNDARY_PERIODIC boundary type.
5513 
5514    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
5515    a single value per point) you can skip filling those indices.
5516 
5517    Level: intermediate
5518 
5519    Concepts: matrices^zeroing rows
5520 
5521 .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5522 @*/
5523 PetscErrorCode  MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5524 {
5525   PetscInt        dim    = mat->stencil.dim;
5526   PetscInt        sdim   = dim - (1 - (PetscInt) mat->stencil.noc);
5527   PetscInt       *dims   = mat->stencil.dims+1;
5528   PetscInt       *starts = mat->stencil.starts;
5529   PetscInt       *dxm    = (PetscInt *) rows;
5530   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
5531   PetscErrorCode ierr;
5532 
5533   PetscFunctionBegin;
5534   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5535   PetscValidType(mat,1);
5536   if (numRows) PetscValidIntPointer(rows,3);
5537 
5538   ierr = PetscMalloc(numRows*sizeof(PetscInt), &jdxm);CHKERRQ(ierr);
5539   for (i = 0; i < numRows; ++i) {
5540     /* Skip unused dimensions (they are ordered k, j, i, c) */
5541     for (j = 0; j < 3-sdim; ++j) dxm++;
5542     /* Local index in X dir */
5543     tmp = *dxm++ - starts[0];
5544     /* Loop over remaining dimensions */
5545     for (j = 0; j < dim-1; ++j) {
5546       /* If nonlocal, set index to be negative */
5547       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5548       /* Update local index */
5549       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5550     }
5551     /* Skip component slot if necessary */
5552     if (mat->stencil.noc) dxm++;
5553     /* Local row number */
5554     if (tmp >= 0) {
5555       jdxm[numNewRows++] = tmp;
5556     }
5557   }
5558   ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
5559   ierr = PetscFree(jdxm);CHKERRQ(ierr);
5560   PetscFunctionReturn(0);
5561 }
5562 
5563 #undef __FUNCT__
5564 #define __FUNCT__ "MatZeroRowsColumnsStencil"
5565 /*@C
5566    MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal)
5567    of a set of rows and columns of a matrix.
5568 
5569    Collective on Mat
5570 
5571    Input Parameters:
5572 +  mat - the matrix
5573 .  numRows - the number of rows/columns to remove
5574 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
5575 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5576 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5577 -  b - optional vector of right hand side, that will be adjusted by provided solution
5578 
5579    Notes:
5580    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5581    but does not release memory.  For the dense and block diagonal
5582    formats this does not alter the nonzero structure.
5583 
5584    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5585    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5586    merely zeroed.
5587 
5588    The user can set a value in the diagonal entry (or for the AIJ and
5589    row formats can optionally remove the main diagonal entry from the
5590    nonzero structure as well, by passing 0.0 as the final argument).
5591 
5592    For the parallel case, all processes that share the matrix (i.e.,
5593    those in the communicator used for matrix creation) MUST call this
5594    routine, regardless of whether any rows being zeroed are owned by
5595    them.
5596 
5597    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5598    list only rows local to itself, but the row/column numbers are given in local numbering).
5599 
5600    The grid coordinates are across the entire grid, not just the local portion
5601 
5602    In Fortran idxm and idxn should be declared as
5603 $     MatStencil idxm(4,m)
5604    and the values inserted using
5605 $    idxm(MatStencil_i,1) = i
5606 $    idxm(MatStencil_j,1) = j
5607 $    idxm(MatStencil_k,1) = k
5608 $    idxm(MatStencil_c,1) = c
5609    etc
5610 
5611    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5612    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5613    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5614    DMDA_BOUNDARY_PERIODIC boundary type.
5615 
5616    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
5617    a single value per point) you can skip filling those indices.
5618 
5619    Level: intermediate
5620 
5621    Concepts: matrices^zeroing rows
5622 
5623 .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5624 @*/
5625 PetscErrorCode  MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5626 {
5627   PetscInt       dim    = mat->stencil.dim;
5628   PetscInt       sdim   = dim - (1 - (PetscInt) mat->stencil.noc);
5629   PetscInt       *dims   = mat->stencil.dims+1;
5630   PetscInt       *starts = mat->stencil.starts;
5631   PetscInt       *dxm    = (PetscInt *) rows;
5632   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
5633   PetscErrorCode ierr;
5634 
5635   PetscFunctionBegin;
5636   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5637   PetscValidType(mat,1);
5638   if (numRows) PetscValidIntPointer(rows,3);
5639 
5640   ierr = PetscMalloc(numRows*sizeof(PetscInt), &jdxm);CHKERRQ(ierr);
5641   for (i = 0; i < numRows; ++i) {
5642     /* Skip unused dimensions (they are ordered k, j, i, c) */
5643     for (j = 0; j < 3-sdim; ++j) dxm++;
5644     /* Local index in X dir */
5645     tmp = *dxm++ - starts[0];
5646     /* Loop over remaining dimensions */
5647     for (j = 0; j < dim-1; ++j) {
5648       /* If nonlocal, set index to be negative */
5649       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5650       /* Update local index */
5651       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5652     }
5653     /* Skip component slot if necessary */
5654     if (mat->stencil.noc) dxm++;
5655     /* Local row number */
5656     if (tmp >= 0) {
5657       jdxm[numNewRows++] = tmp;
5658     }
5659   }
5660   ierr = MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
5661   ierr = PetscFree(jdxm);CHKERRQ(ierr);
5662   PetscFunctionReturn(0);
5663 }
5664 
5665 #undef __FUNCT__
5666 #define __FUNCT__ "MatZeroRowsLocal"
5667 /*@C
5668    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
5669    of a set of rows of a matrix; using local numbering of rows.
5670 
5671    Collective on Mat
5672 
5673    Input Parameters:
5674 +  mat - the matrix
5675 .  numRows - the number of rows to remove
5676 .  rows - the global row indices
5677 .  diag - value put in all diagonals of eliminated rows
5678 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5679 -  b - optional vector of right hand side, that will be adjusted by provided solution
5680 
5681    Notes:
5682    Before calling MatZeroRowsLocal(), the user must first set the
5683    local-to-global mapping by calling MatSetLocalToGlobalMapping().
5684 
5685    For the AIJ matrix formats this removes the old nonzero structure,
5686    but does not release memory.  For the dense and block diagonal
5687    formats this does not alter the nonzero structure.
5688 
5689    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5690    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5691    merely zeroed.
5692 
5693    The user can set a value in the diagonal entry (or for the AIJ and
5694    row formats can optionally remove the main diagonal entry from the
5695    nonzero structure as well, by passing 0.0 as the final argument).
5696 
5697    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5698    owns that are to be zeroed. This saves a global synchronization in the implementation.
5699 
5700    Level: intermediate
5701 
5702    Concepts: matrices^zeroing
5703 
5704 .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5705 @*/
5706 PetscErrorCode  MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5707 {
5708   PetscErrorCode ierr;
5709   PetscMPIInt    size;
5710 
5711   PetscFunctionBegin;
5712   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5713   PetscValidType(mat,1);
5714   if (numRows) PetscValidIntPointer(rows,3);
5715   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5716   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5717   MatCheckPreallocated(mat,1);
5718 
5719   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
5720   if (mat->ops->zerorowslocal) {
5721     ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5722   } else if (size == 1) {
5723     ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5724   } else {
5725     IS             is, newis;
5726     const PetscInt *newRows;
5727 
5728     if (!mat->rmap->mapping) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5729     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
5730     ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr);
5731     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
5732     ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
5733     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
5734     ierr = ISDestroy(&newis);CHKERRQ(ierr);
5735     ierr = ISDestroy(&is);CHKERRQ(ierr);
5736   }
5737   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5738 #if defined(PETSC_HAVE_CUSP)
5739   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5740     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5741   }
5742 #endif
5743   PetscFunctionReturn(0);
5744 }
5745 
5746 #undef __FUNCT__
5747 #define __FUNCT__ "MatZeroRowsLocalIS"
5748 /*@C
5749    MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
5750    of a set of rows of a matrix; using local numbering of rows.
5751 
5752    Collective on Mat
5753 
5754    Input Parameters:
5755 +  mat - the matrix
5756 .  is - index set of rows to remove
5757 .  diag - value put in all diagonals of eliminated rows
5758 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5759 -  b - optional vector of right hand side, that will be adjusted by provided solution
5760 
5761    Notes:
5762    Before calling MatZeroRowsLocalIS(), the user must first set the
5763    local-to-global mapping by calling MatSetLocalToGlobalMapping().
5764 
5765    For the AIJ matrix formats this removes the old nonzero structure,
5766    but does not release memory.  For the dense and block diagonal
5767    formats this does not alter the nonzero structure.
5768 
5769    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5770    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5771    merely zeroed.
5772 
5773    The user can set a value in the diagonal entry (or for the AIJ and
5774    row formats can optionally remove the main diagonal entry from the
5775    nonzero structure as well, by passing 0.0 as the final argument).
5776 
5777    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5778    owns that are to be zeroed. This saves a global synchronization in the implementation.
5779 
5780    Level: intermediate
5781 
5782    Concepts: matrices^zeroing
5783 
5784 .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5785 @*/
5786 PetscErrorCode  MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5787 {
5788   PetscErrorCode ierr;
5789   PetscInt       numRows;
5790   const PetscInt *rows;
5791 
5792   PetscFunctionBegin;
5793   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5794   PetscValidType(mat,1);
5795   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5796   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5797   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5798   MatCheckPreallocated(mat,1);
5799 
5800   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5801   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5802   ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5803   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5804   PetscFunctionReturn(0);
5805 }
5806 
5807 #undef __FUNCT__
5808 #define __FUNCT__ "MatZeroRowsColumnsLocal"
5809 /*@C
5810    MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
5811    of a set of rows and columns of a matrix; using local numbering of rows.
5812 
5813    Collective on Mat
5814 
5815    Input Parameters:
5816 +  mat - the matrix
5817 .  numRows - the number of rows to remove
5818 .  rows - the global row indices
5819 .  diag - value put in all diagonals of eliminated rows
5820 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5821 -  b - optional vector of right hand side, that will be adjusted by provided solution
5822 
5823    Notes:
5824    Before calling MatZeroRowsColumnsLocal(), the user must first set the
5825    local-to-global mapping by calling MatSetLocalToGlobalMapping().
5826 
5827    The user can set a value in the diagonal entry (or for the AIJ and
5828    row formats can optionally remove the main diagonal entry from the
5829    nonzero structure as well, by passing 0.0 as the final argument).
5830 
5831    Level: intermediate
5832 
5833    Concepts: matrices^zeroing
5834 
5835 .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5836 @*/
5837 PetscErrorCode  MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5838 {
5839   PetscErrorCode ierr;
5840   PetscMPIInt    size;
5841 
5842   PetscFunctionBegin;
5843   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5844   PetscValidType(mat,1);
5845   if (numRows) PetscValidIntPointer(rows,3);
5846   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5847   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5848   MatCheckPreallocated(mat,1);
5849 
5850   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
5851   if (size == 1) {
5852     ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5853   } else {
5854     IS             is, newis;
5855     const PetscInt *newRows;
5856 
5857     if (!mat->cmap->mapping) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5858     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
5859     ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr);
5860     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
5861     ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
5862     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
5863     ierr = ISDestroy(&newis);CHKERRQ(ierr);
5864     ierr = ISDestroy(&is);CHKERRQ(ierr);
5865   }
5866   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5867 #if defined(PETSC_HAVE_CUSP)
5868   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5869     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5870   }
5871 #endif
5872   PetscFunctionReturn(0);
5873 }
5874 
5875 #undef __FUNCT__
5876 #define __FUNCT__ "MatZeroRowsColumnsLocalIS"
5877 /*@C
5878    MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
5879    of a set of rows and columns of a matrix; using local numbering of rows.
5880 
5881    Collective on Mat
5882 
5883    Input Parameters:
5884 +  mat - the matrix
5885 .  is - index set of rows to remove
5886 .  diag - value put in all diagonals of eliminated rows
5887 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5888 -  b - optional vector of right hand side, that will be adjusted by provided solution
5889 
5890    Notes:
5891    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
5892    local-to-global mapping by calling MatSetLocalToGlobalMapping().
5893 
5894    The user can set a value in the diagonal entry (or for the AIJ and
5895    row formats can optionally remove the main diagonal entry from the
5896    nonzero structure as well, by passing 0.0 as the final argument).
5897 
5898    Level: intermediate
5899 
5900    Concepts: matrices^zeroing
5901 
5902 .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5903 @*/
5904 PetscErrorCode  MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5905 {
5906   PetscErrorCode ierr;
5907   PetscInt       numRows;
5908   const PetscInt *rows;
5909 
5910   PetscFunctionBegin;
5911   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5912   PetscValidType(mat,1);
5913   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5914   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5915   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5916   MatCheckPreallocated(mat,1);
5917 
5918   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5919   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5920   ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5921   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5922   PetscFunctionReturn(0);
5923 }
5924 
5925 #undef __FUNCT__
5926 #define __FUNCT__ "MatGetSize"
5927 /*@
5928    MatGetSize - Returns the numbers of rows and columns in a matrix.
5929 
5930    Not Collective
5931 
5932    Input Parameter:
5933 .  mat - the matrix
5934 
5935    Output Parameters:
5936 +  m - the number of global rows
5937 -  n - the number of global columns
5938 
5939    Note: both output parameters can be PETSC_NULL on input.
5940 
5941    Level: beginner
5942 
5943    Concepts: matrices^size
5944 
5945 .seealso: MatGetLocalSize()
5946 @*/
5947 PetscErrorCode  MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
5948 {
5949   PetscFunctionBegin;
5950   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5951   if (m) *m = mat->rmap->N;
5952   if (n) *n = mat->cmap->N;
5953   PetscFunctionReturn(0);
5954 }
5955 
5956 #undef __FUNCT__
5957 #define __FUNCT__ "MatGetLocalSize"
5958 /*@
5959    MatGetLocalSize - Returns the number of rows and columns in a matrix
5960    stored locally.  This information may be implementation dependent, so
5961    use with care.
5962 
5963    Not Collective
5964 
5965    Input Parameters:
5966 .  mat - the matrix
5967 
5968    Output Parameters:
5969 +  m - the number of local rows
5970 -  n - the number of local columns
5971 
5972    Note: both output parameters can be PETSC_NULL on input.
5973 
5974    Level: beginner
5975 
5976    Concepts: matrices^local size
5977 
5978 .seealso: MatGetSize()
5979 @*/
5980 PetscErrorCode  MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
5981 {
5982   PetscFunctionBegin;
5983   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5984   if (m) PetscValidIntPointer(m,2);
5985   if (n) PetscValidIntPointer(n,3);
5986   if (m) *m = mat->rmap->n;
5987   if (n) *n = mat->cmap->n;
5988   PetscFunctionReturn(0);
5989 }
5990 
5991 #undef __FUNCT__
5992 #define __FUNCT__ "MatGetOwnershipRangeColumn"
5993 /*@
5994    MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
5995    this processor. (The columns of the "diagonal block")
5996 
5997    Not Collective, unless matrix has not been allocated, then collective on Mat
5998 
5999    Input Parameters:
6000 .  mat - the matrix
6001 
6002    Output Parameters:
6003 +  m - the global index of the first local column
6004 -  n - one more than the global index of the last local column
6005 
6006    Notes: both output parameters can be PETSC_NULL on input.
6007 
6008    Level: developer
6009 
6010    Concepts: matrices^column ownership
6011 
6012 .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
6013 
6014 @*/
6015 PetscErrorCode  MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
6016 {
6017   PetscFunctionBegin;
6018   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6019   PetscValidType(mat,1);
6020   if (m) PetscValidIntPointer(m,2);
6021   if (n) PetscValidIntPointer(n,3);
6022   MatCheckPreallocated(mat,1);
6023   if (m) *m = mat->cmap->rstart;
6024   if (n) *n = mat->cmap->rend;
6025   PetscFunctionReturn(0);
6026 }
6027 
6028 #undef __FUNCT__
6029 #define __FUNCT__ "MatGetOwnershipRange"
6030 /*@
6031    MatGetOwnershipRange - Returns the range of matrix rows owned by
6032    this processor, assuming that the matrix is laid out with the first
6033    n1 rows on the first processor, the next n2 rows on the second, etc.
6034    For certain parallel layouts this range may not be well defined.
6035 
6036    Not Collective
6037 
6038    Input Parameters:
6039 .  mat - the matrix
6040 
6041    Output Parameters:
6042 +  m - the global index of the first local row
6043 -  n - one more than the global index of the last local row
6044 
6045    Note: Both output parameters can be PETSC_NULL on input.
6046 $  This function requires that the matrix be preallocated. If you have not preallocated, consider using
6047 $    PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
6048 $  and then MPI_Scan() to calculate prefix sums of the local sizes.
6049 
6050    Level: beginner
6051 
6052    Concepts: matrices^row ownership
6053 
6054 .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()
6055 
6056 @*/
6057 PetscErrorCode  MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6058 {
6059   PetscFunctionBegin;
6060   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6061   PetscValidType(mat,1);
6062   if (m) PetscValidIntPointer(m,2);
6063   if (n) PetscValidIntPointer(n,3);
6064   MatCheckPreallocated(mat,1);
6065   if (m) *m = mat->rmap->rstart;
6066   if (n) *n = mat->rmap->rend;
6067   PetscFunctionReturn(0);
6068 }
6069 
6070 #undef __FUNCT__
6071 #define __FUNCT__ "MatGetOwnershipRanges"
6072 /*@C
6073    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6074    each process
6075 
6076    Not Collective, unless matrix has not been allocated, then collective on Mat
6077 
6078    Input Parameters:
6079 .  mat - the matrix
6080 
6081    Output Parameters:
6082 .  ranges - start of each processors portion plus one more then the total length at the end
6083 
6084    Level: beginner
6085 
6086    Concepts: matrices^row ownership
6087 
6088 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
6089 
6090 @*/
6091 PetscErrorCode  MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6092 {
6093   PetscErrorCode ierr;
6094 
6095   PetscFunctionBegin;
6096   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6097   PetscValidType(mat,1);
6098   MatCheckPreallocated(mat,1);
6099   ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr);
6100   PetscFunctionReturn(0);
6101 }
6102 
6103 #undef __FUNCT__
6104 #define __FUNCT__ "MatGetOwnershipRangesColumn"
6105 /*@C
6106    MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6107    this processor. (The columns of the "diagonal blocks" for each process)
6108 
6109    Not Collective, unless matrix has not been allocated, then collective on Mat
6110 
6111    Input Parameters:
6112 .  mat - the matrix
6113 
6114    Output Parameters:
6115 .  ranges - start of each processors portion plus one more then the total length at the end
6116 
6117    Level: beginner
6118 
6119    Concepts: matrices^column ownership
6120 
6121 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
6122 
6123 @*/
6124 PetscErrorCode  MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6125 {
6126   PetscErrorCode ierr;
6127 
6128   PetscFunctionBegin;
6129   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6130   PetscValidType(mat,1);
6131   MatCheckPreallocated(mat,1);
6132   ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr);
6133   PetscFunctionReturn(0);
6134 }
6135 
6136 #undef __FUNCT__
6137 #define __FUNCT__ "MatGetOwnershipIS"
6138 /*@C
6139    MatGetOwnershipIS - Get row and column ownership as index sets
6140 
6141    Not Collective
6142 
6143    Input Arguments:
6144 .  A - matrix of type Elemental
6145 
6146    Output Arguments:
6147 +  rows - rows in which this process owns elements
6148 .  cols - columns in which this process owns elements
6149 
6150    Level: intermediate
6151 
6152 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL, MatSetValues()
6153 @*/
6154 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6155 {
6156   PetscErrorCode ierr,(*f)(Mat,IS*,IS*);
6157 
6158   PetscFunctionBegin;
6159   MatCheckPreallocated(A,1);
6160   ierr = PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",(PetscVoidStarFunction)&f);CHKERRQ(ierr);
6161   if (f) {
6162     ierr = (*f)(A,rows,cols);CHKERRQ(ierr);
6163   } else {   /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6164     if (rows) {ierr = ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);CHKERRQ(ierr);}
6165     if (cols) {ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);CHKERRQ(ierr);}
6166   }
6167   PetscFunctionReturn(0);
6168 }
6169 
6170 #undef __FUNCT__
6171 #define __FUNCT__ "MatILUFactorSymbolic"
6172 /*@C
6173    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6174    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6175    to complete the factorization.
6176 
6177    Collective on Mat
6178 
6179    Input Parameters:
6180 +  mat - the matrix
6181 .  row - row permutation
6182 .  column - column permutation
6183 -  info - structure containing
6184 $      levels - number of levels of fill.
6185 $      expected fill - as ratio of original fill.
6186 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6187                 missing diagonal entries)
6188 
6189    Output Parameters:
6190 .  fact - new matrix that has been symbolically factored
6191 
6192    Notes:
6193    See the <a href="../../docs/manual.pdf">users manual</a>  for additional information about
6194    choosing the fill factor for better efficiency.
6195 
6196    Most users should employ the simplified KSP interface for linear solvers
6197    instead of working directly with matrix algebra routines such as this.
6198    See, e.g., KSPCreate().
6199 
6200    Level: developer
6201 
6202   Concepts: matrices^symbolic LU factorization
6203   Concepts: matrices^factorization
6204   Concepts: LU^symbolic factorization
6205 
6206 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6207           MatGetOrdering(), MatFactorInfo
6208 
6209     Developer Note: fortran interface is not autogenerated as the f90
6210     interface defintion cannot be generated correctly [due to MatFactorInfo]
6211 
6212 @*/
6213 PetscErrorCode  MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6214 {
6215   PetscErrorCode ierr;
6216 
6217   PetscFunctionBegin;
6218   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6219   PetscValidType(mat,1);
6220   PetscValidHeaderSpecific(row,IS_CLASSID,2);
6221   PetscValidHeaderSpecific(col,IS_CLASSID,3);
6222   PetscValidPointer(info,4);
6223   PetscValidPointer(fact,5);
6224   if (info->levels < 0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6225   if (info->fill < 1.0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
6226   if (!(fact)->ops->ilufactorsymbolic) {
6227     const MatSolverPackage spackage;
6228     ierr = MatFactorGetSolverPackage(fact,&spackage);CHKERRQ(ierr);
6229     SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6230   }
6231   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6232   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6233   MatCheckPreallocated(mat,2);
6234 
6235   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6236   ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
6237   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6238   PetscFunctionReturn(0);
6239 }
6240 
6241 #undef __FUNCT__
6242 #define __FUNCT__ "MatICCFactorSymbolic"
6243 /*@C
6244    MatICCFactorSymbolic - Performs symbolic incomplete
6245    Cholesky factorization for a symmetric matrix.  Use
6246    MatCholeskyFactorNumeric() to complete the factorization.
6247 
6248    Collective on Mat
6249 
6250    Input Parameters:
6251 +  mat - the matrix
6252 .  perm - row and column permutation
6253 -  info - structure containing
6254 $      levels - number of levels of fill.
6255 $      expected fill - as ratio of original fill.
6256 
6257    Output Parameter:
6258 .  fact - the factored matrix
6259 
6260    Notes:
6261    Most users should employ the KSP interface for linear solvers
6262    instead of working directly with matrix algebra routines such as this.
6263    See, e.g., KSPCreate().
6264 
6265    Level: developer
6266 
6267   Concepts: matrices^symbolic incomplete Cholesky factorization
6268   Concepts: matrices^factorization
6269   Concepts: Cholsky^symbolic factorization
6270 
6271 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
6272 
6273     Developer Note: fortran interface is not autogenerated as the f90
6274     interface defintion cannot be generated correctly [due to MatFactorInfo]
6275 
6276 @*/
6277 PetscErrorCode  MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6278 {
6279   PetscErrorCode ierr;
6280 
6281   PetscFunctionBegin;
6282   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6283   PetscValidType(mat,1);
6284   PetscValidHeaderSpecific(perm,IS_CLASSID,2);
6285   PetscValidPointer(info,3);
6286   PetscValidPointer(fact,4);
6287   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6288   if (info->levels < 0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6289   if (info->fill < 1.0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
6290   if (!(fact)->ops->iccfactorsymbolic) {
6291     const MatSolverPackage spackage;
6292     ierr = MatFactorGetSolverPackage(fact,&spackage);CHKERRQ(ierr);
6293     SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6294   }
6295   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6296   MatCheckPreallocated(mat,2);
6297 
6298   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6299   ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
6300   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6301   PetscFunctionReturn(0);
6302 }
6303 
6304 #undef __FUNCT__
6305 #define __FUNCT__ "MatGetSubMatrices"
6306 /*@C
6307    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
6308    points to an array of valid matrices, they may be reused to store the new
6309    submatrices.
6310 
6311    Collective on Mat
6312 
6313    Input Parameters:
6314 +  mat - the matrix
6315 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6316 .  irow, icol - index sets of rows and columns to extract (must be sorted)
6317 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6318 
6319    Output Parameter:
6320 .  submat - the array of submatrices
6321 
6322    Notes:
6323    MatGetSubMatrices() can extract ONLY sequential submatrices
6324    (from both sequential and parallel matrices). Use MatGetSubMatrix()
6325    to extract a parallel submatrix.
6326 
6327    Currently both row and column indices must be sorted to guarantee
6328    correctness with all matrix types.
6329 
6330    When extracting submatrices from a parallel matrix, each processor can
6331    form a different submatrix by setting the rows and columns of its
6332    individual index sets according to the local submatrix desired.
6333 
6334    When finished using the submatrices, the user should destroy
6335    them with MatDestroyMatrices().
6336 
6337    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6338    original matrix has not changed from that last call to MatGetSubMatrices().
6339 
6340    This routine creates the matrices in submat; you should NOT create them before
6341    calling it. It also allocates the array of matrix pointers submat.
6342 
6343    For BAIJ matrices the index sets must respect the block structure, that is if they
6344    request one row/column in a block, they must request all rows/columns that are in
6345    that block. For example, if the block size is 2 you cannot request just row 0 and
6346    column 0.
6347 
6348    Fortran Note:
6349    The Fortran interface is slightly different from that given below; it
6350    requires one to pass in  as submat a Mat (integer) array of size at least m.
6351 
6352    Level: advanced
6353 
6354    Concepts: matrices^accessing submatrices
6355    Concepts: submatrices
6356 
6357 .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6358 @*/
6359 PetscErrorCode  MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6360 {
6361   PetscErrorCode ierr;
6362   PetscInt       i;
6363   PetscBool      eq;
6364 
6365   PetscFunctionBegin;
6366   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6367   PetscValidType(mat,1);
6368   if (n) {
6369     PetscValidPointer(irow,3);
6370     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6371     PetscValidPointer(icol,4);
6372     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6373   }
6374   PetscValidPointer(submat,6);
6375   if (n && scall == MAT_REUSE_MATRIX) {
6376     PetscValidPointer(*submat,6);
6377     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6378   }
6379   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6380   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6381   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6382   MatCheckPreallocated(mat,1);
6383 
6384   ierr = PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
6385   ierr = (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6386   ierr = PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
6387   for (i=0; i<n; i++) {
6388     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6389       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6390       if (eq) {
6391 	if (mat->symmetric) {
6392 	  ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6393 	} else if (mat->hermitian) {
6394 	  ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6395 	} else if (mat->structurally_symmetric) {
6396 	  ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6397 	}
6398       }
6399     }
6400   }
6401   PetscFunctionReturn(0);
6402 }
6403 
6404 #undef __FUNCT__
6405 #define __FUNCT__ "MatGetSubMatricesParallel"
6406 PetscErrorCode  MatGetSubMatricesParallel(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6407 {
6408   PetscErrorCode ierr;
6409   PetscInt       i;
6410   PetscBool      eq;
6411 
6412   PetscFunctionBegin;
6413   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6414   PetscValidType(mat,1);
6415   if (n) {
6416     PetscValidPointer(irow,3);
6417     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6418     PetscValidPointer(icol,4);
6419     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6420   }
6421   PetscValidPointer(submat,6);
6422   if (n && scall == MAT_REUSE_MATRIX) {
6423     PetscValidPointer(*submat,6);
6424     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6425   }
6426   if (!mat->ops->getsubmatricesparallel) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6427   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6428   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6429   MatCheckPreallocated(mat,1);
6430 
6431   ierr = PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
6432   ierr = (*mat->ops->getsubmatricesparallel)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6433   ierr = PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
6434   for (i=0; i<n; i++) {
6435     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6436       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6437       if (eq) {
6438 	if (mat->symmetric) {
6439 	  ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6440 	} else if (mat->hermitian) {
6441 	  ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6442 	} else if (mat->structurally_symmetric) {
6443 	  ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6444 	}
6445       }
6446     }
6447   }
6448   PetscFunctionReturn(0);
6449 }
6450 
6451 #undef __FUNCT__
6452 #define __FUNCT__ "MatDestroyMatrices"
6453 /*@C
6454    MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().
6455 
6456    Collective on Mat
6457 
6458    Input Parameters:
6459 +  n - the number of local matrices
6460 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6461                        sequence of MatGetSubMatrices())
6462 
6463    Level: advanced
6464 
6465     Notes: Frees not only the matrices, but also the array that contains the matrices
6466            In Fortran will not free the array.
6467 
6468 .seealso: MatGetSubMatrices()
6469 @*/
6470 PetscErrorCode  MatDestroyMatrices(PetscInt n,Mat *mat[])
6471 {
6472   PetscErrorCode ierr;
6473   PetscInt       i;
6474 
6475   PetscFunctionBegin;
6476   if (!*mat) PetscFunctionReturn(0);
6477   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6478   PetscValidPointer(mat,2);
6479   for (i=0; i<n; i++) {
6480     ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr);
6481   }
6482   /* memory is allocated even if n = 0 */
6483   ierr = PetscFree(*mat);CHKERRQ(ierr);
6484   *mat = PETSC_NULL;
6485   PetscFunctionReturn(0);
6486 }
6487 
6488 #undef __FUNCT__
6489 #define __FUNCT__ "MatGetSeqNonzeroStructure"
6490 /*@C
6491    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
6492 
6493    Collective on Mat
6494 
6495    Input Parameters:
6496 .  mat - the matrix
6497 
6498    Output Parameter:
6499 .  matstruct - the sequential matrix with the nonzero structure of mat
6500 
6501   Level: intermediate
6502 
6503 .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
6504 @*/
6505 PetscErrorCode  MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6506 {
6507   PetscErrorCode ierr;
6508 
6509   PetscFunctionBegin;
6510   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6511   PetscValidPointer(matstruct,2);
6512 
6513   PetscValidType(mat,1);
6514   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6515   MatCheckPreallocated(mat,1);
6516 
6517   if (!mat->ops->getseqnonzerostructure) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6518   ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
6519   ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr);
6520   ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
6521   PetscFunctionReturn(0);
6522 }
6523 
6524 #undef __FUNCT__
6525 #define __FUNCT__ "MatDestroySeqNonzeroStructure"
6526 /*@C
6527    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
6528 
6529    Collective on Mat
6530 
6531    Input Parameters:
6532 .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
6533                        sequence of MatGetSequentialNonzeroStructure())
6534 
6535    Level: advanced
6536 
6537     Notes: Frees not only the matrices, but also the array that contains the matrices
6538 
6539 .seealso: MatGetSeqNonzeroStructure()
6540 @*/
6541 PetscErrorCode  MatDestroySeqNonzeroStructure(Mat *mat)
6542 {
6543   PetscErrorCode ierr;
6544 
6545   PetscFunctionBegin;
6546   PetscValidPointer(mat,1);
6547   ierr = MatDestroy(mat);CHKERRQ(ierr);
6548   PetscFunctionReturn(0);
6549 }
6550 
6551 #undef __FUNCT__
6552 #define __FUNCT__ "MatIncreaseOverlap"
6553 /*@
6554    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6555    replaces the index sets by larger ones that represent submatrices with
6556    additional overlap.
6557 
6558    Collective on Mat
6559 
6560    Input Parameters:
6561 +  mat - the matrix
6562 .  n   - the number of index sets
6563 .  is  - the array of index sets (these index sets will changed during the call)
6564 -  ov  - the additional overlap requested
6565 
6566    Level: developer
6567 
6568    Concepts: overlap
6569    Concepts: ASM^computing overlap
6570 
6571 .seealso: MatGetSubMatrices()
6572 @*/
6573 PetscErrorCode  MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6574 {
6575   PetscErrorCode ierr;
6576 
6577   PetscFunctionBegin;
6578   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6579   PetscValidType(mat,1);
6580   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6581   if (n) {
6582     PetscValidPointer(is,3);
6583     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
6584   }
6585   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6586   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6587   MatCheckPreallocated(mat,1);
6588 
6589   if (!ov) PetscFunctionReturn(0);
6590   if (!mat->ops->increaseoverlap) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6591   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
6592   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
6593   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
6594   PetscFunctionReturn(0);
6595 }
6596 
6597 #undef __FUNCT__
6598 #define __FUNCT__ "MatGetBlockSize"
6599 /*@
6600    MatGetBlockSize - Returns the matrix block size; useful especially for the
6601    block row and block diagonal formats.
6602 
6603    Not Collective
6604 
6605    Input Parameter:
6606 .  mat - the matrix
6607 
6608    Output Parameter:
6609 .  bs - block size
6610 
6611    Notes:
6612    Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ
6613 
6614    Level: intermediate
6615 
6616    Concepts: matrices^block size
6617 
6618 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
6619 @*/
6620 PetscErrorCode  MatGetBlockSize(Mat mat,PetscInt *bs)
6621 {
6622   PetscFunctionBegin;
6623   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6624   PetscValidType(mat,1);
6625   PetscValidIntPointer(bs,2);
6626   MatCheckPreallocated(mat,1);
6627   *bs = mat->rmap->bs;
6628   PetscFunctionReturn(0);
6629 }
6630 
6631 #undef __FUNCT__
6632 #define __FUNCT__ "MatGetBlockSizes"
6633 /*@
6634    MatGetBlockSizes - Returns the matrix block row and column sizes;
6635    useful especially for the block row and block diagonal formats.
6636 
6637    Not Collective
6638 
6639    Input Parameter:
6640 .  mat - the matrix
6641 
6642    Output Parameter:
6643 .  rbs - row block size
6644 .  cbs - coumn block size
6645 
6646    Notes:
6647    Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ
6648 
6649    Level: intermediate
6650 
6651    Concepts: matrices^block size
6652 
6653 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
6654 @*/
6655 PetscErrorCode  MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
6656 {
6657   PetscFunctionBegin;
6658   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6659   PetscValidType(mat,1);
6660   if (rbs) PetscValidIntPointer(rbs,2);
6661   if (cbs) PetscValidIntPointer(cbs,3);
6662   MatCheckPreallocated(mat,1);
6663   if (rbs) *rbs = mat->rmap->bs;
6664   if (cbs) *cbs = mat->cmap->bs;
6665   PetscFunctionReturn(0);
6666 }
6667 
6668 #undef __FUNCT__
6669 #define __FUNCT__ "MatSetBlockSize"
6670 /*@
6671    MatSetBlockSize - Sets the matrix block size.
6672 
6673    Logically Collective on Mat
6674 
6675    Input Parameters:
6676 +  mat - the matrix
6677 -  bs - block size
6678 
6679    Notes:
6680      This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later
6681 
6682    Level: intermediate
6683 
6684    Concepts: matrices^block size
6685 
6686 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
6687 @*/
6688 PetscErrorCode  MatSetBlockSize(Mat mat,PetscInt bs)
6689 {
6690   PetscErrorCode ierr;
6691 
6692   PetscFunctionBegin;
6693   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6694   PetscValidLogicalCollectiveInt(mat,bs,2);
6695   ierr = PetscLayoutSetBlockSize(mat->rmap,bs);CHKERRQ(ierr);
6696   ierr = PetscLayoutSetBlockSize(mat->cmap,bs);CHKERRQ(ierr);
6697   PetscFunctionReturn(0);
6698 }
6699 
6700 #undef __FUNCT__
6701 #define __FUNCT__ "MatSetBlockSizes"
6702 /*@
6703    MatSetBlockSizes - Sets the matrix block row and column sizes.
6704 
6705    Logically Collective on Mat
6706 
6707    Input Parameters:
6708 +  mat - the matrix
6709 -  rbs - row block size
6710 -  cbs - column block size
6711 
6712    Notes:
6713      This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later
6714 
6715    Level: intermediate
6716 
6717    Concepts: matrices^block size
6718 
6719 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
6720 @*/
6721 PetscErrorCode  MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
6722 {
6723   PetscErrorCode ierr;
6724 
6725   PetscFunctionBegin;
6726   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6727   PetscValidLogicalCollectiveInt(mat,rbs,2);
6728   ierr = PetscLayoutSetBlockSize(mat->rmap,rbs);CHKERRQ(ierr);
6729   ierr = PetscLayoutSetBlockSize(mat->cmap,cbs);CHKERRQ(ierr);
6730   PetscFunctionReturn(0);
6731 }
6732 
6733 #undef __FUNCT__
6734 #define __FUNCT__ "MatGetRowIJ"
6735 /*@C
6736     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
6737 
6738    Collective on Mat
6739 
6740     Input Parameters:
6741 +   mat - the matrix
6742 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
6743 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
6744 -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
6745                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6746                  always used.
6747 
6748     Output Parameters:
6749 +   n - number of rows in the (possibly compressed) matrix
6750 .   ia - the row pointers [of length n+1]
6751 .   ja - the column indices
6752 -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
6753            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
6754 
6755     Level: developer
6756 
6757     Notes: You CANNOT change any of the ia[] or ja[] values.
6758 
6759            Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values
6760 
6761     Fortran Node
6762 
6763            In Fortran use
6764 $           PetscInt ia(1), ja(1)
6765 $           PetscOffset iia, jja
6766 $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
6767 $
6768 $          or
6769 $
6770 $           PetscScalar, pointer :: xx_v(:)
6771 $    call  MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
6772 
6773 
6774        Acess the ith and jth entries via ia(iia + i) and ja(jja + j)
6775 
6776 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
6777 @*/
6778 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
6779 {
6780   PetscErrorCode ierr;
6781 
6782   PetscFunctionBegin;
6783   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6784   PetscValidType(mat,1);
6785   PetscValidIntPointer(n,4);
6786   if (ia) PetscValidIntPointer(ia,5);
6787   if (ja) PetscValidIntPointer(ja,6);
6788   PetscValidIntPointer(done,7);
6789   MatCheckPreallocated(mat,1);
6790   if (!mat->ops->getrowij) *done = PETSC_FALSE;
6791   else {
6792     *done = PETSC_TRUE;
6793     ierr = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
6794     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6795     ierr = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
6796   }
6797   PetscFunctionReturn(0);
6798 }
6799 
6800 #undef __FUNCT__
6801 #define __FUNCT__ "MatGetColumnIJ"
6802 /*@C
6803     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
6804 
6805     Collective on Mat
6806 
6807     Input Parameters:
6808 +   mat - the matrix
6809 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6810 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6811                 symmetrized
6812 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6813                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6814                  always used.
6815 
6816     Output Parameters:
6817 +   n - number of columns in the (possibly compressed) matrix
6818 .   ia - the column pointers
6819 .   ja - the row indices
6820 -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
6821 
6822     Level: developer
6823 
6824 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6825 @*/
6826 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
6827 {
6828   PetscErrorCode ierr;
6829 
6830   PetscFunctionBegin;
6831   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6832   PetscValidType(mat,1);
6833   PetscValidIntPointer(n,4);
6834   if (ia) PetscValidIntPointer(ia,5);
6835   if (ja) PetscValidIntPointer(ja,6);
6836   PetscValidIntPointer(done,7);
6837   MatCheckPreallocated(mat,1);
6838   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
6839   else {
6840     *done = PETSC_TRUE;
6841     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6842   }
6843   PetscFunctionReturn(0);
6844 }
6845 
6846 #undef __FUNCT__
6847 #define __FUNCT__ "MatRestoreRowIJ"
6848 /*@C
6849     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
6850     MatGetRowIJ().
6851 
6852     Collective on Mat
6853 
6854     Input Parameters:
6855 +   mat - the matrix
6856 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6857 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6858                 symmetrized
6859 -   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6860                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6861                  always used.
6862 
6863     Output Parameters:
6864 +   n - size of (possibly compressed) matrix
6865 .   ia - the row pointers
6866 .   ja - the column indices
6867 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
6868 
6869     Level: developer
6870 
6871 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6872 @*/
6873 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
6874 {
6875   PetscErrorCode ierr;
6876 
6877   PetscFunctionBegin;
6878   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6879   PetscValidType(mat,1);
6880   if (ia) PetscValidIntPointer(ia,5);
6881   if (ja) PetscValidIntPointer(ja,6);
6882   PetscValidIntPointer(done,7);
6883   MatCheckPreallocated(mat,1);
6884 
6885   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
6886   else {
6887     *done = PETSC_TRUE;
6888     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6889   }
6890   PetscFunctionReturn(0);
6891 }
6892 
6893 #undef __FUNCT__
6894 #define __FUNCT__ "MatRestoreColumnIJ"
6895 /*@C
6896     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
6897     MatGetColumnIJ().
6898 
6899     Collective on Mat
6900 
6901     Input Parameters:
6902 +   mat - the matrix
6903 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6904 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6905                 symmetrized
6906 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6907                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6908                  always used.
6909 
6910     Output Parameters:
6911 +   n - size of (possibly compressed) matrix
6912 .   ia - the column pointers
6913 .   ja - the row indices
6914 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
6915 
6916     Level: developer
6917 
6918 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
6919 @*/
6920 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
6921 {
6922   PetscErrorCode ierr;
6923 
6924   PetscFunctionBegin;
6925   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6926   PetscValidType(mat,1);
6927   if (ia) PetscValidIntPointer(ia,5);
6928   if (ja) PetscValidIntPointer(ja,6);
6929   PetscValidIntPointer(done,7);
6930   MatCheckPreallocated(mat,1);
6931 
6932   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
6933   else {
6934     *done = PETSC_TRUE;
6935     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6936   }
6937   PetscFunctionReturn(0);
6938 }
6939 
6940 #undef __FUNCT__
6941 #define __FUNCT__ "MatColoringPatch"
6942 /*@C
6943     MatColoringPatch -Used inside matrix coloring routines that
6944     use MatGetRowIJ() and/or MatGetColumnIJ().
6945 
6946     Collective on Mat
6947 
6948     Input Parameters:
6949 +   mat - the matrix
6950 .   ncolors - max color value
6951 .   n   - number of entries in colorarray
6952 -   colorarray - array indicating color for each column
6953 
6954     Output Parameters:
6955 .   iscoloring - coloring generated using colorarray information
6956 
6957     Level: developer
6958 
6959 .seealso: MatGetRowIJ(), MatGetColumnIJ()
6960 
6961 @*/
6962 PetscErrorCode  MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
6963 {
6964   PetscErrorCode ierr;
6965 
6966   PetscFunctionBegin;
6967   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6968   PetscValidType(mat,1);
6969   PetscValidIntPointer(colorarray,4);
6970   PetscValidPointer(iscoloring,5);
6971   MatCheckPreallocated(mat,1);
6972 
6973   if (!mat->ops->coloringpatch) {
6974     ierr = ISColoringCreate(((PetscObject)mat)->comm,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
6975   } else {
6976     ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
6977   }
6978   PetscFunctionReturn(0);
6979 }
6980 
6981 
6982 #undef __FUNCT__
6983 #define __FUNCT__ "MatSetUnfactored"
6984 /*@
6985    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
6986 
6987    Logically Collective on Mat
6988 
6989    Input Parameter:
6990 .  mat - the factored matrix to be reset
6991 
6992    Notes:
6993    This routine should be used only with factored matrices formed by in-place
6994    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
6995    format).  This option can save memory, for example, when solving nonlinear
6996    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
6997    ILU(0) preconditioner.
6998 
6999    Note that one can specify in-place ILU(0) factorization by calling
7000 .vb
7001      PCType(pc,PCILU);
7002      PCFactorSeUseInPlace(pc);
7003 .ve
7004    or by using the options -pc_type ilu -pc_factor_in_place
7005 
7006    In-place factorization ILU(0) can also be used as a local
7007    solver for the blocks within the block Jacobi or additive Schwarz
7008    methods (runtime option: -sub_pc_factor_in_place).  See the discussion
7009    of these preconditioners in the <a href="../../docs/manual.pdf#ch_pc">PC chapter of the users manual</a> for details on setting
7010    local solver options.
7011 
7012    Most users should employ the simplified KSP interface for linear solvers
7013    instead of working directly with matrix algebra routines such as this.
7014    See, e.g., KSPCreate().
7015 
7016    Level: developer
7017 
7018 .seealso: PCFactorSetUseInPlace()
7019 
7020    Concepts: matrices^unfactored
7021 
7022 @*/
7023 PetscErrorCode  MatSetUnfactored(Mat mat)
7024 {
7025   PetscErrorCode ierr;
7026 
7027   PetscFunctionBegin;
7028   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7029   PetscValidType(mat,1);
7030   MatCheckPreallocated(mat,1);
7031   mat->factortype = MAT_FACTOR_NONE;
7032   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
7033   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
7034   PetscFunctionReturn(0);
7035 }
7036 
7037 /*MC
7038     MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.
7039 
7040     Synopsis:
7041     MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7042 
7043     Not collective
7044 
7045     Input Parameter:
7046 .   x - matrix
7047 
7048     Output Parameters:
7049 +   xx_v - the Fortran90 pointer to the array
7050 -   ierr - error code
7051 
7052     Example of Usage:
7053 .vb
7054       PetscScalar, pointer xx_v(:,:)
7055       ....
7056       call MatDenseGetArrayF90(x,xx_v,ierr)
7057       a = xx_v(3)
7058       call MatDenseRestoreArrayF90(x,xx_v,ierr)
7059 .ve
7060 
7061     Level: advanced
7062 
7063 .seealso:  MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray()
7064 
7065     Concepts: matrices^accessing array
7066 
7067 M*/
7068 
7069 /*MC
7070     MatDenseRestoreArrayF90 - Restores a matrix array that has been
7071     accessed with MatGetArrayF90().
7072 
7073     Synopsis:
7074     MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7075 
7076     Not collective
7077 
7078     Input Parameters:
7079 +   x - matrix
7080 -   xx_v - the Fortran90 pointer to the array
7081 
7082     Output Parameter:
7083 .   ierr - error code
7084 
7085     Example of Usage:
7086 .vb
7087        PetscScalar, pointer xx_v(:)
7088        ....
7089        call MatDenseGetArrayF90(x,xx_v,ierr)
7090        a = xx_v(3)
7091        call MatDenseRestoreArrayF90(x,xx_v,ierr)
7092 .ve
7093 
7094     Level: advanced
7095 
7096 .seealso:  MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray()
7097 
7098 M*/
7099 
7100 
7101 #undef __FUNCT__
7102 #define __FUNCT__ "MatGetSubMatrix"
7103 /*@
7104     MatGetSubMatrix - Gets a single submatrix on the same number of processors
7105                       as the original matrix.
7106 
7107     Collective on Mat
7108 
7109     Input Parameters:
7110 +   mat - the original matrix
7111 .   isrow - parallel IS containing the rows this processor should obtain
7112 .   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.
7113 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7114 
7115     Output Parameter:
7116 .   newmat - the new submatrix, of the same type as the old
7117 
7118     Level: advanced
7119 
7120     Notes:
7121     The submatrix will be able to be multiplied with vectors using the same layout as iscol.
7122 
7123     The rows in isrow will be sorted into the same order as the original matrix on each process.
7124 
7125       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7126    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
7127    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7128    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
7129    you are finished using it.
7130 
7131     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7132     the input matrix.
7133 
7134     If iscol is PETSC_NULL then all columns are obtained (not supported in Fortran).
7135 
7136    Example usage:
7137    Consider the following 8x8 matrix with 34 non-zero values, that is
7138    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7139    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7140    as follows:
7141 
7142 .vb
7143             1  2  0  |  0  3  0  |  0  4
7144     Proc0   0  5  6  |  7  0  0  |  8  0
7145             9  0 10  | 11  0  0  | 12  0
7146     -------------------------------------
7147            13  0 14  | 15 16 17  |  0  0
7148     Proc1   0 18  0  | 19 20 21  |  0  0
7149             0  0  0  | 22 23  0  | 24  0
7150     -------------------------------------
7151     Proc2  25 26 27  |  0  0 28  | 29  0
7152            30  0  0  | 31 32 33  |  0 34
7153 .ve
7154 
7155     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is
7156 
7157 .vb
7158             2  0  |  0  3  0  |  0
7159     Proc0   5  6  |  7  0  0  |  8
7160     -------------------------------
7161     Proc1  18  0  | 19 20 21  |  0
7162     -------------------------------
7163     Proc2  26 27  |  0  0 28  | 29
7164             0  0  | 31 32 33  |  0
7165 .ve
7166 
7167 
7168     Concepts: matrices^submatrices
7169 
7170 .seealso: MatGetSubMatrices()
7171 @*/
7172 PetscErrorCode  MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7173 {
7174   PetscErrorCode ierr;
7175   PetscMPIInt    size;
7176   Mat            *local;
7177   IS             iscoltmp;
7178 
7179   PetscFunctionBegin;
7180   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7181   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
7182   if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
7183   PetscValidPointer(newmat,5);
7184   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5);
7185   PetscValidType(mat,1);
7186   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7187   MatCheckPreallocated(mat,1);
7188   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
7189 
7190   if (!iscol) {
7191     ierr = ISCreateStride(((PetscObject)mat)->comm,mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr);
7192   } else {
7193     iscoltmp = iscol;
7194   }
7195 
7196   /* if original matrix is on just one processor then use submatrix generated */
7197   if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7198     ierr = MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
7199     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7200     PetscFunctionReturn(0);
7201   } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) {
7202     ierr    = MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
7203     *newmat = *local;
7204     ierr    = PetscFree(local);CHKERRQ(ierr);
7205     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7206     PetscFunctionReturn(0);
7207   } else if (!mat->ops->getsubmatrix) {
7208     /* Create a new matrix type that implements the operation using the full matrix */
7209     switch (cll) {
7210       case MAT_INITIAL_MATRIX:
7211         ierr = MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr);
7212         break;
7213       case MAT_REUSE_MATRIX:
7214         ierr = MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr);
7215         break;
7216       default: SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7217     }
7218     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7219     PetscFunctionReturn(0);
7220   }
7221 
7222   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7223   ierr = (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr);
7224   if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7225   if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);}
7226   PetscFunctionReturn(0);
7227 }
7228 
7229 #undef __FUNCT__
7230 #define __FUNCT__ "MatStashSetInitialSize"
7231 /*@
7232    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7233    used during the assembly process to store values that belong to
7234    other processors.
7235 
7236    Not Collective
7237 
7238    Input Parameters:
7239 +  mat   - the matrix
7240 .  size  - the initial size of the stash.
7241 -  bsize - the initial size of the block-stash(if used).
7242 
7243    Options Database Keys:
7244 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
7245 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
7246 
7247    Level: intermediate
7248 
7249    Notes:
7250      The block-stash is used for values set with MatSetValuesBlocked() while
7251      the stash is used for values set with MatSetValues()
7252 
7253      Run with the option -info and look for output of the form
7254      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7255      to determine the appropriate value, MM, to use for size and
7256      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7257      to determine the value, BMM to use for bsize
7258 
7259    Concepts: stash^setting matrix size
7260    Concepts: matrices^stash
7261 
7262 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
7263 
7264 @*/
7265 PetscErrorCode  MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7266 {
7267   PetscErrorCode ierr;
7268 
7269   PetscFunctionBegin;
7270   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7271   PetscValidType(mat,1);
7272   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
7273   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
7274   PetscFunctionReturn(0);
7275 }
7276 
7277 #undef __FUNCT__
7278 #define __FUNCT__ "MatInterpolateAdd"
7279 /*@
7280    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
7281      the matrix
7282 
7283    Neighbor-wise Collective on Mat
7284 
7285    Input Parameters:
7286 +  mat   - the matrix
7287 .  x,y - the vectors
7288 -  w - where the result is stored
7289 
7290    Level: intermediate
7291 
7292    Notes:
7293     w may be the same vector as y.
7294 
7295     This allows one to use either the restriction or interpolation (its transpose)
7296     matrix to do the interpolation
7297 
7298     Concepts: interpolation
7299 
7300 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7301 
7302 @*/
7303 PetscErrorCode  MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7304 {
7305   PetscErrorCode ierr;
7306   PetscInt       M,N,Ny;
7307 
7308   PetscFunctionBegin;
7309   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7310   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7311   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7312   PetscValidHeaderSpecific(w,VEC_CLASSID,4);
7313   PetscValidType(A,1);
7314   MatCheckPreallocated(A,1);
7315   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
7316   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
7317   if (M == Ny) {
7318     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
7319   } else {
7320     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
7321   }
7322   PetscFunctionReturn(0);
7323 }
7324 
7325 #undef __FUNCT__
7326 #define __FUNCT__ "MatInterpolate"
7327 /*@
7328    MatInterpolate - y = A*x or A'*x depending on the shape of
7329      the matrix
7330 
7331    Neighbor-wise Collective on Mat
7332 
7333    Input Parameters:
7334 +  mat   - the matrix
7335 -  x,y - the vectors
7336 
7337    Level: intermediate
7338 
7339    Notes:
7340     This allows one to use either the restriction or interpolation (its transpose)
7341     matrix to do the interpolation
7342 
7343    Concepts: matrices^interpolation
7344 
7345 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7346 
7347 @*/
7348 PetscErrorCode  MatInterpolate(Mat A,Vec x,Vec y)
7349 {
7350   PetscErrorCode ierr;
7351   PetscInt       M,N,Ny;
7352 
7353   PetscFunctionBegin;
7354   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7355   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7356   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7357   PetscValidType(A,1);
7358   MatCheckPreallocated(A,1);
7359   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
7360   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
7361   if (M == Ny) {
7362     ierr = MatMult(A,x,y);CHKERRQ(ierr);
7363   } else {
7364     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
7365   }
7366   PetscFunctionReturn(0);
7367 }
7368 
7369 #undef __FUNCT__
7370 #define __FUNCT__ "MatRestrict"
7371 /*@
7372    MatRestrict - y = A*x or A'*x
7373 
7374    Neighbor-wise Collective on Mat
7375 
7376    Input Parameters:
7377 +  mat   - the matrix
7378 -  x,y - the vectors
7379 
7380    Level: intermediate
7381 
7382    Notes:
7383     This allows one to use either the restriction or interpolation (its transpose)
7384     matrix to do the restriction
7385 
7386    Concepts: matrices^restriction
7387 
7388 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
7389 
7390 @*/
7391 PetscErrorCode  MatRestrict(Mat A,Vec x,Vec y)
7392 {
7393   PetscErrorCode ierr;
7394   PetscInt       M,N,Ny;
7395 
7396   PetscFunctionBegin;
7397   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7398   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7399   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7400   PetscValidType(A,1);
7401   MatCheckPreallocated(A,1);
7402 
7403   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
7404   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
7405   if (M == Ny) {
7406     ierr = MatMult(A,x,y);CHKERRQ(ierr);
7407   } else {
7408     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
7409   }
7410   PetscFunctionReturn(0);
7411 }
7412 
7413 #undef __FUNCT__
7414 #define __FUNCT__ "MatGetNullSpace"
7415 /*@
7416    MatGetNullSpace - retrieves the null space to a matrix.
7417 
7418    Logically Collective on Mat and MatNullSpace
7419 
7420    Input Parameters:
7421 +  mat - the matrix
7422 -  nullsp - the null space object
7423 
7424    Level: developer
7425 
7426    Notes:
7427       This null space is used by solvers. Overwrites any previous null space that may have been attached
7428 
7429    Concepts: null space^attaching to matrix
7430 
7431 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace()
7432 @*/
7433 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
7434 {
7435   PetscFunctionBegin;
7436   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7437   PetscValidType(mat,1);
7438   PetscValidPointer(nullsp,2);
7439   *nullsp = mat->nullsp;
7440   PetscFunctionReturn(0);
7441 }
7442 
7443 #undef __FUNCT__
7444 #define __FUNCT__ "MatSetNullSpace"
7445 /*@
7446    MatSetNullSpace - attaches a null space to a matrix.
7447         This null space will be removed from the resulting vector whenever
7448         MatMult() is called
7449 
7450    Logically Collective on Mat and MatNullSpace
7451 
7452    Input Parameters:
7453 +  mat - the matrix
7454 -  nullsp - the null space object
7455 
7456    Level: advanced
7457 
7458    Notes:
7459       This null space is used by solvers. Overwrites any previous null space that may have been attached
7460 
7461    Concepts: null space^attaching to matrix
7462 
7463 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace()
7464 @*/
7465 PetscErrorCode  MatSetNullSpace(Mat mat,MatNullSpace nullsp)
7466 {
7467   PetscErrorCode ierr;
7468 
7469   PetscFunctionBegin;
7470   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7471   PetscValidType(mat,1);
7472   PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
7473   MatCheckPreallocated(mat,1);
7474   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
7475   ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr);
7476   mat->nullsp = nullsp;
7477   PetscFunctionReturn(0);
7478 }
7479 
7480 #undef __FUNCT__
7481 #define __FUNCT__ "MatSetNearNullSpace"
7482 /*@
7483    MatSetNearNullSpace - attaches a null space to a matrix.
7484         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.
7485 
7486    Logically Collective on Mat and MatNullSpace
7487 
7488    Input Parameters:
7489 +  mat - the matrix
7490 -  nullsp - the null space object
7491 
7492    Level: advanced
7493 
7494    Notes:
7495       Overwrites any previous near null space that may have been attached
7496 
7497    Concepts: null space^attaching to matrix
7498 
7499 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace()
7500 @*/
7501 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
7502 {
7503   PetscErrorCode ierr;
7504 
7505   PetscFunctionBegin;
7506   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7507   PetscValidType(mat,1);
7508   PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
7509   MatCheckPreallocated(mat,1);
7510   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
7511   ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr);
7512   mat->nearnullsp = nullsp;
7513   PetscFunctionReturn(0);
7514 }
7515 
7516 #undef __FUNCT__
7517 #define __FUNCT__ "MatGetNearNullSpace"
7518 /*@
7519    MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()
7520 
7521    Not Collective
7522 
7523    Input Parameters:
7524 .  mat - the matrix
7525 
7526    Output Parameters:
7527 .  nullsp - the null space object, PETSC_NULL if not set
7528 
7529    Level: developer
7530 
7531    Concepts: null space^attaching to matrix
7532 
7533 .seealso: MatSetNearNullSpace(), MatGetNullSpace()
7534 @*/
7535 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
7536 {
7537   PetscFunctionBegin;
7538   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7539   PetscValidType(mat,1);
7540   PetscValidPointer(nullsp,2);
7541   MatCheckPreallocated(mat,1);
7542   *nullsp = mat->nearnullsp;
7543   PetscFunctionReturn(0);
7544 }
7545 
7546 #undef __FUNCT__
7547 #define __FUNCT__ "MatICCFactor"
7548 /*@C
7549    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
7550 
7551    Collective on Mat
7552 
7553    Input Parameters:
7554 +  mat - the matrix
7555 .  row - row/column permutation
7556 .  fill - expected fill factor >= 1.0
7557 -  level - level of fill, for ICC(k)
7558 
7559    Notes:
7560    Probably really in-place only when level of fill is zero, otherwise allocates
7561    new space to store factored matrix and deletes previous memory.
7562 
7563    Most users should employ the simplified KSP interface for linear solvers
7564    instead of working directly with matrix algebra routines such as this.
7565    See, e.g., KSPCreate().
7566 
7567    Level: developer
7568 
7569    Concepts: matrices^incomplete Cholesky factorization
7570    Concepts: Cholesky factorization
7571 
7572 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
7573 
7574     Developer Note: fortran interface is not autogenerated as the f90
7575     interface defintion cannot be generated correctly [due to MatFactorInfo]
7576 
7577 @*/
7578 PetscErrorCode  MatICCFactor(Mat mat,IS row,const MatFactorInfo* info)
7579 {
7580   PetscErrorCode ierr;
7581 
7582   PetscFunctionBegin;
7583   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7584   PetscValidType(mat,1);
7585   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
7586   PetscValidPointer(info,3);
7587   if (mat->rmap->N != mat->cmap->N) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONG,"matrix must be square");
7588   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7589   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7590   if (!mat->ops->iccfactor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7591   MatCheckPreallocated(mat,1);
7592   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
7593   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
7594   PetscFunctionReturn(0);
7595 }
7596 
7597 #undef __FUNCT__
7598 #define __FUNCT__ "MatSetValuesAdic"
7599 /*@
7600    MatSetValuesAdic - Sets values computed with ADIC automatic differentiation into a matrix.
7601 
7602    Not Collective
7603 
7604    Input Parameters:
7605 +  mat - the matrix
7606 -  v - the values compute with ADIC
7607 
7608    Level: developer
7609 
7610    Notes:
7611      Must call MatSetColoring() before using this routine. Also this matrix must already
7612      have its nonzero pattern determined.
7613 
7614 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7615           MatSetValues(), MatSetColoring(), MatSetValuesAdifor()
7616 @*/
7617 PetscErrorCode  MatSetValuesAdic(Mat mat,void *v)
7618 {
7619   PetscErrorCode ierr;
7620 
7621   PetscFunctionBegin;
7622   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7623   PetscValidType(mat,1);
7624   PetscValidPointer(mat,2);
7625 
7626   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7627   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
7628   if (!mat->ops->setvaluesadic) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7629   ierr = (*mat->ops->setvaluesadic)(mat,v);CHKERRQ(ierr);
7630   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
7631   ierr = MatView_Private(mat);CHKERRQ(ierr);
7632   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
7633   PetscFunctionReturn(0);
7634 }
7635 
7636 
7637 #undef __FUNCT__
7638 #define __FUNCT__ "MatSetColoring"
7639 /*@
7640    MatSetColoring - Sets a coloring used by calls to MatSetValuesAdic()
7641 
7642    Not Collective
7643 
7644    Input Parameters:
7645 +  mat - the matrix
7646 -  coloring - the coloring
7647 
7648    Level: developer
7649 
7650 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7651           MatSetValues(), MatSetValuesAdic()
7652 @*/
7653 PetscErrorCode  MatSetColoring(Mat mat,ISColoring coloring)
7654 {
7655   PetscErrorCode ierr;
7656 
7657   PetscFunctionBegin;
7658   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7659   PetscValidType(mat,1);
7660   PetscValidPointer(coloring,2);
7661 
7662   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7663   if (!mat->ops->setcoloring) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7664   ierr = (*mat->ops->setcoloring)(mat,coloring);CHKERRQ(ierr);
7665   PetscFunctionReturn(0);
7666 }
7667 
7668 #undef __FUNCT__
7669 #define __FUNCT__ "MatSetValuesAdifor"
7670 /*@
7671    MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.
7672 
7673    Not Collective
7674 
7675    Input Parameters:
7676 +  mat - the matrix
7677 .  nl - leading dimension of v
7678 -  v - the values compute with ADIFOR
7679 
7680    Level: developer
7681 
7682    Notes:
7683      Must call MatSetColoring() before using this routine. Also this matrix must already
7684      have its nonzero pattern determined.
7685 
7686 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7687           MatSetValues(), MatSetColoring()
7688 @*/
7689 PetscErrorCode  MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
7690 {
7691   PetscErrorCode ierr;
7692 
7693   PetscFunctionBegin;
7694   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7695   PetscValidType(mat,1);
7696   PetscValidPointer(v,3);
7697 
7698   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7699   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
7700   if (!mat->ops->setvaluesadifor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7701   ierr = (*mat->ops->setvaluesadifor)(mat,nl,v);CHKERRQ(ierr);
7702   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
7703   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
7704   PetscFunctionReturn(0);
7705 }
7706 
7707 #undef __FUNCT__
7708 #define __FUNCT__ "MatDiagonalScaleLocal"
7709 /*@
7710    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
7711          ghosted ones.
7712 
7713    Not Collective
7714 
7715    Input Parameters:
7716 +  mat - the matrix
7717 -  diag = the diagonal values, including ghost ones
7718 
7719    Level: developer
7720 
7721    Notes: Works only for MPIAIJ and MPIBAIJ matrices
7722 
7723 .seealso: MatDiagonalScale()
7724 @*/
7725 PetscErrorCode  MatDiagonalScaleLocal(Mat mat,Vec diag)
7726 {
7727   PetscErrorCode ierr;
7728   PetscMPIInt    size;
7729 
7730   PetscFunctionBegin;
7731   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7732   PetscValidHeaderSpecific(diag,VEC_CLASSID,2);
7733   PetscValidType(mat,1);
7734 
7735   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7736   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
7737   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
7738   if (size == 1) {
7739     PetscInt n,m;
7740     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
7741     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
7742     if (m == n) {
7743       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
7744     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
7745   } else {
7746     ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr);
7747   }
7748   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
7749   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
7750   PetscFunctionReturn(0);
7751 }
7752 
7753 #undef __FUNCT__
7754 #define __FUNCT__ "MatGetInertia"
7755 /*@
7756    MatGetInertia - Gets the inertia from a factored matrix
7757 
7758    Collective on Mat
7759 
7760    Input Parameter:
7761 .  mat - the matrix
7762 
7763    Output Parameters:
7764 +   nneg - number of negative eigenvalues
7765 .   nzero - number of zero eigenvalues
7766 -   npos - number of positive eigenvalues
7767 
7768    Level: advanced
7769 
7770    Notes: Matrix must have been factored by MatCholeskyFactor()
7771 
7772 
7773 @*/
7774 PetscErrorCode  MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
7775 {
7776   PetscErrorCode ierr;
7777 
7778   PetscFunctionBegin;
7779   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7780   PetscValidType(mat,1);
7781   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7782   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
7783   if (!mat->ops->getinertia) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7784   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
7785   PetscFunctionReturn(0);
7786 }
7787 
7788 /* ----------------------------------------------------------------*/
7789 #undef __FUNCT__
7790 #define __FUNCT__ "MatSolves"
7791 /*@C
7792    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
7793 
7794    Neighbor-wise Collective on Mat and Vecs
7795 
7796    Input Parameters:
7797 +  mat - the factored matrix
7798 -  b - the right-hand-side vectors
7799 
7800    Output Parameter:
7801 .  x - the result vectors
7802 
7803    Notes:
7804    The vectors b and x cannot be the same.  I.e., one cannot
7805    call MatSolves(A,x,x).
7806 
7807    Notes:
7808    Most users should employ the simplified KSP interface for linear solvers
7809    instead of working directly with matrix algebra routines such as this.
7810    See, e.g., KSPCreate().
7811 
7812    Level: developer
7813 
7814    Concepts: matrices^triangular solves
7815 
7816 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
7817 @*/
7818 PetscErrorCode  MatSolves(Mat mat,Vecs b,Vecs x)
7819 {
7820   PetscErrorCode ierr;
7821 
7822   PetscFunctionBegin;
7823   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7824   PetscValidType(mat,1);
7825   if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
7826   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7827   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
7828 
7829   if (!mat->ops->solves) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7830   MatCheckPreallocated(mat,1);
7831   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
7832   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
7833   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
7834   PetscFunctionReturn(0);
7835 }
7836 
7837 #undef __FUNCT__
7838 #define __FUNCT__ "MatIsSymmetric"
7839 /*@
7840    MatIsSymmetric - Test whether a matrix is symmetric
7841 
7842    Collective on Mat
7843 
7844    Input Parameter:
7845 +  A - the matrix to test
7846 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
7847 
7848    Output Parameters:
7849 .  flg - the result
7850 
7851    Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
7852 
7853    Level: intermediate
7854 
7855    Concepts: matrix^symmetry
7856 
7857 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
7858 @*/
7859 PetscErrorCode  MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
7860 {
7861   PetscErrorCode ierr;
7862 
7863   PetscFunctionBegin;
7864   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7865   PetscValidPointer(flg,2);
7866 
7867   if (!A->symmetric_set) {
7868     if (!A->ops->issymmetric) {
7869       MatType mattype;
7870       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7871       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7872     }
7873     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
7874     if (!tol) {
7875       A->symmetric_set = PETSC_TRUE;
7876       A->symmetric = *flg;
7877       if (A->symmetric) {
7878 	A->structurally_symmetric_set = PETSC_TRUE;
7879 	A->structurally_symmetric     = PETSC_TRUE;
7880       }
7881     }
7882   } else if (A->symmetric) {
7883     *flg = PETSC_TRUE;
7884   } else if (!tol) {
7885     *flg = PETSC_FALSE;
7886   } else {
7887     if (!A->ops->issymmetric) {
7888       MatType mattype;
7889       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7890       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7891     }
7892     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
7893   }
7894   PetscFunctionReturn(0);
7895 }
7896 
7897 #undef __FUNCT__
7898 #define __FUNCT__ "MatIsHermitian"
7899 /*@
7900    MatIsHermitian - Test whether a matrix is Hermitian
7901 
7902    Collective on Mat
7903 
7904    Input Parameter:
7905 +  A - the matrix to test
7906 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
7907 
7908    Output Parameters:
7909 .  flg - the result
7910 
7911    Level: intermediate
7912 
7913    Concepts: matrix^symmetry
7914 
7915 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
7916           MatIsSymmetricKnown(), MatIsSymmetric()
7917 @*/
7918 PetscErrorCode  MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
7919 {
7920   PetscErrorCode ierr;
7921 
7922   PetscFunctionBegin;
7923   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7924   PetscValidPointer(flg,2);
7925 
7926   if (!A->hermitian_set) {
7927     if (!A->ops->ishermitian) {
7928       MatType mattype;
7929       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7930       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7931     }
7932     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
7933     if (!tol) {
7934       A->hermitian_set = PETSC_TRUE;
7935       A->hermitian = *flg;
7936       if (A->hermitian) {
7937 	A->structurally_symmetric_set = PETSC_TRUE;
7938 	A->structurally_symmetric     = PETSC_TRUE;
7939       }
7940     }
7941   } else if (A->hermitian) {
7942     *flg = PETSC_TRUE;
7943   } else if (!tol) {
7944     *flg = PETSC_FALSE;
7945   } else {
7946     if (!A->ops->ishermitian) {
7947       MatType mattype;
7948       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7949       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7950     }
7951     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
7952   }
7953   PetscFunctionReturn(0);
7954 }
7955 
7956 #undef __FUNCT__
7957 #define __FUNCT__ "MatIsSymmetricKnown"
7958 /*@
7959    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
7960 
7961    Not Collective
7962 
7963    Input Parameter:
7964 .  A - the matrix to check
7965 
7966    Output Parameters:
7967 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
7968 -  flg - the result
7969 
7970    Level: advanced
7971 
7972    Concepts: matrix^symmetry
7973 
7974    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
7975          if you want it explicitly checked
7976 
7977 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
7978 @*/
7979 PetscErrorCode  MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
7980 {
7981   PetscFunctionBegin;
7982   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7983   PetscValidPointer(set,2);
7984   PetscValidPointer(flg,3);
7985   if (A->symmetric_set) {
7986     *set = PETSC_TRUE;
7987     *flg = A->symmetric;
7988   } else {
7989     *set = PETSC_FALSE;
7990   }
7991   PetscFunctionReturn(0);
7992 }
7993 
7994 #undef __FUNCT__
7995 #define __FUNCT__ "MatIsHermitianKnown"
7996 /*@
7997    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
7998 
7999    Not Collective
8000 
8001    Input Parameter:
8002 .  A - the matrix to check
8003 
8004    Output Parameters:
8005 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8006 -  flg - the result
8007 
8008    Level: advanced
8009 
8010    Concepts: matrix^symmetry
8011 
8012    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8013          if you want it explicitly checked
8014 
8015 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8016 @*/
8017 PetscErrorCode  MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8018 {
8019   PetscFunctionBegin;
8020   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8021   PetscValidPointer(set,2);
8022   PetscValidPointer(flg,3);
8023   if (A->hermitian_set) {
8024     *set = PETSC_TRUE;
8025     *flg = A->hermitian;
8026   } else {
8027     *set = PETSC_FALSE;
8028   }
8029   PetscFunctionReturn(0);
8030 }
8031 
8032 #undef __FUNCT__
8033 #define __FUNCT__ "MatIsStructurallySymmetric"
8034 /*@
8035    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
8036 
8037    Collective on Mat
8038 
8039    Input Parameter:
8040 .  A - the matrix to test
8041 
8042    Output Parameters:
8043 .  flg - the result
8044 
8045    Level: intermediate
8046 
8047    Concepts: matrix^symmetry
8048 
8049 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8050 @*/
8051 PetscErrorCode  MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
8052 {
8053   PetscErrorCode ierr;
8054 
8055   PetscFunctionBegin;
8056   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8057   PetscValidPointer(flg,2);
8058   if (!A->structurally_symmetric_set) {
8059     if (!A->ops->isstructurallysymmetric) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8060     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
8061     A->structurally_symmetric_set = PETSC_TRUE;
8062   }
8063   *flg = A->structurally_symmetric;
8064   PetscFunctionReturn(0);
8065 }
8066 
8067 #undef __FUNCT__
8068 #define __FUNCT__ "MatStashGetInfo"
8069 extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
8070 /*@
8071    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8072        to be communicated to other processors during the MatAssemblyBegin/End() process
8073 
8074     Not collective
8075 
8076    Input Parameter:
8077 .   vec - the vector
8078 
8079    Output Parameters:
8080 +   nstash   - the size of the stash
8081 .   reallocs - the number of additional mallocs incurred.
8082 .   bnstash   - the size of the block stash
8083 -   breallocs - the number of additional mallocs incurred.in the block stash
8084 
8085    Level: advanced
8086 
8087 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
8088 
8089 @*/
8090 PetscErrorCode  MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8091 {
8092   PetscErrorCode ierr;
8093 
8094   PetscFunctionBegin;
8095   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
8096   ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
8097   PetscFunctionReturn(0);
8098 }
8099 
8100 #undef __FUNCT__
8101 #define __FUNCT__ "MatGetVecs"
8102 /*@C
8103    MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same
8104      parallel layout
8105 
8106    Collective on Mat
8107 
8108    Input Parameter:
8109 .  mat - the matrix
8110 
8111    Output Parameter:
8112 +   right - (optional) vector that the matrix can be multiplied against
8113 -   left - (optional) vector that the matrix vector product can be stored in
8114 
8115   Level: advanced
8116 
8117 .seealso: MatCreate()
8118 @*/
8119 PetscErrorCode  MatGetVecs(Mat mat,Vec *right,Vec *left)
8120 {
8121   PetscErrorCode ierr;
8122 
8123   PetscFunctionBegin;
8124   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8125   PetscValidType(mat,1);
8126   MatCheckPreallocated(mat,1);
8127   if (mat->ops->getvecs) {
8128     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
8129   } else {
8130     PetscMPIInt size;
8131     ierr = MPI_Comm_size(((PetscObject)mat)->comm, &size);CHKERRQ(ierr);
8132     if (right) {
8133       ierr = VecCreate(((PetscObject)mat)->comm,right);CHKERRQ(ierr);
8134       ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8135       ierr = VecSetBlockSize(*right,mat->rmap->bs);CHKERRQ(ierr);
8136       ierr = VecSetType(*right,VECSTANDARD);CHKERRQ(ierr);
8137       ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr);
8138     }
8139     if (left) {
8140       ierr = VecCreate(((PetscObject)mat)->comm,left);CHKERRQ(ierr);
8141       ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8142       ierr = VecSetBlockSize(*left,mat->rmap->bs);CHKERRQ(ierr);
8143       ierr = VecSetType(*left,VECSTANDARD);CHKERRQ(ierr);
8144       ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr);
8145     }
8146   }
8147   PetscFunctionReturn(0);
8148 }
8149 
8150 #undef __FUNCT__
8151 #define __FUNCT__ "MatFactorInfoInitialize"
8152 /*@C
8153    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8154      with default values.
8155 
8156    Not Collective
8157 
8158    Input Parameters:
8159 .    info - the MatFactorInfo data structure
8160 
8161 
8162    Notes: The solvers are generally used through the KSP and PC objects, for example
8163           PCLU, PCILU, PCCHOLESKY, PCICC
8164 
8165    Level: developer
8166 
8167 .seealso: MatFactorInfo
8168 
8169     Developer Note: fortran interface is not autogenerated as the f90
8170     interface defintion cannot be generated correctly [due to MatFactorInfo]
8171 
8172 @*/
8173 
8174 PetscErrorCode  MatFactorInfoInitialize(MatFactorInfo *info)
8175 {
8176   PetscErrorCode ierr;
8177 
8178   PetscFunctionBegin;
8179   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
8180   PetscFunctionReturn(0);
8181 }
8182 
8183 #undef __FUNCT__
8184 #define __FUNCT__ "MatPtAP"
8185 /*@
8186    MatPtAP - Creates the matrix product C = P^T * A * P
8187 
8188    Neighbor-wise Collective on Mat
8189 
8190    Input Parameters:
8191 +  A - the matrix
8192 .  P - the projection matrix
8193 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8194 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P))
8195 
8196    Output Parameters:
8197 .  C - the product matrix
8198 
8199    Notes:
8200    C will be created and must be destroyed by the user with MatDestroy().
8201 
8202    This routine is currently only implemented for pairs of AIJ matrices and classes
8203    which inherit from AIJ.
8204 
8205    Level: intermediate
8206 
8207 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
8208 @*/
8209 PetscErrorCode  MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
8210 {
8211   PetscErrorCode ierr;
8212   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8213   PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
8214   PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=PETSC_NULL;
8215   PetscBool      viatranspose=PETSC_FALSE,viamatmatmatmult=PETSC_FALSE;
8216 
8217   PetscFunctionBegin;
8218   ierr = PetscOptionsGetBool(((PetscObject)A)->prefix,"-matptap_viatranspose",&viatranspose,PETSC_NULL);CHKERRQ(ierr);
8219   ierr = PetscOptionsGetBool(((PetscObject)A)->prefix,"-matptap_viamatmatmatmult",&viamatmatmatmult,PETSC_NULL);CHKERRQ(ierr);
8220 
8221   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8222   PetscValidType(A,1);
8223   MatCheckPreallocated(A,1);
8224   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8225   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8226   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
8227   PetscValidType(P,2);
8228   MatCheckPreallocated(P,2);
8229   if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8230   if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8231 
8232   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);
8233   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8234 
8235   if (scall == MAT_REUSE_MATRIX) {
8236     PetscValidPointer(*C,5);
8237     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
8238     ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
8239     if (viatranspose || viamatmatmatmult){
8240       Mat Pt;
8241       ierr = MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);CHKERRQ(ierr);
8242       if (viamatmatmatmult){
8243         ierr = MatMatMatMult(Pt,A,P,scall,fill,C);CHKERRQ(ierr);
8244       } else {
8245         Mat AP;
8246         ierr = MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);CHKERRQ(ierr);
8247         ierr = MatMatMult(Pt,AP,scall,fill,C);CHKERRQ(ierr);
8248         ierr = MatDestroy(&AP);CHKERRQ(ierr);
8249       }
8250       ierr = MatDestroy(&Pt);CHKERRQ(ierr);
8251     } else {
8252       ierr = (*(*C)->ops->ptap)(A,P,scall,fill,C);CHKERRQ(ierr);
8253     }
8254     ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
8255     PetscFunctionReturn(0);
8256   }
8257 
8258   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8259   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8260 
8261   fA = A->ops->ptap;
8262   fP = P->ops->ptap;
8263   if (fP == fA) {
8264     if (!fA) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name);
8265     ptap = fA;
8266   } else {
8267     /* dispatch based on the type of A and P from their PetscObject's PetscFLists. */
8268     char  ptapname[256];
8269     ierr = PetscStrcpy(ptapname,"MatPtAP_");CHKERRQ(ierr);
8270     ierr = PetscStrcat(ptapname,((PetscObject)A)->type_name);CHKERRQ(ierr);
8271     ierr = PetscStrcat(ptapname,"_");CHKERRQ(ierr);
8272     ierr = PetscStrcat(ptapname,((PetscObject)P)->type_name);CHKERRQ(ierr);
8273     ierr = PetscStrcat(ptapname,"_C");CHKERRQ(ierr); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
8274     ierr = PetscObjectQueryFunction((PetscObject)P,ptapname,(void (**)(void))&ptap);CHKERRQ(ierr);
8275     if (!ptap) {
8276       /* dual dispatch using MatQueryOp */
8277       ierr = MatQueryOp(((PetscObject)A)->comm, (PetscVoidFunction*)(&ptap), "MatPtAP",2,((PetscObject)A)->type_name,((PetscObject)P)->type_name); CHKERRQ(ierr);
8278       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);
8279     }
8280   }
8281 
8282   ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
8283   if (viatranspose || viamatmatmatmult) {
8284     Mat Pt;
8285     ierr = MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);CHKERRQ(ierr);
8286     if (viamatmatmatmult){
8287       ierr = MatMatMatMult(Pt,A,P,scall,fill,C);CHKERRQ(ierr);
8288       ierr = PetscInfo(*C,"MatPtAP via MatMatMatMult\n");CHKERRQ(ierr);
8289     } else {
8290       Mat AP;
8291       ierr = MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);CHKERRQ(ierr);
8292       ierr = MatMatMult(Pt,AP,scall,fill,C);CHKERRQ(ierr);
8293       ierr = MatDestroy(&AP);CHKERRQ(ierr);
8294       ierr = PetscInfo(*C,"MatPtAP via MatTranspose and MatMatMult\n");CHKERRQ(ierr);
8295     }
8296     ierr = MatDestroy(&Pt);CHKERRQ(ierr);
8297   } else {
8298     ierr = (*ptap)(A,P,scall,fill,C);CHKERRQ(ierr);
8299   }
8300   ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
8301   PetscFunctionReturn(0);
8302 }
8303 
8304 #undef __FUNCT__
8305 #define __FUNCT__ "MatPtAPNumeric"
8306 /*@
8307    MatPtAPNumeric - Computes the matrix product C = P^T * A * P
8308 
8309    Neighbor-wise Collective on Mat
8310 
8311    Input Parameters:
8312 +  A - the matrix
8313 -  P - the projection matrix
8314 
8315    Output Parameters:
8316 .  C - the product matrix
8317 
8318    Notes:
8319    C must have been created by calling MatPtAPSymbolic and must be destroyed by
8320    the user using MatDeatroy().
8321 
8322    This routine is currently only implemented for pairs of AIJ matrices and classes
8323    which inherit from AIJ.  C will be of type MATAIJ.
8324 
8325    Level: intermediate
8326 
8327 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
8328 @*/
8329 PetscErrorCode  MatPtAPNumeric(Mat A,Mat P,Mat C)
8330 {
8331   PetscErrorCode ierr;
8332 
8333   PetscFunctionBegin;
8334   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8335   PetscValidType(A,1);
8336   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8337   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8338   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
8339   PetscValidType(P,2);
8340   MatCheckPreallocated(P,2);
8341   if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8342   if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8343   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
8344   PetscValidType(C,3);
8345   MatCheckPreallocated(C,3);
8346   if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8347   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);
8348   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);
8349   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);
8350   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);
8351   MatCheckPreallocated(A,1);
8352 
8353   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
8354   ierr = (*C->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr);
8355   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
8356   PetscFunctionReturn(0);
8357 }
8358 
8359 #undef __FUNCT__
8360 #define __FUNCT__ "MatPtAPSymbolic"
8361 /*@
8362    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P
8363 
8364    Neighbor-wise Collective on Mat
8365 
8366    Input Parameters:
8367 +  A - the matrix
8368 -  P - the projection matrix
8369 
8370    Output Parameters:
8371 .  C - the (i,j) structure of the product matrix
8372 
8373    Notes:
8374    C will be created and must be destroyed by the user with MatDestroy().
8375 
8376    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
8377    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
8378    this (i,j) structure by calling MatPtAPNumeric().
8379 
8380    Level: intermediate
8381 
8382 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
8383 @*/
8384 PetscErrorCode  MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
8385 {
8386   PetscErrorCode ierr;
8387 
8388   PetscFunctionBegin;
8389   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8390   PetscValidType(A,1);
8391   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8392   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8393   if (fill <1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8394   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
8395   PetscValidType(P,2);
8396   MatCheckPreallocated(P,2);
8397   if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8398   if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8399   PetscValidPointer(C,3);
8400 
8401   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);
8402   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);
8403   MatCheckPreallocated(A,1);
8404   ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
8405   ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr);
8406   ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
8407 
8408   /* ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); NO! this is not always true -ma */
8409   PetscFunctionReturn(0);
8410 }
8411 
8412 #undef __FUNCT__
8413 #define __FUNCT__ "MatRARt"
8414 /*@
8415    MatRARt - Creates the matrix product C = R * A * R^T
8416 
8417    Neighbor-wise Collective on Mat
8418 
8419    Input Parameters:
8420 +  A - the matrix
8421 .  R - the projection matrix
8422 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8423 -  fill - expected fill as ratio of nnz(C)/nnz(A)
8424 
8425    Output Parameters:
8426 .  C - the product matrix
8427 
8428    Notes:
8429    C will be created and must be destroyed by the user with MatDestroy().
8430 
8431    This routine is currently only implemented for pairs of AIJ matrices and classes
8432    which inherit from AIJ.
8433 
8434    Level: intermediate
8435 
8436 .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
8437 @*/
8438 PetscErrorCode  MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
8439 {
8440   PetscErrorCode ierr;
8441 
8442   PetscFunctionBegin;
8443   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8444   PetscValidType(A,1);
8445   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8446   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8447   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
8448   PetscValidType(R,2);
8449   MatCheckPreallocated(R,2);
8450   if (!R->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8451   if (R->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8452   PetscValidPointer(C,3);
8453   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);
8454   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8455   MatCheckPreallocated(A,1);
8456 
8457   if (!A->ops->rart) {
8458     MatType mattype;
8459     ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8460     SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix of type <%s> does not support RARt",mattype);
8461   }
8462   ierr = PetscLogEventBegin(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
8463   ierr = (*A->ops->rart)(A,R,scall,fill,C);CHKERRQ(ierr);
8464   ierr = PetscLogEventEnd(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
8465   PetscFunctionReturn(0);
8466 }
8467 
8468 #undef __FUNCT__
8469 #define __FUNCT__ "MatRARtNumeric"
8470 /*@
8471    MatRARtNumeric - Computes the matrix product C = R * A * R^T
8472 
8473    Neighbor-wise Collective on Mat
8474 
8475    Input Parameters:
8476 +  A - the matrix
8477 -  R - the projection matrix
8478 
8479    Output Parameters:
8480 .  C - the product matrix
8481 
8482    Notes:
8483    C must have been created by calling MatRARtSymbolic and must be destroyed by
8484    the user using MatDeatroy().
8485 
8486    This routine is currently only implemented for pairs of AIJ matrices and classes
8487    which inherit from AIJ.  C will be of type MATAIJ.
8488 
8489    Level: intermediate
8490 
8491 .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
8492 @*/
8493 PetscErrorCode  MatRARtNumeric(Mat A,Mat R,Mat C)
8494 {
8495   PetscErrorCode ierr;
8496 
8497   PetscFunctionBegin;
8498   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8499   PetscValidType(A,1);
8500   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8501   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8502   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
8503   PetscValidType(R,2);
8504   MatCheckPreallocated(R,2);
8505   if (!R->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8506   if (R->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8507   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
8508   PetscValidType(C,3);
8509   MatCheckPreallocated(C,3);
8510   if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8511   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);
8512   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);
8513   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);
8514   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);
8515   MatCheckPreallocated(A,1);
8516 
8517   ierr = PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
8518   ierr = (*A->ops->rartnumeric)(A,R,C);CHKERRQ(ierr);
8519   ierr = PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
8520   PetscFunctionReturn(0);
8521 }
8522 
8523 #undef __FUNCT__
8524 #define __FUNCT__ "MatRARtSymbolic"
8525 /*@
8526    MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T
8527 
8528    Neighbor-wise Collective on Mat
8529 
8530    Input Parameters:
8531 +  A - the matrix
8532 -  R - the projection matrix
8533 
8534    Output Parameters:
8535 .  C - the (i,j) structure of the product matrix
8536 
8537    Notes:
8538    C will be created and must be destroyed by the user with MatDestroy().
8539 
8540    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
8541    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
8542    this (i,j) structure by calling MatRARtNumeric().
8543 
8544    Level: intermediate
8545 
8546 .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
8547 @*/
8548 PetscErrorCode  MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
8549 {
8550   PetscErrorCode ierr;
8551 
8552   PetscFunctionBegin;
8553   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8554   PetscValidType(A,1);
8555   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8556   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8557   if (fill <1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8558   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
8559   PetscValidType(R,2);
8560   MatCheckPreallocated(R,2);
8561   if (!R->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8562   if (R->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8563   PetscValidPointer(C,3);
8564 
8565   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);
8566   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);
8567   MatCheckPreallocated(A,1);
8568   ierr = PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
8569   ierr = (*A->ops->rartsymbolic)(A,R,fill,C);CHKERRQ(ierr);
8570   ierr = PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
8571 
8572   ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr);
8573   PetscFunctionReturn(0);
8574 }
8575 
8576 extern PetscErrorCode MatQueryOp(MPI_Comm comm, void (**function)(void), const char op[], PetscInt numArgs, ...);
8577 
8578 #undef __FUNCT__
8579 #define __FUNCT__ "MatMatMult"
8580 /*@
8581    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
8582 
8583    Neighbor-wise Collective on Mat
8584 
8585    Input Parameters:
8586 +  A - the left matrix
8587 .  B - the right matrix
8588 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8589 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
8590           if the result is a dense matrix this is irrelevent
8591 
8592    Output Parameters:
8593 .  C - the product matrix
8594 
8595    Notes:
8596    Unless scall is MAT_REUSE_MATRIX C will be created.
8597 
8598    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8599 
8600    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8601    actually needed.
8602 
8603    If you have many matrices with the same non-zero structure to multiply, you
8604    should either
8605 $   1) use MAT_REUSE_MATRIX in all calls but the first or
8606 $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
8607 
8608    Level: intermediate
8609 
8610 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(),  MatMatTransposeMult(), MatPtAP()
8611 @*/
8612 PetscErrorCode  MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8613 {
8614   PetscErrorCode ierr;
8615   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8616   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8617   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat *)=PETSC_NULL;
8618 
8619   PetscFunctionBegin;
8620   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8621   PetscValidType(A,1);
8622   MatCheckPreallocated(A,1);
8623   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8624   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8625   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8626   PetscValidType(B,2);
8627   MatCheckPreallocated(B,2);
8628   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8629   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8630   PetscValidPointer(C,3);
8631   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);
8632   if (scall == MAT_REUSE_MATRIX) {
8633     PetscValidPointer(*C,5);
8634     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
8635     ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
8636     ierr = (*(*C)->ops->matmult)(A,B,scall,fill,C);CHKERRQ(ierr);
8637     ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
8638     PetscFunctionReturn(0);
8639   }
8640   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8641   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8642 
8643   fA = A->ops->matmult;
8644   fB = B->ops->matmult;
8645   if (fB == fA) {
8646     if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
8647     mult = fB;
8648   } else {
8649     /* dispatch based on the type of A and B from their PetscObject's PetscFLists. */
8650     char  multname[256];
8651     ierr = PetscStrcpy(multname,"MatMatMult_");CHKERRQ(ierr);
8652     ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr);
8653     ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);
8654     ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr);
8655     ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
8656     ierr = PetscObjectQueryFunction((PetscObject)B,multname,(void (**)(void))&mult);CHKERRQ(ierr);
8657     if (!mult) {
8658       /* dual dispatch using MatQueryOp */
8659       ierr = MatQueryOp(((PetscObject)A)->comm, (PetscVoidFunction*)(&mult), "MatMatMult",2,((PetscObject)A)->type_name,((PetscObject)B)->type_name); CHKERRQ(ierr);
8660       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);
8661     }
8662   }
8663   ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
8664   ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr);
8665   ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
8666   PetscFunctionReturn(0);
8667 }
8668 
8669 #undef __FUNCT__
8670 #define __FUNCT__ "MatMatMultSymbolic"
8671 /*@
8672    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
8673    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().
8674 
8675    Neighbor-wise Collective on Mat
8676 
8677    Input Parameters:
8678 +  A - the left matrix
8679 .  B - the right matrix
8680 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
8681       if C is a dense matrix this is irrelevent
8682 
8683    Output Parameters:
8684 .  C - the product matrix
8685 
8686    Notes:
8687    Unless scall is MAT_REUSE_MATRIX C will be created.
8688 
8689    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8690    actually needed.
8691 
8692    This routine is currently implemented for
8693     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
8694     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8695     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
8696 
8697    Level: intermediate
8698 
8699    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
8700      We should incorporate them into PETSc.
8701 
8702 .seealso: MatMatMult(), MatMatMultNumeric()
8703 @*/
8704 PetscErrorCode  MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
8705 {
8706   PetscErrorCode ierr;
8707   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat *);
8708   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat *);
8709   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat *)=PETSC_NULL;
8710 
8711   PetscFunctionBegin;
8712   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8713   PetscValidType(A,1);
8714   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8715   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8716 
8717   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8718   PetscValidType(B,2);
8719   MatCheckPreallocated(B,2);
8720   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8721   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8722   PetscValidPointer(C,3);
8723 
8724   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);
8725   if (fill == PETSC_DEFAULT) fill = 2.0;
8726   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8727   MatCheckPreallocated(A,1);
8728 
8729   Asymbolic = A->ops->matmultsymbolic;
8730   Bsymbolic = B->ops->matmultsymbolic;
8731   if (Asymbolic == Bsymbolic) {
8732     if (!Bsymbolic) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
8733     symbolic = Bsymbolic;
8734   } else { /* dispatch based on the type of A and B */
8735     char  symbolicname[256];
8736     ierr = PetscStrcpy(symbolicname,"MatMatMultSymbolic_");CHKERRQ(ierr);
8737     ierr = PetscStrcat(symbolicname,((PetscObject)A)->type_name);CHKERRQ(ierr);
8738     ierr = PetscStrcat(symbolicname,"_");CHKERRQ(ierr);
8739     ierr = PetscStrcat(symbolicname,((PetscObject)B)->type_name);CHKERRQ(ierr);
8740     ierr = PetscStrcat(symbolicname,"_C");CHKERRQ(ierr);
8741     ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,(void (**)(void))&symbolic);CHKERRQ(ierr);
8742     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);
8743   }
8744   ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
8745   ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr);
8746   ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
8747   PetscFunctionReturn(0);
8748 }
8749 
8750 #undef __FUNCT__
8751 #define __FUNCT__ "MatMatMultNumeric"
8752 /*@
8753    MatMatMultNumeric - Performs the numeric matrix-matrix product.
8754    Call this routine after first calling MatMatMultSymbolic().
8755 
8756    Neighbor-wise Collective on Mat
8757 
8758    Input Parameters:
8759 +  A - the left matrix
8760 -  B - the right matrix
8761 
8762    Output Parameters:
8763 .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
8764 
8765    Notes:
8766    C must have been created with MatMatMultSymbolic().
8767 
8768    This routine is currently implemented for
8769     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
8770     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8771     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
8772 
8773    Level: intermediate
8774 
8775 .seealso: MatMatMult(), MatMatMultSymbolic()
8776 @*/
8777 PetscErrorCode  MatMatMultNumeric(Mat A,Mat B,Mat C)
8778 {
8779   PetscErrorCode ierr;
8780   PetscErrorCode (*Anumeric)(Mat,Mat,Mat);
8781   PetscErrorCode (*Bnumeric)(Mat,Mat,Mat);
8782   PetscErrorCode (*numeric)(Mat,Mat,Mat)=PETSC_NULL;
8783 
8784   PetscFunctionBegin;
8785   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8786   PetscValidType(A,1);
8787   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8788   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8789 
8790   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8791   PetscValidType(B,2);
8792   MatCheckPreallocated(B,2);
8793   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8794   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8795 
8796   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
8797   PetscValidType(C,3);
8798   MatCheckPreallocated(C,3);
8799   if (!C->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8800   if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8801 
8802   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);
8803   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);
8804   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);
8805   MatCheckPreallocated(A,1);
8806 
8807   Anumeric = A->ops->matmultnumeric;
8808   Bnumeric = B->ops->matmultnumeric;
8809   if (Anumeric == Bnumeric) {
8810     if (!Bnumeric) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMultNumeric not supported for B of type %s",((PetscObject)B)->type_name);
8811     numeric = Bnumeric;
8812   } else {
8813     char  numericname[256];
8814     ierr = PetscStrcpy(numericname,"MatMatMultNumeric_");CHKERRQ(ierr);
8815     ierr = PetscStrcat(numericname,((PetscObject)A)->type_name);CHKERRQ(ierr);
8816     ierr = PetscStrcat(numericname,"_");CHKERRQ(ierr);
8817     ierr = PetscStrcat(numericname,((PetscObject)B)->type_name);CHKERRQ(ierr);
8818     ierr = PetscStrcat(numericname,"_C");CHKERRQ(ierr);
8819     ierr = PetscObjectQueryFunction((PetscObject)B,numericname,(void (**)(void))&numeric);CHKERRQ(ierr);
8820     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);
8821   }
8822   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
8823   ierr = (*numeric)(A,B,C);CHKERRQ(ierr);
8824   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
8825   PetscFunctionReturn(0);
8826 }
8827 
8828 #undef __FUNCT__
8829 #define __FUNCT__ "MatMatTransposeMult"
8830 /*@
8831    MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.
8832 
8833    Neighbor-wise Collective on Mat
8834 
8835    Input Parameters:
8836 +  A - the left matrix
8837 .  B - the right matrix
8838 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8839 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
8840 
8841    Output Parameters:
8842 .  C - the product matrix
8843 
8844    Notes:
8845    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
8846 
8847    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8848 
8849   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8850    actually needed.
8851 
8852    This routine is currently only implemented for pairs of SeqAIJ matrices.  C will be of type MATSEQAIJ.
8853 
8854    Level: intermediate
8855 
8856 .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
8857 @*/
8858 PetscErrorCode  MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8859 {
8860   PetscErrorCode ierr;
8861   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8862   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8863 
8864   PetscFunctionBegin;
8865   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8866   PetscValidType(A,1);
8867   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8868   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8869   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8870   PetscValidType(B,2);
8871   MatCheckPreallocated(B,2);
8872   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8873   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8874   PetscValidPointer(C,3);
8875   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);
8876   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8877   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8878   MatCheckPreallocated(A,1);
8879 
8880   fA = A->ops->mattransposemult;
8881   if (!fA) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
8882   fB = B->ops->mattransposemult;
8883   if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
8884   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);
8885 
8886   if (scall == MAT_INITIAL_MATRIX) {
8887     ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
8888     ierr = (*A->ops->mattransposemultsymbolic)(A,B,fill,C);CHKERRQ(ierr);
8889     ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
8890   }
8891   ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
8892   ierr = (*A->ops->mattransposemultnumeric)(A,B,*C);CHKERRQ(ierr);
8893   ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
8894   PetscFunctionReturn(0);
8895 }
8896 
8897 #undef __FUNCT__
8898 #define __FUNCT__ "MatTransposeMatMult"
8899 /*@
8900    MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.
8901 
8902    Neighbor-wise Collective on Mat
8903 
8904    Input Parameters:
8905 +  A - the left matrix
8906 .  B - the right matrix
8907 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8908 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
8909 
8910    Output Parameters:
8911 .  C - the product matrix
8912 
8913    Notes:
8914    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
8915 
8916    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8917 
8918   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8919    actually needed.
8920 
8921    This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
8922    which inherit from SeqAIJ.  C will be of same type as the input matrices.
8923 
8924    Level: intermediate
8925 
8926 .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
8927 @*/
8928 PetscErrorCode  MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8929 {
8930   PetscErrorCode ierr;
8931   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8932   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8933   PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*);
8934 
8935   PetscFunctionBegin;
8936   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8937   PetscValidType(A,1);
8938   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8939   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8940   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8941   PetscValidType(B,2);
8942   MatCheckPreallocated(B,2);
8943   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8944   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8945   PetscValidPointer(C,3);
8946   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);
8947   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8948   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8949   MatCheckPreallocated(A,1);
8950 
8951   fA = A->ops->transposematmult;
8952   if (!fA) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
8953   fB = B->ops->transposematmult;
8954   if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatTransposeMatMult not supported for B of type %s",((PetscObject)B)->type_name);
8955   if (fB==fA) {
8956     transposematmult = fA;
8957   } else {
8958     /* dual dispatch using MatQueryOp */
8959     ierr = MatQueryOp(((PetscObject)A)->comm, (PetscVoidFunction*)(&transposematmult), "MatTansposeMatMult",2,((PetscObject)A)->type_name,((PetscObject)B)->type_name); CHKERRQ(ierr);
8960     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);
8961   }
8962   ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
8963   ierr = (*transposematmult)(A,B,scall,fill,C);CHKERRQ(ierr);
8964   ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
8965   PetscFunctionReturn(0);
8966 }
8967 
8968 #undef __FUNCT__
8969 #define __FUNCT__ "MatMatMatMult"
8970 /*@
8971    MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.
8972 
8973    Neighbor-wise Collective on Mat
8974 
8975    Input Parameters:
8976 +  A - the left matrix
8977 .  B - the middle matrix
8978 .  C - the right matrix
8979 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8980 -  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
8981           if the result is a dense matrix this is irrelevent
8982 
8983    Output Parameters:
8984 .  D - the product matrix
8985 
8986    Notes:
8987    Unless scall is MAT_REUSE_MATRIX D will be created.
8988 
8989    MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call
8990 
8991    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8992    actually needed.
8993 
8994    If you have many matrices with the same non-zero structure to multiply, you
8995    should either
8996 $   1) use MAT_REUSE_MATRIX in all calls but the first or
8997 $   2) call MatMatMatMultSymbolic() once and then MatMatMatMultNumeric() for each product needed
8998 
8999    Level: intermediate
9000 
9001 .seealso: MatMatMult, MatPtAP()
9002 @*/
9003 PetscErrorCode  MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
9004 {
9005   PetscErrorCode ierr;
9006   PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9007   PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9008   PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9009   PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat *)=PETSC_NULL;
9010 
9011   PetscFunctionBegin;
9012   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9013   PetscValidType(A,1);
9014   MatCheckPreallocated(A,1);
9015   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9016   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9017   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9018   PetscValidType(B,2);
9019   MatCheckPreallocated(B,2);
9020   if (!B->assembled) SETERRQ(((PetscObject)B)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9021   if (B->factortype) SETERRQ(((PetscObject)B)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9022   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9023   PetscValidPointer(C,3);
9024   MatCheckPreallocated(C,3);
9025   if (!C->assembled) SETERRQ(((PetscObject)C)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9026   if (C->factortype) SETERRQ(((PetscObject)C)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9027   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);
9028   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);
9029   if (scall == MAT_REUSE_MATRIX) {
9030     PetscValidPointer(*D,6);
9031     PetscValidHeaderSpecific(*D,MAT_CLASSID,6);
9032     ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9033     ierr = (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
9034     ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9035     PetscFunctionReturn(0);
9036   }
9037   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9038   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
9039 
9040   fA = A->ops->matmatmult;
9041   fB = B->ops->matmatmult;
9042   fC = C->ops->matmatmult;
9043   if (fA == fB && fA == fC) {
9044     if (!fA) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9045     mult = fA;
9046   } else {
9047     /* dispatch based on the type of A, B and C from their PetscObject's PetscFLists. */
9048     char  multname[256];
9049     ierr = PetscStrcpy(multname,"MatMatMatMult_");CHKERRQ(ierr);
9050     ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr);
9051     ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);
9052     ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr);
9053     ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);
9054     ierr = PetscStrcat(multname,((PetscObject)C)->type_name);CHKERRQ(ierr);
9055     ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr);
9056     ierr = PetscObjectQueryFunction((PetscObject)B,multname,(void (**)(void))&mult);CHKERRQ(ierr);
9057     if (!mult) {
9058       /* dual dispatch using MatQueryOp */
9059       ierr = MatQueryOp(((PetscObject)A)->comm, (PetscVoidFunction*)(&mult), "MatMatMatMult",3,((PetscObject)A)->type_name,((PetscObject)B)->type_name,((PetscObject)C)->type_name); CHKERRQ(ierr);
9060       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);
9061     }
9062   }
9063   ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9064   ierr = (*mult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
9065   ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9066   PetscFunctionReturn(0);
9067 }
9068 
9069 #undef __FUNCT__
9070 #define __FUNCT__ "MatGetRedundantMatrix"
9071 /*@C
9072    MatGetRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
9073 
9074    Collective on Mat
9075 
9076    Input Parameters:
9077 +  mat - the matrix
9078 .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
9079 .  subcomm - MPI communicator split from the communicator where mat resides in
9080 .  mlocal_red - number of local rows of the redundant matrix
9081 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9082 
9083    Output Parameter:
9084 .  matredundant - redundant matrix
9085 
9086    Notes:
9087    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
9088    original matrix has not changed from that last call to MatGetRedundantMatrix().
9089 
9090    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
9091    calling it.
9092 
9093    Only MPIAIJ matrix is supported.
9094 
9095    Level: advanced
9096 
9097    Concepts: subcommunicator
9098    Concepts: duplicate matrix
9099 
9100 .seealso: MatDestroy()
9101 @*/
9102 PetscErrorCode  MatGetRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,PetscInt mlocal_red,MatReuse reuse,Mat *matredundant)
9103 {
9104   PetscErrorCode ierr;
9105 
9106   PetscFunctionBegin;
9107   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9108   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
9109     PetscValidPointer(*matredundant,6);
9110     PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,6);
9111   }
9112   if (!mat->ops->getredundantmatrix) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
9113   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9114   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9115   MatCheckPreallocated(mat,1);
9116 
9117   ierr = PetscLogEventBegin(MAT_GetRedundantMatrix,mat,0,0,0);CHKERRQ(ierr);
9118   ierr = (*mat->ops->getredundantmatrix)(mat,nsubcomm,subcomm,mlocal_red,reuse,matredundant);CHKERRQ(ierr);
9119   ierr = PetscLogEventEnd(MAT_GetRedundantMatrix,mat,0,0,0);CHKERRQ(ierr);
9120   PetscFunctionReturn(0);
9121 }
9122 
9123 #undef __FUNCT__
9124 #define __FUNCT__ "MatGetMultiProcBlock"
9125 /*@C
9126    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
9127    a given 'mat' object. Each submatrix can span multiple procs.
9128 
9129    Collective on Mat
9130 
9131    Input Parameters:
9132 +  mat - the matrix
9133 .  subcomm - the subcommunicator obtained by com_split(comm)
9134 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9135 
9136    Output Parameter:
9137 .  subMat - 'parallel submatrices each spans a given subcomm
9138 
9139   Notes:
9140   The submatrix partition across processors is dicated by 'subComm' a
9141   communicator obtained by com_split(comm). The comm_split
9142   is not restriced to be grouped with consequitive original ranks.
9143 
9144   Due the comm_split() usage, the parallel layout of the submatrices
9145   map directly to the layout of the original matrix [wrt the local
9146   row,col partitioning]. So the original 'DiagonalMat' naturally maps
9147   into the 'DiagonalMat' of the subMat, hence it is used directly from
9148   the subMat. However the offDiagMat looses some columns - and this is
9149   reconstructed with MatSetValues()
9150 
9151   Level: advanced
9152 
9153   Concepts: subcommunicator
9154   Concepts: submatrices
9155 
9156 .seealso: MatGetSubMatrices()
9157 @*/
9158 PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat* subMat)
9159 {
9160   PetscErrorCode ierr;
9161   PetscMPIInt    commsize,subCommSize;
9162 
9163   PetscFunctionBegin;
9164   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&commsize);CHKERRQ(ierr);
9165   ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr);
9166   if (subCommSize > commsize) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
9167 
9168   ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
9169   ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr);
9170   ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
9171   PetscFunctionReturn(0);
9172 }
9173 
9174 #undef __FUNCT__
9175 #define __FUNCT__ "MatGetLocalSubMatrix"
9176 /*@
9177    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
9178 
9179    Not Collective
9180 
9181    Input Arguments:
9182    mat - matrix to extract local submatrix from
9183    isrow - local row indices for submatrix
9184    iscol - local column indices for submatrix
9185 
9186    Output Arguments:
9187    submat - the submatrix
9188 
9189    Level: intermediate
9190 
9191    Notes:
9192    The submat should be returned with MatRestoreLocalSubMatrix().
9193 
9194    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
9195    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
9196 
9197    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
9198    MatSetValuesBlockedLocal() will also be implemented.
9199 
9200 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef()
9201 @*/
9202 PetscErrorCode  MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9203 {
9204   PetscErrorCode ierr;
9205 
9206   PetscFunctionBegin;
9207   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9208   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
9209   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
9210   PetscCheckSameComm(isrow,2,iscol,3);
9211   PetscValidPointer(submat,4);
9212 
9213   if (mat->ops->getlocalsubmatrix) {
9214     ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
9215   } else {
9216     ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr);
9217   }
9218   PetscFunctionReturn(0);
9219 }
9220 
9221 #undef __FUNCT__
9222 #define __FUNCT__ "MatRestoreLocalSubMatrix"
9223 /*@
9224    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
9225 
9226    Not Collective
9227 
9228    Input Arguments:
9229    mat - matrix to extract local submatrix from
9230    isrow - local row indices for submatrix
9231    iscol - local column indices for submatrix
9232    submat - the submatrix
9233 
9234    Level: intermediate
9235 
9236 .seealso: MatGetLocalSubMatrix()
9237 @*/
9238 PetscErrorCode  MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9239 {
9240   PetscErrorCode ierr;
9241 
9242   PetscFunctionBegin;
9243   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9244   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
9245   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
9246   PetscCheckSameComm(isrow,2,iscol,3);
9247   PetscValidPointer(submat,4);
9248   if (*submat) {PetscValidHeaderSpecific(*submat,MAT_CLASSID,4);}
9249 
9250   if (mat->ops->restorelocalsubmatrix) {
9251     ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
9252   } else {
9253     ierr = MatDestroy(submat);CHKERRQ(ierr);
9254   }
9255   *submat = PETSC_NULL;
9256   PetscFunctionReturn(0);
9257 }
9258 
9259 /* --------------------------------------------------------*/
9260 #undef __FUNCT__
9261 #define __FUNCT__ "MatFindZeroDiagonals"
9262 /*@
9263    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no entry in the matrix
9264 
9265    Collective on Mat
9266 
9267    Input Parameter:
9268 .  mat - the matrix
9269 
9270    Output Parameter:
9271 .  is - if any rows have zero diagonals this contains the list of them
9272 
9273    Level: developer
9274 
9275    Concepts: matrix-vector product
9276 
9277 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
9278 @*/
9279 PetscErrorCode  MatFindZeroDiagonals(Mat mat,IS *is)
9280 {
9281   PetscErrorCode ierr;
9282 
9283   PetscFunctionBegin;
9284   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9285   PetscValidType(mat,1);
9286   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9287   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9288 
9289   if (!mat->ops->findzerodiagonals) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"This matrix type does not have a find zero diagonals defined");
9290   ierr = (*mat->ops->findzerodiagonals)(mat,is);CHKERRQ(ierr);
9291   PetscFunctionReturn(0);
9292 }
9293 
9294 #undef __FUNCT__
9295 #define __FUNCT__ "MatInvertBlockDiagonal"
9296 /*@C
9297   MatInvertBlockDiagonal - Inverts the block diagonal entries.
9298 
9299   Collective on Mat
9300 
9301   Input Parameters:
9302 . mat - the matrix
9303 
9304   Output Parameters:
9305 . values - the block inverses in column major order (FORTRAN-like)
9306 
9307    Note:
9308    This routine is not available from Fortran.
9309 
9310   Level: advanced
9311 @*/
9312 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
9313 {
9314   PetscErrorCode ierr;
9315 
9316   PetscFunctionBegin;
9317   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9318   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9319   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9320   if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
9321   ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr);
9322   PetscFunctionReturn(0);
9323 }
9324 
9325 #undef __FUNCT__
9326 #define __FUNCT__ "MatTransposeColoringDestroy"
9327 /*@C
9328     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
9329     via MatTransposeColoringCreate().
9330 
9331     Collective on MatTransposeColoring
9332 
9333     Input Parameter:
9334 .   c - coloring context
9335 
9336     Level: intermediate
9337 
9338 .seealso: MatTransposeColoringCreate()
9339 @*/
9340 PetscErrorCode  MatTransposeColoringDestroy(MatTransposeColoring *c)
9341 {
9342   PetscErrorCode       ierr;
9343   MatTransposeColoring matcolor=*c;
9344 
9345   PetscFunctionBegin;
9346   if (!matcolor) PetscFunctionReturn(0);
9347   if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; PetscFunctionReturn(0);}
9348 
9349   ierr = PetscFree(matcolor->ncolumns);CHKERRQ(ierr);
9350   ierr = PetscFree(matcolor->nrows);CHKERRQ(ierr);
9351   ierr = PetscFree(matcolor->colorforrow);CHKERRQ(ierr);
9352   ierr = PetscFree2(matcolor->rows,matcolor->columnsforspidx);CHKERRQ(ierr);
9353   ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr);
9354   ierr = PetscFree(matcolor->columns);CHKERRQ(ierr);
9355   ierr = PetscHeaderDestroy(c);CHKERRQ(ierr);
9356   PetscFunctionReturn(0);
9357 }
9358 
9359 #undef __FUNCT__
9360 #define __FUNCT__ "MatTransColoringApplySpToDen"
9361 /*@C
9362     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
9363     a MatTransposeColoring context has been created, computes a dense B^T by Apply
9364     MatTransposeColoring to sparse B.
9365 
9366     Collective on MatTransposeColoring
9367 
9368     Input Parameters:
9369 +   B - sparse matrix B
9370 .   Btdense - symbolic dense matrix B^T
9371 -   coloring - coloring context created with MatTransposeColoringCreate()
9372 
9373     Output Parameter:
9374 .   Btdense - dense matrix B^T
9375 
9376     Options Database Keys:
9377 +    -mat_transpose_coloring_view - Activates basic viewing or coloring
9378 .    -mat_transpose_coloring_view_draw - Activates drawing of coloring
9379 -    -mat_transpose_coloring_view_info - Activates viewing of coloring info
9380 
9381     Level: intermediate
9382 
9383 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy()
9384 
9385 .keywords: coloring
9386 @*/
9387 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
9388 {
9389   PetscErrorCode ierr;
9390 
9391   PetscFunctionBegin;
9392   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
9393   PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2);
9394   PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3);
9395 
9396   if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
9397   ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr);
9398   PetscFunctionReturn(0);
9399 }
9400 
9401 #undef __FUNCT__
9402 #define __FUNCT__ "MatTransColoringApplyDenToSp"
9403 /*@C
9404     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
9405     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
9406     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
9407     Csp from Cden.
9408 
9409     Collective on MatTransposeColoring
9410 
9411     Input Parameters:
9412 +   coloring - coloring context created with MatTransposeColoringCreate()
9413 -   Cden - matrix product of a sparse matrix and a dense matrix Btdense
9414 
9415     Output Parameter:
9416 .   Csp - sparse matrix
9417 
9418     Options Database Keys:
9419 +    -mat_multtranspose_coloring_view - Activates basic viewing or coloring
9420 .    -mat_multtranspose_coloring_view_draw - Activates drawing of coloring
9421 -    -mat_multtranspose_coloring_view_info - Activates viewing of coloring info
9422 
9423     Level: intermediate
9424 
9425 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()
9426 
9427 .keywords: coloring
9428 @*/
9429 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
9430 {
9431   PetscErrorCode ierr;
9432 
9433   PetscFunctionBegin;
9434   PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1);
9435   PetscValidHeaderSpecific(Cden,MAT_CLASSID,2);
9436   PetscValidHeaderSpecific(Csp,MAT_CLASSID,3);
9437 
9438   if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
9439   ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr);
9440   PetscFunctionReturn(0);
9441 }
9442 
9443 #undef __FUNCT__
9444 #define __FUNCT__ "MatTransposeColoringCreate"
9445 /*@C
9446    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.
9447 
9448    Collective on Mat
9449 
9450    Input Parameters:
9451 +  mat - the matrix product C
9452 -  iscoloring - the coloring of the matrix; usually obtained with MatGetColoring() or DMCreateColoring()
9453 
9454     Output Parameter:
9455 .   color - the new coloring context
9456 
9457     Level: intermediate
9458 
9459 .seealso: MatTransposeColoringDestroy(), MatTransposeColoringSetFromOptions(), MatTransColoringApplySpToDen(),
9460            MatTransColoringApplyDenToSp(), MatTransposeColoringView(),
9461 @*/
9462 PetscErrorCode  MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
9463 {
9464   MatTransposeColoring c;
9465   MPI_Comm             comm;
9466   PetscErrorCode       ierr;
9467 
9468   PetscFunctionBegin;
9469   ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
9470   ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
9471   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);
9472 
9473   c->ctype = iscoloring->ctype;
9474   if (mat->ops->transposecoloringcreate) {
9475     ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr);
9476   } else SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Code not yet written for this matrix type");
9477 
9478   *color = c;
9479   ierr = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
9480   PetscFunctionReturn(0);
9481 }
9482