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