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