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