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