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