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