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