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