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