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