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