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