xref: /petsc/src/mat/interface/matrix.c (revision 5afd8efcc1874d90de966124faaa87a5a5b2b947)
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->subsetoffprocentries = flg;
5604     PetscFunctionReturn(0);
5605   case MAT_NO_OFF_PROC_ZERO_ROWS:
5606     mat->nooffproczerorows = flg;
5607     PetscFunctionReturn(0);
5608     break;
5609   case MAT_SPD:
5610     mat->spd_set = PETSC_TRUE;
5611     mat->spd     = flg;
5612     if (flg) {
5613       mat->symmetric                  = PETSC_TRUE;
5614       mat->structurally_symmetric     = PETSC_TRUE;
5615       mat->symmetric_set              = PETSC_TRUE;
5616       mat->structurally_symmetric_set = PETSC_TRUE;
5617     }
5618     break;
5619   case MAT_SYMMETRIC:
5620     mat->symmetric = flg;
5621     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5622     mat->symmetric_set              = PETSC_TRUE;
5623     mat->structurally_symmetric_set = flg;
5624 #if !defined(PETSC_USE_COMPLEX)
5625     mat->hermitian     = flg;
5626     mat->hermitian_set = PETSC_TRUE;
5627 #endif
5628     break;
5629   case MAT_HERMITIAN:
5630     mat->hermitian = flg;
5631     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5632     mat->hermitian_set              = PETSC_TRUE;
5633     mat->structurally_symmetric_set = flg;
5634 #if !defined(PETSC_USE_COMPLEX)
5635     mat->symmetric     = flg;
5636     mat->symmetric_set = PETSC_TRUE;
5637 #endif
5638     break;
5639   case MAT_STRUCTURALLY_SYMMETRIC:
5640     mat->structurally_symmetric     = flg;
5641     mat->structurally_symmetric_set = PETSC_TRUE;
5642     break;
5643   case MAT_SYMMETRY_ETERNAL:
5644     mat->symmetric_eternal = flg;
5645     break;
5646   case MAT_STRUCTURE_ONLY:
5647     mat->structure_only = flg;
5648     break;
5649   default:
5650     break;
5651   }
5652   if (mat->ops->setoption) {
5653     ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr);
5654   }
5655   PetscFunctionReturn(0);
5656 }
5657 
5658 /*@
5659    MatGetOption - Gets a parameter option that has been set for a matrix.
5660 
5661    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5662 
5663    Input Parameters:
5664 +  mat - the matrix
5665 -  option - the option, this only responds to certain options, check the code for which ones
5666 
5667    Output Parameter:
5668 .  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5669 
5670     Notes:
5671     Can only be called after MatSetSizes() and MatSetType() have been set.
5672 
5673    Level: intermediate
5674 
5675    Concepts: matrices^setting options
5676 
5677 .seealso:  MatOption, MatSetOption()
5678 
5679 @*/
5680 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg)
5681 {
5682   PetscFunctionBegin;
5683   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5684   PetscValidType(mat,1);
5685 
5686   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);
5687   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()");
5688 
5689   switch (op) {
5690   case MAT_NO_OFF_PROC_ENTRIES:
5691     *flg = mat->nooffprocentries;
5692     break;
5693   case MAT_NO_OFF_PROC_ZERO_ROWS:
5694     *flg = mat->nooffproczerorows;
5695     break;
5696   case MAT_SYMMETRIC:
5697     *flg = mat->symmetric;
5698     break;
5699   case MAT_HERMITIAN:
5700     *flg = mat->hermitian;
5701     break;
5702   case MAT_STRUCTURALLY_SYMMETRIC:
5703     *flg = mat->structurally_symmetric;
5704     break;
5705   case MAT_SYMMETRY_ETERNAL:
5706     *flg = mat->symmetric_eternal;
5707     break;
5708   case MAT_SPD:
5709     *flg = mat->spd;
5710     break;
5711   default:
5712     break;
5713   }
5714   PetscFunctionReturn(0);
5715 }
5716 
5717 /*@
5718    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5719    this routine retains the old nonzero structure.
5720 
5721    Logically Collective on Mat
5722 
5723    Input Parameters:
5724 .  mat - the matrix
5725 
5726    Level: intermediate
5727 
5728    Notes:
5729     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.
5730    See the Performance chapter of the users manual for information on preallocating matrices.
5731 
5732    Concepts: matrices^zeroing
5733 
5734 .seealso: MatZeroRows()
5735 @*/
5736 PetscErrorCode MatZeroEntries(Mat mat)
5737 {
5738   PetscErrorCode ierr;
5739 
5740   PetscFunctionBegin;
5741   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5742   PetscValidType(mat,1);
5743   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5744   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");
5745   if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5746   MatCheckPreallocated(mat,1);
5747 
5748   ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5749   ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
5750   ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5751   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5752 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5753   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5754     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5755   }
5756 #endif
5757   PetscFunctionReturn(0);
5758 }
5759 
5760 /*@
5761    MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal)
5762    of a set of rows and columns of a matrix.
5763 
5764    Collective on Mat
5765 
5766    Input Parameters:
5767 +  mat - the matrix
5768 .  numRows - the number of rows to remove
5769 .  rows - the global row indices
5770 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5771 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5772 -  b - optional vector of right hand side, that will be adjusted by provided solution
5773 
5774    Notes:
5775    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5776 
5777    The user can set a value in the diagonal entry (or for the AIJ and
5778    row formats can optionally remove the main diagonal entry from the
5779    nonzero structure as well, by passing 0.0 as the final argument).
5780 
5781    For the parallel case, all processes that share the matrix (i.e.,
5782    those in the communicator used for matrix creation) MUST call this
5783    routine, regardless of whether any rows being zeroed are owned by
5784    them.
5785 
5786    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5787    list only rows local to itself).
5788 
5789    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5790 
5791    Level: intermediate
5792 
5793    Concepts: matrices^zeroing rows
5794 
5795 .seealso: MatZeroRowsIS(), MatZeroRows(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5796           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5797 @*/
5798 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5799 {
5800   PetscErrorCode ierr;
5801 
5802   PetscFunctionBegin;
5803   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5804   PetscValidType(mat,1);
5805   if (numRows) PetscValidIntPointer(rows,3);
5806   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5807   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5808   if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5809   MatCheckPreallocated(mat,1);
5810 
5811   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5812   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5813   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5814 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5815   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5816     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5817   }
5818 #endif
5819   PetscFunctionReturn(0);
5820 }
5821 
5822 /*@
5823    MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
5824    of a set of rows and columns of a matrix.
5825 
5826    Collective on Mat
5827 
5828    Input Parameters:
5829 +  mat - the matrix
5830 .  is - the rows to zero
5831 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5832 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5833 -  b - optional vector of right hand side, that will be adjusted by provided solution
5834 
5835    Notes:
5836    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5837 
5838    The user can set a value in the diagonal entry (or for the AIJ and
5839    row formats can optionally remove the main diagonal entry from the
5840    nonzero structure as well, by passing 0.0 as the final argument).
5841 
5842    For the parallel case, all processes that share the matrix (i.e.,
5843    those in the communicator used for matrix creation) MUST call this
5844    routine, regardless of whether any rows being zeroed are owned by
5845    them.
5846 
5847    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5848    list only rows local to itself).
5849 
5850    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5851 
5852    Level: intermediate
5853 
5854    Concepts: matrices^zeroing rows
5855 
5856 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5857           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRows(), MatZeroRowsColumnsStencil()
5858 @*/
5859 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5860 {
5861   PetscErrorCode ierr;
5862   PetscInt       numRows;
5863   const PetscInt *rows;
5864 
5865   PetscFunctionBegin;
5866   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5867   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5868   PetscValidType(mat,1);
5869   PetscValidType(is,2);
5870   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5871   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5872   ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5873   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5874   PetscFunctionReturn(0);
5875 }
5876 
5877 /*@
5878    MatZeroRows - Zeros all entries (except possibly the main diagonal)
5879    of a set of rows of a matrix.
5880 
5881    Collective on Mat
5882 
5883    Input Parameters:
5884 +  mat - the matrix
5885 .  numRows - the number of rows to remove
5886 .  rows - the global row indices
5887 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5888 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5889 -  b - optional vector of right hand side, that will be adjusted by provided solution
5890 
5891    Notes:
5892    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5893    but does not release memory.  For the dense and block diagonal
5894    formats this does not alter the nonzero structure.
5895 
5896    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5897    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5898    merely zeroed.
5899 
5900    The user can set a value in the diagonal entry (or for the AIJ and
5901    row formats can optionally remove the main diagonal entry from the
5902    nonzero structure as well, by passing 0.0 as the final argument).
5903 
5904    For the parallel case, all processes that share the matrix (i.e.,
5905    those in the communicator used for matrix creation) MUST call this
5906    routine, regardless of whether any rows being zeroed are owned by
5907    them.
5908 
5909    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5910    list only rows local to itself).
5911 
5912    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5913    owns that are to be zeroed. This saves a global synchronization in the implementation.
5914 
5915    Level: intermediate
5916 
5917    Concepts: matrices^zeroing rows
5918 
5919 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5920           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5921 @*/
5922 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5923 {
5924   PetscErrorCode ierr;
5925 
5926   PetscFunctionBegin;
5927   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5928   PetscValidType(mat,1);
5929   if (numRows) PetscValidIntPointer(rows,3);
5930   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5931   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5932   if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5933   MatCheckPreallocated(mat,1);
5934 
5935   ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5936   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5937   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5938 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5939   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5940     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5941   }
5942 #endif
5943   PetscFunctionReturn(0);
5944 }
5945 
5946 /*@
5947    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5948    of a set of rows of a matrix.
5949 
5950    Collective on Mat
5951 
5952    Input Parameters:
5953 +  mat - the matrix
5954 .  is - index set of rows to remove
5955 .  diag - value put in all diagonals of eliminated rows
5956 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5957 -  b - optional vector of right hand side, that will be adjusted by provided solution
5958 
5959    Notes:
5960    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5961    but does not release memory.  For the dense and block diagonal
5962    formats this does not alter the nonzero structure.
5963 
5964    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5965    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5966    merely zeroed.
5967 
5968    The user can set a value in the diagonal entry (or for the AIJ and
5969    row formats can optionally remove the main diagonal entry from the
5970    nonzero structure as well, by passing 0.0 as the final argument).
5971 
5972    For the parallel case, all processes that share the matrix (i.e.,
5973    those in the communicator used for matrix creation) MUST call this
5974    routine, regardless of whether any rows being zeroed are owned by
5975    them.
5976 
5977    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5978    list only rows local to itself).
5979 
5980    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5981    owns that are to be zeroed. This saves a global synchronization in the implementation.
5982 
5983    Level: intermediate
5984 
5985    Concepts: matrices^zeroing rows
5986 
5987 .seealso: MatZeroRows(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5988           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5989 @*/
5990 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5991 {
5992   PetscInt       numRows;
5993   const PetscInt *rows;
5994   PetscErrorCode ierr;
5995 
5996   PetscFunctionBegin;
5997   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5998   PetscValidType(mat,1);
5999   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6000   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6001   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6002   ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6003   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6004   PetscFunctionReturn(0);
6005 }
6006 
6007 /*@
6008    MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
6009    of a set of rows of a matrix. These rows must be local to the process.
6010 
6011    Collective on Mat
6012 
6013    Input Parameters:
6014 +  mat - the matrix
6015 .  numRows - the number of rows to remove
6016 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
6017 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
6018 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6019 -  b - optional vector of right hand side, that will be adjusted by provided solution
6020 
6021    Notes:
6022    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
6023    but does not release memory.  For the dense and block diagonal
6024    formats this does not alter the nonzero structure.
6025 
6026    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6027    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6028    merely zeroed.
6029 
6030    The user can set a value in the diagonal entry (or for the AIJ and
6031    row formats can optionally remove the main diagonal entry from the
6032    nonzero structure as well, by passing 0.0 as the final argument).
6033 
6034    For the parallel case, all processes that share the matrix (i.e.,
6035    those in the communicator used for matrix creation) MUST call this
6036    routine, regardless of whether any rows being zeroed are owned by
6037    them.
6038 
6039    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
6040    list only rows local to itself).
6041 
6042    The grid coordinates are across the entire grid, not just the local portion
6043 
6044    In Fortran idxm and idxn should be declared as
6045 $     MatStencil idxm(4,m)
6046    and the values inserted using
6047 $    idxm(MatStencil_i,1) = i
6048 $    idxm(MatStencil_j,1) = j
6049 $    idxm(MatStencil_k,1) = k
6050 $    idxm(MatStencil_c,1) = c
6051    etc
6052 
6053    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
6054    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
6055    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
6056    DM_BOUNDARY_PERIODIC boundary type.
6057 
6058    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
6059    a single value per point) you can skip filling those indices.
6060 
6061    Level: intermediate
6062 
6063    Concepts: matrices^zeroing rows
6064 
6065 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsl(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6066           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6067 @*/
6068 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
6069 {
6070   PetscInt       dim     = mat->stencil.dim;
6071   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
6072   PetscInt       *dims   = mat->stencil.dims+1;
6073   PetscInt       *starts = mat->stencil.starts;
6074   PetscInt       *dxm    = (PetscInt*) rows;
6075   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
6076   PetscErrorCode ierr;
6077 
6078   PetscFunctionBegin;
6079   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6080   PetscValidType(mat,1);
6081   if (numRows) PetscValidIntPointer(rows,3);
6082 
6083   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
6084   for (i = 0; i < numRows; ++i) {
6085     /* Skip unused dimensions (they are ordered k, j, i, c) */
6086     for (j = 0; j < 3-sdim; ++j) dxm++;
6087     /* Local index in X dir */
6088     tmp = *dxm++ - starts[0];
6089     /* Loop over remaining dimensions */
6090     for (j = 0; j < dim-1; ++j) {
6091       /* If nonlocal, set index to be negative */
6092       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6093       /* Update local index */
6094       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6095     }
6096     /* Skip component slot if necessary */
6097     if (mat->stencil.noc) dxm++;
6098     /* Local row number */
6099     if (tmp >= 0) {
6100       jdxm[numNewRows++] = tmp;
6101     }
6102   }
6103   ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
6104   ierr = PetscFree(jdxm);CHKERRQ(ierr);
6105   PetscFunctionReturn(0);
6106 }
6107 
6108 /*@
6109    MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal)
6110    of a set of rows and columns of a matrix.
6111 
6112    Collective on Mat
6113 
6114    Input Parameters:
6115 +  mat - the matrix
6116 .  numRows - the number of rows/columns to remove
6117 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
6118 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
6119 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6120 -  b - optional vector of right hand side, that will be adjusted by provided solution
6121 
6122    Notes:
6123    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
6124    but does not release memory.  For the dense and block diagonal
6125    formats this does not alter the nonzero structure.
6126 
6127    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6128    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6129    merely zeroed.
6130 
6131    The user can set a value in the diagonal entry (or for the AIJ and
6132    row formats can optionally remove the main diagonal entry from the
6133    nonzero structure as well, by passing 0.0 as the final argument).
6134 
6135    For the parallel case, all processes that share the matrix (i.e.,
6136    those in the communicator used for matrix creation) MUST call this
6137    routine, regardless of whether any rows being zeroed are owned by
6138    them.
6139 
6140    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
6141    list only rows local to itself, but the row/column numbers are given in local numbering).
6142 
6143    The grid coordinates are across the entire grid, not just the local portion
6144 
6145    In Fortran idxm and idxn should be declared as
6146 $     MatStencil idxm(4,m)
6147    and the values inserted using
6148 $    idxm(MatStencil_i,1) = i
6149 $    idxm(MatStencil_j,1) = j
6150 $    idxm(MatStencil_k,1) = k
6151 $    idxm(MatStencil_c,1) = c
6152    etc
6153 
6154    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
6155    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
6156    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
6157    DM_BOUNDARY_PERIODIC boundary type.
6158 
6159    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
6160    a single value per point) you can skip filling those indices.
6161 
6162    Level: intermediate
6163 
6164    Concepts: matrices^zeroing rows
6165 
6166 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6167           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRows()
6168 @*/
6169 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
6170 {
6171   PetscInt       dim     = mat->stencil.dim;
6172   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
6173   PetscInt       *dims   = mat->stencil.dims+1;
6174   PetscInt       *starts = mat->stencil.starts;
6175   PetscInt       *dxm    = (PetscInt*) rows;
6176   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
6177   PetscErrorCode ierr;
6178 
6179   PetscFunctionBegin;
6180   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6181   PetscValidType(mat,1);
6182   if (numRows) PetscValidIntPointer(rows,3);
6183 
6184   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
6185   for (i = 0; i < numRows; ++i) {
6186     /* Skip unused dimensions (they are ordered k, j, i, c) */
6187     for (j = 0; j < 3-sdim; ++j) dxm++;
6188     /* Local index in X dir */
6189     tmp = *dxm++ - starts[0];
6190     /* Loop over remaining dimensions */
6191     for (j = 0; j < dim-1; ++j) {
6192       /* If nonlocal, set index to be negative */
6193       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6194       /* Update local index */
6195       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6196     }
6197     /* Skip component slot if necessary */
6198     if (mat->stencil.noc) dxm++;
6199     /* Local row number */
6200     if (tmp >= 0) {
6201       jdxm[numNewRows++] = tmp;
6202     }
6203   }
6204   ierr = MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
6205   ierr = PetscFree(jdxm);CHKERRQ(ierr);
6206   PetscFunctionReturn(0);
6207 }
6208 
6209 /*@C
6210    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
6211    of a set of rows of a matrix; using local numbering of rows.
6212 
6213    Collective on Mat
6214 
6215    Input Parameters:
6216 +  mat - the matrix
6217 .  numRows - the number of rows to remove
6218 .  rows - the global row indices
6219 .  diag - value put in all diagonals of eliminated rows
6220 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6221 -  b - optional vector of right hand side, that will be adjusted by provided solution
6222 
6223    Notes:
6224    Before calling MatZeroRowsLocal(), the user must first set the
6225    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6226 
6227    For the AIJ matrix formats this removes the old nonzero structure,
6228    but does not release memory.  For the dense and block diagonal
6229    formats this does not alter the nonzero structure.
6230 
6231    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6232    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6233    merely zeroed.
6234 
6235    The user can set a value in the diagonal entry (or for the AIJ and
6236    row formats can optionally remove the main diagonal entry from the
6237    nonzero structure as well, by passing 0.0 as the final argument).
6238 
6239    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6240    owns that are to be zeroed. This saves a global synchronization in the implementation.
6241 
6242    Level: intermediate
6243 
6244    Concepts: matrices^zeroing
6245 
6246 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRows(), MatSetOption(),
6247           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6248 @*/
6249 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6250 {
6251   PetscErrorCode ierr;
6252 
6253   PetscFunctionBegin;
6254   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6255   PetscValidType(mat,1);
6256   if (numRows) PetscValidIntPointer(rows,3);
6257   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6258   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6259   MatCheckPreallocated(mat,1);
6260 
6261   if (mat->ops->zerorowslocal) {
6262     ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6263   } else {
6264     IS             is, newis;
6265     const PetscInt *newRows;
6266 
6267     if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6268     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6269     ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr);
6270     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6271     ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6272     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6273     ierr = ISDestroy(&newis);CHKERRQ(ierr);
6274     ierr = ISDestroy(&is);CHKERRQ(ierr);
6275   }
6276   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6277 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
6278   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
6279     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
6280   }
6281 #endif
6282   PetscFunctionReturn(0);
6283 }
6284 
6285 /*@
6286    MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
6287    of a set of rows of a matrix; using local numbering of rows.
6288 
6289    Collective on Mat
6290 
6291    Input Parameters:
6292 +  mat - the matrix
6293 .  is - index set of rows to remove
6294 .  diag - value put in all diagonals of eliminated rows
6295 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6296 -  b - optional vector of right hand side, that will be adjusted by provided solution
6297 
6298    Notes:
6299    Before calling MatZeroRowsLocalIS(), the user must first set the
6300    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6301 
6302    For the AIJ matrix formats this removes the old nonzero structure,
6303    but does not release memory.  For the dense and block diagonal
6304    formats this does not alter the nonzero structure.
6305 
6306    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6307    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6308    merely zeroed.
6309 
6310    The user can set a value in the diagonal entry (or for the AIJ and
6311    row formats can optionally remove the main diagonal entry from the
6312    nonzero structure as well, by passing 0.0 as the final argument).
6313 
6314    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6315    owns that are to be zeroed. This saves a global synchronization in the implementation.
6316 
6317    Level: intermediate
6318 
6319    Concepts: matrices^zeroing
6320 
6321 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6322           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6323 @*/
6324 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6325 {
6326   PetscErrorCode ierr;
6327   PetscInt       numRows;
6328   const PetscInt *rows;
6329 
6330   PetscFunctionBegin;
6331   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6332   PetscValidType(mat,1);
6333   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6334   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6335   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6336   MatCheckPreallocated(mat,1);
6337 
6338   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6339   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6340   ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6341   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6342   PetscFunctionReturn(0);
6343 }
6344 
6345 /*@
6346    MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
6347    of a set of rows and columns of a matrix; using local numbering of rows.
6348 
6349    Collective on Mat
6350 
6351    Input Parameters:
6352 +  mat - the matrix
6353 .  numRows - the number of rows to remove
6354 .  rows - the global row indices
6355 .  diag - value put in all diagonals of eliminated rows
6356 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6357 -  b - optional vector of right hand side, that will be adjusted by provided solution
6358 
6359    Notes:
6360    Before calling MatZeroRowsColumnsLocal(), the user must first set the
6361    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6362 
6363    The user can set a value in the diagonal entry (or for the AIJ and
6364    row formats can optionally remove the main diagonal entry from the
6365    nonzero structure as well, by passing 0.0 as the final argument).
6366 
6367    Level: intermediate
6368 
6369    Concepts: matrices^zeroing
6370 
6371 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6372           MatZeroRows(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6373 @*/
6374 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6375 {
6376   PetscErrorCode ierr;
6377   IS             is, newis;
6378   const PetscInt *newRows;
6379 
6380   PetscFunctionBegin;
6381   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6382   PetscValidType(mat,1);
6383   if (numRows) PetscValidIntPointer(rows,3);
6384   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6385   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6386   MatCheckPreallocated(mat,1);
6387 
6388   if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6389   ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6390   ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr);
6391   ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6392   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6393   ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6394   ierr = ISDestroy(&newis);CHKERRQ(ierr);
6395   ierr = ISDestroy(&is);CHKERRQ(ierr);
6396   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6397 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
6398   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
6399     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
6400   }
6401 #endif
6402   PetscFunctionReturn(0);
6403 }
6404 
6405 /*@
6406    MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
6407    of a set of rows and columns of a matrix; using local numbering of rows.
6408 
6409    Collective on Mat
6410 
6411    Input Parameters:
6412 +  mat - the matrix
6413 .  is - index set of rows to remove
6414 .  diag - value put in all diagonals of eliminated rows
6415 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6416 -  b - optional vector of right hand side, that will be adjusted by provided solution
6417 
6418    Notes:
6419    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
6420    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6421 
6422    The user can set a value in the diagonal entry (or for the AIJ and
6423    row formats can optionally remove the main diagonal entry from the
6424    nonzero structure as well, by passing 0.0 as the final argument).
6425 
6426    Level: intermediate
6427 
6428    Concepts: matrices^zeroing
6429 
6430 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6431           MatZeroRowsColumnsLocal(), MatZeroRows(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6432 @*/
6433 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6434 {
6435   PetscErrorCode ierr;
6436   PetscInt       numRows;
6437   const PetscInt *rows;
6438 
6439   PetscFunctionBegin;
6440   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6441   PetscValidType(mat,1);
6442   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6443   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6444   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6445   MatCheckPreallocated(mat,1);
6446 
6447   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6448   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6449   ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6450   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6451   PetscFunctionReturn(0);
6452 }
6453 
6454 /*@C
6455    MatGetSize - Returns the numbers of rows and columns in a matrix.
6456 
6457    Not Collective
6458 
6459    Input Parameter:
6460 .  mat - the matrix
6461 
6462    Output Parameters:
6463 +  m - the number of global rows
6464 -  n - the number of global columns
6465 
6466    Note: both output parameters can be NULL on input.
6467 
6468    Level: beginner
6469 
6470    Concepts: matrices^size
6471 
6472 .seealso: MatGetLocalSize()
6473 @*/
6474 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
6475 {
6476   PetscFunctionBegin;
6477   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6478   if (m) *m = mat->rmap->N;
6479   if (n) *n = mat->cmap->N;
6480   PetscFunctionReturn(0);
6481 }
6482 
6483 /*@C
6484    MatGetLocalSize - Returns the number of rows and columns in a matrix
6485    stored locally.  This information may be implementation dependent, so
6486    use with care.
6487 
6488    Not Collective
6489 
6490    Input Parameters:
6491 .  mat - the matrix
6492 
6493    Output Parameters:
6494 +  m - the number of local rows
6495 -  n - the number of local columns
6496 
6497    Note: both output parameters can be NULL on input.
6498 
6499    Level: beginner
6500 
6501    Concepts: matrices^local size
6502 
6503 .seealso: MatGetSize()
6504 @*/
6505 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
6506 {
6507   PetscFunctionBegin;
6508   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6509   if (m) PetscValidIntPointer(m,2);
6510   if (n) PetscValidIntPointer(n,3);
6511   if (m) *m = mat->rmap->n;
6512   if (n) *n = mat->cmap->n;
6513   PetscFunctionReturn(0);
6514 }
6515 
6516 /*@C
6517    MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6518    this processor. (The columns of the "diagonal block")
6519 
6520    Not Collective, unless matrix has not been allocated, then collective on Mat
6521 
6522    Input Parameters:
6523 .  mat - the matrix
6524 
6525    Output Parameters:
6526 +  m - the global index of the first local column
6527 -  n - one more than the global index of the last local column
6528 
6529    Notes:
6530     both output parameters can be NULL on input.
6531 
6532    Level: developer
6533 
6534    Concepts: matrices^column ownership
6535 
6536 .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
6537 
6538 @*/
6539 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
6540 {
6541   PetscFunctionBegin;
6542   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6543   PetscValidType(mat,1);
6544   if (m) PetscValidIntPointer(m,2);
6545   if (n) PetscValidIntPointer(n,3);
6546   MatCheckPreallocated(mat,1);
6547   if (m) *m = mat->cmap->rstart;
6548   if (n) *n = mat->cmap->rend;
6549   PetscFunctionReturn(0);
6550 }
6551 
6552 /*@C
6553    MatGetOwnershipRange - Returns the range of matrix rows owned by
6554    this processor, assuming that the matrix is laid out with the first
6555    n1 rows on the first processor, the next n2 rows on the second, etc.
6556    For certain parallel layouts this range may not be well defined.
6557 
6558    Not Collective
6559 
6560    Input Parameters:
6561 .  mat - the matrix
6562 
6563    Output Parameters:
6564 +  m - the global index of the first local row
6565 -  n - one more than the global index of the last local row
6566 
6567    Note: Both output parameters can be NULL on input.
6568 $  This function requires that the matrix be preallocated. If you have not preallocated, consider using
6569 $    PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
6570 $  and then MPI_Scan() to calculate prefix sums of the local sizes.
6571 
6572    Level: beginner
6573 
6574    Concepts: matrices^row ownership
6575 
6576 .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()
6577 
6578 @*/
6579 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6580 {
6581   PetscFunctionBegin;
6582   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6583   PetscValidType(mat,1);
6584   if (m) PetscValidIntPointer(m,2);
6585   if (n) PetscValidIntPointer(n,3);
6586   MatCheckPreallocated(mat,1);
6587   if (m) *m = mat->rmap->rstart;
6588   if (n) *n = mat->rmap->rend;
6589   PetscFunctionReturn(0);
6590 }
6591 
6592 /*@C
6593    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6594    each process
6595 
6596    Not Collective, unless matrix has not been allocated, then collective on Mat
6597 
6598    Input Parameters:
6599 .  mat - the matrix
6600 
6601    Output Parameters:
6602 .  ranges - start of each processors portion plus one more than the total length at the end
6603 
6604    Level: beginner
6605 
6606    Concepts: matrices^row ownership
6607 
6608 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
6609 
6610 @*/
6611 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6612 {
6613   PetscErrorCode ierr;
6614 
6615   PetscFunctionBegin;
6616   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6617   PetscValidType(mat,1);
6618   MatCheckPreallocated(mat,1);
6619   ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr);
6620   PetscFunctionReturn(0);
6621 }
6622 
6623 /*@C
6624    MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6625    this processor. (The columns of the "diagonal blocks" for each process)
6626 
6627    Not Collective, unless matrix has not been allocated, then collective on Mat
6628 
6629    Input Parameters:
6630 .  mat - the matrix
6631 
6632    Output Parameters:
6633 .  ranges - start of each processors portion plus one more then the total length at the end
6634 
6635    Level: beginner
6636 
6637    Concepts: matrices^column ownership
6638 
6639 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
6640 
6641 @*/
6642 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6643 {
6644   PetscErrorCode ierr;
6645 
6646   PetscFunctionBegin;
6647   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6648   PetscValidType(mat,1);
6649   MatCheckPreallocated(mat,1);
6650   ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr);
6651   PetscFunctionReturn(0);
6652 }
6653 
6654 /*@C
6655    MatGetOwnershipIS - Get row and column ownership as index sets
6656 
6657    Not Collective
6658 
6659    Input Arguments:
6660 .  A - matrix of type Elemental
6661 
6662    Output Arguments:
6663 +  rows - rows in which this process owns elements
6664 .  cols - columns in which this process owns elements
6665 
6666    Level: intermediate
6667 
6668 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL
6669 @*/
6670 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6671 {
6672   PetscErrorCode ierr,(*f)(Mat,IS*,IS*);
6673 
6674   PetscFunctionBegin;
6675   MatCheckPreallocated(A,1);
6676   ierr = PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);CHKERRQ(ierr);
6677   if (f) {
6678     ierr = (*f)(A,rows,cols);CHKERRQ(ierr);
6679   } else {   /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6680     if (rows) {ierr = ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);CHKERRQ(ierr);}
6681     if (cols) {ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);CHKERRQ(ierr);}
6682   }
6683   PetscFunctionReturn(0);
6684 }
6685 
6686 /*@C
6687    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6688    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6689    to complete the factorization.
6690 
6691    Collective on Mat
6692 
6693    Input Parameters:
6694 +  mat - the matrix
6695 .  row - row permutation
6696 .  column - column permutation
6697 -  info - structure containing
6698 $      levels - number of levels of fill.
6699 $      expected fill - as ratio of original fill.
6700 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6701                 missing diagonal entries)
6702 
6703    Output Parameters:
6704 .  fact - new matrix that has been symbolically factored
6705 
6706    Notes:
6707     See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
6708 
6709    Most users should employ the simplified KSP interface for linear solvers
6710    instead of working directly with matrix algebra routines such as this.
6711    See, e.g., KSPCreate().
6712 
6713    Level: developer
6714 
6715   Concepts: matrices^symbolic LU factorization
6716   Concepts: matrices^factorization
6717   Concepts: LU^symbolic factorization
6718 
6719 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6720           MatGetOrdering(), MatFactorInfo
6721 
6722     Note: this uses the definition of level of fill as in Y. Saad, 2003
6723 
6724     Developer Note: fortran interface is not autogenerated as the f90
6725     interface defintion cannot be generated correctly [due to MatFactorInfo]
6726 
6727    References:
6728      Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003
6729 @*/
6730 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6731 {
6732   PetscErrorCode ierr;
6733 
6734   PetscFunctionBegin;
6735   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6736   PetscValidType(mat,1);
6737   PetscValidHeaderSpecific(row,IS_CLASSID,2);
6738   PetscValidHeaderSpecific(col,IS_CLASSID,3);
6739   PetscValidPointer(info,4);
6740   PetscValidPointer(fact,5);
6741   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6742   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6743   if (!(fact)->ops->ilufactorsymbolic) {
6744     MatSolverType spackage;
6745     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
6746     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6747   }
6748   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6749   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6750   MatCheckPreallocated(mat,2);
6751 
6752   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6753   ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
6754   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6755   PetscFunctionReturn(0);
6756 }
6757 
6758 /*@C
6759    MatICCFactorSymbolic - Performs symbolic incomplete
6760    Cholesky factorization for a symmetric matrix.  Use
6761    MatCholeskyFactorNumeric() to complete the factorization.
6762 
6763    Collective on Mat
6764 
6765    Input Parameters:
6766 +  mat - the matrix
6767 .  perm - row and column permutation
6768 -  info - structure containing
6769 $      levels - number of levels of fill.
6770 $      expected fill - as ratio of original fill.
6771 
6772    Output Parameter:
6773 .  fact - the factored matrix
6774 
6775    Notes:
6776    Most users should employ the KSP interface for linear solvers
6777    instead of working directly with matrix algebra routines such as this.
6778    See, e.g., KSPCreate().
6779 
6780    Level: developer
6781 
6782   Concepts: matrices^symbolic incomplete Cholesky factorization
6783   Concepts: matrices^factorization
6784   Concepts: Cholsky^symbolic factorization
6785 
6786 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
6787 
6788     Note: this uses the definition of level of fill as in Y. Saad, 2003
6789 
6790     Developer Note: fortran interface is not autogenerated as the f90
6791     interface defintion cannot be generated correctly [due to MatFactorInfo]
6792 
6793    References:
6794      Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003
6795 @*/
6796 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6797 {
6798   PetscErrorCode ierr;
6799 
6800   PetscFunctionBegin;
6801   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6802   PetscValidType(mat,1);
6803   PetscValidHeaderSpecific(perm,IS_CLASSID,2);
6804   PetscValidPointer(info,3);
6805   PetscValidPointer(fact,4);
6806   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6807   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6808   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6809   if (!(fact)->ops->iccfactorsymbolic) {
6810     MatSolverType spackage;
6811     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
6812     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6813   }
6814   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6815   MatCheckPreallocated(mat,2);
6816 
6817   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6818   ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
6819   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6820   PetscFunctionReturn(0);
6821 }
6822 
6823 /*@C
6824    MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat
6825    points to an array of valid matrices, they may be reused to store the new
6826    submatrices.
6827 
6828    Collective on Mat
6829 
6830    Input Parameters:
6831 +  mat - the matrix
6832 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6833 .  irow, icol - index sets of rows and columns to extract
6834 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6835 
6836    Output Parameter:
6837 .  submat - the array of submatrices
6838 
6839    Notes:
6840    MatCreateSubMatrices() can extract ONLY sequential submatrices
6841    (from both sequential and parallel matrices). Use MatCreateSubMatrix()
6842    to extract a parallel submatrix.
6843 
6844    Some matrix types place restrictions on the row and column
6845    indices, such as that they be sorted or that they be equal to each other.
6846 
6847    The index sets may not have duplicate entries.
6848 
6849    When extracting submatrices from a parallel matrix, each processor can
6850    form a different submatrix by setting the rows and columns of its
6851    individual index sets according to the local submatrix desired.
6852 
6853    When finished using the submatrices, the user should destroy
6854    them with MatDestroySubMatrices().
6855 
6856    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6857    original matrix has not changed from that last call to MatCreateSubMatrices().
6858 
6859    This routine creates the matrices in submat; you should NOT create them before
6860    calling it. It also allocates the array of matrix pointers submat.
6861 
6862    For BAIJ matrices the index sets must respect the block structure, that is if they
6863    request one row/column in a block, they must request all rows/columns that are in
6864    that block. For example, if the block size is 2 you cannot request just row 0 and
6865    column 0.
6866 
6867    Fortran Note:
6868    The Fortran interface is slightly different from that given below; it
6869    requires one to pass in  as submat a Mat (integer) array of size at least n+1.
6870 
6871    Level: advanced
6872 
6873    Concepts: matrices^accessing submatrices
6874    Concepts: submatrices
6875 
6876 .seealso: MatDestroySubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6877 @*/
6878 PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6879 {
6880   PetscErrorCode ierr;
6881   PetscInt       i;
6882   PetscBool      eq;
6883 
6884   PetscFunctionBegin;
6885   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6886   PetscValidType(mat,1);
6887   if (n) {
6888     PetscValidPointer(irow,3);
6889     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6890     PetscValidPointer(icol,4);
6891     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6892   }
6893   PetscValidPointer(submat,6);
6894   if (n && scall == MAT_REUSE_MATRIX) {
6895     PetscValidPointer(*submat,6);
6896     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6897   }
6898   if (!mat->ops->createsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6899   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6900   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6901   MatCheckPreallocated(mat,1);
6902 
6903   ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6904   ierr = (*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6905   ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6906   for (i=0; i<n; i++) {
6907     (*submat)[i]->factortype = MAT_FACTOR_NONE;  /* in case in place factorization was previously done on submatrix */
6908     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6909       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6910       if (eq) {
6911         if (mat->symmetric) {
6912           ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6913         } else if (mat->hermitian) {
6914           ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6915         } else if (mat->structurally_symmetric) {
6916           ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6917         }
6918       }
6919     }
6920   }
6921   PetscFunctionReturn(0);
6922 }
6923 
6924 /*@C
6925    MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms).
6926 
6927    Collective on Mat
6928 
6929    Input Parameters:
6930 +  mat - the matrix
6931 .  n   - the number of submatrixes to be extracted
6932 .  irow, icol - index sets of rows and columns to extract
6933 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6934 
6935    Output Parameter:
6936 .  submat - the array of submatrices
6937 
6938    Level: advanced
6939 
6940    Concepts: matrices^accessing submatrices
6941    Concepts: submatrices
6942 
6943 .seealso: MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6944 @*/
6945 PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6946 {
6947   PetscErrorCode ierr;
6948   PetscInt       i;
6949   PetscBool      eq;
6950 
6951   PetscFunctionBegin;
6952   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6953   PetscValidType(mat,1);
6954   if (n) {
6955     PetscValidPointer(irow,3);
6956     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6957     PetscValidPointer(icol,4);
6958     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6959   }
6960   PetscValidPointer(submat,6);
6961   if (n && scall == MAT_REUSE_MATRIX) {
6962     PetscValidPointer(*submat,6);
6963     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6964   }
6965   if (!mat->ops->createsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6966   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6967   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6968   MatCheckPreallocated(mat,1);
6969 
6970   ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6971   ierr = (*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6972   ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6973   for (i=0; i<n; i++) {
6974     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6975       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6976       if (eq) {
6977         if (mat->symmetric) {
6978           ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6979         } else if (mat->hermitian) {
6980           ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6981         } else if (mat->structurally_symmetric) {
6982           ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6983         }
6984       }
6985     }
6986   }
6987   PetscFunctionReturn(0);
6988 }
6989 
6990 /*@C
6991    MatDestroyMatrices - Destroys an array of matrices.
6992 
6993    Collective on Mat
6994 
6995    Input Parameters:
6996 +  n - the number of local matrices
6997 -  mat - the matrices (note that this is a pointer to the array of matrices)
6998 
6999    Level: advanced
7000 
7001     Notes:
7002     Frees not only the matrices, but also the array that contains the matrices
7003            In Fortran will not free the array.
7004 
7005 .seealso: MatCreateSubMatrices() MatDestroySubMatrices()
7006 @*/
7007 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
7008 {
7009   PetscErrorCode ierr;
7010   PetscInt       i;
7011 
7012   PetscFunctionBegin;
7013   if (!*mat) PetscFunctionReturn(0);
7014   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
7015   PetscValidPointer(mat,2);
7016 
7017   for (i=0; i<n; i++) {
7018     ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr);
7019   }
7020 
7021   /* memory is allocated even if n = 0 */
7022   ierr = PetscFree(*mat);CHKERRQ(ierr);
7023   PetscFunctionReturn(0);
7024 }
7025 
7026 /*@C
7027    MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices().
7028 
7029    Collective on Mat
7030 
7031    Input Parameters:
7032 +  n - the number of local matrices
7033 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
7034                        sequence of MatCreateSubMatrices())
7035 
7036    Level: advanced
7037 
7038     Notes:
7039     Frees not only the matrices, but also the array that contains the matrices
7040            In Fortran will not free the array.
7041 
7042 .seealso: MatCreateSubMatrices()
7043 @*/
7044 PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[])
7045 {
7046   PetscErrorCode ierr;
7047   Mat            mat0;
7048 
7049   PetscFunctionBegin;
7050   if (!*mat) PetscFunctionReturn(0);
7051   /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */
7052   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
7053   PetscValidPointer(mat,2);
7054 
7055   mat0 = (*mat)[0];
7056   if (mat0 && mat0->ops->destroysubmatrices) {
7057     ierr = (mat0->ops->destroysubmatrices)(n,mat);CHKERRQ(ierr);
7058   } else {
7059     ierr = MatDestroyMatrices(n,mat);CHKERRQ(ierr);
7060   }
7061   PetscFunctionReturn(0);
7062 }
7063 
7064 /*@C
7065    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
7066 
7067    Collective on Mat
7068 
7069    Input Parameters:
7070 .  mat - the matrix
7071 
7072    Output Parameter:
7073 .  matstruct - the sequential matrix with the nonzero structure of mat
7074 
7075   Level: intermediate
7076 
7077 .seealso: MatDestroySeqNonzeroStructure(), MatCreateSubMatrices(), MatDestroyMatrices()
7078 @*/
7079 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
7080 {
7081   PetscErrorCode ierr;
7082 
7083   PetscFunctionBegin;
7084   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7085   PetscValidPointer(matstruct,2);
7086 
7087   PetscValidType(mat,1);
7088   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7089   MatCheckPreallocated(mat,1);
7090 
7091   if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
7092   ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
7093   ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr);
7094   ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
7095   PetscFunctionReturn(0);
7096 }
7097 
7098 /*@C
7099    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
7100 
7101    Collective on Mat
7102 
7103    Input Parameters:
7104 .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
7105                        sequence of MatGetSequentialNonzeroStructure())
7106 
7107    Level: advanced
7108 
7109     Notes:
7110     Frees not only the matrices, but also the array that contains the matrices
7111 
7112 .seealso: MatGetSeqNonzeroStructure()
7113 @*/
7114 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
7115 {
7116   PetscErrorCode ierr;
7117 
7118   PetscFunctionBegin;
7119   PetscValidPointer(mat,1);
7120   ierr = MatDestroy(mat);CHKERRQ(ierr);
7121   PetscFunctionReturn(0);
7122 }
7123 
7124 /*@
7125    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
7126    replaces the index sets by larger ones that represent submatrices with
7127    additional overlap.
7128 
7129    Collective on Mat
7130 
7131    Input Parameters:
7132 +  mat - the matrix
7133 .  n   - the number of index sets
7134 .  is  - the array of index sets (these index sets will changed during the call)
7135 -  ov  - the additional overlap requested
7136 
7137    Options Database:
7138 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
7139 
7140    Level: developer
7141 
7142    Concepts: overlap
7143    Concepts: ASM^computing overlap
7144 
7145 .seealso: MatCreateSubMatrices()
7146 @*/
7147 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
7148 {
7149   PetscErrorCode ierr;
7150 
7151   PetscFunctionBegin;
7152   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7153   PetscValidType(mat,1);
7154   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
7155   if (n) {
7156     PetscValidPointer(is,3);
7157     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
7158   }
7159   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7160   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7161   MatCheckPreallocated(mat,1);
7162 
7163   if (!ov) PetscFunctionReturn(0);
7164   if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7165   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7166   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
7167   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7168   PetscFunctionReturn(0);
7169 }
7170 
7171 
7172 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt);
7173 
7174 /*@
7175    MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across
7176    a sub communicator, replaces the index sets by larger ones that represent submatrices with
7177    additional overlap.
7178 
7179    Collective on Mat
7180 
7181    Input Parameters:
7182 +  mat - the matrix
7183 .  n   - the number of index sets
7184 .  is  - the array of index sets (these index sets will changed during the call)
7185 -  ov  - the additional overlap requested
7186 
7187    Options Database:
7188 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
7189 
7190    Level: developer
7191 
7192    Concepts: overlap
7193    Concepts: ASM^computing overlap
7194 
7195 .seealso: MatCreateSubMatrices()
7196 @*/
7197 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov)
7198 {
7199   PetscInt       i;
7200   PetscErrorCode ierr;
7201 
7202   PetscFunctionBegin;
7203   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7204   PetscValidType(mat,1);
7205   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
7206   if (n) {
7207     PetscValidPointer(is,3);
7208     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
7209   }
7210   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7211   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7212   MatCheckPreallocated(mat,1);
7213   if (!ov) PetscFunctionReturn(0);
7214   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7215   for(i=0; i<n; i++){
7216 	ierr =  MatIncreaseOverlapSplit_Single(mat,&is[i],ov);CHKERRQ(ierr);
7217   }
7218   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7219   PetscFunctionReturn(0);
7220 }
7221 
7222 
7223 
7224 
7225 /*@
7226    MatGetBlockSize - Returns the matrix block size.
7227 
7228    Not Collective
7229 
7230    Input Parameter:
7231 .  mat - the matrix
7232 
7233    Output Parameter:
7234 .  bs - block size
7235 
7236    Notes:
7237     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7238 
7239    If the block size has not been set yet this routine returns 1.
7240 
7241    Level: intermediate
7242 
7243    Concepts: matrices^block size
7244 
7245 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
7246 @*/
7247 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
7248 {
7249   PetscFunctionBegin;
7250   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7251   PetscValidIntPointer(bs,2);
7252   *bs = PetscAbs(mat->rmap->bs);
7253   PetscFunctionReturn(0);
7254 }
7255 
7256 /*@
7257    MatGetBlockSizes - Returns the matrix block row and column sizes.
7258 
7259    Not Collective
7260 
7261    Input Parameter:
7262 .  mat - the matrix
7263 
7264    Output Parameter:
7265 .  rbs - row block size
7266 .  cbs - column block size
7267 
7268    Notes:
7269     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7270     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7271 
7272    If a block size has not been set yet this routine returns 1.
7273 
7274    Level: intermediate
7275 
7276    Concepts: matrices^block size
7277 
7278 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes()
7279 @*/
7280 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
7281 {
7282   PetscFunctionBegin;
7283   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7284   if (rbs) PetscValidIntPointer(rbs,2);
7285   if (cbs) PetscValidIntPointer(cbs,3);
7286   if (rbs) *rbs = PetscAbs(mat->rmap->bs);
7287   if (cbs) *cbs = PetscAbs(mat->cmap->bs);
7288   PetscFunctionReturn(0);
7289 }
7290 
7291 /*@
7292    MatSetBlockSize - Sets the matrix block size.
7293 
7294    Logically Collective on Mat
7295 
7296    Input Parameters:
7297 +  mat - the matrix
7298 -  bs - block size
7299 
7300    Notes:
7301     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7302     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later.
7303 
7304     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size
7305     is compatible with the matrix local sizes.
7306 
7307    Level: intermediate
7308 
7309    Concepts: matrices^block size
7310 
7311 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes()
7312 @*/
7313 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
7314 {
7315   PetscErrorCode ierr;
7316 
7317   PetscFunctionBegin;
7318   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7319   PetscValidLogicalCollectiveInt(mat,bs,2);
7320   ierr = MatSetBlockSizes(mat,bs,bs);CHKERRQ(ierr);
7321   PetscFunctionReturn(0);
7322 }
7323 
7324 /*@
7325    MatSetVariableBlockSizes - Sets a diagonal blocks of the matrix that need not be of the same size
7326 
7327    Logically Collective on Mat
7328 
7329    Input Parameters:
7330 +  mat - the matrix
7331 .  nblocks - the number of blocks on this process
7332 -  bsizes - the block sizes
7333 
7334    Notes:
7335     Currently used by PCVPBJACOBI for SeqAIJ matrices
7336 
7337    Level: intermediate
7338 
7339    Concepts: matrices^block size
7340 
7341 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatGetVariableBlockSizes()
7342 @*/
7343 PetscErrorCode MatSetVariableBlockSizes(Mat mat,PetscInt nblocks,PetscInt *bsizes)
7344 {
7345   PetscErrorCode ierr;
7346   PetscInt       i,ncnt = 0, nlocal;
7347 
7348   PetscFunctionBegin;
7349   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7350   if (nblocks < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number of local blocks must be great than or equal to zero");
7351   ierr = MatGetLocalSize(mat,&nlocal,NULL);CHKERRQ(ierr);
7352   for (i=0; i<nblocks; i++) ncnt += bsizes[i];
7353   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);
7354   ierr = PetscFree(mat->bsizes);CHKERRQ(ierr);
7355   mat->nblocks = nblocks;
7356   ierr = PetscMalloc1(nblocks,&mat->bsizes);CHKERRQ(ierr);
7357   ierr = PetscMemcpy(mat->bsizes,bsizes,nblocks*sizeof(PetscInt));CHKERRQ(ierr);
7358   PetscFunctionReturn(0);
7359 }
7360 
7361 /*@C
7362    MatGetVariableBlockSizes - Gets a diagonal blocks of the matrix that need not be of the same size
7363 
7364    Logically Collective on Mat
7365 
7366    Input Parameters:
7367 .  mat - the matrix
7368 
7369    Output Parameters:
7370 +  nblocks - the number of blocks on this process
7371 -  bsizes - the block sizes
7372 
7373    Notes: Currently not supported from Fortran
7374 
7375    Level: intermediate
7376 
7377    Concepts: matrices^block size
7378 
7379 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatSetVariableBlockSizes()
7380 @*/
7381 PetscErrorCode MatGetVariableBlockSizes(Mat mat,PetscInt *nblocks,const PetscInt **bsizes)
7382 {
7383   PetscFunctionBegin;
7384   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7385   *nblocks = mat->nblocks;
7386   *bsizes  = mat->bsizes;
7387   PetscFunctionReturn(0);
7388 }
7389 
7390 /*@
7391    MatSetBlockSizes - Sets the matrix block row and column sizes.
7392 
7393    Logically Collective on Mat
7394 
7395    Input Parameters:
7396 +  mat - the matrix
7397 -  rbs - row block size
7398 -  cbs - column block size
7399 
7400    Notes:
7401     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7402     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7403     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later
7404 
7405     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes
7406     are compatible with the matrix local sizes.
7407 
7408     The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs().
7409 
7410    Level: intermediate
7411 
7412    Concepts: matrices^block size
7413 
7414 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes()
7415 @*/
7416 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
7417 {
7418   PetscErrorCode ierr;
7419 
7420   PetscFunctionBegin;
7421   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7422   PetscValidLogicalCollectiveInt(mat,rbs,2);
7423   PetscValidLogicalCollectiveInt(mat,cbs,3);
7424   if (mat->ops->setblocksizes) {
7425     ierr = (*mat->ops->setblocksizes)(mat,rbs,cbs);CHKERRQ(ierr);
7426   }
7427   if (mat->rmap->refcnt) {
7428     ISLocalToGlobalMapping l2g = NULL;
7429     PetscLayout            nmap = NULL;
7430 
7431     ierr = PetscLayoutDuplicate(mat->rmap,&nmap);CHKERRQ(ierr);
7432     if (mat->rmap->mapping) {
7433       ierr = ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g);CHKERRQ(ierr);
7434     }
7435     ierr = PetscLayoutDestroy(&mat->rmap);CHKERRQ(ierr);
7436     mat->rmap = nmap;
7437     mat->rmap->mapping = l2g;
7438   }
7439   if (mat->cmap->refcnt) {
7440     ISLocalToGlobalMapping l2g = NULL;
7441     PetscLayout            nmap = NULL;
7442 
7443     ierr = PetscLayoutDuplicate(mat->cmap,&nmap);CHKERRQ(ierr);
7444     if (mat->cmap->mapping) {
7445       ierr = ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g);CHKERRQ(ierr);
7446     }
7447     ierr = PetscLayoutDestroy(&mat->cmap);CHKERRQ(ierr);
7448     mat->cmap = nmap;
7449     mat->cmap->mapping = l2g;
7450   }
7451   ierr = PetscLayoutSetBlockSize(mat->rmap,rbs);CHKERRQ(ierr);
7452   ierr = PetscLayoutSetBlockSize(mat->cmap,cbs);CHKERRQ(ierr);
7453   PetscFunctionReturn(0);
7454 }
7455 
7456 /*@
7457    MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices
7458 
7459    Logically Collective on Mat
7460 
7461    Input Parameters:
7462 +  mat - the matrix
7463 .  fromRow - matrix from which to copy row block size
7464 -  fromCol - matrix from which to copy column block size (can be same as fromRow)
7465 
7466    Level: developer
7467 
7468    Concepts: matrices^block size
7469 
7470 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes()
7471 @*/
7472 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)
7473 {
7474   PetscErrorCode ierr;
7475 
7476   PetscFunctionBegin;
7477   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7478   PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2);
7479   PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3);
7480   if (fromRow->rmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);CHKERRQ(ierr);}
7481   if (fromCol->cmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);CHKERRQ(ierr);}
7482   PetscFunctionReturn(0);
7483 }
7484 
7485 /*@
7486    MatResidual - Default routine to calculate the residual.
7487 
7488    Collective on Mat and Vec
7489 
7490    Input Parameters:
7491 +  mat - the matrix
7492 .  b   - the right-hand-side
7493 -  x   - the approximate solution
7494 
7495    Output Parameter:
7496 .  r - location to store the residual
7497 
7498    Level: developer
7499 
7500 .keywords: MG, default, multigrid, residual
7501 
7502 .seealso: PCMGSetResidual()
7503 @*/
7504 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r)
7505 {
7506   PetscErrorCode ierr;
7507 
7508   PetscFunctionBegin;
7509   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7510   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
7511   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
7512   PetscValidHeaderSpecific(r,VEC_CLASSID,4);
7513   PetscValidType(mat,1);
7514   MatCheckPreallocated(mat,1);
7515   ierr  = PetscLogEventBegin(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7516   if (!mat->ops->residual) {
7517     ierr = MatMult(mat,x,r);CHKERRQ(ierr);
7518     ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr);
7519   } else {
7520     ierr  = (*mat->ops->residual)(mat,b,x,r);CHKERRQ(ierr);
7521   }
7522   ierr  = PetscLogEventEnd(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7523   PetscFunctionReturn(0);
7524 }
7525 
7526 /*@C
7527     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
7528 
7529    Collective on Mat
7530 
7531     Input Parameters:
7532 +   mat - the matrix
7533 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
7534 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
7535 -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
7536                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7537                  always used.
7538 
7539     Output Parameters:
7540 +   n - number of rows in the (possibly compressed) matrix
7541 .   ia - the row pointers; that is ia[0] = 0, ia[row] = ia[row-1] + number of elements in that row of the matrix
7542 .   ja - the column indices
7543 -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
7544            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
7545 
7546     Level: developer
7547 
7548     Notes:
7549     You CANNOT change any of the ia[] or ja[] values.
7550 
7551     Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values.
7552 
7553     Fortran Notes:
7554     In Fortran use
7555 $
7556 $      PetscInt ia(1), ja(1)
7557 $      PetscOffset iia, jja
7558 $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
7559 $      ! Access the ith and jth entries via ia(iia + i) and ja(jja + j)
7560 
7561      or
7562 $
7563 $    PetscInt, pointer :: ia(:),ja(:)
7564 $    call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
7565 $    ! Access the ith and jth entries via ia(i) and ja(j)
7566 
7567 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
7568 @*/
7569 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7570 {
7571   PetscErrorCode ierr;
7572 
7573   PetscFunctionBegin;
7574   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7575   PetscValidType(mat,1);
7576   PetscValidIntPointer(n,5);
7577   if (ia) PetscValidIntPointer(ia,6);
7578   if (ja) PetscValidIntPointer(ja,7);
7579   PetscValidIntPointer(done,8);
7580   MatCheckPreallocated(mat,1);
7581   if (!mat->ops->getrowij) *done = PETSC_FALSE;
7582   else {
7583     *done = PETSC_TRUE;
7584     ierr  = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7585     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7586     ierr  = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7587   }
7588   PetscFunctionReturn(0);
7589 }
7590 
7591 /*@C
7592     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
7593 
7594     Collective on Mat
7595 
7596     Input Parameters:
7597 +   mat - the matrix
7598 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7599 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7600                 symmetrized
7601 .   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7602                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7603                  always used.
7604 .   n - number of columns in the (possibly compressed) matrix
7605 .   ia - the column pointers; that is ia[0] = 0, ia[col] = i[col-1] + number of elements in that col of the matrix
7606 -   ja - the row indices
7607 
7608     Output Parameters:
7609 .   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
7610 
7611     Level: developer
7612 
7613 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7614 @*/
7615 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7616 {
7617   PetscErrorCode ierr;
7618 
7619   PetscFunctionBegin;
7620   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7621   PetscValidType(mat,1);
7622   PetscValidIntPointer(n,4);
7623   if (ia) PetscValidIntPointer(ia,5);
7624   if (ja) PetscValidIntPointer(ja,6);
7625   PetscValidIntPointer(done,7);
7626   MatCheckPreallocated(mat,1);
7627   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
7628   else {
7629     *done = PETSC_TRUE;
7630     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7631   }
7632   PetscFunctionReturn(0);
7633 }
7634 
7635 /*@C
7636     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
7637     MatGetRowIJ().
7638 
7639     Collective on Mat
7640 
7641     Input Parameters:
7642 +   mat - the matrix
7643 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7644 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7645                 symmetrized
7646 .   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7647                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7648                  always used.
7649 .   n - size of (possibly compressed) matrix
7650 .   ia - the row pointers
7651 -   ja - the column indices
7652 
7653     Output Parameters:
7654 .   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7655 
7656     Note:
7657     This routine zeros out n, ia, and ja. This is to prevent accidental
7658     us of the array after it has been restored. If you pass NULL, it will
7659     not zero the pointers.  Use of ia or ja after MatRestoreRowIJ() is invalid.
7660 
7661     Level: developer
7662 
7663 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7664 @*/
7665 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7666 {
7667   PetscErrorCode ierr;
7668 
7669   PetscFunctionBegin;
7670   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7671   PetscValidType(mat,1);
7672   if (ia) PetscValidIntPointer(ia,6);
7673   if (ja) PetscValidIntPointer(ja,7);
7674   PetscValidIntPointer(done,8);
7675   MatCheckPreallocated(mat,1);
7676 
7677   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
7678   else {
7679     *done = PETSC_TRUE;
7680     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7681     if (n)  *n = 0;
7682     if (ia) *ia = NULL;
7683     if (ja) *ja = NULL;
7684   }
7685   PetscFunctionReturn(0);
7686 }
7687 
7688 /*@C
7689     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
7690     MatGetColumnIJ().
7691 
7692     Collective on Mat
7693 
7694     Input Parameters:
7695 +   mat - the matrix
7696 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7697 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7698                 symmetrized
7699 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7700                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7701                  always used.
7702 
7703     Output Parameters:
7704 +   n - size of (possibly compressed) matrix
7705 .   ia - the column pointers
7706 .   ja - the row indices
7707 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7708 
7709     Level: developer
7710 
7711 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
7712 @*/
7713 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7714 {
7715   PetscErrorCode ierr;
7716 
7717   PetscFunctionBegin;
7718   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7719   PetscValidType(mat,1);
7720   if (ia) PetscValidIntPointer(ia,5);
7721   if (ja) PetscValidIntPointer(ja,6);
7722   PetscValidIntPointer(done,7);
7723   MatCheckPreallocated(mat,1);
7724 
7725   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
7726   else {
7727     *done = PETSC_TRUE;
7728     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7729     if (n)  *n = 0;
7730     if (ia) *ia = NULL;
7731     if (ja) *ja = NULL;
7732   }
7733   PetscFunctionReturn(0);
7734 }
7735 
7736 /*@C
7737     MatColoringPatch -Used inside matrix coloring routines that
7738     use MatGetRowIJ() and/or MatGetColumnIJ().
7739 
7740     Collective on Mat
7741 
7742     Input Parameters:
7743 +   mat - the matrix
7744 .   ncolors - max color value
7745 .   n   - number of entries in colorarray
7746 -   colorarray - array indicating color for each column
7747 
7748     Output Parameters:
7749 .   iscoloring - coloring generated using colorarray information
7750 
7751     Level: developer
7752 
7753 .seealso: MatGetRowIJ(), MatGetColumnIJ()
7754 
7755 @*/
7756 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7757 {
7758   PetscErrorCode ierr;
7759 
7760   PetscFunctionBegin;
7761   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7762   PetscValidType(mat,1);
7763   PetscValidIntPointer(colorarray,4);
7764   PetscValidPointer(iscoloring,5);
7765   MatCheckPreallocated(mat,1);
7766 
7767   if (!mat->ops->coloringpatch) {
7768     ierr = ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);CHKERRQ(ierr);
7769   } else {
7770     ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
7771   }
7772   PetscFunctionReturn(0);
7773 }
7774 
7775 
7776 /*@
7777    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
7778 
7779    Logically Collective on Mat
7780 
7781    Input Parameter:
7782 .  mat - the factored matrix to be reset
7783 
7784    Notes:
7785    This routine should be used only with factored matrices formed by in-place
7786    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7787    format).  This option can save memory, for example, when solving nonlinear
7788    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7789    ILU(0) preconditioner.
7790 
7791    Note that one can specify in-place ILU(0) factorization by calling
7792 .vb
7793      PCType(pc,PCILU);
7794      PCFactorSeUseInPlace(pc);
7795 .ve
7796    or by using the options -pc_type ilu -pc_factor_in_place
7797 
7798    In-place factorization ILU(0) can also be used as a local
7799    solver for the blocks within the block Jacobi or additive Schwarz
7800    methods (runtime option: -sub_pc_factor_in_place).  See Users-Manual: ch_pc
7801    for details on setting local solver options.
7802 
7803    Most users should employ the simplified KSP interface for linear solvers
7804    instead of working directly with matrix algebra routines such as this.
7805    See, e.g., KSPCreate().
7806 
7807    Level: developer
7808 
7809 .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace()
7810 
7811    Concepts: matrices^unfactored
7812 
7813 @*/
7814 PetscErrorCode MatSetUnfactored(Mat mat)
7815 {
7816   PetscErrorCode ierr;
7817 
7818   PetscFunctionBegin;
7819   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7820   PetscValidType(mat,1);
7821   MatCheckPreallocated(mat,1);
7822   mat->factortype = MAT_FACTOR_NONE;
7823   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
7824   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
7825   PetscFunctionReturn(0);
7826 }
7827 
7828 /*MC
7829     MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.
7830 
7831     Synopsis:
7832     MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7833 
7834     Not collective
7835 
7836     Input Parameter:
7837 .   x - matrix
7838 
7839     Output Parameters:
7840 +   xx_v - the Fortran90 pointer to the array
7841 -   ierr - error code
7842 
7843     Example of Usage:
7844 .vb
7845       PetscScalar, pointer xx_v(:,:)
7846       ....
7847       call MatDenseGetArrayF90(x,xx_v,ierr)
7848       a = xx_v(3)
7849       call MatDenseRestoreArrayF90(x,xx_v,ierr)
7850 .ve
7851 
7852     Level: advanced
7853 
7854 .seealso:  MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90()
7855 
7856     Concepts: matrices^accessing array
7857 
7858 M*/
7859 
7860 /*MC
7861     MatDenseRestoreArrayF90 - Restores a matrix array that has been
7862     accessed with MatDenseGetArrayF90().
7863 
7864     Synopsis:
7865     MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7866 
7867     Not collective
7868 
7869     Input Parameters:
7870 +   x - matrix
7871 -   xx_v - the Fortran90 pointer to the array
7872 
7873     Output Parameter:
7874 .   ierr - error code
7875 
7876     Example of Usage:
7877 .vb
7878        PetscScalar, pointer xx_v(:,:)
7879        ....
7880        call MatDenseGetArrayF90(x,xx_v,ierr)
7881        a = xx_v(3)
7882        call MatDenseRestoreArrayF90(x,xx_v,ierr)
7883 .ve
7884 
7885     Level: advanced
7886 
7887 .seealso:  MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90()
7888 
7889 M*/
7890 
7891 
7892 /*MC
7893     MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.
7894 
7895     Synopsis:
7896     MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7897 
7898     Not collective
7899 
7900     Input Parameter:
7901 .   x - matrix
7902 
7903     Output Parameters:
7904 +   xx_v - the Fortran90 pointer to the array
7905 -   ierr - error code
7906 
7907     Example of Usage:
7908 .vb
7909       PetscScalar, pointer xx_v(:)
7910       ....
7911       call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7912       a = xx_v(3)
7913       call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7914 .ve
7915 
7916     Level: advanced
7917 
7918 .seealso:  MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90()
7919 
7920     Concepts: matrices^accessing array
7921 
7922 M*/
7923 
7924 /*MC
7925     MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7926     accessed with MatSeqAIJGetArrayF90().
7927 
7928     Synopsis:
7929     MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7930 
7931     Not collective
7932 
7933     Input Parameters:
7934 +   x - matrix
7935 -   xx_v - the Fortran90 pointer to the array
7936 
7937     Output Parameter:
7938 .   ierr - error code
7939 
7940     Example of Usage:
7941 .vb
7942        PetscScalar, pointer xx_v(:)
7943        ....
7944        call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7945        a = xx_v(3)
7946        call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7947 .ve
7948 
7949     Level: advanced
7950 
7951 .seealso:  MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90()
7952 
7953 M*/
7954 
7955 
7956 /*@
7957     MatCreateSubMatrix - Gets a single submatrix on the same number of processors
7958                       as the original matrix.
7959 
7960     Collective on Mat
7961 
7962     Input Parameters:
7963 +   mat - the original matrix
7964 .   isrow - parallel IS containing the rows this processor should obtain
7965 .   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.
7966 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7967 
7968     Output Parameter:
7969 .   newmat - the new submatrix, of the same type as the old
7970 
7971     Level: advanced
7972 
7973     Notes:
7974     The submatrix will be able to be multiplied with vectors using the same layout as iscol.
7975 
7976     Some matrix types place restrictions on the row and column indices, such
7977     as that they be sorted or that they be equal to each other.
7978 
7979     The index sets may not have duplicate entries.
7980 
7981       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7982    the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls
7983    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7984    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
7985    you are finished using it.
7986 
7987     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7988     the input matrix.
7989 
7990     If iscol is NULL then all columns are obtained (not supported in Fortran).
7991 
7992    Example usage:
7993    Consider the following 8x8 matrix with 34 non-zero values, that is
7994    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7995    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7996    as follows:
7997 
7998 .vb
7999             1  2  0  |  0  3  0  |  0  4
8000     Proc0   0  5  6  |  7  0  0  |  8  0
8001             9  0 10  | 11  0  0  | 12  0
8002     -------------------------------------
8003            13  0 14  | 15 16 17  |  0  0
8004     Proc1   0 18  0  | 19 20 21  |  0  0
8005             0  0  0  | 22 23  0  | 24  0
8006     -------------------------------------
8007     Proc2  25 26 27  |  0  0 28  | 29  0
8008            30  0  0  | 31 32 33  |  0 34
8009 .ve
8010 
8011     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is
8012 
8013 .vb
8014             2  0  |  0  3  0  |  0
8015     Proc0   5  6  |  7  0  0  |  8
8016     -------------------------------
8017     Proc1  18  0  | 19 20 21  |  0
8018     -------------------------------
8019     Proc2  26 27  |  0  0 28  | 29
8020             0  0  | 31 32 33  |  0
8021 .ve
8022 
8023 
8024     Concepts: matrices^submatrices
8025 
8026 .seealso: MatCreateSubMatrices()
8027 @*/
8028 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
8029 {
8030   PetscErrorCode ierr;
8031   PetscMPIInt    size;
8032   Mat            *local;
8033   IS             iscoltmp;
8034 
8035   PetscFunctionBegin;
8036   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8037   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
8038   if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
8039   PetscValidPointer(newmat,5);
8040   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5);
8041   PetscValidType(mat,1);
8042   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8043   if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX");
8044 
8045   MatCheckPreallocated(mat,1);
8046   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
8047 
8048   if (!iscol || isrow == iscol) {
8049     PetscBool   stride;
8050     PetscMPIInt grabentirematrix = 0,grab;
8051     ierr = PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);CHKERRQ(ierr);
8052     if (stride) {
8053       PetscInt first,step,n,rstart,rend;
8054       ierr = ISStrideGetInfo(isrow,&first,&step);CHKERRQ(ierr);
8055       if (step == 1) {
8056         ierr = MatGetOwnershipRange(mat,&rstart,&rend);CHKERRQ(ierr);
8057         if (rstart == first) {
8058           ierr = ISGetLocalSize(isrow,&n);CHKERRQ(ierr);
8059           if (n == rend-rstart) {
8060             grabentirematrix = 1;
8061           }
8062         }
8063       }
8064     }
8065     ierr = MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr);
8066     if (grab) {
8067       ierr = PetscInfo(mat,"Getting entire matrix as submatrix\n");CHKERRQ(ierr);
8068       if (cll == MAT_INITIAL_MATRIX) {
8069         *newmat = mat;
8070         ierr    = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr);
8071       }
8072       PetscFunctionReturn(0);
8073     }
8074   }
8075 
8076   if (!iscol) {
8077     ierr = ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr);
8078   } else {
8079     iscoltmp = iscol;
8080   }
8081 
8082   /* if original matrix is on just one processor then use submatrix generated */
8083   if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
8084     ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
8085     goto setproperties;
8086   } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) {
8087     ierr    = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
8088     *newmat = *local;
8089     ierr    = PetscFree(local);CHKERRQ(ierr);
8090     goto setproperties;
8091   } else if (!mat->ops->createsubmatrix) {
8092     /* Create a new matrix type that implements the operation using the full matrix */
8093     ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8094     switch (cll) {
8095     case MAT_INITIAL_MATRIX:
8096       ierr = MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr);
8097       break;
8098     case MAT_REUSE_MATRIX:
8099       ierr = MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr);
8100       break;
8101     default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
8102     }
8103     ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8104     goto setproperties;
8105   }
8106 
8107   if (!mat->ops->createsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8108   ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8109   ierr = (*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr);
8110   ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8111 
8112   /* Propagate symmetry information for diagonal blocks */
8113 setproperties:
8114   if (isrow == iscoltmp) {
8115     if (mat->symmetric_set && mat->symmetric) {
8116       ierr = MatSetOption(*newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
8117     }
8118     if (mat->structurally_symmetric_set && mat->structurally_symmetric) {
8119       ierr = MatSetOption(*newmat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
8120     }
8121     if (mat->hermitian_set && mat->hermitian) {
8122       ierr = MatSetOption(*newmat,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
8123     }
8124     if (mat->spd_set && mat->spd) {
8125       ierr = MatSetOption(*newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr);
8126     }
8127   }
8128 
8129   if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
8130   if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);}
8131   PetscFunctionReturn(0);
8132 }
8133 
8134 /*@
8135    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
8136    used during the assembly process to store values that belong to
8137    other processors.
8138 
8139    Not Collective
8140 
8141    Input Parameters:
8142 +  mat   - the matrix
8143 .  size  - the initial size of the stash.
8144 -  bsize - the initial size of the block-stash(if used).
8145 
8146    Options Database Keys:
8147 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
8148 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
8149 
8150    Level: intermediate
8151 
8152    Notes:
8153      The block-stash is used for values set with MatSetValuesBlocked() while
8154      the stash is used for values set with MatSetValues()
8155 
8156      Run with the option -info and look for output of the form
8157      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
8158      to determine the appropriate value, MM, to use for size and
8159      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
8160      to determine the value, BMM to use for bsize
8161 
8162    Concepts: stash^setting matrix size
8163    Concepts: matrices^stash
8164 
8165 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
8166 
8167 @*/
8168 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
8169 {
8170   PetscErrorCode ierr;
8171 
8172   PetscFunctionBegin;
8173   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8174   PetscValidType(mat,1);
8175   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
8176   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
8177   PetscFunctionReturn(0);
8178 }
8179 
8180 /*@
8181    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
8182      the matrix
8183 
8184    Neighbor-wise Collective on Mat
8185 
8186    Input Parameters:
8187 +  mat   - the matrix
8188 .  x,y - the vectors
8189 -  w - where the result is stored
8190 
8191    Level: intermediate
8192 
8193    Notes:
8194     w may be the same vector as y.
8195 
8196     This allows one to use either the restriction or interpolation (its transpose)
8197     matrix to do the interpolation
8198 
8199     Concepts: interpolation
8200 
8201 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
8202 
8203 @*/
8204 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
8205 {
8206   PetscErrorCode ierr;
8207   PetscInt       M,N,Ny;
8208 
8209   PetscFunctionBegin;
8210   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8211   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8212   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8213   PetscValidHeaderSpecific(w,VEC_CLASSID,4);
8214   PetscValidType(A,1);
8215   MatCheckPreallocated(A,1);
8216   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8217   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8218   if (M == Ny) {
8219     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
8220   } else {
8221     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
8222   }
8223   PetscFunctionReturn(0);
8224 }
8225 
8226 /*@
8227    MatInterpolate - y = A*x or A'*x depending on the shape of
8228      the matrix
8229 
8230    Neighbor-wise Collective on Mat
8231 
8232    Input Parameters:
8233 +  mat   - the matrix
8234 -  x,y - the vectors
8235 
8236    Level: intermediate
8237 
8238    Notes:
8239     This allows one to use either the restriction or interpolation (its transpose)
8240     matrix to do the interpolation
8241 
8242    Concepts: matrices^interpolation
8243 
8244 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
8245 
8246 @*/
8247 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
8248 {
8249   PetscErrorCode ierr;
8250   PetscInt       M,N,Ny;
8251 
8252   PetscFunctionBegin;
8253   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8254   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8255   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8256   PetscValidType(A,1);
8257   MatCheckPreallocated(A,1);
8258   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8259   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8260   if (M == Ny) {
8261     ierr = MatMult(A,x,y);CHKERRQ(ierr);
8262   } else {
8263     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
8264   }
8265   PetscFunctionReturn(0);
8266 }
8267 
8268 /*@
8269    MatRestrict - y = A*x or A'*x
8270 
8271    Neighbor-wise Collective on Mat
8272 
8273    Input Parameters:
8274 +  mat   - the matrix
8275 -  x,y - the vectors
8276 
8277    Level: intermediate
8278 
8279    Notes:
8280     This allows one to use either the restriction or interpolation (its transpose)
8281     matrix to do the restriction
8282 
8283    Concepts: matrices^restriction
8284 
8285 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
8286 
8287 @*/
8288 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
8289 {
8290   PetscErrorCode ierr;
8291   PetscInt       M,N,Ny;
8292 
8293   PetscFunctionBegin;
8294   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8295   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8296   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8297   PetscValidType(A,1);
8298   MatCheckPreallocated(A,1);
8299 
8300   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8301   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8302   if (M == Ny) {
8303     ierr = MatMult(A,x,y);CHKERRQ(ierr);
8304   } else {
8305     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
8306   }
8307   PetscFunctionReturn(0);
8308 }
8309 
8310 /*@
8311    MatGetNullSpace - retrieves the null space of a matrix.
8312 
8313    Logically Collective on Mat and MatNullSpace
8314 
8315    Input Parameters:
8316 +  mat - the matrix
8317 -  nullsp - the null space object
8318 
8319    Level: developer
8320 
8321    Concepts: null space^attaching to matrix
8322 
8323 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace()
8324 @*/
8325 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
8326 {
8327   PetscFunctionBegin;
8328   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8329   PetscValidPointer(nullsp,2);
8330   *nullsp = (mat->symmetric_set && mat->symmetric && !mat->nullsp) ? mat->transnullsp : mat->nullsp;
8331   PetscFunctionReturn(0);
8332 }
8333 
8334 /*@
8335    MatSetNullSpace - attaches a null space to a matrix.
8336 
8337    Logically Collective on Mat and MatNullSpace
8338 
8339    Input Parameters:
8340 +  mat - the matrix
8341 -  nullsp - the null space object
8342 
8343    Level: advanced
8344 
8345    Notes:
8346       This null space is used by the linear solvers. Overwrites any previous null space that may have been attached
8347 
8348       For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should
8349       call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense.
8350 
8351       You can remove the null space by calling this routine with an nullsp of NULL
8352 
8353 
8354       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8355    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).
8356    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
8357    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
8358    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).
8359 
8360       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8361 
8362     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
8363     routine also automatically calls MatSetTransposeNullSpace().
8364 
8365    Concepts: null space^attaching to matrix
8366 
8367 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8368 @*/
8369 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp)
8370 {
8371   PetscErrorCode ierr;
8372 
8373   PetscFunctionBegin;
8374   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8375   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8376   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8377   ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr);
8378   mat->nullsp = nullsp;
8379   if (mat->symmetric_set && mat->symmetric) {
8380     ierr = MatSetTransposeNullSpace(mat,nullsp);CHKERRQ(ierr);
8381   }
8382   PetscFunctionReturn(0);
8383 }
8384 
8385 /*@
8386    MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix.
8387 
8388    Logically Collective on Mat and MatNullSpace
8389 
8390    Input Parameters:
8391 +  mat - the matrix
8392 -  nullsp - the null space object
8393 
8394    Level: developer
8395 
8396    Concepts: null space^attaching to matrix
8397 
8398 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace()
8399 @*/
8400 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp)
8401 {
8402   PetscFunctionBegin;
8403   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8404   PetscValidType(mat,1);
8405   PetscValidPointer(nullsp,2);
8406   *nullsp = (mat->symmetric_set && mat->symmetric && !mat->transnullsp) ? mat->nullsp : mat->transnullsp;
8407   PetscFunctionReturn(0);
8408 }
8409 
8410 /*@
8411    MatSetTransposeNullSpace - attaches a null space to a matrix.
8412 
8413    Logically Collective on Mat and MatNullSpace
8414 
8415    Input Parameters:
8416 +  mat - the matrix
8417 -  nullsp - the null space object
8418 
8419    Level: advanced
8420 
8421    Notes:
8422       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.
8423       You must also call MatSetNullSpace()
8424 
8425 
8426       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8427    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).
8428    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
8429    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
8430    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).
8431 
8432       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8433 
8434    Concepts: null space^attaching to matrix
8435 
8436 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8437 @*/
8438 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp)
8439 {
8440   PetscErrorCode ierr;
8441 
8442   PetscFunctionBegin;
8443   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8444   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8445   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8446   ierr = MatNullSpaceDestroy(&mat->transnullsp);CHKERRQ(ierr);
8447   mat->transnullsp = nullsp;
8448   PetscFunctionReturn(0);
8449 }
8450 
8451 /*@
8452    MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions
8453         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.
8454 
8455    Logically Collective on Mat and MatNullSpace
8456 
8457    Input Parameters:
8458 +  mat - the matrix
8459 -  nullsp - the null space object
8460 
8461    Level: advanced
8462 
8463    Notes:
8464       Overwrites any previous near null space that may have been attached
8465 
8466       You can remove the null space by calling this routine with an nullsp of NULL
8467 
8468    Concepts: null space^attaching to matrix
8469 
8470 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace()
8471 @*/
8472 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
8473 {
8474   PetscErrorCode ierr;
8475 
8476   PetscFunctionBegin;
8477   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8478   PetscValidType(mat,1);
8479   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8480   MatCheckPreallocated(mat,1);
8481   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8482   ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr);
8483   mat->nearnullsp = nullsp;
8484   PetscFunctionReturn(0);
8485 }
8486 
8487 /*@
8488    MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()
8489 
8490    Not Collective
8491 
8492    Input Parameters:
8493 .  mat - the matrix
8494 
8495    Output Parameters:
8496 .  nullsp - the null space object, NULL if not set
8497 
8498    Level: developer
8499 
8500    Concepts: null space^attaching to matrix
8501 
8502 .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate()
8503 @*/
8504 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
8505 {
8506   PetscFunctionBegin;
8507   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8508   PetscValidType(mat,1);
8509   PetscValidPointer(nullsp,2);
8510   MatCheckPreallocated(mat,1);
8511   *nullsp = mat->nearnullsp;
8512   PetscFunctionReturn(0);
8513 }
8514 
8515 /*@C
8516    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
8517 
8518    Collective on Mat
8519 
8520    Input Parameters:
8521 +  mat - the matrix
8522 .  row - row/column permutation
8523 .  fill - expected fill factor >= 1.0
8524 -  level - level of fill, for ICC(k)
8525 
8526    Notes:
8527    Probably really in-place only when level of fill is zero, otherwise allocates
8528    new space to store factored matrix and deletes previous memory.
8529 
8530    Most users should employ the simplified KSP interface for linear solvers
8531    instead of working directly with matrix algebra routines such as this.
8532    See, e.g., KSPCreate().
8533 
8534    Level: developer
8535 
8536    Concepts: matrices^incomplete Cholesky factorization
8537    Concepts: Cholesky factorization
8538 
8539 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
8540 
8541     Developer Note: fortran interface is not autogenerated as the f90
8542     interface defintion cannot be generated correctly [due to MatFactorInfo]
8543 
8544 @*/
8545 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
8546 {
8547   PetscErrorCode ierr;
8548 
8549   PetscFunctionBegin;
8550   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8551   PetscValidType(mat,1);
8552   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
8553   PetscValidPointer(info,3);
8554   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
8555   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8556   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8557   if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8558   MatCheckPreallocated(mat,1);
8559   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
8560   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8561   PetscFunctionReturn(0);
8562 }
8563 
8564 /*@
8565    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
8566          ghosted ones.
8567 
8568    Not Collective
8569 
8570    Input Parameters:
8571 +  mat - the matrix
8572 -  diag = the diagonal values, including ghost ones
8573 
8574    Level: developer
8575 
8576    Notes:
8577     Works only for MPIAIJ and MPIBAIJ matrices
8578 
8579 .seealso: MatDiagonalScale()
8580 @*/
8581 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
8582 {
8583   PetscErrorCode ierr;
8584   PetscMPIInt    size;
8585 
8586   PetscFunctionBegin;
8587   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8588   PetscValidHeaderSpecific(diag,VEC_CLASSID,2);
8589   PetscValidType(mat,1);
8590 
8591   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8592   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8593   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
8594   if (size == 1) {
8595     PetscInt n,m;
8596     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
8597     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
8598     if (m == n) {
8599       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
8600     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
8601   } else {
8602     ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr);
8603   }
8604   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8605   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8606   PetscFunctionReturn(0);
8607 }
8608 
8609 /*@
8610    MatGetInertia - Gets the inertia from a factored matrix
8611 
8612    Collective on Mat
8613 
8614    Input Parameter:
8615 .  mat - the matrix
8616 
8617    Output Parameters:
8618 +   nneg - number of negative eigenvalues
8619 .   nzero - number of zero eigenvalues
8620 -   npos - number of positive eigenvalues
8621 
8622    Level: advanced
8623 
8624    Notes:
8625     Matrix must have been factored by MatCholeskyFactor()
8626 
8627 
8628 @*/
8629 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
8630 {
8631   PetscErrorCode ierr;
8632 
8633   PetscFunctionBegin;
8634   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8635   PetscValidType(mat,1);
8636   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8637   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
8638   if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8639   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
8640   PetscFunctionReturn(0);
8641 }
8642 
8643 /* ----------------------------------------------------------------*/
8644 /*@C
8645    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
8646 
8647    Neighbor-wise Collective on Mat and Vecs
8648 
8649    Input Parameters:
8650 +  mat - the factored matrix
8651 -  b - the right-hand-side vectors
8652 
8653    Output Parameter:
8654 .  x - the result vectors
8655 
8656    Notes:
8657    The vectors b and x cannot be the same.  I.e., one cannot
8658    call MatSolves(A,x,x).
8659 
8660    Notes:
8661    Most users should employ the simplified KSP interface for linear solvers
8662    instead of working directly with matrix algebra routines such as this.
8663    See, e.g., KSPCreate().
8664 
8665    Level: developer
8666 
8667    Concepts: matrices^triangular solves
8668 
8669 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
8670 @*/
8671 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
8672 {
8673   PetscErrorCode ierr;
8674 
8675   PetscFunctionBegin;
8676   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8677   PetscValidType(mat,1);
8678   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
8679   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8680   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
8681 
8682   if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8683   MatCheckPreallocated(mat,1);
8684   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8685   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
8686   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8687   PetscFunctionReturn(0);
8688 }
8689 
8690 /*@
8691    MatIsSymmetric - Test whether a matrix is symmetric
8692 
8693    Collective on Mat
8694 
8695    Input Parameter:
8696 +  A - the matrix to test
8697 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
8698 
8699    Output Parameters:
8700 .  flg - the result
8701 
8702    Notes:
8703     For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
8704 
8705    Level: intermediate
8706 
8707    Concepts: matrix^symmetry
8708 
8709 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
8710 @*/
8711 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
8712 {
8713   PetscErrorCode ierr;
8714 
8715   PetscFunctionBegin;
8716   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8717   PetscValidPointer(flg,2);
8718 
8719   if (!A->symmetric_set) {
8720     if (!A->ops->issymmetric) {
8721       MatType mattype;
8722       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8723       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8724     }
8725     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8726     if (!tol) {
8727       A->symmetric_set = PETSC_TRUE;
8728       A->symmetric     = *flg;
8729       if (A->symmetric) {
8730         A->structurally_symmetric_set = PETSC_TRUE;
8731         A->structurally_symmetric     = PETSC_TRUE;
8732       }
8733     }
8734   } else if (A->symmetric) {
8735     *flg = PETSC_TRUE;
8736   } else if (!tol) {
8737     *flg = PETSC_FALSE;
8738   } else {
8739     if (!A->ops->issymmetric) {
8740       MatType mattype;
8741       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8742       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8743     }
8744     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8745   }
8746   PetscFunctionReturn(0);
8747 }
8748 
8749 /*@
8750    MatIsHermitian - Test whether a matrix is Hermitian
8751 
8752    Collective on Mat
8753 
8754    Input Parameter:
8755 +  A - the matrix to test
8756 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
8757 
8758    Output Parameters:
8759 .  flg - the result
8760 
8761    Level: intermediate
8762 
8763    Concepts: matrix^symmetry
8764 
8765 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
8766           MatIsSymmetricKnown(), MatIsSymmetric()
8767 @*/
8768 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
8769 {
8770   PetscErrorCode ierr;
8771 
8772   PetscFunctionBegin;
8773   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8774   PetscValidPointer(flg,2);
8775 
8776   if (!A->hermitian_set) {
8777     if (!A->ops->ishermitian) {
8778       MatType mattype;
8779       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8780       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8781     }
8782     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8783     if (!tol) {
8784       A->hermitian_set = PETSC_TRUE;
8785       A->hermitian     = *flg;
8786       if (A->hermitian) {
8787         A->structurally_symmetric_set = PETSC_TRUE;
8788         A->structurally_symmetric     = PETSC_TRUE;
8789       }
8790     }
8791   } else if (A->hermitian) {
8792     *flg = PETSC_TRUE;
8793   } else if (!tol) {
8794     *flg = PETSC_FALSE;
8795   } else {
8796     if (!A->ops->ishermitian) {
8797       MatType mattype;
8798       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8799       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8800     }
8801     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8802   }
8803   PetscFunctionReturn(0);
8804 }
8805 
8806 /*@
8807    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
8808 
8809    Not Collective
8810 
8811    Input Parameter:
8812 .  A - the matrix to check
8813 
8814    Output Parameters:
8815 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
8816 -  flg - the result
8817 
8818    Level: advanced
8819 
8820    Concepts: matrix^symmetry
8821 
8822    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
8823          if you want it explicitly checked
8824 
8825 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8826 @*/
8827 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8828 {
8829   PetscFunctionBegin;
8830   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8831   PetscValidPointer(set,2);
8832   PetscValidPointer(flg,3);
8833   if (A->symmetric_set) {
8834     *set = PETSC_TRUE;
8835     *flg = A->symmetric;
8836   } else {
8837     *set = PETSC_FALSE;
8838   }
8839   PetscFunctionReturn(0);
8840 }
8841 
8842 /*@
8843    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
8844 
8845    Not Collective
8846 
8847    Input Parameter:
8848 .  A - the matrix to check
8849 
8850    Output Parameters:
8851 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8852 -  flg - the result
8853 
8854    Level: advanced
8855 
8856    Concepts: matrix^symmetry
8857 
8858    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8859          if you want it explicitly checked
8860 
8861 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8862 @*/
8863 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8864 {
8865   PetscFunctionBegin;
8866   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8867   PetscValidPointer(set,2);
8868   PetscValidPointer(flg,3);
8869   if (A->hermitian_set) {
8870     *set = PETSC_TRUE;
8871     *flg = A->hermitian;
8872   } else {
8873     *set = PETSC_FALSE;
8874   }
8875   PetscFunctionReturn(0);
8876 }
8877 
8878 /*@
8879    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
8880 
8881    Collective on Mat
8882 
8883    Input Parameter:
8884 .  A - the matrix to test
8885 
8886    Output Parameters:
8887 .  flg - the result
8888 
8889    Level: intermediate
8890 
8891    Concepts: matrix^symmetry
8892 
8893 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8894 @*/
8895 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
8896 {
8897   PetscErrorCode ierr;
8898 
8899   PetscFunctionBegin;
8900   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8901   PetscValidPointer(flg,2);
8902   if (!A->structurally_symmetric_set) {
8903     if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8904     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
8905 
8906     A->structurally_symmetric_set = PETSC_TRUE;
8907   }
8908   *flg = A->structurally_symmetric;
8909   PetscFunctionReturn(0);
8910 }
8911 
8912 /*@
8913    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8914        to be communicated to other processors during the MatAssemblyBegin/End() process
8915 
8916     Not collective
8917 
8918    Input Parameter:
8919 .   vec - the vector
8920 
8921    Output Parameters:
8922 +   nstash   - the size of the stash
8923 .   reallocs - the number of additional mallocs incurred.
8924 .   bnstash   - the size of the block stash
8925 -   breallocs - the number of additional mallocs incurred.in the block stash
8926 
8927    Level: advanced
8928 
8929 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
8930 
8931 @*/
8932 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8933 {
8934   PetscErrorCode ierr;
8935 
8936   PetscFunctionBegin;
8937   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
8938   ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
8939   PetscFunctionReturn(0);
8940 }
8941 
8942 /*@C
8943    MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same
8944      parallel layout
8945 
8946    Collective on Mat
8947 
8948    Input Parameter:
8949 .  mat - the matrix
8950 
8951    Output Parameter:
8952 +   right - (optional) vector that the matrix can be multiplied against
8953 -   left - (optional) vector that the matrix vector product can be stored in
8954 
8955    Notes:
8956     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().
8957 
8958   Notes:
8959     These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed
8960 
8961   Level: advanced
8962 
8963 .seealso: MatCreate(), VecDestroy()
8964 @*/
8965 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left)
8966 {
8967   PetscErrorCode ierr;
8968 
8969   PetscFunctionBegin;
8970   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8971   PetscValidType(mat,1);
8972   if (mat->ops->getvecs) {
8973     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
8974   } else {
8975     PetscInt rbs,cbs;
8976     ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr);
8977     if (right) {
8978       if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup");
8979       ierr = VecCreate(PetscObjectComm((PetscObject)mat),right);CHKERRQ(ierr);
8980       ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8981       ierr = VecSetBlockSize(*right,cbs);CHKERRQ(ierr);
8982       ierr = VecSetType(*right,mat->defaultvectype);CHKERRQ(ierr);
8983       ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr);
8984     }
8985     if (left) {
8986       if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup");
8987       ierr = VecCreate(PetscObjectComm((PetscObject)mat),left);CHKERRQ(ierr);
8988       ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8989       ierr = VecSetBlockSize(*left,rbs);CHKERRQ(ierr);
8990       ierr = VecSetType(*left,mat->defaultvectype);CHKERRQ(ierr);
8991       ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr);
8992     }
8993   }
8994   PetscFunctionReturn(0);
8995 }
8996 
8997 /*@C
8998    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8999      with default values.
9000 
9001    Not Collective
9002 
9003    Input Parameters:
9004 .    info - the MatFactorInfo data structure
9005 
9006 
9007    Notes:
9008     The solvers are generally used through the KSP and PC objects, for example
9009           PCLU, PCILU, PCCHOLESKY, PCICC
9010 
9011    Level: developer
9012 
9013 .seealso: MatFactorInfo
9014 
9015     Developer Note: fortran interface is not autogenerated as the f90
9016     interface defintion cannot be generated correctly [due to MatFactorInfo]
9017 
9018 @*/
9019 
9020 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
9021 {
9022   PetscErrorCode ierr;
9023 
9024   PetscFunctionBegin;
9025   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
9026   PetscFunctionReturn(0);
9027 }
9028 
9029 /*@
9030    MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed
9031 
9032    Collective on Mat
9033 
9034    Input Parameters:
9035 +  mat - the factored matrix
9036 -  is - the index set defining the Schur indices (0-based)
9037 
9038    Notes:
9039     Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system.
9040 
9041    You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call.
9042 
9043    Level: developer
9044 
9045    Concepts:
9046 
9047 .seealso: MatGetFactor(), MatFactorGetSchurComplement(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSolveSchurComplement(),
9048           MatFactorSolveSchurComplementTranspose(), MatFactorSolveSchurComplement()
9049 
9050 @*/
9051 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is)
9052 {
9053   PetscErrorCode ierr,(*f)(Mat,IS);
9054 
9055   PetscFunctionBegin;
9056   PetscValidType(mat,1);
9057   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9058   PetscValidType(is,2);
9059   PetscValidHeaderSpecific(is,IS_CLASSID,2);
9060   PetscCheckSameComm(mat,1,is,2);
9061   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
9062   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);CHKERRQ(ierr);
9063   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");
9064   if (mat->schur) {
9065     ierr = MatDestroy(&mat->schur);CHKERRQ(ierr);
9066   }
9067   ierr = (*f)(mat,is);CHKERRQ(ierr);
9068   if (!mat->schur) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created");
9069   ierr = MatFactorSetUpInPlaceSchur_Private(mat);CHKERRQ(ierr);
9070   PetscFunctionReturn(0);
9071 }
9072 
9073 /*@
9074   MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step
9075 
9076    Logically Collective on Mat
9077 
9078    Input Parameters:
9079 +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
9080 .  S - location where to return the Schur complement, can be NULL
9081 -  status - the status of the Schur complement matrix, can be NULL
9082 
9083    Notes:
9084    You must call MatFactorSetSchurIS() before calling this routine.
9085 
9086    The routine provides a copy of the Schur matrix stored within the solver data structures.
9087    The caller must destroy the object when it is no longer needed.
9088    If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse.
9089 
9090    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)
9091 
9092    Developer Notes:
9093     The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc
9094    matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix.
9095 
9096    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
9097 
9098    Level: advanced
9099 
9100    References:
9101 
9102 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorSchurStatus
9103 @*/
9104 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
9105 {
9106   PetscErrorCode ierr;
9107 
9108   PetscFunctionBegin;
9109   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9110   if (S) PetscValidPointer(S,2);
9111   if (status) PetscValidPointer(status,3);
9112   if (S) {
9113     PetscErrorCode (*f)(Mat,Mat*);
9114 
9115     ierr = PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f);CHKERRQ(ierr);
9116     if (f) {
9117       ierr = (*f)(F,S);CHKERRQ(ierr);
9118     } else {
9119       ierr = MatDuplicate(F->schur,MAT_COPY_VALUES,S);CHKERRQ(ierr);
9120     }
9121   }
9122   if (status) *status = F->schur_status;
9123   PetscFunctionReturn(0);
9124 }
9125 
9126 /*@
9127   MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix
9128 
9129    Logically Collective on Mat
9130 
9131    Input Parameters:
9132 +  F - the factored matrix obtained by calling MatGetFactor()
9133 .  *S - location where to return the Schur complement, can be NULL
9134 -  status - the status of the Schur complement matrix, can be NULL
9135 
9136    Notes:
9137    You must call MatFactorSetSchurIS() before calling this routine.
9138 
9139    Schur complement mode is currently implemented for sequential matrices.
9140    The routine returns a the Schur Complement stored within the data strutures of the solver.
9141    If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement.
9142    The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed.
9143 
9144    Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix
9145 
9146    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
9147 
9148    Level: advanced
9149 
9150    References:
9151 
9152 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
9153 @*/
9154 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
9155 {
9156   PetscFunctionBegin;
9157   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9158   if (S) PetscValidPointer(S,2);
9159   if (status) PetscValidPointer(status,3);
9160   if (S) *S = F->schur;
9161   if (status) *status = F->schur_status;
9162   PetscFunctionReturn(0);
9163 }
9164 
9165 /*@
9166   MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement
9167 
9168    Logically Collective on Mat
9169 
9170    Input Parameters:
9171 +  F - the factored matrix obtained by calling MatGetFactor()
9172 .  *S - location where the Schur complement is stored
9173 -  status - the status of the Schur complement matrix (see MatFactorSchurStatus)
9174 
9175    Notes:
9176 
9177    Level: advanced
9178 
9179    References:
9180 
9181 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
9182 @*/
9183 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status)
9184 {
9185   PetscErrorCode ierr;
9186 
9187   PetscFunctionBegin;
9188   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9189   if (S) {
9190     PetscValidHeaderSpecific(*S,MAT_CLASSID,2);
9191     *S = NULL;
9192   }
9193   F->schur_status = status;
9194   ierr = MatFactorUpdateSchurStatus_Private(F);CHKERRQ(ierr);
9195   PetscFunctionReturn(0);
9196 }
9197 
9198 /*@
9199   MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step
9200 
9201    Logically Collective on Mat
9202 
9203    Input Parameters:
9204 +  F - the factored matrix obtained by calling MatGetFactor()
9205 .  rhs - location where the right hand side of the Schur complement system is stored
9206 -  sol - location where the solution of the Schur complement system has to be returned
9207 
9208    Notes:
9209    The sizes of the vectors should match the size of the Schur complement
9210 
9211    Must be called after MatFactorSetSchurIS()
9212 
9213    Level: advanced
9214 
9215    References:
9216 
9217 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplement()
9218 @*/
9219 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol)
9220 {
9221   PetscErrorCode ierr;
9222 
9223   PetscFunctionBegin;
9224   PetscValidType(F,1);
9225   PetscValidType(rhs,2);
9226   PetscValidType(sol,3);
9227   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9228   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
9229   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
9230   PetscCheckSameComm(F,1,rhs,2);
9231   PetscCheckSameComm(F,1,sol,3);
9232   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9233   switch (F->schur_status) {
9234   case MAT_FACTOR_SCHUR_FACTORED:
9235     ierr = MatSolveTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
9236     break;
9237   case MAT_FACTOR_SCHUR_INVERTED:
9238     ierr = MatMultTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
9239     break;
9240   default:
9241     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9242     break;
9243   }
9244   PetscFunctionReturn(0);
9245 }
9246 
9247 /*@
9248   MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step
9249 
9250    Logically Collective on Mat
9251 
9252    Input Parameters:
9253 +  F - the factored matrix obtained by calling MatGetFactor()
9254 .  rhs - location where the right hand side of the Schur complement system is stored
9255 -  sol - location where the solution of the Schur complement system has to be returned
9256 
9257    Notes:
9258    The sizes of the vectors should match the size of the Schur complement
9259 
9260    Must be called after MatFactorSetSchurIS()
9261 
9262    Level: advanced
9263 
9264    References:
9265 
9266 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplementTranspose()
9267 @*/
9268 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol)
9269 {
9270   PetscErrorCode ierr;
9271 
9272   PetscFunctionBegin;
9273   PetscValidType(F,1);
9274   PetscValidType(rhs,2);
9275   PetscValidType(sol,3);
9276   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9277   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
9278   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
9279   PetscCheckSameComm(F,1,rhs,2);
9280   PetscCheckSameComm(F,1,sol,3);
9281   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9282   switch (F->schur_status) {
9283   case MAT_FACTOR_SCHUR_FACTORED:
9284     ierr = MatSolve(F->schur,rhs,sol);CHKERRQ(ierr);
9285     break;
9286   case MAT_FACTOR_SCHUR_INVERTED:
9287     ierr = MatMult(F->schur,rhs,sol);CHKERRQ(ierr);
9288     break;
9289   default:
9290     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9291     break;
9292   }
9293   PetscFunctionReturn(0);
9294 }
9295 
9296 /*@
9297   MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step
9298 
9299    Logically Collective on Mat
9300 
9301    Input Parameters:
9302 +  F - the factored matrix obtained by calling MatGetFactor()
9303 
9304    Notes:
9305     Must be called after MatFactorSetSchurIS().
9306 
9307    Call MatFactorGetSchurComplement() or  MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it.
9308 
9309    Level: advanced
9310 
9311    References:
9312 
9313 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorCreateSchurComplement()
9314 @*/
9315 PetscErrorCode MatFactorInvertSchurComplement(Mat F)
9316 {
9317   PetscErrorCode ierr;
9318 
9319   PetscFunctionBegin;
9320   PetscValidType(F,1);
9321   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9322   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0);
9323   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9324   ierr = MatFactorInvertSchurComplement_Private(F);CHKERRQ(ierr);
9325   F->schur_status = MAT_FACTOR_SCHUR_INVERTED;
9326   PetscFunctionReturn(0);
9327 }
9328 
9329 /*@
9330   MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step
9331 
9332    Logically Collective on Mat
9333 
9334    Input Parameters:
9335 +  F - the factored matrix obtained by calling MatGetFactor()
9336 
9337    Notes:
9338     Must be called after MatFactorSetSchurIS().
9339 
9340    Level: advanced
9341 
9342    References:
9343 
9344 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorInvertSchurComplement()
9345 @*/
9346 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F)
9347 {
9348   PetscErrorCode ierr;
9349 
9350   PetscFunctionBegin;
9351   PetscValidType(F,1);
9352   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9353   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0);
9354   ierr = MatFactorFactorizeSchurComplement_Private(F);CHKERRQ(ierr);
9355   F->schur_status = MAT_FACTOR_SCHUR_FACTORED;
9356   PetscFunctionReturn(0);
9357 }
9358 
9359 /*@
9360    MatPtAP - Creates the matrix product C = P^T * A * P
9361 
9362    Neighbor-wise Collective on Mat
9363 
9364    Input Parameters:
9365 +  A - the matrix
9366 .  P - the projection matrix
9367 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9368 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate
9369           if the result is a dense matrix this is irrelevent
9370 
9371    Output Parameters:
9372 .  C - the product matrix
9373 
9374    Notes:
9375    C will be created and must be destroyed by the user with MatDestroy().
9376 
9377    This routine is currently only implemented for pairs of sequential dense matrices, AIJ matrices and classes
9378    which inherit from AIJ.
9379 
9380    Level: intermediate
9381 
9382 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
9383 @*/
9384 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
9385 {
9386   PetscErrorCode ierr;
9387   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9388   PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
9389   PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9390   PetscBool      sametype;
9391 
9392   PetscFunctionBegin;
9393   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9394   PetscValidType(A,1);
9395   MatCheckPreallocated(A,1);
9396   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9397   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9398   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9399   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9400   PetscValidType(P,2);
9401   MatCheckPreallocated(P,2);
9402   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9403   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9404 
9405   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);
9406   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);
9407   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9408   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9409 
9410   if (scall == MAT_REUSE_MATRIX) {
9411     PetscValidPointer(*C,5);
9412     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9413 
9414     if (!(*C)->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You cannot use MAT_REUSE_MATRIX");
9415     ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9416     ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9417     ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr);
9418     ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9419     ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9420     PetscFunctionReturn(0);
9421   }
9422 
9423   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9424   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9425 
9426   fA = A->ops->ptap;
9427   fP = P->ops->ptap;
9428   ierr = PetscStrcmp(((PetscObject)A)->type_name,((PetscObject)P)->type_name,&sametype);CHKERRQ(ierr);
9429   if (fP == fA && sametype) {
9430     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name);
9431     ptap = fA;
9432   } else {
9433     /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
9434     char ptapname[256];
9435     ierr = PetscStrncpy(ptapname,"MatPtAP_",sizeof(ptapname));CHKERRQ(ierr);
9436     ierr = PetscStrlcat(ptapname,((PetscObject)A)->type_name,sizeof(ptapname));CHKERRQ(ierr);
9437     ierr = PetscStrlcat(ptapname,"_",sizeof(ptapname));CHKERRQ(ierr);
9438     ierr = PetscStrlcat(ptapname,((PetscObject)P)->type_name,sizeof(ptapname));CHKERRQ(ierr);
9439     ierr = PetscStrlcat(ptapname,"_C",sizeof(ptapname));CHKERRQ(ierr); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
9440     ierr = PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);CHKERRQ(ierr);
9441     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);
9442   }
9443 
9444   ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9445   ierr = (*ptap)(A,P,scall,fill,C);CHKERRQ(ierr);
9446   ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9447   if (A->symmetric_set && A->symmetric) {
9448     ierr = MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
9449   }
9450   PetscFunctionReturn(0);
9451 }
9452 
9453 /*@
9454    MatPtAPNumeric - Computes the matrix product C = P^T * A * P
9455 
9456    Neighbor-wise Collective on Mat
9457 
9458    Input Parameters:
9459 +  A - the matrix
9460 -  P - the projection matrix
9461 
9462    Output Parameters:
9463 .  C - the product matrix
9464 
9465    Notes:
9466    C must have been created by calling MatPtAPSymbolic and must be destroyed by
9467    the user using MatDeatroy().
9468 
9469    This routine is currently only implemented for pairs of AIJ matrices and classes
9470    which inherit from AIJ.  C will be of type MATAIJ.
9471 
9472    Level: intermediate
9473 
9474 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
9475 @*/
9476 PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C)
9477 {
9478   PetscErrorCode ierr;
9479 
9480   PetscFunctionBegin;
9481   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9482   PetscValidType(A,1);
9483   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9484   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9485   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9486   PetscValidType(P,2);
9487   MatCheckPreallocated(P,2);
9488   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9489   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9490   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9491   PetscValidType(C,3);
9492   MatCheckPreallocated(C,3);
9493   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9494   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);
9495   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);
9496   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);
9497   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);
9498   MatCheckPreallocated(A,1);
9499 
9500   if (!C->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You should call MatPtAPSymbolic first");
9501   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9502   ierr = (*C->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr);
9503   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9504   PetscFunctionReturn(0);
9505 }
9506 
9507 /*@
9508    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P
9509 
9510    Neighbor-wise Collective on Mat
9511 
9512    Input Parameters:
9513 +  A - the matrix
9514 -  P - the projection matrix
9515 
9516    Output Parameters:
9517 .  C - the (i,j) structure of the product matrix
9518 
9519    Notes:
9520    C will be created and must be destroyed by the user with MatDestroy().
9521 
9522    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9523    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9524    this (i,j) structure by calling MatPtAPNumeric().
9525 
9526    Level: intermediate
9527 
9528 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
9529 @*/
9530 PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
9531 {
9532   PetscErrorCode ierr;
9533 
9534   PetscFunctionBegin;
9535   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9536   PetscValidType(A,1);
9537   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9538   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9539   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9540   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9541   PetscValidType(P,2);
9542   MatCheckPreallocated(P,2);
9543   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9544   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9545   PetscValidPointer(C,3);
9546 
9547   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);
9548   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);
9549   MatCheckPreallocated(A,1);
9550 
9551   if (!A->ops->ptapsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatType %s",((PetscObject)A)->type_name);
9552   ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
9553   ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr);
9554   ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
9555 
9556   /* ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); NO! this is not always true -ma */
9557   PetscFunctionReturn(0);
9558 }
9559 
9560 /*@
9561    MatRARt - Creates the matrix product C = R * A * R^T
9562 
9563    Neighbor-wise Collective on Mat
9564 
9565    Input Parameters:
9566 +  A - the matrix
9567 .  R - the projection matrix
9568 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9569 -  fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate
9570           if the result is a dense matrix this is irrelevent
9571 
9572    Output Parameters:
9573 .  C - the product matrix
9574 
9575    Notes:
9576    C will be created and must be destroyed by the user with MatDestroy().
9577 
9578    This routine is currently only implemented for pairs of AIJ matrices and classes
9579    which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes,
9580    parallel MatRARt is implemented via explicit transpose of R, which could be very expensive.
9581    We recommend using MatPtAP().
9582 
9583    Level: intermediate
9584 
9585 .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
9586 @*/
9587 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
9588 {
9589   PetscErrorCode ierr;
9590 
9591   PetscFunctionBegin;
9592   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9593   PetscValidType(A,1);
9594   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9595   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9596   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9597   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9598   PetscValidType(R,2);
9599   MatCheckPreallocated(R,2);
9600   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9601   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9602   PetscValidPointer(C,3);
9603   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);
9604 
9605   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9606   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9607   MatCheckPreallocated(A,1);
9608 
9609   if (!A->ops->rart) {
9610     Mat Rt;
9611     ierr = MatTranspose(R,MAT_INITIAL_MATRIX,&Rt);CHKERRQ(ierr);
9612     ierr = MatMatMatMult(R,A,Rt,scall,fill,C);CHKERRQ(ierr);
9613     ierr = MatDestroy(&Rt);CHKERRQ(ierr);
9614     PetscFunctionReturn(0);
9615   }
9616   ierr = PetscLogEventBegin(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
9617   ierr = (*A->ops->rart)(A,R,scall,fill,C);CHKERRQ(ierr);
9618   ierr = PetscLogEventEnd(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
9619   PetscFunctionReturn(0);
9620 }
9621 
9622 /*@
9623    MatRARtNumeric - Computes the matrix product C = R * A * R^T
9624 
9625    Neighbor-wise Collective on Mat
9626 
9627    Input Parameters:
9628 +  A - the matrix
9629 -  R - the projection matrix
9630 
9631    Output Parameters:
9632 .  C - the product matrix
9633 
9634    Notes:
9635    C must have been created by calling MatRARtSymbolic and must be destroyed by
9636    the user using MatDestroy().
9637 
9638    This routine is currently only implemented for pairs of AIJ matrices and classes
9639    which inherit from AIJ.  C will be of type MATAIJ.
9640 
9641    Level: intermediate
9642 
9643 .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
9644 @*/
9645 PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C)
9646 {
9647   PetscErrorCode ierr;
9648 
9649   PetscFunctionBegin;
9650   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9651   PetscValidType(A,1);
9652   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9653   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9654   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9655   PetscValidType(R,2);
9656   MatCheckPreallocated(R,2);
9657   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9658   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9659   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9660   PetscValidType(C,3);
9661   MatCheckPreallocated(C,3);
9662   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9663   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);
9664   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);
9665   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);
9666   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);
9667   MatCheckPreallocated(A,1);
9668 
9669   ierr = PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
9670   ierr = (*A->ops->rartnumeric)(A,R,C);CHKERRQ(ierr);
9671   ierr = PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
9672   PetscFunctionReturn(0);
9673 }
9674 
9675 /*@
9676    MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T
9677 
9678    Neighbor-wise Collective on Mat
9679 
9680    Input Parameters:
9681 +  A - the matrix
9682 -  R - the projection matrix
9683 
9684    Output Parameters:
9685 .  C - the (i,j) structure of the product matrix
9686 
9687    Notes:
9688    C will be created and must be destroyed by the user with MatDestroy().
9689 
9690    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9691    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9692    this (i,j) structure by calling MatRARtNumeric().
9693 
9694    Level: intermediate
9695 
9696 .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
9697 @*/
9698 PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
9699 {
9700   PetscErrorCode ierr;
9701 
9702   PetscFunctionBegin;
9703   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9704   PetscValidType(A,1);
9705   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9706   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9707   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9708   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9709   PetscValidType(R,2);
9710   MatCheckPreallocated(R,2);
9711   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9712   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9713   PetscValidPointer(C,3);
9714 
9715   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);
9716   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);
9717   MatCheckPreallocated(A,1);
9718   ierr = PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
9719   ierr = (*A->ops->rartsymbolic)(A,R,fill,C);CHKERRQ(ierr);
9720   ierr = PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
9721 
9722   ierr = MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));CHKERRQ(ierr);
9723   PetscFunctionReturn(0);
9724 }
9725 
9726 /*@
9727    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
9728 
9729    Neighbor-wise Collective on Mat
9730 
9731    Input Parameters:
9732 +  A - the left matrix
9733 .  B - the right matrix
9734 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9735 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
9736           if the result is a dense matrix this is irrelevent
9737 
9738    Output Parameters:
9739 .  C - the product matrix
9740 
9741    Notes:
9742    Unless scall is MAT_REUSE_MATRIX C will be created.
9743 
9744    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
9745    call to this function with either MAT_INITIAL_MATRIX or MatMatMultSymbolic()
9746 
9747    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9748    actually needed.
9749 
9750    If you have many matrices with the same non-zero structure to multiply, you
9751    should either
9752 $   1) use MAT_REUSE_MATRIX in all calls but the first or
9753 $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
9754    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
9755    with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse.
9756 
9757    Level: intermediate
9758 
9759 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(),  MatMatTransposeMult(), MatPtAP()
9760 @*/
9761 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9762 {
9763   PetscErrorCode ierr;
9764   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9765   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9766   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9767 
9768   PetscFunctionBegin;
9769   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9770   PetscValidType(A,1);
9771   MatCheckPreallocated(A,1);
9772   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9773   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9774   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9775   PetscValidType(B,2);
9776   MatCheckPreallocated(B,2);
9777   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9778   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9779   PetscValidPointer(C,3);
9780   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9781   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);
9782   if (scall == MAT_REUSE_MATRIX) {
9783     PetscValidPointer(*C,5);
9784     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9785     ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9786     ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9787     ierr = (*(*C)->ops->matmultnumeric)(A,B,*C);CHKERRQ(ierr);
9788     ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9789     ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9790     PetscFunctionReturn(0);
9791   }
9792   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9793   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9794 
9795   fA = A->ops->matmult;
9796   fB = B->ops->matmult;
9797   if (fB == fA) {
9798     if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
9799     mult = fB;
9800   } else {
9801     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9802     char multname[256];
9803     ierr = PetscStrncpy(multname,"MatMatMult_",sizeof(multname));CHKERRQ(ierr);
9804     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
9805     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
9806     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
9807     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9808     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
9809     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);
9810   }
9811   ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9812   ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr);
9813   ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9814   PetscFunctionReturn(0);
9815 }
9816 
9817 /*@
9818    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
9819    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().
9820 
9821    Neighbor-wise Collective on Mat
9822 
9823    Input Parameters:
9824 +  A - the left matrix
9825 .  B - the right matrix
9826 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
9827       if C is a dense matrix this is irrelevent
9828 
9829    Output Parameters:
9830 .  C - the product matrix
9831 
9832    Notes:
9833    Unless scall is MAT_REUSE_MATRIX C will be created.
9834 
9835    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9836    actually needed.
9837 
9838    This routine is currently implemented for
9839     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
9840     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9841     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9842 
9843    Level: intermediate
9844 
9845    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
9846      We should incorporate them into PETSc.
9847 
9848 .seealso: MatMatMult(), MatMatMultNumeric()
9849 @*/
9850 PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
9851 {
9852   PetscErrorCode ierr;
9853   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*);
9854   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*);
9855   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL;
9856 
9857   PetscFunctionBegin;
9858   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9859   PetscValidType(A,1);
9860   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9861   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9862 
9863   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9864   PetscValidType(B,2);
9865   MatCheckPreallocated(B,2);
9866   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9867   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9868   PetscValidPointer(C,3);
9869 
9870   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);
9871   if (fill == PETSC_DEFAULT) fill = 2.0;
9872   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9873   MatCheckPreallocated(A,1);
9874 
9875   Asymbolic = A->ops->matmultsymbolic;
9876   Bsymbolic = B->ops->matmultsymbolic;
9877   if (Asymbolic == Bsymbolic) {
9878     if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
9879     symbolic = Bsymbolic;
9880   } else { /* dispatch based on the type of A and B */
9881     char symbolicname[256];
9882     ierr = PetscStrncpy(symbolicname,"MatMatMultSymbolic_",sizeof(symbolicname));CHKERRQ(ierr);
9883     ierr = PetscStrlcat(symbolicname,((PetscObject)A)->type_name,sizeof(symbolicname));CHKERRQ(ierr);
9884     ierr = PetscStrlcat(symbolicname,"_",sizeof(symbolicname));CHKERRQ(ierr);
9885     ierr = PetscStrlcat(symbolicname,((PetscObject)B)->type_name,sizeof(symbolicname));CHKERRQ(ierr);
9886     ierr = PetscStrlcat(symbolicname,"_C",sizeof(symbolicname));CHKERRQ(ierr);
9887     ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);CHKERRQ(ierr);
9888     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);
9889   }
9890   ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9891   ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr);
9892   ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9893   PetscFunctionReturn(0);
9894 }
9895 
9896 /*@
9897    MatMatMultNumeric - Performs the numeric matrix-matrix product.
9898    Call this routine after first calling MatMatMultSymbolic().
9899 
9900    Neighbor-wise Collective on Mat
9901 
9902    Input Parameters:
9903 +  A - the left matrix
9904 -  B - the right matrix
9905 
9906    Output Parameters:
9907 .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
9908 
9909    Notes:
9910    C must have been created with MatMatMultSymbolic().
9911 
9912    This routine is currently implemented for
9913     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
9914     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9915     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9916 
9917    Level: intermediate
9918 
9919 .seealso: MatMatMult(), MatMatMultSymbolic()
9920 @*/
9921 PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C)
9922 {
9923   PetscErrorCode ierr;
9924 
9925   PetscFunctionBegin;
9926   ierr = MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);CHKERRQ(ierr);
9927   PetscFunctionReturn(0);
9928 }
9929 
9930 /*@
9931    MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.
9932 
9933    Neighbor-wise Collective on Mat
9934 
9935    Input Parameters:
9936 +  A - the left matrix
9937 .  B - the right matrix
9938 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9939 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9940 
9941    Output Parameters:
9942 .  C - the product matrix
9943 
9944    Notes:
9945    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9946 
9947    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9948 
9949   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9950    actually needed.
9951 
9952    This routine is currently only implemented for pairs of SeqAIJ matrices, for the SeqDense class,
9953    and for pairs of MPIDense matrices.
9954 
9955    Options Database Keys:
9956 +  -matmattransmult_mpidense_mpidense_via {allgatherv,cyclic} - Choose between algorthims for MPIDense matrices: the
9957                                                                 first redundantly copies the transposed B matrix on each process and requiers O(log P) communication complexity;
9958                                                                 the second never stores more than one portion of the B matrix at a time by requires O(P) communication complexity.
9959 
9960    Level: intermediate
9961 
9962 .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
9963 @*/
9964 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9965 {
9966   PetscErrorCode ierr;
9967   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9968   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9969 
9970   PetscFunctionBegin;
9971   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9972   PetscValidType(A,1);
9973   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9974   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9975   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9976   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9977   PetscValidType(B,2);
9978   MatCheckPreallocated(B,2);
9979   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9980   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9981   PetscValidPointer(C,3);
9982   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);
9983   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9984   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9985   MatCheckPreallocated(A,1);
9986 
9987   fA = A->ops->mattransposemult;
9988   if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
9989   fB = B->ops->mattransposemult;
9990   if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
9991   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);
9992 
9993   ierr = PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
9994   if (scall == MAT_INITIAL_MATRIX) {
9995     ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9996     ierr = (*A->ops->mattransposemultsymbolic)(A,B,fill,C);CHKERRQ(ierr);
9997     ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9998   }
9999   ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
10000   ierr = (*A->ops->mattransposemultnumeric)(A,B,*C);CHKERRQ(ierr);
10001   ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
10002   ierr = PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
10003   PetscFunctionReturn(0);
10004 }
10005 
10006 /*@
10007    MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.
10008 
10009    Neighbor-wise Collective on Mat
10010 
10011    Input Parameters:
10012 +  A - the left matrix
10013 .  B - the right matrix
10014 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10015 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
10016 
10017    Output Parameters:
10018 .  C - the product matrix
10019 
10020    Notes:
10021    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
10022 
10023    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
10024 
10025   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
10026    actually needed.
10027 
10028    This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
10029    which inherit from SeqAIJ.  C will be of same type as the input matrices.
10030 
10031    Level: intermediate
10032 
10033 .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
10034 @*/
10035 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
10036 {
10037   PetscErrorCode ierr;
10038   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
10039   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
10040   PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL;
10041 
10042   PetscFunctionBegin;
10043   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
10044   PetscValidType(A,1);
10045   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10046   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10047   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10048   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
10049   PetscValidType(B,2);
10050   MatCheckPreallocated(B,2);
10051   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10052   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10053   PetscValidPointer(C,3);
10054   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);
10055   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
10056   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
10057   MatCheckPreallocated(A,1);
10058 
10059   fA = A->ops->transposematmult;
10060   fB = B->ops->transposematmult;
10061   if (fB==fA) {
10062     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
10063     transposematmult = fA;
10064   } else {
10065     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
10066     char multname[256];
10067     ierr = PetscStrncpy(multname,"MatTransposeMatMult_",sizeof(multname));CHKERRQ(ierr);
10068     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
10069     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
10070     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
10071     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
10072     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);CHKERRQ(ierr);
10073     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);
10074   }
10075   ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
10076   ierr = (*transposematmult)(A,B,scall,fill,C);CHKERRQ(ierr);
10077   ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
10078   PetscFunctionReturn(0);
10079 }
10080 
10081 /*@
10082    MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.
10083 
10084    Neighbor-wise Collective on Mat
10085 
10086    Input Parameters:
10087 +  A - the left matrix
10088 .  B - the middle matrix
10089 .  C - the right matrix
10090 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10091 -  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
10092           if the result is a dense matrix this is irrelevent
10093 
10094    Output Parameters:
10095 .  D - the product matrix
10096 
10097    Notes:
10098    Unless scall is MAT_REUSE_MATRIX D will be created.
10099 
10100    MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call
10101 
10102    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
10103    actually needed.
10104 
10105    If you have many matrices with the same non-zero structure to multiply, you
10106    should use MAT_REUSE_MATRIX in all calls but the first or
10107 
10108    Level: intermediate
10109 
10110 .seealso: MatMatMult, MatPtAP()
10111 @*/
10112 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
10113 {
10114   PetscErrorCode ierr;
10115   PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
10116   PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
10117   PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
10118   PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
10119 
10120   PetscFunctionBegin;
10121   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
10122   PetscValidType(A,1);
10123   MatCheckPreallocated(A,1);
10124   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10125   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10126   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10127   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
10128   PetscValidType(B,2);
10129   MatCheckPreallocated(B,2);
10130   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10131   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10132   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
10133   PetscValidPointer(C,3);
10134   MatCheckPreallocated(C,3);
10135   if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10136   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10137   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);
10138   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);
10139   if (scall == MAT_REUSE_MATRIX) {
10140     PetscValidPointer(*D,6);
10141     PetscValidHeaderSpecific(*D,MAT_CLASSID,6);
10142     ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10143     ierr = (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
10144     ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10145     PetscFunctionReturn(0);
10146   }
10147   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
10148   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
10149 
10150   fA = A->ops->matmatmult;
10151   fB = B->ops->matmatmult;
10152   fC = C->ops->matmatmult;
10153   if (fA == fB && fA == fC) {
10154     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name);
10155     mult = fA;
10156   } else {
10157     /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */
10158     char multname[256];
10159     ierr = PetscStrncpy(multname,"MatMatMatMult_",sizeof(multname));CHKERRQ(ierr);
10160     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
10161     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
10162     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
10163     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
10164     ierr = PetscStrlcat(multname,((PetscObject)C)->type_name,sizeof(multname));CHKERRQ(ierr);
10165     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr);
10166     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
10167     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);
10168   }
10169   ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10170   ierr = (*mult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
10171   ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10172   PetscFunctionReturn(0);
10173 }
10174 
10175 /*@
10176    MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
10177 
10178    Collective on Mat
10179 
10180    Input Parameters:
10181 +  mat - the matrix
10182 .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
10183 .  subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used)
10184 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10185 
10186    Output Parameter:
10187 .  matredundant - redundant matrix
10188 
10189    Notes:
10190    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
10191    original matrix has not changed from that last call to MatCreateRedundantMatrix().
10192 
10193    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
10194    calling it.
10195 
10196    Level: advanced
10197 
10198    Concepts: subcommunicator
10199    Concepts: duplicate matrix
10200 
10201 .seealso: MatDestroy()
10202 @*/
10203 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant)
10204 {
10205   PetscErrorCode ierr;
10206   MPI_Comm       comm;
10207   PetscMPIInt    size;
10208   PetscInt       mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs;
10209   Mat_Redundant  *redund=NULL;
10210   PetscSubcomm   psubcomm=NULL;
10211   MPI_Comm       subcomm_in=subcomm;
10212   Mat            *matseq;
10213   IS             isrow,iscol;
10214   PetscBool      newsubcomm=PETSC_FALSE;
10215 
10216   PetscFunctionBegin;
10217   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10218   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
10219     PetscValidPointer(*matredundant,5);
10220     PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5);
10221   }
10222 
10223   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
10224   if (size == 1 || nsubcomm == 1) {
10225     if (reuse == MAT_INITIAL_MATRIX) {
10226       ierr = MatDuplicate(mat,MAT_COPY_VALUES,matredundant);CHKERRQ(ierr);
10227     } else {
10228       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");
10229       ierr = MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
10230     }
10231     PetscFunctionReturn(0);
10232   }
10233 
10234   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10235   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10236   MatCheckPreallocated(mat,1);
10237 
10238   ierr = PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
10239   if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */
10240     /* create psubcomm, then get subcomm */
10241     ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
10242     ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
10243     if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size);
10244 
10245     ierr = PetscSubcommCreate(comm,&psubcomm);CHKERRQ(ierr);
10246     ierr = PetscSubcommSetNumber(psubcomm,nsubcomm);CHKERRQ(ierr);
10247     ierr = PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);CHKERRQ(ierr);
10248     ierr = PetscSubcommSetFromOptions(psubcomm);CHKERRQ(ierr);
10249     ierr = PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);CHKERRQ(ierr);
10250     newsubcomm = PETSC_TRUE;
10251     ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr);
10252   }
10253 
10254   /* get isrow, iscol and a local sequential matrix matseq[0] */
10255   if (reuse == MAT_INITIAL_MATRIX) {
10256     mloc_sub = PETSC_DECIDE;
10257     nloc_sub = PETSC_DECIDE;
10258     if (bs < 1) {
10259       ierr = PetscSplitOwnership(subcomm,&mloc_sub,&M);CHKERRQ(ierr);
10260       ierr = PetscSplitOwnership(subcomm,&nloc_sub,&N);CHKERRQ(ierr);
10261     } else {
10262       ierr = PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);CHKERRQ(ierr);
10263       ierr = PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N);CHKERRQ(ierr);
10264     }
10265     ierr = MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);CHKERRQ(ierr);
10266     rstart = rend - mloc_sub;
10267     ierr = ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);CHKERRQ(ierr);
10268     ierr = ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);CHKERRQ(ierr);
10269   } else { /* reuse == MAT_REUSE_MATRIX */
10270     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");
10271     /* retrieve subcomm */
10272     ierr = PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);CHKERRQ(ierr);
10273     redund = (*matredundant)->redundant;
10274     isrow  = redund->isrow;
10275     iscol  = redund->iscol;
10276     matseq = redund->matseq;
10277   }
10278   ierr = MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);CHKERRQ(ierr);
10279 
10280   /* get matredundant over subcomm */
10281   if (reuse == MAT_INITIAL_MATRIX) {
10282     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant);CHKERRQ(ierr);
10283 
10284     /* create a supporting struct and attach it to C for reuse */
10285     ierr = PetscNewLog(*matredundant,&redund);CHKERRQ(ierr);
10286     (*matredundant)->redundant = redund;
10287     redund->isrow              = isrow;
10288     redund->iscol              = iscol;
10289     redund->matseq             = matseq;
10290     if (newsubcomm) {
10291       redund->subcomm          = subcomm;
10292     } else {
10293       redund->subcomm          = MPI_COMM_NULL;
10294     }
10295   } else {
10296     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);CHKERRQ(ierr);
10297   }
10298   ierr = PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
10299   PetscFunctionReturn(0);
10300 }
10301 
10302 /*@C
10303    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
10304    a given 'mat' object. Each submatrix can span multiple procs.
10305 
10306    Collective on Mat
10307 
10308    Input Parameters:
10309 +  mat - the matrix
10310 .  subcomm - the subcommunicator obtained by com_split(comm)
10311 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10312 
10313    Output Parameter:
10314 .  subMat - 'parallel submatrices each spans a given subcomm
10315 
10316   Notes:
10317   The submatrix partition across processors is dictated by 'subComm' a
10318   communicator obtained by com_split(comm). The comm_split
10319   is not restriced to be grouped with consecutive original ranks.
10320 
10321   Due the comm_split() usage, the parallel layout of the submatrices
10322   map directly to the layout of the original matrix [wrt the local
10323   row,col partitioning]. So the original 'DiagonalMat' naturally maps
10324   into the 'DiagonalMat' of the subMat, hence it is used directly from
10325   the subMat. However the offDiagMat looses some columns - and this is
10326   reconstructed with MatSetValues()
10327 
10328   Level: advanced
10329 
10330   Concepts: subcommunicator
10331   Concepts: submatrices
10332 
10333 .seealso: MatCreateSubMatrices()
10334 @*/
10335 PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
10336 {
10337   PetscErrorCode ierr;
10338   PetscMPIInt    commsize,subCommSize;
10339 
10340   PetscFunctionBegin;
10341   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRQ(ierr);
10342   ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr);
10343   if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
10344 
10345   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");
10346   ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10347   ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr);
10348   ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10349   PetscFunctionReturn(0);
10350 }
10351 
10352 /*@
10353    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
10354 
10355    Not Collective
10356 
10357    Input Arguments:
10358    mat - matrix to extract local submatrix from
10359    isrow - local row indices for submatrix
10360    iscol - local column indices for submatrix
10361 
10362    Output Arguments:
10363    submat - the submatrix
10364 
10365    Level: intermediate
10366 
10367    Notes:
10368    The submat should be returned with MatRestoreLocalSubMatrix().
10369 
10370    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
10371    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
10372 
10373    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
10374    MatSetValuesBlockedLocal() will also be implemented.
10375 
10376    The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that
10377    matrices obtained with DMCreateMatrix() generally already have the local to global mapping provided.
10378 
10379 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping()
10380 @*/
10381 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10382 {
10383   PetscErrorCode ierr;
10384 
10385   PetscFunctionBegin;
10386   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10387   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10388   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10389   PetscCheckSameComm(isrow,2,iscol,3);
10390   PetscValidPointer(submat,4);
10391   if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call");
10392 
10393   if (mat->ops->getlocalsubmatrix) {
10394     ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10395   } else {
10396     ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr);
10397   }
10398   PetscFunctionReturn(0);
10399 }
10400 
10401 /*@
10402    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
10403 
10404    Not Collective
10405 
10406    Input Arguments:
10407    mat - matrix to extract local submatrix from
10408    isrow - local row indices for submatrix
10409    iscol - local column indices for submatrix
10410    submat - the submatrix
10411 
10412    Level: intermediate
10413 
10414 .seealso: MatGetLocalSubMatrix()
10415 @*/
10416 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10417 {
10418   PetscErrorCode ierr;
10419 
10420   PetscFunctionBegin;
10421   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10422   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10423   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10424   PetscCheckSameComm(isrow,2,iscol,3);
10425   PetscValidPointer(submat,4);
10426   if (*submat) {
10427     PetscValidHeaderSpecific(*submat,MAT_CLASSID,4);
10428   }
10429 
10430   if (mat->ops->restorelocalsubmatrix) {
10431     ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10432   } else {
10433     ierr = MatDestroy(submat);CHKERRQ(ierr);
10434   }
10435   *submat = NULL;
10436   PetscFunctionReturn(0);
10437 }
10438 
10439 /* --------------------------------------------------------*/
10440 /*@
10441    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix
10442 
10443    Collective on Mat
10444 
10445    Input Parameter:
10446 .  mat - the matrix
10447 
10448    Output Parameter:
10449 .  is - if any rows have zero diagonals this contains the list of them
10450 
10451    Level: developer
10452 
10453    Concepts: matrix-vector product
10454 
10455 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10456 @*/
10457 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is)
10458 {
10459   PetscErrorCode ierr;
10460 
10461   PetscFunctionBegin;
10462   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10463   PetscValidType(mat,1);
10464   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10465   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10466 
10467   if (!mat->ops->findzerodiagonals) {
10468     Vec                diag;
10469     const PetscScalar *a;
10470     PetscInt          *rows;
10471     PetscInt           rStart, rEnd, r, nrow = 0;
10472 
10473     ierr = MatCreateVecs(mat, &diag, NULL);CHKERRQ(ierr);
10474     ierr = MatGetDiagonal(mat, diag);CHKERRQ(ierr);
10475     ierr = MatGetOwnershipRange(mat, &rStart, &rEnd);CHKERRQ(ierr);
10476     ierr = VecGetArrayRead(diag, &a);CHKERRQ(ierr);
10477     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow;
10478     ierr = PetscMalloc1(nrow, &rows);CHKERRQ(ierr);
10479     nrow = 0;
10480     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart;
10481     ierr = VecRestoreArrayRead(diag, &a);CHKERRQ(ierr);
10482     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10483     ierr = ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);CHKERRQ(ierr);
10484   } else {
10485     ierr = (*mat->ops->findzerodiagonals)(mat, is);CHKERRQ(ierr);
10486   }
10487   PetscFunctionReturn(0);
10488 }
10489 
10490 /*@
10491    MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size)
10492 
10493    Collective on Mat
10494 
10495    Input Parameter:
10496 .  mat - the matrix
10497 
10498    Output Parameter:
10499 .  is - contains the list of rows with off block diagonal entries
10500 
10501    Level: developer
10502 
10503    Concepts: matrix-vector product
10504 
10505 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10506 @*/
10507 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is)
10508 {
10509   PetscErrorCode ierr;
10510 
10511   PetscFunctionBegin;
10512   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10513   PetscValidType(mat,1);
10514   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10515   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10516 
10517   if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined");
10518   ierr = (*mat->ops->findoffblockdiagonalentries)(mat,is);CHKERRQ(ierr);
10519   PetscFunctionReturn(0);
10520 }
10521 
10522 /*@C
10523   MatInvertBlockDiagonal - Inverts the block diagonal entries.
10524 
10525   Collective on Mat
10526 
10527   Input Parameters:
10528 . mat - the matrix
10529 
10530   Output Parameters:
10531 . values - the block inverses in column major order (FORTRAN-like)
10532 
10533    Note:
10534    This routine is not available from Fortran.
10535 
10536   Level: advanced
10537 
10538 .seealso: MatInvertBockDiagonalMat
10539 @*/
10540 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
10541 {
10542   PetscErrorCode ierr;
10543 
10544   PetscFunctionBegin;
10545   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10546   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10547   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10548   if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
10549   ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr);
10550   PetscFunctionReturn(0);
10551 }
10552 
10553 /*@C
10554   MatInvertVariableBlockDiagonal - Inverts the block diagonal entries.
10555 
10556   Collective on Mat
10557 
10558   Input Parameters:
10559 + mat - the matrix
10560 . nblocks - the number of blocks
10561 - bsizes - the size of each block
10562 
10563   Output Parameters:
10564 . values - the block inverses in column major order (FORTRAN-like)
10565 
10566    Note:
10567    This routine is not available from Fortran.
10568 
10569   Level: advanced
10570 
10571 .seealso: MatInvertBockDiagonal()
10572 @*/
10573 PetscErrorCode MatInvertVariableBlockDiagonal(Mat mat,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *values)
10574 {
10575   PetscErrorCode ierr;
10576 
10577   PetscFunctionBegin;
10578   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10579   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10580   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10581   if (!mat->ops->invertvariableblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
10582   ierr = (*mat->ops->invertvariableblockdiagonal)(mat,nblocks,bsizes,values);CHKERRQ(ierr);
10583   PetscFunctionReturn(0);
10584 }
10585 
10586 /*@
10587   MatInvertBlockDiagonalMat - set matrix C to be the inverted block diagonal of matrix A
10588 
10589   Collective on Mat
10590 
10591   Input Parameters:
10592 . A - the matrix
10593 
10594   Output Parameters:
10595 . C - matrix with inverted block diagonal of A.  This matrix should be created and may have its type set.
10596 
10597   Notes: the blocksize of the matrix is used to determine the blocks on the diagonal of C
10598 
10599   Level: advanced
10600 
10601 .seealso: MatInvertBockDiagonal()
10602 @*/
10603 PetscErrorCode MatInvertBlockDiagonalMat(Mat A,Mat C)
10604 {
10605   PetscErrorCode     ierr;
10606   const PetscScalar *vals;
10607   PetscInt          *dnnz;
10608   PetscInt           M,N,m,n,rstart,rend,bs,i,j;
10609 
10610   PetscFunctionBegin;
10611   ierr = MatInvertBlockDiagonal(A,&vals);CHKERRQ(ierr);
10612   ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr);
10613   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
10614   ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr);
10615   ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr);
10616   ierr = MatSetBlockSize(C,bs);CHKERRQ(ierr);
10617   ierr = PetscMalloc1(m/bs,&dnnz);CHKERRQ(ierr);
10618   for (j = 0; j < m/bs; j++) dnnz[j] = 1;
10619   ierr = MatXAIJSetPreallocation(C,bs,dnnz,NULL,NULL,NULL);CHKERRQ(ierr);
10620   ierr = PetscFree(dnnz);CHKERRQ(ierr);
10621   ierr = MatGetOwnershipRange(C,&rstart,&rend);CHKERRQ(ierr);
10622   ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr);
10623   for (i = rstart/bs; i < rend/bs; i++) {
10624     ierr = MatSetValuesBlocked(C,1,&i,1,&i,&vals[(i-rstart/bs)*bs*bs],INSERT_VALUES);CHKERRQ(ierr);
10625   }
10626   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10627   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10628   ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr);
10629   PetscFunctionReturn(0);
10630 }
10631 
10632 /*@C
10633     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
10634     via MatTransposeColoringCreate().
10635 
10636     Collective on MatTransposeColoring
10637 
10638     Input Parameter:
10639 .   c - coloring context
10640 
10641     Level: intermediate
10642 
10643 .seealso: MatTransposeColoringCreate()
10644 @*/
10645 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c)
10646 {
10647   PetscErrorCode       ierr;
10648   MatTransposeColoring matcolor=*c;
10649 
10650   PetscFunctionBegin;
10651   if (!matcolor) PetscFunctionReturn(0);
10652   if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; PetscFunctionReturn(0);}
10653 
10654   ierr = PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);CHKERRQ(ierr);
10655   ierr = PetscFree(matcolor->rows);CHKERRQ(ierr);
10656   ierr = PetscFree(matcolor->den2sp);CHKERRQ(ierr);
10657   ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr);
10658   ierr = PetscFree(matcolor->columns);CHKERRQ(ierr);
10659   if (matcolor->brows>0) {
10660     ierr = PetscFree(matcolor->lstart);CHKERRQ(ierr);
10661   }
10662   ierr = PetscHeaderDestroy(c);CHKERRQ(ierr);
10663   PetscFunctionReturn(0);
10664 }
10665 
10666 /*@C
10667     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
10668     a MatTransposeColoring context has been created, computes a dense B^T by Apply
10669     MatTransposeColoring to sparse B.
10670 
10671     Collective on MatTransposeColoring
10672 
10673     Input Parameters:
10674 +   B - sparse matrix B
10675 .   Btdense - symbolic dense matrix B^T
10676 -   coloring - coloring context created with MatTransposeColoringCreate()
10677 
10678     Output Parameter:
10679 .   Btdense - dense matrix B^T
10680 
10681     Level: advanced
10682 
10683      Notes:
10684     These are used internally for some implementations of MatRARt()
10685 
10686 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplyDenToSp()
10687 
10688 .keywords: coloring
10689 @*/
10690 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
10691 {
10692   PetscErrorCode ierr;
10693 
10694   PetscFunctionBegin;
10695   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
10696   PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2);
10697   PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3);
10698 
10699   if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
10700   ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr);
10701   PetscFunctionReturn(0);
10702 }
10703 
10704 /*@C
10705     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
10706     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
10707     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
10708     Csp from Cden.
10709 
10710     Collective on MatTransposeColoring
10711 
10712     Input Parameters:
10713 +   coloring - coloring context created with MatTransposeColoringCreate()
10714 -   Cden - matrix product of a sparse matrix and a dense matrix Btdense
10715 
10716     Output Parameter:
10717 .   Csp - sparse matrix
10718 
10719     Level: advanced
10720 
10721      Notes:
10722     These are used internally for some implementations of MatRARt()
10723 
10724 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()
10725 
10726 .keywords: coloring
10727 @*/
10728 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
10729 {
10730   PetscErrorCode ierr;
10731 
10732   PetscFunctionBegin;
10733   PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1);
10734   PetscValidHeaderSpecific(Cden,MAT_CLASSID,2);
10735   PetscValidHeaderSpecific(Csp,MAT_CLASSID,3);
10736 
10737   if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
10738   ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr);
10739   PetscFunctionReturn(0);
10740 }
10741 
10742 /*@C
10743    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.
10744 
10745    Collective on Mat
10746 
10747    Input Parameters:
10748 +  mat - the matrix product C
10749 -  iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring()
10750 
10751     Output Parameter:
10752 .   color - the new coloring context
10753 
10754     Level: intermediate
10755 
10756 .seealso: MatTransposeColoringDestroy(),  MatTransColoringApplySpToDen(),
10757            MatTransColoringApplyDenToSp()
10758 @*/
10759 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
10760 {
10761   MatTransposeColoring c;
10762   MPI_Comm             comm;
10763   PetscErrorCode       ierr;
10764 
10765   PetscFunctionBegin;
10766   ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10767   ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
10768   ierr = PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);CHKERRQ(ierr);
10769 
10770   c->ctype = iscoloring->ctype;
10771   if (mat->ops->transposecoloringcreate) {
10772     ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr);
10773   } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type");
10774 
10775   *color = c;
10776   ierr   = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10777   PetscFunctionReturn(0);
10778 }
10779 
10780 /*@
10781       MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the
10782         matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the
10783         same, otherwise it will be larger
10784 
10785      Not Collective
10786 
10787   Input Parameter:
10788 .    A  - the matrix
10789 
10790   Output Parameter:
10791 .    state - the current state
10792 
10793   Notes:
10794     You can only compare states from two different calls to the SAME matrix, you cannot compare calls between
10795          different matrices
10796 
10797   Level: intermediate
10798 
10799 @*/
10800 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state)
10801 {
10802   PetscFunctionBegin;
10803   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10804   *state = mat->nonzerostate;
10805   PetscFunctionReturn(0);
10806 }
10807 
10808 /*@
10809       MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential
10810                  matrices from each processor
10811 
10812     Collective on MPI_Comm
10813 
10814    Input Parameters:
10815 +    comm - the communicators the parallel matrix will live on
10816 .    seqmat - the input sequential matrices
10817 .    n - number of local columns (or PETSC_DECIDE)
10818 -    reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10819 
10820    Output Parameter:
10821 .    mpimat - the parallel matrix generated
10822 
10823     Level: advanced
10824 
10825    Notes:
10826     The number of columns of the matrix in EACH processor MUST be the same.
10827 
10828 @*/
10829 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat)
10830 {
10831   PetscErrorCode ierr;
10832 
10833   PetscFunctionBegin;
10834   if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name);
10835   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");
10836 
10837   ierr = PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10838   ierr = (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);CHKERRQ(ierr);
10839   ierr = PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10840   PetscFunctionReturn(0);
10841 }
10842 
10843 /*@
10844      MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent
10845                  ranks' ownership ranges.
10846 
10847     Collective on A
10848 
10849    Input Parameters:
10850 +    A   - the matrix to create subdomains from
10851 -    N   - requested number of subdomains
10852 
10853 
10854    Output Parameters:
10855 +    n   - number of subdomains resulting on this rank
10856 -    iss - IS list with indices of subdomains on this rank
10857 
10858     Level: advanced
10859 
10860     Notes:
10861     number of subdomains must be smaller than the communicator size
10862 @*/
10863 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[])
10864 {
10865   MPI_Comm        comm,subcomm;
10866   PetscMPIInt     size,rank,color;
10867   PetscInt        rstart,rend,k;
10868   PetscErrorCode  ierr;
10869 
10870   PetscFunctionBegin;
10871   ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr);
10872   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
10873   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
10874   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);
10875   *n = 1;
10876   k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */
10877   color = rank/k;
10878   ierr = MPI_Comm_split(comm,color,rank,&subcomm);CHKERRQ(ierr);
10879   ierr = PetscMalloc1(1,iss);CHKERRQ(ierr);
10880   ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
10881   ierr = ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);CHKERRQ(ierr);
10882   ierr = MPI_Comm_free(&subcomm);CHKERRQ(ierr);
10883   PetscFunctionReturn(0);
10884 }
10885 
10886 /*@
10887    MatGalerkin - Constructs the coarse grid problem via Galerkin projection.
10888 
10889    If the interpolation and restriction operators are the same, uses MatPtAP.
10890    If they are not the same, use MatMatMatMult.
10891 
10892    Once the coarse grid problem is constructed, correct for interpolation operators
10893    that are not of full rank, which can legitimately happen in the case of non-nested
10894    geometric multigrid.
10895 
10896    Input Parameters:
10897 +  restrct - restriction operator
10898 .  dA - fine grid matrix
10899 .  interpolate - interpolation operator
10900 .  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10901 -  fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate
10902 
10903    Output Parameters:
10904 .  A - the Galerkin coarse matrix
10905 
10906    Options Database Key:
10907 .  -pc_mg_galerkin <both,pmat,mat,none>
10908 
10909    Level: developer
10910 
10911 .keywords: MG, multigrid, Galerkin
10912 
10913 .seealso: MatPtAP(), MatMatMatMult()
10914 @*/
10915 PetscErrorCode  MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A)
10916 {
10917   PetscErrorCode ierr;
10918   IS             zerorows;
10919   Vec            diag;
10920 
10921   PetscFunctionBegin;
10922   if (reuse == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10923   /* Construct the coarse grid matrix */
10924   if (interpolate == restrct) {
10925     ierr = MatPtAP(dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10926   } else {
10927     ierr = MatMatMatMult(restrct,dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10928   }
10929 
10930   /* If the interpolation matrix is not of full rank, A will have zero rows.
10931      This can legitimately happen in the case of non-nested geometric multigrid.
10932      In that event, we set the rows of the matrix to the rows of the identity,
10933      ignoring the equations (as the RHS will also be zero). */
10934 
10935   ierr = MatFindZeroRows(*A, &zerorows);CHKERRQ(ierr);
10936 
10937   if (zerorows != NULL) { /* if there are any zero rows */
10938     ierr = MatCreateVecs(*A, &diag, NULL);CHKERRQ(ierr);
10939     ierr = MatGetDiagonal(*A, diag);CHKERRQ(ierr);
10940     ierr = VecISSet(diag, zerorows, 1.0);CHKERRQ(ierr);
10941     ierr = MatDiagonalSet(*A, diag, INSERT_VALUES);CHKERRQ(ierr);
10942     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10943     ierr = ISDestroy(&zerorows);CHKERRQ(ierr);
10944   }
10945   PetscFunctionReturn(0);
10946 }
10947 
10948 /*@C
10949     MatSetOperation - Allows user to set a matrix operation for any matrix type
10950 
10951    Logically Collective on Mat
10952 
10953     Input Parameters:
10954 +   mat - the matrix
10955 .   op - the name of the operation
10956 -   f - the function that provides the operation
10957 
10958    Level: developer
10959 
10960     Usage:
10961 $      extern PetscErrorCode usermult(Mat,Vec,Vec);
10962 $      ierr = MatCreateXXX(comm,...&A);
10963 $      ierr = MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult);
10964 
10965     Notes:
10966     See the file include/petscmat.h for a complete list of matrix
10967     operations, which all have the form MATOP_<OPERATION>, where
10968     <OPERATION> is the name (in all capital letters) of the
10969     user interface routine (e.g., MatMult() -> MATOP_MULT).
10970 
10971     All user-provided functions (except for MATOP_DESTROY) should have the same calling
10972     sequence as the usual matrix interface routines, since they
10973     are intended to be accessed via the usual matrix interface
10974     routines, e.g.,
10975 $       MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec)
10976 
10977     In particular each function MUST return an error code of 0 on success and
10978     nonzero on failure.
10979 
10980     This routine is distinct from MatShellSetOperation() in that it can be called on any matrix type.
10981 
10982 .keywords: matrix, set, operation
10983 
10984 .seealso: MatGetOperation(), MatCreateShell(), MatShellSetContext(), MatShellSetOperation()
10985 @*/
10986 PetscErrorCode MatSetOperation(Mat mat,MatOperation op,void (*f)(void))
10987 {
10988   PetscFunctionBegin;
10989   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10990   if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) {
10991     mat->ops->viewnative = mat->ops->view;
10992   }
10993   (((void(**)(void))mat->ops)[op]) = f;
10994   PetscFunctionReturn(0);
10995 }
10996 
10997 /*@C
10998     MatGetOperation - Gets a matrix operation for any matrix type.
10999 
11000     Not Collective
11001 
11002     Input Parameters:
11003 +   mat - the matrix
11004 -   op - the name of the operation
11005 
11006     Output Parameter:
11007 .   f - the function that provides the operation
11008 
11009     Level: developer
11010 
11011     Usage:
11012 $      PetscErrorCode (*usermult)(Mat,Vec,Vec);
11013 $      ierr = MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult);
11014 
11015     Notes:
11016     See the file include/petscmat.h for a complete list of matrix
11017     operations, which all have the form MATOP_<OPERATION>, where
11018     <OPERATION> is the name (in all capital letters) of the
11019     user interface routine (e.g., MatMult() -> MATOP_MULT).
11020 
11021     This routine is distinct from MatShellGetOperation() in that it can be called on any matrix type.
11022 
11023 .keywords: matrix, get, operation
11024 
11025 .seealso: MatSetOperation(), MatCreateShell(), MatShellGetContext(), MatShellGetOperation()
11026 @*/
11027 PetscErrorCode MatGetOperation(Mat mat,MatOperation op,void(**f)(void))
11028 {
11029   PetscFunctionBegin;
11030   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
11031   *f = (((void (**)(void))mat->ops)[op]);
11032   PetscFunctionReturn(0);
11033 }
11034 
11035 /*@
11036     MatHasOperation - Determines whether the given matrix supports the particular
11037     operation.
11038 
11039    Not Collective
11040 
11041    Input Parameters:
11042 +  mat - the matrix
11043 -  op - the operation, for example, MATOP_GET_DIAGONAL
11044 
11045    Output Parameter:
11046 .  has - either PETSC_TRUE or PETSC_FALSE
11047 
11048    Level: advanced
11049 
11050    Notes:
11051    See the file include/petscmat.h for a complete list of matrix
11052    operations, which all have the form MATOP_<OPERATION>, where
11053    <OPERATION> is the name (in all capital letters) of the
11054    user-level routine.  E.g., MatNorm() -> MATOP_NORM.
11055 
11056 .keywords: matrix, has, operation
11057 
11058 .seealso: MatCreateShell()
11059 @*/
11060 PetscErrorCode MatHasOperation(Mat mat,MatOperation op,PetscBool *has)
11061 {
11062   PetscErrorCode ierr;
11063 
11064   PetscFunctionBegin;
11065   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
11066   PetscValidType(mat,1);
11067   PetscValidPointer(has,3);
11068   if (mat->ops->hasoperation) {
11069     ierr = (*mat->ops->hasoperation)(mat,op,has);CHKERRQ(ierr);
11070   } else {
11071     if (((void**)mat->ops)[op]) *has =  PETSC_TRUE;
11072     else {
11073       *has = PETSC_FALSE;
11074       if (op == MATOP_CREATE_SUBMATRIX) {
11075         PetscMPIInt size;
11076 
11077         ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
11078         if (size == 1) {
11079           ierr = MatHasOperation(mat,MATOP_CREATE_SUBMATRICES,has);CHKERRQ(ierr);
11080         }
11081       }
11082     }
11083   }
11084   PetscFunctionReturn(0);
11085 }
11086 
11087 /*@
11088     MatHasCongruentLayouts - Determines whether the rows and columns layouts
11089     of the matrix are congruent
11090 
11091    Collective on mat
11092 
11093    Input Parameters:
11094 .  mat - the matrix
11095 
11096    Output Parameter:
11097 .  cong - either PETSC_TRUE or PETSC_FALSE
11098 
11099    Level: beginner
11100 
11101    Notes:
11102 
11103 .keywords: matrix, has
11104 
11105 .seealso: MatCreate(), MatSetSizes()
11106 @*/
11107 PetscErrorCode MatHasCongruentLayouts(Mat mat,PetscBool *cong)
11108 {
11109   PetscErrorCode ierr;
11110 
11111   PetscFunctionBegin;
11112   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
11113   PetscValidType(mat,1);
11114   PetscValidPointer(cong,2);
11115   if (!mat->rmap || !mat->cmap) {
11116     *cong = mat->rmap == mat->cmap ? PETSC_TRUE : PETSC_FALSE;
11117     PetscFunctionReturn(0);
11118   }
11119   if (mat->congruentlayouts == PETSC_DECIDE) { /* first time we compare rows and cols layouts */
11120     ierr = PetscLayoutCompare(mat->rmap,mat->cmap,cong);CHKERRQ(ierr);
11121     if (*cong) mat->congruentlayouts = 1;
11122     else       mat->congruentlayouts = 0;
11123   } else *cong = mat->congruentlayouts ? PETSC_TRUE : PETSC_FALSE;
11124   PetscFunctionReturn(0);
11125 }
11126 
11127 /*@
11128     MatFreeIntermediateDataStructures - Free intermediate data structures created for reuse,
11129     e.g., matrx product of MatPtAP.
11130 
11131    Collective on mat
11132 
11133    Input Parameters:
11134 .  mat - the matrix
11135 
11136    Output Parameter:
11137 .  mat - the matrix with intermediate data structures released
11138 
11139    Level: advanced
11140 
11141    Notes:
11142 
11143 .keywords: matrix
11144 
11145 .seealso: MatPtAP(), MatMatMult()
11146 @*/
11147 PetscErrorCode MatFreeIntermediateDataStructures(Mat mat)
11148 {
11149   PetscErrorCode ierr;
11150 
11151   PetscFunctionBegin;
11152   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
11153   PetscValidType(mat,1);
11154   if (mat->ops->freeintermediatedatastructures) {
11155     ierr = (*mat->ops->freeintermediatedatastructures)(mat);CHKERRQ(ierr);
11156   }
11157   PetscFunctionReturn(0);
11158 }
11159