xref: /petsc/src/mat/interface/matrix.c (revision 8208b9ae9936b534ffb14d7e4c50ae7ef117b6f5)
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 static PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X, PetscBool trans)
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     if (trans) {
3293       ierr = MatSolveTranspose(A,b,x);CHKERRQ(ierr);
3294     } else {
3295       ierr = MatSolve(A,b,x);CHKERRQ(ierr);
3296     }
3297     ierr = VecResetArray(x);CHKERRQ(ierr);
3298     ierr = VecResetArray(b);CHKERRQ(ierr);
3299   }
3300   ierr = VecDestroy(&b);CHKERRQ(ierr);
3301   ierr = VecDestroy(&x);CHKERRQ(ierr);
3302   ierr = MatDenseRestoreArray(B,&bb);CHKERRQ(ierr);
3303   ierr = MatDenseRestoreArray(X,&xx);CHKERRQ(ierr);
3304   PetscFunctionReturn(0);
3305 }
3306 
3307 /*@
3308    MatMatSolve - Solves A X = B, given a factored matrix.
3309 
3310    Neighbor-wise Collective on Mat
3311 
3312    Input Parameters:
3313 +  A - the factored matrix
3314 -  B - the right-hand-side matrix  (dense matrix)
3315 
3316    Output Parameter:
3317 .  X - the result matrix (dense matrix)
3318 
3319    Notes:
3320    The matrices b and x cannot be the same.  I.e., one cannot
3321    call MatMatSolve(A,x,x).
3322 
3323    Notes:
3324    Most users should usually employ the simplified KSP interface for linear solvers
3325    instead of working directly with matrix algebra routines such as this.
3326    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3327    at a time.
3328 
3329    When using SuperLU_Dist as a parallel solver PETSc will use the SuperLU_Dist functionality to solve multiple right hand sides simultaneously. For MUMPS
3330    it calls a separate solve for each right hand side since MUMPS does not yet support distributed right hand sides.
3331 
3332    Since the resulting matrix X must always be dense we do not support sparse representation of the matrix B.
3333 
3334    Level: developer
3335 
3336    Concepts: matrices^triangular solves
3337 
3338 .seealso: MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor()
3339 @*/
3340 PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X)
3341 {
3342   PetscErrorCode ierr;
3343 
3344   PetscFunctionBegin;
3345   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3346   PetscValidType(A,1);
3347   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3348   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3349   PetscCheckSameComm(A,1,B,2);
3350   PetscCheckSameComm(A,1,X,3);
3351   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3352   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3353   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);
3354   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);
3355   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);
3356   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");
3357   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3358   MatCheckPreallocated(A,1);
3359 
3360   ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3361   if (!A->ops->matsolve) {
3362     ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name);CHKERRQ(ierr);
3363     ierr = MatMatSolve_Basic(A,B,X,PETSC_FALSE);CHKERRQ(ierr);
3364   } else {
3365     ierr = (*A->ops->matsolve)(A,B,X);CHKERRQ(ierr);
3366   }
3367   ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3368   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3369   PetscFunctionReturn(0);
3370 }
3371 
3372 /*@
3373    MatMatSolveTranspose - Solves A^T X = B, given a factored matrix.
3374 
3375    Neighbor-wise Collective on Mat
3376 
3377    Input Parameters:
3378 +  A - the factored matrix
3379 -  B - the right-hand-side matrix  (dense matrix)
3380 
3381    Output Parameter:
3382 .  X - the result matrix (dense matrix)
3383 
3384    Notes:
3385    The matrices b and x cannot be the same.  I.e., one cannot
3386    call MatMatSolveTranspose(A,x,x).
3387 
3388    Notes:
3389    Most users should usually employ the simplified KSP interface for linear solvers
3390    instead of working directly with matrix algebra routines such as this.
3391    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3392    at a time.
3393 
3394    When using SuperLU_Dist as a parallel solver PETSc will use the SuperLU_Dist functionality to solve multiple right hand sides simultaneously. For MUMPS
3395    it calls a separate solve for each right hand side since MUMPS does not yet support distributed right hand sides.
3396 
3397    Since the resulting matrix X must always be dense we do not support sparse representation of the matrix B.
3398 
3399    Level: developer
3400 
3401    Concepts: matrices^triangular solves
3402 
3403 .seealso: MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor()
3404 @*/
3405 PetscErrorCode MatMatSolveTranspose(Mat A,Mat B,Mat X)
3406 {
3407   PetscErrorCode ierr;
3408 
3409   PetscFunctionBegin;
3410   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3411   PetscValidType(A,1);
3412   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3413   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3414   PetscCheckSameComm(A,1,B,2);
3415   PetscCheckSameComm(A,1,X,3);
3416   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3417   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3418   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);
3419   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);
3420   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);
3421   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");
3422   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3423   MatCheckPreallocated(A,1);
3424 
3425   ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3426   if (!A->ops->matsolvetranspose) {
3427     ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolveTranspose\n",((PetscObject)A)->type_name);CHKERRQ(ierr);
3428     ierr = MatMatSolve_Basic(A,B,X,PETSC_TRUE);CHKERRQ(ierr);
3429   } else {
3430     ierr = (*A->ops->matsolvetranspose)(A,B,X);CHKERRQ(ierr);
3431   }
3432   ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3433   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3434   PetscFunctionReturn(0);
3435 }
3436 
3437 /*@
3438    MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or
3439                             U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U,
3440 
3441    Neighbor-wise Collective on Mat and Vec
3442 
3443    Input Parameters:
3444 +  mat - the factored matrix
3445 -  b - the right-hand-side vector
3446 
3447    Output Parameter:
3448 .  x - the result vector
3449 
3450    Notes:
3451    MatSolve() should be used for most applications, as it performs
3452    a forward solve followed by a backward solve.
3453 
3454    The vectors b and x cannot be the same,  i.e., one cannot
3455    call MatForwardSolve(A,x,x).
3456 
3457    For matrix in seqsbaij format with block size larger than 1,
3458    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3459    MatForwardSolve() solves U^T*D y = b, and
3460    MatBackwardSolve() solves U x = y.
3461    Thus they do not provide a symmetric preconditioner.
3462 
3463    Most users should employ the simplified KSP interface for linear solvers
3464    instead of working directly with matrix algebra routines such as this.
3465    See, e.g., KSPCreate().
3466 
3467    Level: developer
3468 
3469    Concepts: matrices^forward solves
3470 
3471 .seealso: MatSolve(), MatBackwardSolve()
3472 @*/
3473 PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x)
3474 {
3475   PetscErrorCode ierr;
3476 
3477   PetscFunctionBegin;
3478   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3479   PetscValidType(mat,1);
3480   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3481   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3482   PetscCheckSameComm(mat,1,b,2);
3483   PetscCheckSameComm(mat,1,x,3);
3484   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3485   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3486   if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3487   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);
3488   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);
3489   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);
3490   MatCheckPreallocated(mat,1);
3491   ierr = PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
3492   ierr = (*mat->ops->forwardsolve)(mat,b,x);CHKERRQ(ierr);
3493   ierr = PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
3494   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3495   PetscFunctionReturn(0);
3496 }
3497 
3498 /*@
3499    MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
3500                              D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U,
3501 
3502    Neighbor-wise Collective on Mat and Vec
3503 
3504    Input Parameters:
3505 +  mat - the factored matrix
3506 -  b - the right-hand-side vector
3507 
3508    Output Parameter:
3509 .  x - the result vector
3510 
3511    Notes:
3512    MatSolve() should be used for most applications, as it performs
3513    a forward solve followed by a backward solve.
3514 
3515    The vectors b and x cannot be the same.  I.e., one cannot
3516    call MatBackwardSolve(A,x,x).
3517 
3518    For matrix in seqsbaij format with block size larger than 1,
3519    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3520    MatForwardSolve() solves U^T*D y = b, and
3521    MatBackwardSolve() solves U x = y.
3522    Thus they do not provide a symmetric preconditioner.
3523 
3524    Most users should employ the simplified KSP interface for linear solvers
3525    instead of working directly with matrix algebra routines such as this.
3526    See, e.g., KSPCreate().
3527 
3528    Level: developer
3529 
3530    Concepts: matrices^backward solves
3531 
3532 .seealso: MatSolve(), MatForwardSolve()
3533 @*/
3534 PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x)
3535 {
3536   PetscErrorCode ierr;
3537 
3538   PetscFunctionBegin;
3539   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3540   PetscValidType(mat,1);
3541   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3542   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3543   PetscCheckSameComm(mat,1,b,2);
3544   PetscCheckSameComm(mat,1,x,3);
3545   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3546   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3547   if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3548   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);
3549   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);
3550   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);
3551   MatCheckPreallocated(mat,1);
3552 
3553   ierr = PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
3554   ierr = (*mat->ops->backwardsolve)(mat,b,x);CHKERRQ(ierr);
3555   ierr = PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
3556   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3557   PetscFunctionReturn(0);
3558 }
3559 
3560 /*@
3561    MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
3562 
3563    Neighbor-wise Collective on Mat and Vec
3564 
3565    Input Parameters:
3566 +  mat - the factored matrix
3567 .  b - the right-hand-side vector
3568 -  y - the vector to be added to
3569 
3570    Output Parameter:
3571 .  x - the result vector
3572 
3573    Notes:
3574    The vectors b and x cannot be the same.  I.e., one cannot
3575    call MatSolveAdd(A,x,y,x).
3576 
3577    Most users should employ the simplified KSP interface for linear solvers
3578    instead of working directly with matrix algebra routines such as this.
3579    See, e.g., KSPCreate().
3580 
3581    Level: developer
3582 
3583    Concepts: matrices^triangular solves
3584 
3585 .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3586 @*/
3587 PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3588 {
3589   PetscScalar    one = 1.0;
3590   Vec            tmp;
3591   PetscErrorCode ierr;
3592 
3593   PetscFunctionBegin;
3594   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3595   PetscValidType(mat,1);
3596   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3597   PetscValidHeaderSpecific(b,VEC_CLASSID,3);
3598   PetscValidHeaderSpecific(x,VEC_CLASSID,4);
3599   PetscCheckSameComm(mat,1,b,2);
3600   PetscCheckSameComm(mat,1,y,2);
3601   PetscCheckSameComm(mat,1,x,3);
3602   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3603   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3604   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);
3605   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);
3606   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);
3607   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);
3608   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);
3609   MatCheckPreallocated(mat,1);
3610 
3611   ierr = PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
3612   if (mat->ops->solveadd) {
3613     ierr = (*mat->ops->solveadd)(mat,b,y,x);CHKERRQ(ierr);
3614   } else {
3615     /* do the solve then the add manually */
3616     if (x != y) {
3617       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
3618       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
3619     } else {
3620       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
3621       ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr);
3622       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
3623       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
3624       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
3625       ierr = VecDestroy(&tmp);CHKERRQ(ierr);
3626     }
3627   }
3628   ierr = PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
3629   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3630   PetscFunctionReturn(0);
3631 }
3632 
3633 /*@
3634    MatSolveTranspose - Solves A' x = b, given a factored matrix.
3635 
3636    Neighbor-wise Collective on Mat and Vec
3637 
3638    Input Parameters:
3639 +  mat - the factored matrix
3640 -  b - the right-hand-side vector
3641 
3642    Output Parameter:
3643 .  x - the result vector
3644 
3645    Notes:
3646    The vectors b and x cannot be the same.  I.e., one cannot
3647    call MatSolveTranspose(A,x,x).
3648 
3649    Most users should employ the simplified KSP interface for linear solvers
3650    instead of working directly with matrix algebra routines such as this.
3651    See, e.g., KSPCreate().
3652 
3653    Level: developer
3654 
3655    Concepts: matrices^triangular solves
3656 
3657 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
3658 @*/
3659 PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x)
3660 {
3661   PetscErrorCode ierr;
3662 
3663   PetscFunctionBegin;
3664   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3665   PetscValidType(mat,1);
3666   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3667   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3668   PetscCheckSameComm(mat,1,b,2);
3669   PetscCheckSameComm(mat,1,x,3);
3670   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3671   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3672   if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3673   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);
3674   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);
3675   MatCheckPreallocated(mat,1);
3676   ierr = PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
3677   if (mat->factorerrortype) {
3678     ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3679     ierr = VecSetInf(x);CHKERRQ(ierr);
3680   } else {
3681     ierr = (*mat->ops->solvetranspose)(mat,b,x);CHKERRQ(ierr);
3682   }
3683   ierr = PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
3684   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3685   PetscFunctionReturn(0);
3686 }
3687 
3688 /*@
3689    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
3690                       factored matrix.
3691 
3692    Neighbor-wise Collective on Mat and Vec
3693 
3694    Input Parameters:
3695 +  mat - the factored matrix
3696 .  b - the right-hand-side vector
3697 -  y - the vector to be added to
3698 
3699    Output Parameter:
3700 .  x - the result vector
3701 
3702    Notes:
3703    The vectors b and x cannot be the same.  I.e., one cannot
3704    call MatSolveTransposeAdd(A,x,y,x).
3705 
3706    Most users should employ the simplified KSP interface for linear solvers
3707    instead of working directly with matrix algebra routines such as this.
3708    See, e.g., KSPCreate().
3709 
3710    Level: developer
3711 
3712    Concepts: matrices^triangular solves
3713 
3714 .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3715 @*/
3716 PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3717 {
3718   PetscScalar    one = 1.0;
3719   PetscErrorCode ierr;
3720   Vec            tmp;
3721 
3722   PetscFunctionBegin;
3723   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3724   PetscValidType(mat,1);
3725   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3726   PetscValidHeaderSpecific(b,VEC_CLASSID,3);
3727   PetscValidHeaderSpecific(x,VEC_CLASSID,4);
3728   PetscCheckSameComm(mat,1,b,2);
3729   PetscCheckSameComm(mat,1,y,3);
3730   PetscCheckSameComm(mat,1,x,4);
3731   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3732   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3733   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);
3734   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);
3735   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);
3736   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);
3737   MatCheckPreallocated(mat,1);
3738 
3739   ierr = PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
3740   if (mat->ops->solvetransposeadd) {
3741     if (mat->factorerrortype) {
3742       ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3743       ierr = VecSetInf(x);CHKERRQ(ierr);
3744     } else {
3745       ierr = (*mat->ops->solvetransposeadd)(mat,b,y,x);CHKERRQ(ierr);
3746     }
3747   } else {
3748     /* do the solve then the add manually */
3749     if (x != y) {
3750       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
3751       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
3752     } else {
3753       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
3754       ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr);
3755       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
3756       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
3757       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
3758       ierr = VecDestroy(&tmp);CHKERRQ(ierr);
3759     }
3760   }
3761   ierr = PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
3762   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3763   PetscFunctionReturn(0);
3764 }
3765 /* ----------------------------------------------------------------*/
3766 
3767 /*@
3768    MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps.
3769 
3770    Neighbor-wise Collective on Mat and Vec
3771 
3772    Input Parameters:
3773 +  mat - the matrix
3774 .  b - the right hand side
3775 .  omega - the relaxation factor
3776 .  flag - flag indicating the type of SOR (see below)
3777 .  shift -  diagonal shift
3778 .  its - the number of iterations
3779 -  lits - the number of local iterations
3780 
3781    Output Parameters:
3782 .  x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess)
3783 
3784    SOR Flags:
3785 .     SOR_FORWARD_SWEEP - forward SOR
3786 .     SOR_BACKWARD_SWEEP - backward SOR
3787 .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3788 .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR
3789 .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
3790 .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3791 .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
3792          upper/lower triangular part of matrix to
3793          vector (with omega)
3794 .     SOR_ZERO_INITIAL_GUESS - zero initial guess
3795 
3796    Notes:
3797    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3798    SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3799    on each processor.
3800 
3801    Application programmers will not generally use MatSOR() directly,
3802    but instead will employ the KSP/PC interface.
3803 
3804    Notes: for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing
3805 
3806    Notes for Advanced Users:
3807    The flags are implemented as bitwise inclusive or operations.
3808    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3809    to specify a zero initial guess for SSOR.
3810 
3811    Most users should employ the simplified KSP interface for linear solvers
3812    instead of working directly with matrix algebra routines such as this.
3813    See, e.g., KSPCreate().
3814 
3815    Vectors x and b CANNOT be the same
3816 
3817    Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes
3818 
3819    Level: developer
3820 
3821    Concepts: matrices^relaxation
3822    Concepts: matrices^SOR
3823    Concepts: matrices^Gauss-Seidel
3824 
3825 @*/
3826 PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3827 {
3828   PetscErrorCode ierr;
3829 
3830   PetscFunctionBegin;
3831   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3832   PetscValidType(mat,1);
3833   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3834   PetscValidHeaderSpecific(x,VEC_CLASSID,8);
3835   PetscCheckSameComm(mat,1,b,2);
3836   PetscCheckSameComm(mat,1,x,8);
3837   if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3838   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3839   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3840   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);
3841   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);
3842   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);
3843   if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
3844   if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
3845   if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");
3846 
3847   MatCheckPreallocated(mat,1);
3848   ierr = PetscLogEventBegin(MAT_SOR,mat,b,x,0);CHKERRQ(ierr);
3849   ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr);
3850   ierr = PetscLogEventEnd(MAT_SOR,mat,b,x,0);CHKERRQ(ierr);
3851   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3852   PetscFunctionReturn(0);
3853 }
3854 
3855 /*
3856       Default matrix copy routine.
3857 */
3858 PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
3859 {
3860   PetscErrorCode    ierr;
3861   PetscInt          i,rstart = 0,rend = 0,nz;
3862   const PetscInt    *cwork;
3863   const PetscScalar *vwork;
3864 
3865   PetscFunctionBegin;
3866   if (B->assembled) {
3867     ierr = MatZeroEntries(B);CHKERRQ(ierr);
3868   }
3869   ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
3870   for (i=rstart; i<rend; i++) {
3871     ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
3872     ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);CHKERRQ(ierr);
3873     ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
3874   }
3875   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3876   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3877   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
3878   PetscFunctionReturn(0);
3879 }
3880 
3881 /*@
3882    MatCopy - Copys a matrix to another matrix.
3883 
3884    Collective on Mat
3885 
3886    Input Parameters:
3887 +  A - the matrix
3888 -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
3889 
3890    Output Parameter:
3891 .  B - where the copy is put
3892 
3893    Notes:
3894    If you use SAME_NONZERO_PATTERN then the two matrices had better have the
3895    same nonzero pattern or the routine will crash.
3896 
3897    MatCopy() copies the matrix entries of a matrix to another existing
3898    matrix (after first zeroing the second matrix).  A related routine is
3899    MatConvert(), which first creates a new matrix and then copies the data.
3900 
3901    Level: intermediate
3902 
3903    Concepts: matrices^copying
3904 
3905 .seealso: MatConvert(), MatDuplicate()
3906 
3907 @*/
3908 PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str)
3909 {
3910   PetscErrorCode ierr;
3911   PetscInt       i;
3912 
3913   PetscFunctionBegin;
3914   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3915   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3916   PetscValidType(A,1);
3917   PetscValidType(B,2);
3918   PetscCheckSameComm(A,1,B,2);
3919   MatCheckPreallocated(B,2);
3920   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3921   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3922   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);
3923   MatCheckPreallocated(A,1);
3924 
3925   ierr = PetscLogEventBegin(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
3926   if (A->ops->copy) {
3927     ierr = (*A->ops->copy)(A,B,str);CHKERRQ(ierr);
3928   } else { /* generic conversion */
3929     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
3930   }
3931 
3932   B->stencil.dim = A->stencil.dim;
3933   B->stencil.noc = A->stencil.noc;
3934   for (i=0; i<=A->stencil.dim; i++) {
3935     B->stencil.dims[i]   = A->stencil.dims[i];
3936     B->stencil.starts[i] = A->stencil.starts[i];
3937   }
3938 
3939   ierr = PetscLogEventEnd(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
3940   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
3941   PetscFunctionReturn(0);
3942 }
3943 
3944 /*@C
3945    MatConvert - Converts a matrix to another matrix, either of the same
3946    or different type.
3947 
3948    Collective on Mat
3949 
3950    Input Parameters:
3951 +  mat - the matrix
3952 .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
3953    same type as the original matrix.
3954 -  reuse - denotes if the destination matrix is to be created or reused.
3955    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
3956    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).
3957 
3958    Output Parameter:
3959 .  M - pointer to place new matrix
3960 
3961    Notes:
3962    MatConvert() first creates a new matrix and then copies the data from
3963    the first matrix.  A related routine is MatCopy(), which copies the matrix
3964    entries of one matrix to another already existing matrix context.
3965 
3966    Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
3967    the MPI communicator of the generated matrix is always the same as the communicator
3968    of the input matrix.
3969 
3970    Level: intermediate
3971 
3972    Concepts: matrices^converting between storage formats
3973 
3974 .seealso: MatCopy(), MatDuplicate()
3975 @*/
3976 PetscErrorCode MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M)
3977 {
3978   PetscErrorCode ierr;
3979   PetscBool      sametype,issame,flg;
3980   char           convname[256],mtype[256];
3981   Mat            B;
3982 
3983   PetscFunctionBegin;
3984   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3985   PetscValidType(mat,1);
3986   PetscValidPointer(M,3);
3987   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3988   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3989   MatCheckPreallocated(mat,1);
3990   ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr);
3991 
3992   ierr = PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);CHKERRQ(ierr);
3993   if (flg) {
3994     newtype = mtype;
3995   }
3996   ierr = PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);CHKERRQ(ierr);
3997   ierr = PetscStrcmp(newtype,"same",&issame);CHKERRQ(ierr);
3998   if ((reuse == MAT_INPLACE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix");
3999   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");
4000 
4001   if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) PetscFunctionReturn(0);
4002 
4003   if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
4004     ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
4005   } else {
4006     PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL;
4007     const char     *prefix[3] = {"seq","mpi",""};
4008     PetscInt       i;
4009     /*
4010        Order of precedence:
4011        1) See if a specialized converter is known to the current matrix.
4012        2) See if a specialized converter is known to the desired matrix class.
4013        3) See if a good general converter is registered for the desired class
4014           (as of 6/27/03 only MATMPIADJ falls into this category).
4015        4) See if a good general converter is known for the current matrix.
4016        5) Use a really basic converter.
4017     */
4018 
4019     /* 1) See if a specialized converter is known to the current matrix and the desired class */
4020     for (i=0; i<3; i++) {
4021       ierr = PetscStrcpy(convname,"MatConvert_");CHKERRQ(ierr);
4022       ierr = PetscStrcat(convname,((PetscObject)mat)->type_name);CHKERRQ(ierr);
4023       ierr = PetscStrcat(convname,"_");CHKERRQ(ierr);
4024       ierr = PetscStrcat(convname,prefix[i]);CHKERRQ(ierr);
4025       ierr = PetscStrcat(convname,issame ? ((PetscObject)mat)->type_name : newtype);CHKERRQ(ierr);
4026       ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
4027       ierr = PetscObjectQueryFunction((PetscObject)mat,convname,&conv);CHKERRQ(ierr);
4028       if (conv) goto foundconv;
4029     }
4030 
4031     /* 2)  See if a specialized converter is known to the desired matrix class. */
4032     ierr = MatCreate(PetscObjectComm((PetscObject)mat),&B);CHKERRQ(ierr);
4033     ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);CHKERRQ(ierr);
4034     ierr = MatSetType(B,newtype);CHKERRQ(ierr);
4035     for (i=0; i<3; i++) {
4036       ierr = PetscStrcpy(convname,"MatConvert_");CHKERRQ(ierr);
4037       ierr = PetscStrcat(convname,((PetscObject)mat)->type_name);CHKERRQ(ierr);
4038       ierr = PetscStrcat(convname,"_");CHKERRQ(ierr);
4039       ierr = PetscStrcat(convname,prefix[i]);CHKERRQ(ierr);
4040       ierr = PetscStrcat(convname,newtype);CHKERRQ(ierr);
4041       ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
4042       ierr = PetscObjectQueryFunction((PetscObject)B,convname,&conv);CHKERRQ(ierr);
4043       if (conv) {
4044         ierr = MatDestroy(&B);CHKERRQ(ierr);
4045         goto foundconv;
4046       }
4047     }
4048 
4049     /* 3) See if a good general converter is registered for the desired class */
4050     conv = B->ops->convertfrom;
4051     ierr = MatDestroy(&B);CHKERRQ(ierr);
4052     if (conv) goto foundconv;
4053 
4054     /* 4) See if a good general converter is known for the current matrix */
4055     if (mat->ops->convert) {
4056       conv = mat->ops->convert;
4057     }
4058     if (conv) goto foundconv;
4059 
4060     /* 5) Use a really basic converter. */
4061     conv = MatConvert_Basic;
4062 
4063 foundconv:
4064     ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4065     ierr = (*conv)(mat,newtype,reuse,M);CHKERRQ(ierr);
4066     ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4067   }
4068   ierr = PetscObjectStateIncrease((PetscObject)*M);CHKERRQ(ierr);
4069 
4070   /* Copy Mat options */
4071   if (mat->symmetric) {ierr = MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);}
4072   if (mat->hermitian) {ierr = MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);}
4073   PetscFunctionReturn(0);
4074 }
4075 
4076 /*@C
4077    MatFactorGetSolverPackage - Returns name of the package providing the factorization routines
4078 
4079    Not Collective
4080 
4081    Input Parameter:
4082 .  mat - the matrix, must be a factored matrix
4083 
4084    Output Parameter:
4085 .   type - the string name of the package (do not free this string)
4086 
4087    Notes:
4088       In Fortran you pass in a empty string and the package name will be copied into it.
4089     (Make sure the string is long enough)
4090 
4091    Level: intermediate
4092 
4093 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
4094 @*/
4095 PetscErrorCode MatFactorGetSolverPackage(Mat mat, const MatSolverPackage *type)
4096 {
4097   PetscErrorCode ierr, (*conv)(Mat,const MatSolverPackage*);
4098 
4099   PetscFunctionBegin;
4100   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4101   PetscValidType(mat,1);
4102   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
4103   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverPackage_C",&conv);CHKERRQ(ierr);
4104   if (!conv) {
4105     *type = MATSOLVERPETSC;
4106   } else {
4107     ierr = (*conv)(mat,type);CHKERRQ(ierr);
4108   }
4109   PetscFunctionReturn(0);
4110 }
4111 
4112 typedef struct _MatSolverPackageForSpecifcType* MatSolverPackageForSpecifcType;
4113 struct _MatSolverPackageForSpecifcType {
4114   MatType                        mtype;
4115   PetscErrorCode                 (*getfactor[4])(Mat,MatFactorType,Mat*);
4116   MatSolverPackageForSpecifcType next;
4117 };
4118 
4119 typedef struct _MatSolverPackageHolder* MatSolverPackageHolder;
4120 struct _MatSolverPackageHolder {
4121   char                           *name;
4122   MatSolverPackageForSpecifcType handlers;
4123   MatSolverPackageHolder         next;
4124 };
4125 
4126 static MatSolverPackageHolder MatSolverPackageHolders = NULL;
4127 
4128 /*@C
4129    MatSolvePackageRegister - Registers a MatSolverPackage that works for a particular matrix type
4130 
4131    Input Parameters:
4132 +    package - name of the package, for example petsc or superlu
4133 .    mtype - the matrix type that works with this package
4134 .    ftype - the type of factorization supported by the package
4135 -    getfactor - routine that will create the factored matrix ready to be used
4136 
4137     Level: intermediate
4138 
4139 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4140 @*/
4141 PetscErrorCode MatSolverPackageRegister(const MatSolverPackage package,const MatType mtype,MatFactorType ftype,PetscErrorCode (*getfactor)(Mat,MatFactorType,Mat*))
4142 {
4143   PetscErrorCode                 ierr;
4144   MatSolverPackageHolder         next = MatSolverPackageHolders,prev;
4145   PetscBool                      flg;
4146   MatSolverPackageForSpecifcType inext,iprev = NULL;
4147 
4148   PetscFunctionBegin;
4149   if (!next) {
4150     ierr = PetscNew(&MatSolverPackageHolders);CHKERRQ(ierr);
4151     ierr = PetscStrallocpy(package,&MatSolverPackageHolders->name);CHKERRQ(ierr);
4152     ierr = PetscNew(&MatSolverPackageHolders->handlers);CHKERRQ(ierr);
4153     ierr = PetscStrallocpy(mtype,(char **)&MatSolverPackageHolders->handlers->mtype);CHKERRQ(ierr);
4154     MatSolverPackageHolders->handlers->getfactor[(int)ftype-1] = getfactor;
4155     PetscFunctionReturn(0);
4156   }
4157   while (next) {
4158     ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr);
4159     if (flg) {
4160       if (!next->handlers) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverPackageHolder is missing handlers");
4161       inext = next->handlers;
4162       while (inext) {
4163         ierr = PetscStrcasecmp(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4164         if (flg) {
4165           inext->getfactor[(int)ftype-1] = getfactor;
4166           PetscFunctionReturn(0);
4167         }
4168         iprev = inext;
4169         inext = inext->next;
4170       }
4171       ierr = PetscNew(&iprev->next);CHKERRQ(ierr);
4172       ierr = PetscStrallocpy(mtype,(char **)&iprev->next->mtype);CHKERRQ(ierr);
4173       iprev->next->getfactor[(int)ftype-1] = getfactor;
4174       PetscFunctionReturn(0);
4175     }
4176     prev = next;
4177     next = next->next;
4178   }
4179   ierr = PetscNew(&prev->next);CHKERRQ(ierr);
4180   ierr = PetscStrallocpy(package,&prev->next->name);CHKERRQ(ierr);
4181   ierr = PetscNew(&prev->next->handlers);CHKERRQ(ierr);
4182   ierr = PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);CHKERRQ(ierr);
4183   prev->next->handlers->getfactor[(int)ftype-1] = getfactor;
4184   PetscFunctionReturn(0);
4185 }
4186 
4187 /*@C
4188    MatSolvePackageGet - Get's the function that creates the factor matrix if it exist
4189 
4190    Input Parameters:
4191 +    package - name of the package, for example petsc or superlu
4192 .    ftype - the type of factorization supported by the package
4193 -    mtype - the matrix type that works with this package
4194 
4195    Output Parameters:
4196 +   foundpackage - PETSC_TRUE if the package was registered
4197 .   foundmtype - PETSC_TRUE if the package supports the requested mtype
4198 -   getfactor - routine that will create the factored matrix ready to be used or NULL if not found
4199 
4200     Level: intermediate
4201 
4202 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4203 @*/
4204 PetscErrorCode MatSolverPackageGet(const MatSolverPackage package,const MatType mtype,MatFactorType ftype,PetscBool *foundpackage,PetscBool *foundmtype,PetscErrorCode (**getfactor)(Mat,MatFactorType,Mat*))
4205 {
4206   PetscErrorCode                 ierr;
4207   MatSolverPackageHolder         next = MatSolverPackageHolders;
4208   PetscBool                      flg;
4209   MatSolverPackageForSpecifcType inext;
4210 
4211   PetscFunctionBegin;
4212   if (foundpackage) *foundpackage = PETSC_FALSE;
4213   if (foundmtype)   *foundmtype   = PETSC_FALSE;
4214   if (getfactor)    *getfactor    = NULL;
4215 
4216   if (package) {
4217     while (next) {
4218       ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr);
4219       if (flg) {
4220         if (foundpackage) *foundpackage = PETSC_TRUE;
4221         inext = next->handlers;
4222         while (inext) {
4223           ierr = PetscStrcasecmp(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4224           if (flg) {
4225             if (foundmtype) *foundmtype = PETSC_TRUE;
4226             if (getfactor)  *getfactor  = inext->getfactor[(int)ftype-1];
4227             PetscFunctionReturn(0);
4228           }
4229           inext = inext->next;
4230         }
4231       }
4232       next = next->next;
4233     }
4234   } else {
4235     while (next) {
4236       inext = next->handlers;
4237       while (inext) {
4238         ierr = PetscStrcasecmp(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4239         if (flg && inext->getfactor[(int)ftype-1]) {
4240           if (foundpackage) *foundpackage = PETSC_TRUE;
4241           if (foundmtype)   *foundmtype   = PETSC_TRUE;
4242           if (getfactor)    *getfactor    = inext->getfactor[(int)ftype-1];
4243           PetscFunctionReturn(0);
4244         }
4245         inext = inext->next;
4246       }
4247       next = next->next;
4248     }
4249   }
4250   PetscFunctionReturn(0);
4251 }
4252 
4253 PetscErrorCode MatSolverPackageDestroy(void)
4254 {
4255   PetscErrorCode                 ierr;
4256   MatSolverPackageHolder         next = MatSolverPackageHolders,prev;
4257   MatSolverPackageForSpecifcType inext,iprev;
4258 
4259   PetscFunctionBegin;
4260   while (next) {
4261     ierr = PetscFree(next->name);CHKERRQ(ierr);
4262     inext = next->handlers;
4263     while (inext) {
4264       ierr = PetscFree(inext->mtype);CHKERRQ(ierr);
4265       iprev = inext;
4266       inext = inext->next;
4267       ierr = PetscFree(iprev);CHKERRQ(ierr);
4268     }
4269     prev = next;
4270     next = next->next;
4271     ierr = PetscFree(prev);CHKERRQ(ierr);
4272   }
4273   MatSolverPackageHolders = NULL;
4274   PetscFunctionReturn(0);
4275 }
4276 
4277 /*@C
4278    MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic()
4279 
4280    Collective on Mat
4281 
4282    Input Parameters:
4283 +  mat - the matrix
4284 .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4285 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4286 
4287    Output Parameters:
4288 .  f - the factor matrix used with MatXXFactorSymbolic() calls
4289 
4290    Notes:
4291       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4292      such as pastix, superlu, mumps etc.
4293 
4294       PETSc must have been ./configure to use the external solver, using the option --download-package
4295 
4296    Level: intermediate
4297 
4298 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4299 @*/
4300 PetscErrorCode MatGetFactor(Mat mat, const MatSolverPackage type,MatFactorType ftype,Mat *f)
4301 {
4302   PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
4303   PetscBool      foundpackage,foundmtype;
4304 
4305   PetscFunctionBegin;
4306   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4307   PetscValidType(mat,1);
4308 
4309   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4310   MatCheckPreallocated(mat,1);
4311 
4312   ierr = MatSolverPackageGet(type,((PetscObject)mat)->type_name,ftype,&foundpackage,&foundmtype,&conv);CHKERRQ(ierr);
4313   if (!foundpackage) {
4314     if (type) {
4315       SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver package %s. Perhaps you must ./configure with --download-%s",type,type);
4316     } else {
4317       SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate a solver package. Perhaps you must ./configure with --download-<package>");
4318     }
4319   }
4320 
4321   if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverPackage %s does not support matrix type %s",type,((PetscObject)mat)->type_name);
4322   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);
4323 
4324   ierr = (*conv)(mat,ftype,f);CHKERRQ(ierr);
4325   PetscFunctionReturn(0);
4326 }
4327 
4328 /*@C
4329    MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type
4330 
4331    Not Collective
4332 
4333    Input Parameters:
4334 +  mat - the matrix
4335 .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4336 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4337 
4338    Output Parameter:
4339 .    flg - PETSC_TRUE if the factorization is available
4340 
4341    Notes:
4342       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4343      such as pastix, superlu, mumps etc.
4344 
4345       PETSc must have been ./configure to use the external solver, using the option --download-package
4346 
4347    Level: intermediate
4348 
4349 .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
4350 @*/
4351 PetscErrorCode MatGetFactorAvailable(Mat mat, const MatSolverPackage type,MatFactorType ftype,PetscBool  *flg)
4352 {
4353   PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*);
4354 
4355   PetscFunctionBegin;
4356   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4357   PetscValidType(mat,1);
4358 
4359   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4360   MatCheckPreallocated(mat,1);
4361 
4362   *flg = PETSC_FALSE;
4363   ierr = MatSolverPackageGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);CHKERRQ(ierr);
4364   if (gconv) {
4365     *flg = PETSC_TRUE;
4366   }
4367   PetscFunctionReturn(0);
4368 }
4369 
4370 #include <petscdmtypes.h>
4371 
4372 /*@
4373    MatDuplicate - Duplicates a matrix including the non-zero structure.
4374 
4375    Collective on Mat
4376 
4377    Input Parameters:
4378 +  mat - the matrix
4379 -  op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy the numerical values in the matrix
4380         MAT_SHARE_NONZERO_PATTERN to share the nonzero patterns with the previous matrix and not copy them.
4381 
4382    Output Parameter:
4383 .  M - pointer to place new matrix
4384 
4385    Level: intermediate
4386 
4387    Concepts: matrices^duplicating
4388 
4389     Notes: You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN.
4390 
4391 .seealso: MatCopy(), MatConvert()
4392 @*/
4393 PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4394 {
4395   PetscErrorCode ierr;
4396   Mat            B;
4397   PetscInt       i;
4398   DM             dm;
4399 
4400   PetscFunctionBegin;
4401   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4402   PetscValidType(mat,1);
4403   PetscValidPointer(M,3);
4404   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4405   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4406   MatCheckPreallocated(mat,1);
4407 
4408   *M = 0;
4409   if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type");
4410   ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4411   ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr);
4412   B    = *M;
4413 
4414   B->stencil.dim = mat->stencil.dim;
4415   B->stencil.noc = mat->stencil.noc;
4416   for (i=0; i<=mat->stencil.dim; i++) {
4417     B->stencil.dims[i]   = mat->stencil.dims[i];
4418     B->stencil.starts[i] = mat->stencil.starts[i];
4419   }
4420 
4421   B->nooffproczerorows = mat->nooffproczerorows;
4422   B->nooffprocentries  = mat->nooffprocentries;
4423 
4424   ierr = PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);CHKERRQ(ierr);
4425   if (dm) {
4426     ierr = PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr);
4427   }
4428   ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4429   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
4430   PetscFunctionReturn(0);
4431 }
4432 
4433 /*@
4434    MatGetDiagonal - Gets the diagonal of a matrix.
4435 
4436    Logically Collective on Mat and Vec
4437 
4438    Input Parameters:
4439 +  mat - the matrix
4440 -  v - the vector for storing the diagonal
4441 
4442    Output Parameter:
4443 .  v - the diagonal of the matrix
4444 
4445    Level: intermediate
4446 
4447    Note:
4448    Currently only correct in parallel for square matrices.
4449 
4450    Concepts: matrices^accessing diagonals
4451 
4452 .seealso: MatGetRow(), MatCreateSubMatrices(), MatCreateSubmatrix(), MatGetRowMaxAbs()
4453 @*/
4454 PetscErrorCode MatGetDiagonal(Mat mat,Vec v)
4455 {
4456   PetscErrorCode ierr;
4457 
4458   PetscFunctionBegin;
4459   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4460   PetscValidType(mat,1);
4461   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4462   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4463   if (!mat->ops->getdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4464   MatCheckPreallocated(mat,1);
4465 
4466   ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr);
4467   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4468   PetscFunctionReturn(0);
4469 }
4470 
4471 /*@C
4472    MatGetRowMin - Gets the minimum value (of the real part) of each
4473         row of the matrix
4474 
4475    Logically Collective on Mat and Vec
4476 
4477    Input Parameters:
4478 .  mat - the matrix
4479 
4480    Output Parameter:
4481 +  v - the vector for storing the maximums
4482 -  idx - the indices of the column found for each row (optional)
4483 
4484    Level: intermediate
4485 
4486    Notes: The result of this call are the same as if one converted the matrix to dense format
4487       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4488 
4489     This code is only implemented for a couple of matrix formats.
4490 
4491    Concepts: matrices^getting row maximums
4492 
4493 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubmatrix(), MatGetRowMaxAbs(),
4494           MatGetRowMax()
4495 @*/
4496 PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4497 {
4498   PetscErrorCode ierr;
4499 
4500   PetscFunctionBegin;
4501   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4502   PetscValidType(mat,1);
4503   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4504   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4505   if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4506   MatCheckPreallocated(mat,1);
4507 
4508   ierr = (*mat->ops->getrowmin)(mat,v,idx);CHKERRQ(ierr);
4509   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4510   PetscFunctionReturn(0);
4511 }
4512 
4513 /*@C
4514    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4515         row of the matrix
4516 
4517    Logically Collective on Mat and Vec
4518 
4519    Input Parameters:
4520 .  mat - the matrix
4521 
4522    Output Parameter:
4523 +  v - the vector for storing the minimums
4524 -  idx - the indices of the column found for each row (or NULL if not needed)
4525 
4526    Level: intermediate
4527 
4528    Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
4529     row is 0 (the first column).
4530 
4531     This code is only implemented for a couple of matrix formats.
4532 
4533    Concepts: matrices^getting row maximums
4534 
4535 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubmatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4536 @*/
4537 PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4538 {
4539   PetscErrorCode ierr;
4540 
4541   PetscFunctionBegin;
4542   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4543   PetscValidType(mat,1);
4544   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4545   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4546   if (!mat->ops->getrowminabs) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4547   MatCheckPreallocated(mat,1);
4548   if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);}
4549 
4550   ierr = (*mat->ops->getrowminabs)(mat,v,idx);CHKERRQ(ierr);
4551   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4552   PetscFunctionReturn(0);
4553 }
4554 
4555 /*@C
4556    MatGetRowMax - Gets the maximum value (of the real part) of each
4557         row of the matrix
4558 
4559    Logically Collective on Mat and Vec
4560 
4561    Input Parameters:
4562 .  mat - the matrix
4563 
4564    Output Parameter:
4565 +  v - the vector for storing the maximums
4566 -  idx - the indices of the column found for each row (optional)
4567 
4568    Level: intermediate
4569 
4570    Notes: The result of this call are the same as if one converted the matrix to dense format
4571       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4572 
4573     This code is only implemented for a couple of matrix formats.
4574 
4575    Concepts: matrices^getting row maximums
4576 
4577 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubmatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4578 @*/
4579 PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4580 {
4581   PetscErrorCode ierr;
4582 
4583   PetscFunctionBegin;
4584   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4585   PetscValidType(mat,1);
4586   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4587   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4588   if (!mat->ops->getrowmax) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4589   MatCheckPreallocated(mat,1);
4590 
4591   ierr = (*mat->ops->getrowmax)(mat,v,idx);CHKERRQ(ierr);
4592   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4593   PetscFunctionReturn(0);
4594 }
4595 
4596 /*@C
4597    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4598         row of the matrix
4599 
4600    Logically Collective on Mat and Vec
4601 
4602    Input Parameters:
4603 .  mat - the matrix
4604 
4605    Output Parameter:
4606 +  v - the vector for storing the maximums
4607 -  idx - the indices of the column found for each row (or NULL if not needed)
4608 
4609    Level: intermediate
4610 
4611    Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
4612     row is 0 (the first column).
4613 
4614     This code is only implemented for a couple of matrix formats.
4615 
4616    Concepts: matrices^getting row maximums
4617 
4618 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubmatrix(), MatGetRowMax(), MatGetRowMin()
4619 @*/
4620 PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4621 {
4622   PetscErrorCode ierr;
4623 
4624   PetscFunctionBegin;
4625   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4626   PetscValidType(mat,1);
4627   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4628   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4629   if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4630   MatCheckPreallocated(mat,1);
4631   if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);}
4632 
4633   ierr = (*mat->ops->getrowmaxabs)(mat,v,idx);CHKERRQ(ierr);
4634   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4635   PetscFunctionReturn(0);
4636 }
4637 
4638 /*@
4639    MatGetRowSum - Gets the sum of each row of the matrix
4640 
4641    Logically Collective on Mat and Vec
4642 
4643    Input Parameters:
4644 .  mat - the matrix
4645 
4646    Output Parameter:
4647 .  v - the vector for storing the sum of rows
4648 
4649    Level: intermediate
4650 
4651    Notes: This code is slow since it is not currently specialized for different formats
4652 
4653    Concepts: matrices^getting row sums
4654 
4655 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubmatrix(), MatGetRowMax(), MatGetRowMin()
4656 @*/
4657 PetscErrorCode MatGetRowSum(Mat mat, Vec v)
4658 {
4659   PetscInt       start = 0, end = 0, row;
4660   PetscScalar    *array;
4661   PetscErrorCode ierr;
4662 
4663   PetscFunctionBegin;
4664   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4665   PetscValidType(mat,1);
4666   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4667   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4668   MatCheckPreallocated(mat,1);
4669   ierr = MatGetOwnershipRange(mat, &start, &end);CHKERRQ(ierr);
4670   ierr = VecGetArray(v, &array);CHKERRQ(ierr);
4671   for (row = start; row < end; ++row) {
4672     PetscInt          ncols, col;
4673     const PetscInt    *cols;
4674     const PetscScalar *vals;
4675 
4676     array[row - start] = 0.0;
4677 
4678     ierr = MatGetRow(mat, row, &ncols, &cols, &vals);CHKERRQ(ierr);
4679     for (col = 0; col < ncols; col++) {
4680       array[row - start] += vals[col];
4681     }
4682     ierr = MatRestoreRow(mat, row, &ncols, &cols, &vals);CHKERRQ(ierr);
4683   }
4684   ierr = VecRestoreArray(v, &array);CHKERRQ(ierr);
4685   ierr = PetscObjectStateIncrease((PetscObject) v);CHKERRQ(ierr);
4686   PetscFunctionReturn(0);
4687 }
4688 
4689 /*@
4690    MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
4691 
4692    Collective on Mat
4693 
4694    Input Parameter:
4695 +  mat - the matrix to transpose
4696 -  reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX
4697 
4698    Output Parameters:
4699 .  B - the transpose
4700 
4701    Notes:
4702      If you use MAT_INPLACE_MATRIX then you must pass in &mat for B
4703 
4704      MAT_REUSE_MATRIX causes the B matrix from a previous call to this function with MAT_INITIAL_MATRIX to be used
4705 
4706      Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed.
4707 
4708    Level: intermediate
4709 
4710    Concepts: matrices^transposing
4711 
4712 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4713 @*/
4714 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4715 {
4716   PetscErrorCode ierr;
4717 
4718   PetscFunctionBegin;
4719   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4720   PetscValidType(mat,1);
4721   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4722   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4723   if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4724   if (reuse == MAT_INPLACE_MATRIX && mat != *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires last matrix to match first");
4725   if (reuse == MAT_REUSE_MATRIX && mat == *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Perhaps you mean MAT_INPLACE_MATRIX");
4726   MatCheckPreallocated(mat,1);
4727 
4728   ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4729   ierr = (*mat->ops->transpose)(mat,reuse,B);CHKERRQ(ierr);
4730   ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4731   if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);}
4732   PetscFunctionReturn(0);
4733 }
4734 
4735 /*@
4736    MatIsTranspose - Test whether a matrix is another one's transpose,
4737         or its own, in which case it tests symmetry.
4738 
4739    Collective on Mat
4740 
4741    Input Parameter:
4742 +  A - the matrix to test
4743 -  B - the matrix to test against, this can equal the first parameter
4744 
4745    Output Parameters:
4746 .  flg - the result
4747 
4748    Notes:
4749    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4750    has a running time of the order of the number of nonzeros; the parallel
4751    test involves parallel copies of the block-offdiagonal parts of the matrix.
4752 
4753    Level: intermediate
4754 
4755    Concepts: matrices^transposing, matrix^symmetry
4756 
4757 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4758 @*/
4759 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4760 {
4761   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4762 
4763   PetscFunctionBegin;
4764   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4765   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4766   PetscValidPointer(flg,3);
4767   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);CHKERRQ(ierr);
4768   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);CHKERRQ(ierr);
4769   *flg = PETSC_FALSE;
4770   if (f && g) {
4771     if (f == g) {
4772       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
4773     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4774   } else {
4775     MatType mattype;
4776     if (!f) {
4777       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
4778     } else {
4779       ierr = MatGetType(B,&mattype);CHKERRQ(ierr);
4780     }
4781     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
4782   }
4783   PetscFunctionReturn(0);
4784 }
4785 
4786 /*@
4787    MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate.
4788 
4789    Collective on Mat
4790 
4791    Input Parameter:
4792 +  mat - the matrix to transpose and complex conjugate
4793 -  reuse - MAT_INITIAL_MATRIX to create a new matrix, MAT_INPLACE_MATRIX to reuse the first argument to store the transpose
4794 
4795    Output Parameters:
4796 .  B - the Hermitian
4797 
4798    Level: intermediate
4799 
4800    Concepts: matrices^transposing, complex conjugatex
4801 
4802 .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4803 @*/
4804 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
4805 {
4806   PetscErrorCode ierr;
4807 
4808   PetscFunctionBegin;
4809   ierr = MatTranspose(mat,reuse,B);CHKERRQ(ierr);
4810 #if defined(PETSC_USE_COMPLEX)
4811   ierr = MatConjugate(*B);CHKERRQ(ierr);
4812 #endif
4813   PetscFunctionReturn(0);
4814 }
4815 
4816 /*@
4817    MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,
4818 
4819    Collective on Mat
4820 
4821    Input Parameter:
4822 +  A - the matrix to test
4823 -  B - the matrix to test against, this can equal the first parameter
4824 
4825    Output Parameters:
4826 .  flg - the result
4827 
4828    Notes:
4829    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4830    has a running time of the order of the number of nonzeros; the parallel
4831    test involves parallel copies of the block-offdiagonal parts of the matrix.
4832 
4833    Level: intermediate
4834 
4835    Concepts: matrices^transposing, matrix^symmetry
4836 
4837 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
4838 @*/
4839 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4840 {
4841   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4842 
4843   PetscFunctionBegin;
4844   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4845   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4846   PetscValidPointer(flg,3);
4847   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);CHKERRQ(ierr);
4848   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);CHKERRQ(ierr);
4849   if (f && g) {
4850     if (f==g) {
4851       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
4852     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
4853   }
4854   PetscFunctionReturn(0);
4855 }
4856 
4857 /*@
4858    MatPermute - Creates a new matrix with rows and columns permuted from the
4859    original.
4860 
4861    Collective on Mat
4862 
4863    Input Parameters:
4864 +  mat - the matrix to permute
4865 .  row - row permutation, each processor supplies only the permutation for its rows
4866 -  col - column permutation, each processor supplies only the permutation for its columns
4867 
4868    Output Parameters:
4869 .  B - the permuted matrix
4870 
4871    Level: advanced
4872 
4873    Note:
4874    The index sets map from row/col of permuted matrix to row/col of original matrix.
4875    The index sets should be on the same communicator as Mat and have the same local sizes.
4876 
4877    Concepts: matrices^permuting
4878 
4879 .seealso: MatGetOrdering(), ISAllGather()
4880 
4881 @*/
4882 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
4883 {
4884   PetscErrorCode ierr;
4885 
4886   PetscFunctionBegin;
4887   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4888   PetscValidType(mat,1);
4889   PetscValidHeaderSpecific(row,IS_CLASSID,2);
4890   PetscValidHeaderSpecific(col,IS_CLASSID,3);
4891   PetscValidPointer(B,4);
4892   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4893   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4894   if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
4895   MatCheckPreallocated(mat,1);
4896 
4897   ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr);
4898   ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);
4899   PetscFunctionReturn(0);
4900 }
4901 
4902 /*@
4903    MatEqual - Compares two matrices.
4904 
4905    Collective on Mat
4906 
4907    Input Parameters:
4908 +  A - the first matrix
4909 -  B - the second matrix
4910 
4911    Output Parameter:
4912 .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
4913 
4914    Level: intermediate
4915 
4916    Concepts: matrices^equality between
4917 @*/
4918 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool  *flg)
4919 {
4920   PetscErrorCode ierr;
4921 
4922   PetscFunctionBegin;
4923   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4924   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4925   PetscValidType(A,1);
4926   PetscValidType(B,2);
4927   PetscValidIntPointer(flg,3);
4928   PetscCheckSameComm(A,1,B,2);
4929   MatCheckPreallocated(B,2);
4930   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4931   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4932   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);
4933   if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4934   if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4935   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);
4936   MatCheckPreallocated(A,1);
4937 
4938   ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr);
4939   PetscFunctionReturn(0);
4940 }
4941 
4942 /*@C
4943    MatDiagonalScale - Scales a matrix on the left and right by diagonal
4944    matrices that are stored as vectors.  Either of the two scaling
4945    matrices can be NULL.
4946 
4947    Collective on Mat
4948 
4949    Input Parameters:
4950 +  mat - the matrix to be scaled
4951 .  l - the left scaling vector (or NULL)
4952 -  r - the right scaling vector (or NULL)
4953 
4954    Notes:
4955    MatDiagonalScale() computes A = LAR, where
4956    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
4957    The L scales the rows of the matrix, the R scales the columns of the matrix.
4958 
4959    Level: intermediate
4960 
4961    Concepts: matrices^diagonal scaling
4962    Concepts: diagonal scaling of matrices
4963 
4964 .seealso: MatScale()
4965 @*/
4966 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
4967 {
4968   PetscErrorCode ierr;
4969 
4970   PetscFunctionBegin;
4971   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4972   PetscValidType(mat,1);
4973   if (!mat->ops->diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4974   if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);}
4975   if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);}
4976   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4977   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4978   MatCheckPreallocated(mat,1);
4979 
4980   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4981   ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr);
4982   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4983   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4984 #if defined(PETSC_HAVE_CUSP)
4985   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4986     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4987   }
4988 #elif defined(PETSC_HAVE_VIENNACL)
4989   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
4990     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
4991   }
4992 #elif defined(PETSC_HAVE_VECCUDA)
4993   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
4994     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
4995   }
4996 #endif
4997   PetscFunctionReturn(0);
4998 }
4999 
5000 /*@
5001     MatScale - Scales all elements of a matrix by a given number.
5002 
5003     Logically Collective on Mat
5004 
5005     Input Parameters:
5006 +   mat - the matrix to be scaled
5007 -   a  - the scaling value
5008 
5009     Output Parameter:
5010 .   mat - the scaled matrix
5011 
5012     Level: intermediate
5013 
5014     Concepts: matrices^scaling all entries
5015 
5016 .seealso: MatDiagonalScale()
5017 @*/
5018 PetscErrorCode MatScale(Mat mat,PetscScalar a)
5019 {
5020   PetscErrorCode ierr;
5021 
5022   PetscFunctionBegin;
5023   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5024   PetscValidType(mat,1);
5025   if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5026   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5027   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5028   PetscValidLogicalCollectiveScalar(mat,a,2);
5029   MatCheckPreallocated(mat,1);
5030 
5031   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5032   if (a != (PetscScalar)1.0) {
5033     ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr);
5034     ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5035 #if defined(PETSC_HAVE_CUSP)
5036     if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5037       mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5038     }
5039 #elif defined(PETSC_HAVE_VIENNACL)
5040     if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5041       mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5042     }
5043 #elif defined(PETSC_HAVE_VECCUDA)
5044     if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5045       mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5046     }
5047 #endif
5048   }
5049   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5050   PetscFunctionReturn(0);
5051 }
5052 
5053 /*@
5054    MatNorm - Calculates various norms of a matrix.
5055 
5056    Collective on Mat
5057 
5058    Input Parameters:
5059 +  mat - the matrix
5060 -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
5061 
5062    Output Parameters:
5063 .  nrm - the resulting norm
5064 
5065    Level: intermediate
5066 
5067    Concepts: matrices^norm
5068    Concepts: norm^of matrix
5069 @*/
5070 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
5071 {
5072   PetscErrorCode ierr;
5073 
5074   PetscFunctionBegin;
5075   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5076   PetscValidType(mat,1);
5077   PetscValidScalarPointer(nrm,3);
5078 
5079   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5080   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5081   if (!mat->ops->norm) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5082   MatCheckPreallocated(mat,1);
5083 
5084   ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr);
5085   PetscFunctionReturn(0);
5086 }
5087 
5088 /*
5089      This variable is used to prevent counting of MatAssemblyBegin() that
5090    are called from within a MatAssemblyEnd().
5091 */
5092 static PetscInt MatAssemblyEnd_InUse = 0;
5093 /*@
5094    MatAssemblyBegin - Begins assembling the matrix.  This routine should
5095    be called after completing all calls to MatSetValues().
5096 
5097    Collective on Mat
5098 
5099    Input Parameters:
5100 +  mat - the matrix
5101 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5102 
5103    Notes:
5104    MatSetValues() generally caches the values.  The matrix is ready to
5105    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5106    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5107    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5108    using the matrix.
5109 
5110    ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the
5111    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
5112    a global collective operation requring all processes that share the matrix.
5113 
5114    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5115    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5116    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5117 
5118    Level: beginner
5119 
5120    Concepts: matrices^assembling
5121 
5122 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
5123 @*/
5124 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
5125 {
5126   PetscErrorCode ierr;
5127 
5128   PetscFunctionBegin;
5129   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5130   PetscValidType(mat,1);
5131   MatCheckPreallocated(mat,1);
5132   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
5133   if (mat->assembled) {
5134     mat->was_assembled = PETSC_TRUE;
5135     mat->assembled     = PETSC_FALSE;
5136   }
5137   if (!MatAssemblyEnd_InUse) {
5138     ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5139     if (mat->ops->assemblybegin) {ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
5140     ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5141   } else if (mat->ops->assemblybegin) {
5142     ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);
5143   }
5144   PetscFunctionReturn(0);
5145 }
5146 
5147 /*@
5148    MatAssembled - Indicates if a matrix has been assembled and is ready for
5149      use; for example, in matrix-vector product.
5150 
5151    Not Collective
5152 
5153    Input Parameter:
5154 .  mat - the matrix
5155 
5156    Output Parameter:
5157 .  assembled - PETSC_TRUE or PETSC_FALSE
5158 
5159    Level: advanced
5160 
5161    Concepts: matrices^assembled?
5162 
5163 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
5164 @*/
5165 PetscErrorCode MatAssembled(Mat mat,PetscBool  *assembled)
5166 {
5167   PetscFunctionBegin;
5168   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5169   PetscValidType(mat,1);
5170   PetscValidPointer(assembled,2);
5171   *assembled = mat->assembled;
5172   PetscFunctionReturn(0);
5173 }
5174 
5175 /*@
5176    MatAssemblyEnd - Completes assembling the matrix.  This routine should
5177    be called after MatAssemblyBegin().
5178 
5179    Collective on Mat
5180 
5181    Input Parameters:
5182 +  mat - the matrix
5183 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5184 
5185    Options Database Keys:
5186 +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
5187 .  -mat_view ::ascii_info_detail - Prints more detailed info
5188 .  -mat_view - Prints matrix in ASCII format
5189 .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
5190 .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
5191 .  -display <name> - Sets display name (default is host)
5192 .  -draw_pause <sec> - Sets number of seconds to pause after display
5193 .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab )
5194 .  -viewer_socket_machine <machine> - Machine to use for socket
5195 .  -viewer_socket_port <port> - Port number to use for socket
5196 -  -mat_view binary:filename[:append] - Save matrix to file in binary format
5197 
5198    Notes:
5199    MatSetValues() generally caches the values.  The matrix is ready to
5200    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5201    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5202    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5203    using the matrix.
5204 
5205    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5206    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5207    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5208 
5209    Level: beginner
5210 
5211 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
5212 @*/
5213 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
5214 {
5215   PetscErrorCode  ierr;
5216   static PetscInt inassm = 0;
5217   PetscBool       flg    = PETSC_FALSE;
5218 
5219   PetscFunctionBegin;
5220   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5221   PetscValidType(mat,1);
5222 
5223   inassm++;
5224   MatAssemblyEnd_InUse++;
5225   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
5226     ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5227     if (mat->ops->assemblyend) {
5228       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5229     }
5230     ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5231   } else if (mat->ops->assemblyend) {
5232     ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5233   }
5234 
5235   /* Flush assembly is not a true assembly */
5236   if (type != MAT_FLUSH_ASSEMBLY) {
5237     mat->assembled = PETSC_TRUE; mat->num_ass++;
5238   }
5239   mat->insertmode = NOT_SET_VALUES;
5240   MatAssemblyEnd_InUse--;
5241   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5242   if (!mat->symmetric_eternal) {
5243     mat->symmetric_set              = PETSC_FALSE;
5244     mat->hermitian_set              = PETSC_FALSE;
5245     mat->structurally_symmetric_set = PETSC_FALSE;
5246   }
5247 #if defined(PETSC_HAVE_CUSP)
5248   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5249     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5250   }
5251 #elif defined(PETSC_HAVE_VIENNACL)
5252   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5253     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5254   }
5255 #elif defined(PETSC_HAVE_VECCUDA)
5256   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5257     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5258   }
5259 #endif
5260   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
5261     ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5262 
5263     if (mat->checksymmetryonassembly) {
5264       ierr = MatIsSymmetric(mat,mat->checksymmetrytol,&flg);CHKERRQ(ierr);
5265       if (flg) {
5266         ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5267       } else {
5268         ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5269       }
5270     }
5271     if (mat->nullsp && mat->checknullspaceonassembly) {
5272       ierr = MatNullSpaceTest(mat->nullsp,mat,NULL);CHKERRQ(ierr);
5273     }
5274   }
5275   inassm--;
5276   PetscFunctionReturn(0);
5277 }
5278 
5279 /*@
5280    MatSetOption - Sets a parameter option for a matrix. Some options
5281    may be specific to certain storage formats.  Some options
5282    determine how values will be inserted (or added). Sorted,
5283    row-oriented input will generally assemble the fastest. The default
5284    is row-oriented.
5285 
5286    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5287 
5288    Input Parameters:
5289 +  mat - the matrix
5290 .  option - the option, one of those listed below (and possibly others),
5291 -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5292 
5293   Options Describing Matrix Structure:
5294 +    MAT_SPD - symmetric positive definite
5295 .    MAT_SYMMETRIC - symmetric in terms of both structure and value
5296 .    MAT_HERMITIAN - transpose is the complex conjugation
5297 .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5298 -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5299                             you set to be kept with all future use of the matrix
5300                             including after MatAssemblyBegin/End() which could
5301                             potentially change the symmetry structure, i.e. you
5302                             KNOW the matrix will ALWAYS have the property you set.
5303 
5304 
5305    Options For Use with MatSetValues():
5306    Insert a logically dense subblock, which can be
5307 .    MAT_ROW_ORIENTED - row-oriented (default)
5308 
5309    Note these options reflect the data you pass in with MatSetValues(); it has
5310    nothing to do with how the data is stored internally in the matrix
5311    data structure.
5312 
5313    When (re)assembling a matrix, we can restrict the input for
5314    efficiency/debugging purposes.  These options include:
5315 +    MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow)
5316 .    MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
5317 .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
5318 .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
5319 .    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
5320 .    MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
5321         any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
5322         performance for very large process counts.
5323 -    MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset
5324         of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly
5325         functions, instead sending only neighbor messages.
5326 
5327    Notes:
5328    Except for MAT_UNUSED_NONZERO_LOCATION_ERR and  MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg!
5329 
5330    Some options are relevant only for particular matrix types and
5331    are thus ignored by others.  Other options are not supported by
5332    certain matrix types and will generate an error message if set.
5333 
5334    If using a Fortran 77 module to compute a matrix, one may need to
5335    use the column-oriented option (or convert to the row-oriented
5336    format).
5337 
5338    MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
5339    that would generate a new entry in the nonzero structure is instead
5340    ignored.  Thus, if memory has not alredy been allocated for this particular
5341    data, then the insertion is ignored. For dense matrices, in which
5342    the entire array is allocated, no entries are ever ignored.
5343    Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5344 
5345    MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5346    that would generate a new entry in the nonzero structure instead produces
5347    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
5348 
5349    MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5350    that would generate a new entry that has not been preallocated will
5351    instead produce an error. (Currently supported for AIJ and BAIJ formats
5352    only.) This is a useful flag when debugging matrix memory preallocation.
5353    If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5354 
5355    MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for
5356    other processors should be dropped, rather than stashed.
5357    This is useful if you know that the "owning" processor is also
5358    always generating the correct matrix entries, so that PETSc need
5359    not transfer duplicate entries generated on another processor.
5360 
5361    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5362    searches during matrix assembly. When this flag is set, the hash table
5363    is created during the first Matrix Assembly. This hash table is
5364    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5365    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5366    should be used with MAT_USE_HASH_TABLE flag. This option is currently
5367    supported by MATMPIBAIJ format only.
5368 
5369    MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries
5370    are kept in the nonzero structure
5371 
5372    MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
5373    a zero location in the matrix
5374 
5375    MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types
5376 
5377    MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the
5378         zero row routines and thus improves performance for very large process counts.
5379 
5380    MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular
5381         part of the matrix (since they should match the upper triangular part).
5382 
5383    Notes: Can only be called after MatSetSizes() and MatSetType() have been set.
5384 
5385    Level: intermediate
5386 
5387    Concepts: matrices^setting options
5388 
5389 .seealso:  MatOption, Mat
5390 
5391 @*/
5392 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg)
5393 {
5394   PetscErrorCode ierr;
5395 
5396   PetscFunctionBegin;
5397   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5398   PetscValidType(mat,1);
5399   if (op > 0) {
5400     PetscValidLogicalCollectiveEnum(mat,op,2);
5401     PetscValidLogicalCollectiveBool(mat,flg,3);
5402   }
5403 
5404   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);
5405   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()");
5406 
5407   switch (op) {
5408   case MAT_NO_OFF_PROC_ENTRIES:
5409     mat->nooffprocentries = flg;
5410     PetscFunctionReturn(0);
5411     break;
5412   case MAT_SUBSET_OFF_PROC_ENTRIES:
5413     mat->subsetoffprocentries = flg;
5414     PetscFunctionReturn(0);
5415   case MAT_NO_OFF_PROC_ZERO_ROWS:
5416     mat->nooffproczerorows = flg;
5417     PetscFunctionReturn(0);
5418     break;
5419   case MAT_SPD:
5420     mat->spd_set = PETSC_TRUE;
5421     mat->spd     = flg;
5422     if (flg) {
5423       mat->symmetric                  = PETSC_TRUE;
5424       mat->structurally_symmetric     = PETSC_TRUE;
5425       mat->symmetric_set              = PETSC_TRUE;
5426       mat->structurally_symmetric_set = PETSC_TRUE;
5427     }
5428     break;
5429   case MAT_SYMMETRIC:
5430     mat->symmetric = flg;
5431     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5432     mat->symmetric_set              = PETSC_TRUE;
5433     mat->structurally_symmetric_set = flg;
5434     break;
5435   case MAT_HERMITIAN:
5436     mat->hermitian = flg;
5437     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5438     mat->hermitian_set              = PETSC_TRUE;
5439     mat->structurally_symmetric_set = flg;
5440     break;
5441   case MAT_STRUCTURALLY_SYMMETRIC:
5442     mat->structurally_symmetric     = flg;
5443     mat->structurally_symmetric_set = PETSC_TRUE;
5444     break;
5445   case MAT_SYMMETRY_ETERNAL:
5446     mat->symmetric_eternal = flg;
5447     break;
5448   default:
5449     break;
5450   }
5451   if (mat->ops->setoption) {
5452     ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr);
5453   }
5454   PetscFunctionReturn(0);
5455 }
5456 
5457 /*@
5458    MatGetOption - Gets a parameter option that has been set for a matrix.
5459 
5460    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5461 
5462    Input Parameters:
5463 +  mat - the matrix
5464 -  option - the option, this only responds to certain options, check the code for which ones
5465 
5466    Output Parameter:
5467 .  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5468 
5469     Notes: Can only be called after MatSetSizes() and MatSetType() have been set.
5470 
5471    Level: intermediate
5472 
5473    Concepts: matrices^setting options
5474 
5475 .seealso:  MatOption, MatSetOption()
5476 
5477 @*/
5478 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg)
5479 {
5480   PetscFunctionBegin;
5481   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5482   PetscValidType(mat,1);
5483 
5484   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);
5485   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()");
5486 
5487   switch (op) {
5488   case MAT_NO_OFF_PROC_ENTRIES:
5489     *flg = mat->nooffprocentries;
5490     break;
5491   case MAT_NO_OFF_PROC_ZERO_ROWS:
5492     *flg = mat->nooffproczerorows;
5493     break;
5494   case MAT_SYMMETRIC:
5495     *flg = mat->symmetric;
5496     break;
5497   case MAT_HERMITIAN:
5498     *flg = mat->hermitian;
5499     break;
5500   case MAT_STRUCTURALLY_SYMMETRIC:
5501     *flg = mat->structurally_symmetric;
5502     break;
5503   case MAT_SYMMETRY_ETERNAL:
5504     *flg = mat->symmetric_eternal;
5505     break;
5506   default:
5507     break;
5508   }
5509   PetscFunctionReturn(0);
5510 }
5511 
5512 /*@
5513    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5514    this routine retains the old nonzero structure.
5515 
5516    Logically Collective on Mat
5517 
5518    Input Parameters:
5519 .  mat - the matrix
5520 
5521    Level: intermediate
5522 
5523    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.
5524    See the Performance chapter of the users manual for information on preallocating matrices.
5525 
5526    Concepts: matrices^zeroing
5527 
5528 .seealso: MatZeroRows()
5529 @*/
5530 PetscErrorCode MatZeroEntries(Mat mat)
5531 {
5532   PetscErrorCode ierr;
5533 
5534   PetscFunctionBegin;
5535   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5536   PetscValidType(mat,1);
5537   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5538   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");
5539   if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5540   MatCheckPreallocated(mat,1);
5541 
5542   ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5543   ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
5544   ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5545   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5546 #if defined(PETSC_HAVE_CUSP)
5547   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5548     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5549   }
5550 #elif defined(PETSC_HAVE_VIENNACL)
5551   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5552     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5553   }
5554 #elif defined(PETSC_HAVE_VECCUDA)
5555   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5556     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5557   }
5558 #endif
5559   PetscFunctionReturn(0);
5560 }
5561 
5562 /*@C
5563    MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal)
5564    of a set of rows and columns of a matrix.
5565 
5566    Collective on Mat
5567 
5568    Input Parameters:
5569 +  mat - the matrix
5570 .  numRows - the number of rows to remove
5571 .  rows - the global row indices
5572 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5573 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5574 -  b - optional vector of right hand side, that will be adjusted by provided solution
5575 
5576    Notes:
5577    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5578 
5579    The user can set a value in the diagonal entry (or for the AIJ and
5580    row formats can optionally remove the main diagonal entry from the
5581    nonzero structure as well, by passing 0.0 as the final argument).
5582 
5583    For the parallel case, all processes that share the matrix (i.e.,
5584    those in the communicator used for matrix creation) MUST call this
5585    routine, regardless of whether any rows being zeroed are owned by
5586    them.
5587 
5588    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5589    list only rows local to itself).
5590 
5591    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5592 
5593    Level: intermediate
5594 
5595    Concepts: matrices^zeroing rows
5596 
5597 .seealso: MatZeroRowsIS(), MatZeroRows(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5598           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5599 @*/
5600 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5601 {
5602   PetscErrorCode ierr;
5603 
5604   PetscFunctionBegin;
5605   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5606   PetscValidType(mat,1);
5607   if (numRows) PetscValidIntPointer(rows,3);
5608   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5609   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5610   if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5611   MatCheckPreallocated(mat,1);
5612 
5613   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5614   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5615   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5616 #if defined(PETSC_HAVE_CUSP)
5617   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5618     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5619   }
5620 #elif defined(PETSC_HAVE_VIENNACL)
5621   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5622     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5623   }
5624 #elif defined(PETSC_HAVE_VECCUDA)
5625   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5626     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5627   }
5628 #endif
5629   PetscFunctionReturn(0);
5630 }
5631 
5632 /*@C
5633    MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
5634    of a set of rows and columns of a matrix.
5635 
5636    Collective on Mat
5637 
5638    Input Parameters:
5639 +  mat - the matrix
5640 .  is - the rows to zero
5641 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5642 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5643 -  b - optional vector of right hand side, that will be adjusted by provided solution
5644 
5645    Notes:
5646    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5647 
5648    The user can set a value in the diagonal entry (or for the AIJ and
5649    row formats can optionally remove the main diagonal entry from the
5650    nonzero structure as well, by passing 0.0 as the final argument).
5651 
5652    For the parallel case, all processes that share the matrix (i.e.,
5653    those in the communicator used for matrix creation) MUST call this
5654    routine, regardless of whether any rows being zeroed are owned by
5655    them.
5656 
5657    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5658    list only rows local to itself).
5659 
5660    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5661 
5662    Level: intermediate
5663 
5664    Concepts: matrices^zeroing rows
5665 
5666 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5667           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRows(), MatZeroRowsColumnsStencil()
5668 @*/
5669 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5670 {
5671   PetscErrorCode ierr;
5672   PetscInt       numRows;
5673   const PetscInt *rows;
5674 
5675   PetscFunctionBegin;
5676   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5677   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5678   PetscValidType(mat,1);
5679   PetscValidType(is,2);
5680   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5681   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5682   ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5683   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5684   PetscFunctionReturn(0);
5685 }
5686 
5687 /*@C
5688    MatZeroRows - Zeros all entries (except possibly the main diagonal)
5689    of a set of rows of a matrix.
5690 
5691    Collective on Mat
5692 
5693    Input Parameters:
5694 +  mat - the matrix
5695 .  numRows - the number of rows to remove
5696 .  rows - the global row indices
5697 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5698 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5699 -  b - optional vector of right hand side, that will be adjusted by provided solution
5700 
5701    Notes:
5702    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5703    but does not release memory.  For the dense and block diagonal
5704    formats this does not alter the nonzero structure.
5705 
5706    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5707    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5708    merely zeroed.
5709 
5710    The user can set a value in the diagonal entry (or for the AIJ and
5711    row formats can optionally remove the main diagonal entry from the
5712    nonzero structure as well, by passing 0.0 as the final argument).
5713 
5714    For the parallel case, all processes that share the matrix (i.e.,
5715    those in the communicator used for matrix creation) MUST call this
5716    routine, regardless of whether any rows being zeroed are owned by
5717    them.
5718 
5719    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5720    list only rows local to itself).
5721 
5722    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5723    owns that are to be zeroed. This saves a global synchronization in the implementation.
5724 
5725    Level: intermediate
5726 
5727    Concepts: matrices^zeroing rows
5728 
5729 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5730           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5731 @*/
5732 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5733 {
5734   PetscErrorCode ierr;
5735 
5736   PetscFunctionBegin;
5737   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5738   PetscValidType(mat,1);
5739   if (numRows) PetscValidIntPointer(rows,3);
5740   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5741   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5742   if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5743   MatCheckPreallocated(mat,1);
5744 
5745   ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5746   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5747   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5748 #if defined(PETSC_HAVE_CUSP)
5749   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5750     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5751   }
5752 #elif defined(PETSC_HAVE_VIENNACL)
5753   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5754     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5755   }
5756 #elif defined(PETSC_HAVE_VECCUDA)
5757   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5758     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5759   }
5760 #endif
5761   PetscFunctionReturn(0);
5762 }
5763 
5764 /*@C
5765    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5766    of a set of rows of a matrix.
5767 
5768    Collective on Mat
5769 
5770    Input Parameters:
5771 +  mat - the matrix
5772 .  is - index set of rows to remove
5773 .  diag - value put in all diagonals of eliminated rows
5774 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5775 -  b - optional vector of right hand side, that will be adjusted by provided solution
5776 
5777    Notes:
5778    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5779    but does not release memory.  For the dense and block diagonal
5780    formats this does not alter the nonzero structure.
5781 
5782    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5783    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5784    merely zeroed.
5785 
5786    The user can set a value in the diagonal entry (or for the AIJ and
5787    row formats can optionally remove the main diagonal entry from the
5788    nonzero structure as well, by passing 0.0 as the final argument).
5789 
5790    For the parallel case, all processes that share the matrix (i.e.,
5791    those in the communicator used for matrix creation) MUST call this
5792    routine, regardless of whether any rows being zeroed are owned by
5793    them.
5794 
5795    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5796    list only rows local to itself).
5797 
5798    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5799    owns that are to be zeroed. This saves a global synchronization in the implementation.
5800 
5801    Level: intermediate
5802 
5803    Concepts: matrices^zeroing rows
5804 
5805 .seealso: MatZeroRows(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5806           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5807 @*/
5808 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5809 {
5810   PetscInt       numRows;
5811   const PetscInt *rows;
5812   PetscErrorCode ierr;
5813 
5814   PetscFunctionBegin;
5815   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5816   PetscValidType(mat,1);
5817   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5818   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5819   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5820   ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5821   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5822   PetscFunctionReturn(0);
5823 }
5824 
5825 /*@C
5826    MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
5827    of a set of rows of a matrix. These rows must be local to the process.
5828 
5829    Collective on Mat
5830 
5831    Input Parameters:
5832 +  mat - the matrix
5833 .  numRows - the number of rows to remove
5834 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
5835 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5836 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5837 -  b - optional vector of right hand side, that will be adjusted by provided solution
5838 
5839    Notes:
5840    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5841    but does not release memory.  For the dense and block diagonal
5842    formats this does not alter the nonzero structure.
5843 
5844    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5845    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5846    merely zeroed.
5847 
5848    The user can set a value in the diagonal entry (or for the AIJ and
5849    row formats can optionally remove the main diagonal entry from the
5850    nonzero structure as well, by passing 0.0 as the final argument).
5851 
5852    For the parallel case, all processes that share the matrix (i.e.,
5853    those in the communicator used for matrix creation) MUST call this
5854    routine, regardless of whether any rows being zeroed are owned by
5855    them.
5856 
5857    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5858    list only rows local to itself).
5859 
5860    The grid coordinates are across the entire grid, not just the local portion
5861 
5862    In Fortran idxm and idxn should be declared as
5863 $     MatStencil idxm(4,m)
5864    and the values inserted using
5865 $    idxm(MatStencil_i,1) = i
5866 $    idxm(MatStencil_j,1) = j
5867 $    idxm(MatStencil_k,1) = k
5868 $    idxm(MatStencil_c,1) = c
5869    etc
5870 
5871    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5872    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5873    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5874    DM_BOUNDARY_PERIODIC boundary type.
5875 
5876    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
5877    a single value per point) you can skip filling those indices.
5878 
5879    Level: intermediate
5880 
5881    Concepts: matrices^zeroing rows
5882 
5883 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsl(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5884           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5885 @*/
5886 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5887 {
5888   PetscInt       dim     = mat->stencil.dim;
5889   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
5890   PetscInt       *dims   = mat->stencil.dims+1;
5891   PetscInt       *starts = mat->stencil.starts;
5892   PetscInt       *dxm    = (PetscInt*) rows;
5893   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
5894   PetscErrorCode ierr;
5895 
5896   PetscFunctionBegin;
5897   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5898   PetscValidType(mat,1);
5899   if (numRows) PetscValidIntPointer(rows,3);
5900 
5901   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
5902   for (i = 0; i < numRows; ++i) {
5903     /* Skip unused dimensions (they are ordered k, j, i, c) */
5904     for (j = 0; j < 3-sdim; ++j) dxm++;
5905     /* Local index in X dir */
5906     tmp = *dxm++ - starts[0];
5907     /* Loop over remaining dimensions */
5908     for (j = 0; j < dim-1; ++j) {
5909       /* If nonlocal, set index to be negative */
5910       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5911       /* Update local index */
5912       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5913     }
5914     /* Skip component slot if necessary */
5915     if (mat->stencil.noc) dxm++;
5916     /* Local row number */
5917     if (tmp >= 0) {
5918       jdxm[numNewRows++] = tmp;
5919     }
5920   }
5921   ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
5922   ierr = PetscFree(jdxm);CHKERRQ(ierr);
5923   PetscFunctionReturn(0);
5924 }
5925 
5926 /*@C
5927    MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal)
5928    of a set of rows and columns of a matrix.
5929 
5930    Collective on Mat
5931 
5932    Input Parameters:
5933 +  mat - the matrix
5934 .  numRows - the number of rows/columns to remove
5935 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
5936 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5937 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5938 -  b - optional vector of right hand side, that will be adjusted by provided solution
5939 
5940    Notes:
5941    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5942    but does not release memory.  For the dense and block diagonal
5943    formats this does not alter the nonzero structure.
5944 
5945    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5946    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5947    merely zeroed.
5948 
5949    The user can set a value in the diagonal entry (or for the AIJ and
5950    row formats can optionally remove the main diagonal entry from the
5951    nonzero structure as well, by passing 0.0 as the final argument).
5952 
5953    For the parallel case, all processes that share the matrix (i.e.,
5954    those in the communicator used for matrix creation) MUST call this
5955    routine, regardless of whether any rows being zeroed are owned by
5956    them.
5957 
5958    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5959    list only rows local to itself, but the row/column numbers are given in local numbering).
5960 
5961    The grid coordinates are across the entire grid, not just the local portion
5962 
5963    In Fortran idxm and idxn should be declared as
5964 $     MatStencil idxm(4,m)
5965    and the values inserted using
5966 $    idxm(MatStencil_i,1) = i
5967 $    idxm(MatStencil_j,1) = j
5968 $    idxm(MatStencil_k,1) = k
5969 $    idxm(MatStencil_c,1) = c
5970    etc
5971 
5972    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5973    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5974    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5975    DM_BOUNDARY_PERIODIC boundary type.
5976 
5977    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
5978    a single value per point) you can skip filling those indices.
5979 
5980    Level: intermediate
5981 
5982    Concepts: matrices^zeroing rows
5983 
5984 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5985           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRows()
5986 @*/
5987 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5988 {
5989   PetscInt       dim     = mat->stencil.dim;
5990   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
5991   PetscInt       *dims   = mat->stencil.dims+1;
5992   PetscInt       *starts = mat->stencil.starts;
5993   PetscInt       *dxm    = (PetscInt*) rows;
5994   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
5995   PetscErrorCode ierr;
5996 
5997   PetscFunctionBegin;
5998   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5999   PetscValidType(mat,1);
6000   if (numRows) PetscValidIntPointer(rows,3);
6001 
6002   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
6003   for (i = 0; i < numRows; ++i) {
6004     /* Skip unused dimensions (they are ordered k, j, i, c) */
6005     for (j = 0; j < 3-sdim; ++j) dxm++;
6006     /* Local index in X dir */
6007     tmp = *dxm++ - starts[0];
6008     /* Loop over remaining dimensions */
6009     for (j = 0; j < dim-1; ++j) {
6010       /* If nonlocal, set index to be negative */
6011       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6012       /* Update local index */
6013       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6014     }
6015     /* Skip component slot if necessary */
6016     if (mat->stencil.noc) dxm++;
6017     /* Local row number */
6018     if (tmp >= 0) {
6019       jdxm[numNewRows++] = tmp;
6020     }
6021   }
6022   ierr = MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
6023   ierr = PetscFree(jdxm);CHKERRQ(ierr);
6024   PetscFunctionReturn(0);
6025 }
6026 
6027 /*@C
6028    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
6029    of a set of rows of a matrix; using local numbering of rows.
6030 
6031    Collective on Mat
6032 
6033    Input Parameters:
6034 +  mat - the matrix
6035 .  numRows - the number of rows to remove
6036 .  rows - the global row indices
6037 .  diag - value put in all diagonals of eliminated rows
6038 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6039 -  b - optional vector of right hand side, that will be adjusted by provided solution
6040 
6041    Notes:
6042    Before calling MatZeroRowsLocal(), the user must first set the
6043    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6044 
6045    For the AIJ matrix formats this removes the old nonzero structure,
6046    but does not release memory.  For the dense and block diagonal
6047    formats this does not alter the nonzero structure.
6048 
6049    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6050    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6051    merely zeroed.
6052 
6053    The user can set a value in the diagonal entry (or for the AIJ and
6054    row formats can optionally remove the main diagonal entry from the
6055    nonzero structure as well, by passing 0.0 as the final argument).
6056 
6057    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6058    owns that are to be zeroed. This saves a global synchronization in the implementation.
6059 
6060    Level: intermediate
6061 
6062    Concepts: matrices^zeroing
6063 
6064 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRows(), MatSetOption(),
6065           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6066 @*/
6067 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6068 {
6069   PetscErrorCode ierr;
6070 
6071   PetscFunctionBegin;
6072   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6073   PetscValidType(mat,1);
6074   if (numRows) PetscValidIntPointer(rows,3);
6075   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6076   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6077   MatCheckPreallocated(mat,1);
6078 
6079   if (mat->ops->zerorowslocal) {
6080     ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6081   } else {
6082     IS             is, newis;
6083     const PetscInt *newRows;
6084 
6085     if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6086     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6087     ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr);
6088     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6089     ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6090     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6091     ierr = ISDestroy(&newis);CHKERRQ(ierr);
6092     ierr = ISDestroy(&is);CHKERRQ(ierr);
6093   }
6094   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6095 #if defined(PETSC_HAVE_CUSP)
6096   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
6097     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
6098   }
6099 #elif defined(PETSC_HAVE_VIENNACL)
6100   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
6101     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
6102   }
6103 #elif defined(PETSC_HAVE_VECCUDA)
6104   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
6105     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
6106   }
6107 #endif
6108   PetscFunctionReturn(0);
6109 }
6110 
6111 /*@C
6112    MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
6113    of a set of rows of a matrix; using local numbering of rows.
6114 
6115    Collective on Mat
6116 
6117    Input Parameters:
6118 +  mat - the matrix
6119 .  is - index set of rows to remove
6120 .  diag - value put in all diagonals of eliminated rows
6121 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6122 -  b - optional vector of right hand side, that will be adjusted by provided solution
6123 
6124    Notes:
6125    Before calling MatZeroRowsLocalIS(), the user must first set the
6126    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6127 
6128    For the AIJ matrix formats this removes the old nonzero structure,
6129    but does not release memory.  For the dense and block diagonal
6130    formats this does not alter the nonzero structure.
6131 
6132    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6133    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6134    merely zeroed.
6135 
6136    The user can set a value in the diagonal entry (or for the AIJ and
6137    row formats can optionally remove the main diagonal entry from the
6138    nonzero structure as well, by passing 0.0 as the final argument).
6139 
6140    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6141    owns that are to be zeroed. This saves a global synchronization in the implementation.
6142 
6143    Level: intermediate
6144 
6145    Concepts: matrices^zeroing
6146 
6147 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6148           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6149 @*/
6150 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6151 {
6152   PetscErrorCode ierr;
6153   PetscInt       numRows;
6154   const PetscInt *rows;
6155 
6156   PetscFunctionBegin;
6157   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6158   PetscValidType(mat,1);
6159   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6160   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6161   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6162   MatCheckPreallocated(mat,1);
6163 
6164   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6165   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6166   ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6167   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6168   PetscFunctionReturn(0);
6169 }
6170 
6171 /*@C
6172    MatZeroRowsColumnsLocal - 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 .  numRows - the number of rows to remove
6180 .  rows - the global row indices
6181 .  diag - value put in all diagonals of eliminated rows
6182 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6183 -  b - optional vector of right hand side, that will be adjusted by provided solution
6184 
6185    Notes:
6186    Before calling MatZeroRowsColumnsLocal(), the user must first set the
6187    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6188 
6189    The user can set a value in the diagonal entry (or for the AIJ and
6190    row formats can optionally remove the main diagonal entry from the
6191    nonzero structure as well, by passing 0.0 as the final argument).
6192 
6193    Level: intermediate
6194 
6195    Concepts: matrices^zeroing
6196 
6197 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6198           MatZeroRows(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6199 @*/
6200 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6201 {
6202   PetscErrorCode ierr;
6203   IS             is, newis;
6204   const PetscInt *newRows;
6205 
6206   PetscFunctionBegin;
6207   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6208   PetscValidType(mat,1);
6209   if (numRows) PetscValidIntPointer(rows,3);
6210   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6211   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6212   MatCheckPreallocated(mat,1);
6213 
6214   if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6215   ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6216   ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr);
6217   ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6218   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6219   ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6220   ierr = ISDestroy(&newis);CHKERRQ(ierr);
6221   ierr = ISDestroy(&is);CHKERRQ(ierr);
6222   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6223 #if defined(PETSC_HAVE_CUSP)
6224   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
6225     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
6226   }
6227 #elif defined(PETSC_HAVE_VIENNACL)
6228   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
6229     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
6230   }
6231 #elif defined(PETSC_HAVE_VECCUDA)
6232   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
6233     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
6234   }
6235 #endif
6236   PetscFunctionReturn(0);
6237 }
6238 
6239 /*@C
6240    MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
6241    of a set of rows and columns of a matrix; using local numbering of rows.
6242 
6243    Collective on Mat
6244 
6245    Input Parameters:
6246 +  mat - the matrix
6247 .  is - index set of rows to remove
6248 .  diag - value put in all diagonals of eliminated rows
6249 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6250 -  b - optional vector of right hand side, that will be adjusted by provided solution
6251 
6252    Notes:
6253    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
6254    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6255 
6256    The user can set a value in the diagonal entry (or for the AIJ and
6257    row formats can optionally remove the main diagonal entry from the
6258    nonzero structure as well, by passing 0.0 as the final argument).
6259 
6260    Level: intermediate
6261 
6262    Concepts: matrices^zeroing
6263 
6264 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6265           MatZeroRowsColumnsLocal(), MatZeroRows(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6266 @*/
6267 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6268 {
6269   PetscErrorCode ierr;
6270   PetscInt       numRows;
6271   const PetscInt *rows;
6272 
6273   PetscFunctionBegin;
6274   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6275   PetscValidType(mat,1);
6276   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6277   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6278   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6279   MatCheckPreallocated(mat,1);
6280 
6281   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6282   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6283   ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6284   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6285   PetscFunctionReturn(0);
6286 }
6287 
6288 /*@C
6289    MatGetSize - Returns the numbers of rows and columns in a matrix.
6290 
6291    Not Collective
6292 
6293    Input Parameter:
6294 .  mat - the matrix
6295 
6296    Output Parameters:
6297 +  m - the number of global rows
6298 -  n - the number of global columns
6299 
6300    Note: both output parameters can be NULL on input.
6301 
6302    Level: beginner
6303 
6304    Concepts: matrices^size
6305 
6306 .seealso: MatGetLocalSize()
6307 @*/
6308 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
6309 {
6310   PetscFunctionBegin;
6311   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6312   if (m) *m = mat->rmap->N;
6313   if (n) *n = mat->cmap->N;
6314   PetscFunctionReturn(0);
6315 }
6316 
6317 /*@C
6318    MatGetLocalSize - Returns the number of rows and columns in a matrix
6319    stored locally.  This information may be implementation dependent, so
6320    use with care.
6321 
6322    Not Collective
6323 
6324    Input Parameters:
6325 .  mat - the matrix
6326 
6327    Output Parameters:
6328 +  m - the number of local rows
6329 -  n - the number of local columns
6330 
6331    Note: both output parameters can be NULL on input.
6332 
6333    Level: beginner
6334 
6335    Concepts: matrices^local size
6336 
6337 .seealso: MatGetSize()
6338 @*/
6339 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
6340 {
6341   PetscFunctionBegin;
6342   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6343   if (m) PetscValidIntPointer(m,2);
6344   if (n) PetscValidIntPointer(n,3);
6345   if (m) *m = mat->rmap->n;
6346   if (n) *n = mat->cmap->n;
6347   PetscFunctionReturn(0);
6348 }
6349 
6350 /*@
6351    MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6352    this processor. (The columns of the "diagonal block")
6353 
6354    Not Collective, unless matrix has not been allocated, then collective on Mat
6355 
6356    Input Parameters:
6357 .  mat - the matrix
6358 
6359    Output Parameters:
6360 +  m - the global index of the first local column
6361 -  n - one more than the global index of the last local column
6362 
6363    Notes: both output parameters can be NULL on input.
6364 
6365    Level: developer
6366 
6367    Concepts: matrices^column ownership
6368 
6369 .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
6370 
6371 @*/
6372 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
6373 {
6374   PetscFunctionBegin;
6375   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6376   PetscValidType(mat,1);
6377   if (m) PetscValidIntPointer(m,2);
6378   if (n) PetscValidIntPointer(n,3);
6379   MatCheckPreallocated(mat,1);
6380   if (m) *m = mat->cmap->rstart;
6381   if (n) *n = mat->cmap->rend;
6382   PetscFunctionReturn(0);
6383 }
6384 
6385 /*@
6386    MatGetOwnershipRange - Returns the range of matrix rows owned by
6387    this processor, assuming that the matrix is laid out with the first
6388    n1 rows on the first processor, the next n2 rows on the second, etc.
6389    For certain parallel layouts this range may not be well defined.
6390 
6391    Not Collective
6392 
6393    Input Parameters:
6394 .  mat - the matrix
6395 
6396    Output Parameters:
6397 +  m - the global index of the first local row
6398 -  n - one more than the global index of the last local row
6399 
6400    Note: Both output parameters can be NULL on input.
6401 $  This function requires that the matrix be preallocated. If you have not preallocated, consider using
6402 $    PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
6403 $  and then MPI_Scan() to calculate prefix sums of the local sizes.
6404 
6405    Level: beginner
6406 
6407    Concepts: matrices^row ownership
6408 
6409 .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()
6410 
6411 @*/
6412 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6413 {
6414   PetscFunctionBegin;
6415   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6416   PetscValidType(mat,1);
6417   if (m) PetscValidIntPointer(m,2);
6418   if (n) PetscValidIntPointer(n,3);
6419   MatCheckPreallocated(mat,1);
6420   if (m) *m = mat->rmap->rstart;
6421   if (n) *n = mat->rmap->rend;
6422   PetscFunctionReturn(0);
6423 }
6424 
6425 /*@C
6426    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6427    each process
6428 
6429    Not Collective, unless matrix has not been allocated, then collective on Mat
6430 
6431    Input Parameters:
6432 .  mat - the matrix
6433 
6434    Output Parameters:
6435 .  ranges - start of each processors portion plus one more than the total length at the end
6436 
6437    Level: beginner
6438 
6439    Concepts: matrices^row ownership
6440 
6441 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
6442 
6443 @*/
6444 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6445 {
6446   PetscErrorCode ierr;
6447 
6448   PetscFunctionBegin;
6449   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6450   PetscValidType(mat,1);
6451   MatCheckPreallocated(mat,1);
6452   ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr);
6453   PetscFunctionReturn(0);
6454 }
6455 
6456 /*@C
6457    MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6458    this processor. (The columns of the "diagonal blocks" for each process)
6459 
6460    Not Collective, unless matrix has not been allocated, then collective on Mat
6461 
6462    Input Parameters:
6463 .  mat - the matrix
6464 
6465    Output Parameters:
6466 .  ranges - start of each processors portion plus one more then the total length at the end
6467 
6468    Level: beginner
6469 
6470    Concepts: matrices^column ownership
6471 
6472 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
6473 
6474 @*/
6475 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6476 {
6477   PetscErrorCode ierr;
6478 
6479   PetscFunctionBegin;
6480   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6481   PetscValidType(mat,1);
6482   MatCheckPreallocated(mat,1);
6483   ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr);
6484   PetscFunctionReturn(0);
6485 }
6486 
6487 /*@C
6488    MatGetOwnershipIS - Get row and column ownership as index sets
6489 
6490    Not Collective
6491 
6492    Input Arguments:
6493 .  A - matrix of type Elemental
6494 
6495    Output Arguments:
6496 +  rows - rows in which this process owns elements
6497 .  cols - columns in which this process owns elements
6498 
6499    Level: intermediate
6500 
6501 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL, MatSetValues()
6502 @*/
6503 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6504 {
6505   PetscErrorCode ierr,(*f)(Mat,IS*,IS*);
6506 
6507   PetscFunctionBegin;
6508   MatCheckPreallocated(A,1);
6509   ierr = PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);CHKERRQ(ierr);
6510   if (f) {
6511     ierr = (*f)(A,rows,cols);CHKERRQ(ierr);
6512   } else {   /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6513     if (rows) {ierr = ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);CHKERRQ(ierr);}
6514     if (cols) {ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);CHKERRQ(ierr);}
6515   }
6516   PetscFunctionReturn(0);
6517 }
6518 
6519 /*@C
6520    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6521    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6522    to complete the factorization.
6523 
6524    Collective on Mat
6525 
6526    Input Parameters:
6527 +  mat - the matrix
6528 .  row - row permutation
6529 .  column - column permutation
6530 -  info - structure containing
6531 $      levels - number of levels of fill.
6532 $      expected fill - as ratio of original fill.
6533 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6534                 missing diagonal entries)
6535 
6536    Output Parameters:
6537 .  fact - new matrix that has been symbolically factored
6538 
6539    Notes: See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
6540 
6541    Most users should employ the simplified KSP interface for linear solvers
6542    instead of working directly with matrix algebra routines such as this.
6543    See, e.g., KSPCreate().
6544 
6545    Level: developer
6546 
6547   Concepts: matrices^symbolic LU factorization
6548   Concepts: matrices^factorization
6549   Concepts: LU^symbolic factorization
6550 
6551 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6552           MatGetOrdering(), MatFactorInfo
6553 
6554     Developer Note: fortran interface is not autogenerated as the f90
6555     interface defintion cannot be generated correctly [due to MatFactorInfo]
6556 
6557 @*/
6558 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6559 {
6560   PetscErrorCode ierr;
6561 
6562   PetscFunctionBegin;
6563   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6564   PetscValidType(mat,1);
6565   PetscValidHeaderSpecific(row,IS_CLASSID,2);
6566   PetscValidHeaderSpecific(col,IS_CLASSID,3);
6567   PetscValidPointer(info,4);
6568   PetscValidPointer(fact,5);
6569   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6570   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6571   if (!(fact)->ops->ilufactorsymbolic) {
6572     const MatSolverPackage spackage;
6573     ierr = MatFactorGetSolverPackage(fact,&spackage);CHKERRQ(ierr);
6574     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6575   }
6576   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6577   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6578   MatCheckPreallocated(mat,2);
6579 
6580   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6581   ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
6582   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6583   PetscFunctionReturn(0);
6584 }
6585 
6586 /*@C
6587    MatICCFactorSymbolic - Performs symbolic incomplete
6588    Cholesky factorization for a symmetric matrix.  Use
6589    MatCholeskyFactorNumeric() to complete the factorization.
6590 
6591    Collective on Mat
6592 
6593    Input Parameters:
6594 +  mat - the matrix
6595 .  perm - row and column permutation
6596 -  info - structure containing
6597 $      levels - number of levels of fill.
6598 $      expected fill - as ratio of original fill.
6599 
6600    Output Parameter:
6601 .  fact - the factored matrix
6602 
6603    Notes:
6604    Most users should employ the KSP interface for linear solvers
6605    instead of working directly with matrix algebra routines such as this.
6606    See, e.g., KSPCreate().
6607 
6608    Level: developer
6609 
6610   Concepts: matrices^symbolic incomplete Cholesky factorization
6611   Concepts: matrices^factorization
6612   Concepts: Cholsky^symbolic factorization
6613 
6614 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
6615 
6616     Developer Note: fortran interface is not autogenerated as the f90
6617     interface defintion cannot be generated correctly [due to MatFactorInfo]
6618 
6619 @*/
6620 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6621 {
6622   PetscErrorCode ierr;
6623 
6624   PetscFunctionBegin;
6625   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6626   PetscValidType(mat,1);
6627   PetscValidHeaderSpecific(perm,IS_CLASSID,2);
6628   PetscValidPointer(info,3);
6629   PetscValidPointer(fact,4);
6630   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6631   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6632   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6633   if (!(fact)->ops->iccfactorsymbolic) {
6634     const MatSolverPackage spackage;
6635     ierr = MatFactorGetSolverPackage(fact,&spackage);CHKERRQ(ierr);
6636     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6637   }
6638   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6639   MatCheckPreallocated(mat,2);
6640 
6641   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6642   ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
6643   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6644   PetscFunctionReturn(0);
6645 }
6646 
6647 /*@C
6648    MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat
6649    points to an array of valid matrices, they may be reused to store the new
6650    submatrices.
6651 
6652    Collective on Mat
6653 
6654    Input Parameters:
6655 +  mat - the matrix
6656 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6657 .  irow, icol - index sets of rows and columns to extract
6658 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6659 
6660    Output Parameter:
6661 .  submat - the array of submatrices
6662 
6663    Notes:
6664    MatCreateSubMatrices() can extract ONLY sequential submatrices
6665    (from both sequential and parallel matrices). Use MatCreateSubMatrix()
6666    to extract a parallel submatrix.
6667 
6668    Some matrix types place restrictions on the row and column
6669    indices, such as that they be sorted or that they be equal to each other.
6670 
6671    The index sets may not have duplicate entries.
6672 
6673    When extracting submatrices from a parallel matrix, each processor can
6674    form a different submatrix by setting the rows and columns of its
6675    individual index sets according to the local submatrix desired.
6676 
6677    When finished using the submatrices, the user should destroy
6678    them with MatDestroyMatrices().
6679 
6680    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6681    original matrix has not changed from that last call to MatCreateSubMatrices().
6682 
6683    This routine creates the matrices in submat; you should NOT create them before
6684    calling it. It also allocates the array of matrix pointers submat.
6685 
6686    For BAIJ matrices the index sets must respect the block structure, that is if they
6687    request one row/column in a block, they must request all rows/columns that are in
6688    that block. For example, if the block size is 2 you cannot request just row 0 and
6689    column 0.
6690 
6691    Fortran Note:
6692    The Fortran interface is slightly different from that given below; it
6693    requires one to pass in  as submat a Mat (integer) array of size at least m.
6694 
6695    Level: advanced
6696 
6697    Concepts: matrices^accessing submatrices
6698    Concepts: submatrices
6699 
6700 .seealso: MatDestroySubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6701 @*/
6702 PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6703 {
6704   PetscErrorCode ierr;
6705   PetscInt       i;
6706   PetscBool      eq;
6707 
6708   PetscFunctionBegin;
6709   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6710   PetscValidType(mat,1);
6711   if (n) {
6712     PetscValidPointer(irow,3);
6713     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6714     PetscValidPointer(icol,4);
6715     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6716   }
6717   PetscValidPointer(submat,6);
6718   if (n && scall == MAT_REUSE_MATRIX) {
6719     PetscValidPointer(*submat,6);
6720     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6721   }
6722   if (!mat->ops->createsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6723   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6724   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6725   MatCheckPreallocated(mat,1);
6726 
6727   ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6728   ierr = (*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6729   ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6730   for (i=0; i<n; i++) {
6731     (*submat)[i]->factortype = MAT_FACTOR_NONE;  /* in case in place factorization was previously done on submatrix */
6732     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6733       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6734       if (eq) {
6735         if (mat->symmetric) {
6736           ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6737         } else if (mat->hermitian) {
6738           ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6739         } else if (mat->structurally_symmetric) {
6740           ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6741         }
6742       }
6743     }
6744   }
6745   PetscFunctionReturn(0);
6746 }
6747 
6748 /*@C
6749    MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms).
6750 
6751    Collective on Mat
6752 
6753    Input Parameters:
6754 +  mat - the matrix
6755 .  n   - the number of submatrixes to be extracted
6756 .  irow, icol - index sets of rows and columns to extract
6757 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6758 
6759    Output Parameter:
6760 .  submat - the array of submatrices
6761 
6762    Level: advanced
6763 
6764    Concepts: matrices^accessing submatrices
6765    Concepts: submatrices
6766 
6767 .seealso: MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6768 @*/
6769 PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6770 {
6771   PetscErrorCode ierr;
6772   PetscInt       i;
6773   PetscBool      eq;
6774 
6775   PetscFunctionBegin;
6776   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6777   PetscValidType(mat,1);
6778   if (n) {
6779     PetscValidPointer(irow,3);
6780     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6781     PetscValidPointer(icol,4);
6782     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6783   }
6784   PetscValidPointer(submat,6);
6785   if (n && scall == MAT_REUSE_MATRIX) {
6786     PetscValidPointer(*submat,6);
6787     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6788   }
6789   if (!mat->ops->createsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6790   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6791   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6792   MatCheckPreallocated(mat,1);
6793 
6794   ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6795   ierr = (*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6796   ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6797   for (i=0; i<n; i++) {
6798     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6799       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6800       if (eq) {
6801         if (mat->symmetric) {
6802           ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6803         } else if (mat->hermitian) {
6804           ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6805         } else if (mat->structurally_symmetric) {
6806           ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6807         }
6808       }
6809     }
6810   }
6811   PetscFunctionReturn(0);
6812 }
6813 
6814 /*@C
6815    MatDestroyMatrices - Destroys an array of matrices.
6816 
6817    Collective on Mat
6818 
6819    Input Parameters:
6820 +  n - the number of local matrices
6821 -  mat - the matrices (note that this is a pointer to the array of matrices)
6822 
6823    Level: advanced
6824 
6825     Notes: Frees not only the matrices, but also the array that contains the matrices
6826            In Fortran will not free the array.
6827 
6828 .seealso: MatCreateSubMatrices() MatDestroySubMatrices()
6829 @*/
6830 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
6831 {
6832   PetscErrorCode ierr;
6833   PetscInt       i;
6834 
6835   PetscFunctionBegin;
6836   if (!*mat) PetscFunctionReturn(0);
6837   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6838   PetscValidPointer(mat,2);
6839 
6840   for (i=0; i<n; i++) {
6841     ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr);
6842   }
6843 
6844   /* memory is allocated even if n = 0 */
6845   ierr = PetscFree(*mat);CHKERRQ(ierr);
6846   PetscFunctionReturn(0);
6847 }
6848 
6849 /*@C
6850    MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices().
6851 
6852    Collective on Mat
6853 
6854    Input Parameters:
6855 +  n - the number of local matrices
6856 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6857                        sequence of MatCreateSubMatrices())
6858 
6859    Level: advanced
6860 
6861     Notes: Frees not only the matrices, but also the array that contains the matrices
6862            In Fortran will not free the array.
6863 
6864 .seealso: MatCreateSubMatrices()
6865 @*/
6866 PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[])
6867 {
6868   PetscErrorCode ierr;
6869 
6870   PetscFunctionBegin;
6871   if (!*mat) PetscFunctionReturn(0);
6872   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6873   PetscValidPointer(mat,2);
6874 
6875   /* Destroy dummy submatrices (*mat)[n]...(*mat)[n+nstages-1] used for reuse struct Mat_SubSppt */
6876   if ((*mat)[n]) {
6877     PetscBool      isdummy;
6878     ierr = PetscObjectTypeCompare((PetscObject)(*mat)[n],MATDUMMY,&isdummy);CHKERRQ(ierr);
6879     if (isdummy) {
6880       Mat_SubSppt* smat = (Mat_SubSppt*)((*mat)[n]->data); /* singleis and nstages are saved in (*mat)[n]->data */
6881 
6882       if (smat && !smat->singleis) {
6883         PetscInt i,nstages=smat->nstages;
6884         for (i=0; i<nstages; i++) {
6885           ierr = MatDestroy(&(*mat)[n+i]);CHKERRQ(ierr);
6886         }
6887       }
6888     }
6889   }
6890 
6891   ierr = MatDestroyMatrices(n,mat);CHKERRQ(ierr);
6892   PetscFunctionReturn(0);
6893 }
6894 
6895 /*@C
6896    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
6897 
6898    Collective on Mat
6899 
6900    Input Parameters:
6901 .  mat - the matrix
6902 
6903    Output Parameter:
6904 .  matstruct - the sequential matrix with the nonzero structure of mat
6905 
6906   Level: intermediate
6907 
6908 .seealso: MatDestroySeqNonzeroStructure(), MatCreateSubMatrices(), MatDestroyMatrices()
6909 @*/
6910 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6911 {
6912   PetscErrorCode ierr;
6913 
6914   PetscFunctionBegin;
6915   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6916   PetscValidPointer(matstruct,2);
6917 
6918   PetscValidType(mat,1);
6919   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6920   MatCheckPreallocated(mat,1);
6921 
6922   if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6923   ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
6924   ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr);
6925   ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
6926   PetscFunctionReturn(0);
6927 }
6928 
6929 /*@C
6930    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
6931 
6932    Collective on Mat
6933 
6934    Input Parameters:
6935 .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
6936                        sequence of MatGetSequentialNonzeroStructure())
6937 
6938    Level: advanced
6939 
6940     Notes: Frees not only the matrices, but also the array that contains the matrices
6941 
6942 .seealso: MatGetSeqNonzeroStructure()
6943 @*/
6944 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
6945 {
6946   PetscErrorCode ierr;
6947 
6948   PetscFunctionBegin;
6949   PetscValidPointer(mat,1);
6950   ierr = MatDestroy(mat);CHKERRQ(ierr);
6951   PetscFunctionReturn(0);
6952 }
6953 
6954 /*@
6955    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6956    replaces the index sets by larger ones that represent submatrices with
6957    additional overlap.
6958 
6959    Collective on Mat
6960 
6961    Input Parameters:
6962 +  mat - the matrix
6963 .  n   - the number of index sets
6964 .  is  - the array of index sets (these index sets will changed during the call)
6965 -  ov  - the additional overlap requested
6966 
6967    Options Database:
6968 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
6969 
6970    Level: developer
6971 
6972    Concepts: overlap
6973    Concepts: ASM^computing overlap
6974 
6975 .seealso: MatCreateSubMatrices()
6976 @*/
6977 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6978 {
6979   PetscErrorCode ierr;
6980 
6981   PetscFunctionBegin;
6982   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6983   PetscValidType(mat,1);
6984   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6985   if (n) {
6986     PetscValidPointer(is,3);
6987     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
6988   }
6989   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6990   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6991   MatCheckPreallocated(mat,1);
6992 
6993   if (!ov) PetscFunctionReturn(0);
6994   if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6995   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
6996   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
6997   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
6998   PetscFunctionReturn(0);
6999 }
7000 
7001 
7002 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt);
7003 
7004 /*@
7005    MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across
7006    a sub communicator, replaces the index sets by larger ones that represent submatrices with
7007    additional overlap.
7008 
7009    Collective on Mat
7010 
7011    Input Parameters:
7012 +  mat - the matrix
7013 .  n   - the number of index sets
7014 .  is  - the array of index sets (these index sets will changed during the call)
7015 -  ov  - the additional overlap requested
7016 
7017    Options Database:
7018 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
7019 
7020    Level: developer
7021 
7022    Concepts: overlap
7023    Concepts: ASM^computing overlap
7024 
7025 .seealso: MatCreateSubMatrices()
7026 @*/
7027 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov)
7028 {
7029   PetscInt       i;
7030   PetscErrorCode ierr;
7031 
7032   PetscFunctionBegin;
7033   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7034   PetscValidType(mat,1);
7035   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
7036   if (n) {
7037     PetscValidPointer(is,3);
7038     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
7039   }
7040   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7041   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7042   MatCheckPreallocated(mat,1);
7043   if (!ov) PetscFunctionReturn(0);
7044   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7045   for(i=0; i<n; i++){
7046 	ierr =  MatIncreaseOverlapSplit_Single(mat,&is[i],ov);CHKERRQ(ierr);
7047   }
7048   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7049   PetscFunctionReturn(0);
7050 }
7051 
7052 
7053 
7054 
7055 /*@
7056    MatGetBlockSize - Returns the matrix block size.
7057 
7058    Not Collective
7059 
7060    Input Parameter:
7061 .  mat - the matrix
7062 
7063    Output Parameter:
7064 .  bs - block size
7065 
7066    Notes:
7067     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7068 
7069    If the block size has not been set yet this routine returns 1.
7070 
7071    Level: intermediate
7072 
7073    Concepts: matrices^block size
7074 
7075 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
7076 @*/
7077 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
7078 {
7079   PetscFunctionBegin;
7080   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7081   PetscValidIntPointer(bs,2);
7082   *bs = PetscAbs(mat->rmap->bs);
7083   PetscFunctionReturn(0);
7084 }
7085 
7086 /*@
7087    MatGetBlockSizes - Returns the matrix block row and column sizes.
7088 
7089    Not Collective
7090 
7091    Input Parameter:
7092 .  mat - the matrix
7093 
7094    Output Parameter:
7095 .  rbs - row block size
7096 .  cbs - coumn block size
7097 
7098    Notes:
7099     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7100     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7101 
7102    If a block size has not been set yet this routine returns 1.
7103 
7104    Level: intermediate
7105 
7106    Concepts: matrices^block size
7107 
7108 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes()
7109 @*/
7110 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
7111 {
7112   PetscFunctionBegin;
7113   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7114   if (rbs) PetscValidIntPointer(rbs,2);
7115   if (cbs) PetscValidIntPointer(cbs,3);
7116   if (rbs) *rbs = PetscAbs(mat->rmap->bs);
7117   if (cbs) *cbs = PetscAbs(mat->cmap->bs);
7118   PetscFunctionReturn(0);
7119 }
7120 
7121 /*@
7122    MatSetBlockSize - Sets the matrix block size.
7123 
7124    Logically Collective on Mat
7125 
7126    Input Parameters:
7127 +  mat - the matrix
7128 -  bs - block size
7129 
7130    Notes:
7131     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7132     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later.
7133 
7134     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size
7135     is compatible with the matrix local sizes.
7136 
7137    Level: intermediate
7138 
7139    Concepts: matrices^block size
7140 
7141 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes()
7142 @*/
7143 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
7144 {
7145   PetscErrorCode ierr;
7146 
7147   PetscFunctionBegin;
7148   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7149   PetscValidLogicalCollectiveInt(mat,bs,2);
7150   ierr = MatSetBlockSizes(mat,bs,bs);CHKERRQ(ierr);
7151   PetscFunctionReturn(0);
7152 }
7153 
7154 /*@
7155    MatSetBlockSizes - Sets the matrix block row and column sizes.
7156 
7157    Logically Collective on Mat
7158 
7159    Input Parameters:
7160 +  mat - the matrix
7161 -  rbs - row block size
7162 -  cbs - column block size
7163 
7164    Notes:
7165     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7166     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7167     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later
7168 
7169     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes
7170     are compatible with the matrix local sizes.
7171 
7172     The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs().
7173 
7174    Level: intermediate
7175 
7176    Concepts: matrices^block size
7177 
7178 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes()
7179 @*/
7180 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
7181 {
7182   PetscErrorCode ierr;
7183 
7184   PetscFunctionBegin;
7185   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7186   PetscValidLogicalCollectiveInt(mat,rbs,2);
7187   PetscValidLogicalCollectiveInt(mat,cbs,3);
7188   if (mat->ops->setblocksizes) {
7189     ierr = (*mat->ops->setblocksizes)(mat,rbs,cbs);CHKERRQ(ierr);
7190   }
7191   if (mat->rmap->refcnt) {
7192     ISLocalToGlobalMapping l2g = NULL;
7193     PetscLayout            nmap = NULL;
7194 
7195     ierr = PetscLayoutDuplicate(mat->rmap,&nmap);CHKERRQ(ierr);
7196     if (mat->rmap->mapping) {
7197       ierr = ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g);CHKERRQ(ierr);
7198     }
7199     ierr = PetscLayoutDestroy(&mat->rmap);CHKERRQ(ierr);
7200     mat->rmap = nmap;
7201     mat->rmap->mapping = l2g;
7202   }
7203   if (mat->cmap->refcnt) {
7204     ISLocalToGlobalMapping l2g = NULL;
7205     PetscLayout            nmap = NULL;
7206 
7207     ierr = PetscLayoutDuplicate(mat->cmap,&nmap);CHKERRQ(ierr);
7208     if (mat->cmap->mapping) {
7209       ierr = ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g);CHKERRQ(ierr);
7210     }
7211     ierr = PetscLayoutDestroy(&mat->cmap);CHKERRQ(ierr);
7212     mat->cmap = nmap;
7213     mat->cmap->mapping = l2g;
7214   }
7215   ierr = PetscLayoutSetBlockSize(mat->rmap,rbs);CHKERRQ(ierr);
7216   ierr = PetscLayoutSetBlockSize(mat->cmap,cbs);CHKERRQ(ierr);
7217   PetscFunctionReturn(0);
7218 }
7219 
7220 /*@
7221    MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices
7222 
7223    Logically Collective on Mat
7224 
7225    Input Parameters:
7226 +  mat - the matrix
7227 .  fromRow - matrix from which to copy row block size
7228 -  fromCol - matrix from which to copy column block size (can be same as fromRow)
7229 
7230    Level: developer
7231 
7232    Concepts: matrices^block size
7233 
7234 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes()
7235 @*/
7236 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)
7237 {
7238   PetscErrorCode ierr;
7239 
7240   PetscFunctionBegin;
7241   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7242   PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2);
7243   PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3);
7244   if (fromRow->rmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);CHKERRQ(ierr);}
7245   if (fromCol->cmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);CHKERRQ(ierr);}
7246   PetscFunctionReturn(0);
7247 }
7248 
7249 /*@
7250    MatResidual - Default routine to calculate the residual.
7251 
7252    Collective on Mat and Vec
7253 
7254    Input Parameters:
7255 +  mat - the matrix
7256 .  b   - the right-hand-side
7257 -  x   - the approximate solution
7258 
7259    Output Parameter:
7260 .  r - location to store the residual
7261 
7262    Level: developer
7263 
7264 .keywords: MG, default, multigrid, residual
7265 
7266 .seealso: PCMGSetResidual()
7267 @*/
7268 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r)
7269 {
7270   PetscErrorCode ierr;
7271 
7272   PetscFunctionBegin;
7273   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7274   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
7275   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
7276   PetscValidHeaderSpecific(r,VEC_CLASSID,4);
7277   PetscValidType(mat,1);
7278   MatCheckPreallocated(mat,1);
7279   ierr  = PetscLogEventBegin(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7280   if (!mat->ops->residual) {
7281     ierr = MatMult(mat,x,r);CHKERRQ(ierr);
7282     ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr);
7283   } else {
7284     ierr  = (*mat->ops->residual)(mat,b,x,r);CHKERRQ(ierr);
7285   }
7286   ierr  = PetscLogEventEnd(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7287   PetscFunctionReturn(0);
7288 }
7289 
7290 /*@C
7291     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
7292 
7293    Collective on Mat
7294 
7295     Input Parameters:
7296 +   mat - the matrix
7297 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
7298 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
7299 -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
7300                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7301                  always used.
7302 
7303     Output Parameters:
7304 +   n - number of rows in the (possibly compressed) matrix
7305 .   ia - the row pointers [of length n+1]
7306 .   ja - the column indices
7307 -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
7308            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
7309 
7310     Level: developer
7311 
7312     Notes: You CANNOT change any of the ia[] or ja[] values.
7313 
7314            Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values
7315 
7316     Fortran Node
7317 
7318            In Fortran use
7319 $           PetscInt ia(1), ja(1)
7320 $           PetscOffset iia, jja
7321 $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
7322 $      Acess the ith and jth entries via ia(iia + i) and ja(jja + j)
7323 $
7324 $          or
7325 $
7326 $           PetscInt, pointer :: ia(:),ja(:)
7327 $    call  MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
7328 $      Acess the ith and jth entries via ia(i) and ja(j)
7329 
7330 
7331 
7332 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
7333 @*/
7334 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7335 {
7336   PetscErrorCode ierr;
7337 
7338   PetscFunctionBegin;
7339   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7340   PetscValidType(mat,1);
7341   PetscValidIntPointer(n,5);
7342   if (ia) PetscValidIntPointer(ia,6);
7343   if (ja) PetscValidIntPointer(ja,7);
7344   PetscValidIntPointer(done,8);
7345   MatCheckPreallocated(mat,1);
7346   if (!mat->ops->getrowij) *done = PETSC_FALSE;
7347   else {
7348     *done = PETSC_TRUE;
7349     ierr  = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7350     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7351     ierr  = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7352   }
7353   PetscFunctionReturn(0);
7354 }
7355 
7356 /*@C
7357     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
7358 
7359     Collective on Mat
7360 
7361     Input Parameters:
7362 +   mat - the matrix
7363 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7364 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7365                 symmetrized
7366 .   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7367                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7368                  always used.
7369 .   n - number of columns in the (possibly compressed) matrix
7370 .   ia - the column pointers
7371 -   ja - the row indices
7372 
7373     Output Parameters:
7374 .   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
7375 
7376     Note:
7377     This routine zeros out n, ia, and ja. This is to prevent accidental
7378     us of the array after it has been restored. If you pass NULL, it will
7379     not zero the pointers.  Use of ia or ja after MatRestoreColumnIJ() is invalid.
7380 
7381     Level: developer
7382 
7383 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7384 @*/
7385 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7386 {
7387   PetscErrorCode ierr;
7388 
7389   PetscFunctionBegin;
7390   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7391   PetscValidType(mat,1);
7392   PetscValidIntPointer(n,4);
7393   if (ia) PetscValidIntPointer(ia,5);
7394   if (ja) PetscValidIntPointer(ja,6);
7395   PetscValidIntPointer(done,7);
7396   MatCheckPreallocated(mat,1);
7397   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
7398   else {
7399     *done = PETSC_TRUE;
7400     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7401   }
7402   PetscFunctionReturn(0);
7403 }
7404 
7405 /*@C
7406     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
7407     MatGetRowIJ().
7408 
7409     Collective on Mat
7410 
7411     Input Parameters:
7412 +   mat - the matrix
7413 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7414 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7415                 symmetrized
7416 .   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7417                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7418                  always used.
7419 .   n - size of (possibly compressed) matrix
7420 .   ia - the row pointers
7421 -   ja - the column indices
7422 
7423     Output Parameters:
7424 .   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7425 
7426     Note:
7427     This routine zeros out n, ia, and ja. This is to prevent accidental
7428     us of the array after it has been restored. If you pass NULL, it will
7429     not zero the pointers.  Use of ia or ja after MatRestoreRowIJ() is invalid.
7430 
7431     Level: developer
7432 
7433 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7434 @*/
7435 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7436 {
7437   PetscErrorCode ierr;
7438 
7439   PetscFunctionBegin;
7440   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7441   PetscValidType(mat,1);
7442   if (ia) PetscValidIntPointer(ia,6);
7443   if (ja) PetscValidIntPointer(ja,7);
7444   PetscValidIntPointer(done,8);
7445   MatCheckPreallocated(mat,1);
7446 
7447   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
7448   else {
7449     *done = PETSC_TRUE;
7450     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7451     if (n)  *n = 0;
7452     if (ia) *ia = NULL;
7453     if (ja) *ja = NULL;
7454   }
7455   PetscFunctionReturn(0);
7456 }
7457 
7458 /*@C
7459     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
7460     MatGetColumnIJ().
7461 
7462     Collective on Mat
7463 
7464     Input Parameters:
7465 +   mat - the matrix
7466 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7467 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7468                 symmetrized
7469 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7470                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7471                  always used.
7472 
7473     Output Parameters:
7474 +   n - size of (possibly compressed) matrix
7475 .   ia - the column pointers
7476 .   ja - the row indices
7477 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7478 
7479     Level: developer
7480 
7481 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
7482 @*/
7483 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7484 {
7485   PetscErrorCode ierr;
7486 
7487   PetscFunctionBegin;
7488   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7489   PetscValidType(mat,1);
7490   if (ia) PetscValidIntPointer(ia,5);
7491   if (ja) PetscValidIntPointer(ja,6);
7492   PetscValidIntPointer(done,7);
7493   MatCheckPreallocated(mat,1);
7494 
7495   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
7496   else {
7497     *done = PETSC_TRUE;
7498     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7499     if (n)  *n = 0;
7500     if (ia) *ia = NULL;
7501     if (ja) *ja = NULL;
7502   }
7503   PetscFunctionReturn(0);
7504 }
7505 
7506 /*@C
7507     MatColoringPatch -Used inside matrix coloring routines that
7508     use MatGetRowIJ() and/or MatGetColumnIJ().
7509 
7510     Collective on Mat
7511 
7512     Input Parameters:
7513 +   mat - the matrix
7514 .   ncolors - max color value
7515 .   n   - number of entries in colorarray
7516 -   colorarray - array indicating color for each column
7517 
7518     Output Parameters:
7519 .   iscoloring - coloring generated using colorarray information
7520 
7521     Level: developer
7522 
7523 .seealso: MatGetRowIJ(), MatGetColumnIJ()
7524 
7525 @*/
7526 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7527 {
7528   PetscErrorCode ierr;
7529 
7530   PetscFunctionBegin;
7531   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7532   PetscValidType(mat,1);
7533   PetscValidIntPointer(colorarray,4);
7534   PetscValidPointer(iscoloring,5);
7535   MatCheckPreallocated(mat,1);
7536 
7537   if (!mat->ops->coloringpatch) {
7538     ierr = ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);CHKERRQ(ierr);
7539   } else {
7540     ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
7541   }
7542   PetscFunctionReturn(0);
7543 }
7544 
7545 
7546 /*@
7547    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
7548 
7549    Logically Collective on Mat
7550 
7551    Input Parameter:
7552 .  mat - the factored matrix to be reset
7553 
7554    Notes:
7555    This routine should be used only with factored matrices formed by in-place
7556    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7557    format).  This option can save memory, for example, when solving nonlinear
7558    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7559    ILU(0) preconditioner.
7560 
7561    Note that one can specify in-place ILU(0) factorization by calling
7562 .vb
7563      PCType(pc,PCILU);
7564      PCFactorSeUseInPlace(pc);
7565 .ve
7566    or by using the options -pc_type ilu -pc_factor_in_place
7567 
7568    In-place factorization ILU(0) can also be used as a local
7569    solver for the blocks within the block Jacobi or additive Schwarz
7570    methods (runtime option: -sub_pc_factor_in_place).  See Users-Manual: ch_pc
7571    for details on setting local solver options.
7572 
7573    Most users should employ the simplified KSP interface for linear solvers
7574    instead of working directly with matrix algebra routines such as this.
7575    See, e.g., KSPCreate().
7576 
7577    Level: developer
7578 
7579 .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace()
7580 
7581    Concepts: matrices^unfactored
7582 
7583 @*/
7584 PetscErrorCode MatSetUnfactored(Mat mat)
7585 {
7586   PetscErrorCode ierr;
7587 
7588   PetscFunctionBegin;
7589   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7590   PetscValidType(mat,1);
7591   MatCheckPreallocated(mat,1);
7592   mat->factortype = MAT_FACTOR_NONE;
7593   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
7594   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
7595   PetscFunctionReturn(0);
7596 }
7597 
7598 /*MC
7599     MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.
7600 
7601     Synopsis:
7602     MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7603 
7604     Not collective
7605 
7606     Input Parameter:
7607 .   x - matrix
7608 
7609     Output Parameters:
7610 +   xx_v - the Fortran90 pointer to the array
7611 -   ierr - error code
7612 
7613     Example of Usage:
7614 .vb
7615       PetscScalar, pointer xx_v(:,:)
7616       ....
7617       call MatDenseGetArrayF90(x,xx_v,ierr)
7618       a = xx_v(3)
7619       call MatDenseRestoreArrayF90(x,xx_v,ierr)
7620 .ve
7621 
7622     Level: advanced
7623 
7624 .seealso:  MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90()
7625 
7626     Concepts: matrices^accessing array
7627 
7628 M*/
7629 
7630 /*MC
7631     MatDenseRestoreArrayF90 - Restores a matrix array that has been
7632     accessed with MatDenseGetArrayF90().
7633 
7634     Synopsis:
7635     MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7636 
7637     Not collective
7638 
7639     Input Parameters:
7640 +   x - matrix
7641 -   xx_v - the Fortran90 pointer to the array
7642 
7643     Output Parameter:
7644 .   ierr - error code
7645 
7646     Example of Usage:
7647 .vb
7648        PetscScalar, pointer xx_v(:,:)
7649        ....
7650        call MatDenseGetArrayF90(x,xx_v,ierr)
7651        a = xx_v(3)
7652        call MatDenseRestoreArrayF90(x,xx_v,ierr)
7653 .ve
7654 
7655     Level: advanced
7656 
7657 .seealso:  MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90()
7658 
7659 M*/
7660 
7661 
7662 /*MC
7663     MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.
7664 
7665     Synopsis:
7666     MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7667 
7668     Not collective
7669 
7670     Input Parameter:
7671 .   x - matrix
7672 
7673     Output Parameters:
7674 +   xx_v - the Fortran90 pointer to the array
7675 -   ierr - error code
7676 
7677     Example of Usage:
7678 .vb
7679       PetscScalar, pointer xx_v(:)
7680       ....
7681       call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7682       a = xx_v(3)
7683       call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7684 .ve
7685 
7686     Level: advanced
7687 
7688 .seealso:  MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90()
7689 
7690     Concepts: matrices^accessing array
7691 
7692 M*/
7693 
7694 /*MC
7695     MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7696     accessed with MatSeqAIJGetArrayF90().
7697 
7698     Synopsis:
7699     MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7700 
7701     Not collective
7702 
7703     Input Parameters:
7704 +   x - matrix
7705 -   xx_v - the Fortran90 pointer to the array
7706 
7707     Output Parameter:
7708 .   ierr - error code
7709 
7710     Example of Usage:
7711 .vb
7712        PetscScalar, pointer xx_v(:)
7713        ....
7714        call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7715        a = xx_v(3)
7716        call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7717 .ve
7718 
7719     Level: advanced
7720 
7721 .seealso:  MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90()
7722 
7723 M*/
7724 
7725 
7726 /*@
7727     MatCreateSubMatrix - Gets a single submatrix on the same number of processors
7728                       as the original matrix.
7729 
7730     Collective on Mat
7731 
7732     Input Parameters:
7733 +   mat - the original matrix
7734 .   isrow - parallel IS containing the rows this processor should obtain
7735 .   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.
7736 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7737 
7738     Output Parameter:
7739 .   newmat - the new submatrix, of the same type as the old
7740 
7741     Level: advanced
7742 
7743     Notes:
7744     The submatrix will be able to be multiplied with vectors using the same layout as iscol.
7745 
7746     Some matrix types place restrictions on the row and column indices, such
7747     as that they be sorted or that they be equal to each other.
7748 
7749     The index sets may not have duplicate entries.
7750 
7751       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7752    the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls
7753    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7754    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
7755    you are finished using it.
7756 
7757     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7758     the input matrix.
7759 
7760     If iscol is NULL then all columns are obtained (not supported in Fortran).
7761 
7762    Example usage:
7763    Consider the following 8x8 matrix with 34 non-zero values, that is
7764    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7765    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7766    as follows:
7767 
7768 .vb
7769             1  2  0  |  0  3  0  |  0  4
7770     Proc0   0  5  6  |  7  0  0  |  8  0
7771             9  0 10  | 11  0  0  | 12  0
7772     -------------------------------------
7773            13  0 14  | 15 16 17  |  0  0
7774     Proc1   0 18  0  | 19 20 21  |  0  0
7775             0  0  0  | 22 23  0  | 24  0
7776     -------------------------------------
7777     Proc2  25 26 27  |  0  0 28  | 29  0
7778            30  0  0  | 31 32 33  |  0 34
7779 .ve
7780 
7781     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is
7782 
7783 .vb
7784             2  0  |  0  3  0  |  0
7785     Proc0   5  6  |  7  0  0  |  8
7786     -------------------------------
7787     Proc1  18  0  | 19 20 21  |  0
7788     -------------------------------
7789     Proc2  26 27  |  0  0 28  | 29
7790             0  0  | 31 32 33  |  0
7791 .ve
7792 
7793 
7794     Concepts: matrices^submatrices
7795 
7796 .seealso: MatCreateSubMatrices()
7797 @*/
7798 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7799 {
7800   PetscErrorCode ierr;
7801   PetscMPIInt    size;
7802   Mat            *local;
7803   IS             iscoltmp;
7804 
7805   PetscFunctionBegin;
7806   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7807   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
7808   if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
7809   PetscValidPointer(newmat,5);
7810   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5);
7811   PetscValidType(mat,1);
7812   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7813   if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX");
7814 
7815   MatCheckPreallocated(mat,1);
7816   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
7817 
7818   if (!iscol || isrow == iscol) {
7819     PetscBool   stride;
7820     PetscMPIInt grabentirematrix = 0,grab;
7821     ierr = PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);CHKERRQ(ierr);
7822     if (stride) {
7823       PetscInt first,step,n,rstart,rend;
7824       ierr = ISStrideGetInfo(isrow,&first,&step);CHKERRQ(ierr);
7825       if (step == 1) {
7826         ierr = MatGetOwnershipRange(mat,&rstart,&rend);CHKERRQ(ierr);
7827         if (rstart == first) {
7828           ierr = ISGetLocalSize(isrow,&n);CHKERRQ(ierr);
7829           if (n == rend-rstart) {
7830             grabentirematrix = 1;
7831           }
7832         }
7833       }
7834     }
7835     ierr = MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr);
7836     if (grab) {
7837       ierr = PetscInfo(mat,"Getting entire matrix as submatrix\n");CHKERRQ(ierr);
7838       if (cll == MAT_INITIAL_MATRIX) {
7839         *newmat = mat;
7840         ierr    = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr);
7841       }
7842       PetscFunctionReturn(0);
7843     }
7844   }
7845 
7846   if (!iscol) {
7847     ierr = ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr);
7848   } else {
7849     iscoltmp = iscol;
7850   }
7851 
7852   /* if original matrix is on just one processor then use submatrix generated */
7853   if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7854     ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
7855     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7856     PetscFunctionReturn(0);
7857   } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) {
7858     ierr    = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
7859     *newmat = *local;
7860     ierr    = PetscFree(local);CHKERRQ(ierr);
7861     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7862     PetscFunctionReturn(0);
7863   } else if (!mat->ops->createsubmatrix) {
7864     /* Create a new matrix type that implements the operation using the full matrix */
7865     ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
7866     switch (cll) {
7867     case MAT_INITIAL_MATRIX:
7868       ierr = MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr);
7869       break;
7870     case MAT_REUSE_MATRIX:
7871       ierr = MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr);
7872       break;
7873     default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7874     }
7875     ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
7876     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7877     PetscFunctionReturn(0);
7878   }
7879 
7880   if (!mat->ops->createsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7881   ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
7882   ierr = (*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr);
7883   ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
7884   if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7885   if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);}
7886   PetscFunctionReturn(0);
7887 }
7888 
7889 /*@
7890    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7891    used during the assembly process to store values that belong to
7892    other processors.
7893 
7894    Not Collective
7895 
7896    Input Parameters:
7897 +  mat   - the matrix
7898 .  size  - the initial size of the stash.
7899 -  bsize - the initial size of the block-stash(if used).
7900 
7901    Options Database Keys:
7902 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
7903 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
7904 
7905    Level: intermediate
7906 
7907    Notes:
7908      The block-stash is used for values set with MatSetValuesBlocked() while
7909      the stash is used for values set with MatSetValues()
7910 
7911      Run with the option -info and look for output of the form
7912      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7913      to determine the appropriate value, MM, to use for size and
7914      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7915      to determine the value, BMM to use for bsize
7916 
7917    Concepts: stash^setting matrix size
7918    Concepts: matrices^stash
7919 
7920 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
7921 
7922 @*/
7923 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7924 {
7925   PetscErrorCode ierr;
7926 
7927   PetscFunctionBegin;
7928   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7929   PetscValidType(mat,1);
7930   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
7931   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
7932   PetscFunctionReturn(0);
7933 }
7934 
7935 /*@
7936    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
7937      the matrix
7938 
7939    Neighbor-wise Collective on Mat
7940 
7941    Input Parameters:
7942 +  mat   - the matrix
7943 .  x,y - the vectors
7944 -  w - where the result is stored
7945 
7946    Level: intermediate
7947 
7948    Notes:
7949     w may be the same vector as y.
7950 
7951     This allows one to use either the restriction or interpolation (its transpose)
7952     matrix to do the interpolation
7953 
7954     Concepts: interpolation
7955 
7956 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7957 
7958 @*/
7959 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7960 {
7961   PetscErrorCode ierr;
7962   PetscInt       M,N,Ny;
7963 
7964   PetscFunctionBegin;
7965   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7966   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7967   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7968   PetscValidHeaderSpecific(w,VEC_CLASSID,4);
7969   PetscValidType(A,1);
7970   MatCheckPreallocated(A,1);
7971   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
7972   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
7973   if (M == Ny) {
7974     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
7975   } else {
7976     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
7977   }
7978   PetscFunctionReturn(0);
7979 }
7980 
7981 /*@
7982    MatInterpolate - y = A*x or A'*x depending on the shape of
7983      the matrix
7984 
7985    Neighbor-wise Collective on Mat
7986 
7987    Input Parameters:
7988 +  mat   - the matrix
7989 -  x,y - the vectors
7990 
7991    Level: intermediate
7992 
7993    Notes:
7994     This allows one to use either the restriction or interpolation (its transpose)
7995     matrix to do the interpolation
7996 
7997    Concepts: matrices^interpolation
7998 
7999 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
8000 
8001 @*/
8002 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
8003 {
8004   PetscErrorCode ierr;
8005   PetscInt       M,N,Ny;
8006 
8007   PetscFunctionBegin;
8008   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8009   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8010   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8011   PetscValidType(A,1);
8012   MatCheckPreallocated(A,1);
8013   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8014   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8015   if (M == Ny) {
8016     ierr = MatMult(A,x,y);CHKERRQ(ierr);
8017   } else {
8018     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
8019   }
8020   PetscFunctionReturn(0);
8021 }
8022 
8023 /*@
8024    MatRestrict - y = A*x or A'*x
8025 
8026    Neighbor-wise Collective on Mat
8027 
8028    Input Parameters:
8029 +  mat   - the matrix
8030 -  x,y - the vectors
8031 
8032    Level: intermediate
8033 
8034    Notes:
8035     This allows one to use either the restriction or interpolation (its transpose)
8036     matrix to do the restriction
8037 
8038    Concepts: matrices^restriction
8039 
8040 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
8041 
8042 @*/
8043 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
8044 {
8045   PetscErrorCode ierr;
8046   PetscInt       M,N,Ny;
8047 
8048   PetscFunctionBegin;
8049   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8050   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8051   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8052   PetscValidType(A,1);
8053   MatCheckPreallocated(A,1);
8054 
8055   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8056   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8057   if (M == Ny) {
8058     ierr = MatMult(A,x,y);CHKERRQ(ierr);
8059   } else {
8060     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
8061   }
8062   PetscFunctionReturn(0);
8063 }
8064 
8065 /*@
8066    MatGetNullSpace - retrieves the null space to a matrix.
8067 
8068    Logically Collective on Mat and MatNullSpace
8069 
8070    Input Parameters:
8071 +  mat - the matrix
8072 -  nullsp - the null space object
8073 
8074    Level: developer
8075 
8076    Concepts: null space^attaching to matrix
8077 
8078 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace()
8079 @*/
8080 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
8081 {
8082   PetscFunctionBegin;
8083   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8084   PetscValidType(mat,1);
8085   PetscValidPointer(nullsp,2);
8086   *nullsp = mat->nullsp;
8087   PetscFunctionReturn(0);
8088 }
8089 
8090 /*@
8091    MatSetNullSpace - attaches a null space to a matrix.
8092 
8093    Logically Collective on Mat and MatNullSpace
8094 
8095    Input Parameters:
8096 +  mat - the matrix
8097 -  nullsp - the null space object
8098 
8099    Level: advanced
8100 
8101    Notes:
8102       This null space is used by the linear solvers. Overwrites any previous null space that may have been attached
8103 
8104       For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should
8105       call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense.
8106 
8107       You can remove the null space by calling this routine with an nullsp of NULL
8108 
8109 
8110       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8111    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).
8112    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
8113    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
8114    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).
8115 
8116       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8117 
8118     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
8119     routine also automatically calls MatSetTransposeNullSpace().
8120 
8121    Concepts: null space^attaching to matrix
8122 
8123 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8124 @*/
8125 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp)
8126 {
8127   PetscErrorCode ierr;
8128 
8129   PetscFunctionBegin;
8130   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8131   PetscValidType(mat,1);
8132   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8133   MatCheckPreallocated(mat,1);
8134   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8135   ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr);
8136   mat->nullsp = nullsp;
8137   if (mat->symmetric_set && mat->symmetric) {
8138     ierr = MatSetTransposeNullSpace(mat,nullsp);CHKERRQ(ierr);
8139   }
8140   PetscFunctionReturn(0);
8141 }
8142 
8143 /*@
8144    MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix.
8145 
8146    Logically Collective on Mat and MatNullSpace
8147 
8148    Input Parameters:
8149 +  mat - the matrix
8150 -  nullsp - the null space object
8151 
8152    Level: developer
8153 
8154    Concepts: null space^attaching to matrix
8155 
8156 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace()
8157 @*/
8158 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp)
8159 {
8160   PetscFunctionBegin;
8161   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8162   PetscValidType(mat,1);
8163   PetscValidPointer(nullsp,2);
8164   *nullsp = mat->transnullsp;
8165   PetscFunctionReturn(0);
8166 }
8167 
8168 /*@
8169    MatSetTransposeNullSpace - attaches a null space to a matrix.
8170 
8171    Logically Collective on Mat and MatNullSpace
8172 
8173    Input Parameters:
8174 +  mat - the matrix
8175 -  nullsp - the null space object
8176 
8177    Level: advanced
8178 
8179    Notes:
8180       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.
8181       You must also call MatSetNullSpace()
8182 
8183 
8184       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8185    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).
8186    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
8187    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
8188    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).
8189 
8190       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8191 
8192    Concepts: null space^attaching to matrix
8193 
8194 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8195 @*/
8196 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp)
8197 {
8198   PetscErrorCode ierr;
8199 
8200   PetscFunctionBegin;
8201   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8202   PetscValidType(mat,1);
8203   PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8204   MatCheckPreallocated(mat,1);
8205   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
8206   ierr = MatNullSpaceDestroy(&mat->transnullsp);CHKERRQ(ierr);
8207   mat->transnullsp = nullsp;
8208   PetscFunctionReturn(0);
8209 }
8210 
8211 /*@
8212    MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions
8213         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.
8214 
8215    Logically Collective on Mat and MatNullSpace
8216 
8217    Input Parameters:
8218 +  mat - the matrix
8219 -  nullsp - the null space object
8220 
8221    Level: advanced
8222 
8223    Notes:
8224       Overwrites any previous near null space that may have been attached
8225 
8226       You can remove the null space by calling this routine with an nullsp of NULL
8227 
8228    Concepts: null space^attaching to matrix
8229 
8230 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace()
8231 @*/
8232 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
8233 {
8234   PetscErrorCode ierr;
8235 
8236   PetscFunctionBegin;
8237   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8238   PetscValidType(mat,1);
8239   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8240   MatCheckPreallocated(mat,1);
8241   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8242   ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr);
8243   mat->nearnullsp = nullsp;
8244   PetscFunctionReturn(0);
8245 }
8246 
8247 /*@
8248    MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()
8249 
8250    Not Collective
8251 
8252    Input Parameters:
8253 .  mat - the matrix
8254 
8255    Output Parameters:
8256 .  nullsp - the null space object, NULL if not set
8257 
8258    Level: developer
8259 
8260    Concepts: null space^attaching to matrix
8261 
8262 .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate()
8263 @*/
8264 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
8265 {
8266   PetscFunctionBegin;
8267   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8268   PetscValidType(mat,1);
8269   PetscValidPointer(nullsp,2);
8270   MatCheckPreallocated(mat,1);
8271   *nullsp = mat->nearnullsp;
8272   PetscFunctionReturn(0);
8273 }
8274 
8275 /*@C
8276    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
8277 
8278    Collective on Mat
8279 
8280    Input Parameters:
8281 +  mat - the matrix
8282 .  row - row/column permutation
8283 .  fill - expected fill factor >= 1.0
8284 -  level - level of fill, for ICC(k)
8285 
8286    Notes:
8287    Probably really in-place only when level of fill is zero, otherwise allocates
8288    new space to store factored matrix and deletes previous memory.
8289 
8290    Most users should employ the simplified KSP interface for linear solvers
8291    instead of working directly with matrix algebra routines such as this.
8292    See, e.g., KSPCreate().
8293 
8294    Level: developer
8295 
8296    Concepts: matrices^incomplete Cholesky factorization
8297    Concepts: Cholesky factorization
8298 
8299 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
8300 
8301     Developer Note: fortran interface is not autogenerated as the f90
8302     interface defintion cannot be generated correctly [due to MatFactorInfo]
8303 
8304 @*/
8305 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
8306 {
8307   PetscErrorCode ierr;
8308 
8309   PetscFunctionBegin;
8310   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8311   PetscValidType(mat,1);
8312   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
8313   PetscValidPointer(info,3);
8314   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
8315   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8316   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8317   if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8318   MatCheckPreallocated(mat,1);
8319   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
8320   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8321   PetscFunctionReturn(0);
8322 }
8323 
8324 /*@
8325    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
8326          ghosted ones.
8327 
8328    Not Collective
8329 
8330    Input Parameters:
8331 +  mat - the matrix
8332 -  diag = the diagonal values, including ghost ones
8333 
8334    Level: developer
8335 
8336    Notes: Works only for MPIAIJ and MPIBAIJ matrices
8337 
8338 .seealso: MatDiagonalScale()
8339 @*/
8340 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
8341 {
8342   PetscErrorCode ierr;
8343   PetscMPIInt    size;
8344 
8345   PetscFunctionBegin;
8346   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8347   PetscValidHeaderSpecific(diag,VEC_CLASSID,2);
8348   PetscValidType(mat,1);
8349 
8350   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8351   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8352   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
8353   if (size == 1) {
8354     PetscInt n,m;
8355     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
8356     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
8357     if (m == n) {
8358       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
8359     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
8360   } else {
8361     ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr);
8362   }
8363   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8364   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8365   PetscFunctionReturn(0);
8366 }
8367 
8368 /*@
8369    MatGetInertia - Gets the inertia from a factored matrix
8370 
8371    Collective on Mat
8372 
8373    Input Parameter:
8374 .  mat - the matrix
8375 
8376    Output Parameters:
8377 +   nneg - number of negative eigenvalues
8378 .   nzero - number of zero eigenvalues
8379 -   npos - number of positive eigenvalues
8380 
8381    Level: advanced
8382 
8383    Notes: Matrix must have been factored by MatCholeskyFactor()
8384 
8385 
8386 @*/
8387 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
8388 {
8389   PetscErrorCode ierr;
8390 
8391   PetscFunctionBegin;
8392   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8393   PetscValidType(mat,1);
8394   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8395   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
8396   if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8397   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
8398   PetscFunctionReturn(0);
8399 }
8400 
8401 /* ----------------------------------------------------------------*/
8402 /*@C
8403    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
8404 
8405    Neighbor-wise Collective on Mat and Vecs
8406 
8407    Input Parameters:
8408 +  mat - the factored matrix
8409 -  b - the right-hand-side vectors
8410 
8411    Output Parameter:
8412 .  x - the result vectors
8413 
8414    Notes:
8415    The vectors b and x cannot be the same.  I.e., one cannot
8416    call MatSolves(A,x,x).
8417 
8418    Notes:
8419    Most users should employ the simplified KSP interface for linear solvers
8420    instead of working directly with matrix algebra routines such as this.
8421    See, e.g., KSPCreate().
8422 
8423    Level: developer
8424 
8425    Concepts: matrices^triangular solves
8426 
8427 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
8428 @*/
8429 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
8430 {
8431   PetscErrorCode ierr;
8432 
8433   PetscFunctionBegin;
8434   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8435   PetscValidType(mat,1);
8436   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
8437   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8438   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
8439 
8440   if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8441   MatCheckPreallocated(mat,1);
8442   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8443   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
8444   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8445   PetscFunctionReturn(0);
8446 }
8447 
8448 /*@
8449    MatIsSymmetric - Test whether a matrix is symmetric
8450 
8451    Collective on Mat
8452 
8453    Input Parameter:
8454 +  A - the matrix to test
8455 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
8456 
8457    Output Parameters:
8458 .  flg - the result
8459 
8460    Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
8461 
8462    Level: intermediate
8463 
8464    Concepts: matrix^symmetry
8465 
8466 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
8467 @*/
8468 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
8469 {
8470   PetscErrorCode ierr;
8471 
8472   PetscFunctionBegin;
8473   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8474   PetscValidPointer(flg,2);
8475 
8476   if (!A->symmetric_set) {
8477     if (!A->ops->issymmetric) {
8478       MatType mattype;
8479       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8480       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8481     }
8482     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8483     if (!tol) {
8484       A->symmetric_set = PETSC_TRUE;
8485       A->symmetric     = *flg;
8486       if (A->symmetric) {
8487         A->structurally_symmetric_set = PETSC_TRUE;
8488         A->structurally_symmetric     = PETSC_TRUE;
8489       }
8490     }
8491   } else if (A->symmetric) {
8492     *flg = PETSC_TRUE;
8493   } else if (!tol) {
8494     *flg = PETSC_FALSE;
8495   } else {
8496     if (!A->ops->issymmetric) {
8497       MatType mattype;
8498       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8499       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8500     }
8501     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8502   }
8503   PetscFunctionReturn(0);
8504 }
8505 
8506 /*@
8507    MatIsHermitian - Test whether a matrix is Hermitian
8508 
8509    Collective on Mat
8510 
8511    Input Parameter:
8512 +  A - the matrix to test
8513 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
8514 
8515    Output Parameters:
8516 .  flg - the result
8517 
8518    Level: intermediate
8519 
8520    Concepts: matrix^symmetry
8521 
8522 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
8523           MatIsSymmetricKnown(), MatIsSymmetric()
8524 @*/
8525 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
8526 {
8527   PetscErrorCode ierr;
8528 
8529   PetscFunctionBegin;
8530   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8531   PetscValidPointer(flg,2);
8532 
8533   if (!A->hermitian_set) {
8534     if (!A->ops->ishermitian) {
8535       MatType mattype;
8536       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8537       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8538     }
8539     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8540     if (!tol) {
8541       A->hermitian_set = PETSC_TRUE;
8542       A->hermitian     = *flg;
8543       if (A->hermitian) {
8544         A->structurally_symmetric_set = PETSC_TRUE;
8545         A->structurally_symmetric     = PETSC_TRUE;
8546       }
8547     }
8548   } else if (A->hermitian) {
8549     *flg = PETSC_TRUE;
8550   } else if (!tol) {
8551     *flg = PETSC_FALSE;
8552   } else {
8553     if (!A->ops->ishermitian) {
8554       MatType mattype;
8555       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8556       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8557     }
8558     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8559   }
8560   PetscFunctionReturn(0);
8561 }
8562 
8563 /*@
8564    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
8565 
8566    Not Collective
8567 
8568    Input Parameter:
8569 .  A - the matrix to check
8570 
8571    Output Parameters:
8572 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
8573 -  flg - the result
8574 
8575    Level: advanced
8576 
8577    Concepts: matrix^symmetry
8578 
8579    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
8580          if you want it explicitly checked
8581 
8582 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8583 @*/
8584 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8585 {
8586   PetscFunctionBegin;
8587   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8588   PetscValidPointer(set,2);
8589   PetscValidPointer(flg,3);
8590   if (A->symmetric_set) {
8591     *set = PETSC_TRUE;
8592     *flg = A->symmetric;
8593   } else {
8594     *set = PETSC_FALSE;
8595   }
8596   PetscFunctionReturn(0);
8597 }
8598 
8599 /*@
8600    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
8601 
8602    Not Collective
8603 
8604    Input Parameter:
8605 .  A - the matrix to check
8606 
8607    Output Parameters:
8608 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8609 -  flg - the result
8610 
8611    Level: advanced
8612 
8613    Concepts: matrix^symmetry
8614 
8615    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8616          if you want it explicitly checked
8617 
8618 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8619 @*/
8620 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8621 {
8622   PetscFunctionBegin;
8623   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8624   PetscValidPointer(set,2);
8625   PetscValidPointer(flg,3);
8626   if (A->hermitian_set) {
8627     *set = PETSC_TRUE;
8628     *flg = A->hermitian;
8629   } else {
8630     *set = PETSC_FALSE;
8631   }
8632   PetscFunctionReturn(0);
8633 }
8634 
8635 /*@
8636    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
8637 
8638    Collective on Mat
8639 
8640    Input Parameter:
8641 .  A - the matrix to test
8642 
8643    Output Parameters:
8644 .  flg - the result
8645 
8646    Level: intermediate
8647 
8648    Concepts: matrix^symmetry
8649 
8650 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8651 @*/
8652 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
8653 {
8654   PetscErrorCode ierr;
8655 
8656   PetscFunctionBegin;
8657   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8658   PetscValidPointer(flg,2);
8659   if (!A->structurally_symmetric_set) {
8660     if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8661     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
8662 
8663     A->structurally_symmetric_set = PETSC_TRUE;
8664   }
8665   *flg = A->structurally_symmetric;
8666   PetscFunctionReturn(0);
8667 }
8668 
8669 /*@
8670    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8671        to be communicated to other processors during the MatAssemblyBegin/End() process
8672 
8673     Not collective
8674 
8675    Input Parameter:
8676 .   vec - the vector
8677 
8678    Output Parameters:
8679 +   nstash   - the size of the stash
8680 .   reallocs - the number of additional mallocs incurred.
8681 .   bnstash   - the size of the block stash
8682 -   breallocs - the number of additional mallocs incurred.in the block stash
8683 
8684    Level: advanced
8685 
8686 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
8687 
8688 @*/
8689 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8690 {
8691   PetscErrorCode ierr;
8692 
8693   PetscFunctionBegin;
8694   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
8695   ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
8696   PetscFunctionReturn(0);
8697 }
8698 
8699 /*@C
8700    MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same
8701      parallel layout
8702 
8703    Collective on Mat
8704 
8705    Input Parameter:
8706 .  mat - the matrix
8707 
8708    Output Parameter:
8709 +   right - (optional) vector that the matrix can be multiplied against
8710 -   left - (optional) vector that the matrix vector product can be stored in
8711 
8712    Notes:
8713     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().
8714 
8715   Notes: These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed
8716 
8717   Level: advanced
8718 
8719 .seealso: MatCreate(), VecDestroy()
8720 @*/
8721 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left)
8722 {
8723   PetscErrorCode ierr;
8724 
8725   PetscFunctionBegin;
8726   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8727   PetscValidType(mat,1);
8728   if (mat->ops->getvecs) {
8729     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
8730   } else {
8731     PetscInt rbs,cbs;
8732     ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr);
8733     if (right) {
8734       if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup");
8735       ierr = VecCreate(PetscObjectComm((PetscObject)mat),right);CHKERRQ(ierr);
8736       ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8737       ierr = VecSetBlockSize(*right,cbs);CHKERRQ(ierr);
8738       ierr = VecSetType(*right,VECSTANDARD);CHKERRQ(ierr);
8739       ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr);
8740     }
8741     if (left) {
8742       if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup");
8743       ierr = VecCreate(PetscObjectComm((PetscObject)mat),left);CHKERRQ(ierr);
8744       ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8745       ierr = VecSetBlockSize(*left,rbs);CHKERRQ(ierr);
8746       ierr = VecSetType(*left,VECSTANDARD);CHKERRQ(ierr);
8747       ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr);
8748     }
8749   }
8750   PetscFunctionReturn(0);
8751 }
8752 
8753 /*@C
8754    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8755      with default values.
8756 
8757    Not Collective
8758 
8759    Input Parameters:
8760 .    info - the MatFactorInfo data structure
8761 
8762 
8763    Notes: The solvers are generally used through the KSP and PC objects, for example
8764           PCLU, PCILU, PCCHOLESKY, PCICC
8765 
8766    Level: developer
8767 
8768 .seealso: MatFactorInfo
8769 
8770     Developer Note: fortran interface is not autogenerated as the f90
8771     interface defintion cannot be generated correctly [due to MatFactorInfo]
8772 
8773 @*/
8774 
8775 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
8776 {
8777   PetscErrorCode ierr;
8778 
8779   PetscFunctionBegin;
8780   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
8781   PetscFunctionReturn(0);
8782 }
8783 
8784 /*@
8785    MatFactorSetSchurIS - Set indices corresponding to the Schur complement
8786 
8787    Collective on Mat
8788 
8789    Input Parameters:
8790 +  mat - the factored matrix
8791 -  is - the index set defining the Schur indices (0-based)
8792 
8793    Notes:
8794 
8795    Level: developer
8796 
8797    Concepts:
8798 
8799 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement()
8800 
8801 @*/
8802 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is)
8803 {
8804   PetscErrorCode ierr,(*f)(Mat,IS);
8805 
8806   PetscFunctionBegin;
8807   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8808   PetscValidType(mat,1);
8809   PetscValidHeaderSpecific(is,IS_CLASSID,2);
8810   PetscValidType(is,2);
8811   PetscCheckSameComm(mat,1,is,2);
8812   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
8813   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);CHKERRQ(ierr);
8814   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");
8815   ierr = (*f)(mat,is);CHKERRQ(ierr);
8816   PetscFunctionReturn(0);
8817 }
8818 
8819 /*@
8820   MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step
8821 
8822    Logically Collective on Mat
8823 
8824    Input Parameters:
8825 +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
8826 .  *S - location where to return the Schur complement (MATDENSE)
8827 -  status - the status of the Schur complement matrix (see MatFactorSchurStatus)
8828 
8829    Notes:
8830    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.
8831    If MatFactorInvertSchurComplement has been called, the routine gets back the inverse
8832 
8833    Level: advanced
8834 
8835    References:
8836 
8837 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorSchurStatus
8838 @*/
8839 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S, MatFactorSchurStatus* status)
8840 {
8841   PetscErrorCode ierr;
8842 
8843   PetscFunctionBegin;
8844   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8845   PetscValidPointer(S,2);
8846   if (status) *status = F->schur_status;
8847   ierr = PetscUseMethod(F,"MatFactorCreateSchurComplement_C",(Mat,Mat*,MatFactorSchurStatus*),(F,S,status));CHKERRQ(ierr);
8848   PetscFunctionReturn(0);
8849 }
8850 
8851 /*@
8852   MatFactorGetSchurComplement - Get a Schur complement matrix object using the current Schur data
8853 
8854    Logically Collective on Mat
8855 
8856    Input Parameters:
8857 +  F - the factored matrix obtained by calling MatGetFactor()
8858 .  *S - location where to return the Schur complement (in MATDENSE format)
8859 -  status - the status of the Schur complement matrix (see MatFactorSchurStatus)
8860 
8861    Notes:
8862    Schur complement mode is currently implemented for sequential matrices.
8863    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.
8864    The caller should call MatFactorRestoreSchurComplement when the object is no longer needed.
8865 
8866    Level: advanced
8867 
8868    References:
8869 
8870 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
8871 @*/
8872 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
8873 {
8874   PetscErrorCode ierr;
8875 
8876   PetscFunctionBegin;
8877   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8878   PetscValidPointer(S,2);
8879   if (status) *status = F->schur_status;
8880   ierr = PetscUseMethod(F,"MatFactorGetSchurComplement_C",(Mat,Mat*,MatFactorSchurStatus*),(F,S,status));CHKERRQ(ierr);
8881   PetscFunctionReturn(0);
8882 }
8883 
8884 /*@
8885   MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement
8886 
8887    Logically Collective on Mat
8888 
8889    Input Parameters:
8890 +  F - the factored matrix obtained by calling MatGetFactor()
8891 .  *S - location where the Schur complement is stored
8892 -  status - the status of the Schur complement matrix (see MatFactorSchurStatus)
8893 
8894    Notes:
8895 
8896    Level: advanced
8897 
8898    References:
8899 
8900 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
8901 @*/
8902 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status)
8903 {
8904   PetscErrorCode ierr;
8905 
8906   PetscFunctionBegin;
8907   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8908   PetscValidHeaderSpecific(*S,MAT_CLASSID,2);
8909   F->schur_status = status;
8910   ierr = MatDestroy(S);CHKERRQ(ierr);
8911   PetscFunctionReturn(0);
8912 }
8913 
8914 /*@
8915   MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step
8916 
8917    Logically Collective on Mat
8918 
8919    Input Parameters:
8920 +  F - the factored matrix obtained by calling MatGetFactor()
8921 .  rhs - location where the right hand side of the Schur complement system is stored
8922 -  sol - location where the solution of the Schur complement system has to be returned
8923 
8924    Notes:
8925    The sizes of the vectors should match the size of the Schur complement
8926 
8927    Level: advanced
8928 
8929    References:
8930 
8931 .seealso: MatGetFactor(), MatFactorSetSchurIS()
8932 @*/
8933 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol)
8934 {
8935   PetscErrorCode ierr;
8936 
8937   PetscFunctionBegin;
8938   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8939   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
8940   PetscValidHeaderSpecific(sol,VEC_CLASSID,2);
8941   PetscCheckSameComm(F,1,rhs,2);
8942   PetscCheckSameComm(F,1,sol,3);
8943   ierr = PetscUseMethod(F,"MatFactorSolveSchurComplementTranspose_C",(Mat,Vec,Vec),(F,rhs,sol));CHKERRQ(ierr);
8944   PetscFunctionReturn(0);
8945 }
8946 
8947 /*@
8948   MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step
8949 
8950    Logically Collective on Mat
8951 
8952    Input Parameters:
8953 +  F - the factored matrix obtained by calling MatGetFactor()
8954 .  rhs - location where the right hand side of the Schur complement system is stored
8955 -  sol - location where the solution of the Schur complement system has to be returned
8956 
8957    Notes:
8958    The sizes of the vectors should match the size of the Schur complement
8959 
8960    Level: advanced
8961 
8962    References:
8963 
8964 .seealso: MatGetFactor(), MatFactorSetSchurIS()
8965 @*/
8966 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol)
8967 {
8968   PetscErrorCode ierr;
8969 
8970   PetscFunctionBegin;
8971   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8972   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
8973   PetscValidHeaderSpecific(sol,VEC_CLASSID,2);
8974   PetscCheckSameComm(F,1,rhs,2);
8975   PetscCheckSameComm(F,1,sol,3);
8976   ierr = PetscUseMethod(F,"MatFactorSolveSchurComplement_C",(Mat,Vec,Vec),(F,rhs,sol));CHKERRQ(ierr);
8977   PetscFunctionReturn(0);
8978 }
8979 
8980 /*@
8981   MatFactorInvertSchurComplement - Invert the raw Schur data computed during the factorization step
8982 
8983    Logically Collective on Mat
8984 
8985    Input Parameters:
8986 +  F - the factored matrix obtained by calling MatGetFactor()
8987 
8988    Notes:
8989 
8990    Level: advanced
8991 
8992    References:
8993 
8994 .seealso: MatGetFactor(), MatFactorSetSchurIS()
8995 @*/
8996 PetscErrorCode MatFactorInvertSchurComplement(Mat F)
8997 {
8998   PetscErrorCode ierr;
8999 
9000   PetscFunctionBegin;
9001   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9002   ierr = PetscUseMethod(F,"MatFactorInvertSchurComplement_C",(Mat),(F));CHKERRQ(ierr);
9003   F->schur_status = MAT_FACTOR_SCHUR_INVERTED;
9004   PetscFunctionReturn(0);
9005 }
9006 
9007 /*@
9008   MatFactorFactorizeSchurComplement - Factorize the raw Schur data computed during the factorization step
9009 
9010    Logically Collective on Mat
9011 
9012    Input Parameters:
9013 +  F - the factored matrix obtained by calling MatGetFactor()
9014 
9015    Notes:
9016    The routine uses the pointer to the raw data of the Schur Complement stored within the solver.
9017 
9018    Level: advanced
9019 
9020    References:
9021 
9022 .seealso: MatGetFactor(), MatMumpsSetSchurIS()
9023 @*/
9024 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F)
9025 {
9026   PetscErrorCode ierr;
9027 
9028   PetscFunctionBegin;
9029   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9030   ierr = PetscUseMethod(F,"MatFactorFactorizeSchurComplement_C",(Mat),(F));CHKERRQ(ierr);
9031   F->schur_status = MAT_FACTOR_SCHUR_FACTORED;
9032   PetscFunctionReturn(0);
9033 }
9034 
9035 /*@
9036   MatFactorSetSchurComplementSolverType - Set type of solver for Schur complement
9037 
9038    Logically Collective on Mat
9039 
9040    Input Parameters:
9041 +  F - the factored matrix obtained by calling MatGetFactor()
9042 -  type - either 0 (non-symmetric), 1 (symmetric positive definite) or 2 (symmetric indefinite)
9043 
9044    Notes:
9045    The parameter is used to compute the correct factorization of the Schur complement matrices
9046    This could be useful in case the nature of the Schur complement is different from that of the matrix to be factored
9047 
9048    Level: advanced
9049 
9050    References:
9051 
9052 .seealso: MatGetFactor(), MatFactorSetSchurIS()
9053 @*/
9054 PetscErrorCode MatFactorSetSchurComplementSolverType(Mat F, PetscInt type)
9055 {
9056   PetscErrorCode ierr;
9057 
9058   PetscFunctionBegin;
9059   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9060   PetscValidLogicalCollectiveInt(F,type,2);
9061   ierr = PetscTryMethod(F,"MatFactorSetSchurComplementSolverType_C",(Mat,PetscInt),(F,type));CHKERRQ(ierr);
9062   PetscFunctionReturn(0);
9063 }
9064 
9065 /*@
9066    MatPtAP - Creates the matrix product C = P^T * A * P
9067 
9068    Neighbor-wise Collective on Mat
9069 
9070    Input Parameters:
9071 +  A - the matrix
9072 .  P - the projection matrix
9073 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9074 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate
9075           if the result is a dense matrix this is irrelevent
9076 
9077    Output Parameters:
9078 .  C - the product matrix
9079 
9080    Notes:
9081    C will be created and must be destroyed by the user with MatDestroy().
9082 
9083    This routine is currently only implemented for pairs of AIJ matrices and classes
9084    which inherit from AIJ.
9085 
9086    Level: intermediate
9087 
9088 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
9089 @*/
9090 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
9091 {
9092   PetscErrorCode ierr;
9093   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9094   PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
9095   PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9096   PetscBool      viatranspose=PETSC_FALSE,viamatmatmatmult=PETSC_FALSE;
9097 
9098   PetscFunctionBegin;
9099   ierr = PetscOptionsGetBool(((PetscObject)A)->options,((PetscObject)A)->prefix,"-matptap_viatranspose",&viatranspose,NULL);CHKERRQ(ierr);
9100   ierr = PetscOptionsGetBool(((PetscObject)A)->options,((PetscObject)A)->prefix,"-matptap_viamatmatmatmult",&viamatmatmatmult,NULL);CHKERRQ(ierr);
9101 
9102   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9103   PetscValidType(A,1);
9104   MatCheckPreallocated(A,1);
9105   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9106   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9107   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9108   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9109   PetscValidType(P,2);
9110   MatCheckPreallocated(P,2);
9111   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9112   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9113 
9114   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);
9115   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);
9116   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9117   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9118 
9119   if (scall == MAT_REUSE_MATRIX) {
9120     PetscValidPointer(*C,5);
9121     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9122     if (viatranspose || viamatmatmatmult) {
9123       Mat Pt;
9124       ierr = MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);CHKERRQ(ierr);
9125       if (viamatmatmatmult) {
9126         ierr = MatMatMatMult(Pt,A,P,scall,fill,C);CHKERRQ(ierr);
9127       } else {
9128         Mat AP;
9129         ierr = MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);CHKERRQ(ierr);
9130         ierr = MatMatMult(Pt,AP,scall,fill,C);CHKERRQ(ierr);
9131         ierr = MatDestroy(&AP);CHKERRQ(ierr);
9132       }
9133       ierr = MatDestroy(&Pt);CHKERRQ(ierr);
9134     } else {
9135       ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9136       ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9137       ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr);
9138       ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9139       ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9140     }
9141     PetscFunctionReturn(0);
9142   }
9143 
9144   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9145   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9146 
9147   fA = A->ops->ptap;
9148   fP = P->ops->ptap;
9149   if (fP == fA) {
9150     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name);
9151     ptap = fA;
9152   } else {
9153     /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
9154     char ptapname[256];
9155     ierr = PetscStrcpy(ptapname,"MatPtAP_");CHKERRQ(ierr);
9156     ierr = PetscStrcat(ptapname,((PetscObject)A)->type_name);CHKERRQ(ierr);
9157     ierr = PetscStrcat(ptapname,"_");CHKERRQ(ierr);
9158     ierr = PetscStrcat(ptapname,((PetscObject)P)->type_name);CHKERRQ(ierr);
9159     ierr = PetscStrcat(ptapname,"_C");CHKERRQ(ierr); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
9160     ierr = PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);CHKERRQ(ierr);
9161     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);
9162   }
9163 
9164   if (viatranspose || viamatmatmatmult) {
9165     Mat Pt;
9166     ierr = MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);CHKERRQ(ierr);
9167     if (viamatmatmatmult) {
9168       ierr = MatMatMatMult(Pt,A,P,scall,fill,C);CHKERRQ(ierr);
9169       ierr = PetscInfo(*C,"MatPtAP via MatMatMatMult\n");CHKERRQ(ierr);
9170     } else {
9171       Mat AP;
9172       ierr = MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);CHKERRQ(ierr);
9173       ierr = MatMatMult(Pt,AP,scall,fill,C);CHKERRQ(ierr);
9174       ierr = MatDestroy(&AP);CHKERRQ(ierr);
9175       ierr = PetscInfo(*C,"MatPtAP via MatTranspose and MatMatMult\n");CHKERRQ(ierr);
9176     }
9177     ierr = MatDestroy(&Pt);CHKERRQ(ierr);
9178   } else {
9179     ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9180     ierr = (*ptap)(A,P,scall,fill,C);CHKERRQ(ierr);
9181     ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9182   }
9183   PetscFunctionReturn(0);
9184 }
9185 
9186 /*@
9187    MatPtAPNumeric - Computes the matrix product C = P^T * A * P
9188 
9189    Neighbor-wise Collective on Mat
9190 
9191    Input Parameters:
9192 +  A - the matrix
9193 -  P - the projection matrix
9194 
9195    Output Parameters:
9196 .  C - the product matrix
9197 
9198    Notes:
9199    C must have been created by calling MatPtAPSymbolic and must be destroyed by
9200    the user using MatDeatroy().
9201 
9202    This routine is currently only implemented for pairs of AIJ matrices and classes
9203    which inherit from AIJ.  C will be of type MATAIJ.
9204 
9205    Level: intermediate
9206 
9207 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
9208 @*/
9209 PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C)
9210 {
9211   PetscErrorCode ierr;
9212 
9213   PetscFunctionBegin;
9214   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9215   PetscValidType(A,1);
9216   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9217   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9218   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9219   PetscValidType(P,2);
9220   MatCheckPreallocated(P,2);
9221   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9222   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9223   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9224   PetscValidType(C,3);
9225   MatCheckPreallocated(C,3);
9226   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9227   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);
9228   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);
9229   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);
9230   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);
9231   MatCheckPreallocated(A,1);
9232 
9233   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9234   ierr = (*C->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr);
9235   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9236   PetscFunctionReturn(0);
9237 }
9238 
9239 /*@
9240    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P
9241 
9242    Neighbor-wise Collective on Mat
9243 
9244    Input Parameters:
9245 +  A - the matrix
9246 -  P - the projection matrix
9247 
9248    Output Parameters:
9249 .  C - the (i,j) structure of the product matrix
9250 
9251    Notes:
9252    C will be created and must be destroyed by the user with MatDestroy().
9253 
9254    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9255    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9256    this (i,j) structure by calling MatPtAPNumeric().
9257 
9258    Level: intermediate
9259 
9260 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
9261 @*/
9262 PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
9263 {
9264   PetscErrorCode ierr;
9265 
9266   PetscFunctionBegin;
9267   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9268   PetscValidType(A,1);
9269   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9270   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9271   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9272   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9273   PetscValidType(P,2);
9274   MatCheckPreallocated(P,2);
9275   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9276   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9277   PetscValidPointer(C,3);
9278 
9279   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);
9280   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);
9281   MatCheckPreallocated(A,1);
9282   ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
9283   ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr);
9284   ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
9285 
9286   /* ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); NO! this is not always true -ma */
9287   PetscFunctionReturn(0);
9288 }
9289 
9290 /*@
9291    MatRARt - Creates the matrix product C = R * A * R^T
9292 
9293    Neighbor-wise Collective on Mat
9294 
9295    Input Parameters:
9296 +  A - the matrix
9297 .  R - the projection matrix
9298 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9299 -  fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate
9300           if the result is a dense matrix this is irrelevent
9301 
9302    Output Parameters:
9303 .  C - the product matrix
9304 
9305    Notes:
9306    C will be created and must be destroyed by the user with MatDestroy().
9307 
9308    This routine is currently only implemented for pairs of AIJ matrices and classes
9309    which inherit from AIJ.
9310 
9311    Level: intermediate
9312 
9313 .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
9314 @*/
9315 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
9316 {
9317   PetscErrorCode ierr;
9318 
9319   PetscFunctionBegin;
9320   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9321   PetscValidType(A,1);
9322   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9323   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9324   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9325   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9326   PetscValidType(R,2);
9327   MatCheckPreallocated(R,2);
9328   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9329   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9330   PetscValidPointer(C,3);
9331   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);
9332 
9333   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9334   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9335   MatCheckPreallocated(A,1);
9336 
9337   if (!A->ops->rart) {
9338     MatType mattype;
9339     ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
9340     SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix of type <%s> does not support RARt",mattype);
9341   }
9342   ierr = PetscLogEventBegin(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
9343   ierr = (*A->ops->rart)(A,R,scall,fill,C);CHKERRQ(ierr);
9344   ierr = PetscLogEventEnd(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
9345   PetscFunctionReturn(0);
9346 }
9347 
9348 /*@
9349    MatRARtNumeric - Computes the matrix product C = R * A * R^T
9350 
9351    Neighbor-wise Collective on Mat
9352 
9353    Input Parameters:
9354 +  A - the matrix
9355 -  R - the projection matrix
9356 
9357    Output Parameters:
9358 .  C - the product matrix
9359 
9360    Notes:
9361    C must have been created by calling MatRARtSymbolic and must be destroyed by
9362    the user using MatDestroy().
9363 
9364    This routine is currently only implemented for pairs of AIJ matrices and classes
9365    which inherit from AIJ.  C will be of type MATAIJ.
9366 
9367    Level: intermediate
9368 
9369 .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
9370 @*/
9371 PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C)
9372 {
9373   PetscErrorCode ierr;
9374 
9375   PetscFunctionBegin;
9376   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9377   PetscValidType(A,1);
9378   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9379   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9380   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9381   PetscValidType(R,2);
9382   MatCheckPreallocated(R,2);
9383   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9384   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9385   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9386   PetscValidType(C,3);
9387   MatCheckPreallocated(C,3);
9388   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9389   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);
9390   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);
9391   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);
9392   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);
9393   MatCheckPreallocated(A,1);
9394 
9395   ierr = PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
9396   ierr = (*A->ops->rartnumeric)(A,R,C);CHKERRQ(ierr);
9397   ierr = PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
9398   PetscFunctionReturn(0);
9399 }
9400 
9401 /*@
9402    MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T
9403 
9404    Neighbor-wise Collective on Mat
9405 
9406    Input Parameters:
9407 +  A - the matrix
9408 -  R - the projection matrix
9409 
9410    Output Parameters:
9411 .  C - the (i,j) structure of the product matrix
9412 
9413    Notes:
9414    C will be created and must be destroyed by the user with MatDestroy().
9415 
9416    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9417    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9418    this (i,j) structure by calling MatRARtNumeric().
9419 
9420    Level: intermediate
9421 
9422 .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
9423 @*/
9424 PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
9425 {
9426   PetscErrorCode ierr;
9427 
9428   PetscFunctionBegin;
9429   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9430   PetscValidType(A,1);
9431   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9432   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9433   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9434   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9435   PetscValidType(R,2);
9436   MatCheckPreallocated(R,2);
9437   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9438   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9439   PetscValidPointer(C,3);
9440 
9441   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);
9442   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);
9443   MatCheckPreallocated(A,1);
9444   ierr = PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
9445   ierr = (*A->ops->rartsymbolic)(A,R,fill,C);CHKERRQ(ierr);
9446   ierr = PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
9447 
9448   ierr = MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));CHKERRQ(ierr);
9449   PetscFunctionReturn(0);
9450 }
9451 
9452 /*@
9453    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
9454 
9455    Neighbor-wise Collective on Mat
9456 
9457    Input Parameters:
9458 +  A - the left matrix
9459 .  B - the right matrix
9460 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9461 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
9462           if the result is a dense matrix this is irrelevent
9463 
9464    Output Parameters:
9465 .  C - the product matrix
9466 
9467    Notes:
9468    Unless scall is MAT_REUSE_MATRIX C will be created.
9469 
9470    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9471 
9472    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9473    actually needed.
9474 
9475    If you have many matrices with the same non-zero structure to multiply, you
9476    should either
9477 $   1) use MAT_REUSE_MATRIX in all calls but the first or
9478 $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
9479    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
9480    with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse.
9481 
9482    Level: intermediate
9483 
9484 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(),  MatMatTransposeMult(), MatPtAP()
9485 @*/
9486 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9487 {
9488   PetscErrorCode ierr;
9489   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9490   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9491   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9492 
9493   PetscFunctionBegin;
9494   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9495   PetscValidType(A,1);
9496   MatCheckPreallocated(A,1);
9497   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9498   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9499   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9500   PetscValidType(B,2);
9501   MatCheckPreallocated(B,2);
9502   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9503   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9504   PetscValidPointer(C,3);
9505   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9506   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);
9507   if (scall == MAT_REUSE_MATRIX) {
9508     PetscValidPointer(*C,5);
9509     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9510     ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9511     ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9512     ierr = (*(*C)->ops->matmultnumeric)(A,B,*C);CHKERRQ(ierr);
9513     ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9514     ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9515     PetscFunctionReturn(0);
9516   }
9517   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9518   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9519 
9520   fA = A->ops->matmult;
9521   fB = B->ops->matmult;
9522   if (fB == fA) {
9523     if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
9524     mult = fB;
9525   } else {
9526     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9527     char multname[256];
9528     ierr = PetscStrcpy(multname,"MatMatMult_");CHKERRQ(ierr);
9529     ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr);
9530     ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);
9531     ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr);
9532     ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9533     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
9534     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);
9535   }
9536   ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9537   ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr);
9538   ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9539   PetscFunctionReturn(0);
9540 }
9541 
9542 /*@
9543    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
9544    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().
9545 
9546    Neighbor-wise Collective on Mat
9547 
9548    Input Parameters:
9549 +  A - the left matrix
9550 .  B - the right matrix
9551 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
9552       if C is a dense matrix this is irrelevent
9553 
9554    Output Parameters:
9555 .  C - the product matrix
9556 
9557    Notes:
9558    Unless scall is MAT_REUSE_MATRIX C will be created.
9559 
9560    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9561    actually needed.
9562 
9563    This routine is currently implemented for
9564     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
9565     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9566     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9567 
9568    Level: intermediate
9569 
9570    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
9571      We should incorporate them into PETSc.
9572 
9573 .seealso: MatMatMult(), MatMatMultNumeric()
9574 @*/
9575 PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
9576 {
9577   PetscErrorCode ierr;
9578   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*);
9579   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*);
9580   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL;
9581 
9582   PetscFunctionBegin;
9583   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9584   PetscValidType(A,1);
9585   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9586   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9587 
9588   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9589   PetscValidType(B,2);
9590   MatCheckPreallocated(B,2);
9591   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9592   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9593   PetscValidPointer(C,3);
9594 
9595   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);
9596   if (fill == PETSC_DEFAULT) fill = 2.0;
9597   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9598   MatCheckPreallocated(A,1);
9599 
9600   Asymbolic = A->ops->matmultsymbolic;
9601   Bsymbolic = B->ops->matmultsymbolic;
9602   if (Asymbolic == Bsymbolic) {
9603     if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
9604     symbolic = Bsymbolic;
9605   } else { /* dispatch based on the type of A and B */
9606     char symbolicname[256];
9607     ierr = PetscStrcpy(symbolicname,"MatMatMultSymbolic_");CHKERRQ(ierr);
9608     ierr = PetscStrcat(symbolicname,((PetscObject)A)->type_name);CHKERRQ(ierr);
9609     ierr = PetscStrcat(symbolicname,"_");CHKERRQ(ierr);
9610     ierr = PetscStrcat(symbolicname,((PetscObject)B)->type_name);CHKERRQ(ierr);
9611     ierr = PetscStrcat(symbolicname,"_C");CHKERRQ(ierr);
9612     ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);CHKERRQ(ierr);
9613     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);
9614   }
9615   ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9616   ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr);
9617   ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9618   PetscFunctionReturn(0);
9619 }
9620 
9621 /*@
9622    MatMatMultNumeric - Performs the numeric matrix-matrix product.
9623    Call this routine after first calling MatMatMultSymbolic().
9624 
9625    Neighbor-wise Collective on Mat
9626 
9627    Input Parameters:
9628 +  A - the left matrix
9629 -  B - the right matrix
9630 
9631    Output Parameters:
9632 .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
9633 
9634    Notes:
9635    C must have been created with MatMatMultSymbolic().
9636 
9637    This routine is currently implemented for
9638     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
9639     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9640     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9641 
9642    Level: intermediate
9643 
9644 .seealso: MatMatMult(), MatMatMultSymbolic()
9645 @*/
9646 PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C)
9647 {
9648   PetscErrorCode ierr;
9649 
9650   PetscFunctionBegin;
9651   ierr = MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);CHKERRQ(ierr);
9652   PetscFunctionReturn(0);
9653 }
9654 
9655 /*@
9656    MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.
9657 
9658    Neighbor-wise Collective on Mat
9659 
9660    Input Parameters:
9661 +  A - the left matrix
9662 .  B - the right matrix
9663 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9664 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9665 
9666    Output Parameters:
9667 .  C - the product matrix
9668 
9669    Notes:
9670    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9671 
9672    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9673 
9674   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9675    actually needed.
9676 
9677    This routine is currently only implemented for pairs of SeqAIJ matrices.  C will be of type MATSEQAIJ.
9678 
9679    Level: intermediate
9680 
9681 .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
9682 @*/
9683 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9684 {
9685   PetscErrorCode ierr;
9686   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9687   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9688 
9689   PetscFunctionBegin;
9690   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9691   PetscValidType(A,1);
9692   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9693   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9694   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9695   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9696   PetscValidType(B,2);
9697   MatCheckPreallocated(B,2);
9698   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9699   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9700   PetscValidPointer(C,3);
9701   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);
9702   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9703   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9704   MatCheckPreallocated(A,1);
9705 
9706   fA = A->ops->mattransposemult;
9707   if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
9708   fB = B->ops->mattransposemult;
9709   if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
9710   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);
9711 
9712   ierr = PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
9713   if (scall == MAT_INITIAL_MATRIX) {
9714     ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9715     ierr = (*A->ops->mattransposemultsymbolic)(A,B,fill,C);CHKERRQ(ierr);
9716     ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9717   }
9718   ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
9719   ierr = (*A->ops->mattransposemultnumeric)(A,B,*C);CHKERRQ(ierr);
9720   ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
9721   ierr = PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
9722   PetscFunctionReturn(0);
9723 }
9724 
9725 /*@
9726    MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.
9727 
9728    Neighbor-wise Collective on Mat
9729 
9730    Input Parameters:
9731 +  A - the left matrix
9732 .  B - the right matrix
9733 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9734 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9735 
9736    Output Parameters:
9737 .  C - the product matrix
9738 
9739    Notes:
9740    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9741 
9742    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9743 
9744   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9745    actually needed.
9746 
9747    This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
9748    which inherit from SeqAIJ.  C will be of same type as the input matrices.
9749 
9750    Level: intermediate
9751 
9752 .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
9753 @*/
9754 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9755 {
9756   PetscErrorCode ierr;
9757   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9758   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9759   PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL;
9760 
9761   PetscFunctionBegin;
9762   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9763   PetscValidType(A,1);
9764   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9765   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9766   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9767   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9768   PetscValidType(B,2);
9769   MatCheckPreallocated(B,2);
9770   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9771   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9772   PetscValidPointer(C,3);
9773   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);
9774   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9775   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9776   MatCheckPreallocated(A,1);
9777 
9778   fA = A->ops->transposematmult;
9779   fB = B->ops->transposematmult;
9780   if (fB==fA) {
9781     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9782     transposematmult = fA;
9783   } else {
9784     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9785     char multname[256];
9786     ierr = PetscStrcpy(multname,"MatTransposeMatMult_");CHKERRQ(ierr);
9787     ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr);
9788     ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);
9789     ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr);
9790     ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9791     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);CHKERRQ(ierr);
9792     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);
9793   }
9794   ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
9795   ierr = (*transposematmult)(A,B,scall,fill,C);CHKERRQ(ierr);
9796   ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
9797   PetscFunctionReturn(0);
9798 }
9799 
9800 /*@
9801    MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.
9802 
9803    Neighbor-wise Collective on Mat
9804 
9805    Input Parameters:
9806 +  A - the left matrix
9807 .  B - the middle matrix
9808 .  C - the right matrix
9809 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9810 -  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
9811           if the result is a dense matrix this is irrelevent
9812 
9813    Output Parameters:
9814 .  D - the product matrix
9815 
9816    Notes:
9817    Unless scall is MAT_REUSE_MATRIX D will be created.
9818 
9819    MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call
9820 
9821    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9822    actually needed.
9823 
9824    If you have many matrices with the same non-zero structure to multiply, you
9825    should use MAT_REUSE_MATRIX in all calls but the first or
9826 
9827    Level: intermediate
9828 
9829 .seealso: MatMatMult, MatPtAP()
9830 @*/
9831 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
9832 {
9833   PetscErrorCode ierr;
9834   PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9835   PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9836   PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9837   PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9838 
9839   PetscFunctionBegin;
9840   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9841   PetscValidType(A,1);
9842   MatCheckPreallocated(A,1);
9843   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9844   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9845   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9846   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9847   PetscValidType(B,2);
9848   MatCheckPreallocated(B,2);
9849   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9850   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9851   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9852   PetscValidPointer(C,3);
9853   MatCheckPreallocated(C,3);
9854   if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9855   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9856   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);
9857   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);
9858   if (scall == MAT_REUSE_MATRIX) {
9859     PetscValidPointer(*D,6);
9860     PetscValidHeaderSpecific(*D,MAT_CLASSID,6);
9861     ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9862     ierr = (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
9863     ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9864     PetscFunctionReturn(0);
9865   }
9866   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9867   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9868 
9869   fA = A->ops->matmatmult;
9870   fB = B->ops->matmatmult;
9871   fC = C->ops->matmatmult;
9872   if (fA == fB && fA == fC) {
9873     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9874     mult = fA;
9875   } else {
9876     /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */
9877     char multname[256];
9878     ierr = PetscStrcpy(multname,"MatMatMatMult_");CHKERRQ(ierr);
9879     ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr);
9880     ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);
9881     ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr);
9882     ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);
9883     ierr = PetscStrcat(multname,((PetscObject)C)->type_name);CHKERRQ(ierr);
9884     ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr);
9885     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
9886     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);
9887   }
9888   ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9889   ierr = (*mult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
9890   ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9891   PetscFunctionReturn(0);
9892 }
9893 
9894 /*@
9895    MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
9896 
9897    Collective on Mat
9898 
9899    Input Parameters:
9900 +  mat - the matrix
9901 .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
9902 .  subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used)
9903 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9904 
9905    Output Parameter:
9906 .  matredundant - redundant matrix
9907 
9908    Notes:
9909    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
9910    original matrix has not changed from that last call to MatCreateRedundantMatrix().
9911 
9912    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
9913    calling it.
9914 
9915    Level: advanced
9916 
9917    Concepts: subcommunicator
9918    Concepts: duplicate matrix
9919 
9920 .seealso: MatDestroy()
9921 @*/
9922 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant)
9923 {
9924   PetscErrorCode ierr;
9925   MPI_Comm       comm;
9926   PetscMPIInt    size;
9927   PetscInt       mloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs;
9928   Mat_Redundant  *redund=NULL;
9929   PetscSubcomm   psubcomm=NULL;
9930   MPI_Comm       subcomm_in=subcomm;
9931   Mat            *matseq;
9932   IS             isrow,iscol;
9933   PetscBool      newsubcomm=PETSC_FALSE;
9934 
9935   PetscFunctionBegin;
9936   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9937   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
9938     PetscValidPointer(*matredundant,5);
9939     PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5);
9940   }
9941 
9942   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
9943   if (size == 1 || nsubcomm == 1) {
9944     if (reuse == MAT_INITIAL_MATRIX) {
9945       ierr = MatDuplicate(mat,MAT_COPY_VALUES,matredundant);CHKERRQ(ierr);
9946     } else {
9947       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");
9948       ierr = MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
9949     }
9950     PetscFunctionReturn(0);
9951   }
9952 
9953   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9954   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9955   MatCheckPreallocated(mat,1);
9956 
9957   ierr = PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
9958   if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */
9959     /* create psubcomm, then get subcomm */
9960     ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
9961     ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
9962     if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size);
9963 
9964     ierr = PetscSubcommCreate(comm,&psubcomm);CHKERRQ(ierr);
9965     ierr = PetscSubcommSetNumber(psubcomm,nsubcomm);CHKERRQ(ierr);
9966     ierr = PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);CHKERRQ(ierr);
9967     ierr = PetscSubcommSetFromOptions(psubcomm);CHKERRQ(ierr);
9968     ierr = PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);CHKERRQ(ierr);
9969     newsubcomm = PETSC_TRUE;
9970     ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr);
9971   }
9972 
9973   /* get isrow, iscol and a local sequential matrix matseq[0] */
9974   if (reuse == MAT_INITIAL_MATRIX) {
9975     mloc_sub = PETSC_DECIDE;
9976     if (bs < 1) {
9977       ierr = PetscSplitOwnership(subcomm,&mloc_sub,&M);CHKERRQ(ierr);
9978     } else {
9979       ierr = PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);CHKERRQ(ierr);
9980     }
9981     ierr = MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);CHKERRQ(ierr);
9982     rstart = rend - mloc_sub;
9983     ierr = ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);CHKERRQ(ierr);
9984     ierr = ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);CHKERRQ(ierr);
9985   } else { /* reuse == MAT_REUSE_MATRIX */
9986     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");
9987     /* retrieve subcomm */
9988     ierr = PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);CHKERRQ(ierr);
9989     redund = (*matredundant)->redundant;
9990     isrow  = redund->isrow;
9991     iscol  = redund->iscol;
9992     matseq = redund->matseq;
9993   }
9994   ierr = MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);CHKERRQ(ierr);
9995 
9996   /* get matredundant over subcomm */
9997   if (reuse == MAT_INITIAL_MATRIX) {
9998     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],mloc_sub,reuse,matredundant);CHKERRQ(ierr);
9999 
10000     /* create a supporting struct and attach it to C for reuse */
10001     ierr = PetscNewLog(*matredundant,&redund);CHKERRQ(ierr);
10002     (*matredundant)->redundant = redund;
10003     redund->isrow              = isrow;
10004     redund->iscol              = iscol;
10005     redund->matseq             = matseq;
10006     if (newsubcomm) {
10007       redund->subcomm          = subcomm;
10008     } else {
10009       redund->subcomm          = MPI_COMM_NULL;
10010     }
10011   } else {
10012     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);CHKERRQ(ierr);
10013   }
10014   ierr = PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
10015   PetscFunctionReturn(0);
10016 }
10017 
10018 /*@C
10019    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
10020    a given 'mat' object. Each submatrix can span multiple procs.
10021 
10022    Collective on Mat
10023 
10024    Input Parameters:
10025 +  mat - the matrix
10026 .  subcomm - the subcommunicator obtained by com_split(comm)
10027 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10028 
10029    Output Parameter:
10030 .  subMat - 'parallel submatrices each spans a given subcomm
10031 
10032   Notes:
10033   The submatrix partition across processors is dictated by 'subComm' a
10034   communicator obtained by com_split(comm). The comm_split
10035   is not restriced to be grouped with consecutive original ranks.
10036 
10037   Due the comm_split() usage, the parallel layout of the submatrices
10038   map directly to the layout of the original matrix [wrt the local
10039   row,col partitioning]. So the original 'DiagonalMat' naturally maps
10040   into the 'DiagonalMat' of the subMat, hence it is used directly from
10041   the subMat. However the offDiagMat looses some columns - and this is
10042   reconstructed with MatSetValues()
10043 
10044   Level: advanced
10045 
10046   Concepts: subcommunicator
10047   Concepts: submatrices
10048 
10049 .seealso: MatCreateSubMatrices()
10050 @*/
10051 PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
10052 {
10053   PetscErrorCode ierr;
10054   PetscMPIInt    commsize,subCommSize;
10055 
10056   PetscFunctionBegin;
10057   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRQ(ierr);
10058   ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr);
10059   if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
10060 
10061   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");
10062   ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10063   ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr);
10064   ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10065   PetscFunctionReturn(0);
10066 }
10067 
10068 /*@
10069    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
10070 
10071    Not Collective
10072 
10073    Input Arguments:
10074    mat - matrix to extract local submatrix from
10075    isrow - local row indices for submatrix
10076    iscol - local column indices for submatrix
10077 
10078    Output Arguments:
10079    submat - the submatrix
10080 
10081    Level: intermediate
10082 
10083    Notes:
10084    The submat should be returned with MatRestoreLocalSubMatrix().
10085 
10086    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
10087    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
10088 
10089    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
10090    MatSetValuesBlockedLocal() will also be implemented.
10091 
10092    The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that
10093    matrices obtained with DMCreateMat() generally already have the local to global mapping provided.
10094 
10095 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping()
10096 @*/
10097 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10098 {
10099   PetscErrorCode ierr;
10100 
10101   PetscFunctionBegin;
10102   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10103   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10104   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10105   PetscCheckSameComm(isrow,2,iscol,3);
10106   PetscValidPointer(submat,4);
10107   if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call");
10108 
10109   if (mat->ops->getlocalsubmatrix) {
10110     ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10111   } else {
10112     ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr);
10113   }
10114   PetscFunctionReturn(0);
10115 }
10116 
10117 /*@
10118    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
10119 
10120    Not Collective
10121 
10122    Input Arguments:
10123    mat - matrix to extract local submatrix from
10124    isrow - local row indices for submatrix
10125    iscol - local column indices for submatrix
10126    submat - the submatrix
10127 
10128    Level: intermediate
10129 
10130 .seealso: MatGetLocalSubMatrix()
10131 @*/
10132 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10133 {
10134   PetscErrorCode ierr;
10135 
10136   PetscFunctionBegin;
10137   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10138   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10139   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10140   PetscCheckSameComm(isrow,2,iscol,3);
10141   PetscValidPointer(submat,4);
10142   if (*submat) {
10143     PetscValidHeaderSpecific(*submat,MAT_CLASSID,4);
10144   }
10145 
10146   if (mat->ops->restorelocalsubmatrix) {
10147     ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10148   } else {
10149     ierr = MatDestroy(submat);CHKERRQ(ierr);
10150   }
10151   *submat = NULL;
10152   PetscFunctionReturn(0);
10153 }
10154 
10155 /* --------------------------------------------------------*/
10156 /*@
10157    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix
10158 
10159    Collective on Mat
10160 
10161    Input Parameter:
10162 .  mat - the matrix
10163 
10164    Output Parameter:
10165 .  is - if any rows have zero diagonals this contains the list of them
10166 
10167    Level: developer
10168 
10169    Concepts: matrix-vector product
10170 
10171 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10172 @*/
10173 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is)
10174 {
10175   PetscErrorCode ierr;
10176 
10177   PetscFunctionBegin;
10178   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10179   PetscValidType(mat,1);
10180   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10181   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10182 
10183   if (!mat->ops->findzerodiagonals) {
10184     Vec                diag;
10185     const PetscScalar *a;
10186     PetscInt          *rows;
10187     PetscInt           rStart, rEnd, r, nrow = 0;
10188 
10189     ierr = MatCreateVecs(mat, &diag, NULL);CHKERRQ(ierr);
10190     ierr = MatGetDiagonal(mat, diag);CHKERRQ(ierr);
10191     ierr = MatGetOwnershipRange(mat, &rStart, &rEnd);CHKERRQ(ierr);
10192     ierr = VecGetArrayRead(diag, &a);CHKERRQ(ierr);
10193     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow;
10194     ierr = PetscMalloc1(nrow, &rows);CHKERRQ(ierr);
10195     nrow = 0;
10196     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart;
10197     ierr = VecRestoreArrayRead(diag, &a);CHKERRQ(ierr);
10198     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10199     ierr = ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);CHKERRQ(ierr);
10200   } else {
10201     ierr = (*mat->ops->findzerodiagonals)(mat, is);CHKERRQ(ierr);
10202   }
10203   PetscFunctionReturn(0);
10204 }
10205 
10206 /*@
10207    MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size)
10208 
10209    Collective on Mat
10210 
10211    Input Parameter:
10212 .  mat - the matrix
10213 
10214    Output Parameter:
10215 .  is - contains the list of rows with off block diagonal entries
10216 
10217    Level: developer
10218 
10219    Concepts: matrix-vector product
10220 
10221 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10222 @*/
10223 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is)
10224 {
10225   PetscErrorCode ierr;
10226 
10227   PetscFunctionBegin;
10228   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10229   PetscValidType(mat,1);
10230   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10231   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10232 
10233   if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined");
10234   ierr = (*mat->ops->findoffblockdiagonalentries)(mat,is);CHKERRQ(ierr);
10235   PetscFunctionReturn(0);
10236 }
10237 
10238 /*@C
10239   MatInvertBlockDiagonal - Inverts the block diagonal entries.
10240 
10241   Collective on Mat
10242 
10243   Input Parameters:
10244 . mat - the matrix
10245 
10246   Output Parameters:
10247 . values - the block inverses in column major order (FORTRAN-like)
10248 
10249    Note:
10250    This routine is not available from Fortran.
10251 
10252   Level: advanced
10253 @*/
10254 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
10255 {
10256   PetscErrorCode ierr;
10257 
10258   PetscFunctionBegin;
10259   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10260   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10261   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10262   if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
10263   ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr);
10264   PetscFunctionReturn(0);
10265 }
10266 
10267 /*@C
10268     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
10269     via MatTransposeColoringCreate().
10270 
10271     Collective on MatTransposeColoring
10272 
10273     Input Parameter:
10274 .   c - coloring context
10275 
10276     Level: intermediate
10277 
10278 .seealso: MatTransposeColoringCreate()
10279 @*/
10280 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c)
10281 {
10282   PetscErrorCode       ierr;
10283   MatTransposeColoring matcolor=*c;
10284 
10285   PetscFunctionBegin;
10286   if (!matcolor) PetscFunctionReturn(0);
10287   if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; PetscFunctionReturn(0);}
10288 
10289   ierr = PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);CHKERRQ(ierr);
10290   ierr = PetscFree(matcolor->rows);CHKERRQ(ierr);
10291   ierr = PetscFree(matcolor->den2sp);CHKERRQ(ierr);
10292   ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr);
10293   ierr = PetscFree(matcolor->columns);CHKERRQ(ierr);
10294   if (matcolor->brows>0) {
10295     ierr = PetscFree(matcolor->lstart);CHKERRQ(ierr);
10296   }
10297   ierr = PetscHeaderDestroy(c);CHKERRQ(ierr);
10298   PetscFunctionReturn(0);
10299 }
10300 
10301 /*@C
10302     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
10303     a MatTransposeColoring context has been created, computes a dense B^T by Apply
10304     MatTransposeColoring to sparse B.
10305 
10306     Collective on MatTransposeColoring
10307 
10308     Input Parameters:
10309 +   B - sparse matrix B
10310 .   Btdense - symbolic dense matrix B^T
10311 -   coloring - coloring context created with MatTransposeColoringCreate()
10312 
10313     Output Parameter:
10314 .   Btdense - dense matrix B^T
10315 
10316     Level: advanced
10317 
10318      Notes: These are used internally for some implementations of MatRARt()
10319 
10320 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplyDenToSp()
10321 
10322 .keywords: coloring
10323 @*/
10324 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
10325 {
10326   PetscErrorCode ierr;
10327 
10328   PetscFunctionBegin;
10329   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
10330   PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2);
10331   PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3);
10332 
10333   if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
10334   ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr);
10335   PetscFunctionReturn(0);
10336 }
10337 
10338 /*@C
10339     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
10340     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
10341     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
10342     Csp from Cden.
10343 
10344     Collective on MatTransposeColoring
10345 
10346     Input Parameters:
10347 +   coloring - coloring context created with MatTransposeColoringCreate()
10348 -   Cden - matrix product of a sparse matrix and a dense matrix Btdense
10349 
10350     Output Parameter:
10351 .   Csp - sparse matrix
10352 
10353     Level: advanced
10354 
10355      Notes: These are used internally for some implementations of MatRARt()
10356 
10357 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()
10358 
10359 .keywords: coloring
10360 @*/
10361 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
10362 {
10363   PetscErrorCode ierr;
10364 
10365   PetscFunctionBegin;
10366   PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1);
10367   PetscValidHeaderSpecific(Cden,MAT_CLASSID,2);
10368   PetscValidHeaderSpecific(Csp,MAT_CLASSID,3);
10369 
10370   if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
10371   ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr);
10372   PetscFunctionReturn(0);
10373 }
10374 
10375 /*@C
10376    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.
10377 
10378    Collective on Mat
10379 
10380    Input Parameters:
10381 +  mat - the matrix product C
10382 -  iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring()
10383 
10384     Output Parameter:
10385 .   color - the new coloring context
10386 
10387     Level: intermediate
10388 
10389 .seealso: MatTransposeColoringDestroy(),  MatTransColoringApplySpToDen(),
10390            MatTransColoringApplyDenToSp()
10391 @*/
10392 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
10393 {
10394   MatTransposeColoring c;
10395   MPI_Comm             comm;
10396   PetscErrorCode       ierr;
10397 
10398   PetscFunctionBegin;
10399   ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10400   ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
10401   ierr = PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);CHKERRQ(ierr);
10402 
10403   c->ctype = iscoloring->ctype;
10404   if (mat->ops->transposecoloringcreate) {
10405     ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr);
10406   } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type");
10407 
10408   *color = c;
10409   ierr   = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10410   PetscFunctionReturn(0);
10411 }
10412 
10413 /*@
10414       MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the
10415         matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the
10416         same, otherwise it will be larger
10417 
10418      Not Collective
10419 
10420   Input Parameter:
10421 .    A  - the matrix
10422 
10423   Output Parameter:
10424 .    state - the current state
10425 
10426   Notes: You can only compare states from two different calls to the SAME matrix, you cannot compare calls between
10427          different matrices
10428 
10429   Level: intermediate
10430 
10431 @*/
10432 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state)
10433 {
10434   PetscFunctionBegin;
10435   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10436   *state = mat->nonzerostate;
10437   PetscFunctionReturn(0);
10438 }
10439 
10440 /*@
10441       MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential
10442                  matrices from each processor
10443 
10444     Collective on MPI_Comm
10445 
10446    Input Parameters:
10447 +    comm - the communicators the parallel matrix will live on
10448 .    seqmat - the input sequential matrices
10449 .    n - number of local columns (or PETSC_DECIDE)
10450 -    reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10451 
10452    Output Parameter:
10453 .    mpimat - the parallel matrix generated
10454 
10455     Level: advanced
10456 
10457    Notes: The number of columns of the matrix in EACH processor MUST be the same.
10458 
10459 @*/
10460 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat)
10461 {
10462   PetscErrorCode ierr;
10463 
10464   PetscFunctionBegin;
10465   if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name);
10466   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");
10467 
10468   ierr = PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10469   ierr = (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);CHKERRQ(ierr);
10470   ierr = PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10471   PetscFunctionReturn(0);
10472 }
10473 
10474 /*@
10475      MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent
10476                  ranks' ownership ranges.
10477 
10478     Collective on A
10479 
10480    Input Parameters:
10481 +    A   - the matrix to create subdomains from
10482 -    N   - requested number of subdomains
10483 
10484 
10485    Output Parameters:
10486 +    n   - number of subdomains resulting on this rank
10487 -    iss - IS list with indices of subdomains on this rank
10488 
10489     Level: advanced
10490 
10491     Notes: number of subdomains must be smaller than the communicator size
10492 @*/
10493 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[])
10494 {
10495   MPI_Comm        comm,subcomm;
10496   PetscMPIInt     size,rank,color;
10497   PetscInt        rstart,rend,k;
10498   PetscErrorCode  ierr;
10499 
10500   PetscFunctionBegin;
10501   ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr);
10502   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
10503   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
10504   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);
10505   *n = 1;
10506   k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */
10507   color = rank/k;
10508   ierr = MPI_Comm_split(comm,color,rank,&subcomm);CHKERRQ(ierr);
10509   ierr = PetscMalloc1(1,iss);CHKERRQ(ierr);
10510   ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
10511   ierr = ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);CHKERRQ(ierr);
10512   ierr = MPI_Comm_free(&subcomm);CHKERRQ(ierr);
10513   PetscFunctionReturn(0);
10514 }
10515 
10516 /*@
10517    MatGalerkin - Constructs the coarse grid problem via Galerkin projection.
10518 
10519    If the interpolation and restriction operators are the same, uses MatPtAP.
10520    If they are not the same, use MatMatMatMult.
10521 
10522    Once the coarse grid problem is constructed, correct for interpolation operators
10523    that are not of full rank, which can legitimately happen in the case of non-nested
10524    geometric multigrid.
10525 
10526    Input Parameters:
10527 +  restrct - restriction operator
10528 .  dA - fine grid matrix
10529 .  interpolate - interpolation operator
10530 .  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10531 -  fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate
10532 
10533    Output Parameters:
10534 .  A - the Galerkin coarse matrix
10535 
10536    Options Database Key:
10537 .  -pc_mg_galerkin <both,pmat,mat,none>
10538 
10539    Level: developer
10540 
10541 .keywords: MG, multigrid, Galerkin
10542 
10543 .seealso: MatPtAP(), MatMatMatMult()
10544 @*/
10545 PetscErrorCode  MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A)
10546 {
10547   PetscErrorCode ierr;
10548   IS             zerorows;
10549   Vec            diag;
10550 
10551   PetscFunctionBegin;
10552   if (reuse == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10553   /* Construct the coarse grid matrix */
10554   if (interpolate == restrct) {
10555     ierr = MatPtAP(dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10556   } else {
10557     ierr = MatMatMatMult(restrct,dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10558   }
10559 
10560   /* If the interpolation matrix is not of full rank, A will have zero rows.
10561      This can legitimately happen in the case of non-nested geometric multigrid.
10562      In that event, we set the rows of the matrix to the rows of the identity,
10563      ignoring the equations (as the RHS will also be zero). */
10564 
10565   ierr = MatFindZeroRows(*A, &zerorows);CHKERRQ(ierr);
10566 
10567   if (zerorows != NULL) { /* if there are any zero rows */
10568     ierr = MatCreateVecs(*A, &diag, NULL);CHKERRQ(ierr);
10569     ierr = MatGetDiagonal(*A, diag);CHKERRQ(ierr);
10570     ierr = VecISSet(diag, zerorows, 1.0);CHKERRQ(ierr);
10571     ierr = MatDiagonalSet(*A, diag, INSERT_VALUES);CHKERRQ(ierr);
10572     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10573     ierr = ISDestroy(&zerorows);CHKERRQ(ierr);
10574   }
10575   PetscFunctionReturn(0);
10576 }
10577