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