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