xref: /petsc/src/mat/interface/matrix.c (revision 60f34548b2a91e3a6ed9e423e5e04b0ea78ffcb7)
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   ierr = MatAssemblyBegin(x, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
94   ierr = MatAssemblyEnd(x, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
95   ierr = PetscRandomDestroy(&randObj);CHKERRQ(ierr);
96   PetscFunctionReturn(0);
97 }
98 
99 /*@
100    MatFactorGetErrorZeroPivot - returns the pivot value that was determined to be zero and the row it occurred in
101 
102    Logically Collective on Mat
103 
104    Input Parameters:
105 .  mat - the factored matrix
106 
107    Output Parameter:
108 +  pivot - the pivot value computed
109 -  row - the row that the zero pivot occurred. Note that this row must be interpreted carefully due to row reorderings and which processes
110          the share the matrix
111 
112    Level: advanced
113 
114    Notes:
115     This routine does not work for factorizations done with external packages.
116    This routine should only be called if MatGetFactorError() returns a value of MAT_FACTOR_NUMERIC_ZEROPIVOT
117 
118    This can be called on non-factored matrices that come from, for example, matrices used in SOR.
119 
120 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot()
121 @*/
122 PetscErrorCode MatFactorGetErrorZeroPivot(Mat mat,PetscReal *pivot,PetscInt *row)
123 {
124   PetscFunctionBegin;
125   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
126   *pivot = mat->factorerror_zeropivot_value;
127   *row   = mat->factorerror_zeropivot_row;
128   PetscFunctionReturn(0);
129 }
130 
131 /*@
132    MatFactorGetError - gets the error code from a factorization
133 
134    Logically Collective on Mat
135 
136    Input Parameters:
137 .  mat - the factored matrix
138 
139    Output Parameter:
140 .  err  - the error code
141 
142    Level: advanced
143 
144    Notes:
145     This can be called on non-factored matrices that come from, for example, matrices used in SOR.
146 
147 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot()
148 @*/
149 PetscErrorCode MatFactorGetError(Mat mat,MatFactorError *err)
150 {
151   PetscFunctionBegin;
152   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
153   *err = mat->factorerrortype;
154   PetscFunctionReturn(0);
155 }
156 
157 /*@
158    MatFactorClearError - clears the error code in a factorization
159 
160    Logically Collective on Mat
161 
162    Input Parameter:
163 .  mat - the factored matrix
164 
165    Level: developer
166 
167    Notes:
168     This can be called on non-factored matrices that come from, for example, matrices used in SOR.
169 
170 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorGetError(), MatFactorGetErrorZeroPivot()
171 @*/
172 PetscErrorCode MatFactorClearError(Mat mat)
173 {
174   PetscFunctionBegin;
175   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
176   mat->factorerrortype             = MAT_FACTOR_NOERROR;
177   mat->factorerror_zeropivot_value = 0.0;
178   mat->factorerror_zeropivot_row   = 0;
179   PetscFunctionReturn(0);
180 }
181 
182 PETSC_INTERN PetscErrorCode MatFindNonzeroRowsOrCols_Basic(Mat mat,PetscBool cols,PetscReal tol,IS *nonzero)
183 {
184   PetscErrorCode    ierr;
185   Vec               r,l;
186   const PetscScalar *al;
187   PetscInt          i,nz,gnz,N,n;
188 
189   PetscFunctionBegin;
190   ierr = MatCreateVecs(mat,&r,&l);CHKERRQ(ierr);
191   if (!cols) { /* nonzero rows */
192     ierr = MatGetSize(mat,&N,NULL);CHKERRQ(ierr);
193     ierr = MatGetLocalSize(mat,&n,NULL);CHKERRQ(ierr);
194     ierr = VecSet(l,0.0);CHKERRQ(ierr);
195     ierr = VecSetRandom(r,NULL);CHKERRQ(ierr);
196     ierr = MatMult(mat,r,l);CHKERRQ(ierr);
197     ierr = VecGetArrayRead(l,&al);CHKERRQ(ierr);
198   } else { /* nonzero columns */
199     ierr = MatGetSize(mat,NULL,&N);CHKERRQ(ierr);
200     ierr = MatGetLocalSize(mat,NULL,&n);CHKERRQ(ierr);
201     ierr = VecSet(r,0.0);CHKERRQ(ierr);
202     ierr = VecSetRandom(l,NULL);CHKERRQ(ierr);
203     ierr = MatMultTranspose(mat,l,r);CHKERRQ(ierr);
204     ierr = VecGetArrayRead(r,&al);CHKERRQ(ierr);
205   }
206   if (tol <= 0.0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nz++; }
207   else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nz++; }
208   ierr = MPIU_Allreduce(&nz,&gnz,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr);
209   if (gnz != N) {
210     PetscInt *nzr;
211     ierr = PetscMalloc1(nz,&nzr);CHKERRQ(ierr);
212     if (nz) {
213       if (tol < 0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nzr[nz++] = i; }
214       else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nzr[nz++] = i; }
215     }
216     ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),nz,nzr,PETSC_OWN_POINTER,nonzero);CHKERRQ(ierr);
217   } else *nonzero = NULL;
218   if (!cols) { /* nonzero rows */
219     ierr = VecRestoreArrayRead(l,&al);CHKERRQ(ierr);
220   } else {
221     ierr = VecRestoreArrayRead(r,&al);CHKERRQ(ierr);
222   }
223   ierr = VecDestroy(&l);CHKERRQ(ierr);
224   ierr = VecDestroy(&r);CHKERRQ(ierr);
225   PetscFunctionReturn(0);
226 }
227 
228 /*@
229       MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix
230 
231   Input Parameter:
232 .    A  - the matrix
233 
234   Output Parameter:
235 .    keptrows - the rows that are not completely zero
236 
237   Notes:
238     keptrows is set to NULL if all rows are nonzero.
239 
240   Level: intermediate
241 
242  @*/
243 PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows)
244 {
245   PetscErrorCode ierr;
246 
247   PetscFunctionBegin;
248   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
249   PetscValidType(mat,1);
250   PetscValidPointer(keptrows,2);
251   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
252   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
253   if (!mat->ops->findnonzerorows) {
254     ierr = MatFindNonzeroRowsOrCols_Basic(mat,PETSC_FALSE,0.0,keptrows);CHKERRQ(ierr);
255   } else {
256     ierr = (*mat->ops->findnonzerorows)(mat,keptrows);CHKERRQ(ierr);
257   }
258   PetscFunctionReturn(0);
259 }
260 
261 /*@
262       MatFindZeroRows - Locate all rows that are completely zero in the matrix
263 
264   Input Parameter:
265 .    A  - the matrix
266 
267   Output Parameter:
268 .    zerorows - the rows that are completely zero
269 
270   Notes:
271     zerorows is set to NULL if no rows are zero.
272 
273   Level: intermediate
274 
275  @*/
276 PetscErrorCode MatFindZeroRows(Mat mat,IS *zerorows)
277 {
278   PetscErrorCode ierr;
279   IS keptrows;
280   PetscInt m, n;
281 
282   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
283   PetscValidType(mat,1);
284 
285   ierr = MatFindNonzeroRows(mat, &keptrows);CHKERRQ(ierr);
286   /* MatFindNonzeroRows sets keptrows to NULL if there are no zero rows.
287      In keeping with this convention, we set zerorows to NULL if there are no zero
288      rows. */
289   if (keptrows == NULL) {
290     *zerorows = NULL;
291   } else {
292     ierr = MatGetOwnershipRange(mat,&m,&n);CHKERRQ(ierr);
293     ierr = ISComplement(keptrows,m,n,zerorows);CHKERRQ(ierr);
294     ierr = ISDestroy(&keptrows);CHKERRQ(ierr);
295   }
296   PetscFunctionReturn(0);
297 }
298 
299 /*@
300    MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling
301 
302    Not Collective
303 
304    Input Parameters:
305 .   A - the matrix
306 
307    Output Parameters:
308 .   a - the diagonal part (which is a SEQUENTIAL matrix)
309 
310    Notes:
311     see the manual page for MatCreateAIJ() for more information on the "diagonal part" of the matrix.
312           Use caution, as the reference count on the returned matrix is not incremented and it is used as
313 	  part of the containing MPI Mat's normal operation.
314 
315    Level: advanced
316 
317 @*/
318 PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a)
319 {
320   PetscErrorCode ierr;
321 
322   PetscFunctionBegin;
323   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
324   PetscValidType(A,1);
325   PetscValidPointer(a,3);
326   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
327   if (!A->ops->getdiagonalblock) {
328     PetscMPIInt size;
329     ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);CHKERRQ(ierr);
330     if (size == 1) {
331       *a = A;
332       PetscFunctionReturn(0);
333     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Not coded for this matrix type");
334   }
335   ierr = (*A->ops->getdiagonalblock)(A,a);CHKERRQ(ierr);
336   PetscFunctionReturn(0);
337 }
338 
339 /*@
340    MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries.
341 
342    Collective on Mat
343 
344    Input Parameters:
345 .  mat - the matrix
346 
347    Output Parameter:
348 .   trace - the sum of the diagonal entries
349 
350    Level: advanced
351 
352 @*/
353 PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace)
354 {
355   PetscErrorCode ierr;
356   Vec            diag;
357 
358   PetscFunctionBegin;
359   ierr = MatCreateVecs(mat,&diag,NULL);CHKERRQ(ierr);
360   ierr = MatGetDiagonal(mat,diag);CHKERRQ(ierr);
361   ierr = VecSum(diag,trace);CHKERRQ(ierr);
362   ierr = VecDestroy(&diag);CHKERRQ(ierr);
363   PetscFunctionReturn(0);
364 }
365 
366 /*@
367    MatRealPart - Zeros out the imaginary part of the matrix
368 
369    Logically Collective on Mat
370 
371    Input Parameters:
372 .  mat - the matrix
373 
374    Level: advanced
375 
376 
377 .seealso: MatImaginaryPart()
378 @*/
379 PetscErrorCode MatRealPart(Mat mat)
380 {
381   PetscErrorCode ierr;
382 
383   PetscFunctionBegin;
384   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
385   PetscValidType(mat,1);
386   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
387   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
388   if (!mat->ops->realpart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
389   MatCheckPreallocated(mat,1);
390   ierr = (*mat->ops->realpart)(mat);CHKERRQ(ierr);
391 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
392   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
393     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
394   }
395 #endif
396   PetscFunctionReturn(0);
397 }
398 
399 /*@C
400    MatGetGhosts - Get the global index of all ghost nodes defined by the sparse matrix
401 
402    Collective on Mat
403 
404    Input Parameter:
405 .  mat - the matrix
406 
407    Output Parameters:
408 +   nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block)
409 -   ghosts - the global indices of the ghost points
410 
411    Notes:
412     the nghosts and ghosts are suitable to pass into VecCreateGhost()
413 
414    Level: advanced
415 
416 @*/
417 PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[])
418 {
419   PetscErrorCode ierr;
420 
421   PetscFunctionBegin;
422   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
423   PetscValidType(mat,1);
424   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
425   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
426   if (!mat->ops->getghosts) {
427     if (nghosts) *nghosts = 0;
428     if (ghosts) *ghosts = 0;
429   } else {
430     ierr = (*mat->ops->getghosts)(mat,nghosts,ghosts);CHKERRQ(ierr);
431   }
432   PetscFunctionReturn(0);
433 }
434 
435 
436 /*@
437    MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part
438 
439    Logically Collective on Mat
440 
441    Input Parameters:
442 .  mat - the matrix
443 
444    Level: advanced
445 
446 
447 .seealso: MatRealPart()
448 @*/
449 PetscErrorCode MatImaginaryPart(Mat mat)
450 {
451   PetscErrorCode ierr;
452 
453   PetscFunctionBegin;
454   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
455   PetscValidType(mat,1);
456   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
457   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
458   if (!mat->ops->imaginarypart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
459   MatCheckPreallocated(mat,1);
460   ierr = (*mat->ops->imaginarypart)(mat);CHKERRQ(ierr);
461 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
462   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
463     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
464   }
465 #endif
466   PetscFunctionReturn(0);
467 }
468 
469 /*@
470    MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices)
471 
472    Not Collective
473 
474    Input Parameter:
475 .  mat - the matrix
476 
477    Output Parameters:
478 +  missing - is any diagonal missing
479 -  dd - first diagonal entry that is missing (optional) on this process
480 
481    Level: advanced
482 
483 
484 .seealso: MatRealPart()
485 @*/
486 PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd)
487 {
488   PetscErrorCode ierr;
489 
490   PetscFunctionBegin;
491   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
492   PetscValidType(mat,1);
493   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
494   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
495   if (!mat->ops->missingdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
496   ierr = (*mat->ops->missingdiagonal)(mat,missing,dd);CHKERRQ(ierr);
497   PetscFunctionReturn(0);
498 }
499 
500 /*@C
501    MatGetRow - Gets a row of a matrix.  You MUST call MatRestoreRow()
502    for each row that you get to ensure that your application does
503    not bleed memory.
504 
505    Not Collective
506 
507    Input Parameters:
508 +  mat - the matrix
509 -  row - the row to get
510 
511    Output Parameters:
512 +  ncols -  if not NULL, the number of nonzeros in the row
513 .  cols - if not NULL, the column numbers
514 -  vals - if not NULL, the values
515 
516    Notes:
517    This routine is provided for people who need to have direct access
518    to the structure of a matrix.  We hope that we provide enough
519    high-level matrix routines that few users will need it.
520 
521    MatGetRow() always returns 0-based column indices, regardless of
522    whether the internal representation is 0-based (default) or 1-based.
523 
524    For better efficiency, set cols and/or vals to NULL if you do
525    not wish to extract these quantities.
526 
527    The user can only examine the values extracted with MatGetRow();
528    the values cannot be altered.  To change the matrix entries, one
529    must use MatSetValues().
530 
531    You can only have one call to MatGetRow() outstanding for a particular
532    matrix at a time, per processor. MatGetRow() can only obtain rows
533    associated with the given processor, it cannot get rows from the
534    other processors; for that we suggest using MatCreateSubMatrices(), then
535    MatGetRow() on the submatrix. The row index passed to MatGetRow()
536    is in the global number of rows.
537 
538    Fortran Notes:
539    The calling sequence from Fortran is
540 .vb
541    MatGetRow(matrix,row,ncols,cols,values,ierr)
542          Mat     matrix (input)
543          integer row    (input)
544          integer ncols  (output)
545          integer cols(maxcols) (output)
546          double precision (or double complex) values(maxcols) output
547 .ve
548    where maxcols >= maximum nonzeros in any row of the matrix.
549 
550 
551    Caution:
552    Do not try to change the contents of the output arrays (cols and vals).
553    In some cases, this may corrupt the matrix.
554 
555    Level: advanced
556 
557    Concepts: matrices^row access
558 
559 .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatCreateSubMatrices(), MatGetDiagonal()
560 @*/
561 PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
562 {
563   PetscErrorCode ierr;
564   PetscInt       incols;
565 
566   PetscFunctionBegin;
567   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
568   PetscValidType(mat,1);
569   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
570   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
571   if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
572   MatCheckPreallocated(mat,1);
573   ierr = PetscLogEventBegin(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr);
574   ierr = (*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals);CHKERRQ(ierr);
575   if (ncols) *ncols = incols;
576   ierr = PetscLogEventEnd(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr);
577   PetscFunctionReturn(0);
578 }
579 
580 /*@
581    MatConjugate - replaces the matrix values with their complex conjugates
582 
583    Logically Collective on Mat
584 
585    Input Parameters:
586 .  mat - the matrix
587 
588    Level: advanced
589 
590 .seealso:  VecConjugate()
591 @*/
592 PetscErrorCode MatConjugate(Mat mat)
593 {
594 #if defined(PETSC_USE_COMPLEX)
595   PetscErrorCode ierr;
596 
597   PetscFunctionBegin;
598   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
599   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
600   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");
601   ierr = (*mat->ops->conjugate)(mat);CHKERRQ(ierr);
602 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
603   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
604     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
605   }
606 #endif
607   PetscFunctionReturn(0);
608 #else
609   return 0;
610 #endif
611 }
612 
613 /*@C
614    MatRestoreRow - Frees any temporary space allocated by MatGetRow().
615 
616    Not Collective
617 
618    Input Parameters:
619 +  mat - the matrix
620 .  row - the row to get
621 .  ncols, cols - the number of nonzeros and their columns
622 -  vals - if nonzero the column values
623 
624    Notes:
625    This routine should be called after you have finished examining the entries.
626 
627    This routine zeros out ncols, cols, and vals. This is to prevent accidental
628    us of the array after it has been restored. If you pass NULL, it will
629    not zero the pointers.  Use of cols or vals after MatRestoreRow is invalid.
630 
631    Fortran Notes:
632    The calling sequence from Fortran is
633 .vb
634    MatRestoreRow(matrix,row,ncols,cols,values,ierr)
635       Mat     matrix (input)
636       integer row    (input)
637       integer ncols  (output)
638       integer cols(maxcols) (output)
639       double precision (or double complex) values(maxcols) output
640 .ve
641    Where maxcols >= maximum nonzeros in any row of the matrix.
642 
643    In Fortran MatRestoreRow() MUST be called after MatGetRow()
644    before another call to MatGetRow() can be made.
645 
646    Level: advanced
647 
648 .seealso:  MatGetRow()
649 @*/
650 PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
651 {
652   PetscErrorCode ierr;
653 
654   PetscFunctionBegin;
655   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
656   if (ncols) PetscValidIntPointer(ncols,3);
657   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
658   if (!mat->ops->restorerow) PetscFunctionReturn(0);
659   ierr = (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);CHKERRQ(ierr);
660   if (ncols) *ncols = 0;
661   if (cols)  *cols = NULL;
662   if (vals)  *vals = NULL;
663   PetscFunctionReturn(0);
664 }
665 
666 /*@
667    MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format.
668    You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag.
669 
670    Not Collective
671 
672    Input Parameters:
673 +  mat - the matrix
674 
675    Notes:
676    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.
677 
678    Level: advanced
679 
680    Concepts: matrices^row access
681 
682 .seealso: MatRestoreRowRowUpperTriangular()
683 @*/
684 PetscErrorCode MatGetRowUpperTriangular(Mat mat)
685 {
686   PetscErrorCode ierr;
687 
688   PetscFunctionBegin;
689   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
690   PetscValidType(mat,1);
691   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
692   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
693   MatCheckPreallocated(mat,1);
694   if (!mat->ops->getrowuppertriangular) PetscFunctionReturn(0);
695   ierr = (*mat->ops->getrowuppertriangular)(mat);CHKERRQ(ierr);
696   PetscFunctionReturn(0);
697 }
698 
699 /*@
700    MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format.
701 
702    Not Collective
703 
704    Input Parameters:
705 +  mat - the matrix
706 
707    Notes:
708    This routine should be called after you have finished MatGetRow/MatRestoreRow().
709 
710 
711    Level: advanced
712 
713 .seealso:  MatGetRowUpperTriangular()
714 @*/
715 PetscErrorCode MatRestoreRowUpperTriangular(Mat mat)
716 {
717   PetscErrorCode ierr;
718 
719   PetscFunctionBegin;
720   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
721   PetscValidType(mat,1);
722   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
723   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
724   MatCheckPreallocated(mat,1);
725   if (!mat->ops->restorerowuppertriangular) PetscFunctionReturn(0);
726   ierr = (*mat->ops->restorerowuppertriangular)(mat);CHKERRQ(ierr);
727   PetscFunctionReturn(0);
728 }
729 
730 /*@C
731    MatSetOptionsPrefix - Sets the prefix used for searching for all
732    Mat options in the database.
733 
734    Logically Collective on Mat
735 
736    Input Parameter:
737 +  A - the Mat context
738 -  prefix - the prefix to prepend to all option names
739 
740    Notes:
741    A hyphen (-) must NOT be given at the beginning of the prefix name.
742    The first character of all runtime options is AUTOMATICALLY the hyphen.
743 
744    Level: advanced
745 
746 .keywords: Mat, set, options, prefix, database
747 
748 .seealso: MatSetFromOptions()
749 @*/
750 PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[])
751 {
752   PetscErrorCode ierr;
753 
754   PetscFunctionBegin;
755   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
756   ierr = PetscObjectSetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
757   PetscFunctionReturn(0);
758 }
759 
760 /*@C
761    MatAppendOptionsPrefix - Appends to the prefix used for searching for all
762    Mat options in the database.
763 
764    Logically Collective on Mat
765 
766    Input Parameters:
767 +  A - the Mat context
768 -  prefix - the prefix to prepend to all option names
769 
770    Notes:
771    A hyphen (-) must NOT be given at the beginning of the prefix name.
772    The first character of all runtime options is AUTOMATICALLY the hyphen.
773 
774    Level: advanced
775 
776 .keywords: Mat, append, options, prefix, database
777 
778 .seealso: MatGetOptionsPrefix()
779 @*/
780 PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[])
781 {
782   PetscErrorCode ierr;
783 
784   PetscFunctionBegin;
785   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
786   ierr = PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
787   PetscFunctionReturn(0);
788 }
789 
790 /*@C
791    MatGetOptionsPrefix - Sets the prefix used for searching for all
792    Mat options in the database.
793 
794    Not Collective
795 
796    Input Parameter:
797 .  A - the Mat context
798 
799    Output Parameter:
800 .  prefix - pointer to the prefix string used
801 
802    Notes:
803     On the fortran side, the user should pass in a string 'prefix' of
804    sufficient length to hold the prefix.
805 
806    Level: advanced
807 
808 .keywords: Mat, get, options, prefix, database
809 
810 .seealso: MatAppendOptionsPrefix()
811 @*/
812 PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[])
813 {
814   PetscErrorCode ierr;
815 
816   PetscFunctionBegin;
817   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
818   ierr = PetscObjectGetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
819   PetscFunctionReturn(0);
820 }
821 
822 /*@
823    MatResetPreallocation - Reset mat to use the original nonzero pattern provided by users.
824 
825    Collective on Mat
826 
827    Input Parameters:
828 .  A - the Mat context
829 
830    Notes:
831    The allocated memory will be shrunk after calling MatAssembly with MAT_FINAL_ASSEMBLY. Users can reset the preallocation to access the original memory.
832    Currently support MPIAIJ and SEQAIJ.
833 
834    Level: beginner
835 
836 .keywords: Mat, ResetPreallocation
837 
838 .seealso: MatSeqAIJSetPreallocation(), MatMPIAIJSetPreallocation(), MatXAIJSetPreallocation()
839 @*/
840 PetscErrorCode MatResetPreallocation(Mat A)
841 {
842   PetscErrorCode ierr;
843 
844   PetscFunctionBegin;
845   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
846   PetscValidType(A,1);
847   ierr = PetscUseMethod(A,"MatResetPreallocation_C",(Mat),(A));CHKERRQ(ierr);
848   PetscFunctionReturn(0);
849 }
850 
851 
852 /*@
853    MatSetUp - Sets up the internal matrix data structures for the later use.
854 
855    Collective on Mat
856 
857    Input Parameters:
858 .  A - the Mat context
859 
860    Notes:
861    If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used.
862 
863    If a suitable preallocation routine is used, this function does not need to be called.
864 
865    See the Performance chapter of the PETSc users manual for how to preallocate matrices
866 
867    Level: beginner
868 
869 .keywords: Mat, setup
870 
871 .seealso: MatCreate(), MatDestroy()
872 @*/
873 PetscErrorCode MatSetUp(Mat A)
874 {
875   PetscMPIInt    size;
876   PetscErrorCode ierr;
877 
878   PetscFunctionBegin;
879   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
880   if (!((PetscObject)A)->type_name) {
881     ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A), &size);CHKERRQ(ierr);
882     if (size == 1) {
883       ierr = MatSetType(A, MATSEQAIJ);CHKERRQ(ierr);
884     } else {
885       ierr = MatSetType(A, MATMPIAIJ);CHKERRQ(ierr);
886     }
887   }
888   if (!A->preallocated && A->ops->setup) {
889     ierr = PetscInfo(A,"Warning not preallocating matrix storage\n");CHKERRQ(ierr);
890     ierr = (*A->ops->setup)(A);CHKERRQ(ierr);
891   }
892   ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr);
893   ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr);
894   A->preallocated = PETSC_TRUE;
895   PetscFunctionReturn(0);
896 }
897 
898 #if defined(PETSC_HAVE_SAWS)
899 #include <petscviewersaws.h>
900 #endif
901 /*@C
902    MatView - Visualizes a matrix object.
903 
904    Collective on Mat
905 
906    Input Parameters:
907 +  mat - the matrix
908 -  viewer - visualization context
909 
910   Notes:
911   The available visualization contexts include
912 +    PETSC_VIEWER_STDOUT_SELF - for sequential matrices
913 .    PETSC_VIEWER_STDOUT_WORLD - for parallel matrices created on PETSC_COMM_WORLD
914 .    PETSC_VIEWER_STDOUT_(comm) - for matrices created on MPI communicator comm
915 -     PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure
916 
917    The user can open alternative visualization contexts with
918 +    PetscViewerASCIIOpen() - Outputs matrix to a specified file
919 .    PetscViewerBinaryOpen() - Outputs matrix in binary to a
920          specified file; corresponding input uses MatLoad()
921 .    PetscViewerDrawOpen() - Outputs nonzero matrix structure to
922          an X window display
923 -    PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
924          Currently only the sequential dense and AIJ
925          matrix types support the Socket viewer.
926 
927    The user can call PetscViewerPushFormat() to specify the output
928    format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
929    PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen).  Available formats include
930 +    PETSC_VIEWER_DEFAULT - default, prints matrix contents
931 .    PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
932 .    PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
933 .    PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse
934          format common among all matrix types
935 .    PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific
936          format (which is in many cases the same as the default)
937 .    PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
938          size and structure (not the matrix entries)
939 -    PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about
940          the matrix structure
941 
942    Options Database Keys:
943 +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatAssemblyEnd()
944 .  -mat_view ::ascii_info_detail - Prints more detailed info
945 .  -mat_view - Prints matrix in ASCII format
946 .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
947 .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
948 .  -display <name> - Sets display name (default is host)
949 .  -draw_pause <sec> - Sets number of seconds to pause after display
950 .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: ch_matlab for details)
951 .  -viewer_socket_machine <machine> -
952 .  -viewer_socket_port <port> -
953 .  -mat_view binary - save matrix to file in binary format
954 -  -viewer_binary_filename <name> -
955    Level: beginner
956 
957    Notes:
958     The ASCII viewers are only recommended for small matrices on at most a moderate number of processes,
959     the program will seemingly hang and take hours for larger matrices, for larger matrices one should use the binary format.
960 
961     See the manual page for MatLoad() for the exact format of the binary file when the binary
962       viewer is used.
963 
964       See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary
965       viewer is used.
966 
967       One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure,
968       and then use the following mouse functions.
969 + left mouse: zoom in
970 . middle mouse: zoom out
971 - right mouse: continue with the simulation
972 
973    Concepts: matrices^viewing
974    Concepts: matrices^plotting
975    Concepts: matrices^printing
976 
977 .seealso: PetscViewerPushFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(),
978           PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
979 @*/
980 PetscErrorCode MatView(Mat mat,PetscViewer viewer)
981 {
982   PetscErrorCode    ierr;
983   PetscInt          rows,cols,rbs,cbs;
984   PetscBool         iascii,ibinary;
985   PetscViewerFormat format;
986   PetscMPIInt       size;
987 #if defined(PETSC_HAVE_SAWS)
988   PetscBool         issaws;
989 #endif
990 
991   PetscFunctionBegin;
992   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
993   PetscValidType(mat,1);
994   if (!viewer) {
995     ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);CHKERRQ(ierr);
996   }
997   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
998   PetscCheckSameComm(mat,1,viewer,2);
999   MatCheckPreallocated(mat,1);
1000   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1001   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
1002   if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(0);
1003   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr);
1004   if (ibinary) {
1005     PetscBool mpiio;
1006     ierr = PetscViewerBinaryGetUseMPIIO(viewer,&mpiio);CHKERRQ(ierr);
1007     if (mpiio) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"PETSc matrix viewers do not support using MPI-IO, turn off that flag");
1008   }
1009 
1010   ierr = PetscLogEventBegin(MAT_View,mat,viewer,0,0);CHKERRQ(ierr);
1011   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1012   if ((!iascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) {
1013     SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detailed");
1014   }
1015 
1016 #if defined(PETSC_HAVE_SAWS)
1017   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr);
1018 #endif
1019   if (iascii) {
1020     if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
1021     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer);CHKERRQ(ierr);
1022     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
1023       MatNullSpace nullsp,transnullsp;
1024 
1025       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1026       ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr);
1027       ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr);
1028       if (rbs != 1 || cbs != 1) {
1029         if (rbs != cbs) {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, rbs=%D, cbs = %D\n",rows,cols,rbs,cbs);CHKERRQ(ierr);}
1030         else            {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,rbs);CHKERRQ(ierr);}
1031       } else {
1032         ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);CHKERRQ(ierr);
1033       }
1034       if (mat->factortype) {
1035         MatSolverType solver;
1036         ierr = MatFactorGetSolverType(mat,&solver);CHKERRQ(ierr);
1037         ierr = PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);CHKERRQ(ierr);
1038       }
1039       if (mat->ops->getinfo) {
1040         MatInfo info;
1041         ierr = MatGetInfo(mat,MAT_GLOBAL_SUM,&info);CHKERRQ(ierr);
1042         ierr = PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated);CHKERRQ(ierr);
1043         ierr = PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls =%D\n",(PetscInt)info.mallocs);CHKERRQ(ierr);
1044       }
1045       ierr = MatGetNullSpace(mat,&nullsp);CHKERRQ(ierr);
1046       ierr = MatGetTransposeNullSpace(mat,&transnullsp);CHKERRQ(ierr);
1047       if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer,"  has attached null space\n");CHKERRQ(ierr);}
1048       if (transnullsp && transnullsp != nullsp) {ierr = PetscViewerASCIIPrintf(viewer,"  has attached transposed null space\n");CHKERRQ(ierr);}
1049       ierr = MatGetNearNullSpace(mat,&nullsp);CHKERRQ(ierr);
1050       if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer,"  has attached near null space\n");CHKERRQ(ierr);}
1051     }
1052 #if defined(PETSC_HAVE_SAWS)
1053   } else if (issaws) {
1054     PetscMPIInt rank;
1055 
1056     ierr = PetscObjectName((PetscObject)mat);CHKERRQ(ierr);
1057     ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
1058     if (!((PetscObject)mat)->amsmem && !rank) {
1059       ierr = PetscObjectViewSAWs((PetscObject)mat,viewer);CHKERRQ(ierr);
1060     }
1061 #endif
1062   }
1063   if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && mat->ops->viewnative) {
1064     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1065     ierr = (*mat->ops->viewnative)(mat,viewer);CHKERRQ(ierr);
1066     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1067   } else if (mat->ops->view) {
1068     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1069     ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr);
1070     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1071   }
1072   if (iascii) {
1073     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1074     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
1075       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1076     }
1077   }
1078   ierr = PetscLogEventEnd(MAT_View,mat,viewer,0,0);CHKERRQ(ierr);
1079   PetscFunctionReturn(0);
1080 }
1081 
1082 #if defined(PETSC_USE_DEBUG)
1083 #include <../src/sys/totalview/tv_data_display.h>
1084 PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat)
1085 {
1086   TV_add_row("Local rows", "int", &mat->rmap->n);
1087   TV_add_row("Local columns", "int", &mat->cmap->n);
1088   TV_add_row("Global rows", "int", &mat->rmap->N);
1089   TV_add_row("Global columns", "int", &mat->cmap->N);
1090   TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name);
1091   return TV_format_OK;
1092 }
1093 #endif
1094 
1095 /*@C
1096    MatLoad - Loads a matrix that has been stored in binary/HDF5 format
1097    with MatView().  The matrix format is determined from the options database.
1098    Generates a parallel MPI matrix if the communicator has more than one
1099    processor.  The default matrix type is AIJ.
1100 
1101    Collective on PetscViewer
1102 
1103    Input Parameters:
1104 +  newmat - the newly loaded matrix, this needs to have been created with MatCreate()
1105             or some related function before a call to MatLoad()
1106 -  viewer - binary/HDF5 file viewer
1107 
1108    Options Database Keys:
1109    Used with block matrix formats (MATSEQBAIJ,  ...) to specify
1110    block size
1111 .    -matload_block_size <bs>
1112 
1113    Level: beginner
1114 
1115    Notes:
1116    If the Mat type has not yet been given then MATAIJ is used, call MatSetFromOptions() on the
1117    Mat before calling this routine if you wish to set it from the options database.
1118 
1119    MatLoad() automatically loads into the options database any options
1120    given in the file filename.info where filename is the name of the file
1121    that was passed to the PetscViewerBinaryOpen(). The options in the info
1122    file will be ignored if you use the -viewer_binary_skip_info option.
1123 
1124    If the type or size of newmat is not set before a call to MatLoad, PETSc
1125    sets the default matrix type AIJ and sets the local and global sizes.
1126    If type and/or size is already set, then the same are used.
1127 
1128    In parallel, each processor can load a subset of rows (or the
1129    entire matrix).  This routine is especially useful when a large
1130    matrix is stored on disk and only part of it is desired on each
1131    processor.  For example, a parallel solver may access only some of
1132    the rows from each processor.  The algorithm used here reads
1133    relatively small blocks of data rather than reading the entire
1134    matrix and then subsetting it.
1135 
1136    Viewer's PetscViewerType must be either PETSCVIEWERBINARY or PETSCVIEWERHDF5.
1137    Such viewer can be created using PetscViewerBinaryOpen()/PetscViewerHDF5Open(),
1138    or the sequence like
1139 $    PetscViewer v;
1140 $    PetscViewerCreate(PETSC_COMM_WORLD,&v);
1141 $    PetscViewerSetType(v,PETSCVIEWERBINARY);
1142 $    PetscViewerSetFromOptions(v);
1143 $    PetscViewerFileSetMode(v,FILE_MODE_READ);
1144 $    PetscViewerFileSetName(v,"datafile");
1145    The optional PetscViewerSetFromOptions() call allows to override PetscViewerSetType() using option
1146 $ -viewer_type {binary,hdf5}
1147 
1148    See the example src/ksp/ksp/examples/tutorials/ex27.c with the first approach,
1149    and src/mat/examples/tutorials/ex10.c with the second approach.
1150 
1151    Notes about the PETSc binary format:
1152    In case of PETSCVIEWERBINARY, a native PETSc binary format is used. Each of the blocks
1153    is read onto rank 0 and then shipped to its destination rank, one after another.
1154    Multiple objects, both matrices and vectors, can be stored within the same file.
1155    Their PetscObject name is ignored; they are loaded in the order of their storage.
1156 
1157    Most users should not need to know the details of the binary storage
1158    format, since MatLoad() and MatView() completely hide these details.
1159    But for anyone who's interested, the standard binary matrix storage
1160    format is
1161 
1162 $    int    MAT_FILE_CLASSID
1163 $    int    number of rows
1164 $    int    number of columns
1165 $    int    total number of nonzeros
1166 $    int    *number nonzeros in each row
1167 $    int    *column indices of all nonzeros (starting index is zero)
1168 $    PetscScalar *values of all nonzeros
1169 
1170    PETSc automatically does the byte swapping for
1171 machines that store the bytes reversed, e.g.  DEC alpha, freebsd,
1172 linux, Windows and the paragon; thus if you write your own binary
1173 read/write routines you have to swap the bytes; see PetscBinaryRead()
1174 and PetscBinaryWrite() to see how this may be done.
1175 
1176    Notes about the HDF5 (MATLAB MAT-File Version 7.3) format:
1177    In case of PETSCVIEWERHDF5, a parallel HDF5 reader is used.
1178    Each processor's chunk is loaded independently by its owning rank.
1179    Multiple objects, both matrices and vectors, can be stored within the same file.
1180    They are looked up by their PetscObject name.
1181 
1182    As the MATLAB MAT-File Version 7.3 format is also a HDF5 flavor, we decided to use
1183    by default the same structure and naming of the AIJ arrays and column count
1184    (see PetscViewerHDF5SetAIJNames())
1185    within the HDF5 file. This means that a MAT file saved with -v7.3 flag, e.g.
1186 $    save example.mat A b -v7.3
1187    can be directly read by this routine (see Reference 1 for details).
1188    Note that depending on your MATLAB version, this format might be a default,
1189    otherwise you can set it as default in Preferences.
1190 
1191    Unless -nocompression flag is used to save the file in MATLAB,
1192    PETSc must be configured with ZLIB package.
1193 
1194    See also examples src/mat/examples/tutorials/ex10.c and src/ksp/ksp/examples/tutorials/ex27.c
1195 
1196    Current HDF5 (MAT-File) limitations:
1197    This reader currently supports only real MATSEQAIJ and MATMPIAIJ matrices.
1198 
1199    Corresponding MatView() is not yet implemented.
1200 
1201    The loaded matrix is actually a transpose of the original one in MATLAB,
1202    unless you push PETSC_VIEWER_HDF5_MAT format (see examples above).
1203    With this format, matrix is automatically transposed by PETSc,
1204    unless the matrix is marked as SPD or symmetric
1205    (see MatSetOption(), MAT_SPD, MAT_SYMMETRIC).
1206 
1207    References:
1208 1. MATLAB(R) Documentation, manual page of save(), https://www.mathworks.com/help/matlab/ref/save.html#btox10b-1-version
1209 
1210 .keywords: matrix, load, binary, input, HDF5
1211 
1212 .seealso: PetscViewerBinaryOpen(), PetscViewerSetType(), PetscViewerHDF5SetAIJNames(), MatView(), VecLoad()
1213 
1214  @*/
1215 PetscErrorCode MatLoad(Mat newmat,PetscViewer viewer)
1216 {
1217   PetscErrorCode ierr;
1218   PetscBool      flg;
1219 
1220   PetscFunctionBegin;
1221   PetscValidHeaderSpecific(newmat,MAT_CLASSID,1);
1222   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1223 
1224   if (!((PetscObject)newmat)->type_name) {
1225     ierr = MatSetType(newmat,MATAIJ);CHKERRQ(ierr);
1226   }
1227 
1228   flg  = PETSC_FALSE;
1229   ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,NULL);CHKERRQ(ierr);
1230   if (flg) {
1231     ierr = MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
1232     ierr = MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);CHKERRQ(ierr);
1233   }
1234   flg  = PETSC_FALSE;
1235   ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_spd",&flg,NULL);CHKERRQ(ierr);
1236   if (flg) {
1237     ierr = MatSetOption(newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr);
1238   }
1239 
1240   if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type");
1241   ierr = PetscLogEventBegin(MAT_Load,viewer,0,0,0);CHKERRQ(ierr);
1242   ierr = (*newmat->ops->load)(newmat,viewer);CHKERRQ(ierr);
1243   ierr = PetscLogEventEnd(MAT_Load,viewer,0,0,0);CHKERRQ(ierr);
1244   PetscFunctionReturn(0);
1245 }
1246 
1247 PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant)
1248 {
1249   PetscErrorCode ierr;
1250   Mat_Redundant  *redund = *redundant;
1251   PetscInt       i;
1252 
1253   PetscFunctionBegin;
1254   if (redund){
1255     if (redund->matseq) { /* via MatCreateSubMatrices()  */
1256       ierr = ISDestroy(&redund->isrow);CHKERRQ(ierr);
1257       ierr = ISDestroy(&redund->iscol);CHKERRQ(ierr);
1258       ierr = MatDestroySubMatrices(1,&redund->matseq);CHKERRQ(ierr);
1259     } else {
1260       ierr = PetscFree2(redund->send_rank,redund->recv_rank);CHKERRQ(ierr);
1261       ierr = PetscFree(redund->sbuf_j);CHKERRQ(ierr);
1262       ierr = PetscFree(redund->sbuf_a);CHKERRQ(ierr);
1263       for (i=0; i<redund->nrecvs; i++) {
1264         ierr = PetscFree(redund->rbuf_j[i]);CHKERRQ(ierr);
1265         ierr = PetscFree(redund->rbuf_a[i]);CHKERRQ(ierr);
1266       }
1267       ierr = PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a);CHKERRQ(ierr);
1268     }
1269 
1270     if (redund->subcomm) {
1271       ierr = PetscCommDestroy(&redund->subcomm);CHKERRQ(ierr);
1272     }
1273     ierr = PetscFree(redund);CHKERRQ(ierr);
1274   }
1275   PetscFunctionReturn(0);
1276 }
1277 
1278 /*@
1279    MatDestroy - Frees space taken by a matrix.
1280 
1281    Collective on Mat
1282 
1283    Input Parameter:
1284 .  A - the matrix
1285 
1286    Level: beginner
1287 
1288 @*/
1289 PetscErrorCode MatDestroy(Mat *A)
1290 {
1291   PetscErrorCode ierr;
1292 
1293   PetscFunctionBegin;
1294   if (!*A) PetscFunctionReturn(0);
1295   PetscValidHeaderSpecific(*A,MAT_CLASSID,1);
1296   if (--((PetscObject)(*A))->refct > 0) {*A = NULL; PetscFunctionReturn(0);}
1297 
1298   /* if memory was published with SAWs then destroy it */
1299   ierr = PetscObjectSAWsViewOff((PetscObject)*A);CHKERRQ(ierr);
1300   if ((*A)->ops->destroy) {
1301     ierr = (*(*A)->ops->destroy)(*A);CHKERRQ(ierr);
1302   }
1303 
1304   ierr = PetscFree((*A)->defaultvectype);CHKERRQ(ierr);
1305   ierr = PetscFree((*A)->bsizes);CHKERRQ(ierr);
1306   ierr = PetscFree((*A)->solvertype);CHKERRQ(ierr);
1307   ierr = MatDestroy_Redundant(&(*A)->redundant);CHKERRQ(ierr);
1308   ierr = MatNullSpaceDestroy(&(*A)->nullsp);CHKERRQ(ierr);
1309   ierr = MatNullSpaceDestroy(&(*A)->transnullsp);CHKERRQ(ierr);
1310   ierr = MatNullSpaceDestroy(&(*A)->nearnullsp);CHKERRQ(ierr);
1311   ierr = MatDestroy(&(*A)->schur);CHKERRQ(ierr);
1312   ierr = PetscLayoutDestroy(&(*A)->rmap);CHKERRQ(ierr);
1313   ierr = PetscLayoutDestroy(&(*A)->cmap);CHKERRQ(ierr);
1314   ierr = PetscHeaderDestroy(A);CHKERRQ(ierr);
1315   PetscFunctionReturn(0);
1316 }
1317 
1318 /*@C
1319    MatSetValues - Inserts or adds a block of values into a matrix.
1320    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1321    MUST be called after all calls to MatSetValues() have been completed.
1322 
1323    Not Collective
1324 
1325    Input Parameters:
1326 +  mat - the matrix
1327 .  v - a logically two-dimensional array of values
1328 .  m, idxm - the number of rows and their global indices
1329 .  n, idxn - the number of columns and their global indices
1330 -  addv - either ADD_VALUES or INSERT_VALUES, where
1331    ADD_VALUES adds values to any existing entries, and
1332    INSERT_VALUES replaces existing entries with new values
1333 
1334    Notes:
1335    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
1336       MatSetUp() before using this routine
1337 
1338    By default the values, v, are row-oriented. See MatSetOption() for other options.
1339 
1340    Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
1341    options cannot be mixed without intervening calls to the assembly
1342    routines.
1343 
1344    MatSetValues() uses 0-based row and column numbers in Fortran
1345    as well as in C.
1346 
1347    Negative indices may be passed in idxm and idxn, these rows and columns are
1348    simply ignored. This allows easily inserting element stiffness matrices
1349    with homogeneous Dirchlet boundary conditions that you don't want represented
1350    in the matrix.
1351 
1352    Efficiency Alert:
1353    The routine MatSetValuesBlocked() may offer much better efficiency
1354    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1355 
1356    Level: beginner
1357 
1358    Developer Notes:
1359     This is labeled with C so does not automatically generate Fortran stubs and interfaces
1360                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
1361 
1362    Concepts: matrices^putting entries in
1363 
1364 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1365           InsertMode, INSERT_VALUES, ADD_VALUES
1366 @*/
1367 PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1368 {
1369   PetscErrorCode ierr;
1370 #if defined(PETSC_USE_DEBUG)
1371   PetscInt       i,j;
1372 #endif
1373 
1374   PetscFunctionBeginHot;
1375   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1376   PetscValidType(mat,1);
1377   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1378   PetscValidIntPointer(idxm,3);
1379   PetscValidIntPointer(idxn,5);
1380   PetscValidScalarPointer(v,6);
1381   MatCheckPreallocated(mat,1);
1382   if (mat->insertmode == NOT_SET_VALUES) {
1383     mat->insertmode = addv;
1384   }
1385 #if defined(PETSC_USE_DEBUG)
1386   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1387   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1388   if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1389 
1390   for (i=0; i<m; i++) {
1391     for (j=0; j<n; j++) {
1392       if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j]))
1393 #if defined(PETSC_USE_COMPLEX)
1394         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]);
1395 #else
1396         SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%D,%D)",(double)v[i*n+j],idxm[i],idxn[j]);
1397 #endif
1398     }
1399   }
1400 #endif
1401 
1402   if (mat->assembled) {
1403     mat->was_assembled = PETSC_TRUE;
1404     mat->assembled     = PETSC_FALSE;
1405   }
1406   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1407   ierr = (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
1408   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1409 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1410   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1411     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1412   }
1413 #endif
1414   PetscFunctionReturn(0);
1415 }
1416 
1417 
1418 /*@
1419    MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
1420         values into a matrix
1421 
1422    Not Collective
1423 
1424    Input Parameters:
1425 +  mat - the matrix
1426 .  row - the (block) row to set
1427 -  v - a logically two-dimensional array of values
1428 
1429    Notes:
1430    By the values, v, are column-oriented (for the block version) and sorted
1431 
1432    All the nonzeros in the row must be provided
1433 
1434    The matrix must have previously had its column indices set
1435 
1436    The row must belong to this process
1437 
1438    Level: intermediate
1439 
1440    Concepts: matrices^putting entries in
1441 
1442 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1443           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping()
1444 @*/
1445 PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
1446 {
1447   PetscErrorCode ierr;
1448   PetscInt       globalrow;
1449 
1450   PetscFunctionBegin;
1451   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1452   PetscValidType(mat,1);
1453   PetscValidScalarPointer(v,2);
1454   ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);CHKERRQ(ierr);
1455   ierr = MatSetValuesRow(mat,globalrow,v);CHKERRQ(ierr);
1456 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1457   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1458     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1459   }
1460 #endif
1461   PetscFunctionReturn(0);
1462 }
1463 
1464 /*@
1465    MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
1466         values into a matrix
1467 
1468    Not Collective
1469 
1470    Input Parameters:
1471 +  mat - the matrix
1472 .  row - the (block) row to set
1473 -  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
1474 
1475    Notes:
1476    The values, v, are column-oriented for the block version.
1477 
1478    All the nonzeros in the row must be provided
1479 
1480    THE MATRIX MUST HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually MatSetValues() is used.
1481 
1482    The row must belong to this process
1483 
1484    Level: advanced
1485 
1486    Concepts: matrices^putting entries in
1487 
1488 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1489           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1490 @*/
1491 PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
1492 {
1493   PetscErrorCode ierr;
1494 
1495   PetscFunctionBeginHot;
1496   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1497   PetscValidType(mat,1);
1498   MatCheckPreallocated(mat,1);
1499   PetscValidScalarPointer(v,2);
1500 #if defined(PETSC_USE_DEBUG)
1501   if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
1502   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1503 #endif
1504   mat->insertmode = INSERT_VALUES;
1505 
1506   if (mat->assembled) {
1507     mat->was_assembled = PETSC_TRUE;
1508     mat->assembled     = PETSC_FALSE;
1509   }
1510   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1511   if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1512   ierr = (*mat->ops->setvaluesrow)(mat,row,v);CHKERRQ(ierr);
1513   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1514 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1515   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1516     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1517   }
1518 #endif
1519   PetscFunctionReturn(0);
1520 }
1521 
1522 /*@
1523    MatSetValuesStencil - Inserts or adds a block of values into a matrix.
1524      Using structured grid indexing
1525 
1526    Not Collective
1527 
1528    Input Parameters:
1529 +  mat - the matrix
1530 .  m - number of rows being entered
1531 .  idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
1532 .  n - number of columns being entered
1533 .  idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered
1534 .  v - a logically two-dimensional array of values
1535 -  addv - either ADD_VALUES or INSERT_VALUES, where
1536    ADD_VALUES adds values to any existing entries, and
1537    INSERT_VALUES replaces existing entries with new values
1538 
1539    Notes:
1540    By default the values, v, are row-oriented.  See MatSetOption() for other options.
1541 
1542    Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
1543    options cannot be mixed without intervening calls to the assembly
1544    routines.
1545 
1546    The grid coordinates are across the entire grid, not just the local portion
1547 
1548    MatSetValuesStencil() uses 0-based row and column numbers in Fortran
1549    as well as in C.
1550 
1551    For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1552 
1553    In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1554    or call MatSetLocalToGlobalMapping() and MatSetStencil() first.
1555 
1556    The columns and rows in the stencil passed in MUST be contained within the
1557    ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1558    if you create a DMDA with an overlap of one grid level and on a particular process its first
1559    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1560    first i index you can use in your column and row indices in MatSetStencil() is 5.
1561 
1562    In Fortran idxm and idxn should be declared as
1563 $     MatStencil idxm(4,m),idxn(4,n)
1564    and the values inserted using
1565 $    idxm(MatStencil_i,1) = i
1566 $    idxm(MatStencil_j,1) = j
1567 $    idxm(MatStencil_k,1) = k
1568 $    idxm(MatStencil_c,1) = c
1569    etc
1570 
1571    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
1572    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
1573    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
1574    DM_BOUNDARY_PERIODIC boundary type.
1575 
1576    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
1577    a single value per point) you can skip filling those indices.
1578 
1579    Inspired by the structured grid interface to the HYPRE package
1580    (http://www.llnl.gov/CASC/hypre)
1581 
1582    Efficiency Alert:
1583    The routine MatSetValuesBlockedStencil() may offer much better efficiency
1584    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1585 
1586    Level: beginner
1587 
1588    Concepts: matrices^putting entries in
1589 
1590 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1591           MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil
1592 @*/
1593 PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1594 {
1595   PetscErrorCode ierr;
1596   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1597   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1598   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1599 
1600   PetscFunctionBegin;
1601   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1602   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1603   PetscValidType(mat,1);
1604   PetscValidIntPointer(idxm,3);
1605   PetscValidIntPointer(idxn,5);
1606   PetscValidScalarPointer(v,6);
1607 
1608   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1609     jdxm = buf; jdxn = buf+m;
1610   } else {
1611     ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr);
1612     jdxm = bufm; jdxn = bufn;
1613   }
1614   for (i=0; i<m; i++) {
1615     for (j=0; j<3-sdim; j++) dxm++;
1616     tmp = *dxm++ - starts[0];
1617     for (j=0; j<dim-1; j++) {
1618       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1619       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1620     }
1621     if (mat->stencil.noc) dxm++;
1622     jdxm[i] = tmp;
1623   }
1624   for (i=0; i<n; i++) {
1625     for (j=0; j<3-sdim; j++) dxn++;
1626     tmp = *dxn++ - starts[0];
1627     for (j=0; j<dim-1; j++) {
1628       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1629       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1630     }
1631     if (mat->stencil.noc) dxn++;
1632     jdxn[i] = tmp;
1633   }
1634   ierr = MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr);
1635   ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr);
1636   PetscFunctionReturn(0);
1637 }
1638 
1639 /*@
1640    MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1641      Using structured grid indexing
1642 
1643    Not Collective
1644 
1645    Input Parameters:
1646 +  mat - the matrix
1647 .  m - number of rows being entered
1648 .  idxm - grid coordinates for matrix rows being entered
1649 .  n - number of columns being entered
1650 .  idxn - grid coordinates for matrix columns being entered
1651 .  v - a logically two-dimensional array of values
1652 -  addv - either ADD_VALUES or INSERT_VALUES, where
1653    ADD_VALUES adds values to any existing entries, and
1654    INSERT_VALUES replaces existing entries with new values
1655 
1656    Notes:
1657    By default the values, v, are row-oriented and unsorted.
1658    See MatSetOption() for other options.
1659 
1660    Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
1661    options cannot be mixed without intervening calls to the assembly
1662    routines.
1663 
1664    The grid coordinates are across the entire grid, not just the local portion
1665 
1666    MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran
1667    as well as in C.
1668 
1669    For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1670 
1671    In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1672    or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first.
1673 
1674    The columns and rows in the stencil passed in MUST be contained within the
1675    ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1676    if you create a DMDA with an overlap of one grid level and on a particular process its first
1677    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1678    first i index you can use in your column and row indices in MatSetStencil() is 5.
1679 
1680    In Fortran idxm and idxn should be declared as
1681 $     MatStencil idxm(4,m),idxn(4,n)
1682    and the values inserted using
1683 $    idxm(MatStencil_i,1) = i
1684 $    idxm(MatStencil_j,1) = j
1685 $    idxm(MatStencil_k,1) = k
1686    etc
1687 
1688    Negative indices may be passed in idxm and idxn, these rows and columns are
1689    simply ignored. This allows easily inserting element stiffness matrices
1690    with homogeneous Dirchlet boundary conditions that you don't want represented
1691    in the matrix.
1692 
1693    Inspired by the structured grid interface to the HYPRE package
1694    (http://www.llnl.gov/CASC/hypre)
1695 
1696    Level: beginner
1697 
1698    Concepts: matrices^putting entries in
1699 
1700 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1701           MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil,
1702           MatSetBlockSize(), MatSetLocalToGlobalMapping()
1703 @*/
1704 PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1705 {
1706   PetscErrorCode ierr;
1707   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1708   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1709   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1710 
1711   PetscFunctionBegin;
1712   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1713   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1714   PetscValidType(mat,1);
1715   PetscValidIntPointer(idxm,3);
1716   PetscValidIntPointer(idxn,5);
1717   PetscValidScalarPointer(v,6);
1718 
1719   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1720     jdxm = buf; jdxn = buf+m;
1721   } else {
1722     ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr);
1723     jdxm = bufm; jdxn = bufn;
1724   }
1725   for (i=0; i<m; i++) {
1726     for (j=0; j<3-sdim; j++) dxm++;
1727     tmp = *dxm++ - starts[0];
1728     for (j=0; j<sdim-1; j++) {
1729       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1730       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1731     }
1732     dxm++;
1733     jdxm[i] = tmp;
1734   }
1735   for (i=0; i<n; i++) {
1736     for (j=0; j<3-sdim; j++) dxn++;
1737     tmp = *dxn++ - starts[0];
1738     for (j=0; j<sdim-1; j++) {
1739       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1740       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1741     }
1742     dxn++;
1743     jdxn[i] = tmp;
1744   }
1745   ierr = MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr);
1746   ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr);
1747 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1748   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1749     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1750   }
1751 #endif
1752   PetscFunctionReturn(0);
1753 }
1754 
1755 /*@
1756    MatSetStencil - Sets the grid information for setting values into a matrix via
1757         MatSetValuesStencil()
1758 
1759    Not Collective
1760 
1761    Input Parameters:
1762 +  mat - the matrix
1763 .  dim - dimension of the grid 1, 2, or 3
1764 .  dims - number of grid points in x, y, and z direction, including ghost points on your processor
1765 .  starts - starting point of ghost nodes on your processor in x, y, and z direction
1766 -  dof - number of degrees of freedom per node
1767 
1768 
1769    Inspired by the structured grid interface to the HYPRE package
1770    (www.llnl.gov/CASC/hyper)
1771 
1772    For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the
1773    user.
1774 
1775    Level: beginner
1776 
1777    Concepts: matrices^putting entries in
1778 
1779 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1780           MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
1781 @*/
1782 PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1783 {
1784   PetscInt i;
1785 
1786   PetscFunctionBegin;
1787   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1788   PetscValidIntPointer(dims,3);
1789   PetscValidIntPointer(starts,4);
1790 
1791   mat->stencil.dim = dim + (dof > 1);
1792   for (i=0; i<dim; i++) {
1793     mat->stencil.dims[i]   = dims[dim-i-1];      /* copy the values in backwards */
1794     mat->stencil.starts[i] = starts[dim-i-1];
1795   }
1796   mat->stencil.dims[dim]   = dof;
1797   mat->stencil.starts[dim] = 0;
1798   mat->stencil.noc         = (PetscBool)(dof == 1);
1799   PetscFunctionReturn(0);
1800 }
1801 
1802 /*@C
1803    MatSetValuesBlocked - Inserts or adds a block of values into a matrix.
1804 
1805    Not Collective
1806 
1807    Input Parameters:
1808 +  mat - the matrix
1809 .  v - a logically two-dimensional array of values
1810 .  m, idxm - the number of block rows and their global block indices
1811 .  n, idxn - the number of block columns and their global block indices
1812 -  addv - either ADD_VALUES or INSERT_VALUES, where
1813    ADD_VALUES adds values to any existing entries, and
1814    INSERT_VALUES replaces existing entries with new values
1815 
1816    Notes:
1817    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call
1818    MatXXXXSetPreallocation() or MatSetUp() before using this routine.
1819 
1820    The m and n count the NUMBER of blocks in the row direction and column direction,
1821    NOT the total number of rows/columns; for example, if the block size is 2 and
1822    you are passing in values for rows 2,3,4,5  then m would be 2 (not 4).
1823    The values in idxm would be 1 2; that is the first index for each block divided by
1824    the block size.
1825 
1826    Note that you must call MatSetBlockSize() when constructing this matrix (before
1827    preallocating it).
1828 
1829    By default the values, v, are row-oriented, so the layout of
1830    v is the same as for MatSetValues(). See MatSetOption() for other options.
1831 
1832    Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
1833    options cannot be mixed without intervening calls to the assembly
1834    routines.
1835 
1836    MatSetValuesBlocked() uses 0-based row and column numbers in Fortran
1837    as well as in C.
1838 
1839    Negative indices may be passed in idxm and idxn, these rows and columns are
1840    simply ignored. This allows easily inserting element stiffness matrices
1841    with homogeneous Dirchlet boundary conditions that you don't want represented
1842    in the matrix.
1843 
1844    Each time an entry is set within a sparse matrix via MatSetValues(),
1845    internal searching must be done to determine where to place the
1846    data in the matrix storage space.  By instead inserting blocks of
1847    entries via MatSetValuesBlocked(), the overhead of matrix assembly is
1848    reduced.
1849 
1850    Example:
1851 $   Suppose m=n=2 and block size(bs) = 2 The array is
1852 $
1853 $   1  2  | 3  4
1854 $   5  6  | 7  8
1855 $   - - - | - - -
1856 $   9  10 | 11 12
1857 $   13 14 | 15 16
1858 $
1859 $   v[] should be passed in like
1860 $   v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
1861 $
1862 $  If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then
1863 $   v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16]
1864 
1865    Level: intermediate
1866 
1867    Concepts: matrices^putting entries in blocked
1868 
1869 .seealso: MatSetBlockSize(), MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal()
1870 @*/
1871 PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1872 {
1873   PetscErrorCode ierr;
1874 
1875   PetscFunctionBeginHot;
1876   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1877   PetscValidType(mat,1);
1878   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1879   PetscValidIntPointer(idxm,3);
1880   PetscValidIntPointer(idxn,5);
1881   PetscValidScalarPointer(v,6);
1882   MatCheckPreallocated(mat,1);
1883   if (mat->insertmode == NOT_SET_VALUES) {
1884     mat->insertmode = addv;
1885   }
1886 #if defined(PETSC_USE_DEBUG)
1887   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1888   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1889   if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1890 #endif
1891 
1892   if (mat->assembled) {
1893     mat->was_assembled = PETSC_TRUE;
1894     mat->assembled     = PETSC_FALSE;
1895   }
1896   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1897   if (mat->ops->setvaluesblocked) {
1898     ierr = (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
1899   } else {
1900     PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn;
1901     PetscInt i,j,bs,cbs;
1902     ierr = MatGetBlockSizes(mat,&bs,&cbs);CHKERRQ(ierr);
1903     if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1904       iidxm = buf; iidxn = buf + m*bs;
1905     } else {
1906       ierr  = PetscMalloc2(m*bs,&bufr,n*cbs,&bufc);CHKERRQ(ierr);
1907       iidxm = bufr; iidxn = bufc;
1908     }
1909     for (i=0; i<m; i++) {
1910       for (j=0; j<bs; j++) {
1911         iidxm[i*bs+j] = bs*idxm[i] + j;
1912       }
1913     }
1914     for (i=0; i<n; i++) {
1915       for (j=0; j<cbs; j++) {
1916         iidxn[i*cbs+j] = cbs*idxn[i] + j;
1917       }
1918     }
1919     ierr = MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv);CHKERRQ(ierr);
1920     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
1921   }
1922   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1923 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1924   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1925     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1926   }
1927 #endif
1928   PetscFunctionReturn(0);
1929 }
1930 
1931 /*@
1932    MatGetValues - Gets a block of values from a matrix.
1933 
1934    Not Collective; currently only returns a local block
1935 
1936    Input Parameters:
1937 +  mat - the matrix
1938 .  v - a logically two-dimensional array for storing the values
1939 .  m, idxm - the number of rows and their global indices
1940 -  n, idxn - the number of columns and their global indices
1941 
1942    Notes:
1943    The user must allocate space (m*n PetscScalars) for the values, v.
1944    The values, v, are then returned in a row-oriented format,
1945    analogous to that used by default in MatSetValues().
1946 
1947    MatGetValues() uses 0-based row and column numbers in
1948    Fortran as well as in C.
1949 
1950    MatGetValues() requires that the matrix has been assembled
1951    with MatAssemblyBegin()/MatAssemblyEnd().  Thus, calls to
1952    MatSetValues() and MatGetValues() CANNOT be made in succession
1953    without intermediate matrix assembly.
1954 
1955    Negative row or column indices will be ignored and those locations in v[] will be
1956    left unchanged.
1957 
1958    Level: advanced
1959 
1960    Concepts: matrices^accessing values
1961 
1962 .seealso: MatGetRow(), MatCreateSubMatrices(), MatSetValues()
1963 @*/
1964 PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1965 {
1966   PetscErrorCode ierr;
1967 
1968   PetscFunctionBegin;
1969   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1970   PetscValidType(mat,1);
1971   if (!m || !n) PetscFunctionReturn(0);
1972   PetscValidIntPointer(idxm,3);
1973   PetscValidIntPointer(idxn,5);
1974   PetscValidScalarPointer(v,6);
1975   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1976   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1977   if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1978   MatCheckPreallocated(mat,1);
1979 
1980   ierr = PetscLogEventBegin(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
1981   ierr = (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);CHKERRQ(ierr);
1982   ierr = PetscLogEventEnd(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
1983   PetscFunctionReturn(0);
1984 }
1985 
1986 /*@
1987   MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and
1988   the same size. Currently, this can only be called once and creates the given matrix.
1989 
1990   Not Collective
1991 
1992   Input Parameters:
1993 + mat - the matrix
1994 . nb - the number of blocks
1995 . bs - the number of rows (and columns) in each block
1996 . rows - a concatenation of the rows for each block
1997 - v - a concatenation of logically two-dimensional arrays of values
1998 
1999   Notes:
2000   In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix.
2001 
2002   Level: advanced
2003 
2004   Concepts: matrices^putting entries in
2005 
2006 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
2007           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
2008 @*/
2009 PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[])
2010 {
2011   PetscErrorCode ierr;
2012 
2013   PetscFunctionBegin;
2014   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2015   PetscValidType(mat,1);
2016   PetscValidScalarPointer(rows,4);
2017   PetscValidScalarPointer(v,5);
2018 #if defined(PETSC_USE_DEBUG)
2019   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2020 #endif
2021 
2022   ierr = PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr);
2023   if (mat->ops->setvaluesbatch) {
2024     ierr = (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);CHKERRQ(ierr);
2025   } else {
2026     PetscInt b;
2027     for (b = 0; b < nb; ++b) {
2028       ierr = MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);CHKERRQ(ierr);
2029     }
2030   }
2031   ierr = PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr);
2032   PetscFunctionReturn(0);
2033 }
2034 
2035 /*@
2036    MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
2037    the routine MatSetValuesLocal() to allow users to insert matrix entries
2038    using a local (per-processor) numbering.
2039 
2040    Not Collective
2041 
2042    Input Parameters:
2043 +  x - the matrix
2044 .  rmapping - row mapping created with ISLocalToGlobalMappingCreate()   or ISLocalToGlobalMappingCreateIS()
2045 - cmapping - column mapping
2046 
2047    Level: intermediate
2048 
2049    Concepts: matrices^local to global mapping
2050    Concepts: local to global mapping^for matrices
2051 
2052 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
2053 @*/
2054 PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
2055 {
2056   PetscErrorCode ierr;
2057 
2058   PetscFunctionBegin;
2059   PetscValidHeaderSpecific(x,MAT_CLASSID,1);
2060   PetscValidType(x,1);
2061   PetscValidHeaderSpecific(rmapping,IS_LTOGM_CLASSID,2);
2062   PetscValidHeaderSpecific(cmapping,IS_LTOGM_CLASSID,3);
2063 
2064   if (x->ops->setlocaltoglobalmapping) {
2065     ierr = (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);CHKERRQ(ierr);
2066   } else {
2067     ierr = PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);CHKERRQ(ierr);
2068     ierr = PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);CHKERRQ(ierr);
2069   }
2070   PetscFunctionReturn(0);
2071 }
2072 
2073 
2074 /*@
2075    MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping()
2076 
2077    Not Collective
2078 
2079    Input Parameters:
2080 .  A - the matrix
2081 
2082    Output Parameters:
2083 + rmapping - row mapping
2084 - cmapping - column mapping
2085 
2086    Level: advanced
2087 
2088    Concepts: matrices^local to global mapping
2089    Concepts: local to global mapping^for matrices
2090 
2091 .seealso:  MatSetValuesLocal()
2092 @*/
2093 PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
2094 {
2095   PetscFunctionBegin;
2096   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2097   PetscValidType(A,1);
2098   if (rmapping) PetscValidPointer(rmapping,2);
2099   if (cmapping) PetscValidPointer(cmapping,3);
2100   if (rmapping) *rmapping = A->rmap->mapping;
2101   if (cmapping) *cmapping = A->cmap->mapping;
2102   PetscFunctionReturn(0);
2103 }
2104 
2105 /*@
2106    MatGetLayouts - Gets the PetscLayout objects for rows and columns
2107 
2108    Not Collective
2109 
2110    Input Parameters:
2111 .  A - the matrix
2112 
2113    Output Parameters:
2114 + rmap - row layout
2115 - cmap - column layout
2116 
2117    Level: advanced
2118 
2119 .seealso:  MatCreateVecs(), MatGetLocalToGlobalMapping()
2120 @*/
2121 PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap)
2122 {
2123   PetscFunctionBegin;
2124   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2125   PetscValidType(A,1);
2126   if (rmap) PetscValidPointer(rmap,2);
2127   if (cmap) PetscValidPointer(cmap,3);
2128   if (rmap) *rmap = A->rmap;
2129   if (cmap) *cmap = A->cmap;
2130   PetscFunctionReturn(0);
2131 }
2132 
2133 /*@C
2134    MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
2135    using a local ordering of the nodes.
2136 
2137    Not Collective
2138 
2139    Input Parameters:
2140 +  mat - the matrix
2141 .  nrow, irow - number of rows and their local indices
2142 .  ncol, icol - number of columns and their local indices
2143 .  y -  a logically two-dimensional array of values
2144 -  addv - either INSERT_VALUES or ADD_VALUES, where
2145    ADD_VALUES adds values to any existing entries, and
2146    INSERT_VALUES replaces existing entries with new values
2147 
2148    Notes:
2149    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
2150       MatSetUp() before using this routine
2151 
2152    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine
2153 
2154    Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
2155    options cannot be mixed without intervening calls to the assembly
2156    routines.
2157 
2158    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2159    MUST be called after all calls to MatSetValuesLocal() have been completed.
2160 
2161    Level: intermediate
2162 
2163    Concepts: matrices^putting entries in with local numbering
2164 
2165    Developer Notes:
2166     This is labeled with C so does not automatically generate Fortran stubs and interfaces
2167                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
2168 
2169 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
2170            MatSetValueLocal()
2171 @*/
2172 PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2173 {
2174   PetscErrorCode ierr;
2175 
2176   PetscFunctionBeginHot;
2177   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2178   PetscValidType(mat,1);
2179   MatCheckPreallocated(mat,1);
2180   if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */
2181   PetscValidIntPointer(irow,3);
2182   PetscValidIntPointer(icol,5);
2183   PetscValidScalarPointer(y,6);
2184   if (mat->insertmode == NOT_SET_VALUES) {
2185     mat->insertmode = addv;
2186   }
2187 #if defined(PETSC_USE_DEBUG)
2188   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2189   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2190   if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2191 #endif
2192 
2193   if (mat->assembled) {
2194     mat->was_assembled = PETSC_TRUE;
2195     mat->assembled     = PETSC_FALSE;
2196   }
2197   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2198   if (mat->ops->setvalueslocal) {
2199     ierr = (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr);
2200   } else {
2201     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2202     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2203       irowm = buf; icolm = buf+nrow;
2204     } else {
2205       ierr  = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr);
2206       irowm = bufr; icolm = bufc;
2207     }
2208     ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr);
2209     ierr = ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr);
2210     ierr = MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
2211     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
2212   }
2213   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2214 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
2215   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
2216     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
2217   }
2218 #endif
2219   PetscFunctionReturn(0);
2220 }
2221 
2222 /*@C
2223    MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix,
2224    using a local ordering of the nodes a block at a time.
2225 
2226    Not Collective
2227 
2228    Input Parameters:
2229 +  x - the matrix
2230 .  nrow, irow - number of rows and their local indices
2231 .  ncol, icol - number of columns and their local indices
2232 .  y -  a logically two-dimensional array of values
2233 -  addv - either INSERT_VALUES or ADD_VALUES, where
2234    ADD_VALUES adds values to any existing entries, and
2235    INSERT_VALUES replaces existing entries with new values
2236 
2237    Notes:
2238    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
2239       MatSetUp() before using this routine
2240 
2241    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMapping()
2242       before using this routineBefore calling MatSetValuesLocal(), the user must first set the
2243 
2244    Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
2245    options cannot be mixed without intervening calls to the assembly
2246    routines.
2247 
2248    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2249    MUST be called after all calls to MatSetValuesBlockedLocal() have been completed.
2250 
2251    Level: intermediate
2252 
2253    Developer Notes:
2254     This is labeled with C so does not automatically generate Fortran stubs and interfaces
2255                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
2256 
2257    Concepts: matrices^putting blocked values in with local numbering
2258 
2259 .seealso:  MatSetBlockSize(), MatSetLocalToGlobalMapping(), MatAssemblyBegin(), MatAssemblyEnd(),
2260            MatSetValuesLocal(),  MatSetValuesBlocked()
2261 @*/
2262 PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2263 {
2264   PetscErrorCode ierr;
2265 
2266   PetscFunctionBeginHot;
2267   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2268   PetscValidType(mat,1);
2269   MatCheckPreallocated(mat,1);
2270   if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */
2271   PetscValidIntPointer(irow,3);
2272   PetscValidIntPointer(icol,5);
2273   PetscValidScalarPointer(y,6);
2274   if (mat->insertmode == NOT_SET_VALUES) {
2275     mat->insertmode = addv;
2276   }
2277 #if defined(PETSC_USE_DEBUG)
2278   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2279   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2280   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);
2281 #endif
2282 
2283   if (mat->assembled) {
2284     mat->was_assembled = PETSC_TRUE;
2285     mat->assembled     = PETSC_FALSE;
2286   }
2287   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2288   if (mat->ops->setvaluesblockedlocal) {
2289     ierr = (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr);
2290   } else {
2291     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2292     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2293       irowm = buf; icolm = buf + nrow;
2294     } else {
2295       ierr  = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr);
2296       irowm = bufr; icolm = bufc;
2297     }
2298     ierr = ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr);
2299     ierr = ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr);
2300     ierr = MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
2301     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
2302   }
2303   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2304 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
2305   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
2306     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
2307   }
2308 #endif
2309   PetscFunctionReturn(0);
2310 }
2311 
2312 /*@
2313    MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal
2314 
2315    Collective on Mat and Vec
2316 
2317    Input Parameters:
2318 +  mat - the matrix
2319 -  x   - the vector to be multiplied
2320 
2321    Output Parameters:
2322 .  y - the result
2323 
2324    Notes:
2325    The vectors x and y cannot be the same.  I.e., one cannot
2326    call MatMult(A,y,y).
2327 
2328    Level: developer
2329 
2330    Concepts: matrix-vector product
2331 
2332 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2333 @*/
2334 PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y)
2335 {
2336   PetscErrorCode ierr;
2337 
2338   PetscFunctionBegin;
2339   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2340   PetscValidType(mat,1);
2341   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2342   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2343 
2344   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2345   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2346   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2347   MatCheckPreallocated(mat,1);
2348 
2349   if (!mat->ops->multdiagonalblock) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2350   ierr = (*mat->ops->multdiagonalblock)(mat,x,y);CHKERRQ(ierr);
2351   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2352   PetscFunctionReturn(0);
2353 }
2354 
2355 /* --------------------------------------------------------*/
2356 /*@
2357    MatMult - Computes the matrix-vector product, y = Ax.
2358 
2359    Neighbor-wise Collective on Mat and Vec
2360 
2361    Input Parameters:
2362 +  mat - the matrix
2363 -  x   - the vector to be multiplied
2364 
2365    Output Parameters:
2366 .  y - the result
2367 
2368    Notes:
2369    The vectors x and y cannot be the same.  I.e., one cannot
2370    call MatMult(A,y,y).
2371 
2372    Level: beginner
2373 
2374    Concepts: matrix-vector product
2375 
2376 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2377 @*/
2378 PetscErrorCode MatMult(Mat mat,Vec x,Vec y)
2379 {
2380   PetscErrorCode ierr;
2381 
2382   PetscFunctionBegin;
2383   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2384   PetscValidType(mat,1);
2385   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2386   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2387   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2388   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2389   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2390 #if !defined(PETSC_HAVE_CONSTRAINTS)
2391   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);
2392   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);
2393   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);
2394 #endif
2395   ierr = VecSetErrorIfLocked(y,3);CHKERRQ(ierr);
2396   if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);}
2397   MatCheckPreallocated(mat,1);
2398 
2399   ierr = VecLockReadPush(x);CHKERRQ(ierr);
2400   if (!mat->ops->mult) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2401   ierr = PetscLogEventBegin(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
2402   ierr = (*mat->ops->mult)(mat,x,y);CHKERRQ(ierr);
2403   ierr = PetscLogEventEnd(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
2404   if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);}
2405   ierr = VecLockReadPop(x);CHKERRQ(ierr);
2406   PetscFunctionReturn(0);
2407 }
2408 
2409 /*@
2410    MatMultTranspose - Computes matrix transpose times a vector y = A^T * x.
2411 
2412    Neighbor-wise Collective on Mat and Vec
2413 
2414    Input Parameters:
2415 +  mat - the matrix
2416 -  x   - the vector to be multiplied
2417 
2418    Output Parameters:
2419 .  y - the result
2420 
2421    Notes:
2422    The vectors x and y cannot be the same.  I.e., one cannot
2423    call MatMultTranspose(A,y,y).
2424 
2425    For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple,
2426    use MatMultHermitianTranspose()
2427 
2428    Level: beginner
2429 
2430    Concepts: matrix vector product^transpose
2431 
2432 .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose()
2433 @*/
2434 PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y)
2435 {
2436   PetscErrorCode ierr;
2437 
2438   PetscFunctionBegin;
2439   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2440   PetscValidType(mat,1);
2441   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2442   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2443 
2444   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2445   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2446   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2447 #if !defined(PETSC_HAVE_CONSTRAINTS)
2448   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);
2449   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);
2450 #endif
2451   if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);}
2452   MatCheckPreallocated(mat,1);
2453 
2454   if (!mat->ops->multtranspose) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply transpose defined");
2455   ierr = PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
2456   ierr = VecLockReadPush(x);CHKERRQ(ierr);
2457   ierr = (*mat->ops->multtranspose)(mat,x,y);CHKERRQ(ierr);
2458   ierr = VecLockReadPop(x);CHKERRQ(ierr);
2459   ierr = PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
2460   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2461   if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);}
2462   PetscFunctionReturn(0);
2463 }
2464 
2465 /*@
2466    MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.
2467 
2468    Neighbor-wise Collective on Mat and Vec
2469 
2470    Input Parameters:
2471 +  mat - the matrix
2472 -  x   - the vector to be multilplied
2473 
2474    Output Parameters:
2475 .  y - the result
2476 
2477    Notes:
2478    The vectors x and y cannot be the same.  I.e., one cannot
2479    call MatMultHermitianTranspose(A,y,y).
2480 
2481    Also called the conjugate transpose, complex conjugate transpose, or adjoint.
2482 
2483    For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical.
2484 
2485    Level: beginner
2486 
2487    Concepts: matrix vector product^transpose
2488 
2489 .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose()
2490 @*/
2491 PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y)
2492 {
2493   PetscErrorCode ierr;
2494   Vec            w;
2495 
2496   PetscFunctionBegin;
2497   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2498   PetscValidType(mat,1);
2499   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2500   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2501 
2502   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2503   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2504   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2505 #if !defined(PETSC_HAVE_CONSTRAINTS)
2506   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);
2507   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);
2508 #endif
2509   MatCheckPreallocated(mat,1);
2510 
2511   ierr = PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr);
2512   if (mat->ops->multhermitiantranspose) {
2513     ierr = VecLockReadPush(x);CHKERRQ(ierr);
2514     ierr = (*mat->ops->multhermitiantranspose)(mat,x,y);CHKERRQ(ierr);
2515     ierr = VecLockReadPop(x);CHKERRQ(ierr);
2516   } else {
2517     ierr = VecDuplicate(x,&w);CHKERRQ(ierr);
2518     ierr = VecCopy(x,w);CHKERRQ(ierr);
2519     ierr = VecConjugate(w);CHKERRQ(ierr);
2520     ierr = MatMultTranspose(mat,w,y);CHKERRQ(ierr);
2521     ierr = VecDestroy(&w);CHKERRQ(ierr);
2522     ierr = VecConjugate(y);CHKERRQ(ierr);
2523   }
2524   ierr = PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr);
2525   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2526   PetscFunctionReturn(0);
2527 }
2528 
2529 /*@
2530     MatMultAdd -  Computes v3 = v2 + A * v1.
2531 
2532     Neighbor-wise Collective on Mat and Vec
2533 
2534     Input Parameters:
2535 +   mat - the matrix
2536 -   v1, v2 - the vectors
2537 
2538     Output Parameters:
2539 .   v3 - the result
2540 
2541     Notes:
2542     The vectors v1 and v3 cannot be the same.  I.e., one cannot
2543     call MatMultAdd(A,v1,v2,v1).
2544 
2545     Level: beginner
2546 
2547     Concepts: matrix vector product^addition
2548 
2549 .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
2550 @*/
2551 PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2552 {
2553   PetscErrorCode ierr;
2554 
2555   PetscFunctionBegin;
2556   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2557   PetscValidType(mat,1);
2558   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2559   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2560   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2561 
2562   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2563   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2564   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);
2565   /* 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);
2566      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); */
2567   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);
2568   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);
2569   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2570   MatCheckPreallocated(mat,1);
2571 
2572   if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name);
2573   ierr = PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2574   ierr = VecLockReadPush(v1);CHKERRQ(ierr);
2575   ierr = (*mat->ops->multadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2576   ierr = VecLockReadPop(v1);CHKERRQ(ierr);
2577   ierr = PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2578   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2579   PetscFunctionReturn(0);
2580 }
2581 
2582 /*@
2583    MatMultTransposeAdd - Computes v3 = v2 + A' * v1.
2584 
2585    Neighbor-wise Collective on Mat and Vec
2586 
2587    Input Parameters:
2588 +  mat - the matrix
2589 -  v1, v2 - the vectors
2590 
2591    Output Parameters:
2592 .  v3 - the result
2593 
2594    Notes:
2595    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2596    call MatMultTransposeAdd(A,v1,v2,v1).
2597 
2598    Level: beginner
2599 
2600    Concepts: matrix vector product^transpose and addition
2601 
2602 .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
2603 @*/
2604 PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2605 {
2606   PetscErrorCode ierr;
2607 
2608   PetscFunctionBegin;
2609   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2610   PetscValidType(mat,1);
2611   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2612   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2613   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2614 
2615   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2616   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2617   if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2618   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2619   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);
2620   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);
2621   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);
2622   MatCheckPreallocated(mat,1);
2623 
2624   ierr = PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2625   ierr = VecLockReadPush(v1);CHKERRQ(ierr);
2626   ierr = (*mat->ops->multtransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2627   ierr = VecLockReadPop(v1);CHKERRQ(ierr);
2628   ierr = PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2629   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2630   PetscFunctionReturn(0);
2631 }
2632 
2633 /*@
2634    MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1.
2635 
2636    Neighbor-wise Collective on Mat and Vec
2637 
2638    Input Parameters:
2639 +  mat - the matrix
2640 -  v1, v2 - the vectors
2641 
2642    Output Parameters:
2643 .  v3 - the result
2644 
2645    Notes:
2646    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2647    call MatMultHermitianTransposeAdd(A,v1,v2,v1).
2648 
2649    Level: beginner
2650 
2651    Concepts: matrix vector product^transpose and addition
2652 
2653 .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult()
2654 @*/
2655 PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2656 {
2657   PetscErrorCode ierr;
2658 
2659   PetscFunctionBegin;
2660   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2661   PetscValidType(mat,1);
2662   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2663   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2664   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2665 
2666   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2667   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2668   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2669   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);
2670   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);
2671   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);
2672   MatCheckPreallocated(mat,1);
2673 
2674   ierr = PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2675   ierr = VecLockReadPush(v1);CHKERRQ(ierr);
2676   if (mat->ops->multhermitiantransposeadd) {
2677     ierr = (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2678   } else {
2679     Vec w,z;
2680     ierr = VecDuplicate(v1,&w);CHKERRQ(ierr);
2681     ierr = VecCopy(v1,w);CHKERRQ(ierr);
2682     ierr = VecConjugate(w);CHKERRQ(ierr);
2683     ierr = VecDuplicate(v3,&z);CHKERRQ(ierr);
2684     ierr = MatMultTranspose(mat,w,z);CHKERRQ(ierr);
2685     ierr = VecDestroy(&w);CHKERRQ(ierr);
2686     ierr = VecConjugate(z);CHKERRQ(ierr);
2687     if (v2 != v3) {
2688       ierr = VecWAXPY(v3,1.0,v2,z);CHKERRQ(ierr);
2689     } else {
2690       ierr = VecAXPY(v3,1.0,z);CHKERRQ(ierr);
2691     }
2692     ierr = VecDestroy(&z);CHKERRQ(ierr);
2693   }
2694   ierr = VecLockReadPop(v1);CHKERRQ(ierr);
2695   ierr = PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2696   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2697   PetscFunctionReturn(0);
2698 }
2699 
2700 /*@
2701    MatMultConstrained - The inner multiplication routine for a
2702    constrained matrix P^T A P.
2703 
2704    Neighbor-wise Collective on Mat and Vec
2705 
2706    Input Parameters:
2707 +  mat - the matrix
2708 -  x   - the vector to be multilplied
2709 
2710    Output Parameters:
2711 .  y - the result
2712 
2713    Notes:
2714    The vectors x and y cannot be the same.  I.e., one cannot
2715    call MatMult(A,y,y).
2716 
2717    Level: beginner
2718 
2719 .keywords: matrix, multiply, matrix-vector product, constraint
2720 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2721 @*/
2722 PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y)
2723 {
2724   PetscErrorCode ierr;
2725 
2726   PetscFunctionBegin;
2727   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2728   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2729   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2730   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2731   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2732   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2733   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);
2734   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);
2735   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);
2736 
2737   ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2738   ierr = VecLockReadPush(x);CHKERRQ(ierr);
2739   ierr = (*mat->ops->multconstrained)(mat,x,y);CHKERRQ(ierr);
2740   ierr = VecLockReadPop(x);CHKERRQ(ierr);
2741   ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2742   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2743   PetscFunctionReturn(0);
2744 }
2745 
2746 /*@
2747    MatMultTransposeConstrained - The inner multiplication routine for a
2748    constrained matrix P^T A^T P.
2749 
2750    Neighbor-wise Collective on Mat and Vec
2751 
2752    Input Parameters:
2753 +  mat - the matrix
2754 -  x   - the vector to be multilplied
2755 
2756    Output Parameters:
2757 .  y - the result
2758 
2759    Notes:
2760    The vectors x and y cannot be the same.  I.e., one cannot
2761    call MatMult(A,y,y).
2762 
2763    Level: beginner
2764 
2765 .keywords: matrix, multiply, matrix-vector product, constraint
2766 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2767 @*/
2768 PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2769 {
2770   PetscErrorCode ierr;
2771 
2772   PetscFunctionBegin;
2773   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2774   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2775   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2776   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2777   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2778   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2779   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);
2780   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);
2781 
2782   ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2783   ierr = (*mat->ops->multtransposeconstrained)(mat,x,y);CHKERRQ(ierr);
2784   ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2785   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2786   PetscFunctionReturn(0);
2787 }
2788 
2789 /*@C
2790    MatGetFactorType - gets the type of factorization it is
2791 
2792    Not Collective
2793 
2794    Input Parameters:
2795 .  mat - the matrix
2796 
2797    Output Parameters:
2798 .  t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT
2799 
2800    Level: intermediate
2801 
2802 .seealso: MatFactorType, MatGetFactor(), MatSetFactorType()
2803 @*/
2804 PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t)
2805 {
2806   PetscFunctionBegin;
2807   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2808   PetscValidType(mat,1);
2809   PetscValidPointer(t,2);
2810   *t = mat->factortype;
2811   PetscFunctionReturn(0);
2812 }
2813 
2814 /*@C
2815    MatSetFactorType - sets the type of factorization it is
2816 
2817    Logically Collective on Mat
2818 
2819    Input Parameters:
2820 +  mat - the matrix
2821 -  t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT
2822 
2823    Level: intermediate
2824 
2825 .seealso: MatFactorType, MatGetFactor(), MatGetFactorType()
2826 @*/
2827 PetscErrorCode MatSetFactorType(Mat mat, MatFactorType t)
2828 {
2829   PetscFunctionBegin;
2830   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2831   PetscValidType(mat,1);
2832   mat->factortype = t;
2833   PetscFunctionReturn(0);
2834 }
2835 
2836 /* ------------------------------------------------------------*/
2837 /*@C
2838    MatGetInfo - Returns information about matrix storage (number of
2839    nonzeros, memory, etc.).
2840 
2841    Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag
2842 
2843    Input Parameters:
2844 .  mat - the matrix
2845 
2846    Output Parameters:
2847 +  flag - flag indicating the type of parameters to be returned
2848    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2849    MAT_GLOBAL_SUM - sum over all processors)
2850 -  info - matrix information context
2851 
2852    Notes:
2853    The MatInfo context contains a variety of matrix data, including
2854    number of nonzeros allocated and used, number of mallocs during
2855    matrix assembly, etc.  Additional information for factored matrices
2856    is provided (such as the fill ratio, number of mallocs during
2857    factorization, etc.).  Much of this info is printed to PETSC_STDOUT
2858    when using the runtime options
2859 $       -info -mat_view ::ascii_info
2860 
2861    Example for C/C++ Users:
2862    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2863    data within the MatInfo context.  For example,
2864 .vb
2865       MatInfo info;
2866       Mat     A;
2867       double  mal, nz_a, nz_u;
2868 
2869       MatGetInfo(A,MAT_LOCAL,&info);
2870       mal  = info.mallocs;
2871       nz_a = info.nz_allocated;
2872 .ve
2873 
2874    Example for Fortran Users:
2875    Fortran users should declare info as a double precision
2876    array of dimension MAT_INFO_SIZE, and then extract the parameters
2877    of interest.  See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h
2878    a complete list of parameter names.
2879 .vb
2880       double  precision info(MAT_INFO_SIZE)
2881       double  precision mal, nz_a
2882       Mat     A
2883       integer ierr
2884 
2885       call MatGetInfo(A,MAT_LOCAL,info,ierr)
2886       mal = info(MAT_INFO_MALLOCS)
2887       nz_a = info(MAT_INFO_NZ_ALLOCATED)
2888 .ve
2889 
2890     Level: intermediate
2891 
2892     Concepts: matrices^getting information on
2893 
2894     Developer Note: fortran interface is not autogenerated as the f90
2895     interface defintion cannot be generated correctly [due to MatInfo]
2896 
2897 .seealso: MatStashGetInfo()
2898 
2899 @*/
2900 PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2901 {
2902   PetscErrorCode ierr;
2903 
2904   PetscFunctionBegin;
2905   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2906   PetscValidType(mat,1);
2907   PetscValidPointer(info,3);
2908   if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2909   MatCheckPreallocated(mat,1);
2910   ierr = (*mat->ops->getinfo)(mat,flag,info);CHKERRQ(ierr);
2911   PetscFunctionReturn(0);
2912 }
2913 
2914 /*
2915    This is used by external packages where it is not easy to get the info from the actual
2916    matrix factorization.
2917 */
2918 PetscErrorCode MatGetInfo_External(Mat A,MatInfoType flag,MatInfo *info)
2919 {
2920   PetscErrorCode ierr;
2921 
2922   PetscFunctionBegin;
2923   ierr = PetscMemzero(info,sizeof(MatInfo));CHKERRQ(ierr);
2924   PetscFunctionReturn(0);
2925 }
2926 
2927 /* ----------------------------------------------------------*/
2928 
2929 /*@C
2930    MatLUFactor - Performs in-place LU factorization of matrix.
2931 
2932    Collective on Mat
2933 
2934    Input Parameters:
2935 +  mat - the matrix
2936 .  row - row permutation
2937 .  col - column permutation
2938 -  info - options for factorization, includes
2939 $          fill - expected fill as ratio of original fill.
2940 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2941 $                   Run with the option -info to determine an optimal value to use
2942 
2943    Notes:
2944    Most users should employ the simplified KSP interface for linear solvers
2945    instead of working directly with matrix algebra routines such as this.
2946    See, e.g., KSPCreate().
2947 
2948    This changes the state of the matrix to a factored matrix; it cannot be used
2949    for example with MatSetValues() unless one first calls MatSetUnfactored().
2950 
2951    Level: developer
2952 
2953    Concepts: matrices^LU factorization
2954 
2955 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2956           MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor()
2957 
2958     Developer Note: fortran interface is not autogenerated as the f90
2959     interface defintion cannot be generated correctly [due to MatFactorInfo]
2960 
2961 @*/
2962 PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2963 {
2964   PetscErrorCode ierr;
2965   MatFactorInfo  tinfo;
2966 
2967   PetscFunctionBegin;
2968   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2969   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
2970   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
2971   if (info) PetscValidPointer(info,4);
2972   PetscValidType(mat,1);
2973   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2974   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2975   if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2976   MatCheckPreallocated(mat,1);
2977   if (!info) {
2978     ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr);
2979     info = &tinfo;
2980   }
2981 
2982   ierr = PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
2983   ierr = (*mat->ops->lufactor)(mat,row,col,info);CHKERRQ(ierr);
2984   ierr = PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
2985   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
2986   PetscFunctionReturn(0);
2987 }
2988 
2989 /*@C
2990    MatILUFactor - Performs in-place ILU factorization of matrix.
2991 
2992    Collective on Mat
2993 
2994    Input Parameters:
2995 +  mat - the matrix
2996 .  row - row permutation
2997 .  col - column permutation
2998 -  info - structure containing
2999 $      levels - number of levels of fill.
3000 $      expected fill - as ratio of original fill.
3001 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
3002                 missing diagonal entries)
3003 
3004    Notes:
3005    Probably really in-place only when level of fill is zero, otherwise allocates
3006    new space to store factored matrix and deletes previous memory.
3007 
3008    Most users should employ the simplified KSP interface for linear solvers
3009    instead of working directly with matrix algebra routines such as this.
3010    See, e.g., KSPCreate().
3011 
3012    Level: developer
3013 
3014    Concepts: matrices^ILU factorization
3015 
3016 .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
3017 
3018     Developer Note: fortran interface is not autogenerated as the f90
3019     interface defintion cannot be generated correctly [due to MatFactorInfo]
3020 
3021 @*/
3022 PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
3023 {
3024   PetscErrorCode ierr;
3025 
3026   PetscFunctionBegin;
3027   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3028   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
3029   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
3030   PetscValidPointer(info,4);
3031   PetscValidType(mat,1);
3032   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
3033   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3034   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3035   if (!mat->ops->ilufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3036   MatCheckPreallocated(mat,1);
3037 
3038   ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
3039   ierr = (*mat->ops->ilufactor)(mat,row,col,info);CHKERRQ(ierr);
3040   ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
3041   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
3042   PetscFunctionReturn(0);
3043 }
3044 
3045 /*@C
3046    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
3047    Call this routine before calling MatLUFactorNumeric().
3048 
3049    Collective on Mat
3050 
3051    Input Parameters:
3052 +  fact - the factor matrix obtained with MatGetFactor()
3053 .  mat - the matrix
3054 .  row, col - row and column permutations
3055 -  info - options for factorization, includes
3056 $          fill - expected fill as ratio of original fill.
3057 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3058 $                   Run with the option -info to determine an optimal value to use
3059 
3060 
3061    Notes:
3062     See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
3063 
3064    Most users should employ the simplified KSP interface for linear solvers
3065    instead of working directly with matrix algebra routines such as this.
3066    See, e.g., KSPCreate().
3067 
3068    Level: developer
3069 
3070    Concepts: matrices^LU symbolic factorization
3071 
3072 .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo, MatFactorInfoInitialize()
3073 
3074     Developer Note: fortran interface is not autogenerated as the f90
3075     interface defintion cannot be generated correctly [due to MatFactorInfo]
3076 
3077 @*/
3078 PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
3079 {
3080   PetscErrorCode ierr;
3081 
3082   PetscFunctionBegin;
3083   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3084   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
3085   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
3086   if (info) PetscValidPointer(info,4);
3087   PetscValidType(mat,1);
3088   PetscValidPointer(fact,5);
3089   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3090   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3091   if (!(fact)->ops->lufactorsymbolic) {
3092     MatSolverType spackage;
3093     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
3094     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage);
3095   }
3096   MatCheckPreallocated(mat,2);
3097 
3098   ierr = PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
3099   ierr = (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
3100   ierr = PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
3101   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3102   PetscFunctionReturn(0);
3103 }
3104 
3105 /*@C
3106    MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
3107    Call this routine after first calling MatLUFactorSymbolic().
3108 
3109    Collective on Mat
3110 
3111    Input Parameters:
3112 +  fact - the factor matrix obtained with MatGetFactor()
3113 .  mat - the matrix
3114 -  info - options for factorization
3115 
3116    Notes:
3117    See MatLUFactor() for in-place factorization.  See
3118    MatCholeskyFactorNumeric() for the symmetric, positive definite case.
3119 
3120    Most users should employ the simplified KSP interface for linear solvers
3121    instead of working directly with matrix algebra routines such as this.
3122    See, e.g., KSPCreate().
3123 
3124    Level: developer
3125 
3126    Concepts: matrices^LU numeric factorization
3127 
3128 .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()
3129 
3130     Developer Note: fortran interface is not autogenerated as the f90
3131     interface defintion cannot be generated correctly [due to MatFactorInfo]
3132 
3133 @*/
3134 PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3135 {
3136   PetscErrorCode ierr;
3137 
3138   PetscFunctionBegin;
3139   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3140   PetscValidType(mat,1);
3141   PetscValidPointer(fact,2);
3142   PetscValidHeaderSpecific(fact,MAT_CLASSID,2);
3143   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3144   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);
3145 
3146   if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name);
3147   MatCheckPreallocated(mat,2);
3148   ierr = PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3149   ierr = (fact->ops->lufactornumeric)(fact,mat,info);CHKERRQ(ierr);
3150   ierr = PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3151   ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr);
3152   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3153   PetscFunctionReturn(0);
3154 }
3155 
3156 /*@C
3157    MatCholeskyFactor - Performs in-place Cholesky factorization of a
3158    symmetric matrix.
3159 
3160    Collective on Mat
3161 
3162    Input Parameters:
3163 +  mat - the matrix
3164 .  perm - row and column permutations
3165 -  f - expected fill as ratio of original fill
3166 
3167    Notes:
3168    See MatLUFactor() for the nonsymmetric case.  See also
3169    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().
3170 
3171    Most users should employ the simplified KSP interface for linear solvers
3172    instead of working directly with matrix algebra routines such as this.
3173    See, e.g., KSPCreate().
3174 
3175    Level: developer
3176 
3177    Concepts: matrices^Cholesky factorization
3178 
3179 .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
3180           MatGetOrdering()
3181 
3182     Developer Note: fortran interface is not autogenerated as the f90
3183     interface defintion cannot be generated correctly [due to MatFactorInfo]
3184 
3185 @*/
3186 PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
3187 {
3188   PetscErrorCode ierr;
3189 
3190   PetscFunctionBegin;
3191   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3192   PetscValidType(mat,1);
3193   if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2);
3194   if (info) PetscValidPointer(info,3);
3195   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3196   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3197   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3198   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);
3199   MatCheckPreallocated(mat,1);
3200 
3201   ierr = PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
3202   ierr = (*mat->ops->choleskyfactor)(mat,perm,info);CHKERRQ(ierr);
3203   ierr = PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
3204   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
3205   PetscFunctionReturn(0);
3206 }
3207 
3208 /*@C
3209    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
3210    of a symmetric matrix.
3211 
3212    Collective on Mat
3213 
3214    Input Parameters:
3215 +  fact - the factor matrix obtained with MatGetFactor()
3216 .  mat - the matrix
3217 .  perm - row and column permutations
3218 -  info - options for factorization, includes
3219 $          fill - expected fill as ratio of original fill.
3220 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3221 $                   Run with the option -info to determine an optimal value to use
3222 
3223    Notes:
3224    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
3225    MatCholeskyFactor() and MatCholeskyFactorNumeric().
3226 
3227    Most users should employ the simplified KSP interface for linear solvers
3228    instead of working directly with matrix algebra routines such as this.
3229    See, e.g., KSPCreate().
3230 
3231    Level: developer
3232 
3233    Concepts: matrices^Cholesky symbolic factorization
3234 
3235 .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
3236           MatGetOrdering()
3237 
3238     Developer Note: fortran interface is not autogenerated as the f90
3239     interface defintion cannot be generated correctly [due to MatFactorInfo]
3240 
3241 @*/
3242 PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
3243 {
3244   PetscErrorCode ierr;
3245 
3246   PetscFunctionBegin;
3247   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3248   PetscValidType(mat,1);
3249   if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2);
3250   if (info) PetscValidPointer(info,3);
3251   PetscValidPointer(fact,4);
3252   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3253   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3254   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3255   if (!(fact)->ops->choleskyfactorsymbolic) {
3256     MatSolverType spackage;
3257     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
3258     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage);
3259   }
3260   MatCheckPreallocated(mat,2);
3261 
3262   ierr = PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
3263   ierr = (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
3264   ierr = PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
3265   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3266   PetscFunctionReturn(0);
3267 }
3268 
3269 /*@C
3270    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
3271    of a symmetric matrix. Call this routine after first calling
3272    MatCholeskyFactorSymbolic().
3273 
3274    Collective on Mat
3275 
3276    Input Parameters:
3277 +  fact - the factor matrix obtained with MatGetFactor()
3278 .  mat - the initial matrix
3279 .  info - options for factorization
3280 -  fact - the symbolic factor of mat
3281 
3282 
3283    Notes:
3284    Most users should employ the simplified KSP interface for linear solvers
3285    instead of working directly with matrix algebra routines such as this.
3286    See, e.g., KSPCreate().
3287 
3288    Level: developer
3289 
3290    Concepts: matrices^Cholesky numeric factorization
3291 
3292 .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
3293 
3294     Developer Note: fortran interface is not autogenerated as the f90
3295     interface defintion cannot be generated correctly [due to MatFactorInfo]
3296 
3297 @*/
3298 PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3299 {
3300   PetscErrorCode ierr;
3301 
3302   PetscFunctionBegin;
3303   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3304   PetscValidType(mat,1);
3305   PetscValidPointer(fact,2);
3306   PetscValidHeaderSpecific(fact,MAT_CLASSID,2);
3307   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3308   if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name);
3309   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);
3310   MatCheckPreallocated(mat,2);
3311 
3312   ierr = PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3313   ierr = (fact->ops->choleskyfactornumeric)(fact,mat,info);CHKERRQ(ierr);
3314   ierr = PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3315   ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr);
3316   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3317   PetscFunctionReturn(0);
3318 }
3319 
3320 /* ----------------------------------------------------------------*/
3321 /*@
3322    MatSolve - Solves A x = b, given a factored matrix.
3323 
3324    Neighbor-wise Collective on Mat and Vec
3325 
3326    Input Parameters:
3327 +  mat - the factored matrix
3328 -  b - the right-hand-side vector
3329 
3330    Output Parameter:
3331 .  x - the result vector
3332 
3333    Notes:
3334    The vectors b and x cannot be the same.  I.e., one cannot
3335    call MatSolve(A,x,x).
3336 
3337    Notes:
3338    Most users should employ the simplified KSP interface for linear solvers
3339    instead of working directly with matrix algebra routines such as this.
3340    See, e.g., KSPCreate().
3341 
3342    Level: developer
3343 
3344    Concepts: matrices^triangular solves
3345 
3346 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
3347 @*/
3348 PetscErrorCode MatSolve(Mat mat,Vec b,Vec x)
3349 {
3350   PetscErrorCode ierr;
3351 
3352   PetscFunctionBegin;
3353   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3354   PetscValidType(mat,1);
3355   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3356   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3357   PetscCheckSameComm(mat,1,b,2);
3358   PetscCheckSameComm(mat,1,x,3);
3359   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3360   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);
3361   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);
3362   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);
3363   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3364   if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3365   MatCheckPreallocated(mat,1);
3366 
3367   ierr = PetscLogEventBegin(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
3368   if (mat->factorerrortype) {
3369     ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3370     ierr = VecSetInf(x);CHKERRQ(ierr);
3371   } else {
3372     if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3373     ierr = (*mat->ops->solve)(mat,b,x);CHKERRQ(ierr);
3374   }
3375   ierr = PetscLogEventEnd(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
3376   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3377   PetscFunctionReturn(0);
3378 }
3379 
3380 static PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X, PetscBool trans)
3381 {
3382   PetscErrorCode ierr;
3383   Vec            b,x;
3384   PetscInt       m,N,i;
3385   PetscScalar    *bb,*xx;
3386   PetscBool      flg;
3387 
3388   PetscFunctionBegin;
3389   ierr = PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr);
3390   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
3391   ierr = PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr);
3392   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");
3393 
3394   ierr = MatDenseGetArray(B,&bb);CHKERRQ(ierr);
3395   ierr = MatDenseGetArray(X,&xx);CHKERRQ(ierr);
3396   ierr = MatGetLocalSize(B,&m,NULL);CHKERRQ(ierr);  /* number local rows */
3397   ierr = MatGetSize(B,NULL,&N);CHKERRQ(ierr);       /* total columns in dense matrix */
3398   ierr = MatCreateVecs(A,&x,&b);CHKERRQ(ierr);
3399   for (i=0; i<N; i++) {
3400     ierr = VecPlaceArray(b,bb + i*m);CHKERRQ(ierr);
3401     ierr = VecPlaceArray(x,xx + i*m);CHKERRQ(ierr);
3402     if (trans) {
3403       ierr = MatSolveTranspose(A,b,x);CHKERRQ(ierr);
3404     } else {
3405       ierr = MatSolve(A,b,x);CHKERRQ(ierr);
3406     }
3407     ierr = VecResetArray(x);CHKERRQ(ierr);
3408     ierr = VecResetArray(b);CHKERRQ(ierr);
3409   }
3410   ierr = VecDestroy(&b);CHKERRQ(ierr);
3411   ierr = VecDestroy(&x);CHKERRQ(ierr);
3412   ierr = MatDenseRestoreArray(B,&bb);CHKERRQ(ierr);
3413   ierr = MatDenseRestoreArray(X,&xx);CHKERRQ(ierr);
3414   PetscFunctionReturn(0);
3415 }
3416 
3417 /*@
3418    MatMatSolve - Solves A X = B, given a factored matrix.
3419 
3420    Neighbor-wise Collective on Mat
3421 
3422    Input Parameters:
3423 +  A - the factored matrix
3424 -  B - the right-hand-side matrix  (dense matrix)
3425 
3426    Output Parameter:
3427 .  X - the result matrix (dense matrix)
3428 
3429    Notes:
3430    The matrices b and x cannot be the same.  I.e., one cannot
3431    call MatMatSolve(A,x,x).
3432 
3433    Notes:
3434    Most users should usually employ the simplified KSP interface for linear solvers
3435    instead of working directly with matrix algebra routines such as this.
3436    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3437    at a time.
3438 
3439    When using SuperLU_Dist as a parallel solver PETSc will use the SuperLU_Dist functionality to solve multiple right hand sides simultaneously. For MUMPS
3440    it calls a separate solve for each right hand side since MUMPS does not yet support distributed right hand sides.
3441 
3442    Since the resulting matrix X must always be dense we do not support sparse representation of the matrix B.
3443 
3444    Level: developer
3445 
3446    Concepts: matrices^triangular solves
3447 
3448 .seealso: MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor()
3449 @*/
3450 PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X)
3451 {
3452   PetscErrorCode ierr;
3453 
3454   PetscFunctionBegin;
3455   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3456   PetscValidType(A,1);
3457   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3458   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3459   PetscCheckSameComm(A,1,B,2);
3460   PetscCheckSameComm(A,1,X,3);
3461   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3462   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);
3463   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);
3464   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");
3465   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3466   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3467   MatCheckPreallocated(A,1);
3468 
3469   ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3470   if (!A->ops->matsolve) {
3471     ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name);CHKERRQ(ierr);
3472     ierr = MatMatSolve_Basic(A,B,X,PETSC_FALSE);CHKERRQ(ierr);
3473   } else {
3474     ierr = (*A->ops->matsolve)(A,B,X);CHKERRQ(ierr);
3475   }
3476   ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3477   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3478   PetscFunctionReturn(0);
3479 }
3480 
3481 /*@
3482    MatMatSolveTranspose - Solves A^T X = B, given a factored matrix.
3483 
3484    Neighbor-wise Collective on Mat
3485 
3486    Input Parameters:
3487 +  A - the factored matrix
3488 -  B - the right-hand-side matrix  (dense matrix)
3489 
3490    Output Parameter:
3491 .  X - the result matrix (dense matrix)
3492 
3493    Notes:
3494    The matrices B and X cannot be the same.  I.e., one cannot
3495    call MatMatSolveTranspose(A,X,X).
3496 
3497    Notes:
3498    Most users should usually employ the simplified KSP interface for linear solvers
3499    instead of working directly with matrix algebra routines such as this.
3500    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3501    at a time.
3502 
3503    When using SuperLU_Dist or MUMPS as a parallel solver, PETSc will use their functionality to solve multiple right hand sides simultaneously.
3504 
3505    Level: developer
3506 
3507    Concepts: matrices^triangular solves
3508 
3509 .seealso: MatMatSolve(), MatLUFactor(), MatCholeskyFactor()
3510 @*/
3511 PetscErrorCode MatMatSolveTranspose(Mat A,Mat B,Mat X)
3512 {
3513   PetscErrorCode ierr;
3514 
3515   PetscFunctionBegin;
3516   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3517   PetscValidType(A,1);
3518   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3519   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3520   PetscCheckSameComm(A,1,B,2);
3521   PetscCheckSameComm(A,1,X,3);
3522   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3523   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);
3524   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);
3525   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);
3526   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");
3527   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3528   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3529   MatCheckPreallocated(A,1);
3530 
3531   ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3532   if (!A->ops->matsolvetranspose) {
3533     ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolveTranspose\n",((PetscObject)A)->type_name);CHKERRQ(ierr);
3534     ierr = MatMatSolve_Basic(A,B,X,PETSC_TRUE);CHKERRQ(ierr);
3535   } else {
3536     ierr = (*A->ops->matsolvetranspose)(A,B,X);CHKERRQ(ierr);
3537   }
3538   ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3539   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3540   PetscFunctionReturn(0);
3541 }
3542 
3543 /*@
3544    MatMatTransposeSolve - Solves A X = B^T, given a factored matrix.
3545 
3546    Neighbor-wise Collective on Mat
3547 
3548    Input Parameters:
3549 +  A - the factored matrix
3550 -  Bt - the transpose of right-hand-side matrix
3551 
3552    Output Parameter:
3553 .  X - the result matrix (dense matrix)
3554 
3555    Notes:
3556    Most users should usually employ the simplified KSP interface for linear solvers
3557    instead of working directly with matrix algebra routines such as this.
3558    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3559    at a time.
3560 
3561    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().
3562 
3563    Level: developer
3564 
3565    Concepts: matrices^triangular solves
3566 
3567 .seealso: MatMatSolve(), MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor()
3568 @*/
3569 PetscErrorCode MatMatTransposeSolve(Mat A,Mat Bt,Mat X)
3570 {
3571   PetscErrorCode ierr;
3572 
3573   PetscFunctionBegin;
3574   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3575   PetscValidType(A,1);
3576   PetscValidHeaderSpecific(Bt,MAT_CLASSID,2);
3577   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3578   PetscCheckSameComm(A,1,Bt,2);
3579   PetscCheckSameComm(A,1,X,3);
3580 
3581   if (X == Bt) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3582   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);
3583   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);
3584   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");
3585   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3586   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3587   MatCheckPreallocated(A,1);
3588 
3589   if (!A->ops->mattransposesolve) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
3590   ierr = PetscLogEventBegin(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr);
3591   ierr = (*A->ops->mattransposesolve)(A,Bt,X);CHKERRQ(ierr);
3592   ierr = PetscLogEventEnd(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr);
3593   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3594   PetscFunctionReturn(0);
3595 }
3596 
3597 /*@
3598    MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or
3599                             U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U,
3600 
3601    Neighbor-wise Collective on Mat and Vec
3602 
3603    Input Parameters:
3604 +  mat - the factored matrix
3605 -  b - the right-hand-side vector
3606 
3607    Output Parameter:
3608 .  x - the result vector
3609 
3610    Notes:
3611    MatSolve() should be used for most applications, as it performs
3612    a forward solve followed by a backward solve.
3613 
3614    The vectors b and x cannot be the same,  i.e., one cannot
3615    call MatForwardSolve(A,x,x).
3616 
3617    For matrix in seqsbaij format with block size larger than 1,
3618    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3619    MatForwardSolve() solves U^T*D y = b, and
3620    MatBackwardSolve() solves U x = y.
3621    Thus they do not provide a symmetric preconditioner.
3622 
3623    Most users should employ the simplified KSP interface for linear solvers
3624    instead of working directly with matrix algebra routines such as this.
3625    See, e.g., KSPCreate().
3626 
3627    Level: developer
3628 
3629    Concepts: matrices^forward solves
3630 
3631 .seealso: MatSolve(), MatBackwardSolve()
3632 @*/
3633 PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x)
3634 {
3635   PetscErrorCode ierr;
3636 
3637   PetscFunctionBegin;
3638   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3639   PetscValidType(mat,1);
3640   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3641   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3642   PetscCheckSameComm(mat,1,b,2);
3643   PetscCheckSameComm(mat,1,x,3);
3644   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3645   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);
3646   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);
3647   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);
3648   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3649   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3650   MatCheckPreallocated(mat,1);
3651 
3652   if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3653   ierr = PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
3654   ierr = (*mat->ops->forwardsolve)(mat,b,x);CHKERRQ(ierr);
3655   ierr = PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
3656   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3657   PetscFunctionReturn(0);
3658 }
3659 
3660 /*@
3661    MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
3662                              D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U,
3663 
3664    Neighbor-wise Collective on Mat and Vec
3665 
3666    Input Parameters:
3667 +  mat - the factored matrix
3668 -  b - the right-hand-side vector
3669 
3670    Output Parameter:
3671 .  x - the result vector
3672 
3673    Notes:
3674    MatSolve() should be used for most applications, as it performs
3675    a forward solve followed by a backward solve.
3676 
3677    The vectors b and x cannot be the same.  I.e., one cannot
3678    call MatBackwardSolve(A,x,x).
3679 
3680    For matrix in seqsbaij format with block size larger than 1,
3681    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3682    MatForwardSolve() solves U^T*D y = b, and
3683    MatBackwardSolve() solves U x = y.
3684    Thus they do not provide a symmetric preconditioner.
3685 
3686    Most users should employ the simplified KSP interface for linear solvers
3687    instead of working directly with matrix algebra routines such as this.
3688    See, e.g., KSPCreate().
3689 
3690    Level: developer
3691 
3692    Concepts: matrices^backward solves
3693 
3694 .seealso: MatSolve(), MatForwardSolve()
3695 @*/
3696 PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x)
3697 {
3698   PetscErrorCode ierr;
3699 
3700   PetscFunctionBegin;
3701   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3702   PetscValidType(mat,1);
3703   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3704   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3705   PetscCheckSameComm(mat,1,b,2);
3706   PetscCheckSameComm(mat,1,x,3);
3707   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3708   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);
3709   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);
3710   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);
3711   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3712   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3713   MatCheckPreallocated(mat,1);
3714 
3715   if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3716   ierr = PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
3717   ierr = (*mat->ops->backwardsolve)(mat,b,x);CHKERRQ(ierr);
3718   ierr = PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
3719   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3720   PetscFunctionReturn(0);
3721 }
3722 
3723 /*@
3724    MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
3725 
3726    Neighbor-wise Collective on Mat and Vec
3727 
3728    Input Parameters:
3729 +  mat - the factored matrix
3730 .  b - the right-hand-side vector
3731 -  y - the vector to be added to
3732 
3733    Output Parameter:
3734 .  x - the result vector
3735 
3736    Notes:
3737    The vectors b and x cannot be the same.  I.e., one cannot
3738    call MatSolveAdd(A,x,y,x).
3739 
3740    Most users should employ the simplified KSP interface for linear solvers
3741    instead of working directly with matrix algebra routines such as this.
3742    See, e.g., KSPCreate().
3743 
3744    Level: developer
3745 
3746    Concepts: matrices^triangular solves
3747 
3748 .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3749 @*/
3750 PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3751 {
3752   PetscScalar    one = 1.0;
3753   Vec            tmp;
3754   PetscErrorCode ierr;
3755 
3756   PetscFunctionBegin;
3757   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3758   PetscValidType(mat,1);
3759   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3760   PetscValidHeaderSpecific(b,VEC_CLASSID,3);
3761   PetscValidHeaderSpecific(x,VEC_CLASSID,4);
3762   PetscCheckSameComm(mat,1,b,2);
3763   PetscCheckSameComm(mat,1,y,2);
3764   PetscCheckSameComm(mat,1,x,3);
3765   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3766   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);
3767   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);
3768   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);
3769   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);
3770   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);
3771   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3772   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3773   MatCheckPreallocated(mat,1);
3774 
3775   ierr = PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
3776   if (mat->ops->solveadd) {
3777     ierr = (*mat->ops->solveadd)(mat,b,y,x);CHKERRQ(ierr);
3778   } else {
3779     /* do the solve then the add manually */
3780     if (x != y) {
3781       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
3782       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
3783     } else {
3784       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
3785       ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr);
3786       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
3787       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
3788       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
3789       ierr = VecDestroy(&tmp);CHKERRQ(ierr);
3790     }
3791   }
3792   ierr = PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
3793   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3794   PetscFunctionReturn(0);
3795 }
3796 
3797 /*@
3798    MatSolveTranspose - Solves A' x = b, given a factored matrix.
3799 
3800    Neighbor-wise Collective on Mat and Vec
3801 
3802    Input Parameters:
3803 +  mat - the factored matrix
3804 -  b - the right-hand-side vector
3805 
3806    Output Parameter:
3807 .  x - the result vector
3808 
3809    Notes:
3810    The vectors b and x cannot be the same.  I.e., one cannot
3811    call MatSolveTranspose(A,x,x).
3812 
3813    Most users should employ the simplified KSP interface for linear solvers
3814    instead of working directly with matrix algebra routines such as this.
3815    See, e.g., KSPCreate().
3816 
3817    Level: developer
3818 
3819    Concepts: matrices^triangular solves
3820 
3821 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
3822 @*/
3823 PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x)
3824 {
3825   PetscErrorCode ierr;
3826 
3827   PetscFunctionBegin;
3828   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3829   PetscValidType(mat,1);
3830   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3831   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3832   PetscCheckSameComm(mat,1,b,2);
3833   PetscCheckSameComm(mat,1,x,3);
3834   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3835   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);
3836   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);
3837   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3838   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3839   MatCheckPreallocated(mat,1);
3840   ierr = PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
3841   if (mat->factorerrortype) {
3842     ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3843     ierr = VecSetInf(x);CHKERRQ(ierr);
3844   } else {
3845     if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3846     ierr = (*mat->ops->solvetranspose)(mat,b,x);CHKERRQ(ierr);
3847   }
3848   ierr = PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
3849   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3850   PetscFunctionReturn(0);
3851 }
3852 
3853 /*@
3854    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
3855                       factored matrix.
3856 
3857    Neighbor-wise Collective on Mat and Vec
3858 
3859    Input Parameters:
3860 +  mat - the factored matrix
3861 .  b - the right-hand-side vector
3862 -  y - the vector to be added to
3863 
3864    Output Parameter:
3865 .  x - the result vector
3866 
3867    Notes:
3868    The vectors b and x cannot be the same.  I.e., one cannot
3869    call MatSolveTransposeAdd(A,x,y,x).
3870 
3871    Most users should employ the simplified KSP interface for linear solvers
3872    instead of working directly with matrix algebra routines such as this.
3873    See, e.g., KSPCreate().
3874 
3875    Level: developer
3876 
3877    Concepts: matrices^triangular solves
3878 
3879 .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3880 @*/
3881 PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3882 {
3883   PetscScalar    one = 1.0;
3884   PetscErrorCode ierr;
3885   Vec            tmp;
3886 
3887   PetscFunctionBegin;
3888   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3889   PetscValidType(mat,1);
3890   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3891   PetscValidHeaderSpecific(b,VEC_CLASSID,3);
3892   PetscValidHeaderSpecific(x,VEC_CLASSID,4);
3893   PetscCheckSameComm(mat,1,b,2);
3894   PetscCheckSameComm(mat,1,y,3);
3895   PetscCheckSameComm(mat,1,x,4);
3896   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3897   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);
3898   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);
3899   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);
3900   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);
3901   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3902   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3903   MatCheckPreallocated(mat,1);
3904 
3905   ierr = PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
3906   if (mat->ops->solvetransposeadd) {
3907     if (mat->factorerrortype) {
3908       ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3909       ierr = VecSetInf(x);CHKERRQ(ierr);
3910     } else {
3911       ierr = (*mat->ops->solvetransposeadd)(mat,b,y,x);CHKERRQ(ierr);
3912     }
3913   } else {
3914     /* do the solve then the add manually */
3915     if (x != y) {
3916       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
3917       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
3918     } else {
3919       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
3920       ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr);
3921       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
3922       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
3923       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
3924       ierr = VecDestroy(&tmp);CHKERRQ(ierr);
3925     }
3926   }
3927   ierr = PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
3928   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3929   PetscFunctionReturn(0);
3930 }
3931 /* ----------------------------------------------------------------*/
3932 
3933 /*@
3934    MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps.
3935 
3936    Neighbor-wise Collective on Mat and Vec
3937 
3938    Input Parameters:
3939 +  mat - the matrix
3940 .  b - the right hand side
3941 .  omega - the relaxation factor
3942 .  flag - flag indicating the type of SOR (see below)
3943 .  shift -  diagonal shift
3944 .  its - the number of iterations
3945 -  lits - the number of local iterations
3946 
3947    Output Parameters:
3948 .  x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess)
3949 
3950    SOR Flags:
3951 .     SOR_FORWARD_SWEEP - forward SOR
3952 .     SOR_BACKWARD_SWEEP - backward SOR
3953 .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3954 .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR
3955 .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
3956 .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3957 .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
3958          upper/lower triangular part of matrix to
3959          vector (with omega)
3960 .     SOR_ZERO_INITIAL_GUESS - zero initial guess
3961 
3962    Notes:
3963    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3964    SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3965    on each processor.
3966 
3967    Application programmers will not generally use MatSOR() directly,
3968    but instead will employ the KSP/PC interface.
3969 
3970    Notes:
3971     for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing
3972 
3973    Notes for Advanced Users:
3974    The flags are implemented as bitwise inclusive or operations.
3975    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3976    to specify a zero initial guess for SSOR.
3977 
3978    Most users should employ the simplified KSP interface for linear solvers
3979    instead of working directly with matrix algebra routines such as this.
3980    See, e.g., KSPCreate().
3981 
3982    Vectors x and b CANNOT be the same
3983 
3984    Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes
3985 
3986    Level: developer
3987 
3988    Concepts: matrices^relaxation
3989    Concepts: matrices^SOR
3990    Concepts: matrices^Gauss-Seidel
3991 
3992 @*/
3993 PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3994 {
3995   PetscErrorCode ierr;
3996 
3997   PetscFunctionBegin;
3998   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3999   PetscValidType(mat,1);
4000   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
4001   PetscValidHeaderSpecific(x,VEC_CLASSID,8);
4002   PetscCheckSameComm(mat,1,b,2);
4003   PetscCheckSameComm(mat,1,x,8);
4004   if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4005   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4006   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4007   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);
4008   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);
4009   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);
4010   if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
4011   if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
4012   if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");
4013 
4014   MatCheckPreallocated(mat,1);
4015   ierr = PetscLogEventBegin(MAT_SOR,mat,b,x,0);CHKERRQ(ierr);
4016   ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr);
4017   ierr = PetscLogEventEnd(MAT_SOR,mat,b,x,0);CHKERRQ(ierr);
4018   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
4019   PetscFunctionReturn(0);
4020 }
4021 
4022 /*
4023       Default matrix copy routine.
4024 */
4025 PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
4026 {
4027   PetscErrorCode    ierr;
4028   PetscInt          i,rstart = 0,rend = 0,nz;
4029   const PetscInt    *cwork;
4030   const PetscScalar *vwork;
4031 
4032   PetscFunctionBegin;
4033   if (B->assembled) {
4034     ierr = MatZeroEntries(B);CHKERRQ(ierr);
4035   }
4036   if (str == SAME_NONZERO_PATTERN) {
4037     ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
4038     for (i=rstart; i<rend; i++) {
4039       ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
4040       ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);CHKERRQ(ierr);
4041       ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
4042     }
4043   } else {
4044     ierr = MatAYPX(B,0.0,A,str);CHKERRQ(ierr);
4045   }
4046   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4047   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4048   PetscFunctionReturn(0);
4049 }
4050 
4051 /*@
4052    MatCopy - Copies a matrix to another matrix.
4053 
4054    Collective on Mat
4055 
4056    Input Parameters:
4057 +  A - the matrix
4058 -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
4059 
4060    Output Parameter:
4061 .  B - where the copy is put
4062 
4063    Notes:
4064    If you use SAME_NONZERO_PATTERN then the two matrices had better have the
4065    same nonzero pattern or the routine will crash.
4066 
4067    MatCopy() copies the matrix entries of a matrix to another existing
4068    matrix (after first zeroing the second matrix).  A related routine is
4069    MatConvert(), which first creates a new matrix and then copies the data.
4070 
4071    Level: intermediate
4072 
4073    Concepts: matrices^copying
4074 
4075 .seealso: MatConvert(), MatDuplicate()
4076 
4077 @*/
4078 PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str)
4079 {
4080   PetscErrorCode ierr;
4081   PetscInt       i;
4082 
4083   PetscFunctionBegin;
4084   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4085   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4086   PetscValidType(A,1);
4087   PetscValidType(B,2);
4088   PetscCheckSameComm(A,1,B,2);
4089   MatCheckPreallocated(B,2);
4090   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4091   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4092   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);
4093   MatCheckPreallocated(A,1);
4094   if (A == B) PetscFunctionReturn(0);
4095 
4096   ierr = PetscLogEventBegin(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
4097   if (A->ops->copy) {
4098     ierr = (*A->ops->copy)(A,B,str);CHKERRQ(ierr);
4099   } else { /* generic conversion */
4100     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
4101   }
4102 
4103   B->stencil.dim = A->stencil.dim;
4104   B->stencil.noc = A->stencil.noc;
4105   for (i=0; i<=A->stencil.dim; i++) {
4106     B->stencil.dims[i]   = A->stencil.dims[i];
4107     B->stencil.starts[i] = A->stencil.starts[i];
4108   }
4109 
4110   ierr = PetscLogEventEnd(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
4111   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
4112   PetscFunctionReturn(0);
4113 }
4114 
4115 /*@C
4116    MatConvert - Converts a matrix to another matrix, either of the same
4117    or different type.
4118 
4119    Collective on Mat
4120 
4121    Input Parameters:
4122 +  mat - the matrix
4123 .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
4124    same type as the original matrix.
4125 -  reuse - denotes if the destination matrix is to be created or reused.
4126    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
4127    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).
4128 
4129    Output Parameter:
4130 .  M - pointer to place new matrix
4131 
4132    Notes:
4133    MatConvert() first creates a new matrix and then copies the data from
4134    the first matrix.  A related routine is MatCopy(), which copies the matrix
4135    entries of one matrix to another already existing matrix context.
4136 
4137    Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
4138    the MPI communicator of the generated matrix is always the same as the communicator
4139    of the input matrix.
4140 
4141    Level: intermediate
4142 
4143    Concepts: matrices^converting between storage formats
4144 
4145 .seealso: MatCopy(), MatDuplicate()
4146 @*/
4147 PetscErrorCode MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M)
4148 {
4149   PetscErrorCode ierr;
4150   PetscBool      sametype,issame,flg;
4151   char           convname[256],mtype[256];
4152   Mat            B;
4153 
4154   PetscFunctionBegin;
4155   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4156   PetscValidType(mat,1);
4157   PetscValidPointer(M,3);
4158   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4159   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4160   MatCheckPreallocated(mat,1);
4161 
4162   ierr = PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);CHKERRQ(ierr);
4163   if (flg) {
4164     newtype = mtype;
4165   }
4166   ierr = PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);CHKERRQ(ierr);
4167   ierr = PetscStrcmp(newtype,"same",&issame);CHKERRQ(ierr);
4168   if ((reuse == MAT_INPLACE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix");
4169   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");
4170 
4171   if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) PetscFunctionReturn(0);
4172 
4173   if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
4174     ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
4175   } else {
4176     PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL;
4177     const char     *prefix[3] = {"seq","mpi",""};
4178     PetscInt       i;
4179     /*
4180        Order of precedence:
4181        0) See if newtype is a superclass of the current matrix.
4182        1) See if a specialized converter is known to the current matrix.
4183        2) See if a specialized converter is known to the desired matrix class.
4184        3) See if a good general converter is registered for the desired class
4185           (as of 6/27/03 only MATMPIADJ falls into this category).
4186        4) See if a good general converter is known for the current matrix.
4187        5) Use a really basic converter.
4188     */
4189 
4190     /* 0) See if newtype is a superclass of the current matrix.
4191           i.e mat is mpiaij and newtype is aij */
4192     for (i=0; i<2; i++) {
4193       ierr = PetscStrncpy(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4194       ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr);
4195       ierr = PetscStrcmp(convname,((PetscObject)mat)->type_name,&flg);CHKERRQ(ierr);
4196       ierr = PetscInfo3(mat,"Check superclass %s %s -> %d\n",convname,((PetscObject)mat)->type_name,flg);CHKERRQ(ierr);
4197       if (flg) {
4198         if (reuse == MAT_INPLACE_MATRIX) {
4199           PetscFunctionReturn(0);
4200         } else if (reuse == MAT_INITIAL_MATRIX && mat->ops->duplicate) {
4201           ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
4202           PetscFunctionReturn(0);
4203         } else if (reuse == MAT_REUSE_MATRIX && mat->ops->copy) {
4204           ierr = MatCopy(mat,*M,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
4205           PetscFunctionReturn(0);
4206         }
4207       }
4208     }
4209     /* 1) See if a specialized converter is known to the current matrix and the desired class */
4210     for (i=0; i<3; i++) {
4211       ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr);
4212       ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr);
4213       ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr);
4214       ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4215       ierr = PetscStrlcat(convname,issame ? ((PetscObject)mat)->type_name : newtype,sizeof(convname));CHKERRQ(ierr);
4216       ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr);
4217       ierr = PetscObjectQueryFunction((PetscObject)mat,convname,&conv);CHKERRQ(ierr);
4218       ierr = PetscInfo3(mat,"Check specialized (1) %s (%s) -> %d\n",convname,((PetscObject)mat)->type_name,!!conv);CHKERRQ(ierr);
4219       if (conv) goto foundconv;
4220     }
4221 
4222     /* 2)  See if a specialized converter is known to the desired matrix class. */
4223     ierr = MatCreate(PetscObjectComm((PetscObject)mat),&B);CHKERRQ(ierr);
4224     ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);CHKERRQ(ierr);
4225     ierr = MatSetType(B,newtype);CHKERRQ(ierr);
4226     for (i=0; i<3; i++) {
4227       ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr);
4228       ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr);
4229       ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr);
4230       ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4231       ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr);
4232       ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr);
4233       ierr = PetscObjectQueryFunction((PetscObject)B,convname,&conv);CHKERRQ(ierr);
4234       ierr = PetscInfo3(mat,"Check specialized (2) %s (%s) -> %d\n",convname,((PetscObject)B)->type_name,!!conv);CHKERRQ(ierr);
4235       if (conv) {
4236         ierr = MatDestroy(&B);CHKERRQ(ierr);
4237         goto foundconv;
4238       }
4239     }
4240 
4241     /* 3) See if a good general converter is registered for the desired class */
4242     conv = B->ops->convertfrom;
4243     ierr = PetscInfo2(mat,"Check convertfrom (%s) -> %d\n",((PetscObject)B)->type_name,!!conv);CHKERRQ(ierr);
4244     ierr = MatDestroy(&B);CHKERRQ(ierr);
4245     if (conv) goto foundconv;
4246 
4247     /* 4) See if a good general converter is known for the current matrix */
4248     if (mat->ops->convert) {
4249       conv = mat->ops->convert;
4250     }
4251     ierr = PetscInfo2(mat,"Check general convert (%s) -> %d\n",((PetscObject)mat)->type_name,!!conv);CHKERRQ(ierr);
4252     if (conv) goto foundconv;
4253 
4254     /* 5) Use a really basic converter. */
4255     ierr = PetscInfo(mat,"Using MatConvert_Basic\n");CHKERRQ(ierr);
4256     conv = MatConvert_Basic;
4257 
4258 foundconv:
4259     ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4260     ierr = (*conv)(mat,newtype,reuse,M);CHKERRQ(ierr);
4261     if (mat->rmap->mapping && mat->cmap->mapping && !(*M)->rmap->mapping && !(*M)->cmap->mapping) {
4262       /* the block sizes must be same if the mappings are copied over */
4263       (*M)->rmap->bs = mat->rmap->bs;
4264       (*M)->cmap->bs = mat->cmap->bs;
4265       ierr = PetscObjectReference((PetscObject)mat->rmap->mapping);CHKERRQ(ierr);
4266       ierr = PetscObjectReference((PetscObject)mat->cmap->mapping);CHKERRQ(ierr);
4267       (*M)->rmap->mapping = mat->rmap->mapping;
4268       (*M)->cmap->mapping = mat->cmap->mapping;
4269     }
4270     (*M)->stencil.dim = mat->stencil.dim;
4271     (*M)->stencil.noc = mat->stencil.noc;
4272     for (i=0; i<=mat->stencil.dim; i++) {
4273       (*M)->stencil.dims[i]   = mat->stencil.dims[i];
4274       (*M)->stencil.starts[i] = mat->stencil.starts[i];
4275     }
4276     ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4277   }
4278   ierr = PetscObjectStateIncrease((PetscObject)*M);CHKERRQ(ierr);
4279 
4280   /* Copy Mat options */
4281   if (mat->symmetric) {ierr = MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);}
4282   if (mat->hermitian) {ierr = MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);}
4283   PetscFunctionReturn(0);
4284 }
4285 
4286 /*@C
4287    MatFactorGetSolverType - Returns name of the package providing the factorization routines
4288 
4289    Not Collective
4290 
4291    Input Parameter:
4292 .  mat - the matrix, must be a factored matrix
4293 
4294    Output Parameter:
4295 .   type - the string name of the package (do not free this string)
4296 
4297    Notes:
4298       In Fortran you pass in a empty string and the package name will be copied into it.
4299     (Make sure the string is long enough)
4300 
4301    Level: intermediate
4302 
4303 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
4304 @*/
4305 PetscErrorCode MatFactorGetSolverType(Mat mat, MatSolverType *type)
4306 {
4307   PetscErrorCode ierr, (*conv)(Mat,MatSolverType*);
4308 
4309   PetscFunctionBegin;
4310   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4311   PetscValidType(mat,1);
4312   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
4313   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverType_C",&conv);CHKERRQ(ierr);
4314   if (!conv) {
4315     *type = MATSOLVERPETSC;
4316   } else {
4317     ierr = (*conv)(mat,type);CHKERRQ(ierr);
4318   }
4319   PetscFunctionReturn(0);
4320 }
4321 
4322 typedef struct _MatSolverTypeForSpecifcType* MatSolverTypeForSpecifcType;
4323 struct _MatSolverTypeForSpecifcType {
4324   MatType                        mtype;
4325   PetscErrorCode                 (*getfactor[4])(Mat,MatFactorType,Mat*);
4326   MatSolverTypeForSpecifcType next;
4327 };
4328 
4329 typedef struct _MatSolverTypeHolder* MatSolverTypeHolder;
4330 struct _MatSolverTypeHolder {
4331   char                           *name;
4332   MatSolverTypeForSpecifcType handlers;
4333   MatSolverTypeHolder         next;
4334 };
4335 
4336 static MatSolverTypeHolder MatSolverTypeHolders = NULL;
4337 
4338 /*@C
4339    MatSolvePackageRegister - Registers a MatSolverType that works for a particular matrix type
4340 
4341    Input Parameters:
4342 +    package - name of the package, for example petsc or superlu
4343 .    mtype - the matrix type that works with this package
4344 .    ftype - the type of factorization supported by the package
4345 -    getfactor - routine that will create the factored matrix ready to be used
4346 
4347     Level: intermediate
4348 
4349 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4350 @*/
4351 PetscErrorCode MatSolverTypeRegister(MatSolverType package,MatType mtype,MatFactorType ftype,PetscErrorCode (*getfactor)(Mat,MatFactorType,Mat*))
4352 {
4353   PetscErrorCode              ierr;
4354   MatSolverTypeHolder         next = MatSolverTypeHolders,prev;
4355   PetscBool                   flg;
4356   MatSolverTypeForSpecifcType inext,iprev = NULL;
4357 
4358   PetscFunctionBegin;
4359   ierr = MatInitializePackage();CHKERRQ(ierr);
4360   if (!next) {
4361     ierr = PetscNew(&MatSolverTypeHolders);CHKERRQ(ierr);
4362     ierr = PetscStrallocpy(package,&MatSolverTypeHolders->name);CHKERRQ(ierr);
4363     ierr = PetscNew(&MatSolverTypeHolders->handlers);CHKERRQ(ierr);
4364     ierr = PetscStrallocpy(mtype,(char **)&MatSolverTypeHolders->handlers->mtype);CHKERRQ(ierr);
4365     MatSolverTypeHolders->handlers->getfactor[(int)ftype-1] = getfactor;
4366     PetscFunctionReturn(0);
4367   }
4368   while (next) {
4369     ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr);
4370     if (flg) {
4371       if (!next->handlers) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverTypeHolder is missing handlers");
4372       inext = next->handlers;
4373       while (inext) {
4374         ierr = PetscStrcasecmp(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4375         if (flg) {
4376           inext->getfactor[(int)ftype-1] = getfactor;
4377           PetscFunctionReturn(0);
4378         }
4379         iprev = inext;
4380         inext = inext->next;
4381       }
4382       ierr = PetscNew(&iprev->next);CHKERRQ(ierr);
4383       ierr = PetscStrallocpy(mtype,(char **)&iprev->next->mtype);CHKERRQ(ierr);
4384       iprev->next->getfactor[(int)ftype-1] = getfactor;
4385       PetscFunctionReturn(0);
4386     }
4387     prev = next;
4388     next = next->next;
4389   }
4390   ierr = PetscNew(&prev->next);CHKERRQ(ierr);
4391   ierr = PetscStrallocpy(package,&prev->next->name);CHKERRQ(ierr);
4392   ierr = PetscNew(&prev->next->handlers);CHKERRQ(ierr);
4393   ierr = PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);CHKERRQ(ierr);
4394   prev->next->handlers->getfactor[(int)ftype-1] = getfactor;
4395   PetscFunctionReturn(0);
4396 }
4397 
4398 /*@C
4399    MatSolvePackageGet - Get's the function that creates the factor matrix if it exist
4400 
4401    Input Parameters:
4402 +    package - name of the package, for example petsc or superlu
4403 .    ftype - the type of factorization supported by the package
4404 -    mtype - the matrix type that works with this package
4405 
4406    Output Parameters:
4407 +   foundpackage - PETSC_TRUE if the package was registered
4408 .   foundmtype - PETSC_TRUE if the package supports the requested mtype
4409 -   getfactor - routine that will create the factored matrix ready to be used or NULL if not found
4410 
4411     Level: intermediate
4412 
4413 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4414 @*/
4415 PetscErrorCode MatSolverTypeGet(MatSolverType package,MatType mtype,MatFactorType ftype,PetscBool *foundpackage,PetscBool *foundmtype,PetscErrorCode (**getfactor)(Mat,MatFactorType,Mat*))
4416 {
4417   PetscErrorCode                 ierr;
4418   MatSolverTypeHolder         next = MatSolverTypeHolders;
4419   PetscBool                      flg;
4420   MatSolverTypeForSpecifcType inext;
4421 
4422   PetscFunctionBegin;
4423   if (foundpackage) *foundpackage = PETSC_FALSE;
4424   if (foundmtype)   *foundmtype   = PETSC_FALSE;
4425   if (getfactor)    *getfactor    = NULL;
4426 
4427   if (package) {
4428     while (next) {
4429       ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr);
4430       if (flg) {
4431         if (foundpackage) *foundpackage = PETSC_TRUE;
4432         inext = next->handlers;
4433         while (inext) {
4434           ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4435           if (flg) {
4436             if (foundmtype) *foundmtype = PETSC_TRUE;
4437             if (getfactor)  *getfactor  = inext->getfactor[(int)ftype-1];
4438             PetscFunctionReturn(0);
4439           }
4440           inext = inext->next;
4441         }
4442       }
4443       next = next->next;
4444     }
4445   } else {
4446     while (next) {
4447       inext = next->handlers;
4448       while (inext) {
4449         ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4450         if (flg && inext->getfactor[(int)ftype-1]) {
4451           if (foundpackage) *foundpackage = PETSC_TRUE;
4452           if (foundmtype)   *foundmtype   = PETSC_TRUE;
4453           if (getfactor)    *getfactor    = inext->getfactor[(int)ftype-1];
4454           PetscFunctionReturn(0);
4455         }
4456         inext = inext->next;
4457       }
4458       next = next->next;
4459     }
4460   }
4461   PetscFunctionReturn(0);
4462 }
4463 
4464 PetscErrorCode MatSolverTypeDestroy(void)
4465 {
4466   PetscErrorCode              ierr;
4467   MatSolverTypeHolder         next = MatSolverTypeHolders,prev;
4468   MatSolverTypeForSpecifcType inext,iprev;
4469 
4470   PetscFunctionBegin;
4471   while (next) {
4472     ierr = PetscFree(next->name);CHKERRQ(ierr);
4473     inext = next->handlers;
4474     while (inext) {
4475       ierr = PetscFree(inext->mtype);CHKERRQ(ierr);
4476       iprev = inext;
4477       inext = inext->next;
4478       ierr = PetscFree(iprev);CHKERRQ(ierr);
4479     }
4480     prev = next;
4481     next = next->next;
4482     ierr = PetscFree(prev);CHKERRQ(ierr);
4483   }
4484   MatSolverTypeHolders = NULL;
4485   PetscFunctionReturn(0);
4486 }
4487 
4488 /*@C
4489    MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic()
4490 
4491    Collective on Mat
4492 
4493    Input Parameters:
4494 +  mat - the matrix
4495 .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4496 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4497 
4498    Output Parameters:
4499 .  f - the factor matrix used with MatXXFactorSymbolic() calls
4500 
4501    Notes:
4502       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4503      such as pastix, superlu, mumps etc.
4504 
4505       PETSc must have been ./configure to use the external solver, using the option --download-package
4506 
4507    Level: intermediate
4508 
4509 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4510 @*/
4511 PetscErrorCode MatGetFactor(Mat mat, MatSolverType type,MatFactorType ftype,Mat *f)
4512 {
4513   PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
4514   PetscBool      foundpackage,foundmtype;
4515 
4516   PetscFunctionBegin;
4517   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4518   PetscValidType(mat,1);
4519 
4520   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4521   MatCheckPreallocated(mat,1);
4522 
4523   ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,&foundpackage,&foundmtype,&conv);CHKERRQ(ierr);
4524   if (!foundpackage) {
4525     if (type) {
4526       SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver package %s. Perhaps you must ./configure with --download-%s",type,type);
4527     } else {
4528       SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate a solver package. Perhaps you must ./configure with --download-<package>");
4529     }
4530   }
4531 
4532   if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support matrix type %s",type,((PetscObject)mat)->type_name);
4533   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);
4534 
4535 #if defined(PETSC_USE_COMPLEX)
4536   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");
4537 #endif
4538 
4539   ierr = (*conv)(mat,ftype,f);CHKERRQ(ierr);
4540   PetscFunctionReturn(0);
4541 }
4542 
4543 /*@C
4544    MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type
4545 
4546    Not Collective
4547 
4548    Input Parameters:
4549 +  mat - the matrix
4550 .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4551 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4552 
4553    Output Parameter:
4554 .    flg - PETSC_TRUE if the factorization is available
4555 
4556    Notes:
4557       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4558      such as pastix, superlu, mumps etc.
4559 
4560       PETSc must have been ./configure to use the external solver, using the option --download-package
4561 
4562    Level: intermediate
4563 
4564 .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
4565 @*/
4566 PetscErrorCode MatGetFactorAvailable(Mat mat, MatSolverType type,MatFactorType ftype,PetscBool  *flg)
4567 {
4568   PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*);
4569 
4570   PetscFunctionBegin;
4571   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4572   PetscValidType(mat,1);
4573 
4574   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4575   MatCheckPreallocated(mat,1);
4576 
4577   *flg = PETSC_FALSE;
4578   ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);CHKERRQ(ierr);
4579   if (gconv) {
4580     *flg = PETSC_TRUE;
4581   }
4582   PetscFunctionReturn(0);
4583 }
4584 
4585 #include <petscdmtypes.h>
4586 
4587 /*@
4588    MatDuplicate - Duplicates a matrix including the non-zero structure.
4589 
4590    Collective on Mat
4591 
4592    Input Parameters:
4593 +  mat - the matrix
4594 -  op - One of MAT_DO_NOT_COPY_VALUES, MAT_COPY_VALUES, or MAT_SHARE_NONZERO_PATTERN.
4595         See the manual page for MatDuplicateOption for an explanation of these options.
4596 
4597    Output Parameter:
4598 .  M - pointer to place new matrix
4599 
4600    Level: intermediate
4601 
4602    Concepts: matrices^duplicating
4603 
4604    Notes:
4605     You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN.
4606     When original mat is a product of matrix operation, e.g., an output of MatMatMult() or MatCreateSubMatrix(), only the simple matrix data structure of mat is duplicated and the internal data structures created for the reuse of previous matrix operations are not duplicated. User should not use MatDuplicate() to create new matrix M if M is intended to be reused as the product of matrix operation.
4607 
4608 .seealso: MatCopy(), MatConvert(), MatDuplicateOption
4609 @*/
4610 PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4611 {
4612   PetscErrorCode ierr;
4613   Mat            B;
4614   PetscInt       i;
4615   DM             dm;
4616   void           (*viewf)(void);
4617 
4618   PetscFunctionBegin;
4619   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4620   PetscValidType(mat,1);
4621   PetscValidPointer(M,3);
4622   if (op == MAT_COPY_VALUES && !mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MAT_COPY_VALUES not allowed for unassembled matrix");
4623   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4624   MatCheckPreallocated(mat,1);
4625 
4626   *M = 0;
4627   if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type");
4628   ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4629   ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr);
4630   B    = *M;
4631 
4632   ierr = MatGetOperation(mat,MATOP_VIEW,&viewf);CHKERRQ(ierr);
4633   if (viewf) {
4634     ierr = MatSetOperation(B,MATOP_VIEW,viewf);CHKERRQ(ierr);
4635   }
4636 
4637   B->stencil.dim = mat->stencil.dim;
4638   B->stencil.noc = mat->stencil.noc;
4639   for (i=0; i<=mat->stencil.dim; i++) {
4640     B->stencil.dims[i]   = mat->stencil.dims[i];
4641     B->stencil.starts[i] = mat->stencil.starts[i];
4642   }
4643 
4644   B->nooffproczerorows = mat->nooffproczerorows;
4645   B->nooffprocentries  = mat->nooffprocentries;
4646 
4647   ierr = PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);CHKERRQ(ierr);
4648   if (dm) {
4649     ierr = PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr);
4650   }
4651   ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4652   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
4653   PetscFunctionReturn(0);
4654 }
4655 
4656 /*@
4657    MatGetDiagonal - Gets the diagonal of a matrix.
4658 
4659    Logically Collective on Mat and Vec
4660 
4661    Input Parameters:
4662 +  mat - the matrix
4663 -  v - the vector for storing the diagonal
4664 
4665    Output Parameter:
4666 .  v - the diagonal of the matrix
4667 
4668    Level: intermediate
4669 
4670    Note:
4671    Currently only correct in parallel for square matrices.
4672 
4673    Concepts: matrices^accessing diagonals
4674 
4675 .seealso: MatGetRow(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs()
4676 @*/
4677 PetscErrorCode MatGetDiagonal(Mat mat,Vec v)
4678 {
4679   PetscErrorCode ierr;
4680 
4681   PetscFunctionBegin;
4682   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4683   PetscValidType(mat,1);
4684   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4685   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4686   if (!mat->ops->getdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4687   MatCheckPreallocated(mat,1);
4688 
4689   ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr);
4690   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4691   PetscFunctionReturn(0);
4692 }
4693 
4694 /*@C
4695    MatGetRowMin - Gets the minimum value (of the real part) of each
4696         row of the matrix
4697 
4698    Logically Collective on Mat and Vec
4699 
4700    Input Parameters:
4701 .  mat - the matrix
4702 
4703    Output Parameter:
4704 +  v - the vector for storing the maximums
4705 -  idx - the indices of the column found for each row (optional)
4706 
4707    Level: intermediate
4708 
4709    Notes:
4710     The result of this call are the same as if one converted the matrix to dense format
4711       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4712 
4713     This code is only implemented for a couple of matrix formats.
4714 
4715    Concepts: matrices^getting row maximums
4716 
4717 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(),
4718           MatGetRowMax()
4719 @*/
4720 PetscErrorCode MatGetRowMin(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->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4730   MatCheckPreallocated(mat,1);
4731 
4732   ierr = (*mat->ops->getrowmin)(mat,v,idx);CHKERRQ(ierr);
4733   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4734   PetscFunctionReturn(0);
4735 }
4736 
4737 /*@C
4738    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4739         row of the matrix
4740 
4741    Logically Collective on Mat and Vec
4742 
4743    Input Parameters:
4744 .  mat - the matrix
4745 
4746    Output Parameter:
4747 +  v - the vector for storing the minimums
4748 -  idx - the indices of the column found for each row (or NULL if not needed)
4749 
4750    Level: intermediate
4751 
4752    Notes:
4753     if a row is completely empty or has only 0.0 values then the idx[] value for that
4754     row is 0 (the first column).
4755 
4756     This code is only implemented for a couple of matrix formats.
4757 
4758    Concepts: matrices^getting row maximums
4759 
4760 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4761 @*/
4762 PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4763 {
4764   PetscErrorCode ierr;
4765 
4766   PetscFunctionBegin;
4767   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4768   PetscValidType(mat,1);
4769   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4770   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4771   if (!mat->ops->getrowminabs) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4772   MatCheckPreallocated(mat,1);
4773   if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);}
4774 
4775   ierr = (*mat->ops->getrowminabs)(mat,v,idx);CHKERRQ(ierr);
4776   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4777   PetscFunctionReturn(0);
4778 }
4779 
4780 /*@C
4781    MatGetRowMax - Gets the maximum value (of the real part) 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 (optional)
4792 
4793    Level: intermediate
4794 
4795    Notes:
4796     The result of this call are the same as if one converted the matrix to dense format
4797       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
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(), MatGetRowMaxAbs(), MatGetRowMin()
4804 @*/
4805 PetscErrorCode MatGetRowMax(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->getrowmax) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4815   MatCheckPreallocated(mat,1);
4816 
4817   ierr = (*mat->ops->getrowmax)(mat,v,idx);CHKERRQ(ierr);
4818   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4819   PetscFunctionReturn(0);
4820 }
4821 
4822 /*@C
4823    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4824         row of the matrix
4825 
4826    Logically Collective on Mat and Vec
4827 
4828    Input Parameters:
4829 .  mat - the matrix
4830 
4831    Output Parameter:
4832 +  v - the vector for storing the maximums
4833 -  idx - the indices of the column found for each row (or NULL if not needed)
4834 
4835    Level: intermediate
4836 
4837    Notes:
4838     if a row is completely empty or has only 0.0 values then the idx[] value for that
4839     row is 0 (the first column).
4840 
4841     This code is only implemented for a couple of matrix formats.
4842 
4843    Concepts: matrices^getting row maximums
4844 
4845 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
4846 @*/
4847 PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4848 {
4849   PetscErrorCode ierr;
4850 
4851   PetscFunctionBegin;
4852   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4853   PetscValidType(mat,1);
4854   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4855   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4856   if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4857   MatCheckPreallocated(mat,1);
4858   if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);}
4859 
4860   ierr = (*mat->ops->getrowmaxabs)(mat,v,idx);CHKERRQ(ierr);
4861   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4862   PetscFunctionReturn(0);
4863 }
4864 
4865 /*@
4866    MatGetRowSum - Gets the sum of each row of the matrix
4867 
4868    Logically or Neighborhood Collective on Mat and Vec
4869 
4870    Input Parameters:
4871 .  mat - the matrix
4872 
4873    Output Parameter:
4874 .  v - the vector for storing the sum of rows
4875 
4876    Level: intermediate
4877 
4878    Notes:
4879     This code is slow since it is not currently specialized for different formats
4880 
4881    Concepts: matrices^getting row sums
4882 
4883 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
4884 @*/
4885 PetscErrorCode MatGetRowSum(Mat mat, Vec v)
4886 {
4887   Vec            ones;
4888   PetscErrorCode ierr;
4889 
4890   PetscFunctionBegin;
4891   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4892   PetscValidType(mat,1);
4893   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4894   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4895   MatCheckPreallocated(mat,1);
4896   ierr = MatCreateVecs(mat,&ones,NULL);CHKERRQ(ierr);
4897   ierr = VecSet(ones,1.);CHKERRQ(ierr);
4898   ierr = MatMult(mat,ones,v);CHKERRQ(ierr);
4899   ierr = VecDestroy(&ones);CHKERRQ(ierr);
4900   PetscFunctionReturn(0);
4901 }
4902 
4903 /*@
4904    MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
4905 
4906    Collective on Mat
4907 
4908    Input Parameter:
4909 +  mat - the matrix to transpose
4910 -  reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX
4911 
4912    Output Parameters:
4913 .  B - the transpose
4914 
4915    Notes:
4916      If you use MAT_INPLACE_MATRIX then you must pass in &mat for B
4917 
4918      MAT_REUSE_MATRIX causes the B matrix from a previous call to this function with MAT_INITIAL_MATRIX to be used
4919 
4920      Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed.
4921 
4922    Level: intermediate
4923 
4924    Concepts: matrices^transposing
4925 
4926 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4927 @*/
4928 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4929 {
4930   PetscErrorCode ierr;
4931 
4932   PetscFunctionBegin;
4933   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4934   PetscValidType(mat,1);
4935   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4936   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4937   if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4938   if (reuse == MAT_INPLACE_MATRIX && mat != *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires last matrix to match first");
4939   if (reuse == MAT_REUSE_MATRIX && mat == *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Perhaps you mean MAT_INPLACE_MATRIX");
4940   MatCheckPreallocated(mat,1);
4941 
4942   ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4943   ierr = (*mat->ops->transpose)(mat,reuse,B);CHKERRQ(ierr);
4944   ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4945   if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);}
4946   PetscFunctionReturn(0);
4947 }
4948 
4949 /*@
4950    MatIsTranspose - Test whether a matrix is another one's transpose,
4951         or its own, in which case it tests symmetry.
4952 
4953    Collective on Mat
4954 
4955    Input Parameter:
4956 +  A - the matrix to test
4957 -  B - the matrix to test against, this can equal the first parameter
4958 
4959    Output Parameters:
4960 .  flg - the result
4961 
4962    Notes:
4963    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4964    has a running time of the order of the number of nonzeros; the parallel
4965    test involves parallel copies of the block-offdiagonal parts of the matrix.
4966 
4967    Level: intermediate
4968 
4969    Concepts: matrices^transposing, matrix^symmetry
4970 
4971 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4972 @*/
4973 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4974 {
4975   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4976 
4977   PetscFunctionBegin;
4978   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4979   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4980   PetscValidPointer(flg,3);
4981   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);CHKERRQ(ierr);
4982   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);CHKERRQ(ierr);
4983   *flg = PETSC_FALSE;
4984   if (f && g) {
4985     if (f == g) {
4986       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
4987     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4988   } else {
4989     MatType mattype;
4990     if (!f) {
4991       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
4992     } else {
4993       ierr = MatGetType(B,&mattype);CHKERRQ(ierr);
4994     }
4995     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
4996   }
4997   PetscFunctionReturn(0);
4998 }
4999 
5000 /*@
5001    MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate.
5002 
5003    Collective on Mat
5004 
5005    Input Parameter:
5006 +  mat - the matrix to transpose and complex conjugate
5007 -  reuse - MAT_INITIAL_MATRIX to create a new matrix, MAT_INPLACE_MATRIX to reuse the first argument to store the transpose
5008 
5009    Output Parameters:
5010 .  B - the Hermitian
5011 
5012    Level: intermediate
5013 
5014    Concepts: matrices^transposing, complex conjugatex
5015 
5016 .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
5017 @*/
5018 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
5019 {
5020   PetscErrorCode ierr;
5021 
5022   PetscFunctionBegin;
5023   ierr = MatTranspose(mat,reuse,B);CHKERRQ(ierr);
5024 #if defined(PETSC_USE_COMPLEX)
5025   ierr = MatConjugate(*B);CHKERRQ(ierr);
5026 #endif
5027   PetscFunctionReturn(0);
5028 }
5029 
5030 /*@
5031    MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,
5032 
5033    Collective on Mat
5034 
5035    Input Parameter:
5036 +  A - the matrix to test
5037 -  B - the matrix to test against, this can equal the first parameter
5038 
5039    Output Parameters:
5040 .  flg - the result
5041 
5042    Notes:
5043    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
5044    has a running time of the order of the number of nonzeros; the parallel
5045    test involves parallel copies of the block-offdiagonal parts of the matrix.
5046 
5047    Level: intermediate
5048 
5049    Concepts: matrices^transposing, matrix^symmetry
5050 
5051 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
5052 @*/
5053 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
5054 {
5055   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
5056 
5057   PetscFunctionBegin;
5058   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
5059   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
5060   PetscValidPointer(flg,3);
5061   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);CHKERRQ(ierr);
5062   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);CHKERRQ(ierr);
5063   if (f && g) {
5064     if (f==g) {
5065       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
5066     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
5067   }
5068   PetscFunctionReturn(0);
5069 }
5070 
5071 /*@
5072    MatPermute - Creates a new matrix with rows and columns permuted from the
5073    original.
5074 
5075    Collective on Mat
5076 
5077    Input Parameters:
5078 +  mat - the matrix to permute
5079 .  row - row permutation, each processor supplies only the permutation for its rows
5080 -  col - column permutation, each processor supplies only the permutation for its columns
5081 
5082    Output Parameters:
5083 .  B - the permuted matrix
5084 
5085    Level: advanced
5086 
5087    Note:
5088    The index sets map from row/col of permuted matrix to row/col of original matrix.
5089    The index sets should be on the same communicator as Mat and have the same local sizes.
5090 
5091    Concepts: matrices^permuting
5092 
5093 .seealso: MatGetOrdering(), ISAllGather()
5094 
5095 @*/
5096 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
5097 {
5098   PetscErrorCode ierr;
5099 
5100   PetscFunctionBegin;
5101   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5102   PetscValidType(mat,1);
5103   PetscValidHeaderSpecific(row,IS_CLASSID,2);
5104   PetscValidHeaderSpecific(col,IS_CLASSID,3);
5105   PetscValidPointer(B,4);
5106   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5107   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5108   if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
5109   MatCheckPreallocated(mat,1);
5110 
5111   ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr);
5112   ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);
5113   PetscFunctionReturn(0);
5114 }
5115 
5116 /*@
5117    MatEqual - Compares two matrices.
5118 
5119    Collective on Mat
5120 
5121    Input Parameters:
5122 +  A - the first matrix
5123 -  B - the second matrix
5124 
5125    Output Parameter:
5126 .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
5127 
5128    Level: intermediate
5129 
5130    Concepts: matrices^equality between
5131 @*/
5132 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool  *flg)
5133 {
5134   PetscErrorCode ierr;
5135 
5136   PetscFunctionBegin;
5137   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
5138   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
5139   PetscValidType(A,1);
5140   PetscValidType(B,2);
5141   PetscValidIntPointer(flg,3);
5142   PetscCheckSameComm(A,1,B,2);
5143   MatCheckPreallocated(B,2);
5144   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5145   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5146   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);
5147   if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
5148   if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
5149   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);
5150   MatCheckPreallocated(A,1);
5151 
5152   ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr);
5153   PetscFunctionReturn(0);
5154 }
5155 
5156 /*@
5157    MatDiagonalScale - Scales a matrix on the left and right by diagonal
5158    matrices that are stored as vectors.  Either of the two scaling
5159    matrices can be NULL.
5160 
5161    Collective on Mat
5162 
5163    Input Parameters:
5164 +  mat - the matrix to be scaled
5165 .  l - the left scaling vector (or NULL)
5166 -  r - the right scaling vector (or NULL)
5167 
5168    Notes:
5169    MatDiagonalScale() computes A = LAR, where
5170    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
5171    The L scales the rows of the matrix, the R scales the columns of the matrix.
5172 
5173    Level: intermediate
5174 
5175    Concepts: matrices^diagonal scaling
5176    Concepts: diagonal scaling of matrices
5177 
5178 .seealso: MatScale(), MatShift(), MatDiagonalSet()
5179 @*/
5180 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
5181 {
5182   PetscErrorCode ierr;
5183 
5184   PetscFunctionBegin;
5185   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5186   PetscValidType(mat,1);
5187   if (!mat->ops->diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5188   if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);}
5189   if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);}
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   MatCheckPreallocated(mat,1);
5193 
5194   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5195   ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr);
5196   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5197   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5198 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5199   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5200     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5201   }
5202 #endif
5203   PetscFunctionReturn(0);
5204 }
5205 
5206 /*@
5207     MatScale - Scales all elements of a matrix by a given number.
5208 
5209     Logically Collective on Mat
5210 
5211     Input Parameters:
5212 +   mat - the matrix to be scaled
5213 -   a  - the scaling value
5214 
5215     Output Parameter:
5216 .   mat - the scaled matrix
5217 
5218     Level: intermediate
5219 
5220     Concepts: matrices^scaling all entries
5221 
5222 .seealso: MatDiagonalScale()
5223 @*/
5224 PetscErrorCode MatScale(Mat mat,PetscScalar a)
5225 {
5226   PetscErrorCode ierr;
5227 
5228   PetscFunctionBegin;
5229   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5230   PetscValidType(mat,1);
5231   if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5232   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5233   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5234   PetscValidLogicalCollectiveScalar(mat,a,2);
5235   MatCheckPreallocated(mat,1);
5236 
5237   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5238   if (a != (PetscScalar)1.0) {
5239     ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr);
5240     ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5241 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5242     if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5243       mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5244     }
5245 #endif
5246   }
5247   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5248   PetscFunctionReturn(0);
5249 }
5250 
5251 /*@
5252    MatNorm - Calculates various norms of a matrix.
5253 
5254    Collective on Mat
5255 
5256    Input Parameters:
5257 +  mat - the matrix
5258 -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
5259 
5260    Output Parameters:
5261 .  nrm - the resulting norm
5262 
5263    Level: intermediate
5264 
5265    Concepts: matrices^norm
5266    Concepts: norm^of matrix
5267 @*/
5268 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
5269 {
5270   PetscErrorCode ierr;
5271 
5272   PetscFunctionBegin;
5273   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5274   PetscValidType(mat,1);
5275   PetscValidScalarPointer(nrm,3);
5276 
5277   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5278   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5279   if (!mat->ops->norm) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5280   MatCheckPreallocated(mat,1);
5281 
5282   ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr);
5283   PetscFunctionReturn(0);
5284 }
5285 
5286 /*
5287      This variable is used to prevent counting of MatAssemblyBegin() that
5288    are called from within a MatAssemblyEnd().
5289 */
5290 static PetscInt MatAssemblyEnd_InUse = 0;
5291 /*@
5292    MatAssemblyBegin - Begins assembling the matrix.  This routine should
5293    be called after completing all calls to MatSetValues().
5294 
5295    Collective on Mat
5296 
5297    Input Parameters:
5298 +  mat - the matrix
5299 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5300 
5301    Notes:
5302    MatSetValues() generally caches the values.  The matrix is ready to
5303    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5304    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5305    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5306    using the matrix.
5307 
5308    ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the
5309    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
5310    a global collective operation requring all processes that share the matrix.
5311 
5312    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5313    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5314    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5315 
5316    Level: beginner
5317 
5318    Concepts: matrices^assembling
5319 
5320 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
5321 @*/
5322 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
5323 {
5324   PetscErrorCode ierr;
5325 
5326   PetscFunctionBegin;
5327   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5328   PetscValidType(mat,1);
5329   MatCheckPreallocated(mat,1);
5330   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
5331   if (mat->assembled) {
5332     mat->was_assembled = PETSC_TRUE;
5333     mat->assembled     = PETSC_FALSE;
5334   }
5335   if (!MatAssemblyEnd_InUse) {
5336     ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5337     if (mat->ops->assemblybegin) {ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
5338     ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5339   } else if (mat->ops->assemblybegin) {
5340     ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);
5341   }
5342   PetscFunctionReturn(0);
5343 }
5344 
5345 /*@
5346    MatAssembled - Indicates if a matrix has been assembled and is ready for
5347      use; for example, in matrix-vector product.
5348 
5349    Not Collective
5350 
5351    Input Parameter:
5352 .  mat - the matrix
5353 
5354    Output Parameter:
5355 .  assembled - PETSC_TRUE or PETSC_FALSE
5356 
5357    Level: advanced
5358 
5359    Concepts: matrices^assembled?
5360 
5361 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
5362 @*/
5363 PetscErrorCode MatAssembled(Mat mat,PetscBool  *assembled)
5364 {
5365   PetscFunctionBegin;
5366   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5367   PetscValidPointer(assembled,2);
5368   *assembled = mat->assembled;
5369   PetscFunctionReturn(0);
5370 }
5371 
5372 /*@
5373    MatAssemblyEnd - Completes assembling the matrix.  This routine should
5374    be called after MatAssemblyBegin().
5375 
5376    Collective on Mat
5377 
5378    Input Parameters:
5379 +  mat - the matrix
5380 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5381 
5382    Options Database Keys:
5383 +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
5384 .  -mat_view ::ascii_info_detail - Prints more detailed info
5385 .  -mat_view - Prints matrix in ASCII format
5386 .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
5387 .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
5388 .  -display <name> - Sets display name (default is host)
5389 .  -draw_pause <sec> - Sets number of seconds to pause after display
5390 .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab )
5391 .  -viewer_socket_machine <machine> - Machine to use for socket
5392 .  -viewer_socket_port <port> - Port number to use for socket
5393 -  -mat_view binary:filename[:append] - Save matrix to file in binary format
5394 
5395    Notes:
5396    MatSetValues() generally caches the values.  The matrix is ready to
5397    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5398    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5399    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5400    using the matrix.
5401 
5402    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5403    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5404    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5405 
5406    Level: beginner
5407 
5408 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
5409 @*/
5410 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
5411 {
5412   PetscErrorCode  ierr;
5413   static PetscInt inassm = 0;
5414   PetscBool       flg    = PETSC_FALSE;
5415 
5416   PetscFunctionBegin;
5417   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5418   PetscValidType(mat,1);
5419 
5420   inassm++;
5421   MatAssemblyEnd_InUse++;
5422   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
5423     ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5424     if (mat->ops->assemblyend) {
5425       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5426     }
5427     ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5428   } else if (mat->ops->assemblyend) {
5429     ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5430   }
5431 
5432   /* Flush assembly is not a true assembly */
5433   if (type != MAT_FLUSH_ASSEMBLY) {
5434     mat->assembled = PETSC_TRUE; mat->num_ass++;
5435   }
5436   mat->insertmode = NOT_SET_VALUES;
5437   MatAssemblyEnd_InUse--;
5438   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5439   if (!mat->symmetric_eternal) {
5440     mat->symmetric_set              = PETSC_FALSE;
5441     mat->hermitian_set              = PETSC_FALSE;
5442     mat->structurally_symmetric_set = PETSC_FALSE;
5443   }
5444 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5445   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5446     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5447   }
5448 #endif
5449   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
5450     ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5451 
5452     if (mat->checksymmetryonassembly) {
5453       ierr = MatIsSymmetric(mat,mat->checksymmetrytol,&flg);CHKERRQ(ierr);
5454       if (flg) {
5455         ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5456       } else {
5457         ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5458       }
5459     }
5460     if (mat->nullsp && mat->checknullspaceonassembly) {
5461       ierr = MatNullSpaceTest(mat->nullsp,mat,NULL);CHKERRQ(ierr);
5462     }
5463   }
5464   inassm--;
5465   PetscFunctionReturn(0);
5466 }
5467 
5468 /*@
5469    MatSetOption - Sets a parameter option for a matrix. Some options
5470    may be specific to certain storage formats.  Some options
5471    determine how values will be inserted (or added). Sorted,
5472    row-oriented input will generally assemble the fastest. The default
5473    is row-oriented.
5474 
5475    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5476 
5477    Input Parameters:
5478 +  mat - the matrix
5479 .  option - the option, one of those listed below (and possibly others),
5480 -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5481 
5482   Options Describing Matrix Structure:
5483 +    MAT_SPD - symmetric positive definite
5484 .    MAT_SYMMETRIC - symmetric in terms of both structure and value
5485 .    MAT_HERMITIAN - transpose is the complex conjugation
5486 .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5487 -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5488                             you set to be kept with all future use of the matrix
5489                             including after MatAssemblyBegin/End() which could
5490                             potentially change the symmetry structure, i.e. you
5491                             KNOW the matrix will ALWAYS have the property you set.
5492 
5493 
5494    Options For Use with MatSetValues():
5495    Insert a logically dense subblock, which can be
5496 .    MAT_ROW_ORIENTED - row-oriented (default)
5497 
5498    Note these options reflect the data you pass in with MatSetValues(); it has
5499    nothing to do with how the data is stored internally in the matrix
5500    data structure.
5501 
5502    When (re)assembling a matrix, we can restrict the input for
5503    efficiency/debugging purposes.  These options include:
5504 +    MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow)
5505 .    MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
5506 .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
5507 .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
5508 .    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
5509 .    MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
5510         any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
5511         performance for very large process counts.
5512 -    MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset
5513         of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly
5514         functions, instead sending only neighbor messages.
5515 
5516    Notes:
5517    Except for MAT_UNUSED_NONZERO_LOCATION_ERR and  MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg!
5518 
5519    Some options are relevant only for particular matrix types and
5520    are thus ignored by others.  Other options are not supported by
5521    certain matrix types and will generate an error message if set.
5522 
5523    If using a Fortran 77 module to compute a matrix, one may need to
5524    use the column-oriented option (or convert to the row-oriented
5525    format).
5526 
5527    MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
5528    that would generate a new entry in the nonzero structure is instead
5529    ignored.  Thus, if memory has not alredy been allocated for this particular
5530    data, then the insertion is ignored. For dense matrices, in which
5531    the entire array is allocated, no entries are ever ignored.
5532    Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5533 
5534    MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5535    that would generate a new entry in the nonzero structure instead produces
5536    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
5537 
5538    MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5539    that would generate a new entry that has not been preallocated will
5540    instead produce an error. (Currently supported for AIJ and BAIJ formats
5541    only.) This is a useful flag when debugging matrix memory preallocation.
5542    If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5543 
5544    MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for
5545    other processors should be dropped, rather than stashed.
5546    This is useful if you know that the "owning" processor is also
5547    always generating the correct matrix entries, so that PETSc need
5548    not transfer duplicate entries generated on another processor.
5549 
5550    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5551    searches during matrix assembly. When this flag is set, the hash table
5552    is created during the first Matrix Assembly. This hash table is
5553    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5554    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5555    should be used with MAT_USE_HASH_TABLE flag. This option is currently
5556    supported by MATMPIBAIJ format only.
5557 
5558    MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries
5559    are kept in the nonzero structure
5560 
5561    MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
5562    a zero location in the matrix
5563 
5564    MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types
5565 
5566    MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the
5567         zero row routines and thus improves performance for very large process counts.
5568 
5569    MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular
5570         part of the matrix (since they should match the upper triangular part).
5571 
5572    Notes:
5573     Can only be called after MatSetSizes() and MatSetType() have been set.
5574 
5575    Level: intermediate
5576 
5577    Concepts: matrices^setting options
5578 
5579 .seealso:  MatOption, Mat
5580 
5581 @*/
5582 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg)
5583 {
5584   PetscErrorCode ierr;
5585 
5586   PetscFunctionBegin;
5587   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5588   PetscValidType(mat,1);
5589   if (op > 0) {
5590     PetscValidLogicalCollectiveEnum(mat,op,2);
5591     PetscValidLogicalCollectiveBool(mat,flg,3);
5592   }
5593 
5594   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);
5595   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()");
5596 
5597   switch (op) {
5598   case MAT_NO_OFF_PROC_ENTRIES:
5599     mat->nooffprocentries = flg;
5600     PetscFunctionReturn(0);
5601     break;
5602   case MAT_SUBSET_OFF_PROC_ENTRIES:
5603     mat->assembly_subset = flg;
5604     if (!mat->assembly_subset) { /* See the same logic in VecAssembly wrt VEC_SUBSET_OFF_PROC_ENTRIES */
5605       ierr = MatStashScatterDestroy_BTS(&mat->stash);CHKERRQ(ierr);
5606       mat->stash.first_assembly_done = PETSC_FALSE;
5607     }
5608     PetscFunctionReturn(0);
5609   case MAT_NO_OFF_PROC_ZERO_ROWS:
5610     mat->nooffproczerorows = flg;
5611     PetscFunctionReturn(0);
5612     break;
5613   case MAT_SPD:
5614     mat->spd_set = PETSC_TRUE;
5615     mat->spd     = flg;
5616     if (flg) {
5617       mat->symmetric                  = PETSC_TRUE;
5618       mat->structurally_symmetric     = PETSC_TRUE;
5619       mat->symmetric_set              = PETSC_TRUE;
5620       mat->structurally_symmetric_set = PETSC_TRUE;
5621     }
5622     break;
5623   case MAT_SYMMETRIC:
5624     mat->symmetric = flg;
5625     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5626     mat->symmetric_set              = PETSC_TRUE;
5627     mat->structurally_symmetric_set = flg;
5628 #if !defined(PETSC_USE_COMPLEX)
5629     mat->hermitian     = flg;
5630     mat->hermitian_set = PETSC_TRUE;
5631 #endif
5632     break;
5633   case MAT_HERMITIAN:
5634     mat->hermitian = flg;
5635     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5636     mat->hermitian_set              = PETSC_TRUE;
5637     mat->structurally_symmetric_set = flg;
5638 #if !defined(PETSC_USE_COMPLEX)
5639     mat->symmetric     = flg;
5640     mat->symmetric_set = PETSC_TRUE;
5641 #endif
5642     break;
5643   case MAT_STRUCTURALLY_SYMMETRIC:
5644     mat->structurally_symmetric     = flg;
5645     mat->structurally_symmetric_set = PETSC_TRUE;
5646     break;
5647   case MAT_SYMMETRY_ETERNAL:
5648     mat->symmetric_eternal = flg;
5649     break;
5650   case MAT_STRUCTURE_ONLY:
5651     mat->structure_only = flg;
5652     break;
5653   default:
5654     break;
5655   }
5656   if (mat->ops->setoption) {
5657     ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr);
5658   }
5659   PetscFunctionReturn(0);
5660 }
5661 
5662 /*@
5663    MatGetOption - Gets a parameter option that has been set for a matrix.
5664 
5665    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5666 
5667    Input Parameters:
5668 +  mat - the matrix
5669 -  option - the option, this only responds to certain options, check the code for which ones
5670 
5671    Output Parameter:
5672 .  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5673 
5674     Notes:
5675     Can only be called after MatSetSizes() and MatSetType() have been set.
5676 
5677    Level: intermediate
5678 
5679    Concepts: matrices^setting options
5680 
5681 .seealso:  MatOption, MatSetOption()
5682 
5683 @*/
5684 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg)
5685 {
5686   PetscFunctionBegin;
5687   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5688   PetscValidType(mat,1);
5689 
5690   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);
5691   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()");
5692 
5693   switch (op) {
5694   case MAT_NO_OFF_PROC_ENTRIES:
5695     *flg = mat->nooffprocentries;
5696     break;
5697   case MAT_NO_OFF_PROC_ZERO_ROWS:
5698     *flg = mat->nooffproczerorows;
5699     break;
5700   case MAT_SYMMETRIC:
5701     *flg = mat->symmetric;
5702     break;
5703   case MAT_HERMITIAN:
5704     *flg = mat->hermitian;
5705     break;
5706   case MAT_STRUCTURALLY_SYMMETRIC:
5707     *flg = mat->structurally_symmetric;
5708     break;
5709   case MAT_SYMMETRY_ETERNAL:
5710     *flg = mat->symmetric_eternal;
5711     break;
5712   case MAT_SPD:
5713     *flg = mat->spd;
5714     break;
5715   default:
5716     break;
5717   }
5718   PetscFunctionReturn(0);
5719 }
5720 
5721 /*@
5722    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5723    this routine retains the old nonzero structure.
5724 
5725    Logically Collective on Mat
5726 
5727    Input Parameters:
5728 .  mat - the matrix
5729 
5730    Level: intermediate
5731 
5732    Notes:
5733     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.
5734    See the Performance chapter of the users manual for information on preallocating matrices.
5735 
5736    Concepts: matrices^zeroing
5737 
5738 .seealso: MatZeroRows()
5739 @*/
5740 PetscErrorCode MatZeroEntries(Mat mat)
5741 {
5742   PetscErrorCode ierr;
5743 
5744   PetscFunctionBegin;
5745   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5746   PetscValidType(mat,1);
5747   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5748   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");
5749   if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5750   MatCheckPreallocated(mat,1);
5751 
5752   ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5753   ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
5754   ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5755   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5756 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5757   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5758     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5759   }
5760 #endif
5761   PetscFunctionReturn(0);
5762 }
5763 
5764 /*@
5765    MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal)
5766    of a set of rows and columns of a matrix.
5767 
5768    Collective on Mat
5769 
5770    Input Parameters:
5771 +  mat - the matrix
5772 .  numRows - the number of rows to remove
5773 .  rows - the global row indices
5774 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5775 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5776 -  b - optional vector of right hand side, that will be adjusted by provided solution
5777 
5778    Notes:
5779    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5780 
5781    The user can set a value in the diagonal entry (or for the AIJ and
5782    row formats can optionally remove the main diagonal entry from the
5783    nonzero structure as well, by passing 0.0 as the final argument).
5784 
5785    For the parallel case, all processes that share the matrix (i.e.,
5786    those in the communicator used for matrix creation) MUST call this
5787    routine, regardless of whether any rows being zeroed are owned by
5788    them.
5789 
5790    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5791    list only rows local to itself).
5792 
5793    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5794 
5795    Level: intermediate
5796 
5797    Concepts: matrices^zeroing rows
5798 
5799 .seealso: MatZeroRowsIS(), MatZeroRows(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5800           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5801 @*/
5802 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5803 {
5804   PetscErrorCode ierr;
5805 
5806   PetscFunctionBegin;
5807   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5808   PetscValidType(mat,1);
5809   if (numRows) PetscValidIntPointer(rows,3);
5810   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5811   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5812   if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5813   MatCheckPreallocated(mat,1);
5814 
5815   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5816   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5817   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5818 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5819   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5820     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5821   }
5822 #endif
5823   PetscFunctionReturn(0);
5824 }
5825 
5826 /*@
5827    MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
5828    of a set of rows and columns of a matrix.
5829 
5830    Collective on Mat
5831 
5832    Input Parameters:
5833 +  mat - the matrix
5834 .  is - the rows to zero
5835 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5836 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5837 -  b - optional vector of right hand side, that will be adjusted by provided solution
5838 
5839    Notes:
5840    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5841 
5842    The user can set a value in the diagonal entry (or for the AIJ and
5843    row formats can optionally remove the main diagonal entry from the
5844    nonzero structure as well, by passing 0.0 as the final argument).
5845 
5846    For the parallel case, all processes that share the matrix (i.e.,
5847    those in the communicator used for matrix creation) MUST call this
5848    routine, regardless of whether any rows being zeroed are owned by
5849    them.
5850 
5851    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5852    list only rows local to itself).
5853 
5854    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5855 
5856    Level: intermediate
5857 
5858    Concepts: matrices^zeroing rows
5859 
5860 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5861           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRows(), MatZeroRowsColumnsStencil()
5862 @*/
5863 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5864 {
5865   PetscErrorCode ierr;
5866   PetscInt       numRows;
5867   const PetscInt *rows;
5868 
5869   PetscFunctionBegin;
5870   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5871   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5872   PetscValidType(mat,1);
5873   PetscValidType(is,2);
5874   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5875   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5876   ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5877   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5878   PetscFunctionReturn(0);
5879 }
5880 
5881 /*@
5882    MatZeroRows - Zeros all entries (except possibly the main diagonal)
5883    of a set of rows of a matrix.
5884 
5885    Collective on Mat
5886 
5887    Input Parameters:
5888 +  mat - the matrix
5889 .  numRows - the number of rows to remove
5890 .  rows - the global row indices
5891 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5892 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5893 -  b - optional vector of right hand side, that will be adjusted by provided solution
5894 
5895    Notes:
5896    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5897    but does not release memory.  For the dense and block diagonal
5898    formats this does not alter the nonzero structure.
5899 
5900    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5901    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5902    merely zeroed.
5903 
5904    The user can set a value in the diagonal entry (or for the AIJ and
5905    row formats can optionally remove the main diagonal entry from the
5906    nonzero structure as well, by passing 0.0 as the final argument).
5907 
5908    For the parallel case, all processes that share the matrix (i.e.,
5909    those in the communicator used for matrix creation) MUST call this
5910    routine, regardless of whether any rows being zeroed are owned by
5911    them.
5912 
5913    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5914    list only rows local to itself).
5915 
5916    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5917    owns that are to be zeroed. This saves a global synchronization in the implementation.
5918 
5919    Level: intermediate
5920 
5921    Concepts: matrices^zeroing rows
5922 
5923 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5924           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5925 @*/
5926 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5927 {
5928   PetscErrorCode ierr;
5929 
5930   PetscFunctionBegin;
5931   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5932   PetscValidType(mat,1);
5933   if (numRows) PetscValidIntPointer(rows,3);
5934   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5935   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5936   if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5937   MatCheckPreallocated(mat,1);
5938 
5939   ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5940   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5941   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5942 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5943   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5944     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5945   }
5946 #endif
5947   PetscFunctionReturn(0);
5948 }
5949 
5950 /*@
5951    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5952    of a set of rows of a matrix.
5953 
5954    Collective on Mat
5955 
5956    Input Parameters:
5957 +  mat - the matrix
5958 .  is - index set of rows to remove
5959 .  diag - value put in all diagonals of eliminated rows
5960 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5961 -  b - optional vector of right hand side, that will be adjusted by provided solution
5962 
5963    Notes:
5964    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5965    but does not release memory.  For the dense and block diagonal
5966    formats this does not alter the nonzero structure.
5967 
5968    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5969    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5970    merely zeroed.
5971 
5972    The user can set a value in the diagonal entry (or for the AIJ and
5973    row formats can optionally remove the main diagonal entry from the
5974    nonzero structure as well, by passing 0.0 as the final argument).
5975 
5976    For the parallel case, all processes that share the matrix (i.e.,
5977    those in the communicator used for matrix creation) MUST call this
5978    routine, regardless of whether any rows being zeroed are owned by
5979    them.
5980 
5981    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5982    list only rows local to itself).
5983 
5984    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5985    owns that are to be zeroed. This saves a global synchronization in the implementation.
5986 
5987    Level: intermediate
5988 
5989    Concepts: matrices^zeroing rows
5990 
5991 .seealso: MatZeroRows(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5992           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5993 @*/
5994 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5995 {
5996   PetscInt       numRows;
5997   const PetscInt *rows;
5998   PetscErrorCode ierr;
5999 
6000   PetscFunctionBegin;
6001   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6002   PetscValidType(mat,1);
6003   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6004   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6005   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6006   ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6007   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6008   PetscFunctionReturn(0);
6009 }
6010 
6011 /*@
6012    MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
6013    of a set of rows of a matrix. These rows must be local to the process.
6014 
6015    Collective on Mat
6016 
6017    Input Parameters:
6018 +  mat - the matrix
6019 .  numRows - the number of rows to remove
6020 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
6021 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
6022 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6023 -  b - optional vector of right hand side, that will be adjusted by provided solution
6024 
6025    Notes:
6026    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
6027    but does not release memory.  For the dense and block diagonal
6028    formats this does not alter the nonzero structure.
6029 
6030    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6031    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6032    merely zeroed.
6033 
6034    The user can set a value in the diagonal entry (or for the AIJ and
6035    row formats can optionally remove the main diagonal entry from the
6036    nonzero structure as well, by passing 0.0 as the final argument).
6037 
6038    For the parallel case, all processes that share the matrix (i.e.,
6039    those in the communicator used for matrix creation) MUST call this
6040    routine, regardless of whether any rows being zeroed are owned by
6041    them.
6042 
6043    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
6044    list only rows local to itself).
6045 
6046    The grid coordinates are across the entire grid, not just the local portion
6047 
6048    In Fortran idxm and idxn should be declared as
6049 $     MatStencil idxm(4,m)
6050    and the values inserted using
6051 $    idxm(MatStencil_i,1) = i
6052 $    idxm(MatStencil_j,1) = j
6053 $    idxm(MatStencil_k,1) = k
6054 $    idxm(MatStencil_c,1) = c
6055    etc
6056 
6057    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
6058    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
6059    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
6060    DM_BOUNDARY_PERIODIC boundary type.
6061 
6062    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
6063    a single value per point) you can skip filling those indices.
6064 
6065    Level: intermediate
6066 
6067    Concepts: matrices^zeroing rows
6068 
6069 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsl(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6070           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6071 @*/
6072 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
6073 {
6074   PetscInt       dim     = mat->stencil.dim;
6075   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
6076   PetscInt       *dims   = mat->stencil.dims+1;
6077   PetscInt       *starts = mat->stencil.starts;
6078   PetscInt       *dxm    = (PetscInt*) rows;
6079   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
6080   PetscErrorCode ierr;
6081 
6082   PetscFunctionBegin;
6083   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6084   PetscValidType(mat,1);
6085   if (numRows) PetscValidIntPointer(rows,3);
6086 
6087   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
6088   for (i = 0; i < numRows; ++i) {
6089     /* Skip unused dimensions (they are ordered k, j, i, c) */
6090     for (j = 0; j < 3-sdim; ++j) dxm++;
6091     /* Local index in X dir */
6092     tmp = *dxm++ - starts[0];
6093     /* Loop over remaining dimensions */
6094     for (j = 0; j < dim-1; ++j) {
6095       /* If nonlocal, set index to be negative */
6096       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6097       /* Update local index */
6098       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6099     }
6100     /* Skip component slot if necessary */
6101     if (mat->stencil.noc) dxm++;
6102     /* Local row number */
6103     if (tmp >= 0) {
6104       jdxm[numNewRows++] = tmp;
6105     }
6106   }
6107   ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
6108   ierr = PetscFree(jdxm);CHKERRQ(ierr);
6109   PetscFunctionReturn(0);
6110 }
6111 
6112 /*@
6113    MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal)
6114    of a set of rows and columns of a matrix.
6115 
6116    Collective on Mat
6117 
6118    Input Parameters:
6119 +  mat - the matrix
6120 .  numRows - the number of rows/columns to remove
6121 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
6122 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
6123 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6124 -  b - optional vector of right hand side, that will be adjusted by provided solution
6125 
6126    Notes:
6127    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
6128    but does not release memory.  For the dense and block diagonal
6129    formats this does not alter the nonzero structure.
6130 
6131    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6132    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6133    merely zeroed.
6134 
6135    The user can set a value in the diagonal entry (or for the AIJ and
6136    row formats can optionally remove the main diagonal entry from the
6137    nonzero structure as well, by passing 0.0 as the final argument).
6138 
6139    For the parallel case, all processes that share the matrix (i.e.,
6140    those in the communicator used for matrix creation) MUST call this
6141    routine, regardless of whether any rows being zeroed are owned by
6142    them.
6143 
6144    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
6145    list only rows local to itself, but the row/column numbers are given in local numbering).
6146 
6147    The grid coordinates are across the entire grid, not just the local portion
6148 
6149    In Fortran idxm and idxn should be declared as
6150 $     MatStencil idxm(4,m)
6151    and the values inserted using
6152 $    idxm(MatStencil_i,1) = i
6153 $    idxm(MatStencil_j,1) = j
6154 $    idxm(MatStencil_k,1) = k
6155 $    idxm(MatStencil_c,1) = c
6156    etc
6157 
6158    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
6159    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
6160    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
6161    DM_BOUNDARY_PERIODIC boundary type.
6162 
6163    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
6164    a single value per point) you can skip filling those indices.
6165 
6166    Level: intermediate
6167 
6168    Concepts: matrices^zeroing rows
6169 
6170 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6171           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRows()
6172 @*/
6173 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
6174 {
6175   PetscInt       dim     = mat->stencil.dim;
6176   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
6177   PetscInt       *dims   = mat->stencil.dims+1;
6178   PetscInt       *starts = mat->stencil.starts;
6179   PetscInt       *dxm    = (PetscInt*) rows;
6180   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
6181   PetscErrorCode ierr;
6182 
6183   PetscFunctionBegin;
6184   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6185   PetscValidType(mat,1);
6186   if (numRows) PetscValidIntPointer(rows,3);
6187 
6188   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
6189   for (i = 0; i < numRows; ++i) {
6190     /* Skip unused dimensions (they are ordered k, j, i, c) */
6191     for (j = 0; j < 3-sdim; ++j) dxm++;
6192     /* Local index in X dir */
6193     tmp = *dxm++ - starts[0];
6194     /* Loop over remaining dimensions */
6195     for (j = 0; j < dim-1; ++j) {
6196       /* If nonlocal, set index to be negative */
6197       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6198       /* Update local index */
6199       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6200     }
6201     /* Skip component slot if necessary */
6202     if (mat->stencil.noc) dxm++;
6203     /* Local row number */
6204     if (tmp >= 0) {
6205       jdxm[numNewRows++] = tmp;
6206     }
6207   }
6208   ierr = MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
6209   ierr = PetscFree(jdxm);CHKERRQ(ierr);
6210   PetscFunctionReturn(0);
6211 }
6212 
6213 /*@C
6214    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
6215    of a set of rows of a matrix; using local numbering of rows.
6216 
6217    Collective on Mat
6218 
6219    Input Parameters:
6220 +  mat - the matrix
6221 .  numRows - the number of rows to remove
6222 .  rows - the global row indices
6223 .  diag - value put in all diagonals of eliminated rows
6224 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6225 -  b - optional vector of right hand side, that will be adjusted by provided solution
6226 
6227    Notes:
6228    Before calling MatZeroRowsLocal(), the user must first set the
6229    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6230 
6231    For the AIJ matrix formats this removes the old nonzero structure,
6232    but does not release memory.  For the dense and block diagonal
6233    formats this does not alter the nonzero structure.
6234 
6235    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6236    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6237    merely zeroed.
6238 
6239    The user can set a value in the diagonal entry (or for the AIJ and
6240    row formats can optionally remove the main diagonal entry from the
6241    nonzero structure as well, by passing 0.0 as the final argument).
6242 
6243    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6244    owns that are to be zeroed. This saves a global synchronization in the implementation.
6245 
6246    Level: intermediate
6247 
6248    Concepts: matrices^zeroing
6249 
6250 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRows(), MatSetOption(),
6251           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6252 @*/
6253 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6254 {
6255   PetscErrorCode ierr;
6256 
6257   PetscFunctionBegin;
6258   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6259   PetscValidType(mat,1);
6260   if (numRows) PetscValidIntPointer(rows,3);
6261   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6262   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6263   MatCheckPreallocated(mat,1);
6264 
6265   if (mat->ops->zerorowslocal) {
6266     ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6267   } else {
6268     IS             is, newis;
6269     const PetscInt *newRows;
6270 
6271     if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6272     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6273     ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr);
6274     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6275     ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6276     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6277     ierr = ISDestroy(&newis);CHKERRQ(ierr);
6278     ierr = ISDestroy(&is);CHKERRQ(ierr);
6279   }
6280   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6281 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
6282   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
6283     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
6284   }
6285 #endif
6286   PetscFunctionReturn(0);
6287 }
6288 
6289 /*@
6290    MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
6291    of a set of rows of a matrix; using local numbering of rows.
6292 
6293    Collective on Mat
6294 
6295    Input Parameters:
6296 +  mat - the matrix
6297 .  is - index set of rows to remove
6298 .  diag - value put in all diagonals of eliminated rows
6299 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6300 -  b - optional vector of right hand side, that will be adjusted by provided solution
6301 
6302    Notes:
6303    Before calling MatZeroRowsLocalIS(), the user must first set the
6304    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6305 
6306    For the AIJ matrix formats this removes the old nonzero structure,
6307    but does not release memory.  For the dense and block diagonal
6308    formats this does not alter the nonzero structure.
6309 
6310    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6311    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6312    merely zeroed.
6313 
6314    The user can set a value in the diagonal entry (or for the AIJ and
6315    row formats can optionally remove the main diagonal entry from the
6316    nonzero structure as well, by passing 0.0 as the final argument).
6317 
6318    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6319    owns that are to be zeroed. This saves a global synchronization in the implementation.
6320 
6321    Level: intermediate
6322 
6323    Concepts: matrices^zeroing
6324 
6325 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6326           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6327 @*/
6328 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6329 {
6330   PetscErrorCode ierr;
6331   PetscInt       numRows;
6332   const PetscInt *rows;
6333 
6334   PetscFunctionBegin;
6335   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6336   PetscValidType(mat,1);
6337   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6338   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6339   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6340   MatCheckPreallocated(mat,1);
6341 
6342   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6343   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6344   ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6345   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6346   PetscFunctionReturn(0);
6347 }
6348 
6349 /*@
6350    MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
6351    of a set of rows and columns of a matrix; using local numbering of rows.
6352 
6353    Collective on Mat
6354 
6355    Input Parameters:
6356 +  mat - the matrix
6357 .  numRows - the number of rows to remove
6358 .  rows - the global row indices
6359 .  diag - value put in all diagonals of eliminated rows
6360 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6361 -  b - optional vector of right hand side, that will be adjusted by provided solution
6362 
6363    Notes:
6364    Before calling MatZeroRowsColumnsLocal(), the user must first set the
6365    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6366 
6367    The user can set a value in the diagonal entry (or for the AIJ and
6368    row formats can optionally remove the main diagonal entry from the
6369    nonzero structure as well, by passing 0.0 as the final argument).
6370 
6371    Level: intermediate
6372 
6373    Concepts: matrices^zeroing
6374 
6375 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6376           MatZeroRows(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6377 @*/
6378 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6379 {
6380   PetscErrorCode ierr;
6381   IS             is, newis;
6382   const PetscInt *newRows;
6383 
6384   PetscFunctionBegin;
6385   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6386   PetscValidType(mat,1);
6387   if (numRows) PetscValidIntPointer(rows,3);
6388   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6389   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6390   MatCheckPreallocated(mat,1);
6391 
6392   if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6393   ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6394   ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr);
6395   ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6396   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6397   ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6398   ierr = ISDestroy(&newis);CHKERRQ(ierr);
6399   ierr = ISDestroy(&is);CHKERRQ(ierr);
6400   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6401 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
6402   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
6403     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
6404   }
6405 #endif
6406   PetscFunctionReturn(0);
6407 }
6408 
6409 /*@
6410    MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
6411    of a set of rows and columns of a matrix; using local numbering of rows.
6412 
6413    Collective on Mat
6414 
6415    Input Parameters:
6416 +  mat - the matrix
6417 .  is - index set of rows to remove
6418 .  diag - value put in all diagonals of eliminated rows
6419 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6420 -  b - optional vector of right hand side, that will be adjusted by provided solution
6421 
6422    Notes:
6423    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
6424    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6425 
6426    The user can set a value in the diagonal entry (or for the AIJ and
6427    row formats can optionally remove the main diagonal entry from the
6428    nonzero structure as well, by passing 0.0 as the final argument).
6429 
6430    Level: intermediate
6431 
6432    Concepts: matrices^zeroing
6433 
6434 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6435           MatZeroRowsColumnsLocal(), MatZeroRows(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6436 @*/
6437 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6438 {
6439   PetscErrorCode ierr;
6440   PetscInt       numRows;
6441   const PetscInt *rows;
6442 
6443   PetscFunctionBegin;
6444   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6445   PetscValidType(mat,1);
6446   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6447   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6448   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6449   MatCheckPreallocated(mat,1);
6450 
6451   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6452   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6453   ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6454   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6455   PetscFunctionReturn(0);
6456 }
6457 
6458 /*@C
6459    MatGetSize - Returns the numbers of rows and columns in a matrix.
6460 
6461    Not Collective
6462 
6463    Input Parameter:
6464 .  mat - the matrix
6465 
6466    Output Parameters:
6467 +  m - the number of global rows
6468 -  n - the number of global columns
6469 
6470    Note: both output parameters can be NULL on input.
6471 
6472    Level: beginner
6473 
6474    Concepts: matrices^size
6475 
6476 .seealso: MatGetLocalSize()
6477 @*/
6478 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
6479 {
6480   PetscFunctionBegin;
6481   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6482   if (m) *m = mat->rmap->N;
6483   if (n) *n = mat->cmap->N;
6484   PetscFunctionReturn(0);
6485 }
6486 
6487 /*@C
6488    MatGetLocalSize - Returns the number of rows and columns in a matrix
6489    stored locally.  This information may be implementation dependent, so
6490    use with care.
6491 
6492    Not Collective
6493 
6494    Input Parameters:
6495 .  mat - the matrix
6496 
6497    Output Parameters:
6498 +  m - the number of local rows
6499 -  n - the number of local columns
6500 
6501    Note: both output parameters can be NULL on input.
6502 
6503    Level: beginner
6504 
6505    Concepts: matrices^local size
6506 
6507 .seealso: MatGetSize()
6508 @*/
6509 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
6510 {
6511   PetscFunctionBegin;
6512   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6513   if (m) PetscValidIntPointer(m,2);
6514   if (n) PetscValidIntPointer(n,3);
6515   if (m) *m = mat->rmap->n;
6516   if (n) *n = mat->cmap->n;
6517   PetscFunctionReturn(0);
6518 }
6519 
6520 /*@C
6521    MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6522    this processor. (The columns of the "diagonal block")
6523 
6524    Not Collective, unless matrix has not been allocated, then collective on Mat
6525 
6526    Input Parameters:
6527 .  mat - the matrix
6528 
6529    Output Parameters:
6530 +  m - the global index of the first local column
6531 -  n - one more than the global index of the last local column
6532 
6533    Notes:
6534     both output parameters can be NULL on input.
6535 
6536    Level: developer
6537 
6538    Concepts: matrices^column ownership
6539 
6540 .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
6541 
6542 @*/
6543 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
6544 {
6545   PetscFunctionBegin;
6546   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6547   PetscValidType(mat,1);
6548   if (m) PetscValidIntPointer(m,2);
6549   if (n) PetscValidIntPointer(n,3);
6550   MatCheckPreallocated(mat,1);
6551   if (m) *m = mat->cmap->rstart;
6552   if (n) *n = mat->cmap->rend;
6553   PetscFunctionReturn(0);
6554 }
6555 
6556 /*@C
6557    MatGetOwnershipRange - Returns the range of matrix rows owned by
6558    this processor, assuming that the matrix is laid out with the first
6559    n1 rows on the first processor, the next n2 rows on the second, etc.
6560    For certain parallel layouts this range may not be well defined.
6561 
6562    Not Collective
6563 
6564    Input Parameters:
6565 .  mat - the matrix
6566 
6567    Output Parameters:
6568 +  m - the global index of the first local row
6569 -  n - one more than the global index of the last local row
6570 
6571    Note: Both output parameters can be NULL on input.
6572 $  This function requires that the matrix be preallocated. If you have not preallocated, consider using
6573 $    PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
6574 $  and then MPI_Scan() to calculate prefix sums of the local sizes.
6575 
6576    Level: beginner
6577 
6578    Concepts: matrices^row ownership
6579 
6580 .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()
6581 
6582 @*/
6583 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6584 {
6585   PetscFunctionBegin;
6586   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6587   PetscValidType(mat,1);
6588   if (m) PetscValidIntPointer(m,2);
6589   if (n) PetscValidIntPointer(n,3);
6590   MatCheckPreallocated(mat,1);
6591   if (m) *m = mat->rmap->rstart;
6592   if (n) *n = mat->rmap->rend;
6593   PetscFunctionReturn(0);
6594 }
6595 
6596 /*@C
6597    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6598    each process
6599 
6600    Not Collective, unless matrix has not been allocated, then collective on Mat
6601 
6602    Input Parameters:
6603 .  mat - the matrix
6604 
6605    Output Parameters:
6606 .  ranges - start of each processors portion plus one more than the total length at the end
6607 
6608    Level: beginner
6609 
6610    Concepts: matrices^row ownership
6611 
6612 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
6613 
6614 @*/
6615 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6616 {
6617   PetscErrorCode ierr;
6618 
6619   PetscFunctionBegin;
6620   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6621   PetscValidType(mat,1);
6622   MatCheckPreallocated(mat,1);
6623   ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr);
6624   PetscFunctionReturn(0);
6625 }
6626 
6627 /*@C
6628    MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6629    this processor. (The columns of the "diagonal blocks" for each process)
6630 
6631    Not Collective, unless matrix has not been allocated, then collective on Mat
6632 
6633    Input Parameters:
6634 .  mat - the matrix
6635 
6636    Output Parameters:
6637 .  ranges - start of each processors portion plus one more then the total length at the end
6638 
6639    Level: beginner
6640 
6641    Concepts: matrices^column ownership
6642 
6643 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
6644 
6645 @*/
6646 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6647 {
6648   PetscErrorCode ierr;
6649 
6650   PetscFunctionBegin;
6651   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6652   PetscValidType(mat,1);
6653   MatCheckPreallocated(mat,1);
6654   ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr);
6655   PetscFunctionReturn(0);
6656 }
6657 
6658 /*@C
6659    MatGetOwnershipIS - Get row and column ownership as index sets
6660 
6661    Not Collective
6662 
6663    Input Arguments:
6664 .  A - matrix of type Elemental
6665 
6666    Output Arguments:
6667 +  rows - rows in which this process owns elements
6668 .  cols - columns in which this process owns elements
6669 
6670    Level: intermediate
6671 
6672 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL
6673 @*/
6674 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6675 {
6676   PetscErrorCode ierr,(*f)(Mat,IS*,IS*);
6677 
6678   PetscFunctionBegin;
6679   MatCheckPreallocated(A,1);
6680   ierr = PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);CHKERRQ(ierr);
6681   if (f) {
6682     ierr = (*f)(A,rows,cols);CHKERRQ(ierr);
6683   } else {   /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6684     if (rows) {ierr = ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);CHKERRQ(ierr);}
6685     if (cols) {ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);CHKERRQ(ierr);}
6686   }
6687   PetscFunctionReturn(0);
6688 }
6689 
6690 /*@C
6691    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6692    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6693    to complete the factorization.
6694 
6695    Collective on Mat
6696 
6697    Input Parameters:
6698 +  mat - the matrix
6699 .  row - row permutation
6700 .  column - column permutation
6701 -  info - structure containing
6702 $      levels - number of levels of fill.
6703 $      expected fill - as ratio of original fill.
6704 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6705                 missing diagonal entries)
6706 
6707    Output Parameters:
6708 .  fact - new matrix that has been symbolically factored
6709 
6710    Notes:
6711     See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
6712 
6713    Most users should employ the simplified KSP interface for linear solvers
6714    instead of working directly with matrix algebra routines such as this.
6715    See, e.g., KSPCreate().
6716 
6717    Level: developer
6718 
6719   Concepts: matrices^symbolic LU factorization
6720   Concepts: matrices^factorization
6721   Concepts: LU^symbolic factorization
6722 
6723 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6724           MatGetOrdering(), MatFactorInfo
6725 
6726     Note: this uses the definition of level of fill as in Y. Saad, 2003
6727 
6728     Developer Note: fortran interface is not autogenerated as the f90
6729     interface defintion cannot be generated correctly [due to MatFactorInfo]
6730 
6731    References:
6732      Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003
6733 @*/
6734 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6735 {
6736   PetscErrorCode ierr;
6737 
6738   PetscFunctionBegin;
6739   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6740   PetscValidType(mat,1);
6741   PetscValidHeaderSpecific(row,IS_CLASSID,2);
6742   PetscValidHeaderSpecific(col,IS_CLASSID,3);
6743   PetscValidPointer(info,4);
6744   PetscValidPointer(fact,5);
6745   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6746   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6747   if (!(fact)->ops->ilufactorsymbolic) {
6748     MatSolverType spackage;
6749     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
6750     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6751   }
6752   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6753   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6754   MatCheckPreallocated(mat,2);
6755 
6756   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6757   ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
6758   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6759   PetscFunctionReturn(0);
6760 }
6761 
6762 /*@C
6763    MatICCFactorSymbolic - Performs symbolic incomplete
6764    Cholesky factorization for a symmetric matrix.  Use
6765    MatCholeskyFactorNumeric() to complete the factorization.
6766 
6767    Collective on Mat
6768 
6769    Input Parameters:
6770 +  mat - the matrix
6771 .  perm - row and column permutation
6772 -  info - structure containing
6773 $      levels - number of levels of fill.
6774 $      expected fill - as ratio of original fill.
6775 
6776    Output Parameter:
6777 .  fact - the factored matrix
6778 
6779    Notes:
6780    Most users should employ the KSP interface for linear solvers
6781    instead of working directly with matrix algebra routines such as this.
6782    See, e.g., KSPCreate().
6783 
6784    Level: developer
6785 
6786   Concepts: matrices^symbolic incomplete Cholesky factorization
6787   Concepts: matrices^factorization
6788   Concepts: Cholsky^symbolic factorization
6789 
6790 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
6791 
6792     Note: this uses the definition of level of fill as in Y. Saad, 2003
6793 
6794     Developer Note: fortran interface is not autogenerated as the f90
6795     interface defintion cannot be generated correctly [due to MatFactorInfo]
6796 
6797    References:
6798      Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003
6799 @*/
6800 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6801 {
6802   PetscErrorCode ierr;
6803 
6804   PetscFunctionBegin;
6805   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6806   PetscValidType(mat,1);
6807   PetscValidHeaderSpecific(perm,IS_CLASSID,2);
6808   PetscValidPointer(info,3);
6809   PetscValidPointer(fact,4);
6810   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6811   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6812   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6813   if (!(fact)->ops->iccfactorsymbolic) {
6814     MatSolverType spackage;
6815     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
6816     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6817   }
6818   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6819   MatCheckPreallocated(mat,2);
6820 
6821   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6822   ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
6823   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6824   PetscFunctionReturn(0);
6825 }
6826 
6827 /*@C
6828    MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat
6829    points to an array of valid matrices, they may be reused to store the new
6830    submatrices.
6831 
6832    Collective on Mat
6833 
6834    Input Parameters:
6835 +  mat - the matrix
6836 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6837 .  irow, icol - index sets of rows and columns to extract
6838 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6839 
6840    Output Parameter:
6841 .  submat - the array of submatrices
6842 
6843    Notes:
6844    MatCreateSubMatrices() can extract ONLY sequential submatrices
6845    (from both sequential and parallel matrices). Use MatCreateSubMatrix()
6846    to extract a parallel submatrix.
6847 
6848    Some matrix types place restrictions on the row and column
6849    indices, such as that they be sorted or that they be equal to each other.
6850 
6851    The index sets may not have duplicate entries.
6852 
6853    When extracting submatrices from a parallel matrix, each processor can
6854    form a different submatrix by setting the rows and columns of its
6855    individual index sets according to the local submatrix desired.
6856 
6857    When finished using the submatrices, the user should destroy
6858    them with MatDestroySubMatrices().
6859 
6860    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6861    original matrix has not changed from that last call to MatCreateSubMatrices().
6862 
6863    This routine creates the matrices in submat; you should NOT create them before
6864    calling it. It also allocates the array of matrix pointers submat.
6865 
6866    For BAIJ matrices the index sets must respect the block structure, that is if they
6867    request one row/column in a block, they must request all rows/columns that are in
6868    that block. For example, if the block size is 2 you cannot request just row 0 and
6869    column 0.
6870 
6871    Fortran Note:
6872    The Fortran interface is slightly different from that given below; it
6873    requires one to pass in  as submat a Mat (integer) array of size at least n+1.
6874 
6875    Level: advanced
6876 
6877    Concepts: matrices^accessing submatrices
6878    Concepts: submatrices
6879 
6880 .seealso: MatDestroySubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6881 @*/
6882 PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6883 {
6884   PetscErrorCode ierr;
6885   PetscInt       i;
6886   PetscBool      eq;
6887 
6888   PetscFunctionBegin;
6889   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6890   PetscValidType(mat,1);
6891   if (n) {
6892     PetscValidPointer(irow,3);
6893     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6894     PetscValidPointer(icol,4);
6895     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6896   }
6897   PetscValidPointer(submat,6);
6898   if (n && scall == MAT_REUSE_MATRIX) {
6899     PetscValidPointer(*submat,6);
6900     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6901   }
6902   if (!mat->ops->createsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6903   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6904   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6905   MatCheckPreallocated(mat,1);
6906 
6907   ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6908   ierr = (*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6909   ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6910   for (i=0; i<n; i++) {
6911     (*submat)[i]->factortype = MAT_FACTOR_NONE;  /* in case in place factorization was previously done on submatrix */
6912     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6913       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6914       if (eq) {
6915         if (mat->symmetric) {
6916           ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6917         } else if (mat->hermitian) {
6918           ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6919         } else if (mat->structurally_symmetric) {
6920           ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6921         }
6922       }
6923     }
6924   }
6925   PetscFunctionReturn(0);
6926 }
6927 
6928 /*@C
6929    MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms).
6930 
6931    Collective on Mat
6932 
6933    Input Parameters:
6934 +  mat - the matrix
6935 .  n   - the number of submatrixes to be extracted
6936 .  irow, icol - index sets of rows and columns to extract
6937 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6938 
6939    Output Parameter:
6940 .  submat - the array of submatrices
6941 
6942    Level: advanced
6943 
6944    Concepts: matrices^accessing submatrices
6945    Concepts: submatrices
6946 
6947 .seealso: MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6948 @*/
6949 PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6950 {
6951   PetscErrorCode ierr;
6952   PetscInt       i;
6953   PetscBool      eq;
6954 
6955   PetscFunctionBegin;
6956   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6957   PetscValidType(mat,1);
6958   if (n) {
6959     PetscValidPointer(irow,3);
6960     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6961     PetscValidPointer(icol,4);
6962     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6963   }
6964   PetscValidPointer(submat,6);
6965   if (n && scall == MAT_REUSE_MATRIX) {
6966     PetscValidPointer(*submat,6);
6967     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6968   }
6969   if (!mat->ops->createsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6970   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6971   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6972   MatCheckPreallocated(mat,1);
6973 
6974   ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6975   ierr = (*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6976   ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6977   for (i=0; i<n; i++) {
6978     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6979       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6980       if (eq) {
6981         if (mat->symmetric) {
6982           ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6983         } else if (mat->hermitian) {
6984           ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6985         } else if (mat->structurally_symmetric) {
6986           ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6987         }
6988       }
6989     }
6990   }
6991   PetscFunctionReturn(0);
6992 }
6993 
6994 /*@C
6995    MatDestroyMatrices - Destroys an array of matrices.
6996 
6997    Collective on Mat
6998 
6999    Input Parameters:
7000 +  n - the number of local matrices
7001 -  mat - the matrices (note that this is a pointer to the array of matrices)
7002 
7003    Level: advanced
7004 
7005     Notes:
7006     Frees not only the matrices, but also the array that contains the matrices
7007            In Fortran will not free the array.
7008 
7009 .seealso: MatCreateSubMatrices() MatDestroySubMatrices()
7010 @*/
7011 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
7012 {
7013   PetscErrorCode ierr;
7014   PetscInt       i;
7015 
7016   PetscFunctionBegin;
7017   if (!*mat) PetscFunctionReturn(0);
7018   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
7019   PetscValidPointer(mat,2);
7020 
7021   for (i=0; i<n; i++) {
7022     ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr);
7023   }
7024 
7025   /* memory is allocated even if n = 0 */
7026   ierr = PetscFree(*mat);CHKERRQ(ierr);
7027   PetscFunctionReturn(0);
7028 }
7029 
7030 /*@C
7031    MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices().
7032 
7033    Collective on Mat
7034 
7035    Input Parameters:
7036 +  n - the number of local matrices
7037 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
7038                        sequence of MatCreateSubMatrices())
7039 
7040    Level: advanced
7041 
7042     Notes:
7043     Frees not only the matrices, but also the array that contains the matrices
7044            In Fortran will not free the array.
7045 
7046 .seealso: MatCreateSubMatrices()
7047 @*/
7048 PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[])
7049 {
7050   PetscErrorCode ierr;
7051   Mat            mat0;
7052 
7053   PetscFunctionBegin;
7054   if (!*mat) PetscFunctionReturn(0);
7055   /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */
7056   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
7057   PetscValidPointer(mat,2);
7058 
7059   mat0 = (*mat)[0];
7060   if (mat0 && mat0->ops->destroysubmatrices) {
7061     ierr = (mat0->ops->destroysubmatrices)(n,mat);CHKERRQ(ierr);
7062   } else {
7063     ierr = MatDestroyMatrices(n,mat);CHKERRQ(ierr);
7064   }
7065   PetscFunctionReturn(0);
7066 }
7067 
7068 /*@C
7069    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
7070 
7071    Collective on Mat
7072 
7073    Input Parameters:
7074 .  mat - the matrix
7075 
7076    Output Parameter:
7077 .  matstruct - the sequential matrix with the nonzero structure of mat
7078 
7079   Level: intermediate
7080 
7081 .seealso: MatDestroySeqNonzeroStructure(), MatCreateSubMatrices(), MatDestroyMatrices()
7082 @*/
7083 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
7084 {
7085   PetscErrorCode ierr;
7086 
7087   PetscFunctionBegin;
7088   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7089   PetscValidPointer(matstruct,2);
7090 
7091   PetscValidType(mat,1);
7092   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7093   MatCheckPreallocated(mat,1);
7094 
7095   if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
7096   ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
7097   ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr);
7098   ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
7099   PetscFunctionReturn(0);
7100 }
7101 
7102 /*@C
7103    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
7104 
7105    Collective on Mat
7106 
7107    Input Parameters:
7108 .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
7109                        sequence of MatGetSequentialNonzeroStructure())
7110 
7111    Level: advanced
7112 
7113     Notes:
7114     Frees not only the matrices, but also the array that contains the matrices
7115 
7116 .seealso: MatGetSeqNonzeroStructure()
7117 @*/
7118 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
7119 {
7120   PetscErrorCode ierr;
7121 
7122   PetscFunctionBegin;
7123   PetscValidPointer(mat,1);
7124   ierr = MatDestroy(mat);CHKERRQ(ierr);
7125   PetscFunctionReturn(0);
7126 }
7127 
7128 /*@
7129    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
7130    replaces the index sets by larger ones that represent submatrices with
7131    additional overlap.
7132 
7133    Collective on Mat
7134 
7135    Input Parameters:
7136 +  mat - the matrix
7137 .  n   - the number of index sets
7138 .  is  - the array of index sets (these index sets will changed during the call)
7139 -  ov  - the additional overlap requested
7140 
7141    Options Database:
7142 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
7143 
7144    Level: developer
7145 
7146    Concepts: overlap
7147    Concepts: ASM^computing overlap
7148 
7149 .seealso: MatCreateSubMatrices()
7150 @*/
7151 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
7152 {
7153   PetscErrorCode ierr;
7154 
7155   PetscFunctionBegin;
7156   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7157   PetscValidType(mat,1);
7158   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
7159   if (n) {
7160     PetscValidPointer(is,3);
7161     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
7162   }
7163   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7164   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7165   MatCheckPreallocated(mat,1);
7166 
7167   if (!ov) PetscFunctionReturn(0);
7168   if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7169   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7170   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
7171   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7172   PetscFunctionReturn(0);
7173 }
7174 
7175 
7176 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt);
7177 
7178 /*@
7179    MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across
7180    a sub communicator, replaces the index sets by larger ones that represent submatrices with
7181    additional overlap.
7182 
7183    Collective on Mat
7184 
7185    Input Parameters:
7186 +  mat - the matrix
7187 .  n   - the number of index sets
7188 .  is  - the array of index sets (these index sets will changed during the call)
7189 -  ov  - the additional overlap requested
7190 
7191    Options Database:
7192 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
7193 
7194    Level: developer
7195 
7196    Concepts: overlap
7197    Concepts: ASM^computing overlap
7198 
7199 .seealso: MatCreateSubMatrices()
7200 @*/
7201 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov)
7202 {
7203   PetscInt       i;
7204   PetscErrorCode ierr;
7205 
7206   PetscFunctionBegin;
7207   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7208   PetscValidType(mat,1);
7209   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
7210   if (n) {
7211     PetscValidPointer(is,3);
7212     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
7213   }
7214   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7215   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7216   MatCheckPreallocated(mat,1);
7217   if (!ov) PetscFunctionReturn(0);
7218   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7219   for(i=0; i<n; i++){
7220 	ierr =  MatIncreaseOverlapSplit_Single(mat,&is[i],ov);CHKERRQ(ierr);
7221   }
7222   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7223   PetscFunctionReturn(0);
7224 }
7225 
7226 
7227 
7228 
7229 /*@
7230    MatGetBlockSize - Returns the matrix block size.
7231 
7232    Not Collective
7233 
7234    Input Parameter:
7235 .  mat - the matrix
7236 
7237    Output Parameter:
7238 .  bs - block size
7239 
7240    Notes:
7241     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7242 
7243    If the block size has not been set yet this routine returns 1.
7244 
7245    Level: intermediate
7246 
7247    Concepts: matrices^block size
7248 
7249 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
7250 @*/
7251 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
7252 {
7253   PetscFunctionBegin;
7254   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7255   PetscValidIntPointer(bs,2);
7256   *bs = PetscAbs(mat->rmap->bs);
7257   PetscFunctionReturn(0);
7258 }
7259 
7260 /*@
7261    MatGetBlockSizes - Returns the matrix block row and column sizes.
7262 
7263    Not Collective
7264 
7265    Input Parameter:
7266 .  mat - the matrix
7267 
7268    Output Parameter:
7269 .  rbs - row block size
7270 .  cbs - column block size
7271 
7272    Notes:
7273     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7274     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7275 
7276    If a block size has not been set yet this routine returns 1.
7277 
7278    Level: intermediate
7279 
7280    Concepts: matrices^block size
7281 
7282 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes()
7283 @*/
7284 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
7285 {
7286   PetscFunctionBegin;
7287   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7288   if (rbs) PetscValidIntPointer(rbs,2);
7289   if (cbs) PetscValidIntPointer(cbs,3);
7290   if (rbs) *rbs = PetscAbs(mat->rmap->bs);
7291   if (cbs) *cbs = PetscAbs(mat->cmap->bs);
7292   PetscFunctionReturn(0);
7293 }
7294 
7295 /*@
7296    MatSetBlockSize - Sets the matrix block size.
7297 
7298    Logically Collective on Mat
7299 
7300    Input Parameters:
7301 +  mat - the matrix
7302 -  bs - block size
7303 
7304    Notes:
7305     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7306     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later.
7307 
7308     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size
7309     is compatible with the matrix local sizes.
7310 
7311    Level: intermediate
7312 
7313    Concepts: matrices^block size
7314 
7315 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes()
7316 @*/
7317 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
7318 {
7319   PetscErrorCode ierr;
7320 
7321   PetscFunctionBegin;
7322   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7323   PetscValidLogicalCollectiveInt(mat,bs,2);
7324   ierr = MatSetBlockSizes(mat,bs,bs);CHKERRQ(ierr);
7325   PetscFunctionReturn(0);
7326 }
7327 
7328 /*@
7329    MatSetVariableBlockSizes - Sets a diagonal blocks of the matrix that need not be of the same size
7330 
7331    Logically Collective on Mat
7332 
7333    Input Parameters:
7334 +  mat - the matrix
7335 .  nblocks - the number of blocks on this process
7336 -  bsizes - the block sizes
7337 
7338    Notes:
7339     Currently used by PCVPBJACOBI for SeqAIJ matrices
7340 
7341    Level: intermediate
7342 
7343    Concepts: matrices^block size
7344 
7345 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatGetVariableBlockSizes()
7346 @*/
7347 PetscErrorCode MatSetVariableBlockSizes(Mat mat,PetscInt nblocks,PetscInt *bsizes)
7348 {
7349   PetscErrorCode ierr;
7350   PetscInt       i,ncnt = 0, nlocal;
7351 
7352   PetscFunctionBegin;
7353   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7354   if (nblocks < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number of local blocks must be great than or equal to zero");
7355   ierr = MatGetLocalSize(mat,&nlocal,NULL);CHKERRQ(ierr);
7356   for (i=0; i<nblocks; i++) ncnt += bsizes[i];
7357   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);
7358   ierr = PetscFree(mat->bsizes);CHKERRQ(ierr);
7359   mat->nblocks = nblocks;
7360   ierr = PetscMalloc1(nblocks,&mat->bsizes);CHKERRQ(ierr);
7361   ierr = PetscMemcpy(mat->bsizes,bsizes,nblocks*sizeof(PetscInt));CHKERRQ(ierr);
7362   PetscFunctionReturn(0);
7363 }
7364 
7365 /*@C
7366    MatGetVariableBlockSizes - Gets a diagonal blocks of the matrix that need not be of the same size
7367 
7368    Logically Collective on Mat
7369 
7370    Input Parameters:
7371 .  mat - the matrix
7372 
7373    Output Parameters:
7374 +  nblocks - the number of blocks on this process
7375 -  bsizes - the block sizes
7376 
7377    Notes: Currently not supported from Fortran
7378 
7379    Level: intermediate
7380 
7381    Concepts: matrices^block size
7382 
7383 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatSetVariableBlockSizes()
7384 @*/
7385 PetscErrorCode MatGetVariableBlockSizes(Mat mat,PetscInt *nblocks,const PetscInt **bsizes)
7386 {
7387   PetscFunctionBegin;
7388   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7389   *nblocks = mat->nblocks;
7390   *bsizes  = mat->bsizes;
7391   PetscFunctionReturn(0);
7392 }
7393 
7394 /*@
7395    MatSetBlockSizes - Sets the matrix block row and column sizes.
7396 
7397    Logically Collective on Mat
7398 
7399    Input Parameters:
7400 +  mat - the matrix
7401 -  rbs - row block size
7402 -  cbs - column block size
7403 
7404    Notes:
7405     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7406     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7407     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later
7408 
7409     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes
7410     are compatible with the matrix local sizes.
7411 
7412     The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs().
7413 
7414    Level: intermediate
7415 
7416    Concepts: matrices^block size
7417 
7418 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes()
7419 @*/
7420 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
7421 {
7422   PetscErrorCode ierr;
7423 
7424   PetscFunctionBegin;
7425   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7426   PetscValidLogicalCollectiveInt(mat,rbs,2);
7427   PetscValidLogicalCollectiveInt(mat,cbs,3);
7428   if (mat->ops->setblocksizes) {
7429     ierr = (*mat->ops->setblocksizes)(mat,rbs,cbs);CHKERRQ(ierr);
7430   }
7431   if (mat->rmap->refcnt) {
7432     ISLocalToGlobalMapping l2g = NULL;
7433     PetscLayout            nmap = NULL;
7434 
7435     ierr = PetscLayoutDuplicate(mat->rmap,&nmap);CHKERRQ(ierr);
7436     if (mat->rmap->mapping) {
7437       ierr = ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g);CHKERRQ(ierr);
7438     }
7439     ierr = PetscLayoutDestroy(&mat->rmap);CHKERRQ(ierr);
7440     mat->rmap = nmap;
7441     mat->rmap->mapping = l2g;
7442   }
7443   if (mat->cmap->refcnt) {
7444     ISLocalToGlobalMapping l2g = NULL;
7445     PetscLayout            nmap = NULL;
7446 
7447     ierr = PetscLayoutDuplicate(mat->cmap,&nmap);CHKERRQ(ierr);
7448     if (mat->cmap->mapping) {
7449       ierr = ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g);CHKERRQ(ierr);
7450     }
7451     ierr = PetscLayoutDestroy(&mat->cmap);CHKERRQ(ierr);
7452     mat->cmap = nmap;
7453     mat->cmap->mapping = l2g;
7454   }
7455   ierr = PetscLayoutSetBlockSize(mat->rmap,rbs);CHKERRQ(ierr);
7456   ierr = PetscLayoutSetBlockSize(mat->cmap,cbs);CHKERRQ(ierr);
7457   PetscFunctionReturn(0);
7458 }
7459 
7460 /*@
7461    MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices
7462 
7463    Logically Collective on Mat
7464 
7465    Input Parameters:
7466 +  mat - the matrix
7467 .  fromRow - matrix from which to copy row block size
7468 -  fromCol - matrix from which to copy column block size (can be same as fromRow)
7469 
7470    Level: developer
7471 
7472    Concepts: matrices^block size
7473 
7474 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes()
7475 @*/
7476 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)
7477 {
7478   PetscErrorCode ierr;
7479 
7480   PetscFunctionBegin;
7481   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7482   PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2);
7483   PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3);
7484   if (fromRow->rmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);CHKERRQ(ierr);}
7485   if (fromCol->cmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);CHKERRQ(ierr);}
7486   PetscFunctionReturn(0);
7487 }
7488 
7489 /*@
7490    MatResidual - Default routine to calculate the residual.
7491 
7492    Collective on Mat and Vec
7493 
7494    Input Parameters:
7495 +  mat - the matrix
7496 .  b   - the right-hand-side
7497 -  x   - the approximate solution
7498 
7499    Output Parameter:
7500 .  r - location to store the residual
7501 
7502    Level: developer
7503 
7504 .keywords: MG, default, multigrid, residual
7505 
7506 .seealso: PCMGSetResidual()
7507 @*/
7508 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r)
7509 {
7510   PetscErrorCode ierr;
7511 
7512   PetscFunctionBegin;
7513   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7514   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
7515   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
7516   PetscValidHeaderSpecific(r,VEC_CLASSID,4);
7517   PetscValidType(mat,1);
7518   MatCheckPreallocated(mat,1);
7519   ierr  = PetscLogEventBegin(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7520   if (!mat->ops->residual) {
7521     ierr = MatMult(mat,x,r);CHKERRQ(ierr);
7522     ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr);
7523   } else {
7524     ierr  = (*mat->ops->residual)(mat,b,x,r);CHKERRQ(ierr);
7525   }
7526   ierr  = PetscLogEventEnd(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7527   PetscFunctionReturn(0);
7528 }
7529 
7530 /*@C
7531     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
7532 
7533    Collective on Mat
7534 
7535     Input Parameters:
7536 +   mat - the matrix
7537 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
7538 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
7539 -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
7540                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7541                  always used.
7542 
7543     Output Parameters:
7544 +   n - number of rows in the (possibly compressed) matrix
7545 .   ia - the row pointers; that is ia[0] = 0, ia[row] = ia[row-1] + number of elements in that row of the matrix
7546 .   ja - the column indices
7547 -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
7548            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
7549 
7550     Level: developer
7551 
7552     Notes:
7553     You CANNOT change any of the ia[] or ja[] values.
7554 
7555     Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values.
7556 
7557     Fortran Notes:
7558     In Fortran use
7559 $
7560 $      PetscInt ia(1), ja(1)
7561 $      PetscOffset iia, jja
7562 $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
7563 $      ! Access the ith and jth entries via ia(iia + i) and ja(jja + j)
7564 
7565      or
7566 $
7567 $    PetscInt, pointer :: ia(:),ja(:)
7568 $    call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
7569 $    ! Access the ith and jth entries via ia(i) and ja(j)
7570 
7571 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
7572 @*/
7573 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7574 {
7575   PetscErrorCode ierr;
7576 
7577   PetscFunctionBegin;
7578   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7579   PetscValidType(mat,1);
7580   PetscValidIntPointer(n,5);
7581   if (ia) PetscValidIntPointer(ia,6);
7582   if (ja) PetscValidIntPointer(ja,7);
7583   PetscValidIntPointer(done,8);
7584   MatCheckPreallocated(mat,1);
7585   if (!mat->ops->getrowij) *done = PETSC_FALSE;
7586   else {
7587     *done = PETSC_TRUE;
7588     ierr  = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7589     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7590     ierr  = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7591   }
7592   PetscFunctionReturn(0);
7593 }
7594 
7595 /*@C
7596     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
7597 
7598     Collective on Mat
7599 
7600     Input Parameters:
7601 +   mat - the matrix
7602 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7603 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7604                 symmetrized
7605 .   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7606                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7607                  always used.
7608 .   n - number of columns in the (possibly compressed) matrix
7609 .   ia - the column pointers; that is ia[0] = 0, ia[col] = i[col-1] + number of elements in that col of the matrix
7610 -   ja - the row indices
7611 
7612     Output Parameters:
7613 .   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
7614 
7615     Level: developer
7616 
7617 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7618 @*/
7619 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7620 {
7621   PetscErrorCode ierr;
7622 
7623   PetscFunctionBegin;
7624   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7625   PetscValidType(mat,1);
7626   PetscValidIntPointer(n,4);
7627   if (ia) PetscValidIntPointer(ia,5);
7628   if (ja) PetscValidIntPointer(ja,6);
7629   PetscValidIntPointer(done,7);
7630   MatCheckPreallocated(mat,1);
7631   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
7632   else {
7633     *done = PETSC_TRUE;
7634     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7635   }
7636   PetscFunctionReturn(0);
7637 }
7638 
7639 /*@C
7640     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
7641     MatGetRowIJ().
7642 
7643     Collective on Mat
7644 
7645     Input Parameters:
7646 +   mat - the matrix
7647 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7648 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7649                 symmetrized
7650 .   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7651                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7652                  always used.
7653 .   n - size of (possibly compressed) matrix
7654 .   ia - the row pointers
7655 -   ja - the column indices
7656 
7657     Output Parameters:
7658 .   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7659 
7660     Note:
7661     This routine zeros out n, ia, and ja. This is to prevent accidental
7662     us of the array after it has been restored. If you pass NULL, it will
7663     not zero the pointers.  Use of ia or ja after MatRestoreRowIJ() is invalid.
7664 
7665     Level: developer
7666 
7667 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7668 @*/
7669 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7670 {
7671   PetscErrorCode ierr;
7672 
7673   PetscFunctionBegin;
7674   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7675   PetscValidType(mat,1);
7676   if (ia) PetscValidIntPointer(ia,6);
7677   if (ja) PetscValidIntPointer(ja,7);
7678   PetscValidIntPointer(done,8);
7679   MatCheckPreallocated(mat,1);
7680 
7681   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
7682   else {
7683     *done = PETSC_TRUE;
7684     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7685     if (n)  *n = 0;
7686     if (ia) *ia = NULL;
7687     if (ja) *ja = NULL;
7688   }
7689   PetscFunctionReturn(0);
7690 }
7691 
7692 /*@C
7693     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
7694     MatGetColumnIJ().
7695 
7696     Collective on Mat
7697 
7698     Input Parameters:
7699 +   mat - the matrix
7700 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7701 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7702                 symmetrized
7703 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7704                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7705                  always used.
7706 
7707     Output Parameters:
7708 +   n - size of (possibly compressed) matrix
7709 .   ia - the column pointers
7710 .   ja - the row indices
7711 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7712 
7713     Level: developer
7714 
7715 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
7716 @*/
7717 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7718 {
7719   PetscErrorCode ierr;
7720 
7721   PetscFunctionBegin;
7722   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7723   PetscValidType(mat,1);
7724   if (ia) PetscValidIntPointer(ia,5);
7725   if (ja) PetscValidIntPointer(ja,6);
7726   PetscValidIntPointer(done,7);
7727   MatCheckPreallocated(mat,1);
7728 
7729   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
7730   else {
7731     *done = PETSC_TRUE;
7732     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7733     if (n)  *n = 0;
7734     if (ia) *ia = NULL;
7735     if (ja) *ja = NULL;
7736   }
7737   PetscFunctionReturn(0);
7738 }
7739 
7740 /*@C
7741     MatColoringPatch -Used inside matrix coloring routines that
7742     use MatGetRowIJ() and/or MatGetColumnIJ().
7743 
7744     Collective on Mat
7745 
7746     Input Parameters:
7747 +   mat - the matrix
7748 .   ncolors - max color value
7749 .   n   - number of entries in colorarray
7750 -   colorarray - array indicating color for each column
7751 
7752     Output Parameters:
7753 .   iscoloring - coloring generated using colorarray information
7754 
7755     Level: developer
7756 
7757 .seealso: MatGetRowIJ(), MatGetColumnIJ()
7758 
7759 @*/
7760 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7761 {
7762   PetscErrorCode ierr;
7763 
7764   PetscFunctionBegin;
7765   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7766   PetscValidType(mat,1);
7767   PetscValidIntPointer(colorarray,4);
7768   PetscValidPointer(iscoloring,5);
7769   MatCheckPreallocated(mat,1);
7770 
7771   if (!mat->ops->coloringpatch) {
7772     ierr = ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);CHKERRQ(ierr);
7773   } else {
7774     ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
7775   }
7776   PetscFunctionReturn(0);
7777 }
7778 
7779 
7780 /*@
7781    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
7782 
7783    Logically Collective on Mat
7784 
7785    Input Parameter:
7786 .  mat - the factored matrix to be reset
7787 
7788    Notes:
7789    This routine should be used only with factored matrices formed by in-place
7790    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7791    format).  This option can save memory, for example, when solving nonlinear
7792    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7793    ILU(0) preconditioner.
7794 
7795    Note that one can specify in-place ILU(0) factorization by calling
7796 .vb
7797      PCType(pc,PCILU);
7798      PCFactorSeUseInPlace(pc);
7799 .ve
7800    or by using the options -pc_type ilu -pc_factor_in_place
7801 
7802    In-place factorization ILU(0) can also be used as a local
7803    solver for the blocks within the block Jacobi or additive Schwarz
7804    methods (runtime option: -sub_pc_factor_in_place).  See Users-Manual: ch_pc
7805    for details on setting local solver options.
7806 
7807    Most users should employ the simplified KSP interface for linear solvers
7808    instead of working directly with matrix algebra routines such as this.
7809    See, e.g., KSPCreate().
7810 
7811    Level: developer
7812 
7813 .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace()
7814 
7815    Concepts: matrices^unfactored
7816 
7817 @*/
7818 PetscErrorCode MatSetUnfactored(Mat mat)
7819 {
7820   PetscErrorCode ierr;
7821 
7822   PetscFunctionBegin;
7823   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7824   PetscValidType(mat,1);
7825   MatCheckPreallocated(mat,1);
7826   mat->factortype = MAT_FACTOR_NONE;
7827   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
7828   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
7829   PetscFunctionReturn(0);
7830 }
7831 
7832 /*MC
7833     MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.
7834 
7835     Synopsis:
7836     MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7837 
7838     Not collective
7839 
7840     Input Parameter:
7841 .   x - matrix
7842 
7843     Output Parameters:
7844 +   xx_v - the Fortran90 pointer to the array
7845 -   ierr - error code
7846 
7847     Example of Usage:
7848 .vb
7849       PetscScalar, pointer xx_v(:,:)
7850       ....
7851       call MatDenseGetArrayF90(x,xx_v,ierr)
7852       a = xx_v(3)
7853       call MatDenseRestoreArrayF90(x,xx_v,ierr)
7854 .ve
7855 
7856     Level: advanced
7857 
7858 .seealso:  MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90()
7859 
7860     Concepts: matrices^accessing array
7861 
7862 M*/
7863 
7864 /*MC
7865     MatDenseRestoreArrayF90 - Restores a matrix array that has been
7866     accessed with MatDenseGetArrayF90().
7867 
7868     Synopsis:
7869     MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7870 
7871     Not collective
7872 
7873     Input Parameters:
7874 +   x - matrix
7875 -   xx_v - the Fortran90 pointer to the array
7876 
7877     Output Parameter:
7878 .   ierr - error code
7879 
7880     Example of Usage:
7881 .vb
7882        PetscScalar, pointer xx_v(:,:)
7883        ....
7884        call MatDenseGetArrayF90(x,xx_v,ierr)
7885        a = xx_v(3)
7886        call MatDenseRestoreArrayF90(x,xx_v,ierr)
7887 .ve
7888 
7889     Level: advanced
7890 
7891 .seealso:  MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90()
7892 
7893 M*/
7894 
7895 
7896 /*MC
7897     MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.
7898 
7899     Synopsis:
7900     MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7901 
7902     Not collective
7903 
7904     Input Parameter:
7905 .   x - matrix
7906 
7907     Output Parameters:
7908 +   xx_v - the Fortran90 pointer to the array
7909 -   ierr - error code
7910 
7911     Example of Usage:
7912 .vb
7913       PetscScalar, pointer xx_v(:)
7914       ....
7915       call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7916       a = xx_v(3)
7917       call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7918 .ve
7919 
7920     Level: advanced
7921 
7922 .seealso:  MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90()
7923 
7924     Concepts: matrices^accessing array
7925 
7926 M*/
7927 
7928 /*MC
7929     MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7930     accessed with MatSeqAIJGetArrayF90().
7931 
7932     Synopsis:
7933     MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7934 
7935     Not collective
7936 
7937     Input Parameters:
7938 +   x - matrix
7939 -   xx_v - the Fortran90 pointer to the array
7940 
7941     Output Parameter:
7942 .   ierr - error code
7943 
7944     Example of Usage:
7945 .vb
7946        PetscScalar, pointer xx_v(:)
7947        ....
7948        call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7949        a = xx_v(3)
7950        call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7951 .ve
7952 
7953     Level: advanced
7954 
7955 .seealso:  MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90()
7956 
7957 M*/
7958 
7959 
7960 /*@
7961     MatCreateSubMatrix - Gets a single submatrix on the same number of processors
7962                       as the original matrix.
7963 
7964     Collective on Mat
7965 
7966     Input Parameters:
7967 +   mat - the original matrix
7968 .   isrow - parallel IS containing the rows this processor should obtain
7969 .   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.
7970 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7971 
7972     Output Parameter:
7973 .   newmat - the new submatrix, of the same type as the old
7974 
7975     Level: advanced
7976 
7977     Notes:
7978     The submatrix will be able to be multiplied with vectors using the same layout as iscol.
7979 
7980     Some matrix types place restrictions on the row and column indices, such
7981     as that they be sorted or that they be equal to each other.
7982 
7983     The index sets may not have duplicate entries.
7984 
7985       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7986    the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls
7987    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7988    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
7989    you are finished using it.
7990 
7991     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7992     the input matrix.
7993 
7994     If iscol is NULL then all columns are obtained (not supported in Fortran).
7995 
7996    Example usage:
7997    Consider the following 8x8 matrix with 34 non-zero values, that is
7998    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7999    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
8000    as follows:
8001 
8002 .vb
8003             1  2  0  |  0  3  0  |  0  4
8004     Proc0   0  5  6  |  7  0  0  |  8  0
8005             9  0 10  | 11  0  0  | 12  0
8006     -------------------------------------
8007            13  0 14  | 15 16 17  |  0  0
8008     Proc1   0 18  0  | 19 20 21  |  0  0
8009             0  0  0  | 22 23  0  | 24  0
8010     -------------------------------------
8011     Proc2  25 26 27  |  0  0 28  | 29  0
8012            30  0  0  | 31 32 33  |  0 34
8013 .ve
8014 
8015     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is
8016 
8017 .vb
8018             2  0  |  0  3  0  |  0
8019     Proc0   5  6  |  7  0  0  |  8
8020     -------------------------------
8021     Proc1  18  0  | 19 20 21  |  0
8022     -------------------------------
8023     Proc2  26 27  |  0  0 28  | 29
8024             0  0  | 31 32 33  |  0
8025 .ve
8026 
8027 
8028     Concepts: matrices^submatrices
8029 
8030 .seealso: MatCreateSubMatrices()
8031 @*/
8032 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
8033 {
8034   PetscErrorCode ierr;
8035   PetscMPIInt    size;
8036   Mat            *local;
8037   IS             iscoltmp;
8038 
8039   PetscFunctionBegin;
8040   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8041   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
8042   if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
8043   PetscValidPointer(newmat,5);
8044   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5);
8045   PetscValidType(mat,1);
8046   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8047   if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX");
8048 
8049   MatCheckPreallocated(mat,1);
8050   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
8051 
8052   if (!iscol || isrow == iscol) {
8053     PetscBool   stride;
8054     PetscMPIInt grabentirematrix = 0,grab;
8055     ierr = PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);CHKERRQ(ierr);
8056     if (stride) {
8057       PetscInt first,step,n,rstart,rend;
8058       ierr = ISStrideGetInfo(isrow,&first,&step);CHKERRQ(ierr);
8059       if (step == 1) {
8060         ierr = MatGetOwnershipRange(mat,&rstart,&rend);CHKERRQ(ierr);
8061         if (rstart == first) {
8062           ierr = ISGetLocalSize(isrow,&n);CHKERRQ(ierr);
8063           if (n == rend-rstart) {
8064             grabentirematrix = 1;
8065           }
8066         }
8067       }
8068     }
8069     ierr = MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr);
8070     if (grab) {
8071       ierr = PetscInfo(mat,"Getting entire matrix as submatrix\n");CHKERRQ(ierr);
8072       if (cll == MAT_INITIAL_MATRIX) {
8073         *newmat = mat;
8074         ierr    = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr);
8075       }
8076       PetscFunctionReturn(0);
8077     }
8078   }
8079 
8080   if (!iscol) {
8081     ierr = ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr);
8082   } else {
8083     iscoltmp = iscol;
8084   }
8085 
8086   /* if original matrix is on just one processor then use submatrix generated */
8087   if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
8088     ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
8089     goto setproperties;
8090   } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) {
8091     ierr    = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
8092     *newmat = *local;
8093     ierr    = PetscFree(local);CHKERRQ(ierr);
8094     goto setproperties;
8095   } else if (!mat->ops->createsubmatrix) {
8096     /* Create a new matrix type that implements the operation using the full matrix */
8097     ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8098     switch (cll) {
8099     case MAT_INITIAL_MATRIX:
8100       ierr = MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr);
8101       break;
8102     case MAT_REUSE_MATRIX:
8103       ierr = MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr);
8104       break;
8105     default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
8106     }
8107     ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8108     goto setproperties;
8109   }
8110 
8111   if (!mat->ops->createsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8112   ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8113   ierr = (*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr);
8114   ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8115 
8116   /* Propagate symmetry information for diagonal blocks */
8117 setproperties:
8118   if (isrow == iscoltmp) {
8119     if (mat->symmetric_set && mat->symmetric) {
8120       ierr = MatSetOption(*newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
8121     }
8122     if (mat->structurally_symmetric_set && mat->structurally_symmetric) {
8123       ierr = MatSetOption(*newmat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
8124     }
8125     if (mat->hermitian_set && mat->hermitian) {
8126       ierr = MatSetOption(*newmat,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
8127     }
8128     if (mat->spd_set && mat->spd) {
8129       ierr = MatSetOption(*newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr);
8130     }
8131   }
8132 
8133   if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
8134   if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);}
8135   PetscFunctionReturn(0);
8136 }
8137 
8138 /*@
8139    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
8140    used during the assembly process to store values that belong to
8141    other processors.
8142 
8143    Not Collective
8144 
8145    Input Parameters:
8146 +  mat   - the matrix
8147 .  size  - the initial size of the stash.
8148 -  bsize - the initial size of the block-stash(if used).
8149 
8150    Options Database Keys:
8151 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
8152 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
8153 
8154    Level: intermediate
8155 
8156    Notes:
8157      The block-stash is used for values set with MatSetValuesBlocked() while
8158      the stash is used for values set with MatSetValues()
8159 
8160      Run with the option -info and look for output of the form
8161      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
8162      to determine the appropriate value, MM, to use for size and
8163      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
8164      to determine the value, BMM to use for bsize
8165 
8166    Concepts: stash^setting matrix size
8167    Concepts: matrices^stash
8168 
8169 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
8170 
8171 @*/
8172 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
8173 {
8174   PetscErrorCode ierr;
8175 
8176   PetscFunctionBegin;
8177   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8178   PetscValidType(mat,1);
8179   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
8180   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
8181   PetscFunctionReturn(0);
8182 }
8183 
8184 /*@
8185    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
8186      the matrix
8187 
8188    Neighbor-wise Collective on Mat
8189 
8190    Input Parameters:
8191 +  mat   - the matrix
8192 .  x,y - the vectors
8193 -  w - where the result is stored
8194 
8195    Level: intermediate
8196 
8197    Notes:
8198     w may be the same vector as y.
8199 
8200     This allows one to use either the restriction or interpolation (its transpose)
8201     matrix to do the interpolation
8202 
8203     Concepts: interpolation
8204 
8205 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
8206 
8207 @*/
8208 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
8209 {
8210   PetscErrorCode ierr;
8211   PetscInt       M,N,Ny;
8212 
8213   PetscFunctionBegin;
8214   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8215   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8216   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8217   PetscValidHeaderSpecific(w,VEC_CLASSID,4);
8218   PetscValidType(A,1);
8219   MatCheckPreallocated(A,1);
8220   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8221   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8222   if (M == Ny) {
8223     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
8224   } else {
8225     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
8226   }
8227   PetscFunctionReturn(0);
8228 }
8229 
8230 /*@
8231    MatInterpolate - y = A*x or A'*x depending on the shape of
8232      the matrix
8233 
8234    Neighbor-wise Collective on Mat
8235 
8236    Input Parameters:
8237 +  mat   - the matrix
8238 -  x,y - the vectors
8239 
8240    Level: intermediate
8241 
8242    Notes:
8243     This allows one to use either the restriction or interpolation (its transpose)
8244     matrix to do the interpolation
8245 
8246    Concepts: matrices^interpolation
8247 
8248 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
8249 
8250 @*/
8251 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
8252 {
8253   PetscErrorCode ierr;
8254   PetscInt       M,N,Ny;
8255 
8256   PetscFunctionBegin;
8257   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8258   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8259   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8260   PetscValidType(A,1);
8261   MatCheckPreallocated(A,1);
8262   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8263   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8264   if (M == Ny) {
8265     ierr = MatMult(A,x,y);CHKERRQ(ierr);
8266   } else {
8267     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
8268   }
8269   PetscFunctionReturn(0);
8270 }
8271 
8272 /*@
8273    MatRestrict - y = A*x or A'*x
8274 
8275    Neighbor-wise Collective on Mat
8276 
8277    Input Parameters:
8278 +  mat   - the matrix
8279 -  x,y - the vectors
8280 
8281    Level: intermediate
8282 
8283    Notes:
8284     This allows one to use either the restriction or interpolation (its transpose)
8285     matrix to do the restriction
8286 
8287    Concepts: matrices^restriction
8288 
8289 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
8290 
8291 @*/
8292 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
8293 {
8294   PetscErrorCode ierr;
8295   PetscInt       M,N,Ny;
8296 
8297   PetscFunctionBegin;
8298   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8299   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8300   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8301   PetscValidType(A,1);
8302   MatCheckPreallocated(A,1);
8303 
8304   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8305   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8306   if (M == Ny) {
8307     ierr = MatMult(A,x,y);CHKERRQ(ierr);
8308   } else {
8309     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
8310   }
8311   PetscFunctionReturn(0);
8312 }
8313 
8314 /*@
8315    MatGetNullSpace - retrieves the null space of a matrix.
8316 
8317    Logically Collective on Mat and MatNullSpace
8318 
8319    Input Parameters:
8320 +  mat - the matrix
8321 -  nullsp - the null space object
8322 
8323    Level: developer
8324 
8325    Concepts: null space^attaching to matrix
8326 
8327 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace()
8328 @*/
8329 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
8330 {
8331   PetscFunctionBegin;
8332   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8333   PetscValidPointer(nullsp,2);
8334   *nullsp = (mat->symmetric_set && mat->symmetric && !mat->nullsp) ? mat->transnullsp : mat->nullsp;
8335   PetscFunctionReturn(0);
8336 }
8337 
8338 /*@
8339    MatSetNullSpace - attaches a null space to a matrix.
8340 
8341    Logically Collective on Mat and MatNullSpace
8342 
8343    Input Parameters:
8344 +  mat - the matrix
8345 -  nullsp - the null space object
8346 
8347    Level: advanced
8348 
8349    Notes:
8350       This null space is used by the linear solvers. Overwrites any previous null space that may have been attached
8351 
8352       For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should
8353       call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense.
8354 
8355       You can remove the null space by calling this routine with an nullsp of NULL
8356 
8357 
8358       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8359    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).
8360    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
8361    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
8362    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).
8363 
8364       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8365 
8366     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
8367     routine also automatically calls MatSetTransposeNullSpace().
8368 
8369    Concepts: null space^attaching to matrix
8370 
8371 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8372 @*/
8373 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp)
8374 {
8375   PetscErrorCode ierr;
8376 
8377   PetscFunctionBegin;
8378   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8379   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8380   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8381   ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr);
8382   mat->nullsp = nullsp;
8383   if (mat->symmetric_set && mat->symmetric) {
8384     ierr = MatSetTransposeNullSpace(mat,nullsp);CHKERRQ(ierr);
8385   }
8386   PetscFunctionReturn(0);
8387 }
8388 
8389 /*@
8390    MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix.
8391 
8392    Logically Collective on Mat and MatNullSpace
8393 
8394    Input Parameters:
8395 +  mat - the matrix
8396 -  nullsp - the null space object
8397 
8398    Level: developer
8399 
8400    Concepts: null space^attaching to matrix
8401 
8402 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace()
8403 @*/
8404 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp)
8405 {
8406   PetscFunctionBegin;
8407   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8408   PetscValidType(mat,1);
8409   PetscValidPointer(nullsp,2);
8410   *nullsp = (mat->symmetric_set && mat->symmetric && !mat->transnullsp) ? mat->nullsp : mat->transnullsp;
8411   PetscFunctionReturn(0);
8412 }
8413 
8414 /*@
8415    MatSetTransposeNullSpace - attaches a null space to a matrix.
8416 
8417    Logically Collective on Mat and MatNullSpace
8418 
8419    Input Parameters:
8420 +  mat - the matrix
8421 -  nullsp - the null space object
8422 
8423    Level: advanced
8424 
8425    Notes:
8426       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.
8427       You must also call MatSetNullSpace()
8428 
8429 
8430       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8431    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).
8432    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
8433    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
8434    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).
8435 
8436       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8437 
8438    Concepts: null space^attaching to matrix
8439 
8440 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8441 @*/
8442 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp)
8443 {
8444   PetscErrorCode ierr;
8445 
8446   PetscFunctionBegin;
8447   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8448   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8449   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8450   ierr = MatNullSpaceDestroy(&mat->transnullsp);CHKERRQ(ierr);
8451   mat->transnullsp = nullsp;
8452   PetscFunctionReturn(0);
8453 }
8454 
8455 /*@
8456    MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions
8457         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.
8458 
8459    Logically Collective on Mat and MatNullSpace
8460 
8461    Input Parameters:
8462 +  mat - the matrix
8463 -  nullsp - the null space object
8464 
8465    Level: advanced
8466 
8467    Notes:
8468       Overwrites any previous near null space that may have been attached
8469 
8470       You can remove the null space by calling this routine with an nullsp of NULL
8471 
8472    Concepts: null space^attaching to matrix
8473 
8474 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace()
8475 @*/
8476 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
8477 {
8478   PetscErrorCode ierr;
8479 
8480   PetscFunctionBegin;
8481   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8482   PetscValidType(mat,1);
8483   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8484   MatCheckPreallocated(mat,1);
8485   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8486   ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr);
8487   mat->nearnullsp = nullsp;
8488   PetscFunctionReturn(0);
8489 }
8490 
8491 /*@
8492    MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()
8493 
8494    Not Collective
8495 
8496    Input Parameters:
8497 .  mat - the matrix
8498 
8499    Output Parameters:
8500 .  nullsp - the null space object, NULL if not set
8501 
8502    Level: developer
8503 
8504    Concepts: null space^attaching to matrix
8505 
8506 .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate()
8507 @*/
8508 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
8509 {
8510   PetscFunctionBegin;
8511   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8512   PetscValidType(mat,1);
8513   PetscValidPointer(nullsp,2);
8514   MatCheckPreallocated(mat,1);
8515   *nullsp = mat->nearnullsp;
8516   PetscFunctionReturn(0);
8517 }
8518 
8519 /*@C
8520    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
8521 
8522    Collective on Mat
8523 
8524    Input Parameters:
8525 +  mat - the matrix
8526 .  row - row/column permutation
8527 .  fill - expected fill factor >= 1.0
8528 -  level - level of fill, for ICC(k)
8529 
8530    Notes:
8531    Probably really in-place only when level of fill is zero, otherwise allocates
8532    new space to store factored matrix and deletes previous memory.
8533 
8534    Most users should employ the simplified KSP interface for linear solvers
8535    instead of working directly with matrix algebra routines such as this.
8536    See, e.g., KSPCreate().
8537 
8538    Level: developer
8539 
8540    Concepts: matrices^incomplete Cholesky factorization
8541    Concepts: Cholesky factorization
8542 
8543 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
8544 
8545     Developer Note: fortran interface is not autogenerated as the f90
8546     interface defintion cannot be generated correctly [due to MatFactorInfo]
8547 
8548 @*/
8549 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
8550 {
8551   PetscErrorCode ierr;
8552 
8553   PetscFunctionBegin;
8554   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8555   PetscValidType(mat,1);
8556   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
8557   PetscValidPointer(info,3);
8558   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
8559   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8560   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8561   if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8562   MatCheckPreallocated(mat,1);
8563   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
8564   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8565   PetscFunctionReturn(0);
8566 }
8567 
8568 /*@
8569    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
8570          ghosted ones.
8571 
8572    Not Collective
8573 
8574    Input Parameters:
8575 +  mat - the matrix
8576 -  diag = the diagonal values, including ghost ones
8577 
8578    Level: developer
8579 
8580    Notes:
8581     Works only for MPIAIJ and MPIBAIJ matrices
8582 
8583 .seealso: MatDiagonalScale()
8584 @*/
8585 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
8586 {
8587   PetscErrorCode ierr;
8588   PetscMPIInt    size;
8589 
8590   PetscFunctionBegin;
8591   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8592   PetscValidHeaderSpecific(diag,VEC_CLASSID,2);
8593   PetscValidType(mat,1);
8594 
8595   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8596   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8597   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
8598   if (size == 1) {
8599     PetscInt n,m;
8600     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
8601     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
8602     if (m == n) {
8603       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
8604     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
8605   } else {
8606     ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr);
8607   }
8608   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8609   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8610   PetscFunctionReturn(0);
8611 }
8612 
8613 /*@
8614    MatGetInertia - Gets the inertia from a factored matrix
8615 
8616    Collective on Mat
8617 
8618    Input Parameter:
8619 .  mat - the matrix
8620 
8621    Output Parameters:
8622 +   nneg - number of negative eigenvalues
8623 .   nzero - number of zero eigenvalues
8624 -   npos - number of positive eigenvalues
8625 
8626    Level: advanced
8627 
8628    Notes:
8629     Matrix must have been factored by MatCholeskyFactor()
8630 
8631 
8632 @*/
8633 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
8634 {
8635   PetscErrorCode ierr;
8636 
8637   PetscFunctionBegin;
8638   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8639   PetscValidType(mat,1);
8640   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8641   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
8642   if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8643   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
8644   PetscFunctionReturn(0);
8645 }
8646 
8647 /* ----------------------------------------------------------------*/
8648 /*@C
8649    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
8650 
8651    Neighbor-wise Collective on Mat and Vecs
8652 
8653    Input Parameters:
8654 +  mat - the factored matrix
8655 -  b - the right-hand-side vectors
8656 
8657    Output Parameter:
8658 .  x - the result vectors
8659 
8660    Notes:
8661    The vectors b and x cannot be the same.  I.e., one cannot
8662    call MatSolves(A,x,x).
8663 
8664    Notes:
8665    Most users should employ the simplified KSP interface for linear solvers
8666    instead of working directly with matrix algebra routines such as this.
8667    See, e.g., KSPCreate().
8668 
8669    Level: developer
8670 
8671    Concepts: matrices^triangular solves
8672 
8673 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
8674 @*/
8675 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
8676 {
8677   PetscErrorCode ierr;
8678 
8679   PetscFunctionBegin;
8680   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8681   PetscValidType(mat,1);
8682   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
8683   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8684   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
8685 
8686   if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8687   MatCheckPreallocated(mat,1);
8688   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8689   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
8690   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8691   PetscFunctionReturn(0);
8692 }
8693 
8694 /*@
8695    MatIsSymmetric - Test whether a matrix is symmetric
8696 
8697    Collective on Mat
8698 
8699    Input Parameter:
8700 +  A - the matrix to test
8701 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
8702 
8703    Output Parameters:
8704 .  flg - the result
8705 
8706    Notes:
8707     For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
8708 
8709    Level: intermediate
8710 
8711    Concepts: matrix^symmetry
8712 
8713 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
8714 @*/
8715 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
8716 {
8717   PetscErrorCode ierr;
8718 
8719   PetscFunctionBegin;
8720   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8721   PetscValidPointer(flg,2);
8722 
8723   if (!A->symmetric_set) {
8724     if (!A->ops->issymmetric) {
8725       MatType mattype;
8726       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8727       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8728     }
8729     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8730     if (!tol) {
8731       A->symmetric_set = PETSC_TRUE;
8732       A->symmetric     = *flg;
8733       if (A->symmetric) {
8734         A->structurally_symmetric_set = PETSC_TRUE;
8735         A->structurally_symmetric     = PETSC_TRUE;
8736       }
8737     }
8738   } else if (A->symmetric) {
8739     *flg = PETSC_TRUE;
8740   } else if (!tol) {
8741     *flg = PETSC_FALSE;
8742   } else {
8743     if (!A->ops->issymmetric) {
8744       MatType mattype;
8745       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8746       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8747     }
8748     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8749   }
8750   PetscFunctionReturn(0);
8751 }
8752 
8753 /*@
8754    MatIsHermitian - Test whether a matrix is Hermitian
8755 
8756    Collective on Mat
8757 
8758    Input Parameter:
8759 +  A - the matrix to test
8760 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
8761 
8762    Output Parameters:
8763 .  flg - the result
8764 
8765    Level: intermediate
8766 
8767    Concepts: matrix^symmetry
8768 
8769 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
8770           MatIsSymmetricKnown(), MatIsSymmetric()
8771 @*/
8772 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
8773 {
8774   PetscErrorCode ierr;
8775 
8776   PetscFunctionBegin;
8777   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8778   PetscValidPointer(flg,2);
8779 
8780   if (!A->hermitian_set) {
8781     if (!A->ops->ishermitian) {
8782       MatType mattype;
8783       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8784       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8785     }
8786     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8787     if (!tol) {
8788       A->hermitian_set = PETSC_TRUE;
8789       A->hermitian     = *flg;
8790       if (A->hermitian) {
8791         A->structurally_symmetric_set = PETSC_TRUE;
8792         A->structurally_symmetric     = PETSC_TRUE;
8793       }
8794     }
8795   } else if (A->hermitian) {
8796     *flg = PETSC_TRUE;
8797   } else if (!tol) {
8798     *flg = PETSC_FALSE;
8799   } else {
8800     if (!A->ops->ishermitian) {
8801       MatType mattype;
8802       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8803       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8804     }
8805     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8806   }
8807   PetscFunctionReturn(0);
8808 }
8809 
8810 /*@
8811    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
8812 
8813    Not Collective
8814 
8815    Input Parameter:
8816 .  A - the matrix to check
8817 
8818    Output Parameters:
8819 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
8820 -  flg - the result
8821 
8822    Level: advanced
8823 
8824    Concepts: matrix^symmetry
8825 
8826    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
8827          if you want it explicitly checked
8828 
8829 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8830 @*/
8831 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8832 {
8833   PetscFunctionBegin;
8834   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8835   PetscValidPointer(set,2);
8836   PetscValidPointer(flg,3);
8837   if (A->symmetric_set) {
8838     *set = PETSC_TRUE;
8839     *flg = A->symmetric;
8840   } else {
8841     *set = PETSC_FALSE;
8842   }
8843   PetscFunctionReturn(0);
8844 }
8845 
8846 /*@
8847    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
8848 
8849    Not Collective
8850 
8851    Input Parameter:
8852 .  A - the matrix to check
8853 
8854    Output Parameters:
8855 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8856 -  flg - the result
8857 
8858    Level: advanced
8859 
8860    Concepts: matrix^symmetry
8861 
8862    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8863          if you want it explicitly checked
8864 
8865 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8866 @*/
8867 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8868 {
8869   PetscFunctionBegin;
8870   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8871   PetscValidPointer(set,2);
8872   PetscValidPointer(flg,3);
8873   if (A->hermitian_set) {
8874     *set = PETSC_TRUE;
8875     *flg = A->hermitian;
8876   } else {
8877     *set = PETSC_FALSE;
8878   }
8879   PetscFunctionReturn(0);
8880 }
8881 
8882 /*@
8883    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
8884 
8885    Collective on Mat
8886 
8887    Input Parameter:
8888 .  A - the matrix to test
8889 
8890    Output Parameters:
8891 .  flg - the result
8892 
8893    Level: intermediate
8894 
8895    Concepts: matrix^symmetry
8896 
8897 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8898 @*/
8899 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
8900 {
8901   PetscErrorCode ierr;
8902 
8903   PetscFunctionBegin;
8904   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8905   PetscValidPointer(flg,2);
8906   if (!A->structurally_symmetric_set) {
8907     if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8908     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
8909 
8910     A->structurally_symmetric_set = PETSC_TRUE;
8911   }
8912   *flg = A->structurally_symmetric;
8913   PetscFunctionReturn(0);
8914 }
8915 
8916 /*@
8917    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8918        to be communicated to other processors during the MatAssemblyBegin/End() process
8919 
8920     Not collective
8921 
8922    Input Parameter:
8923 .   vec - the vector
8924 
8925    Output Parameters:
8926 +   nstash   - the size of the stash
8927 .   reallocs - the number of additional mallocs incurred.
8928 .   bnstash   - the size of the block stash
8929 -   breallocs - the number of additional mallocs incurred.in the block stash
8930 
8931    Level: advanced
8932 
8933 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
8934 
8935 @*/
8936 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8937 {
8938   PetscErrorCode ierr;
8939 
8940   PetscFunctionBegin;
8941   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
8942   ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
8943   PetscFunctionReturn(0);
8944 }
8945 
8946 /*@C
8947    MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same
8948      parallel layout
8949 
8950    Collective on Mat
8951 
8952    Input Parameter:
8953 .  mat - the matrix
8954 
8955    Output Parameter:
8956 +   right - (optional) vector that the matrix can be multiplied against
8957 -   left - (optional) vector that the matrix vector product can be stored in
8958 
8959    Notes:
8960     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().
8961 
8962   Notes:
8963     These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed
8964 
8965   Level: advanced
8966 
8967 .seealso: MatCreate(), VecDestroy()
8968 @*/
8969 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left)
8970 {
8971   PetscErrorCode ierr;
8972 
8973   PetscFunctionBegin;
8974   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8975   PetscValidType(mat,1);
8976   if (mat->ops->getvecs) {
8977     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
8978   } else {
8979     PetscInt rbs,cbs;
8980     ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr);
8981     if (right) {
8982       if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup");
8983       ierr = VecCreate(PetscObjectComm((PetscObject)mat),right);CHKERRQ(ierr);
8984       ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8985       ierr = VecSetBlockSize(*right,cbs);CHKERRQ(ierr);
8986       ierr = VecSetType(*right,mat->defaultvectype);CHKERRQ(ierr);
8987       ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr);
8988     }
8989     if (left) {
8990       if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup");
8991       ierr = VecCreate(PetscObjectComm((PetscObject)mat),left);CHKERRQ(ierr);
8992       ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8993       ierr = VecSetBlockSize(*left,rbs);CHKERRQ(ierr);
8994       ierr = VecSetType(*left,mat->defaultvectype);CHKERRQ(ierr);
8995       ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr);
8996     }
8997   }
8998   PetscFunctionReturn(0);
8999 }
9000 
9001 /*@C
9002    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
9003      with default values.
9004 
9005    Not Collective
9006 
9007    Input Parameters:
9008 .    info - the MatFactorInfo data structure
9009 
9010 
9011    Notes:
9012     The solvers are generally used through the KSP and PC objects, for example
9013           PCLU, PCILU, PCCHOLESKY, PCICC
9014 
9015    Level: developer
9016 
9017 .seealso: MatFactorInfo
9018 
9019     Developer Note: fortran interface is not autogenerated as the f90
9020     interface defintion cannot be generated correctly [due to MatFactorInfo]
9021 
9022 @*/
9023 
9024 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
9025 {
9026   PetscErrorCode ierr;
9027 
9028   PetscFunctionBegin;
9029   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
9030   PetscFunctionReturn(0);
9031 }
9032 
9033 /*@
9034    MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed
9035 
9036    Collective on Mat
9037 
9038    Input Parameters:
9039 +  mat - the factored matrix
9040 -  is - the index set defining the Schur indices (0-based)
9041 
9042    Notes:
9043     Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system.
9044 
9045    You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call.
9046 
9047    Level: developer
9048 
9049    Concepts:
9050 
9051 .seealso: MatGetFactor(), MatFactorGetSchurComplement(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSolveSchurComplement(),
9052           MatFactorSolveSchurComplementTranspose(), MatFactorSolveSchurComplement()
9053 
9054 @*/
9055 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is)
9056 {
9057   PetscErrorCode ierr,(*f)(Mat,IS);
9058 
9059   PetscFunctionBegin;
9060   PetscValidType(mat,1);
9061   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9062   PetscValidType(is,2);
9063   PetscValidHeaderSpecific(is,IS_CLASSID,2);
9064   PetscCheckSameComm(mat,1,is,2);
9065   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
9066   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);CHKERRQ(ierr);
9067   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");
9068   if (mat->schur) {
9069     ierr = MatDestroy(&mat->schur);CHKERRQ(ierr);
9070   }
9071   ierr = (*f)(mat,is);CHKERRQ(ierr);
9072   if (!mat->schur) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created");
9073   ierr = MatFactorSetUpInPlaceSchur_Private(mat);CHKERRQ(ierr);
9074   PetscFunctionReturn(0);
9075 }
9076 
9077 /*@
9078   MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step
9079 
9080    Logically Collective on Mat
9081 
9082    Input Parameters:
9083 +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
9084 .  S - location where to return the Schur complement, can be NULL
9085 -  status - the status of the Schur complement matrix, can be NULL
9086 
9087    Notes:
9088    You must call MatFactorSetSchurIS() before calling this routine.
9089 
9090    The routine provides a copy of the Schur matrix stored within the solver data structures.
9091    The caller must destroy the object when it is no longer needed.
9092    If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse.
9093 
9094    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)
9095 
9096    Developer Notes:
9097     The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc
9098    matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix.
9099 
9100    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
9101 
9102    Level: advanced
9103 
9104    References:
9105 
9106 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorSchurStatus
9107 @*/
9108 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
9109 {
9110   PetscErrorCode ierr;
9111 
9112   PetscFunctionBegin;
9113   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9114   if (S) PetscValidPointer(S,2);
9115   if (status) PetscValidPointer(status,3);
9116   if (S) {
9117     PetscErrorCode (*f)(Mat,Mat*);
9118 
9119     ierr = PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f);CHKERRQ(ierr);
9120     if (f) {
9121       ierr = (*f)(F,S);CHKERRQ(ierr);
9122     } else {
9123       ierr = MatDuplicate(F->schur,MAT_COPY_VALUES,S);CHKERRQ(ierr);
9124     }
9125   }
9126   if (status) *status = F->schur_status;
9127   PetscFunctionReturn(0);
9128 }
9129 
9130 /*@
9131   MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix
9132 
9133    Logically Collective on Mat
9134 
9135    Input Parameters:
9136 +  F - the factored matrix obtained by calling MatGetFactor()
9137 .  *S - location where to return the Schur complement, can be NULL
9138 -  status - the status of the Schur complement matrix, can be NULL
9139 
9140    Notes:
9141    You must call MatFactorSetSchurIS() before calling this routine.
9142 
9143    Schur complement mode is currently implemented for sequential matrices.
9144    The routine returns a the Schur Complement stored within the data strutures of the solver.
9145    If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement.
9146    The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed.
9147 
9148    Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix
9149 
9150    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
9151 
9152    Level: advanced
9153 
9154    References:
9155 
9156 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
9157 @*/
9158 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
9159 {
9160   PetscFunctionBegin;
9161   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9162   if (S) PetscValidPointer(S,2);
9163   if (status) PetscValidPointer(status,3);
9164   if (S) *S = F->schur;
9165   if (status) *status = F->schur_status;
9166   PetscFunctionReturn(0);
9167 }
9168 
9169 /*@
9170   MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement
9171 
9172    Logically Collective on Mat
9173 
9174    Input Parameters:
9175 +  F - the factored matrix obtained by calling MatGetFactor()
9176 .  *S - location where the Schur complement is stored
9177 -  status - the status of the Schur complement matrix (see MatFactorSchurStatus)
9178 
9179    Notes:
9180 
9181    Level: advanced
9182 
9183    References:
9184 
9185 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
9186 @*/
9187 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status)
9188 {
9189   PetscErrorCode ierr;
9190 
9191   PetscFunctionBegin;
9192   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9193   if (S) {
9194     PetscValidHeaderSpecific(*S,MAT_CLASSID,2);
9195     *S = NULL;
9196   }
9197   F->schur_status = status;
9198   ierr = MatFactorUpdateSchurStatus_Private(F);CHKERRQ(ierr);
9199   PetscFunctionReturn(0);
9200 }
9201 
9202 /*@
9203   MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step
9204 
9205    Logically Collective on Mat
9206 
9207    Input Parameters:
9208 +  F - the factored matrix obtained by calling MatGetFactor()
9209 .  rhs - location where the right hand side of the Schur complement system is stored
9210 -  sol - location where the solution of the Schur complement system has to be returned
9211 
9212    Notes:
9213    The sizes of the vectors should match the size of the Schur complement
9214 
9215    Must be called after MatFactorSetSchurIS()
9216 
9217    Level: advanced
9218 
9219    References:
9220 
9221 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplement()
9222 @*/
9223 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol)
9224 {
9225   PetscErrorCode ierr;
9226 
9227   PetscFunctionBegin;
9228   PetscValidType(F,1);
9229   PetscValidType(rhs,2);
9230   PetscValidType(sol,3);
9231   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9232   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
9233   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
9234   PetscCheckSameComm(F,1,rhs,2);
9235   PetscCheckSameComm(F,1,sol,3);
9236   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9237   switch (F->schur_status) {
9238   case MAT_FACTOR_SCHUR_FACTORED:
9239     ierr = MatSolveTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
9240     break;
9241   case MAT_FACTOR_SCHUR_INVERTED:
9242     ierr = MatMultTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
9243     break;
9244   default:
9245     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9246     break;
9247   }
9248   PetscFunctionReturn(0);
9249 }
9250 
9251 /*@
9252   MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step
9253 
9254    Logically Collective on Mat
9255 
9256    Input Parameters:
9257 +  F - the factored matrix obtained by calling MatGetFactor()
9258 .  rhs - location where the right hand side of the Schur complement system is stored
9259 -  sol - location where the solution of the Schur complement system has to be returned
9260 
9261    Notes:
9262    The sizes of the vectors should match the size of the Schur complement
9263 
9264    Must be called after MatFactorSetSchurIS()
9265 
9266    Level: advanced
9267 
9268    References:
9269 
9270 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplementTranspose()
9271 @*/
9272 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol)
9273 {
9274   PetscErrorCode ierr;
9275 
9276   PetscFunctionBegin;
9277   PetscValidType(F,1);
9278   PetscValidType(rhs,2);
9279   PetscValidType(sol,3);
9280   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9281   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
9282   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
9283   PetscCheckSameComm(F,1,rhs,2);
9284   PetscCheckSameComm(F,1,sol,3);
9285   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9286   switch (F->schur_status) {
9287   case MAT_FACTOR_SCHUR_FACTORED:
9288     ierr = MatSolve(F->schur,rhs,sol);CHKERRQ(ierr);
9289     break;
9290   case MAT_FACTOR_SCHUR_INVERTED:
9291     ierr = MatMult(F->schur,rhs,sol);CHKERRQ(ierr);
9292     break;
9293   default:
9294     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9295     break;
9296   }
9297   PetscFunctionReturn(0);
9298 }
9299 
9300 /*@
9301   MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step
9302 
9303    Logically Collective on Mat
9304 
9305    Input Parameters:
9306 +  F - the factored matrix obtained by calling MatGetFactor()
9307 
9308    Notes:
9309     Must be called after MatFactorSetSchurIS().
9310 
9311    Call MatFactorGetSchurComplement() or  MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it.
9312 
9313    Level: advanced
9314 
9315    References:
9316 
9317 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorCreateSchurComplement()
9318 @*/
9319 PetscErrorCode MatFactorInvertSchurComplement(Mat F)
9320 {
9321   PetscErrorCode ierr;
9322 
9323   PetscFunctionBegin;
9324   PetscValidType(F,1);
9325   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9326   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0);
9327   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9328   ierr = MatFactorInvertSchurComplement_Private(F);CHKERRQ(ierr);
9329   F->schur_status = MAT_FACTOR_SCHUR_INVERTED;
9330   PetscFunctionReturn(0);
9331 }
9332 
9333 /*@
9334   MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step
9335 
9336    Logically Collective on Mat
9337 
9338    Input Parameters:
9339 +  F - the factored matrix obtained by calling MatGetFactor()
9340 
9341    Notes:
9342     Must be called after MatFactorSetSchurIS().
9343 
9344    Level: advanced
9345 
9346    References:
9347 
9348 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorInvertSchurComplement()
9349 @*/
9350 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F)
9351 {
9352   PetscErrorCode ierr;
9353 
9354   PetscFunctionBegin;
9355   PetscValidType(F,1);
9356   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9357   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0);
9358   ierr = MatFactorFactorizeSchurComplement_Private(F);CHKERRQ(ierr);
9359   F->schur_status = MAT_FACTOR_SCHUR_FACTORED;
9360   PetscFunctionReturn(0);
9361 }
9362 
9363 /*@
9364    MatPtAP - Creates the matrix product C = P^T * A * P
9365 
9366    Neighbor-wise Collective on Mat
9367 
9368    Input Parameters:
9369 +  A - the matrix
9370 .  P - the projection matrix
9371 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9372 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate
9373           if the result is a dense matrix this is irrelevent
9374 
9375    Output Parameters:
9376 .  C - the product matrix
9377 
9378    Notes:
9379    C will be created and must be destroyed by the user with MatDestroy().
9380 
9381    This routine is currently only implemented for pairs of sequential dense matrices, AIJ matrices and classes
9382    which inherit from AIJ.
9383 
9384    Level: intermediate
9385 
9386 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
9387 @*/
9388 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
9389 {
9390   PetscErrorCode ierr;
9391   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9392   PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
9393   PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9394   PetscBool      sametype;
9395 
9396   PetscFunctionBegin;
9397   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9398   PetscValidType(A,1);
9399   MatCheckPreallocated(A,1);
9400   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9401   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9402   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9403   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9404   PetscValidType(P,2);
9405   MatCheckPreallocated(P,2);
9406   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9407   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9408 
9409   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);
9410   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);
9411   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9412   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9413 
9414   if (scall == MAT_REUSE_MATRIX) {
9415     PetscValidPointer(*C,5);
9416     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9417 
9418     if (!(*C)->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You cannot use MAT_REUSE_MATRIX");
9419     ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9420     ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9421     ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr);
9422     ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9423     ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9424     PetscFunctionReturn(0);
9425   }
9426 
9427   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9428   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9429 
9430   fA = A->ops->ptap;
9431   fP = P->ops->ptap;
9432   ierr = PetscStrcmp(((PetscObject)A)->type_name,((PetscObject)P)->type_name,&sametype);CHKERRQ(ierr);
9433   if (fP == fA && sametype) {
9434     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name);
9435     ptap = fA;
9436   } else {
9437     /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
9438     char ptapname[256];
9439     ierr = PetscStrncpy(ptapname,"MatPtAP_",sizeof(ptapname));CHKERRQ(ierr);
9440     ierr = PetscStrlcat(ptapname,((PetscObject)A)->type_name,sizeof(ptapname));CHKERRQ(ierr);
9441     ierr = PetscStrlcat(ptapname,"_",sizeof(ptapname));CHKERRQ(ierr);
9442     ierr = PetscStrlcat(ptapname,((PetscObject)P)->type_name,sizeof(ptapname));CHKERRQ(ierr);
9443     ierr = PetscStrlcat(ptapname,"_C",sizeof(ptapname));CHKERRQ(ierr); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
9444     ierr = PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);CHKERRQ(ierr);
9445     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);
9446   }
9447 
9448   ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9449   ierr = (*ptap)(A,P,scall,fill,C);CHKERRQ(ierr);
9450   ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9451   if (A->symmetric_set && A->symmetric) {
9452     ierr = MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
9453   }
9454   PetscFunctionReturn(0);
9455 }
9456 
9457 /*@
9458    MatPtAPNumeric - Computes the matrix product C = P^T * A * P
9459 
9460    Neighbor-wise Collective on Mat
9461 
9462    Input Parameters:
9463 +  A - the matrix
9464 -  P - the projection matrix
9465 
9466    Output Parameters:
9467 .  C - the product matrix
9468 
9469    Notes:
9470    C must have been created by calling MatPtAPSymbolic and must be destroyed by
9471    the user using MatDeatroy().
9472 
9473    This routine is currently only implemented for pairs of AIJ matrices and classes
9474    which inherit from AIJ.  C will be of type MATAIJ.
9475 
9476    Level: intermediate
9477 
9478 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
9479 @*/
9480 PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C)
9481 {
9482   PetscErrorCode ierr;
9483 
9484   PetscFunctionBegin;
9485   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9486   PetscValidType(A,1);
9487   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9488   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9489   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9490   PetscValidType(P,2);
9491   MatCheckPreallocated(P,2);
9492   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9493   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9494   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9495   PetscValidType(C,3);
9496   MatCheckPreallocated(C,3);
9497   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9498   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);
9499   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);
9500   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);
9501   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);
9502   MatCheckPreallocated(A,1);
9503 
9504   if (!C->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You should call MatPtAPSymbolic first");
9505   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9506   ierr = (*C->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr);
9507   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9508   PetscFunctionReturn(0);
9509 }
9510 
9511 /*@
9512    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P
9513 
9514    Neighbor-wise Collective on Mat
9515 
9516    Input Parameters:
9517 +  A - the matrix
9518 -  P - the projection matrix
9519 
9520    Output Parameters:
9521 .  C - the (i,j) structure of the product matrix
9522 
9523    Notes:
9524    C will be created and must be destroyed by the user with MatDestroy().
9525 
9526    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9527    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9528    this (i,j) structure by calling MatPtAPNumeric().
9529 
9530    Level: intermediate
9531 
9532 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
9533 @*/
9534 PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
9535 {
9536   PetscErrorCode ierr;
9537 
9538   PetscFunctionBegin;
9539   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9540   PetscValidType(A,1);
9541   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9542   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9543   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9544   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9545   PetscValidType(P,2);
9546   MatCheckPreallocated(P,2);
9547   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9548   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9549   PetscValidPointer(C,3);
9550 
9551   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);
9552   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);
9553   MatCheckPreallocated(A,1);
9554 
9555   if (!A->ops->ptapsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatType %s",((PetscObject)A)->type_name);
9556   ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
9557   ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr);
9558   ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
9559 
9560   /* ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); NO! this is not always true -ma */
9561   PetscFunctionReturn(0);
9562 }
9563 
9564 /*@
9565    MatRARt - Creates the matrix product C = R * A * R^T
9566 
9567    Neighbor-wise Collective on Mat
9568 
9569    Input Parameters:
9570 +  A - the matrix
9571 .  R - the projection matrix
9572 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9573 -  fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate
9574           if the result is a dense matrix this is irrelevent
9575 
9576    Output Parameters:
9577 .  C - the product matrix
9578 
9579    Notes:
9580    C will be created and must be destroyed by the user with MatDestroy().
9581 
9582    This routine is currently only implemented for pairs of AIJ matrices and classes
9583    which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes,
9584    parallel MatRARt is implemented via explicit transpose of R, which could be very expensive.
9585    We recommend using MatPtAP().
9586 
9587    Level: intermediate
9588 
9589 .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
9590 @*/
9591 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
9592 {
9593   PetscErrorCode ierr;
9594 
9595   PetscFunctionBegin;
9596   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9597   PetscValidType(A,1);
9598   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9599   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9600   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9601   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9602   PetscValidType(R,2);
9603   MatCheckPreallocated(R,2);
9604   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9605   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9606   PetscValidPointer(C,3);
9607   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);
9608 
9609   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9610   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9611   MatCheckPreallocated(A,1);
9612 
9613   if (!A->ops->rart) {
9614     Mat Rt;
9615     ierr = MatTranspose(R,MAT_INITIAL_MATRIX,&Rt);CHKERRQ(ierr);
9616     ierr = MatMatMatMult(R,A,Rt,scall,fill,C);CHKERRQ(ierr);
9617     ierr = MatDestroy(&Rt);CHKERRQ(ierr);
9618     PetscFunctionReturn(0);
9619   }
9620   ierr = PetscLogEventBegin(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
9621   ierr = (*A->ops->rart)(A,R,scall,fill,C);CHKERRQ(ierr);
9622   ierr = PetscLogEventEnd(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
9623   PetscFunctionReturn(0);
9624 }
9625 
9626 /*@
9627    MatRARtNumeric - Computes the matrix product C = R * A * R^T
9628 
9629    Neighbor-wise Collective on Mat
9630 
9631    Input Parameters:
9632 +  A - the matrix
9633 -  R - the projection matrix
9634 
9635    Output Parameters:
9636 .  C - the product matrix
9637 
9638    Notes:
9639    C must have been created by calling MatRARtSymbolic and must be destroyed by
9640    the user using MatDestroy().
9641 
9642    This routine is currently only implemented for pairs of AIJ matrices and classes
9643    which inherit from AIJ.  C will be of type MATAIJ.
9644 
9645    Level: intermediate
9646 
9647 .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
9648 @*/
9649 PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C)
9650 {
9651   PetscErrorCode ierr;
9652 
9653   PetscFunctionBegin;
9654   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9655   PetscValidType(A,1);
9656   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9657   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9658   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9659   PetscValidType(R,2);
9660   MatCheckPreallocated(R,2);
9661   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9662   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9663   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9664   PetscValidType(C,3);
9665   MatCheckPreallocated(C,3);
9666   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9667   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);
9668   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);
9669   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);
9670   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);
9671   MatCheckPreallocated(A,1);
9672 
9673   ierr = PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
9674   ierr = (*A->ops->rartnumeric)(A,R,C);CHKERRQ(ierr);
9675   ierr = PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
9676   PetscFunctionReturn(0);
9677 }
9678 
9679 /*@
9680    MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T
9681 
9682    Neighbor-wise Collective on Mat
9683 
9684    Input Parameters:
9685 +  A - the matrix
9686 -  R - the projection matrix
9687 
9688    Output Parameters:
9689 .  C - the (i,j) structure of the product matrix
9690 
9691    Notes:
9692    C will be created and must be destroyed by the user with MatDestroy().
9693 
9694    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9695    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9696    this (i,j) structure by calling MatRARtNumeric().
9697 
9698    Level: intermediate
9699 
9700 .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
9701 @*/
9702 PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
9703 {
9704   PetscErrorCode ierr;
9705 
9706   PetscFunctionBegin;
9707   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9708   PetscValidType(A,1);
9709   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9710   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9711   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9712   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9713   PetscValidType(R,2);
9714   MatCheckPreallocated(R,2);
9715   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9716   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9717   PetscValidPointer(C,3);
9718 
9719   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);
9720   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);
9721   MatCheckPreallocated(A,1);
9722   ierr = PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
9723   ierr = (*A->ops->rartsymbolic)(A,R,fill,C);CHKERRQ(ierr);
9724   ierr = PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
9725 
9726   ierr = MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));CHKERRQ(ierr);
9727   PetscFunctionReturn(0);
9728 }
9729 
9730 /*@
9731    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
9732 
9733    Neighbor-wise Collective on Mat
9734 
9735    Input Parameters:
9736 +  A - the left matrix
9737 .  B - the right matrix
9738 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9739 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
9740           if the result is a dense matrix this is irrelevent
9741 
9742    Output Parameters:
9743 .  C - the product matrix
9744 
9745    Notes:
9746    Unless scall is MAT_REUSE_MATRIX C will be created.
9747 
9748    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
9749    call to this function with either MAT_INITIAL_MATRIX or MatMatMultSymbolic()
9750 
9751    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9752    actually needed.
9753 
9754    If you have many matrices with the same non-zero structure to multiply, you
9755    should either
9756 $   1) use MAT_REUSE_MATRIX in all calls but the first or
9757 $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
9758    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
9759    with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse.
9760 
9761    Level: intermediate
9762 
9763 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(),  MatMatTransposeMult(), MatPtAP()
9764 @*/
9765 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9766 {
9767   PetscErrorCode ierr;
9768   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9769   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9770   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9771 
9772   PetscFunctionBegin;
9773   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9774   PetscValidType(A,1);
9775   MatCheckPreallocated(A,1);
9776   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9777   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9778   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9779   PetscValidType(B,2);
9780   MatCheckPreallocated(B,2);
9781   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9782   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9783   PetscValidPointer(C,3);
9784   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9785   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);
9786   if (scall == MAT_REUSE_MATRIX) {
9787     PetscValidPointer(*C,5);
9788     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9789     ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9790     ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9791     ierr = (*(*C)->ops->matmultnumeric)(A,B,*C);CHKERRQ(ierr);
9792     ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9793     ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9794     PetscFunctionReturn(0);
9795   }
9796   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9797   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9798 
9799   fA = A->ops->matmult;
9800   fB = B->ops->matmult;
9801   if (fB == fA) {
9802     if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
9803     mult = fB;
9804   } else {
9805     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9806     char multname[256];
9807     ierr = PetscStrncpy(multname,"MatMatMult_",sizeof(multname));CHKERRQ(ierr);
9808     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
9809     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
9810     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
9811     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9812     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
9813     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);
9814   }
9815   ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9816   ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr);
9817   ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9818   PetscFunctionReturn(0);
9819 }
9820 
9821 /*@
9822    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
9823    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().
9824 
9825    Neighbor-wise Collective on Mat
9826 
9827    Input Parameters:
9828 +  A - the left matrix
9829 .  B - the right matrix
9830 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
9831       if C is a dense matrix this is irrelevent
9832 
9833    Output Parameters:
9834 .  C - the product matrix
9835 
9836    Notes:
9837    Unless scall is MAT_REUSE_MATRIX C will be created.
9838 
9839    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9840    actually needed.
9841 
9842    This routine is currently implemented for
9843     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
9844     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9845     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9846 
9847    Level: intermediate
9848 
9849    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
9850      We should incorporate them into PETSc.
9851 
9852 .seealso: MatMatMult(), MatMatMultNumeric()
9853 @*/
9854 PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
9855 {
9856   PetscErrorCode ierr;
9857   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*);
9858   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*);
9859   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL;
9860 
9861   PetscFunctionBegin;
9862   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9863   PetscValidType(A,1);
9864   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9865   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9866 
9867   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9868   PetscValidType(B,2);
9869   MatCheckPreallocated(B,2);
9870   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9871   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9872   PetscValidPointer(C,3);
9873 
9874   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);
9875   if (fill == PETSC_DEFAULT) fill = 2.0;
9876   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9877   MatCheckPreallocated(A,1);
9878 
9879   Asymbolic = A->ops->matmultsymbolic;
9880   Bsymbolic = B->ops->matmultsymbolic;
9881   if (Asymbolic == Bsymbolic) {
9882     if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
9883     symbolic = Bsymbolic;
9884   } else { /* dispatch based on the type of A and B */
9885     char symbolicname[256];
9886     ierr = PetscStrncpy(symbolicname,"MatMatMultSymbolic_",sizeof(symbolicname));CHKERRQ(ierr);
9887     ierr = PetscStrlcat(symbolicname,((PetscObject)A)->type_name,sizeof(symbolicname));CHKERRQ(ierr);
9888     ierr = PetscStrlcat(symbolicname,"_",sizeof(symbolicname));CHKERRQ(ierr);
9889     ierr = PetscStrlcat(symbolicname,((PetscObject)B)->type_name,sizeof(symbolicname));CHKERRQ(ierr);
9890     ierr = PetscStrlcat(symbolicname,"_C",sizeof(symbolicname));CHKERRQ(ierr);
9891     ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);CHKERRQ(ierr);
9892     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);
9893   }
9894   ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9895   ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr);
9896   ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9897   PetscFunctionReturn(0);
9898 }
9899 
9900 /*@
9901    MatMatMultNumeric - Performs the numeric matrix-matrix product.
9902    Call this routine after first calling MatMatMultSymbolic().
9903 
9904    Neighbor-wise Collective on Mat
9905 
9906    Input Parameters:
9907 +  A - the left matrix
9908 -  B - the right matrix
9909 
9910    Output Parameters:
9911 .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
9912 
9913    Notes:
9914    C must have been created with MatMatMultSymbolic().
9915 
9916    This routine is currently implemented for
9917     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
9918     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9919     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9920 
9921    Level: intermediate
9922 
9923 .seealso: MatMatMult(), MatMatMultSymbolic()
9924 @*/
9925 PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C)
9926 {
9927   PetscErrorCode ierr;
9928 
9929   PetscFunctionBegin;
9930   ierr = MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);CHKERRQ(ierr);
9931   PetscFunctionReturn(0);
9932 }
9933 
9934 /*@
9935    MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.
9936 
9937    Neighbor-wise Collective on Mat
9938 
9939    Input Parameters:
9940 +  A - the left matrix
9941 .  B - the right matrix
9942 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9943 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9944 
9945    Output Parameters:
9946 .  C - the product matrix
9947 
9948    Notes:
9949    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9950 
9951    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9952 
9953   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9954    actually needed.
9955 
9956    This routine is currently only implemented for pairs of SeqAIJ matrices, for the SeqDense class,
9957    and for pairs of MPIDense matrices.
9958 
9959    Options Database Keys:
9960 +  -matmattransmult_mpidense_mpidense_via {allgatherv,cyclic} - Choose between algorthims for MPIDense matrices: the
9961                                                                 first redundantly copies the transposed B matrix on each process and requiers O(log P) communication complexity;
9962                                                                 the second never stores more than one portion of the B matrix at a time by requires O(P) communication complexity.
9963 
9964    Level: intermediate
9965 
9966 .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
9967 @*/
9968 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9969 {
9970   PetscErrorCode ierr;
9971   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9972   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9973 
9974   PetscFunctionBegin;
9975   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9976   PetscValidType(A,1);
9977   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9978   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9979   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9980   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9981   PetscValidType(B,2);
9982   MatCheckPreallocated(B,2);
9983   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9984   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9985   PetscValidPointer(C,3);
9986   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);
9987   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9988   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9989   MatCheckPreallocated(A,1);
9990 
9991   fA = A->ops->mattransposemult;
9992   if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
9993   fB = B->ops->mattransposemult;
9994   if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
9995   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);
9996 
9997   ierr = PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
9998   if (scall == MAT_INITIAL_MATRIX) {
9999     ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
10000     ierr = (*A->ops->mattransposemultsymbolic)(A,B,fill,C);CHKERRQ(ierr);
10001     ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
10002   }
10003   ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
10004   ierr = (*A->ops->mattransposemultnumeric)(A,B,*C);CHKERRQ(ierr);
10005   ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
10006   ierr = PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
10007   PetscFunctionReturn(0);
10008 }
10009 
10010 /*@
10011    MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.
10012 
10013    Neighbor-wise Collective on Mat
10014 
10015    Input Parameters:
10016 +  A - the left matrix
10017 .  B - the right matrix
10018 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10019 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
10020 
10021    Output Parameters:
10022 .  C - the product matrix
10023 
10024    Notes:
10025    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
10026 
10027    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
10028 
10029   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
10030    actually needed.
10031 
10032    This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
10033    which inherit from SeqAIJ.  C will be of same type as the input matrices.
10034 
10035    Level: intermediate
10036 
10037 .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
10038 @*/
10039 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
10040 {
10041   PetscErrorCode ierr;
10042   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
10043   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
10044   PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL;
10045 
10046   PetscFunctionBegin;
10047   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
10048   PetscValidType(A,1);
10049   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10050   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10051   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10052   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
10053   PetscValidType(B,2);
10054   MatCheckPreallocated(B,2);
10055   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10056   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10057   PetscValidPointer(C,3);
10058   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);
10059   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
10060   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
10061   MatCheckPreallocated(A,1);
10062 
10063   fA = A->ops->transposematmult;
10064   fB = B->ops->transposematmult;
10065   if (fB==fA) {
10066     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
10067     transposematmult = fA;
10068   } else {
10069     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
10070     char multname[256];
10071     ierr = PetscStrncpy(multname,"MatTransposeMatMult_",sizeof(multname));CHKERRQ(ierr);
10072     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
10073     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
10074     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
10075     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
10076     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);CHKERRQ(ierr);
10077     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);
10078   }
10079   ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
10080   ierr = (*transposematmult)(A,B,scall,fill,C);CHKERRQ(ierr);
10081   ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
10082   PetscFunctionReturn(0);
10083 }
10084 
10085 /*@
10086    MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.
10087 
10088    Neighbor-wise Collective on Mat
10089 
10090    Input Parameters:
10091 +  A - the left matrix
10092 .  B - the middle matrix
10093 .  C - the right matrix
10094 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10095 -  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
10096           if the result is a dense matrix this is irrelevent
10097 
10098    Output Parameters:
10099 .  D - the product matrix
10100 
10101    Notes:
10102    Unless scall is MAT_REUSE_MATRIX D will be created.
10103 
10104    MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call
10105 
10106    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
10107    actually needed.
10108 
10109    If you have many matrices with the same non-zero structure to multiply, you
10110    should use MAT_REUSE_MATRIX in all calls but the first or
10111 
10112    Level: intermediate
10113 
10114 .seealso: MatMatMult, MatPtAP()
10115 @*/
10116 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
10117 {
10118   PetscErrorCode ierr;
10119   PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
10120   PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
10121   PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
10122   PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
10123 
10124   PetscFunctionBegin;
10125   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
10126   PetscValidType(A,1);
10127   MatCheckPreallocated(A,1);
10128   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10129   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10130   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10131   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
10132   PetscValidType(B,2);
10133   MatCheckPreallocated(B,2);
10134   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10135   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10136   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
10137   PetscValidPointer(C,3);
10138   MatCheckPreallocated(C,3);
10139   if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10140   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10141   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);
10142   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);
10143   if (scall == MAT_REUSE_MATRIX) {
10144     PetscValidPointer(*D,6);
10145     PetscValidHeaderSpecific(*D,MAT_CLASSID,6);
10146     ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10147     ierr = (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
10148     ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10149     PetscFunctionReturn(0);
10150   }
10151   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
10152   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
10153 
10154   fA = A->ops->matmatmult;
10155   fB = B->ops->matmatmult;
10156   fC = C->ops->matmatmult;
10157   if (fA == fB && fA == fC) {
10158     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name);
10159     mult = fA;
10160   } else {
10161     /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */
10162     char multname[256];
10163     ierr = PetscStrncpy(multname,"MatMatMatMult_",sizeof(multname));CHKERRQ(ierr);
10164     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
10165     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
10166     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
10167     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
10168     ierr = PetscStrlcat(multname,((PetscObject)C)->type_name,sizeof(multname));CHKERRQ(ierr);
10169     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr);
10170     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
10171     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);
10172   }
10173   ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10174   ierr = (*mult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
10175   ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10176   PetscFunctionReturn(0);
10177 }
10178 
10179 /*@
10180    MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
10181 
10182    Collective on Mat
10183 
10184    Input Parameters:
10185 +  mat - the matrix
10186 .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
10187 .  subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used)
10188 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10189 
10190    Output Parameter:
10191 .  matredundant - redundant matrix
10192 
10193    Notes:
10194    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
10195    original matrix has not changed from that last call to MatCreateRedundantMatrix().
10196 
10197    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
10198    calling it.
10199 
10200    Level: advanced
10201 
10202    Concepts: subcommunicator
10203    Concepts: duplicate matrix
10204 
10205 .seealso: MatDestroy()
10206 @*/
10207 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant)
10208 {
10209   PetscErrorCode ierr;
10210   MPI_Comm       comm;
10211   PetscMPIInt    size;
10212   PetscInt       mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs;
10213   Mat_Redundant  *redund=NULL;
10214   PetscSubcomm   psubcomm=NULL;
10215   MPI_Comm       subcomm_in=subcomm;
10216   Mat            *matseq;
10217   IS             isrow,iscol;
10218   PetscBool      newsubcomm=PETSC_FALSE;
10219 
10220   PetscFunctionBegin;
10221   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10222   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
10223     PetscValidPointer(*matredundant,5);
10224     PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5);
10225   }
10226 
10227   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
10228   if (size == 1 || nsubcomm == 1) {
10229     if (reuse == MAT_INITIAL_MATRIX) {
10230       ierr = MatDuplicate(mat,MAT_COPY_VALUES,matredundant);CHKERRQ(ierr);
10231     } else {
10232       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");
10233       ierr = MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
10234     }
10235     PetscFunctionReturn(0);
10236   }
10237 
10238   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10239   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10240   MatCheckPreallocated(mat,1);
10241 
10242   ierr = PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
10243   if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */
10244     /* create psubcomm, then get subcomm */
10245     ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
10246     ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
10247     if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size);
10248 
10249     ierr = PetscSubcommCreate(comm,&psubcomm);CHKERRQ(ierr);
10250     ierr = PetscSubcommSetNumber(psubcomm,nsubcomm);CHKERRQ(ierr);
10251     ierr = PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);CHKERRQ(ierr);
10252     ierr = PetscSubcommSetFromOptions(psubcomm);CHKERRQ(ierr);
10253     ierr = PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);CHKERRQ(ierr);
10254     newsubcomm = PETSC_TRUE;
10255     ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr);
10256   }
10257 
10258   /* get isrow, iscol and a local sequential matrix matseq[0] */
10259   if (reuse == MAT_INITIAL_MATRIX) {
10260     mloc_sub = PETSC_DECIDE;
10261     nloc_sub = PETSC_DECIDE;
10262     if (bs < 1) {
10263       ierr = PetscSplitOwnership(subcomm,&mloc_sub,&M);CHKERRQ(ierr);
10264       ierr = PetscSplitOwnership(subcomm,&nloc_sub,&N);CHKERRQ(ierr);
10265     } else {
10266       ierr = PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);CHKERRQ(ierr);
10267       ierr = PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N);CHKERRQ(ierr);
10268     }
10269     ierr = MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);CHKERRQ(ierr);
10270     rstart = rend - mloc_sub;
10271     ierr = ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);CHKERRQ(ierr);
10272     ierr = ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);CHKERRQ(ierr);
10273   } else { /* reuse == MAT_REUSE_MATRIX */
10274     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");
10275     /* retrieve subcomm */
10276     ierr = PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);CHKERRQ(ierr);
10277     redund = (*matredundant)->redundant;
10278     isrow  = redund->isrow;
10279     iscol  = redund->iscol;
10280     matseq = redund->matseq;
10281   }
10282   ierr = MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);CHKERRQ(ierr);
10283 
10284   /* get matredundant over subcomm */
10285   if (reuse == MAT_INITIAL_MATRIX) {
10286     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant);CHKERRQ(ierr);
10287 
10288     /* create a supporting struct and attach it to C for reuse */
10289     ierr = PetscNewLog(*matredundant,&redund);CHKERRQ(ierr);
10290     (*matredundant)->redundant = redund;
10291     redund->isrow              = isrow;
10292     redund->iscol              = iscol;
10293     redund->matseq             = matseq;
10294     if (newsubcomm) {
10295       redund->subcomm          = subcomm;
10296     } else {
10297       redund->subcomm          = MPI_COMM_NULL;
10298     }
10299   } else {
10300     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);CHKERRQ(ierr);
10301   }
10302   ierr = PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
10303   PetscFunctionReturn(0);
10304 }
10305 
10306 /*@C
10307    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
10308    a given 'mat' object. Each submatrix can span multiple procs.
10309 
10310    Collective on Mat
10311 
10312    Input Parameters:
10313 +  mat - the matrix
10314 .  subcomm - the subcommunicator obtained by com_split(comm)
10315 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10316 
10317    Output Parameter:
10318 .  subMat - 'parallel submatrices each spans a given subcomm
10319 
10320   Notes:
10321   The submatrix partition across processors is dictated by 'subComm' a
10322   communicator obtained by com_split(comm). The comm_split
10323   is not restriced to be grouped with consecutive original ranks.
10324 
10325   Due the comm_split() usage, the parallel layout of the submatrices
10326   map directly to the layout of the original matrix [wrt the local
10327   row,col partitioning]. So the original 'DiagonalMat' naturally maps
10328   into the 'DiagonalMat' of the subMat, hence it is used directly from
10329   the subMat. However the offDiagMat looses some columns - and this is
10330   reconstructed with MatSetValues()
10331 
10332   Level: advanced
10333 
10334   Concepts: subcommunicator
10335   Concepts: submatrices
10336 
10337 .seealso: MatCreateSubMatrices()
10338 @*/
10339 PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
10340 {
10341   PetscErrorCode ierr;
10342   PetscMPIInt    commsize,subCommSize;
10343 
10344   PetscFunctionBegin;
10345   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRQ(ierr);
10346   ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr);
10347   if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
10348 
10349   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");
10350   ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10351   ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr);
10352   ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10353   PetscFunctionReturn(0);
10354 }
10355 
10356 /*@
10357    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
10358 
10359    Not Collective
10360 
10361    Input Arguments:
10362    mat - matrix to extract local submatrix from
10363    isrow - local row indices for submatrix
10364    iscol - local column indices for submatrix
10365 
10366    Output Arguments:
10367    submat - the submatrix
10368 
10369    Level: intermediate
10370 
10371    Notes:
10372    The submat should be returned with MatRestoreLocalSubMatrix().
10373 
10374    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
10375    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
10376 
10377    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
10378    MatSetValuesBlockedLocal() will also be implemented.
10379 
10380    The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that
10381    matrices obtained with DMCreateMatrix() generally already have the local to global mapping provided.
10382 
10383 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping()
10384 @*/
10385 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10386 {
10387   PetscErrorCode ierr;
10388 
10389   PetscFunctionBegin;
10390   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10391   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10392   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10393   PetscCheckSameComm(isrow,2,iscol,3);
10394   PetscValidPointer(submat,4);
10395   if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call");
10396 
10397   if (mat->ops->getlocalsubmatrix) {
10398     ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10399   } else {
10400     ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr);
10401   }
10402   PetscFunctionReturn(0);
10403 }
10404 
10405 /*@
10406    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
10407 
10408    Not Collective
10409 
10410    Input Arguments:
10411    mat - matrix to extract local submatrix from
10412    isrow - local row indices for submatrix
10413    iscol - local column indices for submatrix
10414    submat - the submatrix
10415 
10416    Level: intermediate
10417 
10418 .seealso: MatGetLocalSubMatrix()
10419 @*/
10420 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10421 {
10422   PetscErrorCode ierr;
10423 
10424   PetscFunctionBegin;
10425   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10426   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10427   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10428   PetscCheckSameComm(isrow,2,iscol,3);
10429   PetscValidPointer(submat,4);
10430   if (*submat) {
10431     PetscValidHeaderSpecific(*submat,MAT_CLASSID,4);
10432   }
10433 
10434   if (mat->ops->restorelocalsubmatrix) {
10435     ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10436   } else {
10437     ierr = MatDestroy(submat);CHKERRQ(ierr);
10438   }
10439   *submat = NULL;
10440   PetscFunctionReturn(0);
10441 }
10442 
10443 /* --------------------------------------------------------*/
10444 /*@
10445    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix
10446 
10447    Collective on Mat
10448 
10449    Input Parameter:
10450 .  mat - the matrix
10451 
10452    Output Parameter:
10453 .  is - if any rows have zero diagonals this contains the list of them
10454 
10455    Level: developer
10456 
10457    Concepts: matrix-vector product
10458 
10459 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10460 @*/
10461 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is)
10462 {
10463   PetscErrorCode ierr;
10464 
10465   PetscFunctionBegin;
10466   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10467   PetscValidType(mat,1);
10468   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10469   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10470 
10471   if (!mat->ops->findzerodiagonals) {
10472     Vec                diag;
10473     const PetscScalar *a;
10474     PetscInt          *rows;
10475     PetscInt           rStart, rEnd, r, nrow = 0;
10476 
10477     ierr = MatCreateVecs(mat, &diag, NULL);CHKERRQ(ierr);
10478     ierr = MatGetDiagonal(mat, diag);CHKERRQ(ierr);
10479     ierr = MatGetOwnershipRange(mat, &rStart, &rEnd);CHKERRQ(ierr);
10480     ierr = VecGetArrayRead(diag, &a);CHKERRQ(ierr);
10481     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow;
10482     ierr = PetscMalloc1(nrow, &rows);CHKERRQ(ierr);
10483     nrow = 0;
10484     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart;
10485     ierr = VecRestoreArrayRead(diag, &a);CHKERRQ(ierr);
10486     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10487     ierr = ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);CHKERRQ(ierr);
10488   } else {
10489     ierr = (*mat->ops->findzerodiagonals)(mat, is);CHKERRQ(ierr);
10490   }
10491   PetscFunctionReturn(0);
10492 }
10493 
10494 /*@
10495    MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size)
10496 
10497    Collective on Mat
10498 
10499    Input Parameter:
10500 .  mat - the matrix
10501 
10502    Output Parameter:
10503 .  is - contains the list of rows with off block diagonal entries
10504 
10505    Level: developer
10506 
10507    Concepts: matrix-vector product
10508 
10509 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10510 @*/
10511 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is)
10512 {
10513   PetscErrorCode ierr;
10514 
10515   PetscFunctionBegin;
10516   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10517   PetscValidType(mat,1);
10518   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10519   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10520 
10521   if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined");
10522   ierr = (*mat->ops->findoffblockdiagonalentries)(mat,is);CHKERRQ(ierr);
10523   PetscFunctionReturn(0);
10524 }
10525 
10526 /*@C
10527   MatInvertBlockDiagonal - Inverts the block diagonal entries.
10528 
10529   Collective on Mat
10530 
10531   Input Parameters:
10532 . mat - the matrix
10533 
10534   Output Parameters:
10535 . values - the block inverses in column major order (FORTRAN-like)
10536 
10537    Note:
10538    This routine is not available from Fortran.
10539 
10540   Level: advanced
10541 
10542 .seealso: MatInvertBockDiagonalMat
10543 @*/
10544 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
10545 {
10546   PetscErrorCode ierr;
10547 
10548   PetscFunctionBegin;
10549   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10550   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10551   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10552   if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
10553   ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr);
10554   PetscFunctionReturn(0);
10555 }
10556 
10557 /*@C
10558   MatInvertVariableBlockDiagonal - Inverts the block diagonal entries.
10559 
10560   Collective on Mat
10561 
10562   Input Parameters:
10563 + mat - the matrix
10564 . nblocks - the number of blocks
10565 - bsizes - the size of each block
10566 
10567   Output Parameters:
10568 . values - the block inverses in column major order (FORTRAN-like)
10569 
10570    Note:
10571    This routine is not available from Fortran.
10572 
10573   Level: advanced
10574 
10575 .seealso: MatInvertBockDiagonal()
10576 @*/
10577 PetscErrorCode MatInvertVariableBlockDiagonal(Mat mat,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *values)
10578 {
10579   PetscErrorCode ierr;
10580 
10581   PetscFunctionBegin;
10582   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10583   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10584   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10585   if (!mat->ops->invertvariableblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
10586   ierr = (*mat->ops->invertvariableblockdiagonal)(mat,nblocks,bsizes,values);CHKERRQ(ierr);
10587   PetscFunctionReturn(0);
10588 }
10589 
10590 /*@
10591   MatInvertBlockDiagonalMat - set matrix C to be the inverted block diagonal of matrix A
10592 
10593   Collective on Mat
10594 
10595   Input Parameters:
10596 . A - the matrix
10597 
10598   Output Parameters:
10599 . C - matrix with inverted block diagonal of A.  This matrix should be created and may have its type set.
10600 
10601   Notes: the blocksize of the matrix is used to determine the blocks on the diagonal of C
10602 
10603   Level: advanced
10604 
10605 .seealso: MatInvertBockDiagonal()
10606 @*/
10607 PetscErrorCode MatInvertBlockDiagonalMat(Mat A,Mat C)
10608 {
10609   PetscErrorCode     ierr;
10610   const PetscScalar *vals;
10611   PetscInt          *dnnz;
10612   PetscInt           M,N,m,n,rstart,rend,bs,i,j;
10613 
10614   PetscFunctionBegin;
10615   ierr = MatInvertBlockDiagonal(A,&vals);CHKERRQ(ierr);
10616   ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr);
10617   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
10618   ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr);
10619   ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr);
10620   ierr = MatSetBlockSize(C,bs);CHKERRQ(ierr);
10621   ierr = PetscMalloc1(m/bs,&dnnz);CHKERRQ(ierr);
10622   for (j = 0; j < m/bs; j++) dnnz[j] = 1;
10623   ierr = MatXAIJSetPreallocation(C,bs,dnnz,NULL,NULL,NULL);CHKERRQ(ierr);
10624   ierr = PetscFree(dnnz);CHKERRQ(ierr);
10625   ierr = MatGetOwnershipRange(C,&rstart,&rend);CHKERRQ(ierr);
10626   ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr);
10627   for (i = rstart/bs; i < rend/bs; i++) {
10628     ierr = MatSetValuesBlocked(C,1,&i,1,&i,&vals[(i-rstart/bs)*bs*bs],INSERT_VALUES);CHKERRQ(ierr);
10629   }
10630   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10631   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10632   ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr);
10633   PetscFunctionReturn(0);
10634 }
10635 
10636 /*@C
10637     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
10638     via MatTransposeColoringCreate().
10639 
10640     Collective on MatTransposeColoring
10641 
10642     Input Parameter:
10643 .   c - coloring context
10644 
10645     Level: intermediate
10646 
10647 .seealso: MatTransposeColoringCreate()
10648 @*/
10649 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c)
10650 {
10651   PetscErrorCode       ierr;
10652   MatTransposeColoring matcolor=*c;
10653 
10654   PetscFunctionBegin;
10655   if (!matcolor) PetscFunctionReturn(0);
10656   if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; PetscFunctionReturn(0);}
10657 
10658   ierr = PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);CHKERRQ(ierr);
10659   ierr = PetscFree(matcolor->rows);CHKERRQ(ierr);
10660   ierr = PetscFree(matcolor->den2sp);CHKERRQ(ierr);
10661   ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr);
10662   ierr = PetscFree(matcolor->columns);CHKERRQ(ierr);
10663   if (matcolor->brows>0) {
10664     ierr = PetscFree(matcolor->lstart);CHKERRQ(ierr);
10665   }
10666   ierr = PetscHeaderDestroy(c);CHKERRQ(ierr);
10667   PetscFunctionReturn(0);
10668 }
10669 
10670 /*@C
10671     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
10672     a MatTransposeColoring context has been created, computes a dense B^T by Apply
10673     MatTransposeColoring to sparse B.
10674 
10675     Collective on MatTransposeColoring
10676 
10677     Input Parameters:
10678 +   B - sparse matrix B
10679 .   Btdense - symbolic dense matrix B^T
10680 -   coloring - coloring context created with MatTransposeColoringCreate()
10681 
10682     Output Parameter:
10683 .   Btdense - dense matrix B^T
10684 
10685     Level: advanced
10686 
10687      Notes:
10688     These are used internally for some implementations of MatRARt()
10689 
10690 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplyDenToSp()
10691 
10692 .keywords: coloring
10693 @*/
10694 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
10695 {
10696   PetscErrorCode ierr;
10697 
10698   PetscFunctionBegin;
10699   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
10700   PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2);
10701   PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3);
10702 
10703   if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
10704   ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr);
10705   PetscFunctionReturn(0);
10706 }
10707 
10708 /*@C
10709     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
10710     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
10711     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
10712     Csp from Cden.
10713 
10714     Collective on MatTransposeColoring
10715 
10716     Input Parameters:
10717 +   coloring - coloring context created with MatTransposeColoringCreate()
10718 -   Cden - matrix product of a sparse matrix and a dense matrix Btdense
10719 
10720     Output Parameter:
10721 .   Csp - sparse matrix
10722 
10723     Level: advanced
10724 
10725      Notes:
10726     These are used internally for some implementations of MatRARt()
10727 
10728 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()
10729 
10730 .keywords: coloring
10731 @*/
10732 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
10733 {
10734   PetscErrorCode ierr;
10735 
10736   PetscFunctionBegin;
10737   PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1);
10738   PetscValidHeaderSpecific(Cden,MAT_CLASSID,2);
10739   PetscValidHeaderSpecific(Csp,MAT_CLASSID,3);
10740 
10741   if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
10742   ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr);
10743   PetscFunctionReturn(0);
10744 }
10745 
10746 /*@C
10747    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.
10748 
10749    Collective on Mat
10750 
10751    Input Parameters:
10752 +  mat - the matrix product C
10753 -  iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring()
10754 
10755     Output Parameter:
10756 .   color - the new coloring context
10757 
10758     Level: intermediate
10759 
10760 .seealso: MatTransposeColoringDestroy(),  MatTransColoringApplySpToDen(),
10761            MatTransColoringApplyDenToSp()
10762 @*/
10763 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
10764 {
10765   MatTransposeColoring c;
10766   MPI_Comm             comm;
10767   PetscErrorCode       ierr;
10768 
10769   PetscFunctionBegin;
10770   ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10771   ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
10772   ierr = PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);CHKERRQ(ierr);
10773 
10774   c->ctype = iscoloring->ctype;
10775   if (mat->ops->transposecoloringcreate) {
10776     ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr);
10777   } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type");
10778 
10779   *color = c;
10780   ierr   = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10781   PetscFunctionReturn(0);
10782 }
10783 
10784 /*@
10785       MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the
10786         matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the
10787         same, otherwise it will be larger
10788 
10789      Not Collective
10790 
10791   Input Parameter:
10792 .    A  - the matrix
10793 
10794   Output Parameter:
10795 .    state - the current state
10796 
10797   Notes:
10798     You can only compare states from two different calls to the SAME matrix, you cannot compare calls between
10799          different matrices
10800 
10801   Level: intermediate
10802 
10803 @*/
10804 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state)
10805 {
10806   PetscFunctionBegin;
10807   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10808   *state = mat->nonzerostate;
10809   PetscFunctionReturn(0);
10810 }
10811 
10812 /*@
10813       MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential
10814                  matrices from each processor
10815 
10816     Collective on MPI_Comm
10817 
10818    Input Parameters:
10819 +    comm - the communicators the parallel matrix will live on
10820 .    seqmat - the input sequential matrices
10821 .    n - number of local columns (or PETSC_DECIDE)
10822 -    reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10823 
10824    Output Parameter:
10825 .    mpimat - the parallel matrix generated
10826 
10827     Level: advanced
10828 
10829    Notes:
10830     The number of columns of the matrix in EACH processor MUST be the same.
10831 
10832 @*/
10833 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat)
10834 {
10835   PetscErrorCode ierr;
10836 
10837   PetscFunctionBegin;
10838   if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name);
10839   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");
10840 
10841   ierr = PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10842   ierr = (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);CHKERRQ(ierr);
10843   ierr = PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10844   PetscFunctionReturn(0);
10845 }
10846 
10847 /*@
10848      MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent
10849                  ranks' ownership ranges.
10850 
10851     Collective on A
10852 
10853    Input Parameters:
10854 +    A   - the matrix to create subdomains from
10855 -    N   - requested number of subdomains
10856 
10857 
10858    Output Parameters:
10859 +    n   - number of subdomains resulting on this rank
10860 -    iss - IS list with indices of subdomains on this rank
10861 
10862     Level: advanced
10863 
10864     Notes:
10865     number of subdomains must be smaller than the communicator size
10866 @*/
10867 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[])
10868 {
10869   MPI_Comm        comm,subcomm;
10870   PetscMPIInt     size,rank,color;
10871   PetscInt        rstart,rend,k;
10872   PetscErrorCode  ierr;
10873 
10874   PetscFunctionBegin;
10875   ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr);
10876   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
10877   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
10878   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);
10879   *n = 1;
10880   k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */
10881   color = rank/k;
10882   ierr = MPI_Comm_split(comm,color,rank,&subcomm);CHKERRQ(ierr);
10883   ierr = PetscMalloc1(1,iss);CHKERRQ(ierr);
10884   ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
10885   ierr = ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);CHKERRQ(ierr);
10886   ierr = MPI_Comm_free(&subcomm);CHKERRQ(ierr);
10887   PetscFunctionReturn(0);
10888 }
10889 
10890 /*@
10891    MatGalerkin - Constructs the coarse grid problem via Galerkin projection.
10892 
10893    If the interpolation and restriction operators are the same, uses MatPtAP.
10894    If they are not the same, use MatMatMatMult.
10895 
10896    Once the coarse grid problem is constructed, correct for interpolation operators
10897    that are not of full rank, which can legitimately happen in the case of non-nested
10898    geometric multigrid.
10899 
10900    Input Parameters:
10901 +  restrct - restriction operator
10902 .  dA - fine grid matrix
10903 .  interpolate - interpolation operator
10904 .  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10905 -  fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate
10906 
10907    Output Parameters:
10908 .  A - the Galerkin coarse matrix
10909 
10910    Options Database Key:
10911 .  -pc_mg_galerkin <both,pmat,mat,none>
10912 
10913    Level: developer
10914 
10915 .keywords: MG, multigrid, Galerkin
10916 
10917 .seealso: MatPtAP(), MatMatMatMult()
10918 @*/
10919 PetscErrorCode  MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A)
10920 {
10921   PetscErrorCode ierr;
10922   IS             zerorows;
10923   Vec            diag;
10924 
10925   PetscFunctionBegin;
10926   if (reuse == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10927   /* Construct the coarse grid matrix */
10928   if (interpolate == restrct) {
10929     ierr = MatPtAP(dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10930   } else {
10931     ierr = MatMatMatMult(restrct,dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10932   }
10933 
10934   /* If the interpolation matrix is not of full rank, A will have zero rows.
10935      This can legitimately happen in the case of non-nested geometric multigrid.
10936      In that event, we set the rows of the matrix to the rows of the identity,
10937      ignoring the equations (as the RHS will also be zero). */
10938 
10939   ierr = MatFindZeroRows(*A, &zerorows);CHKERRQ(ierr);
10940 
10941   if (zerorows != NULL) { /* if there are any zero rows */
10942     ierr = MatCreateVecs(*A, &diag, NULL);CHKERRQ(ierr);
10943     ierr = MatGetDiagonal(*A, diag);CHKERRQ(ierr);
10944     ierr = VecISSet(diag, zerorows, 1.0);CHKERRQ(ierr);
10945     ierr = MatDiagonalSet(*A, diag, INSERT_VALUES);CHKERRQ(ierr);
10946     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10947     ierr = ISDestroy(&zerorows);CHKERRQ(ierr);
10948   }
10949   PetscFunctionReturn(0);
10950 }
10951 
10952 /*@C
10953     MatSetOperation - Allows user to set a matrix operation for any matrix type
10954 
10955    Logically Collective on Mat
10956 
10957     Input Parameters:
10958 +   mat - the matrix
10959 .   op - the name of the operation
10960 -   f - the function that provides the operation
10961 
10962    Level: developer
10963 
10964     Usage:
10965 $      extern PetscErrorCode usermult(Mat,Vec,Vec);
10966 $      ierr = MatCreateXXX(comm,...&A);
10967 $      ierr = MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult);
10968 
10969     Notes:
10970     See the file include/petscmat.h for a complete list of matrix
10971     operations, which all have the form MATOP_<OPERATION>, where
10972     <OPERATION> is the name (in all capital letters) of the
10973     user interface routine (e.g., MatMult() -> MATOP_MULT).
10974 
10975     All user-provided functions (except for MATOP_DESTROY) should have the same calling
10976     sequence as the usual matrix interface routines, since they
10977     are intended to be accessed via the usual matrix interface
10978     routines, e.g.,
10979 $       MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec)
10980 
10981     In particular each function MUST return an error code of 0 on success and
10982     nonzero on failure.
10983 
10984     This routine is distinct from MatShellSetOperation() in that it can be called on any matrix type.
10985 
10986 .keywords: matrix, set, operation
10987 
10988 .seealso: MatGetOperation(), MatCreateShell(), MatShellSetContext(), MatShellSetOperation()
10989 @*/
10990 PetscErrorCode MatSetOperation(Mat mat,MatOperation op,void (*f)(void))
10991 {
10992   PetscFunctionBegin;
10993   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10994   if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) {
10995     mat->ops->viewnative = mat->ops->view;
10996   }
10997   (((void(**)(void))mat->ops)[op]) = f;
10998   PetscFunctionReturn(0);
10999 }
11000 
11001 /*@C
11002     MatGetOperation - Gets a matrix operation for any matrix type.
11003 
11004     Not Collective
11005 
11006     Input Parameters:
11007 +   mat - the matrix
11008 -   op - the name of the operation
11009 
11010     Output Parameter:
11011 .   f - the function that provides the operation
11012 
11013     Level: developer
11014 
11015     Usage:
11016 $      PetscErrorCode (*usermult)(Mat,Vec,Vec);
11017 $      ierr = MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult);
11018 
11019     Notes:
11020     See the file include/petscmat.h for a complete list of matrix
11021     operations, which all have the form MATOP_<OPERATION>, where
11022     <OPERATION> is the name (in all capital letters) of the
11023     user interface routine (e.g., MatMult() -> MATOP_MULT).
11024 
11025     This routine is distinct from MatShellGetOperation() in that it can be called on any matrix type.
11026 
11027 .keywords: matrix, get, operation
11028 
11029 .seealso: MatSetOperation(), MatCreateShell(), MatShellGetContext(), MatShellGetOperation()
11030 @*/
11031 PetscErrorCode MatGetOperation(Mat mat,MatOperation op,void(**f)(void))
11032 {
11033   PetscFunctionBegin;
11034   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
11035   *f = (((void (**)(void))mat->ops)[op]);
11036   PetscFunctionReturn(0);
11037 }
11038 
11039 /*@
11040     MatHasOperation - Determines whether the given matrix supports the particular
11041     operation.
11042 
11043    Not Collective
11044 
11045    Input Parameters:
11046 +  mat - the matrix
11047 -  op - the operation, for example, MATOP_GET_DIAGONAL
11048 
11049    Output Parameter:
11050 .  has - either PETSC_TRUE or PETSC_FALSE
11051 
11052    Level: advanced
11053 
11054    Notes:
11055    See the file include/petscmat.h for a complete list of matrix
11056    operations, which all have the form MATOP_<OPERATION>, where
11057    <OPERATION> is the name (in all capital letters) of the
11058    user-level routine.  E.g., MatNorm() -> MATOP_NORM.
11059 
11060 .keywords: matrix, has, operation
11061 
11062 .seealso: MatCreateShell()
11063 @*/
11064 PetscErrorCode MatHasOperation(Mat mat,MatOperation op,PetscBool *has)
11065 {
11066   PetscErrorCode ierr;
11067 
11068   PetscFunctionBegin;
11069   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
11070   PetscValidType(mat,1);
11071   PetscValidPointer(has,3);
11072   if (mat->ops->hasoperation) {
11073     ierr = (*mat->ops->hasoperation)(mat,op,has);CHKERRQ(ierr);
11074   } else {
11075     if (((void**)mat->ops)[op]) *has =  PETSC_TRUE;
11076     else {
11077       *has = PETSC_FALSE;
11078       if (op == MATOP_CREATE_SUBMATRIX) {
11079         PetscMPIInt size;
11080 
11081         ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
11082         if (size == 1) {
11083           ierr = MatHasOperation(mat,MATOP_CREATE_SUBMATRICES,has);CHKERRQ(ierr);
11084         }
11085       }
11086     }
11087   }
11088   PetscFunctionReturn(0);
11089 }
11090 
11091 /*@
11092     MatHasCongruentLayouts - Determines whether the rows and columns layouts
11093     of the matrix are congruent
11094 
11095    Collective on mat
11096 
11097    Input Parameters:
11098 .  mat - the matrix
11099 
11100    Output Parameter:
11101 .  cong - either PETSC_TRUE or PETSC_FALSE
11102 
11103    Level: beginner
11104 
11105    Notes:
11106 
11107 .keywords: matrix, has
11108 
11109 .seealso: MatCreate(), MatSetSizes()
11110 @*/
11111 PetscErrorCode MatHasCongruentLayouts(Mat mat,PetscBool *cong)
11112 {
11113   PetscErrorCode ierr;
11114 
11115   PetscFunctionBegin;
11116   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
11117   PetscValidType(mat,1);
11118   PetscValidPointer(cong,2);
11119   if (!mat->rmap || !mat->cmap) {
11120     *cong = mat->rmap == mat->cmap ? PETSC_TRUE : PETSC_FALSE;
11121     PetscFunctionReturn(0);
11122   }
11123   if (mat->congruentlayouts == PETSC_DECIDE) { /* first time we compare rows and cols layouts */
11124     ierr = PetscLayoutCompare(mat->rmap,mat->cmap,cong);CHKERRQ(ierr);
11125     if (*cong) mat->congruentlayouts = 1;
11126     else       mat->congruentlayouts = 0;
11127   } else *cong = mat->congruentlayouts ? PETSC_TRUE : PETSC_FALSE;
11128   PetscFunctionReturn(0);
11129 }
11130 
11131 /*@
11132     MatFreeIntermediateDataStructures - Free intermediate data structures created for reuse,
11133     e.g., matrx product of MatPtAP.
11134 
11135    Collective on mat
11136 
11137    Input Parameters:
11138 .  mat - the matrix
11139 
11140    Output Parameter:
11141 .  mat - the matrix with intermediate data structures released
11142 
11143    Level: advanced
11144 
11145    Notes:
11146 
11147 .keywords: matrix
11148 
11149 .seealso: MatPtAP(), MatMatMult()
11150 @*/
11151 PetscErrorCode MatFreeIntermediateDataStructures(Mat mat)
11152 {
11153   PetscErrorCode ierr;
11154 
11155   PetscFunctionBegin;
11156   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
11157   PetscValidType(mat,1);
11158   if (mat->ops->freeintermediatedatastructures) {
11159     ierr = (*mat->ops->freeintermediatedatastructures)(mat);CHKERRQ(ierr);
11160   }
11161   PetscFunctionReturn(0);
11162 }
11163