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