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