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