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