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