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