xref: /petsc/src/mat/interface/matrix.c (revision 998f007d705dc5d9e5f0c7585b0b366811b9ba79) !
1 
2 /*
3    This is where the abstract matrix operations are defined
4 */
5 
6 #include <petsc/private/matimpl.h>        /*I "petscmat.h" I*/
7 #include <petsc/private/isimpl.h>
8 #include <petsc/private/vecimpl.h>
9 
10 /* Logging support */
11 PetscClassId MAT_CLASSID;
12 PetscClassId MAT_COLORING_CLASSID;
13 PetscClassId MAT_FDCOLORING_CLASSID;
14 PetscClassId MAT_TRANSPOSECOLORING_CLASSID;
15 
16 PetscLogEvent MAT_Mult, MAT_Mults, MAT_MultConstrained, MAT_MultAdd, MAT_MultTranspose;
17 PetscLogEvent MAT_MultTransposeConstrained, MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve,MAT_MatTrSolve;
18 PetscLogEvent MAT_SolveTransposeAdd, MAT_SOR, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic;
19 PetscLogEvent MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor;
20 PetscLogEvent MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin;
21 PetscLogEvent MAT_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetRowIJ, MAT_CreateSubMats, MAT_GetOrdering, MAT_RedundantMat, MAT_GetSeqNonzeroStructure;
22 PetscLogEvent MAT_IncreaseOverlap, MAT_Partitioning, MAT_PartitioningND, MAT_Coarsen, MAT_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate;
23 PetscLogEvent MAT_FDColoringSetUp, MAT_FDColoringApply,MAT_Transpose,MAT_FDColoringFunction, MAT_CreateSubMat;
24 PetscLogEvent MAT_TransposeColoringCreate;
25 PetscLogEvent MAT_MatMult, MAT_MatMultSymbolic, MAT_MatMultNumeric;
26 PetscLogEvent MAT_PtAP, MAT_PtAPSymbolic, MAT_PtAPNumeric,MAT_RARt, MAT_RARtSymbolic, MAT_RARtNumeric;
27 PetscLogEvent MAT_MatTransposeMult, MAT_MatTransposeMultSymbolic, MAT_MatTransposeMultNumeric;
28 PetscLogEvent MAT_TransposeMatMult, MAT_TransposeMatMultSymbolic, MAT_TransposeMatMultNumeric;
29 PetscLogEvent MAT_MatMatMult, MAT_MatMatMultSymbolic, MAT_MatMatMultNumeric;
30 PetscLogEvent MAT_MultHermitianTranspose,MAT_MultHermitianTransposeAdd;
31 PetscLogEvent MAT_Getsymtranspose, MAT_Getsymtransreduced, MAT_Transpose_SeqAIJ, MAT_GetBrowsOfAcols;
32 PetscLogEvent MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym;
33 PetscLogEvent MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure;
34 PetscLogEvent MAT_GetMultiProcBlock;
35 PetscLogEvent MAT_CUSPARSECopyToGPU, MAT_SetValuesBatch;
36 PetscLogEvent MAT_ViennaCLCopyToGPU;
37 PetscLogEvent MAT_Merge,MAT_Residual,MAT_SetRandom;
38 PetscLogEvent MATCOLORING_Apply,MATCOLORING_Comm,MATCOLORING_Local,MATCOLORING_ISCreate,MATCOLORING_SetUp,MATCOLORING_Weights;
39 
40 const char *const MatFactorTypes[] = {"NONE","LU","CHOLESKY","ILU","ICC","ILUDT","MatFactorType","MAT_FACTOR_",0};
41 
42 /*@
43    MatSetRandom - Sets all components of a matrix to random numbers. For sparse matrices that have been preallocated it randomly selects appropriate locations
44 
45    Logically Collective on Mat
46 
47    Input Parameters:
48 +  x  - the matrix
49 -  rctx - the random number context, formed by PetscRandomCreate(), or NULL and
50           it will create one internally.
51 
52    Output Parameter:
53 .  x  - the matrix
54 
55    Example of Usage:
56 .vb
57      PetscRandomCreate(PETSC_COMM_WORLD,&rctx);
58      MatSetRandom(x,rctx);
59      PetscRandomDestroy(rctx);
60 .ve
61 
62    Level: intermediate
63 
64    Concepts: matrix^setting to random
65    Concepts: random^matrix
66 
67 .seealso: MatZeroEntries(), MatSetValues(), PetscRandomCreate(), PetscRandomDestroy()
68 @*/
69 PetscErrorCode MatSetRandom(Mat x,PetscRandom rctx)
70 {
71   PetscErrorCode ierr;
72   PetscRandom    randObj = NULL;
73 
74   PetscFunctionBegin;
75   PetscValidHeaderSpecific(x,MAT_CLASSID,1);
76   if (rctx) PetscValidHeaderSpecific(rctx,PETSC_RANDOM_CLASSID,2);
77   PetscValidType(x,1);
78 
79   if (!x->ops->setrandom) SETERRQ1(PetscObjectComm((PetscObject)x),PETSC_ERR_SUP,"Mat type %s",((PetscObject)x)->type_name);
80 
81   if (!rctx) {
82     MPI_Comm comm;
83     ierr = PetscObjectGetComm((PetscObject)x,&comm);CHKERRQ(ierr);
84     ierr = PetscRandomCreate(comm,&randObj);CHKERRQ(ierr);
85     ierr = PetscRandomSetFromOptions(randObj);CHKERRQ(ierr);
86     rctx = randObj;
87   }
88 
89   ierr = PetscLogEventBegin(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr);
90   ierr = (*x->ops->setrandom)(x,rctx);CHKERRQ(ierr);
91   ierr = PetscLogEventEnd(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr);
92 
93   ierr = MatAssemblyBegin(x, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
94   ierr = MatAssemblyEnd(x, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
95   ierr = PetscRandomDestroy(&randObj);CHKERRQ(ierr);
96   PetscFunctionReturn(0);
97 }
98 
99 /*@
100    MatFactorGetErrorZeroPivot - returns the pivot value that was determined to be zero and the row it occurred in
101 
102    Logically Collective on Mat
103 
104    Input Parameters:
105 .  mat - the factored matrix
106 
107    Output Parameter:
108 +  pivot - the pivot value computed
109 -  row - the row that the zero pivot occurred. Note that this row must be interpreted carefully due to row reorderings and which processes
110          the share the matrix
111 
112    Level: advanced
113 
114    Notes:
115     This routine does not work for factorizations done with external packages.
116    This routine should only be called if MatGetFactorError() returns a value of MAT_FACTOR_NUMERIC_ZEROPIVOT
117 
118    This can be called on non-factored matrices that come from, for example, matrices used in SOR.
119 
120 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot()
121 @*/
122 PetscErrorCode MatFactorGetErrorZeroPivot(Mat mat,PetscReal *pivot,PetscInt *row)
123 {
124   PetscFunctionBegin;
125   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
126   *pivot = mat->factorerror_zeropivot_value;
127   *row   = mat->factorerror_zeropivot_row;
128   PetscFunctionReturn(0);
129 }
130 
131 /*@
132    MatFactorGetError - gets the error code from a factorization
133 
134    Logically Collective on Mat
135 
136    Input Parameters:
137 .  mat - the factored matrix
138 
139    Output Parameter:
140 .  err  - the error code
141 
142    Level: advanced
143 
144    Notes:
145     This can be called on non-factored matrices that come from, for example, matrices used in SOR.
146 
147 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot()
148 @*/
149 PetscErrorCode MatFactorGetError(Mat mat,MatFactorError *err)
150 {
151   PetscFunctionBegin;
152   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
153   *err = mat->factorerrortype;
154   PetscFunctionReturn(0);
155 }
156 
157 /*@
158    MatFactorClearError - clears the error code in a factorization
159 
160    Logically Collective on Mat
161 
162    Input Parameter:
163 .  mat - the factored matrix
164 
165    Level: developer
166 
167    Notes:
168     This can be called on non-factored matrices that come from, for example, matrices used in SOR.
169 
170 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorGetError(), MatFactorGetErrorZeroPivot()
171 @*/
172 PetscErrorCode MatFactorClearError(Mat mat)
173 {
174   PetscFunctionBegin;
175   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
176   mat->factorerrortype             = MAT_FACTOR_NOERROR;
177   mat->factorerror_zeropivot_value = 0.0;
178   mat->factorerror_zeropivot_row   = 0;
179   PetscFunctionReturn(0);
180 }
181 
182 PETSC_INTERN PetscErrorCode MatFindNonzeroRowsOrCols_Basic(Mat mat,PetscBool cols,PetscReal tol,IS *nonzero)
183 {
184   PetscErrorCode    ierr;
185   Vec               r,l;
186   const PetscScalar *al;
187   PetscInt          i,nz,gnz,N,n;
188 
189   PetscFunctionBegin;
190   ierr = MatCreateVecs(mat,&r,&l);CHKERRQ(ierr);
191   if (!cols) { /* nonzero rows */
192     ierr = MatGetSize(mat,&N,NULL);CHKERRQ(ierr);
193     ierr = MatGetLocalSize(mat,&n,NULL);CHKERRQ(ierr);
194     ierr = VecSet(l,0.0);CHKERRQ(ierr);
195     ierr = VecSetRandom(r,NULL);CHKERRQ(ierr);
196     ierr = MatMult(mat,r,l);CHKERRQ(ierr);
197     ierr = VecGetArrayRead(l,&al);CHKERRQ(ierr);
198   } else { /* nonzero columns */
199     ierr = MatGetSize(mat,NULL,&N);CHKERRQ(ierr);
200     ierr = MatGetLocalSize(mat,NULL,&n);CHKERRQ(ierr);
201     ierr = VecSet(r,0.0);CHKERRQ(ierr);
202     ierr = VecSetRandom(l,NULL);CHKERRQ(ierr);
203     ierr = MatMultTranspose(mat,l,r);CHKERRQ(ierr);
204     ierr = VecGetArrayRead(r,&al);CHKERRQ(ierr);
205   }
206   if (tol <= 0.0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nz++; }
207   else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nz++; }
208   ierr = MPIU_Allreduce(&nz,&gnz,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr);
209   if (gnz != N) {
210     PetscInt *nzr;
211     ierr = PetscMalloc1(nz,&nzr);CHKERRQ(ierr);
212     if (nz) {
213       if (tol < 0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nzr[nz++] = i; }
214       else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nzr[nz++] = i; }
215     }
216     ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),nz,nzr,PETSC_OWN_POINTER,nonzero);CHKERRQ(ierr);
217   } else *nonzero = NULL;
218   if (!cols) { /* nonzero rows */
219     ierr = VecRestoreArrayRead(l,&al);CHKERRQ(ierr);
220   } else {
221     ierr = VecRestoreArrayRead(r,&al);CHKERRQ(ierr);
222   }
223   ierr = VecDestroy(&l);CHKERRQ(ierr);
224   ierr = VecDestroy(&r);CHKERRQ(ierr);
225   PetscFunctionReturn(0);
226 }
227 
228 /*@
229       MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix
230 
231   Input Parameter:
232 .    A  - the matrix
233 
234   Output Parameter:
235 .    keptrows - the rows that are not completely zero
236 
237   Notes:
238     keptrows is set to NULL if all rows are nonzero.
239 
240   Level: intermediate
241 
242  @*/
243 PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows)
244 {
245   PetscErrorCode ierr;
246 
247   PetscFunctionBegin;
248   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
249   PetscValidType(mat,1);
250   PetscValidPointer(keptrows,2);
251   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
252   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
253   if (!mat->ops->findnonzerorows) {
254     ierr = MatFindNonzeroRowsOrCols_Basic(mat,PETSC_FALSE,0.0,keptrows);CHKERRQ(ierr);
255   } else {
256     ierr = (*mat->ops->findnonzerorows)(mat,keptrows);CHKERRQ(ierr);
257   }
258   PetscFunctionReturn(0);
259 }
260 
261 /*@
262       MatFindZeroRows - Locate all rows that are completely zero in the matrix
263 
264   Input Parameter:
265 .    A  - the matrix
266 
267   Output Parameter:
268 .    zerorows - the rows that are completely zero
269 
270   Notes:
271     zerorows is set to NULL if no rows are zero.
272 
273   Level: intermediate
274 
275  @*/
276 PetscErrorCode MatFindZeroRows(Mat mat,IS *zerorows)
277 {
278   PetscErrorCode ierr;
279   IS keptrows;
280   PetscInt m, n;
281 
282   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
283   PetscValidType(mat,1);
284 
285   ierr = MatFindNonzeroRows(mat, &keptrows);CHKERRQ(ierr);
286   /* MatFindNonzeroRows sets keptrows to NULL if there are no zero rows.
287      In keeping with this convention, we set zerorows to NULL if there are no zero
288      rows. */
289   if (keptrows == NULL) {
290     *zerorows = NULL;
291   } else {
292     ierr = MatGetOwnershipRange(mat,&m,&n);CHKERRQ(ierr);
293     ierr = ISComplement(keptrows,m,n,zerorows);CHKERRQ(ierr);
294     ierr = ISDestroy(&keptrows);CHKERRQ(ierr);
295   }
296   PetscFunctionReturn(0);
297 }
298 
299 /*@
300    MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling
301 
302    Not Collective
303 
304    Input Parameters:
305 .   A - the matrix
306 
307    Output Parameters:
308 .   a - the diagonal part (which is a SEQUENTIAL matrix)
309 
310    Notes:
311     see the manual page for MatCreateAIJ() for more information on the "diagonal part" of the matrix.
312           Use caution, as the reference count on the returned matrix is not incremented and it is used as
313 	  part of the containing MPI Mat's normal operation.
314 
315    Level: advanced
316 
317 @*/
318 PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a)
319 {
320   PetscErrorCode ierr;
321 
322   PetscFunctionBegin;
323   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
324   PetscValidType(A,1);
325   PetscValidPointer(a,3);
326   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
327   if (!A->ops->getdiagonalblock) {
328     PetscMPIInt size;
329     ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);CHKERRQ(ierr);
330     if (size == 1) {
331       *a = A;
332       PetscFunctionReturn(0);
333     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Not coded for this matrix type");
334   }
335   ierr = (*A->ops->getdiagonalblock)(A,a);CHKERRQ(ierr);
336   PetscFunctionReturn(0);
337 }
338 
339 /*@
340    MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries.
341 
342    Collective on Mat
343 
344    Input Parameters:
345 .  mat - the matrix
346 
347    Output Parameter:
348 .   trace - the sum of the diagonal entries
349 
350    Level: advanced
351 
352 @*/
353 PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace)
354 {
355   PetscErrorCode ierr;
356   Vec            diag;
357 
358   PetscFunctionBegin;
359   ierr = MatCreateVecs(mat,&diag,NULL);CHKERRQ(ierr);
360   ierr = MatGetDiagonal(mat,diag);CHKERRQ(ierr);
361   ierr = VecSum(diag,trace);CHKERRQ(ierr);
362   ierr = VecDestroy(&diag);CHKERRQ(ierr);
363   PetscFunctionReturn(0);
364 }
365 
366 /*@
367    MatRealPart - Zeros out the imaginary part of the matrix
368 
369    Logically Collective on Mat
370 
371    Input Parameters:
372 .  mat - the matrix
373 
374    Level: advanced
375 
376 
377 .seealso: MatImaginaryPart()
378 @*/
379 PetscErrorCode MatRealPart(Mat mat)
380 {
381   PetscErrorCode ierr;
382 
383   PetscFunctionBegin;
384   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
385   PetscValidType(mat,1);
386   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
387   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
388   if (!mat->ops->realpart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
389   MatCheckPreallocated(mat,1);
390   ierr = (*mat->ops->realpart)(mat);CHKERRQ(ierr);
391 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
392   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
393     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
394   }
395 #endif
396   PetscFunctionReturn(0);
397 }
398 
399 /*@C
400    MatGetGhosts - Get the global index of all ghost nodes defined by the sparse matrix
401 
402    Collective on Mat
403 
404    Input Parameter:
405 .  mat - the matrix
406 
407    Output Parameters:
408 +   nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block)
409 -   ghosts - the global indices of the ghost points
410 
411    Notes:
412     the nghosts and ghosts are suitable to pass into VecCreateGhost()
413 
414    Level: advanced
415 
416 @*/
417 PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[])
418 {
419   PetscErrorCode ierr;
420 
421   PetscFunctionBegin;
422   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
423   PetscValidType(mat,1);
424   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
425   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
426   if (!mat->ops->getghosts) {
427     if (nghosts) *nghosts = 0;
428     if (ghosts) *ghosts = 0;
429   } else {
430     ierr = (*mat->ops->getghosts)(mat,nghosts,ghosts);CHKERRQ(ierr);
431   }
432   PetscFunctionReturn(0);
433 }
434 
435 
436 /*@
437    MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part
438 
439    Logically Collective on Mat
440 
441    Input Parameters:
442 .  mat - the matrix
443 
444    Level: advanced
445 
446 
447 .seealso: MatRealPart()
448 @*/
449 PetscErrorCode MatImaginaryPart(Mat mat)
450 {
451   PetscErrorCode ierr;
452 
453   PetscFunctionBegin;
454   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
455   PetscValidType(mat,1);
456   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
457   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
458   if (!mat->ops->imaginarypart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
459   MatCheckPreallocated(mat,1);
460   ierr = (*mat->ops->imaginarypart)(mat);CHKERRQ(ierr);
461 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
462   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
463     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
464   }
465 #endif
466   PetscFunctionReturn(0);
467 }
468 
469 /*@
470    MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices)
471 
472    Not Collective
473 
474    Input Parameter:
475 .  mat - the matrix
476 
477    Output Parameters:
478 +  missing - is any diagonal missing
479 -  dd - first diagonal entry that is missing (optional) on this process
480 
481    Level: advanced
482 
483 
484 .seealso: MatRealPart()
485 @*/
486 PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd)
487 {
488   PetscErrorCode ierr;
489 
490   PetscFunctionBegin;
491   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
492   PetscValidType(mat,1);
493   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
494   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
495   if (!mat->ops->missingdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
496   ierr = (*mat->ops->missingdiagonal)(mat,missing,dd);CHKERRQ(ierr);
497   PetscFunctionReturn(0);
498 }
499 
500 /*@C
501    MatGetRow - Gets a row of a matrix.  You MUST call MatRestoreRow()
502    for each row that you get to ensure that your application does
503    not bleed memory.
504 
505    Not Collective
506 
507    Input Parameters:
508 +  mat - the matrix
509 -  row - the row to get
510 
511    Output Parameters:
512 +  ncols -  if not NULL, the number of nonzeros in the row
513 .  cols - if not NULL, the column numbers
514 -  vals - if not NULL, the values
515 
516    Notes:
517    This routine is provided for people who need to have direct access
518    to the structure of a matrix.  We hope that we provide enough
519    high-level matrix routines that few users will need it.
520 
521    MatGetRow() always returns 0-based column indices, regardless of
522    whether the internal representation is 0-based (default) or 1-based.
523 
524    For better efficiency, set cols and/or vals to NULL if you do
525    not wish to extract these quantities.
526 
527    The user can only examine the values extracted with MatGetRow();
528    the values cannot be altered.  To change the matrix entries, one
529    must use MatSetValues().
530 
531    You can only have one call to MatGetRow() outstanding for a particular
532    matrix at a time, per processor. MatGetRow() can only obtain rows
533    associated with the given processor, it cannot get rows from the
534    other processors; for that we suggest using MatCreateSubMatrices(), then
535    MatGetRow() on the submatrix. The row index passed to MatGetRow()
536    is in the global number of rows.
537 
538    Fortran Notes:
539    The calling sequence from Fortran is
540 .vb
541    MatGetRow(matrix,row,ncols,cols,values,ierr)
542          Mat     matrix (input)
543          integer row    (input)
544          integer ncols  (output)
545          integer cols(maxcols) (output)
546          double precision (or double complex) values(maxcols) output
547 .ve
548    where maxcols >= maximum nonzeros in any row of the matrix.
549 
550 
551    Caution:
552    Do not try to change the contents of the output arrays (cols and vals).
553    In some cases, this may corrupt the matrix.
554 
555    Level: advanced
556 
557    Concepts: matrices^row access
558 
559 .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatCreateSubMatrices(), MatGetDiagonal()
560 @*/
561 PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
562 {
563   PetscErrorCode ierr;
564   PetscInt       incols;
565 
566   PetscFunctionBegin;
567   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
568   PetscValidType(mat,1);
569   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
570   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
571   if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
572   MatCheckPreallocated(mat,1);
573   ierr = PetscLogEventBegin(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr);
574   ierr = (*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals);CHKERRQ(ierr);
575   if (ncols) *ncols = incols;
576   ierr = PetscLogEventEnd(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr);
577   PetscFunctionReturn(0);
578 }
579 
580 /*@
581    MatConjugate - replaces the matrix values with their complex conjugates
582 
583    Logically Collective on Mat
584 
585    Input Parameters:
586 .  mat - the matrix
587 
588    Level: advanced
589 
590 .seealso:  VecConjugate()
591 @*/
592 PetscErrorCode MatConjugate(Mat mat)
593 {
594 #if defined(PETSC_USE_COMPLEX)
595   PetscErrorCode ierr;
596 
597   PetscFunctionBegin;
598   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
599   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
600   if (!mat->ops->conjugate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not provided for this matrix format, send email to petsc-maint@mcs.anl.gov");
601   ierr = (*mat->ops->conjugate)(mat);CHKERRQ(ierr);
602 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
603   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
604     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
605   }
606 #endif
607   PetscFunctionReturn(0);
608 #else
609   return 0;
610 #endif
611 }
612 
613 /*@C
614    MatRestoreRow - Frees any temporary space allocated by MatGetRow().
615 
616    Not Collective
617 
618    Input Parameters:
619 +  mat - the matrix
620 .  row - the row to get
621 .  ncols, cols - the number of nonzeros and their columns
622 -  vals - if nonzero the column values
623 
624    Notes:
625    This routine should be called after you have finished examining the entries.
626 
627    This routine zeros out ncols, cols, and vals. This is to prevent accidental
628    us of the array after it has been restored. If you pass NULL, it will
629    not zero the pointers.  Use of cols or vals after MatRestoreRow is invalid.
630 
631    Fortran Notes:
632    The calling sequence from Fortran is
633 .vb
634    MatRestoreRow(matrix,row,ncols,cols,values,ierr)
635       Mat     matrix (input)
636       integer row    (input)
637       integer ncols  (output)
638       integer cols(maxcols) (output)
639       double precision (or double complex) values(maxcols) output
640 .ve
641    Where maxcols >= maximum nonzeros in any row of the matrix.
642 
643    In Fortran MatRestoreRow() MUST be called after MatGetRow()
644    before another call to MatGetRow() can be made.
645 
646    Level: advanced
647 
648 .seealso:  MatGetRow()
649 @*/
650 PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
651 {
652   PetscErrorCode ierr;
653 
654   PetscFunctionBegin;
655   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
656   if (ncols) PetscValidIntPointer(ncols,3);
657   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
658   if (!mat->ops->restorerow) PetscFunctionReturn(0);
659   ierr = (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);CHKERRQ(ierr);
660   if (ncols) *ncols = 0;
661   if (cols)  *cols = NULL;
662   if (vals)  *vals = NULL;
663   PetscFunctionReturn(0);
664 }
665 
666 /*@
667    MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format.
668    You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag.
669 
670    Not Collective
671 
672    Input Parameters:
673 +  mat - the matrix
674 
675    Notes:
676    The flag is to ensure that users are aware of MatGetRow() only provides the upper trianglular part of the row for the matrices in MATSBAIJ format.
677 
678    Level: advanced
679 
680    Concepts: matrices^row access
681 
682 .seealso: MatRestoreRowRowUpperTriangular()
683 @*/
684 PetscErrorCode MatGetRowUpperTriangular(Mat mat)
685 {
686   PetscErrorCode ierr;
687 
688   PetscFunctionBegin;
689   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
690   PetscValidType(mat,1);
691   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
692   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
693   if (!mat->ops->getrowuppertriangular) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
694   MatCheckPreallocated(mat,1);
695   ierr = (*mat->ops->getrowuppertriangular)(mat);CHKERRQ(ierr);
696   PetscFunctionReturn(0);
697 }
698 
699 /*@
700    MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format.
701 
702    Not Collective
703 
704    Input Parameters:
705 +  mat - the matrix
706 
707    Notes:
708    This routine should be called after you have finished MatGetRow/MatRestoreRow().
709 
710 
711    Level: advanced
712 
713 .seealso:  MatGetRowUpperTriangular()
714 @*/
715 PetscErrorCode MatRestoreRowUpperTriangular(Mat mat)
716 {
717   PetscErrorCode ierr;
718 
719   PetscFunctionBegin;
720   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
721   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
722   if (!mat->ops->restorerowuppertriangular) PetscFunctionReturn(0);
723   ierr = (*mat->ops->restorerowuppertriangular)(mat);CHKERRQ(ierr);
724   PetscFunctionReturn(0);
725 }
726 
727 /*@C
728    MatSetOptionsPrefix - Sets the prefix used for searching for all
729    Mat options in the database.
730 
731    Logically Collective on Mat
732 
733    Input Parameter:
734 +  A - the Mat context
735 -  prefix - the prefix to prepend to all option names
736 
737    Notes:
738    A hyphen (-) must NOT be given at the beginning of the prefix name.
739    The first character of all runtime options is AUTOMATICALLY the hyphen.
740 
741    Level: advanced
742 
743 .keywords: Mat, set, options, prefix, database
744 
745 .seealso: MatSetFromOptions()
746 @*/
747 PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[])
748 {
749   PetscErrorCode ierr;
750 
751   PetscFunctionBegin;
752   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
753   ierr = PetscObjectSetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
754   PetscFunctionReturn(0);
755 }
756 
757 /*@C
758    MatAppendOptionsPrefix - Appends to the prefix used for searching for all
759    Mat options in the database.
760 
761    Logically Collective on Mat
762 
763    Input Parameters:
764 +  A - the Mat context
765 -  prefix - the prefix to prepend to all option names
766 
767    Notes:
768    A hyphen (-) must NOT be given at the beginning of the prefix name.
769    The first character of all runtime options is AUTOMATICALLY the hyphen.
770 
771    Level: advanced
772 
773 .keywords: Mat, append, options, prefix, database
774 
775 .seealso: MatGetOptionsPrefix()
776 @*/
777 PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[])
778 {
779   PetscErrorCode ierr;
780 
781   PetscFunctionBegin;
782   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
783   ierr = PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
784   PetscFunctionReturn(0);
785 }
786 
787 /*@C
788    MatGetOptionsPrefix - Sets the prefix used for searching for all
789    Mat options in the database.
790 
791    Not Collective
792 
793    Input Parameter:
794 .  A - the Mat context
795 
796    Output Parameter:
797 .  prefix - pointer to the prefix string used
798 
799    Notes:
800     On the fortran side, the user should pass in a string 'prefix' of
801    sufficient length to hold the prefix.
802 
803    Level: advanced
804 
805 .keywords: Mat, get, options, prefix, database
806 
807 .seealso: MatAppendOptionsPrefix()
808 @*/
809 PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[])
810 {
811   PetscErrorCode ierr;
812 
813   PetscFunctionBegin;
814   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
815   ierr = PetscObjectGetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
816   PetscFunctionReturn(0);
817 }
818 
819 /*@
820    MatResetPreallocation - Reset mat to use the original nonzero pattern provided by users.
821 
822    Collective on Mat
823 
824    Input Parameters:
825 .  A - the Mat context
826 
827    Notes:
828    The allocated memory will be shrunk after calling MatAssembly with MAT_FINAL_ASSEMBLY. Users can reset the preallocation to access the original memory.
829    Currently support MPIAIJ and SEQAIJ.
830 
831    Level: beginner
832 
833 .keywords: Mat, ResetPreallocation
834 
835 .seealso: MatSeqAIJSetPreallocation(), MatMPIAIJSetPreallocation(), MatXAIJSetPreallocation()
836 @*/
837 PetscErrorCode MatResetPreallocation(Mat A)
838 {
839   PetscErrorCode ierr;
840 
841   PetscFunctionBegin;
842   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
843   PetscValidType(A,1);
844   ierr = PetscUseMethod(A,"MatResetPreallocation_C",(Mat),(A));CHKERRQ(ierr);
845   PetscFunctionReturn(0);
846 }
847 
848 
849 /*@
850    MatSetUp - Sets up the internal matrix data structures for the later use.
851 
852    Collective on Mat
853 
854    Input Parameters:
855 .  A - the Mat context
856 
857    Notes:
858    If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used.
859 
860    If a suitable preallocation routine is used, this function does not need to be called.
861 
862    See the Performance chapter of the PETSc users manual for how to preallocate matrices
863 
864    Level: beginner
865 
866 .keywords: Mat, setup
867 
868 .seealso: MatCreate(), MatDestroy()
869 @*/
870 PetscErrorCode MatSetUp(Mat A)
871 {
872   PetscMPIInt    size;
873   PetscErrorCode ierr;
874 
875   PetscFunctionBegin;
876   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
877   if (!((PetscObject)A)->type_name) {
878     ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A), &size);CHKERRQ(ierr);
879     if (size == 1) {
880       ierr = MatSetType(A, MATSEQAIJ);CHKERRQ(ierr);
881     } else {
882       ierr = MatSetType(A, MATMPIAIJ);CHKERRQ(ierr);
883     }
884   }
885   if (!A->preallocated && A->ops->setup) {
886     ierr = PetscInfo(A,"Warning not preallocating matrix storage\n");CHKERRQ(ierr);
887     ierr = (*A->ops->setup)(A);CHKERRQ(ierr);
888   }
889   ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr);
890   ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr);
891   A->preallocated = PETSC_TRUE;
892   PetscFunctionReturn(0);
893 }
894 
895 #if defined(PETSC_HAVE_SAWS)
896 #include <petscviewersaws.h>
897 #endif
898 /*@C
899    MatView - Visualizes a matrix object.
900 
901    Collective on Mat
902 
903    Input Parameters:
904 +  mat - the matrix
905 -  viewer - visualization context
906 
907   Notes:
908   The available visualization contexts include
909 +    PETSC_VIEWER_STDOUT_SELF - for sequential matrices
910 .    PETSC_VIEWER_STDOUT_WORLD - for parallel matrices created on PETSC_COMM_WORLD
911 .    PETSC_VIEWER_STDOUT_(comm) - for matrices created on MPI communicator comm
912 -     PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure
913 
914    The user can open alternative visualization contexts with
915 +    PetscViewerASCIIOpen() - Outputs matrix to a specified file
916 .    PetscViewerBinaryOpen() - Outputs matrix in binary to a
917          specified file; corresponding input uses MatLoad()
918 .    PetscViewerDrawOpen() - Outputs nonzero matrix structure to
919          an X window display
920 -    PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
921          Currently only the sequential dense and AIJ
922          matrix types support the Socket viewer.
923 
924    The user can call PetscViewerPushFormat() to specify the output
925    format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
926    PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen).  Available formats include
927 +    PETSC_VIEWER_DEFAULT - default, prints matrix contents
928 .    PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
929 .    PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
930 .    PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse
931          format common among all matrix types
932 .    PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific
933          format (which is in many cases the same as the default)
934 .    PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
935          size and structure (not the matrix entries)
936 -    PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about
937          the matrix structure
938 
939    Options Database Keys:
940 +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatAssemblyEnd()
941 .  -mat_view ::ascii_info_detail - Prints more detailed info
942 .  -mat_view - Prints matrix in ASCII format
943 .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
944 .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
945 .  -display <name> - Sets display name (default is host)
946 .  -draw_pause <sec> - Sets number of seconds to pause after display
947 .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: ch_matlab for details)
948 .  -viewer_socket_machine <machine> -
949 .  -viewer_socket_port <port> -
950 .  -mat_view binary - save matrix to file in binary format
951 -  -viewer_binary_filename <name> -
952    Level: beginner
953 
954    Notes:
955     The ASCII viewers are only recommended for small matrices on at most a moderate number of processes,
956     the program will seemingly hang and take hours for larger matrices, for larger matrices one should use the binary format.
957 
958     See the manual page for MatLoad() for the exact format of the binary file when the binary
959       viewer is used.
960 
961       See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary
962       viewer is used.
963 
964       One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure,
965       and then use the following mouse functions.
966 + left mouse: zoom in
967 . middle mouse: zoom out
968 - right mouse: continue with the simulation
969 
970    Concepts: matrices^viewing
971    Concepts: matrices^plotting
972    Concepts: matrices^printing
973 
974 .seealso: PetscViewerPushFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(),
975           PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
976 @*/
977 PetscErrorCode MatView(Mat mat,PetscViewer viewer)
978 {
979   PetscErrorCode    ierr;
980   PetscInt          rows,cols,rbs,cbs;
981   PetscBool         iascii,ibinary;
982   PetscViewerFormat format;
983   PetscMPIInt       size;
984 #if defined(PETSC_HAVE_SAWS)
985   PetscBool         issaws;
986 #endif
987 
988   PetscFunctionBegin;
989   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
990   PetscValidType(mat,1);
991   if (!viewer) {
992     ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);CHKERRQ(ierr);
993   }
994   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
995   PetscCheckSameComm(mat,1,viewer,2);
996   MatCheckPreallocated(mat,1);
997   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
998   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
999   if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(0);
1000   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr);
1001   if (ibinary) {
1002     PetscBool mpiio;
1003     ierr = PetscViewerBinaryGetUseMPIIO(viewer,&mpiio);CHKERRQ(ierr);
1004     if (mpiio) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"PETSc matrix viewers do not support using MPI-IO, turn off that flag");
1005   }
1006 
1007   ierr = PetscLogEventBegin(MAT_View,mat,viewer,0,0);CHKERRQ(ierr);
1008   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1009   if ((!iascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) {
1010     SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detailed");
1011   }
1012 
1013 #if defined(PETSC_HAVE_SAWS)
1014   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr);
1015 #endif
1016   if (iascii) {
1017     if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
1018     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer);CHKERRQ(ierr);
1019     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
1020       MatNullSpace nullsp,transnullsp;
1021 
1022       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1023       ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr);
1024       ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr);
1025       if (rbs != 1 || cbs != 1) {
1026         if (rbs != cbs) {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, rbs=%D, cbs = %D\n",rows,cols,rbs,cbs);CHKERRQ(ierr);}
1027         else            {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,rbs);CHKERRQ(ierr);}
1028       } else {
1029         ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);CHKERRQ(ierr);
1030       }
1031       if (mat->factortype) {
1032         MatSolverType solver;
1033         ierr = MatFactorGetSolverType(mat,&solver);CHKERRQ(ierr);
1034         ierr = PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);CHKERRQ(ierr);
1035       }
1036       if (mat->ops->getinfo) {
1037         MatInfo info;
1038         ierr = MatGetInfo(mat,MAT_GLOBAL_SUM,&info);CHKERRQ(ierr);
1039         ierr = PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated);CHKERRQ(ierr);
1040         ierr = PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls =%D\n",(PetscInt)info.mallocs);CHKERRQ(ierr);
1041       }
1042       ierr = MatGetNullSpace(mat,&nullsp);CHKERRQ(ierr);
1043       ierr = MatGetTransposeNullSpace(mat,&transnullsp);CHKERRQ(ierr);
1044       if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer,"  has attached null space\n");CHKERRQ(ierr);}
1045       if (transnullsp && transnullsp != nullsp) {ierr = PetscViewerASCIIPrintf(viewer,"  has attached transposed null space\n");CHKERRQ(ierr);}
1046       ierr = MatGetNearNullSpace(mat,&nullsp);CHKERRQ(ierr);
1047       if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer,"  has attached near null space\n");CHKERRQ(ierr);}
1048     }
1049 #if defined(PETSC_HAVE_SAWS)
1050   } else if (issaws) {
1051     PetscMPIInt rank;
1052 
1053     ierr = PetscObjectName((PetscObject)mat);CHKERRQ(ierr);
1054     ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
1055     if (!((PetscObject)mat)->amsmem && !rank) {
1056       ierr = PetscObjectViewSAWs((PetscObject)mat,viewer);CHKERRQ(ierr);
1057     }
1058 #endif
1059   }
1060   if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && mat->ops->viewnative) {
1061     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1062     ierr = (*mat->ops->viewnative)(mat,viewer);CHKERRQ(ierr);
1063     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1064   } else if (mat->ops->view) {
1065     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1066     ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr);
1067     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1068   }
1069   if (iascii) {
1070     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1071     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
1072       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1073     }
1074   }
1075   ierr = PetscLogEventEnd(MAT_View,mat,viewer,0,0);CHKERRQ(ierr);
1076   PetscFunctionReturn(0);
1077 }
1078 
1079 #if defined(PETSC_USE_DEBUG)
1080 #include <../src/sys/totalview/tv_data_display.h>
1081 PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat)
1082 {
1083   TV_add_row("Local rows", "int", &mat->rmap->n);
1084   TV_add_row("Local columns", "int", &mat->cmap->n);
1085   TV_add_row("Global rows", "int", &mat->rmap->N);
1086   TV_add_row("Global columns", "int", &mat->cmap->N);
1087   TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name);
1088   return TV_format_OK;
1089 }
1090 #endif
1091 
1092 /*@C
1093    MatLoad - Loads a matrix that has been stored in binary/HDF5 format
1094    with MatView().  The matrix format is determined from the options database.
1095    Generates a parallel MPI matrix if the communicator has more than one
1096    processor.  The default matrix type is AIJ.
1097 
1098    Collective on PetscViewer
1099 
1100    Input Parameters:
1101 +  newmat - the newly loaded matrix, this needs to have been created with MatCreate()
1102             or some related function before a call to MatLoad()
1103 -  viewer - binary/HDF5 file viewer
1104 
1105    Options Database Keys:
1106    Used with block matrix formats (MATSEQBAIJ,  ...) to specify
1107    block size
1108 .    -matload_block_size <bs>
1109 
1110    Level: beginner
1111 
1112    Notes:
1113    If the Mat type has not yet been given then MATAIJ is used, call MatSetFromOptions() on the
1114    Mat before calling this routine if you wish to set it from the options database.
1115 
1116    MatLoad() automatically loads into the options database any options
1117    given in the file filename.info where filename is the name of the file
1118    that was passed to the PetscViewerBinaryOpen(). The options in the info
1119    file will be ignored if you use the -viewer_binary_skip_info option.
1120 
1121    If the type or size of newmat is not set before a call to MatLoad, PETSc
1122    sets the default matrix type AIJ and sets the local and global sizes.
1123    If type and/or size is already set, then the same are used.
1124 
1125    In parallel, each processor can load a subset of rows (or the
1126    entire matrix).  This routine is especially useful when a large
1127    matrix is stored on disk and only part of it is desired on each
1128    processor.  For example, a parallel solver may access only some of
1129    the rows from each processor.  The algorithm used here reads
1130    relatively small blocks of data rather than reading the entire
1131    matrix and then subsetting it.
1132 
1133    Viewer's PetscViewerType must be either PETSCVIEWERBINARY or PETSCVIEWERHDF5.
1134    Such viewer can be created using PetscViewerBinaryOpen()/PetscViewerHDF5Open(),
1135    or the sequence like
1136 $    PetscViewer v;
1137 $    PetscViewerCreate(PETSC_COMM_WORLD,&v);
1138 $    PetscViewerSetType(v,PETSCVIEWERBINARY);
1139 $    PetscViewerSetFromOptions(v);
1140 $    PetscViewerFileSetMode(v,FILE_MODE_READ);
1141 $    PetscViewerFileSetName(v,"datafile");
1142    The optional PetscViewerSetFromOptions() call allows to override PetscViewerSetType() using option
1143 $ -viewer_type {binary,hdf5}
1144 
1145    See the example src/ksp/ksp/examples/tutorials/ex27.c with the first approach,
1146    and src/mat/examples/tutorials/ex10.c with the second approach.
1147 
1148    Notes about the PETSc binary format:
1149    In case of PETSCVIEWERBINARY, a native PETSc binary format is used. Each of the blocks
1150    is read onto rank 0 and then shipped to its destination rank, one after another.
1151    Multiple objects, both matrices and vectors, can be stored within the same file.
1152    Their PetscObject name is ignored; they are loaded in the order of their storage.
1153 
1154    Most users should not need to know the details of the binary storage
1155    format, since MatLoad() and MatView() completely hide these details.
1156    But for anyone who's interested, the standard binary matrix storage
1157    format is
1158 
1159 $    int    MAT_FILE_CLASSID
1160 $    int    number of rows
1161 $    int    number of columns
1162 $    int    total number of nonzeros
1163 $    int    *number nonzeros in each row
1164 $    int    *column indices of all nonzeros (starting index is zero)
1165 $    PetscScalar *values of all nonzeros
1166 
1167    PETSc automatically does the byte swapping for
1168 machines that store the bytes reversed, e.g.  DEC alpha, freebsd,
1169 linux, Windows and the paragon; thus if you write your own binary
1170 read/write routines you have to swap the bytes; see PetscBinaryRead()
1171 and PetscBinaryWrite() to see how this may be done.
1172 
1173    Notes about the HDF5 (MATLAB MAT-File Version 7.3) format:
1174    In case of PETSCVIEWERHDF5, a parallel HDF5 reader is used.
1175    Each processor's chunk is loaded independently by its owning rank.
1176    Multiple objects, both matrices and vectors, can be stored within the same file.
1177    They are looked up by their PetscObject name.
1178 
1179    As the MATLAB MAT-File Version 7.3 format is also a HDF5 flavor, we decided to use
1180    by default the same structure and naming of the AIJ arrays and column count
1181    (see PetscViewerHDF5SetAIJNames())
1182    within the HDF5 file. This means that a MAT file saved with -v7.3 flag, e.g.
1183 $    save example.mat A b -v7.3
1184    can be directly read by this routine (see Reference 1 for details).
1185    Note that depending on your MATLAB version, this format might be a default,
1186    otherwise you can set it as default in Preferences.
1187 
1188    Unless -nocompression flag is used to save the file in MATLAB,
1189    PETSc must be configured with ZLIB package.
1190 
1191    See also examples src/mat/examples/tutorials/ex10.c and src/ksp/ksp/examples/tutorials/ex27.c
1192 
1193    Current HDF5 (MAT-File) limitations:
1194    This reader currently supports only real MATSEQAIJ and MATMPIAIJ matrices.
1195 
1196    Corresponding MatView() is not yet implemented.
1197 
1198    The loaded matrix is actually a transpose of the original one in MATLAB,
1199    unless you push PETSC_VIEWER_HDF5_MAT format (see examples above).
1200    With this format, matrix is automatically transposed by PETSc,
1201    unless the matrix is marked as SPD or symmetric
1202    (see MatSetOption(), MAT_SPD, MAT_SYMMETRIC).
1203 
1204    References:
1205 1. MATLAB(R) Documentation, manual page of save(), https://www.mathworks.com/help/matlab/ref/save.html#btox10b-1-version
1206 
1207 .keywords: matrix, load, binary, input, HDF5
1208 
1209 .seealso: PetscViewerBinaryOpen(), PetscViewerSetType(), PetscViewerHDF5SetAIJNames(), MatView(), VecLoad()
1210 
1211  @*/
1212 PetscErrorCode MatLoad(Mat newmat,PetscViewer viewer)
1213 {
1214   PetscErrorCode ierr;
1215   PetscBool      flg;
1216 
1217   PetscFunctionBegin;
1218   PetscValidHeaderSpecific(newmat,MAT_CLASSID,1);
1219   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1220 
1221   if (!((PetscObject)newmat)->type_name) {
1222     ierr = MatSetType(newmat,MATAIJ);CHKERRQ(ierr);
1223   }
1224 
1225   flg  = PETSC_FALSE;
1226   ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,NULL);CHKERRQ(ierr);
1227   if (flg) {
1228     ierr = MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
1229     ierr = MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);CHKERRQ(ierr);
1230   }
1231   flg  = PETSC_FALSE;
1232   ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_spd",&flg,NULL);CHKERRQ(ierr);
1233   if (flg) {
1234     ierr = MatSetOption(newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr);
1235   }
1236 
1237   if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type");
1238   ierr = PetscLogEventBegin(MAT_Load,viewer,0,0,0);CHKERRQ(ierr);
1239   ierr = (*newmat->ops->load)(newmat,viewer);CHKERRQ(ierr);
1240   ierr = PetscLogEventEnd(MAT_Load,viewer,0,0,0);CHKERRQ(ierr);
1241   PetscFunctionReturn(0);
1242 }
1243 
1244 PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant)
1245 {
1246   PetscErrorCode ierr;
1247   Mat_Redundant  *redund = *redundant;
1248   PetscInt       i;
1249 
1250   PetscFunctionBegin;
1251   if (redund){
1252     if (redund->matseq) { /* via MatCreateSubMatrices()  */
1253       ierr = ISDestroy(&redund->isrow);CHKERRQ(ierr);
1254       ierr = ISDestroy(&redund->iscol);CHKERRQ(ierr);
1255       ierr = MatDestroySubMatrices(1,&redund->matseq);CHKERRQ(ierr);
1256     } else {
1257       ierr = PetscFree2(redund->send_rank,redund->recv_rank);CHKERRQ(ierr);
1258       ierr = PetscFree(redund->sbuf_j);CHKERRQ(ierr);
1259       ierr = PetscFree(redund->sbuf_a);CHKERRQ(ierr);
1260       for (i=0; i<redund->nrecvs; i++) {
1261         ierr = PetscFree(redund->rbuf_j[i]);CHKERRQ(ierr);
1262         ierr = PetscFree(redund->rbuf_a[i]);CHKERRQ(ierr);
1263       }
1264       ierr = PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a);CHKERRQ(ierr);
1265     }
1266 
1267     if (redund->subcomm) {
1268       ierr = PetscCommDestroy(&redund->subcomm);CHKERRQ(ierr);
1269     }
1270     ierr = PetscFree(redund);CHKERRQ(ierr);
1271   }
1272   PetscFunctionReturn(0);
1273 }
1274 
1275 /*@
1276    MatDestroy - Frees space taken by a matrix.
1277 
1278    Collective on Mat
1279 
1280    Input Parameter:
1281 .  A - the matrix
1282 
1283    Level: beginner
1284 
1285 @*/
1286 PetscErrorCode MatDestroy(Mat *A)
1287 {
1288   PetscErrorCode ierr;
1289 
1290   PetscFunctionBegin;
1291   if (!*A) PetscFunctionReturn(0);
1292   PetscValidHeaderSpecific(*A,MAT_CLASSID,1);
1293   if (--((PetscObject)(*A))->refct > 0) {*A = NULL; PetscFunctionReturn(0);}
1294 
1295   /* if memory was published with SAWs then destroy it */
1296   ierr = PetscObjectSAWsViewOff((PetscObject)*A);CHKERRQ(ierr);
1297   if ((*A)->ops->destroy) {
1298     ierr = (*(*A)->ops->destroy)(*A);CHKERRQ(ierr);
1299   }
1300 
1301   ierr = PetscFree((*A)->defaultvectype);CHKERRQ(ierr);
1302   ierr = PetscFree((*A)->bsizes);CHKERRQ(ierr);
1303   ierr = PetscFree((*A)->solvertype);CHKERRQ(ierr);
1304   ierr = MatDestroy_Redundant(&(*A)->redundant);CHKERRQ(ierr);
1305   ierr = MatNullSpaceDestroy(&(*A)->nullsp);CHKERRQ(ierr);
1306   ierr = MatNullSpaceDestroy(&(*A)->transnullsp);CHKERRQ(ierr);
1307   ierr = MatNullSpaceDestroy(&(*A)->nearnullsp);CHKERRQ(ierr);
1308   ierr = MatDestroy(&(*A)->schur);CHKERRQ(ierr);
1309   ierr = PetscLayoutDestroy(&(*A)->rmap);CHKERRQ(ierr);
1310   ierr = PetscLayoutDestroy(&(*A)->cmap);CHKERRQ(ierr);
1311   ierr = PetscHeaderDestroy(A);CHKERRQ(ierr);
1312   PetscFunctionReturn(0);
1313 }
1314 
1315 /*@C
1316    MatSetValues - Inserts or adds a block of values into a matrix.
1317    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1318    MUST be called after all calls to MatSetValues() have been completed.
1319 
1320    Not Collective
1321 
1322    Input Parameters:
1323 +  mat - the matrix
1324 .  v - a logically two-dimensional array of values
1325 .  m, idxm - the number of rows and their global indices
1326 .  n, idxn - the number of columns and their global indices
1327 -  addv - either ADD_VALUES or INSERT_VALUES, where
1328    ADD_VALUES adds values to any existing entries, and
1329    INSERT_VALUES replaces existing entries with new values
1330 
1331    Notes:
1332    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
1333       MatSetUp() before using this routine
1334 
1335    By default the values, v, are row-oriented. See MatSetOption() for other options.
1336 
1337    Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
1338    options cannot be mixed without intervening calls to the assembly
1339    routines.
1340 
1341    MatSetValues() uses 0-based row and column numbers in Fortran
1342    as well as in C.
1343 
1344    Negative indices may be passed in idxm and idxn, these rows and columns are
1345    simply ignored. This allows easily inserting element stiffness matrices
1346    with homogeneous Dirchlet boundary conditions that you don't want represented
1347    in the matrix.
1348 
1349    Efficiency Alert:
1350    The routine MatSetValuesBlocked() may offer much better efficiency
1351    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1352 
1353    Level: beginner
1354 
1355    Developer Notes:
1356     This is labeled with C so does not automatically generate Fortran stubs and interfaces
1357                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
1358 
1359    Concepts: matrices^putting entries in
1360 
1361 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1362           InsertMode, INSERT_VALUES, ADD_VALUES
1363 @*/
1364 PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1365 {
1366   PetscErrorCode ierr;
1367 #if defined(PETSC_USE_DEBUG)
1368   PetscInt       i,j;
1369 #endif
1370 
1371   PetscFunctionBeginHot;
1372   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1373   PetscValidType(mat,1);
1374   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1375   PetscValidIntPointer(idxm,3);
1376   PetscValidIntPointer(idxn,5);
1377   PetscValidScalarPointer(v,6);
1378   MatCheckPreallocated(mat,1);
1379   if (mat->insertmode == NOT_SET_VALUES) {
1380     mat->insertmode = addv;
1381   }
1382 #if defined(PETSC_USE_DEBUG)
1383   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1384   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1385   if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1386 
1387   for (i=0; i<m; i++) {
1388     for (j=0; j<n; j++) {
1389       if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j]))
1390 #if defined(PETSC_USE_COMPLEX)
1391         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]);
1392 #else
1393         SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%D,%D)",(double)v[i*n+j],idxm[i],idxn[j]);
1394 #endif
1395     }
1396   }
1397 #endif
1398 
1399   if (mat->assembled) {
1400     mat->was_assembled = PETSC_TRUE;
1401     mat->assembled     = PETSC_FALSE;
1402   }
1403   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1404   ierr = (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
1405   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1406 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1407   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1408     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1409   }
1410 #endif
1411   PetscFunctionReturn(0);
1412 }
1413 
1414 
1415 /*@
1416    MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
1417         values into a matrix
1418 
1419    Not Collective
1420 
1421    Input Parameters:
1422 +  mat - the matrix
1423 .  row - the (block) row to set
1424 -  v - a logically two-dimensional array of values
1425 
1426    Notes:
1427    By the values, v, are column-oriented (for the block version) and sorted
1428 
1429    All the nonzeros in the row must be provided
1430 
1431    The matrix must have previously had its column indices set
1432 
1433    The row must belong to this process
1434 
1435    Level: intermediate
1436 
1437    Concepts: matrices^putting entries in
1438 
1439 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1440           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping()
1441 @*/
1442 PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
1443 {
1444   PetscErrorCode ierr;
1445   PetscInt       globalrow;
1446 
1447   PetscFunctionBegin;
1448   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1449   PetscValidType(mat,1);
1450   PetscValidScalarPointer(v,2);
1451   ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);CHKERRQ(ierr);
1452   ierr = MatSetValuesRow(mat,globalrow,v);CHKERRQ(ierr);
1453 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1454   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1455     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1456   }
1457 #endif
1458   PetscFunctionReturn(0);
1459 }
1460 
1461 /*@
1462    MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
1463         values into a matrix
1464 
1465    Not Collective
1466 
1467    Input Parameters:
1468 +  mat - the matrix
1469 .  row - the (block) row to set
1470 -  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
1471 
1472    Notes:
1473    The values, v, are column-oriented for the block version.
1474 
1475    All the nonzeros in the row must be provided
1476 
1477    THE MATRIX MUST HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually MatSetValues() is used.
1478 
1479    The row must belong to this process
1480 
1481    Level: advanced
1482 
1483    Concepts: matrices^putting entries in
1484 
1485 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1486           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1487 @*/
1488 PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
1489 {
1490   PetscErrorCode ierr;
1491 
1492   PetscFunctionBeginHot;
1493   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1494   PetscValidType(mat,1);
1495   MatCheckPreallocated(mat,1);
1496   PetscValidScalarPointer(v,2);
1497 #if defined(PETSC_USE_DEBUG)
1498   if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
1499   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1500 #endif
1501   mat->insertmode = INSERT_VALUES;
1502 
1503   if (mat->assembled) {
1504     mat->was_assembled = PETSC_TRUE;
1505     mat->assembled     = PETSC_FALSE;
1506   }
1507   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1508   if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1509   ierr = (*mat->ops->setvaluesrow)(mat,row,v);CHKERRQ(ierr);
1510   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1511 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1512   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1513     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1514   }
1515 #endif
1516   PetscFunctionReturn(0);
1517 }
1518 
1519 /*@
1520    MatSetValuesStencil - Inserts or adds a block of values into a matrix.
1521      Using structured grid indexing
1522 
1523    Not Collective
1524 
1525    Input Parameters:
1526 +  mat - the matrix
1527 .  m - number of rows being entered
1528 .  idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
1529 .  n - number of columns being entered
1530 .  idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered
1531 .  v - a logically two-dimensional array of values
1532 -  addv - either ADD_VALUES or INSERT_VALUES, where
1533    ADD_VALUES adds values to any existing entries, and
1534    INSERT_VALUES replaces existing entries with new values
1535 
1536    Notes:
1537    By default the values, v, are row-oriented.  See MatSetOption() for other options.
1538 
1539    Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
1540    options cannot be mixed without intervening calls to the assembly
1541    routines.
1542 
1543    The grid coordinates are across the entire grid, not just the local portion
1544 
1545    MatSetValuesStencil() uses 0-based row and column numbers in Fortran
1546    as well as in C.
1547 
1548    For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1549 
1550    In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1551    or call MatSetLocalToGlobalMapping() and MatSetStencil() first.
1552 
1553    The columns and rows in the stencil passed in MUST be contained within the
1554    ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1555    if you create a DMDA with an overlap of one grid level and on a particular process its first
1556    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1557    first i index you can use in your column and row indices in MatSetStencil() is 5.
1558 
1559    In Fortran idxm and idxn should be declared as
1560 $     MatStencil idxm(4,m),idxn(4,n)
1561    and the values inserted using
1562 $    idxm(MatStencil_i,1) = i
1563 $    idxm(MatStencil_j,1) = j
1564 $    idxm(MatStencil_k,1) = k
1565 $    idxm(MatStencil_c,1) = c
1566    etc
1567 
1568    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
1569    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
1570    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
1571    DM_BOUNDARY_PERIODIC boundary type.
1572 
1573    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
1574    a single value per point) you can skip filling those indices.
1575 
1576    Inspired by the structured grid interface to the HYPRE package
1577    (http://www.llnl.gov/CASC/hypre)
1578 
1579    Efficiency Alert:
1580    The routine MatSetValuesBlockedStencil() may offer much better efficiency
1581    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1582 
1583    Level: beginner
1584 
1585    Concepts: matrices^putting entries in
1586 
1587 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1588           MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil
1589 @*/
1590 PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1591 {
1592   PetscErrorCode ierr;
1593   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1594   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1595   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1596 
1597   PetscFunctionBegin;
1598   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1599   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1600   PetscValidType(mat,1);
1601   PetscValidIntPointer(idxm,3);
1602   PetscValidIntPointer(idxn,5);
1603   PetscValidScalarPointer(v,6);
1604 
1605   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1606     jdxm = buf; jdxn = buf+m;
1607   } else {
1608     ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr);
1609     jdxm = bufm; jdxn = bufn;
1610   }
1611   for (i=0; i<m; i++) {
1612     for (j=0; j<3-sdim; j++) dxm++;
1613     tmp = *dxm++ - starts[0];
1614     for (j=0; j<dim-1; j++) {
1615       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1616       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1617     }
1618     if (mat->stencil.noc) dxm++;
1619     jdxm[i] = tmp;
1620   }
1621   for (i=0; i<n; i++) {
1622     for (j=0; j<3-sdim; j++) dxn++;
1623     tmp = *dxn++ - starts[0];
1624     for (j=0; j<dim-1; j++) {
1625       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1626       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1627     }
1628     if (mat->stencil.noc) dxn++;
1629     jdxn[i] = tmp;
1630   }
1631   ierr = MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr);
1632   ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr);
1633   PetscFunctionReturn(0);
1634 }
1635 
1636 /*@
1637    MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1638      Using structured grid indexing
1639 
1640    Not Collective
1641 
1642    Input Parameters:
1643 +  mat - the matrix
1644 .  m - number of rows being entered
1645 .  idxm - grid coordinates for matrix rows being entered
1646 .  n - number of columns being entered
1647 .  idxn - grid coordinates for matrix columns being entered
1648 .  v - a logically two-dimensional array of values
1649 -  addv - either ADD_VALUES or INSERT_VALUES, where
1650    ADD_VALUES adds values to any existing entries, and
1651    INSERT_VALUES replaces existing entries with new values
1652 
1653    Notes:
1654    By default the values, v, are row-oriented and unsorted.
1655    See MatSetOption() for other options.
1656 
1657    Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
1658    options cannot be mixed without intervening calls to the assembly
1659    routines.
1660 
1661    The grid coordinates are across the entire grid, not just the local portion
1662 
1663    MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran
1664    as well as in C.
1665 
1666    For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1667 
1668    In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1669    or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first.
1670 
1671    The columns and rows in the stencil passed in MUST be contained within the
1672    ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1673    if you create a DMDA with an overlap of one grid level and on a particular process its first
1674    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1675    first i index you can use in your column and row indices in MatSetStencil() is 5.
1676 
1677    In Fortran idxm and idxn should be declared as
1678 $     MatStencil idxm(4,m),idxn(4,n)
1679    and the values inserted using
1680 $    idxm(MatStencil_i,1) = i
1681 $    idxm(MatStencil_j,1) = j
1682 $    idxm(MatStencil_k,1) = k
1683    etc
1684 
1685    Negative indices may be passed in idxm and idxn, these rows and columns are
1686    simply ignored. This allows easily inserting element stiffness matrices
1687    with homogeneous Dirchlet boundary conditions that you don't want represented
1688    in the matrix.
1689 
1690    Inspired by the structured grid interface to the HYPRE package
1691    (http://www.llnl.gov/CASC/hypre)
1692 
1693    Level: beginner
1694 
1695    Concepts: matrices^putting entries in
1696 
1697 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1698           MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil,
1699           MatSetBlockSize(), MatSetLocalToGlobalMapping()
1700 @*/
1701 PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1702 {
1703   PetscErrorCode ierr;
1704   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1705   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1706   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1707 
1708   PetscFunctionBegin;
1709   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1710   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1711   PetscValidType(mat,1);
1712   PetscValidIntPointer(idxm,3);
1713   PetscValidIntPointer(idxn,5);
1714   PetscValidScalarPointer(v,6);
1715 
1716   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1717     jdxm = buf; jdxn = buf+m;
1718   } else {
1719     ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr);
1720     jdxm = bufm; jdxn = bufn;
1721   }
1722   for (i=0; i<m; i++) {
1723     for (j=0; j<3-sdim; j++) dxm++;
1724     tmp = *dxm++ - starts[0];
1725     for (j=0; j<sdim-1; j++) {
1726       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1727       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1728     }
1729     dxm++;
1730     jdxm[i] = tmp;
1731   }
1732   for (i=0; i<n; i++) {
1733     for (j=0; j<3-sdim; j++) dxn++;
1734     tmp = *dxn++ - starts[0];
1735     for (j=0; j<sdim-1; j++) {
1736       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1737       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1738     }
1739     dxn++;
1740     jdxn[i] = tmp;
1741   }
1742   ierr = MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr);
1743   ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr);
1744 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1745   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1746     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1747   }
1748 #endif
1749   PetscFunctionReturn(0);
1750 }
1751 
1752 /*@
1753    MatSetStencil - Sets the grid information for setting values into a matrix via
1754         MatSetValuesStencil()
1755 
1756    Not Collective
1757 
1758    Input Parameters:
1759 +  mat - the matrix
1760 .  dim - dimension of the grid 1, 2, or 3
1761 .  dims - number of grid points in x, y, and z direction, including ghost points on your processor
1762 .  starts - starting point of ghost nodes on your processor in x, y, and z direction
1763 -  dof - number of degrees of freedom per node
1764 
1765 
1766    Inspired by the structured grid interface to the HYPRE package
1767    (www.llnl.gov/CASC/hyper)
1768 
1769    For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the
1770    user.
1771 
1772    Level: beginner
1773 
1774    Concepts: matrices^putting entries in
1775 
1776 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1777           MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
1778 @*/
1779 PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1780 {
1781   PetscInt i;
1782 
1783   PetscFunctionBegin;
1784   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1785   PetscValidIntPointer(dims,3);
1786   PetscValidIntPointer(starts,4);
1787 
1788   mat->stencil.dim = dim + (dof > 1);
1789   for (i=0; i<dim; i++) {
1790     mat->stencil.dims[i]   = dims[dim-i-1];      /* copy the values in backwards */
1791     mat->stencil.starts[i] = starts[dim-i-1];
1792   }
1793   mat->stencil.dims[dim]   = dof;
1794   mat->stencil.starts[dim] = 0;
1795   mat->stencil.noc         = (PetscBool)(dof == 1);
1796   PetscFunctionReturn(0);
1797 }
1798 
1799 /*@C
1800    MatSetValuesBlocked - Inserts or adds a block of values into a matrix.
1801 
1802    Not Collective
1803 
1804    Input Parameters:
1805 +  mat - the matrix
1806 .  v - a logically two-dimensional array of values
1807 .  m, idxm - the number of block rows and their global block indices
1808 .  n, idxn - the number of block columns and their global block indices
1809 -  addv - either ADD_VALUES or INSERT_VALUES, where
1810    ADD_VALUES adds values to any existing entries, and
1811    INSERT_VALUES replaces existing entries with new values
1812 
1813    Notes:
1814    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call
1815    MatXXXXSetPreallocation() or MatSetUp() before using this routine.
1816 
1817    The m and n count the NUMBER of blocks in the row direction and column direction,
1818    NOT the total number of rows/columns; for example, if the block size is 2 and
1819    you are passing in values for rows 2,3,4,5  then m would be 2 (not 4).
1820    The values in idxm would be 1 2; that is the first index for each block divided by
1821    the block size.
1822 
1823    Note that you must call MatSetBlockSize() when constructing this matrix (before
1824    preallocating it).
1825 
1826    By default the values, v, are row-oriented, so the layout of
1827    v is the same as for MatSetValues(). See MatSetOption() for other options.
1828 
1829    Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
1830    options cannot be mixed without intervening calls to the assembly
1831    routines.
1832 
1833    MatSetValuesBlocked() uses 0-based row and column numbers in Fortran
1834    as well as in C.
1835 
1836    Negative indices may be passed in idxm and idxn, these rows and columns are
1837    simply ignored. This allows easily inserting element stiffness matrices
1838    with homogeneous Dirchlet boundary conditions that you don't want represented
1839    in the matrix.
1840 
1841    Each time an entry is set within a sparse matrix via MatSetValues(),
1842    internal searching must be done to determine where to place the
1843    data in the matrix storage space.  By instead inserting blocks of
1844    entries via MatSetValuesBlocked(), the overhead of matrix assembly is
1845    reduced.
1846 
1847    Example:
1848 $   Suppose m=n=2 and block size(bs) = 2 The array is
1849 $
1850 $   1  2  | 3  4
1851 $   5  6  | 7  8
1852 $   - - - | - - -
1853 $   9  10 | 11 12
1854 $   13 14 | 15 16
1855 $
1856 $   v[] should be passed in like
1857 $   v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
1858 $
1859 $  If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then
1860 $   v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16]
1861 
1862    Level: intermediate
1863 
1864    Concepts: matrices^putting entries in blocked
1865 
1866 .seealso: MatSetBlockSize(), MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal()
1867 @*/
1868 PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1869 {
1870   PetscErrorCode ierr;
1871 
1872   PetscFunctionBeginHot;
1873   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1874   PetscValidType(mat,1);
1875   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1876   PetscValidIntPointer(idxm,3);
1877   PetscValidIntPointer(idxn,5);
1878   PetscValidScalarPointer(v,6);
1879   MatCheckPreallocated(mat,1);
1880   if (mat->insertmode == NOT_SET_VALUES) {
1881     mat->insertmode = addv;
1882   }
1883 #if defined(PETSC_USE_DEBUG)
1884   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1885   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1886   if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1887 #endif
1888 
1889   if (mat->assembled) {
1890     mat->was_assembled = PETSC_TRUE;
1891     mat->assembled     = PETSC_FALSE;
1892   }
1893   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1894   if (mat->ops->setvaluesblocked) {
1895     ierr = (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
1896   } else {
1897     PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn;
1898     PetscInt i,j,bs,cbs;
1899     ierr = MatGetBlockSizes(mat,&bs,&cbs);CHKERRQ(ierr);
1900     if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1901       iidxm = buf; iidxn = buf + m*bs;
1902     } else {
1903       ierr  = PetscMalloc2(m*bs,&bufr,n*cbs,&bufc);CHKERRQ(ierr);
1904       iidxm = bufr; iidxn = bufc;
1905     }
1906     for (i=0; i<m; i++) {
1907       for (j=0; j<bs; j++) {
1908         iidxm[i*bs+j] = bs*idxm[i] + j;
1909       }
1910     }
1911     for (i=0; i<n; i++) {
1912       for (j=0; j<cbs; j++) {
1913         iidxn[i*cbs+j] = cbs*idxn[i] + j;
1914       }
1915     }
1916     ierr = MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv);CHKERRQ(ierr);
1917     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
1918   }
1919   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1920 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1921   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1922     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1923   }
1924 #endif
1925   PetscFunctionReturn(0);
1926 }
1927 
1928 /*@
1929    MatGetValues - Gets a block of values from a matrix.
1930 
1931    Not Collective; currently only returns a local block
1932 
1933    Input Parameters:
1934 +  mat - the matrix
1935 .  v - a logically two-dimensional array for storing the values
1936 .  m, idxm - the number of rows and their global indices
1937 -  n, idxn - the number of columns and their global indices
1938 
1939    Notes:
1940    The user must allocate space (m*n PetscScalars) for the values, v.
1941    The values, v, are then returned in a row-oriented format,
1942    analogous to that used by default in MatSetValues().
1943 
1944    MatGetValues() uses 0-based row and column numbers in
1945    Fortran as well as in C.
1946 
1947    MatGetValues() requires that the matrix has been assembled
1948    with MatAssemblyBegin()/MatAssemblyEnd().  Thus, calls to
1949    MatSetValues() and MatGetValues() CANNOT be made in succession
1950    without intermediate matrix assembly.
1951 
1952    Negative row or column indices will be ignored and those locations in v[] will be
1953    left unchanged.
1954 
1955    Level: advanced
1956 
1957    Concepts: matrices^accessing values
1958 
1959 .seealso: MatGetRow(), MatCreateSubMatrices(), MatSetValues()
1960 @*/
1961 PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1962 {
1963   PetscErrorCode ierr;
1964 
1965   PetscFunctionBegin;
1966   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1967   PetscValidType(mat,1);
1968   if (!m || !n) PetscFunctionReturn(0);
1969   PetscValidIntPointer(idxm,3);
1970   PetscValidIntPointer(idxn,5);
1971   PetscValidScalarPointer(v,6);
1972   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1973   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1974   if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1975   MatCheckPreallocated(mat,1);
1976 
1977   ierr = PetscLogEventBegin(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
1978   ierr = (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);CHKERRQ(ierr);
1979   ierr = PetscLogEventEnd(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
1980   PetscFunctionReturn(0);
1981 }
1982 
1983 /*@
1984   MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and
1985   the same size. Currently, this can only be called once and creates the given matrix.
1986 
1987   Not Collective
1988 
1989   Input Parameters:
1990 + mat - the matrix
1991 . nb - the number of blocks
1992 . bs - the number of rows (and columns) in each block
1993 . rows - a concatenation of the rows for each block
1994 - v - a concatenation of logically two-dimensional arrays of values
1995 
1996   Notes:
1997   In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix.
1998 
1999   Level: advanced
2000 
2001   Concepts: matrices^putting entries in
2002 
2003 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
2004           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
2005 @*/
2006 PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[])
2007 {
2008   PetscErrorCode ierr;
2009 
2010   PetscFunctionBegin;
2011   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2012   PetscValidType(mat,1);
2013   PetscValidScalarPointer(rows,4);
2014   PetscValidScalarPointer(v,5);
2015 #if defined(PETSC_USE_DEBUG)
2016   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2017 #endif
2018 
2019   ierr = PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr);
2020   if (mat->ops->setvaluesbatch) {
2021     ierr = (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);CHKERRQ(ierr);
2022   } else {
2023     PetscInt b;
2024     for (b = 0; b < nb; ++b) {
2025       ierr = MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);CHKERRQ(ierr);
2026     }
2027   }
2028   ierr = PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr);
2029   PetscFunctionReturn(0);
2030 }
2031 
2032 /*@
2033    MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
2034    the routine MatSetValuesLocal() to allow users to insert matrix entries
2035    using a local (per-processor) numbering.
2036 
2037    Not Collective
2038 
2039    Input Parameters:
2040 +  x - the matrix
2041 .  rmapping - row mapping created with ISLocalToGlobalMappingCreate()   or ISLocalToGlobalMappingCreateIS()
2042 - cmapping - column mapping
2043 
2044    Level: intermediate
2045 
2046    Concepts: matrices^local to global mapping
2047    Concepts: local to global mapping^for matrices
2048 
2049 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
2050 @*/
2051 PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
2052 {
2053   PetscErrorCode ierr;
2054 
2055   PetscFunctionBegin;
2056   PetscValidHeaderSpecific(x,MAT_CLASSID,1);
2057   PetscValidType(x,1);
2058   PetscValidHeaderSpecific(rmapping,IS_LTOGM_CLASSID,2);
2059   PetscValidHeaderSpecific(cmapping,IS_LTOGM_CLASSID,3);
2060 
2061   if (x->ops->setlocaltoglobalmapping) {
2062     ierr = (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);CHKERRQ(ierr);
2063   } else {
2064     ierr = PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);CHKERRQ(ierr);
2065     ierr = PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);CHKERRQ(ierr);
2066   }
2067   PetscFunctionReturn(0);
2068 }
2069 
2070 
2071 /*@
2072    MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping()
2073 
2074    Not Collective
2075 
2076    Input Parameters:
2077 .  A - the matrix
2078 
2079    Output Parameters:
2080 + rmapping - row mapping
2081 - cmapping - column mapping
2082 
2083    Level: advanced
2084 
2085    Concepts: matrices^local to global mapping
2086    Concepts: local to global mapping^for matrices
2087 
2088 .seealso:  MatSetValuesLocal()
2089 @*/
2090 PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
2091 {
2092   PetscFunctionBegin;
2093   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2094   PetscValidType(A,1);
2095   if (rmapping) PetscValidPointer(rmapping,2);
2096   if (cmapping) PetscValidPointer(cmapping,3);
2097   if (rmapping) *rmapping = A->rmap->mapping;
2098   if (cmapping) *cmapping = A->cmap->mapping;
2099   PetscFunctionReturn(0);
2100 }
2101 
2102 /*@
2103    MatGetLayouts - Gets the PetscLayout objects for rows and columns
2104 
2105    Not Collective
2106 
2107    Input Parameters:
2108 .  A - the matrix
2109 
2110    Output Parameters:
2111 + rmap - row layout
2112 - cmap - column layout
2113 
2114    Level: advanced
2115 
2116 .seealso:  MatCreateVecs(), MatGetLocalToGlobalMapping()
2117 @*/
2118 PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap)
2119 {
2120   PetscFunctionBegin;
2121   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2122   PetscValidType(A,1);
2123   if (rmap) PetscValidPointer(rmap,2);
2124   if (cmap) PetscValidPointer(cmap,3);
2125   if (rmap) *rmap = A->rmap;
2126   if (cmap) *cmap = A->cmap;
2127   PetscFunctionReturn(0);
2128 }
2129 
2130 /*@C
2131    MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
2132    using a local ordering of the nodes.
2133 
2134    Not Collective
2135 
2136    Input Parameters:
2137 +  mat - the matrix
2138 .  nrow, irow - number of rows and their local indices
2139 .  ncol, icol - number of columns and their local indices
2140 .  y -  a logically two-dimensional array of values
2141 -  addv - either INSERT_VALUES or ADD_VALUES, where
2142    ADD_VALUES adds values to any existing entries, and
2143    INSERT_VALUES replaces existing entries with new values
2144 
2145    Notes:
2146    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
2147       MatSetUp() before using this routine
2148 
2149    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine
2150 
2151    Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
2152    options cannot be mixed without intervening calls to the assembly
2153    routines.
2154 
2155    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2156    MUST be called after all calls to MatSetValuesLocal() have been completed.
2157 
2158    Level: intermediate
2159 
2160    Concepts: matrices^putting entries in with local numbering
2161 
2162    Developer Notes:
2163     This is labeled with C so does not automatically generate Fortran stubs and interfaces
2164                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
2165 
2166 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
2167            MatSetValueLocal()
2168 @*/
2169 PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2170 {
2171   PetscErrorCode ierr;
2172 
2173   PetscFunctionBeginHot;
2174   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2175   PetscValidType(mat,1);
2176   MatCheckPreallocated(mat,1);
2177   if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */
2178   PetscValidIntPointer(irow,3);
2179   PetscValidIntPointer(icol,5);
2180   PetscValidScalarPointer(y,6);
2181   if (mat->insertmode == NOT_SET_VALUES) {
2182     mat->insertmode = addv;
2183   }
2184 #if defined(PETSC_USE_DEBUG)
2185   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2186   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2187   if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2188 #endif
2189 
2190   if (mat->assembled) {
2191     mat->was_assembled = PETSC_TRUE;
2192     mat->assembled     = PETSC_FALSE;
2193   }
2194   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2195   if (mat->ops->setvalueslocal) {
2196     ierr = (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr);
2197   } else {
2198     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2199     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2200       irowm = buf; icolm = buf+nrow;
2201     } else {
2202       ierr  = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr);
2203       irowm = bufr; icolm = bufc;
2204     }
2205     ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr);
2206     ierr = ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr);
2207     ierr = MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
2208     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
2209   }
2210   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2211 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
2212   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
2213     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
2214   }
2215 #endif
2216   PetscFunctionReturn(0);
2217 }
2218 
2219 /*@C
2220    MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix,
2221    using a local ordering of the nodes a block at a time.
2222 
2223    Not Collective
2224 
2225    Input Parameters:
2226 +  x - the matrix
2227 .  nrow, irow - number of rows and their local indices
2228 .  ncol, icol - number of columns and their local indices
2229 .  y -  a logically two-dimensional array of values
2230 -  addv - either INSERT_VALUES or ADD_VALUES, where
2231    ADD_VALUES adds values to any existing entries, and
2232    INSERT_VALUES replaces existing entries with new values
2233 
2234    Notes:
2235    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
2236       MatSetUp() before using this routine
2237 
2238    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMapping()
2239       before using this routineBefore calling MatSetValuesLocal(), the user must first set the
2240 
2241    Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
2242    options cannot be mixed without intervening calls to the assembly
2243    routines.
2244 
2245    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2246    MUST be called after all calls to MatSetValuesBlockedLocal() have been completed.
2247 
2248    Level: intermediate
2249 
2250    Developer Notes:
2251     This is labeled with C so does not automatically generate Fortran stubs and interfaces
2252                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
2253 
2254    Concepts: matrices^putting blocked values in with local numbering
2255 
2256 .seealso:  MatSetBlockSize(), MatSetLocalToGlobalMapping(), MatAssemblyBegin(), MatAssemblyEnd(),
2257            MatSetValuesLocal(),  MatSetValuesBlocked()
2258 @*/
2259 PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2260 {
2261   PetscErrorCode ierr;
2262 
2263   PetscFunctionBeginHot;
2264   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2265   PetscValidType(mat,1);
2266   MatCheckPreallocated(mat,1);
2267   if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */
2268   PetscValidIntPointer(irow,3);
2269   PetscValidIntPointer(icol,5);
2270   PetscValidScalarPointer(y,6);
2271   if (mat->insertmode == NOT_SET_VALUES) {
2272     mat->insertmode = addv;
2273   }
2274 #if defined(PETSC_USE_DEBUG)
2275   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2276   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2277   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);
2278 #endif
2279 
2280   if (mat->assembled) {
2281     mat->was_assembled = PETSC_TRUE;
2282     mat->assembled     = PETSC_FALSE;
2283   }
2284 #if defined(PETSC_USE_DEBUG)
2285   /* Condition on the mapping existing, because MatSetValuesBlockedLocal_IS does not require it to be set. */
2286   if (mat->rmap->mapping) {
2287     PetscInt irbs, rbs;
2288     ierr = MatGetBlockSizes(mat, &rbs, NULL);CHKERRQ(ierr);
2289     ierr = ISLocalToGlobalMappingGetBlockSize(mat->rmap->mapping,&irbs);CHKERRQ(ierr);
2290     if (rbs != irbs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different row block sizes! mat %D, row l2g map %D",rbs,irbs);
2291   }
2292   if (mat->cmap->mapping) {
2293     PetscInt icbs, cbs;
2294     ierr = MatGetBlockSizes(mat,NULL,&cbs);CHKERRQ(ierr);
2295     ierr = ISLocalToGlobalMappingGetBlockSize(mat->cmap->mapping,&icbs);CHKERRQ(ierr);
2296     if (cbs != icbs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different col block sizes! mat %D, col l2g map %D",cbs,icbs);
2297   }
2298 #endif
2299   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2300   if (mat->ops->setvaluesblockedlocal) {
2301     ierr = (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr);
2302   } else {
2303     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2304     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2305       irowm = buf; icolm = buf + nrow;
2306     } else {
2307       ierr  = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr);
2308       irowm = bufr; icolm = bufc;
2309     }
2310     ierr = ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr);
2311     ierr = ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr);
2312     ierr = MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
2313     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
2314   }
2315   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2316 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
2317   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
2318     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
2319   }
2320 #endif
2321   PetscFunctionReturn(0);
2322 }
2323 
2324 /*@
2325    MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal
2326 
2327    Collective on Mat and Vec
2328 
2329    Input Parameters:
2330 +  mat - the matrix
2331 -  x   - the vector to be multiplied
2332 
2333    Output Parameters:
2334 .  y - the result
2335 
2336    Notes:
2337    The vectors x and y cannot be the same.  I.e., one cannot
2338    call MatMult(A,y,y).
2339 
2340    Level: developer
2341 
2342    Concepts: matrix-vector product
2343 
2344 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2345 @*/
2346 PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y)
2347 {
2348   PetscErrorCode ierr;
2349 
2350   PetscFunctionBegin;
2351   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2352   PetscValidType(mat,1);
2353   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2354   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2355 
2356   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2357   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2358   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2359   MatCheckPreallocated(mat,1);
2360 
2361   if (!mat->ops->multdiagonalblock) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2362   ierr = (*mat->ops->multdiagonalblock)(mat,x,y);CHKERRQ(ierr);
2363   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2364   PetscFunctionReturn(0);
2365 }
2366 
2367 /* --------------------------------------------------------*/
2368 /*@
2369    MatMult - Computes the matrix-vector product, y = Ax.
2370 
2371    Neighbor-wise Collective on Mat and Vec
2372 
2373    Input Parameters:
2374 +  mat - the matrix
2375 -  x   - the vector to be multiplied
2376 
2377    Output Parameters:
2378 .  y - the result
2379 
2380    Notes:
2381    The vectors x and y cannot be the same.  I.e., one cannot
2382    call MatMult(A,y,y).
2383 
2384    Level: beginner
2385 
2386    Concepts: matrix-vector product
2387 
2388 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2389 @*/
2390 PetscErrorCode MatMult(Mat mat,Vec x,Vec y)
2391 {
2392   PetscErrorCode ierr;
2393 
2394   PetscFunctionBegin;
2395   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2396   PetscValidType(mat,1);
2397   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2398   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2399   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2400   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2401   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2402 #if !defined(PETSC_HAVE_CONSTRAINTS)
2403   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);
2404   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);
2405   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);
2406 #endif
2407   ierr = VecSetErrorIfLocked(y,3);CHKERRQ(ierr);
2408   if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);}
2409   MatCheckPreallocated(mat,1);
2410 
2411   ierr = VecLockReadPush(x);CHKERRQ(ierr);
2412   if (!mat->ops->mult) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2413   ierr = PetscLogEventBegin(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
2414   ierr = (*mat->ops->mult)(mat,x,y);CHKERRQ(ierr);
2415   ierr = PetscLogEventEnd(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
2416   if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);}
2417   ierr = VecLockReadPop(x);CHKERRQ(ierr);
2418   PetscFunctionReturn(0);
2419 }
2420 
2421 /*@
2422    MatMultTranspose - Computes matrix transpose times a vector y = A^T * x.
2423 
2424    Neighbor-wise Collective on Mat and Vec
2425 
2426    Input Parameters:
2427 +  mat - the matrix
2428 -  x   - the vector to be multiplied
2429 
2430    Output Parameters:
2431 .  y - the result
2432 
2433    Notes:
2434    The vectors x and y cannot be the same.  I.e., one cannot
2435    call MatMultTranspose(A,y,y).
2436 
2437    For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple,
2438    use MatMultHermitianTranspose()
2439 
2440    Level: beginner
2441 
2442    Concepts: matrix vector product^transpose
2443 
2444 .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose()
2445 @*/
2446 PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y)
2447 {
2448   PetscErrorCode ierr;
2449 
2450   PetscFunctionBegin;
2451   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2452   PetscValidType(mat,1);
2453   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2454   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2455 
2456   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2457   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2458   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2459 #if !defined(PETSC_HAVE_CONSTRAINTS)
2460   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);
2461   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);
2462 #endif
2463   if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);}
2464   MatCheckPreallocated(mat,1);
2465 
2466   if (!mat->ops->multtranspose) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply transpose defined");
2467   ierr = PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
2468   ierr = VecLockReadPush(x);CHKERRQ(ierr);
2469   ierr = (*mat->ops->multtranspose)(mat,x,y);CHKERRQ(ierr);
2470   ierr = VecLockReadPop(x);CHKERRQ(ierr);
2471   ierr = PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
2472   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2473   if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);}
2474   PetscFunctionReturn(0);
2475 }
2476 
2477 /*@
2478    MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.
2479 
2480    Neighbor-wise Collective on Mat and Vec
2481 
2482    Input Parameters:
2483 +  mat - the matrix
2484 -  x   - the vector to be multilplied
2485 
2486    Output Parameters:
2487 .  y - the result
2488 
2489    Notes:
2490    The vectors x and y cannot be the same.  I.e., one cannot
2491    call MatMultHermitianTranspose(A,y,y).
2492 
2493    Also called the conjugate transpose, complex conjugate transpose, or adjoint.
2494 
2495    For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical.
2496 
2497    Level: beginner
2498 
2499    Concepts: matrix vector product^transpose
2500 
2501 .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose()
2502 @*/
2503 PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y)
2504 {
2505   PetscErrorCode ierr;
2506   Vec            w;
2507 
2508   PetscFunctionBegin;
2509   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2510   PetscValidType(mat,1);
2511   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2512   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2513 
2514   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2515   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2516   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2517 #if !defined(PETSC_HAVE_CONSTRAINTS)
2518   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);
2519   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);
2520 #endif
2521   MatCheckPreallocated(mat,1);
2522 
2523   ierr = PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr);
2524   if (mat->ops->multhermitiantranspose) {
2525     ierr = VecLockReadPush(x);CHKERRQ(ierr);
2526     ierr = (*mat->ops->multhermitiantranspose)(mat,x,y);CHKERRQ(ierr);
2527     ierr = VecLockReadPop(x);CHKERRQ(ierr);
2528   } else {
2529     ierr = VecDuplicate(x,&w);CHKERRQ(ierr);
2530     ierr = VecCopy(x,w);CHKERRQ(ierr);
2531     ierr = VecConjugate(w);CHKERRQ(ierr);
2532     ierr = MatMultTranspose(mat,w,y);CHKERRQ(ierr);
2533     ierr = VecDestroy(&w);CHKERRQ(ierr);
2534     ierr = VecConjugate(y);CHKERRQ(ierr);
2535   }
2536   ierr = PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr);
2537   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2538   PetscFunctionReturn(0);
2539 }
2540 
2541 /*@
2542     MatMultAdd -  Computes v3 = v2 + A * v1.
2543 
2544     Neighbor-wise Collective on Mat and Vec
2545 
2546     Input Parameters:
2547 +   mat - the matrix
2548 -   v1, v2 - the vectors
2549 
2550     Output Parameters:
2551 .   v3 - the result
2552 
2553     Notes:
2554     The vectors v1 and v3 cannot be the same.  I.e., one cannot
2555     call MatMultAdd(A,v1,v2,v1).
2556 
2557     Level: beginner
2558 
2559     Concepts: matrix vector product^addition
2560 
2561 .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
2562 @*/
2563 PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2564 {
2565   PetscErrorCode ierr;
2566 
2567   PetscFunctionBegin;
2568   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2569   PetscValidType(mat,1);
2570   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2571   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2572   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2573 
2574   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2575   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2576   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);
2577   /* 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);
2578      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); */
2579   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);
2580   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);
2581   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2582   MatCheckPreallocated(mat,1);
2583 
2584   if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name);
2585   ierr = PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2586   ierr = VecLockReadPush(v1);CHKERRQ(ierr);
2587   ierr = (*mat->ops->multadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2588   ierr = VecLockReadPop(v1);CHKERRQ(ierr);
2589   ierr = PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2590   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2591   PetscFunctionReturn(0);
2592 }
2593 
2594 /*@
2595    MatMultTransposeAdd - Computes v3 = v2 + A' * v1.
2596 
2597    Neighbor-wise Collective on Mat and Vec
2598 
2599    Input Parameters:
2600 +  mat - the matrix
2601 -  v1, v2 - the vectors
2602 
2603    Output Parameters:
2604 .  v3 - the result
2605 
2606    Notes:
2607    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2608    call MatMultTransposeAdd(A,v1,v2,v1).
2609 
2610    Level: beginner
2611 
2612    Concepts: matrix vector product^transpose and addition
2613 
2614 .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
2615 @*/
2616 PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2617 {
2618   PetscErrorCode ierr;
2619 
2620   PetscFunctionBegin;
2621   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2622   PetscValidType(mat,1);
2623   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2624   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2625   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2626 
2627   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2628   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2629   if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2630   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2631   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);
2632   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);
2633   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);
2634   MatCheckPreallocated(mat,1);
2635 
2636   ierr = PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2637   ierr = VecLockReadPush(v1);CHKERRQ(ierr);
2638   ierr = (*mat->ops->multtransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2639   ierr = VecLockReadPop(v1);CHKERRQ(ierr);
2640   ierr = PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2641   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2642   PetscFunctionReturn(0);
2643 }
2644 
2645 /*@
2646    MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1.
2647 
2648    Neighbor-wise Collective on Mat and Vec
2649 
2650    Input Parameters:
2651 +  mat - the matrix
2652 -  v1, v2 - the vectors
2653 
2654    Output Parameters:
2655 .  v3 - the result
2656 
2657    Notes:
2658    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2659    call MatMultHermitianTransposeAdd(A,v1,v2,v1).
2660 
2661    Level: beginner
2662 
2663    Concepts: matrix vector product^transpose and addition
2664 
2665 .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult()
2666 @*/
2667 PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2668 {
2669   PetscErrorCode ierr;
2670 
2671   PetscFunctionBegin;
2672   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2673   PetscValidType(mat,1);
2674   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2675   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2676   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2677 
2678   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2679   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2680   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2681   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);
2682   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);
2683   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);
2684   MatCheckPreallocated(mat,1);
2685 
2686   ierr = PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2687   ierr = VecLockReadPush(v1);CHKERRQ(ierr);
2688   if (mat->ops->multhermitiantransposeadd) {
2689     ierr = (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2690   } else {
2691     Vec w,z;
2692     ierr = VecDuplicate(v1,&w);CHKERRQ(ierr);
2693     ierr = VecCopy(v1,w);CHKERRQ(ierr);
2694     ierr = VecConjugate(w);CHKERRQ(ierr);
2695     ierr = VecDuplicate(v3,&z);CHKERRQ(ierr);
2696     ierr = MatMultTranspose(mat,w,z);CHKERRQ(ierr);
2697     ierr = VecDestroy(&w);CHKERRQ(ierr);
2698     ierr = VecConjugate(z);CHKERRQ(ierr);
2699     if (v2 != v3) {
2700       ierr = VecWAXPY(v3,1.0,v2,z);CHKERRQ(ierr);
2701     } else {
2702       ierr = VecAXPY(v3,1.0,z);CHKERRQ(ierr);
2703     }
2704     ierr = VecDestroy(&z);CHKERRQ(ierr);
2705   }
2706   ierr = VecLockReadPop(v1);CHKERRQ(ierr);
2707   ierr = PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2708   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2709   PetscFunctionReturn(0);
2710 }
2711 
2712 /*@
2713    MatMultConstrained - The inner multiplication routine for a
2714    constrained matrix P^T A P.
2715 
2716    Neighbor-wise Collective on Mat and Vec
2717 
2718    Input Parameters:
2719 +  mat - the matrix
2720 -  x   - the vector to be multilplied
2721 
2722    Output Parameters:
2723 .  y - the result
2724 
2725    Notes:
2726    The vectors x and y cannot be the same.  I.e., one cannot
2727    call MatMult(A,y,y).
2728 
2729    Level: beginner
2730 
2731 .keywords: matrix, multiply, matrix-vector product, constraint
2732 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2733 @*/
2734 PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y)
2735 {
2736   PetscErrorCode ierr;
2737 
2738   PetscFunctionBegin;
2739   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2740   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2741   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2742   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2743   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2744   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2745   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);
2746   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);
2747   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);
2748 
2749   ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2750   ierr = VecLockReadPush(x);CHKERRQ(ierr);
2751   ierr = (*mat->ops->multconstrained)(mat,x,y);CHKERRQ(ierr);
2752   ierr = VecLockReadPop(x);CHKERRQ(ierr);
2753   ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2754   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2755   PetscFunctionReturn(0);
2756 }
2757 
2758 /*@
2759    MatMultTransposeConstrained - The inner multiplication routine for a
2760    constrained matrix P^T A^T P.
2761 
2762    Neighbor-wise Collective on Mat and Vec
2763 
2764    Input Parameters:
2765 +  mat - the matrix
2766 -  x   - the vector to be multilplied
2767 
2768    Output Parameters:
2769 .  y - the result
2770 
2771    Notes:
2772    The vectors x and y cannot be the same.  I.e., one cannot
2773    call MatMult(A,y,y).
2774 
2775    Level: beginner
2776 
2777 .keywords: matrix, multiply, matrix-vector product, constraint
2778 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2779 @*/
2780 PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2781 {
2782   PetscErrorCode ierr;
2783 
2784   PetscFunctionBegin;
2785   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2786   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2787   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2788   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2789   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2790   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2791   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);
2792   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);
2793 
2794   ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2795   ierr = (*mat->ops->multtransposeconstrained)(mat,x,y);CHKERRQ(ierr);
2796   ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2797   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2798   PetscFunctionReturn(0);
2799 }
2800 
2801 /*@C
2802    MatGetFactorType - gets the type of factorization it is
2803 
2804    Not Collective
2805 
2806    Input Parameters:
2807 .  mat - the matrix
2808 
2809    Output Parameters:
2810 .  t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT
2811 
2812    Level: intermediate
2813 
2814 .seealso: MatFactorType, MatGetFactor(), MatSetFactorType()
2815 @*/
2816 PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t)
2817 {
2818   PetscFunctionBegin;
2819   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2820   PetscValidType(mat,1);
2821   PetscValidPointer(t,2);
2822   *t = mat->factortype;
2823   PetscFunctionReturn(0);
2824 }
2825 
2826 /*@C
2827    MatSetFactorType - sets the type of factorization it is
2828 
2829    Logically Collective on Mat
2830 
2831    Input Parameters:
2832 +  mat - the matrix
2833 -  t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT
2834 
2835    Level: intermediate
2836 
2837 .seealso: MatFactorType, MatGetFactor(), MatGetFactorType()
2838 @*/
2839 PetscErrorCode MatSetFactorType(Mat mat, MatFactorType t)
2840 {
2841   PetscFunctionBegin;
2842   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2843   PetscValidType(mat,1);
2844   mat->factortype = t;
2845   PetscFunctionReturn(0);
2846 }
2847 
2848 /* ------------------------------------------------------------*/
2849 /*@C
2850    MatGetInfo - Returns information about matrix storage (number of
2851    nonzeros, memory, etc.).
2852 
2853    Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag
2854 
2855    Input Parameters:
2856 .  mat - the matrix
2857 
2858    Output Parameters:
2859 +  flag - flag indicating the type of parameters to be returned
2860    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2861    MAT_GLOBAL_SUM - sum over all processors)
2862 -  info - matrix information context
2863 
2864    Notes:
2865    The MatInfo context contains a variety of matrix data, including
2866    number of nonzeros allocated and used, number of mallocs during
2867    matrix assembly, etc.  Additional information for factored matrices
2868    is provided (such as the fill ratio, number of mallocs during
2869    factorization, etc.).  Much of this info is printed to PETSC_STDOUT
2870    when using the runtime options
2871 $       -info -mat_view ::ascii_info
2872 
2873    Example for C/C++ Users:
2874    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2875    data within the MatInfo context.  For example,
2876 .vb
2877       MatInfo info;
2878       Mat     A;
2879       double  mal, nz_a, nz_u;
2880 
2881       MatGetInfo(A,MAT_LOCAL,&info);
2882       mal  = info.mallocs;
2883       nz_a = info.nz_allocated;
2884 .ve
2885 
2886    Example for Fortran Users:
2887    Fortran users should declare info as a double precision
2888    array of dimension MAT_INFO_SIZE, and then extract the parameters
2889    of interest.  See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h
2890    a complete list of parameter names.
2891 .vb
2892       double  precision info(MAT_INFO_SIZE)
2893       double  precision mal, nz_a
2894       Mat     A
2895       integer ierr
2896 
2897       call MatGetInfo(A,MAT_LOCAL,info,ierr)
2898       mal = info(MAT_INFO_MALLOCS)
2899       nz_a = info(MAT_INFO_NZ_ALLOCATED)
2900 .ve
2901 
2902     Level: intermediate
2903 
2904     Concepts: matrices^getting information on
2905 
2906     Developer Note: fortran interface is not autogenerated as the f90
2907     interface defintion cannot be generated correctly [due to MatInfo]
2908 
2909 .seealso: MatStashGetInfo()
2910 
2911 @*/
2912 PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2913 {
2914   PetscErrorCode ierr;
2915 
2916   PetscFunctionBegin;
2917   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2918   PetscValidType(mat,1);
2919   PetscValidPointer(info,3);
2920   if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2921   MatCheckPreallocated(mat,1);
2922   ierr = (*mat->ops->getinfo)(mat,flag,info);CHKERRQ(ierr);
2923   PetscFunctionReturn(0);
2924 }
2925 
2926 /*
2927    This is used by external packages where it is not easy to get the info from the actual
2928    matrix factorization.
2929 */
2930 PetscErrorCode MatGetInfo_External(Mat A,MatInfoType flag,MatInfo *info)
2931 {
2932   PetscErrorCode ierr;
2933 
2934   PetscFunctionBegin;
2935   ierr = PetscMemzero(info,sizeof(MatInfo));CHKERRQ(ierr);
2936   PetscFunctionReturn(0);
2937 }
2938 
2939 /* ----------------------------------------------------------*/
2940 
2941 /*@C
2942    MatLUFactor - Performs in-place LU factorization of matrix.
2943 
2944    Collective on Mat
2945 
2946    Input Parameters:
2947 +  mat - the matrix
2948 .  row - row permutation
2949 .  col - column permutation
2950 -  info - options for factorization, includes
2951 $          fill - expected fill as ratio of original fill.
2952 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2953 $                   Run with the option -info to determine an optimal value to use
2954 
2955    Notes:
2956    Most users should employ the simplified KSP interface for linear solvers
2957    instead of working directly with matrix algebra routines such as this.
2958    See, e.g., KSPCreate().
2959 
2960    This changes the state of the matrix to a factored matrix; it cannot be used
2961    for example with MatSetValues() unless one first calls MatSetUnfactored().
2962 
2963    Level: developer
2964 
2965    Concepts: matrices^LU factorization
2966 
2967 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2968           MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor()
2969 
2970     Developer Note: fortran interface is not autogenerated as the f90
2971     interface defintion cannot be generated correctly [due to MatFactorInfo]
2972 
2973 @*/
2974 PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2975 {
2976   PetscErrorCode ierr;
2977   MatFactorInfo  tinfo;
2978 
2979   PetscFunctionBegin;
2980   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2981   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
2982   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
2983   if (info) PetscValidPointer(info,4);
2984   PetscValidType(mat,1);
2985   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2986   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2987   if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2988   MatCheckPreallocated(mat,1);
2989   if (!info) {
2990     ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr);
2991     info = &tinfo;
2992   }
2993 
2994   ierr = PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
2995   ierr = (*mat->ops->lufactor)(mat,row,col,info);CHKERRQ(ierr);
2996   ierr = PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
2997   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
2998   PetscFunctionReturn(0);
2999 }
3000 
3001 /*@C
3002    MatILUFactor - Performs in-place ILU factorization of matrix.
3003 
3004    Collective on Mat
3005 
3006    Input Parameters:
3007 +  mat - the matrix
3008 .  row - row permutation
3009 .  col - column permutation
3010 -  info - structure containing
3011 $      levels - number of levels of fill.
3012 $      expected fill - as ratio of original fill.
3013 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
3014                 missing diagonal entries)
3015 
3016    Notes:
3017    Probably really in-place only when level of fill is zero, otherwise allocates
3018    new space to store factored matrix and deletes previous memory.
3019 
3020    Most users should employ the simplified KSP interface for linear solvers
3021    instead of working directly with matrix algebra routines such as this.
3022    See, e.g., KSPCreate().
3023 
3024    Level: developer
3025 
3026    Concepts: matrices^ILU factorization
3027 
3028 .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
3029 
3030     Developer Note: fortran interface is not autogenerated as the f90
3031     interface defintion cannot be generated correctly [due to MatFactorInfo]
3032 
3033 @*/
3034 PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
3035 {
3036   PetscErrorCode ierr;
3037 
3038   PetscFunctionBegin;
3039   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3040   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
3041   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
3042   PetscValidPointer(info,4);
3043   PetscValidType(mat,1);
3044   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
3045   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3046   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3047   if (!mat->ops->ilufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3048   MatCheckPreallocated(mat,1);
3049 
3050   ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
3051   ierr = (*mat->ops->ilufactor)(mat,row,col,info);CHKERRQ(ierr);
3052   ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
3053   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
3054   PetscFunctionReturn(0);
3055 }
3056 
3057 /*@C
3058    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
3059    Call this routine before calling MatLUFactorNumeric().
3060 
3061    Collective on Mat
3062 
3063    Input Parameters:
3064 +  fact - the factor matrix obtained with MatGetFactor()
3065 .  mat - the matrix
3066 .  row, col - row and column permutations
3067 -  info - options for factorization, includes
3068 $          fill - expected fill as ratio of original fill.
3069 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3070 $                   Run with the option -info to determine an optimal value to use
3071 
3072 
3073    Notes:
3074     See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
3075 
3076    Most users should employ the simplified KSP interface for linear solvers
3077    instead of working directly with matrix algebra routines such as this.
3078    See, e.g., KSPCreate().
3079 
3080    Level: developer
3081 
3082    Concepts: matrices^LU symbolic factorization
3083 
3084 .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo, MatFactorInfoInitialize()
3085 
3086     Developer Note: fortran interface is not autogenerated as the f90
3087     interface defintion cannot be generated correctly [due to MatFactorInfo]
3088 
3089 @*/
3090 PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
3091 {
3092   PetscErrorCode ierr;
3093 
3094   PetscFunctionBegin;
3095   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3096   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
3097   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
3098   if (info) PetscValidPointer(info,4);
3099   PetscValidType(mat,1);
3100   PetscValidPointer(fact,5);
3101   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3102   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3103   if (!(fact)->ops->lufactorsymbolic) {
3104     MatSolverType spackage;
3105     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
3106     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage);
3107   }
3108   MatCheckPreallocated(mat,2);
3109 
3110   ierr = PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
3111   ierr = (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
3112   ierr = PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
3113   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3114   PetscFunctionReturn(0);
3115 }
3116 
3117 /*@C
3118    MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
3119    Call this routine after first calling MatLUFactorSymbolic().
3120 
3121    Collective on Mat
3122 
3123    Input Parameters:
3124 +  fact - the factor matrix obtained with MatGetFactor()
3125 .  mat - the matrix
3126 -  info - options for factorization
3127 
3128    Notes:
3129    See MatLUFactor() for in-place factorization.  See
3130    MatCholeskyFactorNumeric() for the symmetric, positive definite case.
3131 
3132    Most users should employ the simplified KSP interface for linear solvers
3133    instead of working directly with matrix algebra routines such as this.
3134    See, e.g., KSPCreate().
3135 
3136    Level: developer
3137 
3138    Concepts: matrices^LU numeric factorization
3139 
3140 .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()
3141 
3142     Developer Note: fortran interface is not autogenerated as the f90
3143     interface defintion cannot be generated correctly [due to MatFactorInfo]
3144 
3145 @*/
3146 PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3147 {
3148   PetscErrorCode ierr;
3149 
3150   PetscFunctionBegin;
3151   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3152   PetscValidType(mat,1);
3153   PetscValidPointer(fact,2);
3154   PetscValidHeaderSpecific(fact,MAT_CLASSID,2);
3155   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3156   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);
3157 
3158   if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name);
3159   MatCheckPreallocated(mat,2);
3160   ierr = PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3161   ierr = (fact->ops->lufactornumeric)(fact,mat,info);CHKERRQ(ierr);
3162   ierr = PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3163   ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr);
3164   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3165   PetscFunctionReturn(0);
3166 }
3167 
3168 /*@C
3169    MatCholeskyFactor - Performs in-place Cholesky factorization of a
3170    symmetric matrix.
3171 
3172    Collective on Mat
3173 
3174    Input Parameters:
3175 +  mat - the matrix
3176 .  perm - row and column permutations
3177 -  f - expected fill as ratio of original fill
3178 
3179    Notes:
3180    See MatLUFactor() for the nonsymmetric case.  See also
3181    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().
3182 
3183    Most users should employ the simplified KSP interface for linear solvers
3184    instead of working directly with matrix algebra routines such as this.
3185    See, e.g., KSPCreate().
3186 
3187    Level: developer
3188 
3189    Concepts: matrices^Cholesky factorization
3190 
3191 .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
3192           MatGetOrdering()
3193 
3194     Developer Note: fortran interface is not autogenerated as the f90
3195     interface defintion cannot be generated correctly [due to MatFactorInfo]
3196 
3197 @*/
3198 PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
3199 {
3200   PetscErrorCode ierr;
3201 
3202   PetscFunctionBegin;
3203   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3204   PetscValidType(mat,1);
3205   if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2);
3206   if (info) PetscValidPointer(info,3);
3207   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3208   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3209   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3210   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);
3211   MatCheckPreallocated(mat,1);
3212 
3213   ierr = PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
3214   ierr = (*mat->ops->choleskyfactor)(mat,perm,info);CHKERRQ(ierr);
3215   ierr = PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
3216   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
3217   PetscFunctionReturn(0);
3218 }
3219 
3220 /*@C
3221    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
3222    of a symmetric matrix.
3223 
3224    Collective on Mat
3225 
3226    Input Parameters:
3227 +  fact - the factor matrix obtained with MatGetFactor()
3228 .  mat - the matrix
3229 .  perm - row and column permutations
3230 -  info - options for factorization, includes
3231 $          fill - expected fill as ratio of original fill.
3232 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3233 $                   Run with the option -info to determine an optimal value to use
3234 
3235    Notes:
3236    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
3237    MatCholeskyFactor() and MatCholeskyFactorNumeric().
3238 
3239    Most users should employ the simplified KSP interface for linear solvers
3240    instead of working directly with matrix algebra routines such as this.
3241    See, e.g., KSPCreate().
3242 
3243    Level: developer
3244 
3245    Concepts: matrices^Cholesky symbolic factorization
3246 
3247 .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
3248           MatGetOrdering()
3249 
3250     Developer Note: fortran interface is not autogenerated as the f90
3251     interface defintion cannot be generated correctly [due to MatFactorInfo]
3252 
3253 @*/
3254 PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
3255 {
3256   PetscErrorCode ierr;
3257 
3258   PetscFunctionBegin;
3259   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3260   PetscValidType(mat,1);
3261   if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2);
3262   if (info) PetscValidPointer(info,3);
3263   PetscValidPointer(fact,4);
3264   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3265   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3266   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3267   if (!(fact)->ops->choleskyfactorsymbolic) {
3268     MatSolverType spackage;
3269     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
3270     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage);
3271   }
3272   MatCheckPreallocated(mat,2);
3273 
3274   ierr = PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
3275   ierr = (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
3276   ierr = PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
3277   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3278   PetscFunctionReturn(0);
3279 }
3280 
3281 /*@C
3282    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
3283    of a symmetric matrix. Call this routine after first calling
3284    MatCholeskyFactorSymbolic().
3285 
3286    Collective on Mat
3287 
3288    Input Parameters:
3289 +  fact - the factor matrix obtained with MatGetFactor()
3290 .  mat - the initial matrix
3291 .  info - options for factorization
3292 -  fact - the symbolic factor of mat
3293 
3294 
3295    Notes:
3296    Most users should employ the simplified KSP interface for linear solvers
3297    instead of working directly with matrix algebra routines such as this.
3298    See, e.g., KSPCreate().
3299 
3300    Level: developer
3301 
3302    Concepts: matrices^Cholesky numeric factorization
3303 
3304 .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
3305 
3306     Developer Note: fortran interface is not autogenerated as the f90
3307     interface defintion cannot be generated correctly [due to MatFactorInfo]
3308 
3309 @*/
3310 PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3311 {
3312   PetscErrorCode ierr;
3313 
3314   PetscFunctionBegin;
3315   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3316   PetscValidType(mat,1);
3317   PetscValidPointer(fact,2);
3318   PetscValidHeaderSpecific(fact,MAT_CLASSID,2);
3319   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3320   if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name);
3321   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);
3322   MatCheckPreallocated(mat,2);
3323 
3324   ierr = PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3325   ierr = (fact->ops->choleskyfactornumeric)(fact,mat,info);CHKERRQ(ierr);
3326   ierr = PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3327   ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr);
3328   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3329   PetscFunctionReturn(0);
3330 }
3331 
3332 /* ----------------------------------------------------------------*/
3333 /*@
3334    MatSolve - Solves A x = b, given a factored matrix.
3335 
3336    Neighbor-wise Collective on Mat and Vec
3337 
3338    Input Parameters:
3339 +  mat - the factored matrix
3340 -  b - the right-hand-side vector
3341 
3342    Output Parameter:
3343 .  x - the result vector
3344 
3345    Notes:
3346    The vectors b and x cannot be the same.  I.e., one cannot
3347    call MatSolve(A,x,x).
3348 
3349    Notes:
3350    Most users should employ the simplified KSP interface for linear solvers
3351    instead of working directly with matrix algebra routines such as this.
3352    See, e.g., KSPCreate().
3353 
3354    Level: developer
3355 
3356    Concepts: matrices^triangular solves
3357 
3358 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
3359 @*/
3360 PetscErrorCode MatSolve(Mat mat,Vec b,Vec x)
3361 {
3362   PetscErrorCode ierr;
3363 
3364   PetscFunctionBegin;
3365   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3366   PetscValidType(mat,1);
3367   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3368   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3369   PetscCheckSameComm(mat,1,b,2);
3370   PetscCheckSameComm(mat,1,x,3);
3371   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3372   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);
3373   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);
3374   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);
3375   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3376   if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3377   MatCheckPreallocated(mat,1);
3378 
3379   ierr = PetscLogEventBegin(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
3380   if (mat->factorerrortype) {
3381     ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3382     ierr = VecSetInf(x);CHKERRQ(ierr);
3383   } else {
3384     if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3385     ierr = (*mat->ops->solve)(mat,b,x);CHKERRQ(ierr);
3386   }
3387   ierr = PetscLogEventEnd(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
3388   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3389   PetscFunctionReturn(0);
3390 }
3391 
3392 static PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X, PetscBool trans)
3393 {
3394   PetscErrorCode ierr;
3395   Vec            b,x;
3396   PetscInt       m,N,i;
3397   PetscScalar    *bb,*xx;
3398   PetscBool      flg;
3399 
3400   PetscFunctionBegin;
3401   ierr = PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr);
3402   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
3403   ierr = PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr);
3404   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");
3405 
3406   ierr = MatDenseGetArray(B,&bb);CHKERRQ(ierr);
3407   ierr = MatDenseGetArray(X,&xx);CHKERRQ(ierr);
3408   ierr = MatGetLocalSize(B,&m,NULL);CHKERRQ(ierr);  /* number local rows */
3409   ierr = MatGetSize(B,NULL,&N);CHKERRQ(ierr);       /* total columns in dense matrix */
3410   ierr = MatCreateVecs(A,&x,&b);CHKERRQ(ierr);
3411   for (i=0; i<N; i++) {
3412     ierr = VecPlaceArray(b,bb + i*m);CHKERRQ(ierr);
3413     ierr = VecPlaceArray(x,xx + i*m);CHKERRQ(ierr);
3414     if (trans) {
3415       ierr = MatSolveTranspose(A,b,x);CHKERRQ(ierr);
3416     } else {
3417       ierr = MatSolve(A,b,x);CHKERRQ(ierr);
3418     }
3419     ierr = VecResetArray(x);CHKERRQ(ierr);
3420     ierr = VecResetArray(b);CHKERRQ(ierr);
3421   }
3422   ierr = VecDestroy(&b);CHKERRQ(ierr);
3423   ierr = VecDestroy(&x);CHKERRQ(ierr);
3424   ierr = MatDenseRestoreArray(B,&bb);CHKERRQ(ierr);
3425   ierr = MatDenseRestoreArray(X,&xx);CHKERRQ(ierr);
3426   PetscFunctionReturn(0);
3427 }
3428 
3429 /*@
3430    MatMatSolve - Solves A X = B, given a factored matrix.
3431 
3432    Neighbor-wise Collective on Mat
3433 
3434    Input Parameters:
3435 +  A - the factored matrix
3436 -  B - the right-hand-side matrix  (dense matrix)
3437 
3438    Output Parameter:
3439 .  X - the result matrix (dense matrix)
3440 
3441    Notes:
3442    The matrices b and x cannot be the same.  I.e., one cannot
3443    call MatMatSolve(A,x,x).
3444 
3445    Notes:
3446    Most users should usually employ the simplified KSP interface for linear solvers
3447    instead of working directly with matrix algebra routines such as this.
3448    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3449    at a time.
3450 
3451    When using SuperLU_Dist as a parallel solver PETSc will use the SuperLU_Dist functionality to solve multiple right hand sides simultaneously. For MUMPS
3452    it calls a separate solve for each right hand side since MUMPS does not yet support distributed right hand sides.
3453 
3454    Since the resulting matrix X must always be dense we do not support sparse representation of the matrix B.
3455 
3456    Level: developer
3457 
3458    Concepts: matrices^triangular solves
3459 
3460 .seealso: MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor()
3461 @*/
3462 PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X)
3463 {
3464   PetscErrorCode ierr;
3465 
3466   PetscFunctionBegin;
3467   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3468   PetscValidType(A,1);
3469   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3470   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3471   PetscCheckSameComm(A,1,B,2);
3472   PetscCheckSameComm(A,1,X,3);
3473   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3474   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);
3475   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);
3476   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");
3477   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3478   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3479   MatCheckPreallocated(A,1);
3480 
3481   ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3482   if (!A->ops->matsolve) {
3483     ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name);CHKERRQ(ierr);
3484     ierr = MatMatSolve_Basic(A,B,X,PETSC_FALSE);CHKERRQ(ierr);
3485   } else {
3486     ierr = (*A->ops->matsolve)(A,B,X);CHKERRQ(ierr);
3487   }
3488   ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3489   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3490   PetscFunctionReturn(0);
3491 }
3492 
3493 /*@
3494    MatMatSolveTranspose - Solves A^T X = B, given a factored matrix.
3495 
3496    Neighbor-wise Collective on Mat
3497 
3498    Input Parameters:
3499 +  A - the factored matrix
3500 -  B - the right-hand-side matrix  (dense matrix)
3501 
3502    Output Parameter:
3503 .  X - the result matrix (dense matrix)
3504 
3505    Notes:
3506    The matrices B and X cannot be the same.  I.e., one cannot
3507    call MatMatSolveTranspose(A,X,X).
3508 
3509    Notes:
3510    Most users should usually employ the simplified KSP interface for linear solvers
3511    instead of working directly with matrix algebra routines such as this.
3512    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3513    at a time.
3514 
3515    When using SuperLU_Dist or MUMPS as a parallel solver, PETSc will use their functionality to solve multiple right hand sides simultaneously.
3516 
3517    Level: developer
3518 
3519    Concepts: matrices^triangular solves
3520 
3521 .seealso: MatMatSolve(), MatLUFactor(), MatCholeskyFactor()
3522 @*/
3523 PetscErrorCode MatMatSolveTranspose(Mat A,Mat B,Mat X)
3524 {
3525   PetscErrorCode ierr;
3526 
3527   PetscFunctionBegin;
3528   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3529   PetscValidType(A,1);
3530   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3531   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3532   PetscCheckSameComm(A,1,B,2);
3533   PetscCheckSameComm(A,1,X,3);
3534   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3535   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);
3536   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);
3537   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);
3538   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");
3539   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3540   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3541   MatCheckPreallocated(A,1);
3542 
3543   ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3544   if (!A->ops->matsolvetranspose) {
3545     ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolveTranspose\n",((PetscObject)A)->type_name);CHKERRQ(ierr);
3546     ierr = MatMatSolve_Basic(A,B,X,PETSC_TRUE);CHKERRQ(ierr);
3547   } else {
3548     ierr = (*A->ops->matsolvetranspose)(A,B,X);CHKERRQ(ierr);
3549   }
3550   ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3551   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3552   PetscFunctionReturn(0);
3553 }
3554 
3555 /*@
3556    MatMatTransposeSolve - Solves A X = B^T, given a factored matrix.
3557 
3558    Neighbor-wise Collective on Mat
3559 
3560    Input Parameters:
3561 +  A - the factored matrix
3562 -  Bt - the transpose of right-hand-side matrix
3563 
3564    Output Parameter:
3565 .  X - the result matrix (dense matrix)
3566 
3567    Notes:
3568    Most users should usually employ the simplified KSP interface for linear solvers
3569    instead of working directly with matrix algebra routines such as this.
3570    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3571    at a time.
3572 
3573    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().
3574 
3575    Level: developer
3576 
3577    Concepts: matrices^triangular solves
3578 
3579 .seealso: MatMatSolve(), MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor()
3580 @*/
3581 PetscErrorCode MatMatTransposeSolve(Mat A,Mat Bt,Mat X)
3582 {
3583   PetscErrorCode ierr;
3584 
3585   PetscFunctionBegin;
3586   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3587   PetscValidType(A,1);
3588   PetscValidHeaderSpecific(Bt,MAT_CLASSID,2);
3589   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3590   PetscCheckSameComm(A,1,Bt,2);
3591   PetscCheckSameComm(A,1,X,3);
3592 
3593   if (X == Bt) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3594   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);
3595   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);
3596   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");
3597   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3598   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3599   MatCheckPreallocated(A,1);
3600 
3601   if (!A->ops->mattransposesolve) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
3602   ierr = PetscLogEventBegin(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr);
3603   ierr = (*A->ops->mattransposesolve)(A,Bt,X);CHKERRQ(ierr);
3604   ierr = PetscLogEventEnd(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr);
3605   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3606   PetscFunctionReturn(0);
3607 }
3608 
3609 /*@
3610    MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or
3611                             U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U,
3612 
3613    Neighbor-wise Collective on Mat and Vec
3614 
3615    Input Parameters:
3616 +  mat - the factored matrix
3617 -  b - the right-hand-side vector
3618 
3619    Output Parameter:
3620 .  x - the result vector
3621 
3622    Notes:
3623    MatSolve() should be used for most applications, as it performs
3624    a forward solve followed by a backward solve.
3625 
3626    The vectors b and x cannot be the same,  i.e., one cannot
3627    call MatForwardSolve(A,x,x).
3628 
3629    For matrix in seqsbaij format with block size larger than 1,
3630    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3631    MatForwardSolve() solves U^T*D y = b, and
3632    MatBackwardSolve() solves U x = y.
3633    Thus they do not provide a symmetric preconditioner.
3634 
3635    Most users should employ the simplified KSP interface for linear solvers
3636    instead of working directly with matrix algebra routines such as this.
3637    See, e.g., KSPCreate().
3638 
3639    Level: developer
3640 
3641    Concepts: matrices^forward solves
3642 
3643 .seealso: MatSolve(), MatBackwardSolve()
3644 @*/
3645 PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x)
3646 {
3647   PetscErrorCode ierr;
3648 
3649   PetscFunctionBegin;
3650   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3651   PetscValidType(mat,1);
3652   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3653   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3654   PetscCheckSameComm(mat,1,b,2);
3655   PetscCheckSameComm(mat,1,x,3);
3656   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3657   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);
3658   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);
3659   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);
3660   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3661   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3662   MatCheckPreallocated(mat,1);
3663 
3664   if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3665   ierr = PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
3666   ierr = (*mat->ops->forwardsolve)(mat,b,x);CHKERRQ(ierr);
3667   ierr = PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
3668   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3669   PetscFunctionReturn(0);
3670 }
3671 
3672 /*@
3673    MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
3674                              D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U,
3675 
3676    Neighbor-wise Collective on Mat and Vec
3677 
3678    Input Parameters:
3679 +  mat - the factored matrix
3680 -  b - the right-hand-side vector
3681 
3682    Output Parameter:
3683 .  x - the result vector
3684 
3685    Notes:
3686    MatSolve() should be used for most applications, as it performs
3687    a forward solve followed by a backward solve.
3688 
3689    The vectors b and x cannot be the same.  I.e., one cannot
3690    call MatBackwardSolve(A,x,x).
3691 
3692    For matrix in seqsbaij format with block size larger than 1,
3693    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3694    MatForwardSolve() solves U^T*D y = b, and
3695    MatBackwardSolve() solves U x = y.
3696    Thus they do not provide a symmetric preconditioner.
3697 
3698    Most users should employ the simplified KSP interface for linear solvers
3699    instead of working directly with matrix algebra routines such as this.
3700    See, e.g., KSPCreate().
3701 
3702    Level: developer
3703 
3704    Concepts: matrices^backward solves
3705 
3706 .seealso: MatSolve(), MatForwardSolve()
3707 @*/
3708 PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x)
3709 {
3710   PetscErrorCode ierr;
3711 
3712   PetscFunctionBegin;
3713   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3714   PetscValidType(mat,1);
3715   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3716   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3717   PetscCheckSameComm(mat,1,b,2);
3718   PetscCheckSameComm(mat,1,x,3);
3719   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3720   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);
3721   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);
3722   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);
3723   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3724   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3725   MatCheckPreallocated(mat,1);
3726 
3727   if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3728   ierr = PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
3729   ierr = (*mat->ops->backwardsolve)(mat,b,x);CHKERRQ(ierr);
3730   ierr = PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
3731   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3732   PetscFunctionReturn(0);
3733 }
3734 
3735 /*@
3736    MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
3737 
3738    Neighbor-wise Collective on Mat and Vec
3739 
3740    Input Parameters:
3741 +  mat - the factored matrix
3742 .  b - the right-hand-side vector
3743 -  y - the vector to be added to
3744 
3745    Output Parameter:
3746 .  x - the result vector
3747 
3748    Notes:
3749    The vectors b and x cannot be the same.  I.e., one cannot
3750    call MatSolveAdd(A,x,y,x).
3751 
3752    Most users should employ the simplified KSP interface for linear solvers
3753    instead of working directly with matrix algebra routines such as this.
3754    See, e.g., KSPCreate().
3755 
3756    Level: developer
3757 
3758    Concepts: matrices^triangular solves
3759 
3760 .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3761 @*/
3762 PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3763 {
3764   PetscScalar    one = 1.0;
3765   Vec            tmp;
3766   PetscErrorCode ierr;
3767 
3768   PetscFunctionBegin;
3769   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3770   PetscValidType(mat,1);
3771   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3772   PetscValidHeaderSpecific(b,VEC_CLASSID,3);
3773   PetscValidHeaderSpecific(x,VEC_CLASSID,4);
3774   PetscCheckSameComm(mat,1,b,2);
3775   PetscCheckSameComm(mat,1,y,2);
3776   PetscCheckSameComm(mat,1,x,3);
3777   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3778   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);
3779   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);
3780   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);
3781   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);
3782   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);
3783   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3784   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3785   MatCheckPreallocated(mat,1);
3786 
3787   ierr = PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
3788   if (mat->ops->solveadd) {
3789     ierr = (*mat->ops->solveadd)(mat,b,y,x);CHKERRQ(ierr);
3790   } else {
3791     /* do the solve then the add manually */
3792     if (x != y) {
3793       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
3794       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
3795     } else {
3796       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
3797       ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr);
3798       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
3799       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
3800       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
3801       ierr = VecDestroy(&tmp);CHKERRQ(ierr);
3802     }
3803   }
3804   ierr = PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
3805   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3806   PetscFunctionReturn(0);
3807 }
3808 
3809 /*@
3810    MatSolveTranspose - Solves A' x = b, given a factored matrix.
3811 
3812    Neighbor-wise Collective on Mat and Vec
3813 
3814    Input Parameters:
3815 +  mat - the factored matrix
3816 -  b - the right-hand-side vector
3817 
3818    Output Parameter:
3819 .  x - the result vector
3820 
3821    Notes:
3822    The vectors b and x cannot be the same.  I.e., one cannot
3823    call MatSolveTranspose(A,x,x).
3824 
3825    Most users should employ the simplified KSP interface for linear solvers
3826    instead of working directly with matrix algebra routines such as this.
3827    See, e.g., KSPCreate().
3828 
3829    Level: developer
3830 
3831    Concepts: matrices^triangular solves
3832 
3833 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
3834 @*/
3835 PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x)
3836 {
3837   PetscErrorCode ierr;
3838 
3839   PetscFunctionBegin;
3840   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3841   PetscValidType(mat,1);
3842   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3843   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3844   PetscCheckSameComm(mat,1,b,2);
3845   PetscCheckSameComm(mat,1,x,3);
3846   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3847   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);
3848   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);
3849   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3850   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3851   MatCheckPreallocated(mat,1);
3852   ierr = PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
3853   if (mat->factorerrortype) {
3854     ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3855     ierr = VecSetInf(x);CHKERRQ(ierr);
3856   } else {
3857     if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3858     ierr = (*mat->ops->solvetranspose)(mat,b,x);CHKERRQ(ierr);
3859   }
3860   ierr = PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
3861   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3862   PetscFunctionReturn(0);
3863 }
3864 
3865 /*@
3866    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
3867                       factored matrix.
3868 
3869    Neighbor-wise Collective on Mat and Vec
3870 
3871    Input Parameters:
3872 +  mat - the factored matrix
3873 .  b - the right-hand-side vector
3874 -  y - the vector to be added to
3875 
3876    Output Parameter:
3877 .  x - the result vector
3878 
3879    Notes:
3880    The vectors b and x cannot be the same.  I.e., one cannot
3881    call MatSolveTransposeAdd(A,x,y,x).
3882 
3883    Most users should employ the simplified KSP interface for linear solvers
3884    instead of working directly with matrix algebra routines such as this.
3885    See, e.g., KSPCreate().
3886 
3887    Level: developer
3888 
3889    Concepts: matrices^triangular solves
3890 
3891 .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3892 @*/
3893 PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3894 {
3895   PetscScalar    one = 1.0;
3896   PetscErrorCode ierr;
3897   Vec            tmp;
3898 
3899   PetscFunctionBegin;
3900   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3901   PetscValidType(mat,1);
3902   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3903   PetscValidHeaderSpecific(b,VEC_CLASSID,3);
3904   PetscValidHeaderSpecific(x,VEC_CLASSID,4);
3905   PetscCheckSameComm(mat,1,b,2);
3906   PetscCheckSameComm(mat,1,y,3);
3907   PetscCheckSameComm(mat,1,x,4);
3908   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3909   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);
3910   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);
3911   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);
3912   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);
3913   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3914   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3915   MatCheckPreallocated(mat,1);
3916 
3917   ierr = PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
3918   if (mat->ops->solvetransposeadd) {
3919     if (mat->factorerrortype) {
3920       ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3921       ierr = VecSetInf(x);CHKERRQ(ierr);
3922     } else {
3923       ierr = (*mat->ops->solvetransposeadd)(mat,b,y,x);CHKERRQ(ierr);
3924     }
3925   } else {
3926     /* do the solve then the add manually */
3927     if (x != y) {
3928       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
3929       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
3930     } else {
3931       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
3932       ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr);
3933       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
3934       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
3935       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
3936       ierr = VecDestroy(&tmp);CHKERRQ(ierr);
3937     }
3938   }
3939   ierr = PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
3940   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3941   PetscFunctionReturn(0);
3942 }
3943 /* ----------------------------------------------------------------*/
3944 
3945 /*@
3946    MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps.
3947 
3948    Neighbor-wise Collective on Mat and Vec
3949 
3950    Input Parameters:
3951 +  mat - the matrix
3952 .  b - the right hand side
3953 .  omega - the relaxation factor
3954 .  flag - flag indicating the type of SOR (see below)
3955 .  shift -  diagonal shift
3956 .  its - the number of iterations
3957 -  lits - the number of local iterations
3958 
3959    Output Parameters:
3960 .  x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess)
3961 
3962    SOR Flags:
3963 .     SOR_FORWARD_SWEEP - forward SOR
3964 .     SOR_BACKWARD_SWEEP - backward SOR
3965 .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3966 .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR
3967 .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
3968 .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3969 .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
3970          upper/lower triangular part of matrix to
3971          vector (with omega)
3972 .     SOR_ZERO_INITIAL_GUESS - zero initial guess
3973 
3974    Notes:
3975    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3976    SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3977    on each processor.
3978 
3979    Application programmers will not generally use MatSOR() directly,
3980    but instead will employ the KSP/PC interface.
3981 
3982    Notes:
3983     for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing
3984 
3985    Notes for Advanced Users:
3986    The flags are implemented as bitwise inclusive or operations.
3987    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3988    to specify a zero initial guess for SSOR.
3989 
3990    Most users should employ the simplified KSP interface for linear solvers
3991    instead of working directly with matrix algebra routines such as this.
3992    See, e.g., KSPCreate().
3993 
3994    Vectors x and b CANNOT be the same
3995 
3996    Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes
3997 
3998    Level: developer
3999 
4000    Concepts: matrices^relaxation
4001    Concepts: matrices^SOR
4002    Concepts: matrices^Gauss-Seidel
4003 
4004 @*/
4005 PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
4006 {
4007   PetscErrorCode ierr;
4008 
4009   PetscFunctionBegin;
4010   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4011   PetscValidType(mat,1);
4012   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
4013   PetscValidHeaderSpecific(x,VEC_CLASSID,8);
4014   PetscCheckSameComm(mat,1,b,2);
4015   PetscCheckSameComm(mat,1,x,8);
4016   if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4017   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4018   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4019   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);
4020   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);
4021   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);
4022   if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
4023   if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
4024   if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");
4025 
4026   MatCheckPreallocated(mat,1);
4027   ierr = PetscLogEventBegin(MAT_SOR,mat,b,x,0);CHKERRQ(ierr);
4028   ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr);
4029   ierr = PetscLogEventEnd(MAT_SOR,mat,b,x,0);CHKERRQ(ierr);
4030   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
4031   PetscFunctionReturn(0);
4032 }
4033 
4034 /*
4035       Default matrix copy routine.
4036 */
4037 PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
4038 {
4039   PetscErrorCode    ierr;
4040   PetscInt          i,rstart = 0,rend = 0,nz;
4041   const PetscInt    *cwork;
4042   const PetscScalar *vwork;
4043 
4044   PetscFunctionBegin;
4045   if (B->assembled) {
4046     ierr = MatZeroEntries(B);CHKERRQ(ierr);
4047   }
4048   ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
4049   for (i=rstart; i<rend; i++) {
4050     ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
4051     ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);CHKERRQ(ierr);
4052     ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
4053   }
4054   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4055   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4056   PetscFunctionReturn(0);
4057 }
4058 
4059 /*@
4060    MatCopy - Copys a matrix to another matrix.
4061 
4062    Collective on Mat
4063 
4064    Input Parameters:
4065 +  A - the matrix
4066 -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
4067 
4068    Output Parameter:
4069 .  B - where the copy is put
4070 
4071    Notes:
4072    If you use SAME_NONZERO_PATTERN then the two matrices had better have the
4073    same nonzero pattern or the routine will crash.
4074 
4075    MatCopy() copies the matrix entries of a matrix to another existing
4076    matrix (after first zeroing the second matrix).  A related routine is
4077    MatConvert(), which first creates a new matrix and then copies the data.
4078 
4079    Level: intermediate
4080 
4081    Concepts: matrices^copying
4082 
4083 .seealso: MatConvert(), MatDuplicate()
4084 
4085 @*/
4086 PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str)
4087 {
4088   PetscErrorCode ierr;
4089   PetscInt       i;
4090 
4091   PetscFunctionBegin;
4092   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4093   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4094   PetscValidType(A,1);
4095   PetscValidType(B,2);
4096   PetscCheckSameComm(A,1,B,2);
4097   MatCheckPreallocated(B,2);
4098   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4099   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4100   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);
4101   MatCheckPreallocated(A,1);
4102   if (A == B) PetscFunctionReturn(0);
4103 
4104   ierr = PetscLogEventBegin(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
4105   if (A->ops->copy) {
4106     ierr = (*A->ops->copy)(A,B,str);CHKERRQ(ierr);
4107   } else { /* generic conversion */
4108     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
4109   }
4110 
4111   B->stencil.dim = A->stencil.dim;
4112   B->stencil.noc = A->stencil.noc;
4113   for (i=0; i<=A->stencil.dim; i++) {
4114     B->stencil.dims[i]   = A->stencil.dims[i];
4115     B->stencil.starts[i] = A->stencil.starts[i];
4116   }
4117 
4118   ierr = PetscLogEventEnd(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
4119   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
4120   PetscFunctionReturn(0);
4121 }
4122 
4123 /*@C
4124    MatConvert - Converts a matrix to another matrix, either of the same
4125    or different type.
4126 
4127    Collective on Mat
4128 
4129    Input Parameters:
4130 +  mat - the matrix
4131 .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
4132    same type as the original matrix.
4133 -  reuse - denotes if the destination matrix is to be created or reused.
4134    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
4135    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).
4136 
4137    Output Parameter:
4138 .  M - pointer to place new matrix
4139 
4140    Notes:
4141    MatConvert() first creates a new matrix and then copies the data from
4142    the first matrix.  A related routine is MatCopy(), which copies the matrix
4143    entries of one matrix to another already existing matrix context.
4144 
4145    Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
4146    the MPI communicator of the generated matrix is always the same as the communicator
4147    of the input matrix.
4148 
4149    Level: intermediate
4150 
4151    Concepts: matrices^converting between storage formats
4152 
4153 .seealso: MatCopy(), MatDuplicate()
4154 @*/
4155 PetscErrorCode MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M)
4156 {
4157   PetscErrorCode ierr;
4158   PetscBool      sametype,issame,flg;
4159   char           convname[256],mtype[256];
4160   Mat            B;
4161 
4162   PetscFunctionBegin;
4163   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4164   PetscValidType(mat,1);
4165   PetscValidPointer(M,3);
4166   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4167   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4168   MatCheckPreallocated(mat,1);
4169 
4170   ierr = PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);CHKERRQ(ierr);
4171   if (flg) {
4172     newtype = mtype;
4173   }
4174   ierr = PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);CHKERRQ(ierr);
4175   ierr = PetscStrcmp(newtype,"same",&issame);CHKERRQ(ierr);
4176   if ((reuse == MAT_INPLACE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix");
4177   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");
4178 
4179   if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) PetscFunctionReturn(0);
4180 
4181   if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
4182     ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
4183   } else {
4184     PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL;
4185     const char     *prefix[3] = {"seq","mpi",""};
4186     PetscInt       i;
4187     /*
4188        Order of precedence:
4189        0) See if newtype is a superclass of the current matrix.
4190        1) See if a specialized converter is known to the current matrix.
4191        2) See if a specialized converter is known to the desired matrix class.
4192        3) See if a good general converter is registered for the desired class
4193           (as of 6/27/03 only MATMPIADJ falls into this category).
4194        4) See if a good general converter is known for the current matrix.
4195        5) Use a really basic converter.
4196     */
4197 
4198     /* 0) See if newtype is a superclass of the current matrix.
4199           i.e mat is mpiaij and newtype is aij */
4200     for (i=0; i<2; i++) {
4201       ierr = PetscStrncpy(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4202       ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr);
4203       ierr = PetscStrcmp(convname,((PetscObject)mat)->type_name,&flg);CHKERRQ(ierr);
4204       if (flg) {
4205         if (reuse == MAT_INPLACE_MATRIX) {
4206           PetscFunctionReturn(0);
4207         } else if (reuse == MAT_INITIAL_MATRIX && mat->ops->duplicate) {
4208           ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
4209           PetscFunctionReturn(0);
4210         } else if (reuse == MAT_REUSE_MATRIX && mat->ops->copy) {
4211           ierr = MatCopy(mat,*M,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
4212           PetscFunctionReturn(0);
4213         }
4214       }
4215     }
4216     /* 1) See if a specialized converter is known to the current matrix and the desired class */
4217     for (i=0; i<3; i++) {
4218       ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr);
4219       ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr);
4220       ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr);
4221       ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4222       ierr = PetscStrlcat(convname,issame ? ((PetscObject)mat)->type_name : newtype,sizeof(convname));CHKERRQ(ierr);
4223       ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr);
4224       ierr = PetscObjectQueryFunction((PetscObject)mat,convname,&conv);CHKERRQ(ierr);
4225       if (conv) goto foundconv;
4226     }
4227 
4228     /* 2)  See if a specialized converter is known to the desired matrix class. */
4229     ierr = MatCreate(PetscObjectComm((PetscObject)mat),&B);CHKERRQ(ierr);
4230     ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);CHKERRQ(ierr);
4231     ierr = MatSetType(B,newtype);CHKERRQ(ierr);
4232     for (i=0; i<3; i++) {
4233       ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr);
4234       ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr);
4235       ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr);
4236       ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4237       ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr);
4238       ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr);
4239       ierr = PetscObjectQueryFunction((PetscObject)B,convname,&conv);CHKERRQ(ierr);
4240       if (conv) {
4241         ierr = MatDestroy(&B);CHKERRQ(ierr);
4242         goto foundconv;
4243       }
4244     }
4245 
4246     /* 3) See if a good general converter is registered for the desired class */
4247     conv = B->ops->convertfrom;
4248     ierr = MatDestroy(&B);CHKERRQ(ierr);
4249     if (conv) goto foundconv;
4250 
4251     /* 4) See if a good general converter is known for the current matrix */
4252     if (mat->ops->convert) {
4253       conv = mat->ops->convert;
4254     }
4255     if (conv) goto foundconv;
4256 
4257     /* 5) Use a really basic converter. */
4258     conv = MatConvert_Basic;
4259 
4260 foundconv:
4261     ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4262     ierr = (*conv)(mat,newtype,reuse,M);CHKERRQ(ierr);
4263     if (mat->rmap->mapping && mat->cmap->mapping && !(*M)->rmap->mapping && !(*M)->cmap->mapping) {
4264       /* the block sizes must be same if the mappings are copied over */
4265       (*M)->rmap->bs = mat->rmap->bs;
4266       (*M)->cmap->bs = mat->cmap->bs;
4267       ierr = PetscObjectReference((PetscObject)mat->rmap->mapping);CHKERRQ(ierr);
4268       ierr = PetscObjectReference((PetscObject)mat->cmap->mapping);CHKERRQ(ierr);
4269       (*M)->rmap->mapping = mat->rmap->mapping;
4270       (*M)->cmap->mapping = mat->cmap->mapping;
4271     }
4272     (*M)->stencil.dim = mat->stencil.dim;
4273     (*M)->stencil.noc = mat->stencil.noc;
4274     for (i=0; i<=mat->stencil.dim; i++) {
4275       (*M)->stencil.dims[i]   = mat->stencil.dims[i];
4276       (*M)->stencil.starts[i] = mat->stencil.starts[i];
4277     }
4278     ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4279   }
4280   ierr = PetscObjectStateIncrease((PetscObject)*M);CHKERRQ(ierr);
4281 
4282   /* Copy Mat options */
4283   if (mat->symmetric) {ierr = MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);}
4284   if (mat->hermitian) {ierr = MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);}
4285   PetscFunctionReturn(0);
4286 }
4287 
4288 /*@C
4289    MatFactorGetSolverType - Returns name of the package providing the factorization routines
4290 
4291    Not Collective
4292 
4293    Input Parameter:
4294 .  mat - the matrix, must be a factored matrix
4295 
4296    Output Parameter:
4297 .   type - the string name of the package (do not free this string)
4298 
4299    Notes:
4300       In Fortran you pass in a empty string and the package name will be copied into it.
4301     (Make sure the string is long enough)
4302 
4303    Level: intermediate
4304 
4305 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
4306 @*/
4307 PetscErrorCode MatFactorGetSolverType(Mat mat, MatSolverType *type)
4308 {
4309   PetscErrorCode ierr, (*conv)(Mat,MatSolverType*);
4310 
4311   PetscFunctionBegin;
4312   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4313   PetscValidType(mat,1);
4314   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
4315   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverType_C",&conv);CHKERRQ(ierr);
4316   if (!conv) {
4317     *type = MATSOLVERPETSC;
4318   } else {
4319     ierr = (*conv)(mat,type);CHKERRQ(ierr);
4320   }
4321   PetscFunctionReturn(0);
4322 }
4323 
4324 typedef struct _MatSolverTypeForSpecifcType* MatSolverTypeForSpecifcType;
4325 struct _MatSolverTypeForSpecifcType {
4326   MatType                        mtype;
4327   PetscErrorCode                 (*getfactor[4])(Mat,MatFactorType,Mat*);
4328   MatSolverTypeForSpecifcType next;
4329 };
4330 
4331 typedef struct _MatSolverTypeHolder* MatSolverTypeHolder;
4332 struct _MatSolverTypeHolder {
4333   char                           *name;
4334   MatSolverTypeForSpecifcType handlers;
4335   MatSolverTypeHolder         next;
4336 };
4337 
4338 static MatSolverTypeHolder MatSolverTypeHolders = NULL;
4339 
4340 /*@C
4341    MatSolvePackageRegister - Registers a MatSolverType that works for a particular matrix type
4342 
4343    Input Parameters:
4344 +    package - name of the package, for example petsc or superlu
4345 .    mtype - the matrix type that works with this package
4346 .    ftype - the type of factorization supported by the package
4347 -    getfactor - routine that will create the factored matrix ready to be used
4348 
4349     Level: intermediate
4350 
4351 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4352 @*/
4353 PetscErrorCode MatSolverTypeRegister(MatSolverType package,MatType mtype,MatFactorType ftype,PetscErrorCode (*getfactor)(Mat,MatFactorType,Mat*))
4354 {
4355   PetscErrorCode              ierr;
4356   MatSolverTypeHolder         next = MatSolverTypeHolders,prev;
4357   PetscBool                   flg;
4358   MatSolverTypeForSpecifcType inext,iprev = NULL;
4359 
4360   PetscFunctionBegin;
4361   ierr = MatInitializePackage();CHKERRQ(ierr);
4362   if (!next) {
4363     ierr = PetscNew(&MatSolverTypeHolders);CHKERRQ(ierr);
4364     ierr = PetscStrallocpy(package,&MatSolverTypeHolders->name);CHKERRQ(ierr);
4365     ierr = PetscNew(&MatSolverTypeHolders->handlers);CHKERRQ(ierr);
4366     ierr = PetscStrallocpy(mtype,(char **)&MatSolverTypeHolders->handlers->mtype);CHKERRQ(ierr);
4367     MatSolverTypeHolders->handlers->getfactor[(int)ftype-1] = getfactor;
4368     PetscFunctionReturn(0);
4369   }
4370   while (next) {
4371     ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr);
4372     if (flg) {
4373       if (!next->handlers) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverTypeHolder is missing handlers");
4374       inext = next->handlers;
4375       while (inext) {
4376         ierr = PetscStrcasecmp(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4377         if (flg) {
4378           inext->getfactor[(int)ftype-1] = getfactor;
4379           PetscFunctionReturn(0);
4380         }
4381         iprev = inext;
4382         inext = inext->next;
4383       }
4384       ierr = PetscNew(&iprev->next);CHKERRQ(ierr);
4385       ierr = PetscStrallocpy(mtype,(char **)&iprev->next->mtype);CHKERRQ(ierr);
4386       iprev->next->getfactor[(int)ftype-1] = getfactor;
4387       PetscFunctionReturn(0);
4388     }
4389     prev = next;
4390     next = next->next;
4391   }
4392   ierr = PetscNew(&prev->next);CHKERRQ(ierr);
4393   ierr = PetscStrallocpy(package,&prev->next->name);CHKERRQ(ierr);
4394   ierr = PetscNew(&prev->next->handlers);CHKERRQ(ierr);
4395   ierr = PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);CHKERRQ(ierr);
4396   prev->next->handlers->getfactor[(int)ftype-1] = getfactor;
4397   PetscFunctionReturn(0);
4398 }
4399 
4400 /*@C
4401    MatSolvePackageGet - Get's the function that creates the factor matrix if it exist
4402 
4403    Input Parameters:
4404 +    package - name of the package, for example petsc or superlu
4405 .    ftype - the type of factorization supported by the package
4406 -    mtype - the matrix type that works with this package
4407 
4408    Output Parameters:
4409 +   foundpackage - PETSC_TRUE if the package was registered
4410 .   foundmtype - PETSC_TRUE if the package supports the requested mtype
4411 -   getfactor - routine that will create the factored matrix ready to be used or NULL if not found
4412 
4413     Level: intermediate
4414 
4415 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4416 @*/
4417 PetscErrorCode MatSolverTypeGet(MatSolverType package,MatType mtype,MatFactorType ftype,PetscBool *foundpackage,PetscBool *foundmtype,PetscErrorCode (**getfactor)(Mat,MatFactorType,Mat*))
4418 {
4419   PetscErrorCode                 ierr;
4420   MatSolverTypeHolder         next = MatSolverTypeHolders;
4421   PetscBool                      flg;
4422   MatSolverTypeForSpecifcType inext;
4423 
4424   PetscFunctionBegin;
4425   if (foundpackage) *foundpackage = PETSC_FALSE;
4426   if (foundmtype)   *foundmtype   = PETSC_FALSE;
4427   if (getfactor)    *getfactor    = NULL;
4428 
4429   if (package) {
4430     while (next) {
4431       ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr);
4432       if (flg) {
4433         if (foundpackage) *foundpackage = PETSC_TRUE;
4434         inext = next->handlers;
4435         while (inext) {
4436           ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4437           if (flg) {
4438             if (foundmtype) *foundmtype = PETSC_TRUE;
4439             if (getfactor)  *getfactor  = inext->getfactor[(int)ftype-1];
4440             PetscFunctionReturn(0);
4441           }
4442           inext = inext->next;
4443         }
4444       }
4445       next = next->next;
4446     }
4447   } else {
4448     while (next) {
4449       inext = next->handlers;
4450       while (inext) {
4451         ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4452         if (flg && inext->getfactor[(int)ftype-1]) {
4453           if (foundpackage) *foundpackage = PETSC_TRUE;
4454           if (foundmtype)   *foundmtype   = PETSC_TRUE;
4455           if (getfactor)    *getfactor    = inext->getfactor[(int)ftype-1];
4456           PetscFunctionReturn(0);
4457         }
4458         inext = inext->next;
4459       }
4460       next = next->next;
4461     }
4462   }
4463   PetscFunctionReturn(0);
4464 }
4465 
4466 PetscErrorCode MatSolverTypeDestroy(void)
4467 {
4468   PetscErrorCode              ierr;
4469   MatSolverTypeHolder         next = MatSolverTypeHolders,prev;
4470   MatSolverTypeForSpecifcType inext,iprev;
4471 
4472   PetscFunctionBegin;
4473   while (next) {
4474     ierr = PetscFree(next->name);CHKERRQ(ierr);
4475     inext = next->handlers;
4476     while (inext) {
4477       ierr = PetscFree(inext->mtype);CHKERRQ(ierr);
4478       iprev = inext;
4479       inext = inext->next;
4480       ierr = PetscFree(iprev);CHKERRQ(ierr);
4481     }
4482     prev = next;
4483     next = next->next;
4484     ierr = PetscFree(prev);CHKERRQ(ierr);
4485   }
4486   MatSolverTypeHolders = NULL;
4487   PetscFunctionReturn(0);
4488 }
4489 
4490 /*@C
4491    MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic()
4492 
4493    Collective on Mat
4494 
4495    Input Parameters:
4496 +  mat - the matrix
4497 .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4498 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4499 
4500    Output Parameters:
4501 .  f - the factor matrix used with MatXXFactorSymbolic() calls
4502 
4503    Notes:
4504       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4505      such as pastix, superlu, mumps etc.
4506 
4507       PETSc must have been ./configure to use the external solver, using the option --download-package
4508 
4509    Level: intermediate
4510 
4511 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4512 @*/
4513 PetscErrorCode MatGetFactor(Mat mat, MatSolverType type,MatFactorType ftype,Mat *f)
4514 {
4515   PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
4516   PetscBool      foundpackage,foundmtype;
4517 
4518   PetscFunctionBegin;
4519   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4520   PetscValidType(mat,1);
4521 
4522   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4523   MatCheckPreallocated(mat,1);
4524 
4525   ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,&foundpackage,&foundmtype,&conv);CHKERRQ(ierr);
4526   if (!foundpackage) {
4527     if (type) {
4528       SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver package %s. Perhaps you must ./configure with --download-%s",type,type);
4529     } else {
4530       SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate a solver package. Perhaps you must ./configure with --download-<package>");
4531     }
4532   }
4533 
4534   if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support matrix type %s",type,((PetscObject)mat)->type_name);
4535   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);
4536 
4537 #if defined(PETSC_USE_COMPLEX)
4538   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");
4539 #endif
4540 
4541   ierr = (*conv)(mat,ftype,f);CHKERRQ(ierr);
4542   PetscFunctionReturn(0);
4543 }
4544 
4545 /*@C
4546    MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type
4547 
4548    Not Collective
4549 
4550    Input Parameters:
4551 +  mat - the matrix
4552 .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4553 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4554 
4555    Output Parameter:
4556 .    flg - PETSC_TRUE if the factorization is available
4557 
4558    Notes:
4559       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4560      such as pastix, superlu, mumps etc.
4561 
4562       PETSc must have been ./configure to use the external solver, using the option --download-package
4563 
4564    Level: intermediate
4565 
4566 .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
4567 @*/
4568 PetscErrorCode MatGetFactorAvailable(Mat mat, MatSolverType type,MatFactorType ftype,PetscBool  *flg)
4569 {
4570   PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*);
4571 
4572   PetscFunctionBegin;
4573   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4574   PetscValidType(mat,1);
4575 
4576   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4577   MatCheckPreallocated(mat,1);
4578 
4579   *flg = PETSC_FALSE;
4580   ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);CHKERRQ(ierr);
4581   if (gconv) {
4582     *flg = PETSC_TRUE;
4583   }
4584   PetscFunctionReturn(0);
4585 }
4586 
4587 #include <petscdmtypes.h>
4588 
4589 /*@
4590    MatDuplicate - Duplicates a matrix including the non-zero structure.
4591 
4592    Collective on Mat
4593 
4594    Input Parameters:
4595 +  mat - the matrix
4596 -  op - One of MAT_DO_NOT_COPY_VALUES, MAT_COPY_VALUES, or MAT_SHARE_NONZERO_PATTERN.
4597         See the manual page for MatDuplicateOption for an explanation of these options.
4598 
4599    Output Parameter:
4600 .  M - pointer to place new matrix
4601 
4602    Level: intermediate
4603 
4604    Concepts: matrices^duplicating
4605 
4606    Notes:
4607     You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN.
4608     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.
4609 
4610 .seealso: MatCopy(), MatConvert(), MatDuplicateOption
4611 @*/
4612 PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4613 {
4614   PetscErrorCode ierr;
4615   Mat            B;
4616   PetscInt       i;
4617   DM             dm;
4618   void           (*viewf)(void);
4619 
4620   PetscFunctionBegin;
4621   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4622   PetscValidType(mat,1);
4623   PetscValidPointer(M,3);
4624   if (op == MAT_COPY_VALUES && !mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MAT_COPY_VALUES not allowed for unassembled matrix");
4625   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4626   MatCheckPreallocated(mat,1);
4627 
4628   *M = 0;
4629   if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type");
4630   ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4631   ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr);
4632   B    = *M;
4633 
4634   ierr = MatGetOperation(mat,MATOP_VIEW,&viewf);CHKERRQ(ierr);
4635   if (viewf) {
4636     ierr = MatSetOperation(B,MATOP_VIEW,viewf);CHKERRQ(ierr);
4637   }
4638 
4639   B->stencil.dim = mat->stencil.dim;
4640   B->stencil.noc = mat->stencil.noc;
4641   for (i=0; i<=mat->stencil.dim; i++) {
4642     B->stencil.dims[i]   = mat->stencil.dims[i];
4643     B->stencil.starts[i] = mat->stencil.starts[i];
4644   }
4645 
4646   B->nooffproczerorows = mat->nooffproczerorows;
4647   B->nooffprocentries  = mat->nooffprocentries;
4648 
4649   ierr = PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);CHKERRQ(ierr);
4650   if (dm) {
4651     ierr = PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr);
4652   }
4653   ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4654   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
4655   PetscFunctionReturn(0);
4656 }
4657 
4658 /*@
4659    MatGetDiagonal - Gets the diagonal of a matrix.
4660 
4661    Logically Collective on Mat and Vec
4662 
4663    Input Parameters:
4664 +  mat - the matrix
4665 -  v - the vector for storing the diagonal
4666 
4667    Output Parameter:
4668 .  v - the diagonal of the matrix
4669 
4670    Level: intermediate
4671 
4672    Note:
4673    Currently only correct in parallel for square matrices.
4674 
4675    Concepts: matrices^accessing diagonals
4676 
4677 .seealso: MatGetRow(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs()
4678 @*/
4679 PetscErrorCode MatGetDiagonal(Mat mat,Vec v)
4680 {
4681   PetscErrorCode ierr;
4682 
4683   PetscFunctionBegin;
4684   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4685   PetscValidType(mat,1);
4686   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4687   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4688   if (!mat->ops->getdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4689   MatCheckPreallocated(mat,1);
4690 
4691   ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr);
4692   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4693   PetscFunctionReturn(0);
4694 }
4695 
4696 /*@C
4697    MatGetRowMin - Gets the minimum value (of the real part) of each
4698         row of the matrix
4699 
4700    Logically Collective on Mat and Vec
4701 
4702    Input Parameters:
4703 .  mat - the matrix
4704 
4705    Output Parameter:
4706 +  v - the vector for storing the maximums
4707 -  idx - the indices of the column found for each row (optional)
4708 
4709    Level: intermediate
4710 
4711    Notes:
4712     The result of this call are the same as if one converted the matrix to dense format
4713       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4714 
4715     This code is only implemented for a couple of matrix formats.
4716 
4717    Concepts: matrices^getting row maximums
4718 
4719 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(),
4720           MatGetRowMax()
4721 @*/
4722 PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4723 {
4724   PetscErrorCode ierr;
4725 
4726   PetscFunctionBegin;
4727   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4728   PetscValidType(mat,1);
4729   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4730   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4731   if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4732   MatCheckPreallocated(mat,1);
4733 
4734   ierr = (*mat->ops->getrowmin)(mat,v,idx);CHKERRQ(ierr);
4735   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4736   PetscFunctionReturn(0);
4737 }
4738 
4739 /*@C
4740    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4741         row of the matrix
4742 
4743    Logically Collective on Mat and Vec
4744 
4745    Input Parameters:
4746 .  mat - the matrix
4747 
4748    Output Parameter:
4749 +  v - the vector for storing the minimums
4750 -  idx - the indices of the column found for each row (or NULL if not needed)
4751 
4752    Level: intermediate
4753 
4754    Notes:
4755     if a row is completely empty or has only 0.0 values then the idx[] value for that
4756     row is 0 (the first column).
4757 
4758     This code is only implemented for a couple of matrix formats.
4759 
4760    Concepts: matrices^getting row maximums
4761 
4762 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4763 @*/
4764 PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4765 {
4766   PetscErrorCode ierr;
4767 
4768   PetscFunctionBegin;
4769   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4770   PetscValidType(mat,1);
4771   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4772   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4773   if (!mat->ops->getrowminabs) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4774   MatCheckPreallocated(mat,1);
4775   if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);}
4776 
4777   ierr = (*mat->ops->getrowminabs)(mat,v,idx);CHKERRQ(ierr);
4778   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4779   PetscFunctionReturn(0);
4780 }
4781 
4782 /*@C
4783    MatGetRowMax - Gets the maximum value (of the real part) of each
4784         row of the matrix
4785 
4786    Logically Collective on Mat and Vec
4787 
4788    Input Parameters:
4789 .  mat - the matrix
4790 
4791    Output Parameter:
4792 +  v - the vector for storing the maximums
4793 -  idx - the indices of the column found for each row (optional)
4794 
4795    Level: intermediate
4796 
4797    Notes:
4798     The result of this call are the same as if one converted the matrix to dense format
4799       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4800 
4801     This code is only implemented for a couple of matrix formats.
4802 
4803    Concepts: matrices^getting row maximums
4804 
4805 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4806 @*/
4807 PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4808 {
4809   PetscErrorCode ierr;
4810 
4811   PetscFunctionBegin;
4812   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4813   PetscValidType(mat,1);
4814   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4815   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4816   if (!mat->ops->getrowmax) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4817   MatCheckPreallocated(mat,1);
4818 
4819   ierr = (*mat->ops->getrowmax)(mat,v,idx);CHKERRQ(ierr);
4820   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4821   PetscFunctionReturn(0);
4822 }
4823 
4824 /*@C
4825    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4826         row of the matrix
4827 
4828    Logically Collective on Mat and Vec
4829 
4830    Input Parameters:
4831 .  mat - the matrix
4832 
4833    Output Parameter:
4834 +  v - the vector for storing the maximums
4835 -  idx - the indices of the column found for each row (or NULL if not needed)
4836 
4837    Level: intermediate
4838 
4839    Notes:
4840     if a row is completely empty or has only 0.0 values then the idx[] value for that
4841     row is 0 (the first column).
4842 
4843     This code is only implemented for a couple of matrix formats.
4844 
4845    Concepts: matrices^getting row maximums
4846 
4847 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
4848 @*/
4849 PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4850 {
4851   PetscErrorCode ierr;
4852 
4853   PetscFunctionBegin;
4854   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4855   PetscValidType(mat,1);
4856   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4857   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4858   if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4859   MatCheckPreallocated(mat,1);
4860   if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);}
4861 
4862   ierr = (*mat->ops->getrowmaxabs)(mat,v,idx);CHKERRQ(ierr);
4863   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4864   PetscFunctionReturn(0);
4865 }
4866 
4867 /*@
4868    MatGetRowSum - Gets the sum of each row of the matrix
4869 
4870    Logically or Neighborhood Collective on Mat and Vec
4871 
4872    Input Parameters:
4873 .  mat - the matrix
4874 
4875    Output Parameter:
4876 .  v - the vector for storing the sum of rows
4877 
4878    Level: intermediate
4879 
4880    Notes:
4881     This code is slow since it is not currently specialized for different formats
4882 
4883    Concepts: matrices^getting row sums
4884 
4885 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
4886 @*/
4887 PetscErrorCode MatGetRowSum(Mat mat, Vec v)
4888 {
4889   Vec            ones;
4890   PetscErrorCode ierr;
4891 
4892   PetscFunctionBegin;
4893   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4894   PetscValidType(mat,1);
4895   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4896   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4897   MatCheckPreallocated(mat,1);
4898   ierr = MatCreateVecs(mat,&ones,NULL);CHKERRQ(ierr);
4899   ierr = VecSet(ones,1.);CHKERRQ(ierr);
4900   ierr = MatMult(mat,ones,v);CHKERRQ(ierr);
4901   ierr = VecDestroy(&ones);CHKERRQ(ierr);
4902   PetscFunctionReturn(0);
4903 }
4904 
4905 /*@
4906    MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
4907 
4908    Collective on Mat
4909 
4910    Input Parameter:
4911 +  mat - the matrix to transpose
4912 -  reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX
4913 
4914    Output Parameters:
4915 .  B - the transpose
4916 
4917    Notes:
4918      If you use MAT_INPLACE_MATRIX then you must pass in &mat for B
4919 
4920      MAT_REUSE_MATRIX causes the B matrix from a previous call to this function with MAT_INITIAL_MATRIX to be used
4921 
4922      Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed.
4923 
4924    Level: intermediate
4925 
4926    Concepts: matrices^transposing
4927 
4928 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4929 @*/
4930 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4931 {
4932   PetscErrorCode ierr;
4933 
4934   PetscFunctionBegin;
4935   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4936   PetscValidType(mat,1);
4937   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4938   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4939   if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4940   if (reuse == MAT_INPLACE_MATRIX && mat != *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires last matrix to match first");
4941   if (reuse == MAT_REUSE_MATRIX && mat == *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Perhaps you mean MAT_INPLACE_MATRIX");
4942   MatCheckPreallocated(mat,1);
4943 
4944   ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4945   ierr = (*mat->ops->transpose)(mat,reuse,B);CHKERRQ(ierr);
4946   ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4947   if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);}
4948   PetscFunctionReturn(0);
4949 }
4950 
4951 /*@
4952    MatIsTranspose - Test whether a matrix is another one's transpose,
4953         or its own, in which case it tests symmetry.
4954 
4955    Collective on Mat
4956 
4957    Input Parameter:
4958 +  A - the matrix to test
4959 -  B - the matrix to test against, this can equal the first parameter
4960 
4961    Output Parameters:
4962 .  flg - the result
4963 
4964    Notes:
4965    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4966    has a running time of the order of the number of nonzeros; the parallel
4967    test involves parallel copies of the block-offdiagonal parts of the matrix.
4968 
4969    Level: intermediate
4970 
4971    Concepts: matrices^transposing, matrix^symmetry
4972 
4973 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4974 @*/
4975 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4976 {
4977   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4978 
4979   PetscFunctionBegin;
4980   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4981   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4982   PetscValidPointer(flg,3);
4983   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);CHKERRQ(ierr);
4984   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);CHKERRQ(ierr);
4985   *flg = PETSC_FALSE;
4986   if (f && g) {
4987     if (f == g) {
4988       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
4989     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4990   } else {
4991     MatType mattype;
4992     if (!f) {
4993       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
4994     } else {
4995       ierr = MatGetType(B,&mattype);CHKERRQ(ierr);
4996     }
4997     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
4998   }
4999   PetscFunctionReturn(0);
5000 }
5001 
5002 /*@
5003    MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate.
5004 
5005    Collective on Mat
5006 
5007    Input Parameter:
5008 +  mat - the matrix to transpose and complex conjugate
5009 -  reuse - MAT_INITIAL_MATRIX to create a new matrix, MAT_INPLACE_MATRIX to reuse the first argument to store the transpose
5010 
5011    Output Parameters:
5012 .  B - the Hermitian
5013 
5014    Level: intermediate
5015 
5016    Concepts: matrices^transposing, complex conjugatex
5017 
5018 .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
5019 @*/
5020 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
5021 {
5022   PetscErrorCode ierr;
5023 
5024   PetscFunctionBegin;
5025   ierr = MatTranspose(mat,reuse,B);CHKERRQ(ierr);
5026 #if defined(PETSC_USE_COMPLEX)
5027   ierr = MatConjugate(*B);CHKERRQ(ierr);
5028 #endif
5029   PetscFunctionReturn(0);
5030 }
5031 
5032 /*@
5033    MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,
5034 
5035    Collective on Mat
5036 
5037    Input Parameter:
5038 +  A - the matrix to test
5039 -  B - the matrix to test against, this can equal the first parameter
5040 
5041    Output Parameters:
5042 .  flg - the result
5043 
5044    Notes:
5045    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
5046    has a running time of the order of the number of nonzeros; the parallel
5047    test involves parallel copies of the block-offdiagonal parts of the matrix.
5048 
5049    Level: intermediate
5050 
5051    Concepts: matrices^transposing, matrix^symmetry
5052 
5053 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
5054 @*/
5055 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
5056 {
5057   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
5058 
5059   PetscFunctionBegin;
5060   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
5061   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
5062   PetscValidPointer(flg,3);
5063   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);CHKERRQ(ierr);
5064   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);CHKERRQ(ierr);
5065   if (f && g) {
5066     if (f==g) {
5067       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
5068     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
5069   }
5070   PetscFunctionReturn(0);
5071 }
5072 
5073 /*@
5074    MatPermute - Creates a new matrix with rows and columns permuted from the
5075    original.
5076 
5077    Collective on Mat
5078 
5079    Input Parameters:
5080 +  mat - the matrix to permute
5081 .  row - row permutation, each processor supplies only the permutation for its rows
5082 -  col - column permutation, each processor supplies only the permutation for its columns
5083 
5084    Output Parameters:
5085 .  B - the permuted matrix
5086 
5087    Level: advanced
5088 
5089    Note:
5090    The index sets map from row/col of permuted matrix to row/col of original matrix.
5091    The index sets should be on the same communicator as Mat and have the same local sizes.
5092 
5093    Concepts: matrices^permuting
5094 
5095 .seealso: MatGetOrdering(), ISAllGather()
5096 
5097 @*/
5098 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
5099 {
5100   PetscErrorCode ierr;
5101 
5102   PetscFunctionBegin;
5103   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5104   PetscValidType(mat,1);
5105   PetscValidHeaderSpecific(row,IS_CLASSID,2);
5106   PetscValidHeaderSpecific(col,IS_CLASSID,3);
5107   PetscValidPointer(B,4);
5108   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5109   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5110   if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
5111   MatCheckPreallocated(mat,1);
5112 
5113   ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr);
5114   ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);
5115   PetscFunctionReturn(0);
5116 }
5117 
5118 /*@
5119    MatEqual - Compares two matrices.
5120 
5121    Collective on Mat
5122 
5123    Input Parameters:
5124 +  A - the first matrix
5125 -  B - the second matrix
5126 
5127    Output Parameter:
5128 .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
5129 
5130    Level: intermediate
5131 
5132    Concepts: matrices^equality between
5133 @*/
5134 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool  *flg)
5135 {
5136   PetscErrorCode ierr;
5137 
5138   PetscFunctionBegin;
5139   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
5140   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
5141   PetscValidType(A,1);
5142   PetscValidType(B,2);
5143   PetscValidIntPointer(flg,3);
5144   PetscCheckSameComm(A,1,B,2);
5145   MatCheckPreallocated(B,2);
5146   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5147   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5148   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);
5149   if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
5150   if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
5151   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);
5152   MatCheckPreallocated(A,1);
5153 
5154   ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr);
5155   PetscFunctionReturn(0);
5156 }
5157 
5158 /*@
5159    MatDiagonalScale - Scales a matrix on the left and right by diagonal
5160    matrices that are stored as vectors.  Either of the two scaling
5161    matrices can be NULL.
5162 
5163    Collective on Mat
5164 
5165    Input Parameters:
5166 +  mat - the matrix to be scaled
5167 .  l - the left scaling vector (or NULL)
5168 -  r - the right scaling vector (or NULL)
5169 
5170    Notes:
5171    MatDiagonalScale() computes A = LAR, where
5172    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
5173    The L scales the rows of the matrix, the R scales the columns of the matrix.
5174 
5175    Level: intermediate
5176 
5177    Concepts: matrices^diagonal scaling
5178    Concepts: diagonal scaling of matrices
5179 
5180 .seealso: MatScale(), MatShift(), MatDiagonalSet()
5181 @*/
5182 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
5183 {
5184   PetscErrorCode ierr;
5185 
5186   PetscFunctionBegin;
5187   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5188   PetscValidType(mat,1);
5189   if (!mat->ops->diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5190   if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);}
5191   if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);}
5192   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5193   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5194   MatCheckPreallocated(mat,1);
5195 
5196   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5197   ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr);
5198   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5199   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5200 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5201   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5202     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5203   }
5204 #endif
5205   PetscFunctionReturn(0);
5206 }
5207 
5208 /*@
5209     MatScale - Scales all elements of a matrix by a given number.
5210 
5211     Logically Collective on Mat
5212 
5213     Input Parameters:
5214 +   mat - the matrix to be scaled
5215 -   a  - the scaling value
5216 
5217     Output Parameter:
5218 .   mat - the scaled matrix
5219 
5220     Level: intermediate
5221 
5222     Concepts: matrices^scaling all entries
5223 
5224 .seealso: MatDiagonalScale()
5225 @*/
5226 PetscErrorCode MatScale(Mat mat,PetscScalar a)
5227 {
5228   PetscErrorCode ierr;
5229 
5230   PetscFunctionBegin;
5231   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5232   PetscValidType(mat,1);
5233   if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5234   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5235   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5236   PetscValidLogicalCollectiveScalar(mat,a,2);
5237   MatCheckPreallocated(mat,1);
5238 
5239   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5240   if (a != (PetscScalar)1.0) {
5241     ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr);
5242     ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5243 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5244     if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5245       mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5246     }
5247 #endif
5248   }
5249   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5250   PetscFunctionReturn(0);
5251 }
5252 
5253 /*@
5254    MatNorm - Calculates various norms of a matrix.
5255 
5256    Collective on Mat
5257 
5258    Input Parameters:
5259 +  mat - the matrix
5260 -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
5261 
5262    Output Parameters:
5263 .  nrm - the resulting norm
5264 
5265    Level: intermediate
5266 
5267    Concepts: matrices^norm
5268    Concepts: norm^of matrix
5269 @*/
5270 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
5271 {
5272   PetscErrorCode ierr;
5273 
5274   PetscFunctionBegin;
5275   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5276   PetscValidType(mat,1);
5277   PetscValidScalarPointer(nrm,3);
5278 
5279   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5280   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5281   if (!mat->ops->norm) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5282   MatCheckPreallocated(mat,1);
5283 
5284   ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr);
5285   PetscFunctionReturn(0);
5286 }
5287 
5288 /*
5289      This variable is used to prevent counting of MatAssemblyBegin() that
5290    are called from within a MatAssemblyEnd().
5291 */
5292 static PetscInt MatAssemblyEnd_InUse = 0;
5293 /*@
5294    MatAssemblyBegin - Begins assembling the matrix.  This routine should
5295    be called after completing all calls to MatSetValues().
5296 
5297    Collective on Mat
5298 
5299    Input Parameters:
5300 +  mat - the matrix
5301 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5302 
5303    Notes:
5304    MatSetValues() generally caches the values.  The matrix is ready to
5305    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5306    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5307    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5308    using the matrix.
5309 
5310    ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the
5311    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
5312    a global collective operation requring all processes that share the matrix.
5313 
5314    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5315    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5316    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5317 
5318    Level: beginner
5319 
5320    Concepts: matrices^assembling
5321 
5322 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
5323 @*/
5324 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
5325 {
5326   PetscErrorCode ierr;
5327 
5328   PetscFunctionBegin;
5329   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5330   PetscValidType(mat,1);
5331   MatCheckPreallocated(mat,1);
5332   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
5333   if (mat->assembled) {
5334     mat->was_assembled = PETSC_TRUE;
5335     mat->assembled     = PETSC_FALSE;
5336   }
5337   if (!MatAssemblyEnd_InUse) {
5338     ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5339     if (mat->ops->assemblybegin) {ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
5340     ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5341   } else if (mat->ops->assemblybegin) {
5342     ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);
5343   }
5344   PetscFunctionReturn(0);
5345 }
5346 
5347 /*@
5348    MatAssembled - Indicates if a matrix has been assembled and is ready for
5349      use; for example, in matrix-vector product.
5350 
5351    Not Collective
5352 
5353    Input Parameter:
5354 .  mat - the matrix
5355 
5356    Output Parameter:
5357 .  assembled - PETSC_TRUE or PETSC_FALSE
5358 
5359    Level: advanced
5360 
5361    Concepts: matrices^assembled?
5362 
5363 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
5364 @*/
5365 PetscErrorCode MatAssembled(Mat mat,PetscBool  *assembled)
5366 {
5367   PetscFunctionBegin;
5368   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5369   PetscValidPointer(assembled,2);
5370   *assembled = mat->assembled;
5371   PetscFunctionReturn(0);
5372 }
5373 
5374 /*@
5375    MatAssemblyEnd - Completes assembling the matrix.  This routine should
5376    be called after MatAssemblyBegin().
5377 
5378    Collective on Mat
5379 
5380    Input Parameters:
5381 +  mat - the matrix
5382 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5383 
5384    Options Database Keys:
5385 +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
5386 .  -mat_view ::ascii_info_detail - Prints more detailed info
5387 .  -mat_view - Prints matrix in ASCII format
5388 .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
5389 .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
5390 .  -display <name> - Sets display name (default is host)
5391 .  -draw_pause <sec> - Sets number of seconds to pause after display
5392 .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab )
5393 .  -viewer_socket_machine <machine> - Machine to use for socket
5394 .  -viewer_socket_port <port> - Port number to use for socket
5395 -  -mat_view binary:filename[:append] - Save matrix to file in binary format
5396 
5397    Notes:
5398    MatSetValues() generally caches the values.  The matrix is ready to
5399    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5400    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5401    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5402    using the matrix.
5403 
5404    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5405    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5406    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5407 
5408    Level: beginner
5409 
5410 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
5411 @*/
5412 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
5413 {
5414   PetscErrorCode  ierr;
5415   static PetscInt inassm = 0;
5416   PetscBool       flg    = PETSC_FALSE;
5417 
5418   PetscFunctionBegin;
5419   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5420   PetscValidType(mat,1);
5421 
5422   inassm++;
5423   MatAssemblyEnd_InUse++;
5424   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
5425     ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5426     if (mat->ops->assemblyend) {
5427       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5428     }
5429     ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5430   } else if (mat->ops->assemblyend) {
5431     ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5432   }
5433 
5434   /* Flush assembly is not a true assembly */
5435   if (type != MAT_FLUSH_ASSEMBLY) {
5436     mat->assembled = PETSC_TRUE; mat->num_ass++;
5437   }
5438   mat->insertmode = NOT_SET_VALUES;
5439   MatAssemblyEnd_InUse--;
5440   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5441   if (!mat->symmetric_eternal) {
5442     mat->symmetric_set              = PETSC_FALSE;
5443     mat->hermitian_set              = PETSC_FALSE;
5444     mat->structurally_symmetric_set = PETSC_FALSE;
5445   }
5446 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5447   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5448     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5449   }
5450 #endif
5451   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
5452     ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5453 
5454     if (mat->checksymmetryonassembly) {
5455       ierr = MatIsSymmetric(mat,mat->checksymmetrytol,&flg);CHKERRQ(ierr);
5456       if (flg) {
5457         ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5458       } else {
5459         ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5460       }
5461     }
5462     if (mat->nullsp && mat->checknullspaceonassembly) {
5463       ierr = MatNullSpaceTest(mat->nullsp,mat,NULL);CHKERRQ(ierr);
5464     }
5465   }
5466   inassm--;
5467   PetscFunctionReturn(0);
5468 }
5469 
5470 /*@
5471    MatSetOption - Sets a parameter option for a matrix. Some options
5472    may be specific to certain storage formats.  Some options
5473    determine how values will be inserted (or added). Sorted,
5474    row-oriented input will generally assemble the fastest. The default
5475    is row-oriented.
5476 
5477    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5478 
5479    Input Parameters:
5480 +  mat - the matrix
5481 .  option - the option, one of those listed below (and possibly others),
5482 -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5483 
5484   Options Describing Matrix Structure:
5485 +    MAT_SPD - symmetric positive definite
5486 .    MAT_SYMMETRIC - symmetric in terms of both structure and value
5487 .    MAT_HERMITIAN - transpose is the complex conjugation
5488 .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5489 -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5490                             you set to be kept with all future use of the matrix
5491                             including after MatAssemblyBegin/End() which could
5492                             potentially change the symmetry structure, i.e. you
5493                             KNOW the matrix will ALWAYS have the property you set.
5494 
5495 
5496    Options For Use with MatSetValues():
5497    Insert a logically dense subblock, which can be
5498 .    MAT_ROW_ORIENTED - row-oriented (default)
5499 
5500    Note these options reflect the data you pass in with MatSetValues(); it has
5501    nothing to do with how the data is stored internally in the matrix
5502    data structure.
5503 
5504    When (re)assembling a matrix, we can restrict the input for
5505    efficiency/debugging purposes.  These options include:
5506 +    MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow)
5507 .    MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
5508 .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
5509 .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
5510 .    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
5511 .    MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
5512         any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
5513         performance for very large process counts.
5514 -    MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset
5515         of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly
5516         functions, instead sending only neighbor messages.
5517 
5518    Notes:
5519    Except for MAT_UNUSED_NONZERO_LOCATION_ERR and  MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg!
5520 
5521    Some options are relevant only for particular matrix types and
5522    are thus ignored by others.  Other options are not supported by
5523    certain matrix types and will generate an error message if set.
5524 
5525    If using a Fortran 77 module to compute a matrix, one may need to
5526    use the column-oriented option (or convert to the row-oriented
5527    format).
5528 
5529    MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
5530    that would generate a new entry in the nonzero structure is instead
5531    ignored.  Thus, if memory has not alredy been allocated for this particular
5532    data, then the insertion is ignored. For dense matrices, in which
5533    the entire array is allocated, no entries are ever ignored.
5534    Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5535 
5536    MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5537    that would generate a new entry in the nonzero structure instead produces
5538    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
5539 
5540    MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5541    that would generate a new entry that has not been preallocated will
5542    instead produce an error. (Currently supported for AIJ and BAIJ formats
5543    only.) This is a useful flag when debugging matrix memory preallocation.
5544    If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5545 
5546    MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for
5547    other processors should be dropped, rather than stashed.
5548    This is useful if you know that the "owning" processor is also
5549    always generating the correct matrix entries, so that PETSc need
5550    not transfer duplicate entries generated on another processor.
5551 
5552    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5553    searches during matrix assembly. When this flag is set, the hash table
5554    is created during the first Matrix Assembly. This hash table is
5555    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5556    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5557    should be used with MAT_USE_HASH_TABLE flag. This option is currently
5558    supported by MATMPIBAIJ format only.
5559 
5560    MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries
5561    are kept in the nonzero structure
5562 
5563    MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
5564    a zero location in the matrix
5565 
5566    MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types
5567 
5568    MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the
5569         zero row routines and thus improves performance for very large process counts.
5570 
5571    MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular
5572         part of the matrix (since they should match the upper triangular part).
5573 
5574    Notes:
5575     Can only be called after MatSetSizes() and MatSetType() have been set.
5576 
5577    Level: intermediate
5578 
5579    Concepts: matrices^setting options
5580 
5581 .seealso:  MatOption, Mat
5582 
5583 @*/
5584 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg)
5585 {
5586   PetscErrorCode ierr;
5587 
5588   PetscFunctionBegin;
5589   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5590   PetscValidType(mat,1);
5591   if (op > 0) {
5592     PetscValidLogicalCollectiveEnum(mat,op,2);
5593     PetscValidLogicalCollectiveBool(mat,flg,3);
5594   }
5595 
5596   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);
5597   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()");
5598 
5599   switch (op) {
5600   case MAT_NO_OFF_PROC_ENTRIES:
5601     mat->nooffprocentries = flg;
5602     PetscFunctionReturn(0);
5603     break;
5604   case MAT_SUBSET_OFF_PROC_ENTRIES:
5605     mat->subsetoffprocentries = flg;
5606     PetscFunctionReturn(0);
5607   case MAT_NO_OFF_PROC_ZERO_ROWS:
5608     mat->nooffproczerorows = flg;
5609     PetscFunctionReturn(0);
5610     break;
5611   case MAT_SPD:
5612     mat->spd_set = PETSC_TRUE;
5613     mat->spd     = flg;
5614     if (flg) {
5615       mat->symmetric                  = PETSC_TRUE;
5616       mat->structurally_symmetric     = PETSC_TRUE;
5617       mat->symmetric_set              = PETSC_TRUE;
5618       mat->structurally_symmetric_set = PETSC_TRUE;
5619     }
5620     break;
5621   case MAT_SYMMETRIC:
5622     mat->symmetric = flg;
5623     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5624     mat->symmetric_set              = PETSC_TRUE;
5625     mat->structurally_symmetric_set = flg;
5626 #if !defined(PETSC_USE_COMPLEX)
5627     mat->hermitian     = flg;
5628     mat->hermitian_set = PETSC_TRUE;
5629 #endif
5630     break;
5631   case MAT_HERMITIAN:
5632     mat->hermitian = flg;
5633     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5634     mat->hermitian_set              = PETSC_TRUE;
5635     mat->structurally_symmetric_set = flg;
5636 #if !defined(PETSC_USE_COMPLEX)
5637     mat->symmetric     = flg;
5638     mat->symmetric_set = PETSC_TRUE;
5639 #endif
5640     break;
5641   case MAT_STRUCTURALLY_SYMMETRIC:
5642     mat->structurally_symmetric     = flg;
5643     mat->structurally_symmetric_set = PETSC_TRUE;
5644     break;
5645   case MAT_SYMMETRY_ETERNAL:
5646     mat->symmetric_eternal = flg;
5647     break;
5648   case MAT_STRUCTURE_ONLY:
5649     mat->structure_only = flg;
5650     break;
5651   default:
5652     break;
5653   }
5654   if (mat->ops->setoption) {
5655     ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr);
5656   }
5657   PetscFunctionReturn(0);
5658 }
5659 
5660 /*@
5661    MatGetOption - Gets a parameter option that has been set for a matrix.
5662 
5663    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5664 
5665    Input Parameters:
5666 +  mat - the matrix
5667 -  option - the option, this only responds to certain options, check the code for which ones
5668 
5669    Output Parameter:
5670 .  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5671 
5672     Notes:
5673     Can only be called after MatSetSizes() and MatSetType() have been set.
5674 
5675    Level: intermediate
5676 
5677    Concepts: matrices^setting options
5678 
5679 .seealso:  MatOption, MatSetOption()
5680 
5681 @*/
5682 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg)
5683 {
5684   PetscFunctionBegin;
5685   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5686   PetscValidType(mat,1);
5687 
5688   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);
5689   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()");
5690 
5691   switch (op) {
5692   case MAT_NO_OFF_PROC_ENTRIES:
5693     *flg = mat->nooffprocentries;
5694     break;
5695   case MAT_NO_OFF_PROC_ZERO_ROWS:
5696     *flg = mat->nooffproczerorows;
5697     break;
5698   case MAT_SYMMETRIC:
5699     *flg = mat->symmetric;
5700     break;
5701   case MAT_HERMITIAN:
5702     *flg = mat->hermitian;
5703     break;
5704   case MAT_STRUCTURALLY_SYMMETRIC:
5705     *flg = mat->structurally_symmetric;
5706     break;
5707   case MAT_SYMMETRY_ETERNAL:
5708     *flg = mat->symmetric_eternal;
5709     break;
5710   case MAT_SPD:
5711     *flg = mat->spd;
5712     break;
5713   default:
5714     break;
5715   }
5716   PetscFunctionReturn(0);
5717 }
5718 
5719 /*@
5720    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5721    this routine retains the old nonzero structure.
5722 
5723    Logically Collective on Mat
5724 
5725    Input Parameters:
5726 .  mat - the matrix
5727 
5728    Level: intermediate
5729 
5730    Notes:
5731     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.
5732    See the Performance chapter of the users manual for information on preallocating matrices.
5733 
5734    Concepts: matrices^zeroing
5735 
5736 .seealso: MatZeroRows()
5737 @*/
5738 PetscErrorCode MatZeroEntries(Mat mat)
5739 {
5740   PetscErrorCode ierr;
5741 
5742   PetscFunctionBegin;
5743   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5744   PetscValidType(mat,1);
5745   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5746   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");
5747   if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5748   MatCheckPreallocated(mat,1);
5749 
5750   ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5751   ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
5752   ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5753   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5754 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5755   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5756     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5757   }
5758 #endif
5759   PetscFunctionReturn(0);
5760 }
5761 
5762 /*@
5763    MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal)
5764    of a set of rows and columns of a matrix.
5765 
5766    Collective on Mat
5767 
5768    Input Parameters:
5769 +  mat - the matrix
5770 .  numRows - the number of rows to remove
5771 .  rows - the global row indices
5772 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5773 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5774 -  b - optional vector of right hand side, that will be adjusted by provided solution
5775 
5776    Notes:
5777    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5778 
5779    The user can set a value in the diagonal entry (or for the AIJ and
5780    row formats can optionally remove the main diagonal entry from the
5781    nonzero structure as well, by passing 0.0 as the final argument).
5782 
5783    For the parallel case, all processes that share the matrix (i.e.,
5784    those in the communicator used for matrix creation) MUST call this
5785    routine, regardless of whether any rows being zeroed are owned by
5786    them.
5787 
5788    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5789    list only rows local to itself).
5790 
5791    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5792 
5793    Level: intermediate
5794 
5795    Concepts: matrices^zeroing rows
5796 
5797 .seealso: MatZeroRowsIS(), MatZeroRows(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5798           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5799 @*/
5800 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5801 {
5802   PetscErrorCode ierr;
5803 
5804   PetscFunctionBegin;
5805   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5806   PetscValidType(mat,1);
5807   if (numRows) PetscValidIntPointer(rows,3);
5808   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5809   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5810   if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5811   MatCheckPreallocated(mat,1);
5812 
5813   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5814   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5815   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5816 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5817   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5818     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5819   }
5820 #endif
5821   PetscFunctionReturn(0);
5822 }
5823 
5824 /*@
5825    MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
5826    of a set of rows and columns of a matrix.
5827 
5828    Collective on Mat
5829 
5830    Input Parameters:
5831 +  mat - the matrix
5832 .  is - the rows to zero
5833 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5834 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5835 -  b - optional vector of right hand side, that will be adjusted by provided solution
5836 
5837    Notes:
5838    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5839 
5840    The user can set a value in the diagonal entry (or for the AIJ and
5841    row formats can optionally remove the main diagonal entry from the
5842    nonzero structure as well, by passing 0.0 as the final argument).
5843 
5844    For the parallel case, all processes that share the matrix (i.e.,
5845    those in the communicator used for matrix creation) MUST call this
5846    routine, regardless of whether any rows being zeroed are owned by
5847    them.
5848 
5849    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5850    list only rows local to itself).
5851 
5852    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5853 
5854    Level: intermediate
5855 
5856    Concepts: matrices^zeroing rows
5857 
5858 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5859           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRows(), MatZeroRowsColumnsStencil()
5860 @*/
5861 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5862 {
5863   PetscErrorCode ierr;
5864   PetscInt       numRows;
5865   const PetscInt *rows;
5866 
5867   PetscFunctionBegin;
5868   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5869   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5870   PetscValidType(mat,1);
5871   PetscValidType(is,2);
5872   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5873   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5874   ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5875   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5876   PetscFunctionReturn(0);
5877 }
5878 
5879 /*@
5880    MatZeroRows - Zeros all entries (except possibly the main diagonal)
5881    of a set of rows of a matrix.
5882 
5883    Collective on Mat
5884 
5885    Input Parameters:
5886 +  mat - the matrix
5887 .  numRows - the number of rows to remove
5888 .  rows - the global row indices
5889 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5890 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5891 -  b - optional vector of right hand side, that will be adjusted by provided solution
5892 
5893    Notes:
5894    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5895    but does not release memory.  For the dense and block diagonal
5896    formats this does not alter the nonzero structure.
5897 
5898    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5899    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5900    merely zeroed.
5901 
5902    The user can set a value in the diagonal entry (or for the AIJ and
5903    row formats can optionally remove the main diagonal entry from the
5904    nonzero structure as well, by passing 0.0 as the final argument).
5905 
5906    For the parallel case, all processes that share the matrix (i.e.,
5907    those in the communicator used for matrix creation) MUST call this
5908    routine, regardless of whether any rows being zeroed are owned by
5909    them.
5910 
5911    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5912    list only rows local to itself).
5913 
5914    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5915    owns that are to be zeroed. This saves a global synchronization in the implementation.
5916 
5917    Level: intermediate
5918 
5919    Concepts: matrices^zeroing rows
5920 
5921 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5922           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5923 @*/
5924 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5925 {
5926   PetscErrorCode ierr;
5927 
5928   PetscFunctionBegin;
5929   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5930   PetscValidType(mat,1);
5931   if (numRows) PetscValidIntPointer(rows,3);
5932   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5933   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5934   if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5935   MatCheckPreallocated(mat,1);
5936 
5937   ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5938   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5939   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5940 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5941   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5942     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5943   }
5944 #endif
5945   PetscFunctionReturn(0);
5946 }
5947 
5948 /*@
5949    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5950    of a set of rows of a matrix.
5951 
5952    Collective on Mat
5953 
5954    Input Parameters:
5955 +  mat - the matrix
5956 .  is - index set of rows to remove
5957 .  diag - value put in all diagonals of eliminated rows
5958 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5959 -  b - optional vector of right hand side, that will be adjusted by provided solution
5960 
5961    Notes:
5962    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5963    but does not release memory.  For the dense and block diagonal
5964    formats this does not alter the nonzero structure.
5965 
5966    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5967    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5968    merely zeroed.
5969 
5970    The user can set a value in the diagonal entry (or for the AIJ and
5971    row formats can optionally remove the main diagonal entry from the
5972    nonzero structure as well, by passing 0.0 as the final argument).
5973 
5974    For the parallel case, all processes that share the matrix (i.e.,
5975    those in the communicator used for matrix creation) MUST call this
5976    routine, regardless of whether any rows being zeroed are owned by
5977    them.
5978 
5979    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5980    list only rows local to itself).
5981 
5982    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5983    owns that are to be zeroed. This saves a global synchronization in the implementation.
5984 
5985    Level: intermediate
5986 
5987    Concepts: matrices^zeroing rows
5988 
5989 .seealso: MatZeroRows(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5990           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5991 @*/
5992 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5993 {
5994   PetscInt       numRows;
5995   const PetscInt *rows;
5996   PetscErrorCode ierr;
5997 
5998   PetscFunctionBegin;
5999   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6000   PetscValidType(mat,1);
6001   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6002   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6003   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6004   ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6005   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6006   PetscFunctionReturn(0);
6007 }
6008 
6009 /*@
6010    MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
6011    of a set of rows of a matrix. These rows must be local to the process.
6012 
6013    Collective on Mat
6014 
6015    Input Parameters:
6016 +  mat - the matrix
6017 .  numRows - the number of rows to remove
6018 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
6019 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
6020 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6021 -  b - optional vector of right hand side, that will be adjusted by provided solution
6022 
6023    Notes:
6024    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
6025    but does not release memory.  For the dense and block diagonal
6026    formats this does not alter the nonzero structure.
6027 
6028    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6029    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6030    merely zeroed.
6031 
6032    The user can set a value in the diagonal entry (or for the AIJ and
6033    row formats can optionally remove the main diagonal entry from the
6034    nonzero structure as well, by passing 0.0 as the final argument).
6035 
6036    For the parallel case, all processes that share the matrix (i.e.,
6037    those in the communicator used for matrix creation) MUST call this
6038    routine, regardless of whether any rows being zeroed are owned by
6039    them.
6040 
6041    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
6042    list only rows local to itself).
6043 
6044    The grid coordinates are across the entire grid, not just the local portion
6045 
6046    In Fortran idxm and idxn should be declared as
6047 $     MatStencil idxm(4,m)
6048    and the values inserted using
6049 $    idxm(MatStencil_i,1) = i
6050 $    idxm(MatStencil_j,1) = j
6051 $    idxm(MatStencil_k,1) = k
6052 $    idxm(MatStencil_c,1) = c
6053    etc
6054 
6055    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
6056    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
6057    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
6058    DM_BOUNDARY_PERIODIC boundary type.
6059 
6060    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
6061    a single value per point) you can skip filling those indices.
6062 
6063    Level: intermediate
6064 
6065    Concepts: matrices^zeroing rows
6066 
6067 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsl(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6068           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6069 @*/
6070 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
6071 {
6072   PetscInt       dim     = mat->stencil.dim;
6073   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
6074   PetscInt       *dims   = mat->stencil.dims+1;
6075   PetscInt       *starts = mat->stencil.starts;
6076   PetscInt       *dxm    = (PetscInt*) rows;
6077   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
6078   PetscErrorCode ierr;
6079 
6080   PetscFunctionBegin;
6081   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6082   PetscValidType(mat,1);
6083   if (numRows) PetscValidIntPointer(rows,3);
6084 
6085   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
6086   for (i = 0; i < numRows; ++i) {
6087     /* Skip unused dimensions (they are ordered k, j, i, c) */
6088     for (j = 0; j < 3-sdim; ++j) dxm++;
6089     /* Local index in X dir */
6090     tmp = *dxm++ - starts[0];
6091     /* Loop over remaining dimensions */
6092     for (j = 0; j < dim-1; ++j) {
6093       /* If nonlocal, set index to be negative */
6094       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6095       /* Update local index */
6096       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6097     }
6098     /* Skip component slot if necessary */
6099     if (mat->stencil.noc) dxm++;
6100     /* Local row number */
6101     if (tmp >= 0) {
6102       jdxm[numNewRows++] = tmp;
6103     }
6104   }
6105   ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
6106   ierr = PetscFree(jdxm);CHKERRQ(ierr);
6107   PetscFunctionReturn(0);
6108 }
6109 
6110 /*@
6111    MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal)
6112    of a set of rows and columns of a matrix.
6113 
6114    Collective on Mat
6115 
6116    Input Parameters:
6117 +  mat - the matrix
6118 .  numRows - the number of rows/columns to remove
6119 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
6120 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
6121 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6122 -  b - optional vector of right hand side, that will be adjusted by provided solution
6123 
6124    Notes:
6125    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
6126    but does not release memory.  For the dense and block diagonal
6127    formats this does not alter the nonzero structure.
6128 
6129    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6130    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6131    merely zeroed.
6132 
6133    The user can set a value in the diagonal entry (or for the AIJ and
6134    row formats can optionally remove the main diagonal entry from the
6135    nonzero structure as well, by passing 0.0 as the final argument).
6136 
6137    For the parallel case, all processes that share the matrix (i.e.,
6138    those in the communicator used for matrix creation) MUST call this
6139    routine, regardless of whether any rows being zeroed are owned by
6140    them.
6141 
6142    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
6143    list only rows local to itself, but the row/column numbers are given in local numbering).
6144 
6145    The grid coordinates are across the entire grid, not just the local portion
6146 
6147    In Fortran idxm and idxn should be declared as
6148 $     MatStencil idxm(4,m)
6149    and the values inserted using
6150 $    idxm(MatStencil_i,1) = i
6151 $    idxm(MatStencil_j,1) = j
6152 $    idxm(MatStencil_k,1) = k
6153 $    idxm(MatStencil_c,1) = c
6154    etc
6155 
6156    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
6157    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
6158    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
6159    DM_BOUNDARY_PERIODIC boundary type.
6160 
6161    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
6162    a single value per point) you can skip filling those indices.
6163 
6164    Level: intermediate
6165 
6166    Concepts: matrices^zeroing rows
6167 
6168 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6169           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRows()
6170 @*/
6171 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
6172 {
6173   PetscInt       dim     = mat->stencil.dim;
6174   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
6175   PetscInt       *dims   = mat->stencil.dims+1;
6176   PetscInt       *starts = mat->stencil.starts;
6177   PetscInt       *dxm    = (PetscInt*) rows;
6178   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
6179   PetscErrorCode ierr;
6180 
6181   PetscFunctionBegin;
6182   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6183   PetscValidType(mat,1);
6184   if (numRows) PetscValidIntPointer(rows,3);
6185 
6186   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
6187   for (i = 0; i < numRows; ++i) {
6188     /* Skip unused dimensions (they are ordered k, j, i, c) */
6189     for (j = 0; j < 3-sdim; ++j) dxm++;
6190     /* Local index in X dir */
6191     tmp = *dxm++ - starts[0];
6192     /* Loop over remaining dimensions */
6193     for (j = 0; j < dim-1; ++j) {
6194       /* If nonlocal, set index to be negative */
6195       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6196       /* Update local index */
6197       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6198     }
6199     /* Skip component slot if necessary */
6200     if (mat->stencil.noc) dxm++;
6201     /* Local row number */
6202     if (tmp >= 0) {
6203       jdxm[numNewRows++] = tmp;
6204     }
6205   }
6206   ierr = MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
6207   ierr = PetscFree(jdxm);CHKERRQ(ierr);
6208   PetscFunctionReturn(0);
6209 }
6210 
6211 /*@C
6212    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
6213    of a set of rows of a matrix; using local numbering of rows.
6214 
6215    Collective on Mat
6216 
6217    Input Parameters:
6218 +  mat - the matrix
6219 .  numRows - the number of rows to remove
6220 .  rows - the global row indices
6221 .  diag - value put in all diagonals of eliminated rows
6222 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6223 -  b - optional vector of right hand side, that will be adjusted by provided solution
6224 
6225    Notes:
6226    Before calling MatZeroRowsLocal(), the user must first set the
6227    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6228 
6229    For the AIJ matrix formats this removes the old nonzero structure,
6230    but does not release memory.  For the dense and block diagonal
6231    formats this does not alter the nonzero structure.
6232 
6233    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6234    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6235    merely zeroed.
6236 
6237    The user can set a value in the diagonal entry (or for the AIJ and
6238    row formats can optionally remove the main diagonal entry from the
6239    nonzero structure as well, by passing 0.0 as the final argument).
6240 
6241    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6242    owns that are to be zeroed. This saves a global synchronization in the implementation.
6243 
6244    Level: intermediate
6245 
6246    Concepts: matrices^zeroing
6247 
6248 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRows(), MatSetOption(),
6249           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6250 @*/
6251 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6252 {
6253   PetscErrorCode ierr;
6254 
6255   PetscFunctionBegin;
6256   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6257   PetscValidType(mat,1);
6258   if (numRows) PetscValidIntPointer(rows,3);
6259   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6260   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6261   MatCheckPreallocated(mat,1);
6262 
6263   if (mat->ops->zerorowslocal) {
6264     ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6265   } else {
6266     IS             is, newis;
6267     const PetscInt *newRows;
6268 
6269     if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6270     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6271     ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr);
6272     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6273     ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6274     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6275     ierr = ISDestroy(&newis);CHKERRQ(ierr);
6276     ierr = ISDestroy(&is);CHKERRQ(ierr);
6277   }
6278   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6279 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
6280   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
6281     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
6282   }
6283 #endif
6284   PetscFunctionReturn(0);
6285 }
6286 
6287 /*@
6288    MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
6289    of a set of rows of a matrix; using local numbering of rows.
6290 
6291    Collective on Mat
6292 
6293    Input Parameters:
6294 +  mat - the matrix
6295 .  is - index set of rows to remove
6296 .  diag - value put in all diagonals of eliminated rows
6297 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6298 -  b - optional vector of right hand side, that will be adjusted by provided solution
6299 
6300    Notes:
6301    Before calling MatZeroRowsLocalIS(), the user must first set the
6302    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6303 
6304    For the AIJ matrix formats this removes the old nonzero structure,
6305    but does not release memory.  For the dense and block diagonal
6306    formats this does not alter the nonzero structure.
6307 
6308    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6309    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6310    merely zeroed.
6311 
6312    The user can set a value in the diagonal entry (or for the AIJ and
6313    row formats can optionally remove the main diagonal entry from the
6314    nonzero structure as well, by passing 0.0 as the final argument).
6315 
6316    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6317    owns that are to be zeroed. This saves a global synchronization in the implementation.
6318 
6319    Level: intermediate
6320 
6321    Concepts: matrices^zeroing
6322 
6323 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6324           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6325 @*/
6326 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6327 {
6328   PetscErrorCode ierr;
6329   PetscInt       numRows;
6330   const PetscInt *rows;
6331 
6332   PetscFunctionBegin;
6333   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6334   PetscValidType(mat,1);
6335   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6336   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6337   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6338   MatCheckPreallocated(mat,1);
6339 
6340   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6341   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6342   ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6343   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6344   PetscFunctionReturn(0);
6345 }
6346 
6347 /*@
6348    MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
6349    of a set of rows and columns of a matrix; using local numbering of rows.
6350 
6351    Collective on Mat
6352 
6353    Input Parameters:
6354 +  mat - the matrix
6355 .  numRows - the number of rows to remove
6356 .  rows - the global row indices
6357 .  diag - value put in all diagonals of eliminated rows
6358 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6359 -  b - optional vector of right hand side, that will be adjusted by provided solution
6360 
6361    Notes:
6362    Before calling MatZeroRowsColumnsLocal(), the user must first set the
6363    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6364 
6365    The user can set a value in the diagonal entry (or for the AIJ and
6366    row formats can optionally remove the main diagonal entry from the
6367    nonzero structure as well, by passing 0.0 as the final argument).
6368 
6369    Level: intermediate
6370 
6371    Concepts: matrices^zeroing
6372 
6373 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6374           MatZeroRows(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6375 @*/
6376 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6377 {
6378   PetscErrorCode ierr;
6379   IS             is, newis;
6380   const PetscInt *newRows;
6381 
6382   PetscFunctionBegin;
6383   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6384   PetscValidType(mat,1);
6385   if (numRows) PetscValidIntPointer(rows,3);
6386   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6387   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6388   MatCheckPreallocated(mat,1);
6389 
6390   if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6391   ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6392   ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr);
6393   ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6394   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6395   ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6396   ierr = ISDestroy(&newis);CHKERRQ(ierr);
6397   ierr = ISDestroy(&is);CHKERRQ(ierr);
6398   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6399 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
6400   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
6401     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
6402   }
6403 #endif
6404   PetscFunctionReturn(0);
6405 }
6406 
6407 /*@
6408    MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
6409    of a set of rows and columns of a matrix; using local numbering of rows.
6410 
6411    Collective on Mat
6412 
6413    Input Parameters:
6414 +  mat - the matrix
6415 .  is - index set of rows to remove
6416 .  diag - value put in all diagonals of eliminated rows
6417 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6418 -  b - optional vector of right hand side, that will be adjusted by provided solution
6419 
6420    Notes:
6421    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
6422    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6423 
6424    The user can set a value in the diagonal entry (or for the AIJ and
6425    row formats can optionally remove the main diagonal entry from the
6426    nonzero structure as well, by passing 0.0 as the final argument).
6427 
6428    Level: intermediate
6429 
6430    Concepts: matrices^zeroing
6431 
6432 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6433           MatZeroRowsColumnsLocal(), MatZeroRows(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6434 @*/
6435 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6436 {
6437   PetscErrorCode ierr;
6438   PetscInt       numRows;
6439   const PetscInt *rows;
6440 
6441   PetscFunctionBegin;
6442   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6443   PetscValidType(mat,1);
6444   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6445   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6446   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6447   MatCheckPreallocated(mat,1);
6448 
6449   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6450   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6451   ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6452   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6453   PetscFunctionReturn(0);
6454 }
6455 
6456 /*@C
6457    MatGetSize - Returns the numbers of rows and columns in a matrix.
6458 
6459    Not Collective
6460 
6461    Input Parameter:
6462 .  mat - the matrix
6463 
6464    Output Parameters:
6465 +  m - the number of global rows
6466 -  n - the number of global columns
6467 
6468    Note: both output parameters can be NULL on input.
6469 
6470    Level: beginner
6471 
6472    Concepts: matrices^size
6473 
6474 .seealso: MatGetLocalSize()
6475 @*/
6476 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
6477 {
6478   PetscFunctionBegin;
6479   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6480   if (m) *m = mat->rmap->N;
6481   if (n) *n = mat->cmap->N;
6482   PetscFunctionReturn(0);
6483 }
6484 
6485 /*@C
6486    MatGetLocalSize - Returns the number of rows and columns in a matrix
6487    stored locally.  This information may be implementation dependent, so
6488    use with care.
6489 
6490    Not Collective
6491 
6492    Input Parameters:
6493 .  mat - the matrix
6494 
6495    Output Parameters:
6496 +  m - the number of local rows
6497 -  n - the number of local columns
6498 
6499    Note: both output parameters can be NULL on input.
6500 
6501    Level: beginner
6502 
6503    Concepts: matrices^local size
6504 
6505 .seealso: MatGetSize()
6506 @*/
6507 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
6508 {
6509   PetscFunctionBegin;
6510   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6511   if (m) PetscValidIntPointer(m,2);
6512   if (n) PetscValidIntPointer(n,3);
6513   if (m) *m = mat->rmap->n;
6514   if (n) *n = mat->cmap->n;
6515   PetscFunctionReturn(0);
6516 }
6517 
6518 /*@C
6519    MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6520    this processor. (The columns of the "diagonal block")
6521 
6522    Not Collective, unless matrix has not been allocated, then collective on Mat
6523 
6524    Input Parameters:
6525 .  mat - the matrix
6526 
6527    Output Parameters:
6528 +  m - the global index of the first local column
6529 -  n - one more than the global index of the last local column
6530 
6531    Notes:
6532     both output parameters can be NULL on input.
6533 
6534    Level: developer
6535 
6536    Concepts: matrices^column ownership
6537 
6538 .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
6539 
6540 @*/
6541 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
6542 {
6543   PetscFunctionBegin;
6544   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6545   PetscValidType(mat,1);
6546   if (m) PetscValidIntPointer(m,2);
6547   if (n) PetscValidIntPointer(n,3);
6548   MatCheckPreallocated(mat,1);
6549   if (m) *m = mat->cmap->rstart;
6550   if (n) *n = mat->cmap->rend;
6551   PetscFunctionReturn(0);
6552 }
6553 
6554 /*@C
6555    MatGetOwnershipRange - Returns the range of matrix rows owned by
6556    this processor, assuming that the matrix is laid out with the first
6557    n1 rows on the first processor, the next n2 rows on the second, etc.
6558    For certain parallel layouts this range may not be well defined.
6559 
6560    Not Collective
6561 
6562    Input Parameters:
6563 .  mat - the matrix
6564 
6565    Output Parameters:
6566 +  m - the global index of the first local row
6567 -  n - one more than the global index of the last local row
6568 
6569    Note: Both output parameters can be NULL on input.
6570 $  This function requires that the matrix be preallocated. If you have not preallocated, consider using
6571 $    PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
6572 $  and then MPI_Scan() to calculate prefix sums of the local sizes.
6573 
6574    Level: beginner
6575 
6576    Concepts: matrices^row ownership
6577 
6578 .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()
6579 
6580 @*/
6581 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6582 {
6583   PetscFunctionBegin;
6584   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6585   PetscValidType(mat,1);
6586   if (m) PetscValidIntPointer(m,2);
6587   if (n) PetscValidIntPointer(n,3);
6588   MatCheckPreallocated(mat,1);
6589   if (m) *m = mat->rmap->rstart;
6590   if (n) *n = mat->rmap->rend;
6591   PetscFunctionReturn(0);
6592 }
6593 
6594 /*@C
6595    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6596    each process
6597 
6598    Not Collective, unless matrix has not been allocated, then collective on Mat
6599 
6600    Input Parameters:
6601 .  mat - the matrix
6602 
6603    Output Parameters:
6604 .  ranges - start of each processors portion plus one more than the total length at the end
6605 
6606    Level: beginner
6607 
6608    Concepts: matrices^row ownership
6609 
6610 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
6611 
6612 @*/
6613 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6614 {
6615   PetscErrorCode ierr;
6616 
6617   PetscFunctionBegin;
6618   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6619   PetscValidType(mat,1);
6620   MatCheckPreallocated(mat,1);
6621   ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr);
6622   PetscFunctionReturn(0);
6623 }
6624 
6625 /*@C
6626    MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6627    this processor. (The columns of the "diagonal blocks" for each process)
6628 
6629    Not Collective, unless matrix has not been allocated, then collective on Mat
6630 
6631    Input Parameters:
6632 .  mat - the matrix
6633 
6634    Output Parameters:
6635 .  ranges - start of each processors portion plus one more then the total length at the end
6636 
6637    Level: beginner
6638 
6639    Concepts: matrices^column ownership
6640 
6641 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
6642 
6643 @*/
6644 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6645 {
6646   PetscErrorCode ierr;
6647 
6648   PetscFunctionBegin;
6649   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6650   PetscValidType(mat,1);
6651   MatCheckPreallocated(mat,1);
6652   ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr);
6653   PetscFunctionReturn(0);
6654 }
6655 
6656 /*@C
6657    MatGetOwnershipIS - Get row and column ownership as index sets
6658 
6659    Not Collective
6660 
6661    Input Arguments:
6662 .  A - matrix of type Elemental
6663 
6664    Output Arguments:
6665 +  rows - rows in which this process owns elements
6666 .  cols - columns in which this process owns elements
6667 
6668    Level: intermediate
6669 
6670 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL
6671 @*/
6672 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6673 {
6674   PetscErrorCode ierr,(*f)(Mat,IS*,IS*);
6675 
6676   PetscFunctionBegin;
6677   MatCheckPreallocated(A,1);
6678   ierr = PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);CHKERRQ(ierr);
6679   if (f) {
6680     ierr = (*f)(A,rows,cols);CHKERRQ(ierr);
6681   } else {   /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6682     if (rows) {ierr = ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);CHKERRQ(ierr);}
6683     if (cols) {ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);CHKERRQ(ierr);}
6684   }
6685   PetscFunctionReturn(0);
6686 }
6687 
6688 /*@C
6689    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6690    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6691    to complete the factorization.
6692 
6693    Collective on Mat
6694 
6695    Input Parameters:
6696 +  mat - the matrix
6697 .  row - row permutation
6698 .  column - column permutation
6699 -  info - structure containing
6700 $      levels - number of levels of fill.
6701 $      expected fill - as ratio of original fill.
6702 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6703                 missing diagonal entries)
6704 
6705    Output Parameters:
6706 .  fact - new matrix that has been symbolically factored
6707 
6708    Notes:
6709     See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
6710 
6711    Most users should employ the simplified KSP interface for linear solvers
6712    instead of working directly with matrix algebra routines such as this.
6713    See, e.g., KSPCreate().
6714 
6715    Level: developer
6716 
6717   Concepts: matrices^symbolic LU factorization
6718   Concepts: matrices^factorization
6719   Concepts: LU^symbolic factorization
6720 
6721 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6722           MatGetOrdering(), MatFactorInfo
6723 
6724     Note: this uses the definition of level of fill as in Y. Saad, 2003
6725 
6726     Developer Note: fortran interface is not autogenerated as the f90
6727     interface defintion cannot be generated correctly [due to MatFactorInfo]
6728 
6729    References:
6730      Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003
6731 @*/
6732 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6733 {
6734   PetscErrorCode ierr;
6735 
6736   PetscFunctionBegin;
6737   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6738   PetscValidType(mat,1);
6739   PetscValidHeaderSpecific(row,IS_CLASSID,2);
6740   PetscValidHeaderSpecific(col,IS_CLASSID,3);
6741   PetscValidPointer(info,4);
6742   PetscValidPointer(fact,5);
6743   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6744   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6745   if (!(fact)->ops->ilufactorsymbolic) {
6746     MatSolverType spackage;
6747     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
6748     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6749   }
6750   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6751   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6752   MatCheckPreallocated(mat,2);
6753 
6754   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6755   ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
6756   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6757   PetscFunctionReturn(0);
6758 }
6759 
6760 /*@C
6761    MatICCFactorSymbolic - Performs symbolic incomplete
6762    Cholesky factorization for a symmetric matrix.  Use
6763    MatCholeskyFactorNumeric() to complete the factorization.
6764 
6765    Collective on Mat
6766 
6767    Input Parameters:
6768 +  mat - the matrix
6769 .  perm - row and column permutation
6770 -  info - structure containing
6771 $      levels - number of levels of fill.
6772 $      expected fill - as ratio of original fill.
6773 
6774    Output Parameter:
6775 .  fact - the factored matrix
6776 
6777    Notes:
6778    Most users should employ the KSP interface for linear solvers
6779    instead of working directly with matrix algebra routines such as this.
6780    See, e.g., KSPCreate().
6781 
6782    Level: developer
6783 
6784   Concepts: matrices^symbolic incomplete Cholesky factorization
6785   Concepts: matrices^factorization
6786   Concepts: Cholsky^symbolic factorization
6787 
6788 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
6789 
6790     Note: this uses the definition of level of fill as in Y. Saad, 2003
6791 
6792     Developer Note: fortran interface is not autogenerated as the f90
6793     interface defintion cannot be generated correctly [due to MatFactorInfo]
6794 
6795    References:
6796      Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003
6797 @*/
6798 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6799 {
6800   PetscErrorCode ierr;
6801 
6802   PetscFunctionBegin;
6803   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6804   PetscValidType(mat,1);
6805   PetscValidHeaderSpecific(perm,IS_CLASSID,2);
6806   PetscValidPointer(info,3);
6807   PetscValidPointer(fact,4);
6808   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6809   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6810   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6811   if (!(fact)->ops->iccfactorsymbolic) {
6812     MatSolverType spackage;
6813     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
6814     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6815   }
6816   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6817   MatCheckPreallocated(mat,2);
6818 
6819   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6820   ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
6821   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6822   PetscFunctionReturn(0);
6823 }
6824 
6825 /*@C
6826    MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat
6827    points to an array of valid matrices, they may be reused to store the new
6828    submatrices.
6829 
6830    Collective on Mat
6831 
6832    Input Parameters:
6833 +  mat - the matrix
6834 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6835 .  irow, icol - index sets of rows and columns to extract
6836 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6837 
6838    Output Parameter:
6839 .  submat - the array of submatrices
6840 
6841    Notes:
6842    MatCreateSubMatrices() can extract ONLY sequential submatrices
6843    (from both sequential and parallel matrices). Use MatCreateSubMatrix()
6844    to extract a parallel submatrix.
6845 
6846    Some matrix types place restrictions on the row and column
6847    indices, such as that they be sorted or that they be equal to each other.
6848 
6849    The index sets may not have duplicate entries.
6850 
6851    When extracting submatrices from a parallel matrix, each processor can
6852    form a different submatrix by setting the rows and columns of its
6853    individual index sets according to the local submatrix desired.
6854 
6855    When finished using the submatrices, the user should destroy
6856    them with MatDestroySubMatrices().
6857 
6858    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6859    original matrix has not changed from that last call to MatCreateSubMatrices().
6860 
6861    This routine creates the matrices in submat; you should NOT create them before
6862    calling it. It also allocates the array of matrix pointers submat.
6863 
6864    For BAIJ matrices the index sets must respect the block structure, that is if they
6865    request one row/column in a block, they must request all rows/columns that are in
6866    that block. For example, if the block size is 2 you cannot request just row 0 and
6867    column 0.
6868 
6869    Fortran Note:
6870    The Fortran interface is slightly different from that given below; it
6871    requires one to pass in  as submat a Mat (integer) array of size at least n+1.
6872 
6873    Level: advanced
6874 
6875    Concepts: matrices^accessing submatrices
6876    Concepts: submatrices
6877 
6878 .seealso: MatDestroySubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6879 @*/
6880 PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6881 {
6882   PetscErrorCode ierr;
6883   PetscInt       i;
6884   PetscBool      eq;
6885 
6886   PetscFunctionBegin;
6887   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6888   PetscValidType(mat,1);
6889   if (n) {
6890     PetscValidPointer(irow,3);
6891     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6892     PetscValidPointer(icol,4);
6893     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6894   }
6895   PetscValidPointer(submat,6);
6896   if (n && scall == MAT_REUSE_MATRIX) {
6897     PetscValidPointer(*submat,6);
6898     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6899   }
6900   if (!mat->ops->createsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6901   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6902   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6903   MatCheckPreallocated(mat,1);
6904 
6905   ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6906   ierr = (*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6907   ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6908   for (i=0; i<n; i++) {
6909     (*submat)[i]->factortype = MAT_FACTOR_NONE;  /* in case in place factorization was previously done on submatrix */
6910     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6911       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6912       if (eq) {
6913         if (mat->symmetric) {
6914           ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6915         } else if (mat->hermitian) {
6916           ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6917         } else if (mat->structurally_symmetric) {
6918           ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6919         }
6920       }
6921     }
6922   }
6923   PetscFunctionReturn(0);
6924 }
6925 
6926 /*@C
6927    MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms).
6928 
6929    Collective on Mat
6930 
6931    Input Parameters:
6932 +  mat - the matrix
6933 .  n   - the number of submatrixes to be extracted
6934 .  irow, icol - index sets of rows and columns to extract
6935 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6936 
6937    Output Parameter:
6938 .  submat - the array of submatrices
6939 
6940    Level: advanced
6941 
6942    Concepts: matrices^accessing submatrices
6943    Concepts: submatrices
6944 
6945 .seealso: MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6946 @*/
6947 PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6948 {
6949   PetscErrorCode ierr;
6950   PetscInt       i;
6951   PetscBool      eq;
6952 
6953   PetscFunctionBegin;
6954   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6955   PetscValidType(mat,1);
6956   if (n) {
6957     PetscValidPointer(irow,3);
6958     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6959     PetscValidPointer(icol,4);
6960     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6961   }
6962   PetscValidPointer(submat,6);
6963   if (n && scall == MAT_REUSE_MATRIX) {
6964     PetscValidPointer(*submat,6);
6965     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6966   }
6967   if (!mat->ops->createsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6968   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6969   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6970   MatCheckPreallocated(mat,1);
6971 
6972   ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6973   ierr = (*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6974   ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6975   for (i=0; i<n; i++) {
6976     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6977       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6978       if (eq) {
6979         if (mat->symmetric) {
6980           ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6981         } else if (mat->hermitian) {
6982           ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6983         } else if (mat->structurally_symmetric) {
6984           ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6985         }
6986       }
6987     }
6988   }
6989   PetscFunctionReturn(0);
6990 }
6991 
6992 /*@C
6993    MatDestroyMatrices - Destroys an array of matrices.
6994 
6995    Collective on Mat
6996 
6997    Input Parameters:
6998 +  n - the number of local matrices
6999 -  mat - the matrices (note that this is a pointer to the array of matrices)
7000 
7001    Level: advanced
7002 
7003     Notes:
7004     Frees not only the matrices, but also the array that contains the matrices
7005            In Fortran will not free the array.
7006 
7007 .seealso: MatCreateSubMatrices() MatDestroySubMatrices()
7008 @*/
7009 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
7010 {
7011   PetscErrorCode ierr;
7012   PetscInt       i;
7013 
7014   PetscFunctionBegin;
7015   if (!*mat) PetscFunctionReturn(0);
7016   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
7017   PetscValidPointer(mat,2);
7018 
7019   for (i=0; i<n; i++) {
7020     ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr);
7021   }
7022 
7023   /* memory is allocated even if n = 0 */
7024   ierr = PetscFree(*mat);CHKERRQ(ierr);
7025   PetscFunctionReturn(0);
7026 }
7027 
7028 /*@C
7029    MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices().
7030 
7031    Collective on Mat
7032 
7033    Input Parameters:
7034 +  n - the number of local matrices
7035 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
7036                        sequence of MatCreateSubMatrices())
7037 
7038    Level: advanced
7039 
7040     Notes:
7041     Frees not only the matrices, but also the array that contains the matrices
7042            In Fortran will not free the array.
7043 
7044 .seealso: MatCreateSubMatrices()
7045 @*/
7046 PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[])
7047 {
7048   PetscErrorCode ierr;
7049   Mat            mat0;
7050 
7051   PetscFunctionBegin;
7052   if (!*mat) PetscFunctionReturn(0);
7053   /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */
7054   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
7055   PetscValidPointer(mat,2);
7056 
7057   mat0 = (*mat)[0];
7058   if (mat0 && mat0->ops->destroysubmatrices) {
7059     ierr = (mat0->ops->destroysubmatrices)(n,mat);CHKERRQ(ierr);
7060   } else {
7061     ierr = MatDestroyMatrices(n,mat);CHKERRQ(ierr);
7062   }
7063   PetscFunctionReturn(0);
7064 }
7065 
7066 /*@C
7067    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
7068 
7069    Collective on Mat
7070 
7071    Input Parameters:
7072 .  mat - the matrix
7073 
7074    Output Parameter:
7075 .  matstruct - the sequential matrix with the nonzero structure of mat
7076 
7077   Level: intermediate
7078 
7079 .seealso: MatDestroySeqNonzeroStructure(), MatCreateSubMatrices(), MatDestroyMatrices()
7080 @*/
7081 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
7082 {
7083   PetscErrorCode ierr;
7084 
7085   PetscFunctionBegin;
7086   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7087   PetscValidPointer(matstruct,2);
7088 
7089   PetscValidType(mat,1);
7090   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7091   MatCheckPreallocated(mat,1);
7092 
7093   if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
7094   ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
7095   ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr);
7096   ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
7097   PetscFunctionReturn(0);
7098 }
7099 
7100 /*@C
7101    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
7102 
7103    Collective on Mat
7104 
7105    Input Parameters:
7106 .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
7107                        sequence of MatGetSequentialNonzeroStructure())
7108 
7109    Level: advanced
7110 
7111     Notes:
7112     Frees not only the matrices, but also the array that contains the matrices
7113 
7114 .seealso: MatGetSeqNonzeroStructure()
7115 @*/
7116 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
7117 {
7118   PetscErrorCode ierr;
7119 
7120   PetscFunctionBegin;
7121   PetscValidPointer(mat,1);
7122   ierr = MatDestroy(mat);CHKERRQ(ierr);
7123   PetscFunctionReturn(0);
7124 }
7125 
7126 /*@
7127    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
7128    replaces the index sets by larger ones that represent submatrices with
7129    additional overlap.
7130 
7131    Collective on Mat
7132 
7133    Input Parameters:
7134 +  mat - the matrix
7135 .  n   - the number of index sets
7136 .  is  - the array of index sets (these index sets will changed during the call)
7137 -  ov  - the additional overlap requested
7138 
7139    Options Database:
7140 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
7141 
7142    Level: developer
7143 
7144    Concepts: overlap
7145    Concepts: ASM^computing overlap
7146 
7147 .seealso: MatCreateSubMatrices()
7148 @*/
7149 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
7150 {
7151   PetscErrorCode ierr;
7152 
7153   PetscFunctionBegin;
7154   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7155   PetscValidType(mat,1);
7156   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
7157   if (n) {
7158     PetscValidPointer(is,3);
7159     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
7160   }
7161   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7162   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7163   MatCheckPreallocated(mat,1);
7164 
7165   if (!ov) PetscFunctionReturn(0);
7166   if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7167   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7168   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
7169   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7170   PetscFunctionReturn(0);
7171 }
7172 
7173 
7174 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt);
7175 
7176 /*@
7177    MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across
7178    a sub communicator, replaces the index sets by larger ones that represent submatrices with
7179    additional overlap.
7180 
7181    Collective on Mat
7182 
7183    Input Parameters:
7184 +  mat - the matrix
7185 .  n   - the number of index sets
7186 .  is  - the array of index sets (these index sets will changed during the call)
7187 -  ov  - the additional overlap requested
7188 
7189    Options Database:
7190 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
7191 
7192    Level: developer
7193 
7194    Concepts: overlap
7195    Concepts: ASM^computing overlap
7196 
7197 .seealso: MatCreateSubMatrices()
7198 @*/
7199 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov)
7200 {
7201   PetscInt       i;
7202   PetscErrorCode ierr;
7203 
7204   PetscFunctionBegin;
7205   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7206   PetscValidType(mat,1);
7207   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
7208   if (n) {
7209     PetscValidPointer(is,3);
7210     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
7211   }
7212   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7213   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7214   MatCheckPreallocated(mat,1);
7215   if (!ov) PetscFunctionReturn(0);
7216   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7217   for(i=0; i<n; i++){
7218 	ierr =  MatIncreaseOverlapSplit_Single(mat,&is[i],ov);CHKERRQ(ierr);
7219   }
7220   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7221   PetscFunctionReturn(0);
7222 }
7223 
7224 
7225 
7226 
7227 /*@
7228    MatGetBlockSize - Returns the matrix block size.
7229 
7230    Not Collective
7231 
7232    Input Parameter:
7233 .  mat - the matrix
7234 
7235    Output Parameter:
7236 .  bs - block size
7237 
7238    Notes:
7239     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7240 
7241    If the block size has not been set yet this routine returns 1.
7242 
7243    Level: intermediate
7244 
7245    Concepts: matrices^block size
7246 
7247 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
7248 @*/
7249 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
7250 {
7251   PetscFunctionBegin;
7252   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7253   PetscValidIntPointer(bs,2);
7254   *bs = PetscAbs(mat->rmap->bs);
7255   PetscFunctionReturn(0);
7256 }
7257 
7258 /*@
7259    MatGetBlockSizes - Returns the matrix block row and column sizes.
7260 
7261    Not Collective
7262 
7263    Input Parameter:
7264 .  mat - the matrix
7265 
7266    Output Parameter:
7267 .  rbs - row block size
7268 .  cbs - column block size
7269 
7270    Notes:
7271     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7272     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7273 
7274    If a block size has not been set yet this routine returns 1.
7275 
7276    Level: intermediate
7277 
7278    Concepts: matrices^block size
7279 
7280 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes()
7281 @*/
7282 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
7283 {
7284   PetscFunctionBegin;
7285   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7286   if (rbs) PetscValidIntPointer(rbs,2);
7287   if (cbs) PetscValidIntPointer(cbs,3);
7288   if (rbs) *rbs = PetscAbs(mat->rmap->bs);
7289   if (cbs) *cbs = PetscAbs(mat->cmap->bs);
7290   PetscFunctionReturn(0);
7291 }
7292 
7293 /*@
7294    MatSetBlockSize - Sets the matrix block size.
7295 
7296    Logically Collective on Mat
7297 
7298    Input Parameters:
7299 +  mat - the matrix
7300 -  bs - block size
7301 
7302    Notes:
7303     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7304     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later.
7305 
7306     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size
7307     is compatible with the matrix local sizes.
7308 
7309    Level: intermediate
7310 
7311    Concepts: matrices^block size
7312 
7313 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes()
7314 @*/
7315 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
7316 {
7317   PetscErrorCode ierr;
7318 
7319   PetscFunctionBegin;
7320   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7321   PetscValidLogicalCollectiveInt(mat,bs,2);
7322   ierr = MatSetBlockSizes(mat,bs,bs);CHKERRQ(ierr);
7323   PetscFunctionReturn(0);
7324 }
7325 
7326 /*@
7327    MatSetVariableBlockSizes - Sets a diagonal blocks of the matrix that need not be of the same size
7328 
7329    Logically Collective on Mat
7330 
7331    Input Parameters:
7332 +  mat - the matrix
7333 .  nblocks - the number of blocks on this process
7334 -  bsizes - the block sizes
7335 
7336    Notes:
7337     Currently used by PCVPBJACOBI for SeqAIJ matrices
7338 
7339    Level: intermediate
7340 
7341    Concepts: matrices^block size
7342 
7343 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatGetVariableBlockSizes()
7344 @*/
7345 PetscErrorCode MatSetVariableBlockSizes(Mat mat,PetscInt nblocks,PetscInt *bsizes)
7346 {
7347   PetscErrorCode ierr;
7348   PetscInt       i,ncnt = 0, nlocal;
7349 
7350   PetscFunctionBegin;
7351   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7352   if (nblocks < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number of local blocks must be great than or equal to zero");
7353   ierr = MatGetLocalSize(mat,&nlocal,NULL);CHKERRQ(ierr);
7354   for (i=0; i<nblocks; i++) ncnt += bsizes[i];
7355   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);
7356   ierr = PetscFree(mat->bsizes);CHKERRQ(ierr);
7357   mat->nblocks = nblocks;
7358   ierr = PetscMalloc1(nblocks,&mat->bsizes);CHKERRQ(ierr);
7359   ierr = PetscMemcpy(mat->bsizes,bsizes,nblocks*sizeof(PetscInt));CHKERRQ(ierr);
7360   PetscFunctionReturn(0);
7361 }
7362 
7363 /*@C
7364    MatGetVariableBlockSizes - Gets a diagonal blocks of the matrix that need not be of the same size
7365 
7366    Logically Collective on Mat
7367 
7368    Input Parameters:
7369 .  mat - the matrix
7370 
7371    Output Parameters:
7372 +  nblocks - the number of blocks on this process
7373 -  bsizes - the block sizes
7374 
7375    Notes: Currently not supported from Fortran
7376 
7377    Level: intermediate
7378 
7379    Concepts: matrices^block size
7380 
7381 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatSetVariableBlockSizes()
7382 @*/
7383 PetscErrorCode MatGetVariableBlockSizes(Mat mat,PetscInt *nblocks,const PetscInt **bsizes)
7384 {
7385   PetscFunctionBegin;
7386   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7387   *nblocks = mat->nblocks;
7388   *bsizes  = mat->bsizes;
7389   PetscFunctionReturn(0);
7390 }
7391 
7392 /*@
7393    MatSetBlockSizes - Sets the matrix block row and column sizes.
7394 
7395    Logically Collective on Mat
7396 
7397    Input Parameters:
7398 +  mat - the matrix
7399 -  rbs - row block size
7400 -  cbs - column block size
7401 
7402    Notes:
7403     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7404     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7405     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later
7406 
7407     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes
7408     are compatible with the matrix local sizes.
7409 
7410     The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs().
7411 
7412    Level: intermediate
7413 
7414    Concepts: matrices^block size
7415 
7416 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes()
7417 @*/
7418 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
7419 {
7420   PetscErrorCode ierr;
7421 
7422   PetscFunctionBegin;
7423   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7424   PetscValidLogicalCollectiveInt(mat,rbs,2);
7425   PetscValidLogicalCollectiveInt(mat,cbs,3);
7426   if (mat->ops->setblocksizes) {
7427     ierr = (*mat->ops->setblocksizes)(mat,rbs,cbs);CHKERRQ(ierr);
7428   }
7429   if (mat->rmap->refcnt) {
7430     ISLocalToGlobalMapping l2g = NULL;
7431     PetscLayout            nmap = NULL;
7432 
7433     ierr = PetscLayoutDuplicate(mat->rmap,&nmap);CHKERRQ(ierr);
7434     if (mat->rmap->mapping) {
7435       ierr = ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g);CHKERRQ(ierr);
7436     }
7437     ierr = PetscLayoutDestroy(&mat->rmap);CHKERRQ(ierr);
7438     mat->rmap = nmap;
7439     mat->rmap->mapping = l2g;
7440   }
7441   if (mat->cmap->refcnt) {
7442     ISLocalToGlobalMapping l2g = NULL;
7443     PetscLayout            nmap = NULL;
7444 
7445     ierr = PetscLayoutDuplicate(mat->cmap,&nmap);CHKERRQ(ierr);
7446     if (mat->cmap->mapping) {
7447       ierr = ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g);CHKERRQ(ierr);
7448     }
7449     ierr = PetscLayoutDestroy(&mat->cmap);CHKERRQ(ierr);
7450     mat->cmap = nmap;
7451     mat->cmap->mapping = l2g;
7452   }
7453   ierr = PetscLayoutSetBlockSize(mat->rmap,rbs);CHKERRQ(ierr);
7454   ierr = PetscLayoutSetBlockSize(mat->cmap,cbs);CHKERRQ(ierr);
7455   PetscFunctionReturn(0);
7456 }
7457 
7458 /*@
7459    MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices
7460 
7461    Logically Collective on Mat
7462 
7463    Input Parameters:
7464 +  mat - the matrix
7465 .  fromRow - matrix from which to copy row block size
7466 -  fromCol - matrix from which to copy column block size (can be same as fromRow)
7467 
7468    Level: developer
7469 
7470    Concepts: matrices^block size
7471 
7472 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes()
7473 @*/
7474 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)
7475 {
7476   PetscErrorCode ierr;
7477 
7478   PetscFunctionBegin;
7479   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7480   PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2);
7481   PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3);
7482   if (fromRow->rmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);CHKERRQ(ierr);}
7483   if (fromCol->cmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);CHKERRQ(ierr);}
7484   PetscFunctionReturn(0);
7485 }
7486 
7487 /*@
7488    MatResidual - Default routine to calculate the residual.
7489 
7490    Collective on Mat and Vec
7491 
7492    Input Parameters:
7493 +  mat - the matrix
7494 .  b   - the right-hand-side
7495 -  x   - the approximate solution
7496 
7497    Output Parameter:
7498 .  r - location to store the residual
7499 
7500    Level: developer
7501 
7502 .keywords: MG, default, multigrid, residual
7503 
7504 .seealso: PCMGSetResidual()
7505 @*/
7506 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r)
7507 {
7508   PetscErrorCode ierr;
7509 
7510   PetscFunctionBegin;
7511   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7512   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
7513   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
7514   PetscValidHeaderSpecific(r,VEC_CLASSID,4);
7515   PetscValidType(mat,1);
7516   MatCheckPreallocated(mat,1);
7517   ierr  = PetscLogEventBegin(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7518   if (!mat->ops->residual) {
7519     ierr = MatMult(mat,x,r);CHKERRQ(ierr);
7520     ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr);
7521   } else {
7522     ierr  = (*mat->ops->residual)(mat,b,x,r);CHKERRQ(ierr);
7523   }
7524   ierr  = PetscLogEventEnd(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7525   PetscFunctionReturn(0);
7526 }
7527 
7528 /*@C
7529     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
7530 
7531    Collective on Mat
7532 
7533     Input Parameters:
7534 +   mat - the matrix
7535 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
7536 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
7537 -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
7538                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7539                  always used.
7540 
7541     Output Parameters:
7542 +   n - number of rows in the (possibly compressed) matrix
7543 .   ia - the row pointers; that is ia[0] = 0, ia[row] = ia[row-1] + number of elements in that row of the matrix
7544 .   ja - the column indices
7545 -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
7546            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
7547 
7548     Level: developer
7549 
7550     Notes:
7551     You CANNOT change any of the ia[] or ja[] values.
7552 
7553     Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values.
7554 
7555     Fortran Notes:
7556     In Fortran use
7557 $
7558 $      PetscInt ia(1), ja(1)
7559 $      PetscOffset iia, jja
7560 $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
7561 $      ! Access the ith and jth entries via ia(iia + i) and ja(jja + j)
7562 
7563      or
7564 $
7565 $    PetscInt, pointer :: ia(:),ja(:)
7566 $    call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
7567 $    ! Access the ith and jth entries via ia(i) and ja(j)
7568 
7569 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
7570 @*/
7571 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7572 {
7573   PetscErrorCode ierr;
7574 
7575   PetscFunctionBegin;
7576   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7577   PetscValidType(mat,1);
7578   PetscValidIntPointer(n,5);
7579   if (ia) PetscValidIntPointer(ia,6);
7580   if (ja) PetscValidIntPointer(ja,7);
7581   PetscValidIntPointer(done,8);
7582   MatCheckPreallocated(mat,1);
7583   if (!mat->ops->getrowij) *done = PETSC_FALSE;
7584   else {
7585     *done = PETSC_TRUE;
7586     ierr  = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7587     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7588     ierr  = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7589   }
7590   PetscFunctionReturn(0);
7591 }
7592 
7593 /*@C
7594     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
7595 
7596     Collective on Mat
7597 
7598     Input Parameters:
7599 +   mat - the matrix
7600 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7601 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7602                 symmetrized
7603 .   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7604                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7605                  always used.
7606 .   n - number of columns in the (possibly compressed) matrix
7607 .   ia - the column pointers; that is ia[0] = 0, ia[col] = i[col-1] + number of elements in that col of the matrix
7608 -   ja - the row indices
7609 
7610     Output Parameters:
7611 .   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
7612 
7613     Level: developer
7614 
7615 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7616 @*/
7617 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7618 {
7619   PetscErrorCode ierr;
7620 
7621   PetscFunctionBegin;
7622   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7623   PetscValidType(mat,1);
7624   PetscValidIntPointer(n,4);
7625   if (ia) PetscValidIntPointer(ia,5);
7626   if (ja) PetscValidIntPointer(ja,6);
7627   PetscValidIntPointer(done,7);
7628   MatCheckPreallocated(mat,1);
7629   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
7630   else {
7631     *done = PETSC_TRUE;
7632     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7633   }
7634   PetscFunctionReturn(0);
7635 }
7636 
7637 /*@C
7638     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
7639     MatGetRowIJ().
7640 
7641     Collective on Mat
7642 
7643     Input Parameters:
7644 +   mat - the matrix
7645 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7646 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7647                 symmetrized
7648 .   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7649                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7650                  always used.
7651 .   n - size of (possibly compressed) matrix
7652 .   ia - the row pointers
7653 -   ja - the column indices
7654 
7655     Output Parameters:
7656 .   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7657 
7658     Note:
7659     This routine zeros out n, ia, and ja. This is to prevent accidental
7660     us of the array after it has been restored. If you pass NULL, it will
7661     not zero the pointers.  Use of ia or ja after MatRestoreRowIJ() is invalid.
7662 
7663     Level: developer
7664 
7665 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7666 @*/
7667 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7668 {
7669   PetscErrorCode ierr;
7670 
7671   PetscFunctionBegin;
7672   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7673   PetscValidType(mat,1);
7674   if (ia) PetscValidIntPointer(ia,6);
7675   if (ja) PetscValidIntPointer(ja,7);
7676   PetscValidIntPointer(done,8);
7677   MatCheckPreallocated(mat,1);
7678 
7679   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
7680   else {
7681     *done = PETSC_TRUE;
7682     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7683     if (n)  *n = 0;
7684     if (ia) *ia = NULL;
7685     if (ja) *ja = NULL;
7686   }
7687   PetscFunctionReturn(0);
7688 }
7689 
7690 /*@C
7691     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
7692     MatGetColumnIJ().
7693 
7694     Collective on Mat
7695 
7696     Input Parameters:
7697 +   mat - the matrix
7698 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7699 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7700                 symmetrized
7701 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7702                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7703                  always used.
7704 
7705     Output Parameters:
7706 +   n - size of (possibly compressed) matrix
7707 .   ia - the column pointers
7708 .   ja - the row indices
7709 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7710 
7711     Level: developer
7712 
7713 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
7714 @*/
7715 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7716 {
7717   PetscErrorCode ierr;
7718 
7719   PetscFunctionBegin;
7720   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7721   PetscValidType(mat,1);
7722   if (ia) PetscValidIntPointer(ia,5);
7723   if (ja) PetscValidIntPointer(ja,6);
7724   PetscValidIntPointer(done,7);
7725   MatCheckPreallocated(mat,1);
7726 
7727   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
7728   else {
7729     *done = PETSC_TRUE;
7730     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7731     if (n)  *n = 0;
7732     if (ia) *ia = NULL;
7733     if (ja) *ja = NULL;
7734   }
7735   PetscFunctionReturn(0);
7736 }
7737 
7738 /*@C
7739     MatColoringPatch -Used inside matrix coloring routines that
7740     use MatGetRowIJ() and/or MatGetColumnIJ().
7741 
7742     Collective on Mat
7743 
7744     Input Parameters:
7745 +   mat - the matrix
7746 .   ncolors - max color value
7747 .   n   - number of entries in colorarray
7748 -   colorarray - array indicating color for each column
7749 
7750     Output Parameters:
7751 .   iscoloring - coloring generated using colorarray information
7752 
7753     Level: developer
7754 
7755 .seealso: MatGetRowIJ(), MatGetColumnIJ()
7756 
7757 @*/
7758 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7759 {
7760   PetscErrorCode ierr;
7761 
7762   PetscFunctionBegin;
7763   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7764   PetscValidType(mat,1);
7765   PetscValidIntPointer(colorarray,4);
7766   PetscValidPointer(iscoloring,5);
7767   MatCheckPreallocated(mat,1);
7768 
7769   if (!mat->ops->coloringpatch) {
7770     ierr = ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);CHKERRQ(ierr);
7771   } else {
7772     ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
7773   }
7774   PetscFunctionReturn(0);
7775 }
7776 
7777 
7778 /*@
7779    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
7780 
7781    Logically Collective on Mat
7782 
7783    Input Parameter:
7784 .  mat - the factored matrix to be reset
7785 
7786    Notes:
7787    This routine should be used only with factored matrices formed by in-place
7788    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7789    format).  This option can save memory, for example, when solving nonlinear
7790    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7791    ILU(0) preconditioner.
7792 
7793    Note that one can specify in-place ILU(0) factorization by calling
7794 .vb
7795      PCType(pc,PCILU);
7796      PCFactorSeUseInPlace(pc);
7797 .ve
7798    or by using the options -pc_type ilu -pc_factor_in_place
7799 
7800    In-place factorization ILU(0) can also be used as a local
7801    solver for the blocks within the block Jacobi or additive Schwarz
7802    methods (runtime option: -sub_pc_factor_in_place).  See Users-Manual: ch_pc
7803    for details on setting local solver options.
7804 
7805    Most users should employ the simplified KSP interface for linear solvers
7806    instead of working directly with matrix algebra routines such as this.
7807    See, e.g., KSPCreate().
7808 
7809    Level: developer
7810 
7811 .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace()
7812 
7813    Concepts: matrices^unfactored
7814 
7815 @*/
7816 PetscErrorCode MatSetUnfactored(Mat mat)
7817 {
7818   PetscErrorCode ierr;
7819 
7820   PetscFunctionBegin;
7821   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7822   PetscValidType(mat,1);
7823   MatCheckPreallocated(mat,1);
7824   mat->factortype = MAT_FACTOR_NONE;
7825   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
7826   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
7827   PetscFunctionReturn(0);
7828 }
7829 
7830 /*MC
7831     MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.
7832 
7833     Synopsis:
7834     MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7835 
7836     Not collective
7837 
7838     Input Parameter:
7839 .   x - matrix
7840 
7841     Output Parameters:
7842 +   xx_v - the Fortran90 pointer to the array
7843 -   ierr - error code
7844 
7845     Example of Usage:
7846 .vb
7847       PetscScalar, pointer xx_v(:,:)
7848       ....
7849       call MatDenseGetArrayF90(x,xx_v,ierr)
7850       a = xx_v(3)
7851       call MatDenseRestoreArrayF90(x,xx_v,ierr)
7852 .ve
7853 
7854     Level: advanced
7855 
7856 .seealso:  MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90()
7857 
7858     Concepts: matrices^accessing array
7859 
7860 M*/
7861 
7862 /*MC
7863     MatDenseRestoreArrayF90 - Restores a matrix array that has been
7864     accessed with MatDenseGetArrayF90().
7865 
7866     Synopsis:
7867     MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7868 
7869     Not collective
7870 
7871     Input Parameters:
7872 +   x - matrix
7873 -   xx_v - the Fortran90 pointer to the array
7874 
7875     Output Parameter:
7876 .   ierr - error code
7877 
7878     Example of Usage:
7879 .vb
7880        PetscScalar, pointer xx_v(:,:)
7881        ....
7882        call MatDenseGetArrayF90(x,xx_v,ierr)
7883        a = xx_v(3)
7884        call MatDenseRestoreArrayF90(x,xx_v,ierr)
7885 .ve
7886 
7887     Level: advanced
7888 
7889 .seealso:  MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90()
7890 
7891 M*/
7892 
7893 
7894 /*MC
7895     MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.
7896 
7897     Synopsis:
7898     MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7899 
7900     Not collective
7901 
7902     Input Parameter:
7903 .   x - matrix
7904 
7905     Output Parameters:
7906 +   xx_v - the Fortran90 pointer to the array
7907 -   ierr - error code
7908 
7909     Example of Usage:
7910 .vb
7911       PetscScalar, pointer xx_v(:)
7912       ....
7913       call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7914       a = xx_v(3)
7915       call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7916 .ve
7917 
7918     Level: advanced
7919 
7920 .seealso:  MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90()
7921 
7922     Concepts: matrices^accessing array
7923 
7924 M*/
7925 
7926 /*MC
7927     MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7928     accessed with MatSeqAIJGetArrayF90().
7929 
7930     Synopsis:
7931     MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7932 
7933     Not collective
7934 
7935     Input Parameters:
7936 +   x - matrix
7937 -   xx_v - the Fortran90 pointer to the array
7938 
7939     Output Parameter:
7940 .   ierr - error code
7941 
7942     Example of Usage:
7943 .vb
7944        PetscScalar, pointer xx_v(:)
7945        ....
7946        call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7947        a = xx_v(3)
7948        call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7949 .ve
7950 
7951     Level: advanced
7952 
7953 .seealso:  MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90()
7954 
7955 M*/
7956 
7957 
7958 /*@
7959     MatCreateSubMatrix - Gets a single submatrix on the same number of processors
7960                       as the original matrix.
7961 
7962     Collective on Mat
7963 
7964     Input Parameters:
7965 +   mat - the original matrix
7966 .   isrow - parallel IS containing the rows this processor should obtain
7967 .   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.
7968 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7969 
7970     Output Parameter:
7971 .   newmat - the new submatrix, of the same type as the old
7972 
7973     Level: advanced
7974 
7975     Notes:
7976     The submatrix will be able to be multiplied with vectors using the same layout as iscol.
7977 
7978     Some matrix types place restrictions on the row and column indices, such
7979     as that they be sorted or that they be equal to each other.
7980 
7981     The index sets may not have duplicate entries.
7982 
7983       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7984    the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls
7985    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7986    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
7987    you are finished using it.
7988 
7989     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7990     the input matrix.
7991 
7992     If iscol is NULL then all columns are obtained (not supported in Fortran).
7993 
7994    Example usage:
7995    Consider the following 8x8 matrix with 34 non-zero values, that is
7996    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7997    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7998    as follows:
7999 
8000 .vb
8001             1  2  0  |  0  3  0  |  0  4
8002     Proc0   0  5  6  |  7  0  0  |  8  0
8003             9  0 10  | 11  0  0  | 12  0
8004     -------------------------------------
8005            13  0 14  | 15 16 17  |  0  0
8006     Proc1   0 18  0  | 19 20 21  |  0  0
8007             0  0  0  | 22 23  0  | 24  0
8008     -------------------------------------
8009     Proc2  25 26 27  |  0  0 28  | 29  0
8010            30  0  0  | 31 32 33  |  0 34
8011 .ve
8012 
8013     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is
8014 
8015 .vb
8016             2  0  |  0  3  0  |  0
8017     Proc0   5  6  |  7  0  0  |  8
8018     -------------------------------
8019     Proc1  18  0  | 19 20 21  |  0
8020     -------------------------------
8021     Proc2  26 27  |  0  0 28  | 29
8022             0  0  | 31 32 33  |  0
8023 .ve
8024 
8025 
8026     Concepts: matrices^submatrices
8027 
8028 .seealso: MatCreateSubMatrices()
8029 @*/
8030 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
8031 {
8032   PetscErrorCode ierr;
8033   PetscMPIInt    size;
8034   Mat            *local;
8035   IS             iscoltmp;
8036 
8037   PetscFunctionBegin;
8038   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8039   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
8040   if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
8041   PetscValidPointer(newmat,5);
8042   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5);
8043   PetscValidType(mat,1);
8044   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8045   if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX");
8046 
8047   MatCheckPreallocated(mat,1);
8048   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
8049 
8050   if (!iscol || isrow == iscol) {
8051     PetscBool   stride;
8052     PetscMPIInt grabentirematrix = 0,grab;
8053     ierr = PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);CHKERRQ(ierr);
8054     if (stride) {
8055       PetscInt first,step,n,rstart,rend;
8056       ierr = ISStrideGetInfo(isrow,&first,&step);CHKERRQ(ierr);
8057       if (step == 1) {
8058         ierr = MatGetOwnershipRange(mat,&rstart,&rend);CHKERRQ(ierr);
8059         if (rstart == first) {
8060           ierr = ISGetLocalSize(isrow,&n);CHKERRQ(ierr);
8061           if (n == rend-rstart) {
8062             grabentirematrix = 1;
8063           }
8064         }
8065       }
8066     }
8067     ierr = MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr);
8068     if (grab) {
8069       ierr = PetscInfo(mat,"Getting entire matrix as submatrix\n");CHKERRQ(ierr);
8070       if (cll == MAT_INITIAL_MATRIX) {
8071         *newmat = mat;
8072         ierr    = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr);
8073       }
8074       PetscFunctionReturn(0);
8075     }
8076   }
8077 
8078   if (!iscol) {
8079     ierr = ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr);
8080   } else {
8081     iscoltmp = iscol;
8082   }
8083 
8084   /* if original matrix is on just one processor then use submatrix generated */
8085   if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
8086     ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
8087     goto setproperties;
8088   } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) {
8089     ierr    = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
8090     *newmat = *local;
8091     ierr    = PetscFree(local);CHKERRQ(ierr);
8092     goto setproperties;
8093   } else if (!mat->ops->createsubmatrix) {
8094     /* Create a new matrix type that implements the operation using the full matrix */
8095     ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8096     switch (cll) {
8097     case MAT_INITIAL_MATRIX:
8098       ierr = MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr);
8099       break;
8100     case MAT_REUSE_MATRIX:
8101       ierr = MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr);
8102       break;
8103     default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
8104     }
8105     ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8106     goto setproperties;
8107   }
8108 
8109   if (!mat->ops->createsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8110   ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8111   ierr = (*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr);
8112   ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8113 
8114   /* Propagate symmetry information for diagonal blocks */
8115 setproperties:
8116   if (isrow == iscoltmp) {
8117     if (mat->symmetric_set && mat->symmetric) {
8118       ierr = MatSetOption(*newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
8119     }
8120     if (mat->structurally_symmetric_set && mat->structurally_symmetric) {
8121       ierr = MatSetOption(*newmat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
8122     }
8123     if (mat->hermitian_set && mat->hermitian) {
8124       ierr = MatSetOption(*newmat,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
8125     }
8126     if (mat->spd_set && mat->spd) {
8127       ierr = MatSetOption(*newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr);
8128     }
8129   }
8130 
8131   if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
8132   if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);}
8133   PetscFunctionReturn(0);
8134 }
8135 
8136 /*@
8137    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
8138    used during the assembly process to store values that belong to
8139    other processors.
8140 
8141    Not Collective
8142 
8143    Input Parameters:
8144 +  mat   - the matrix
8145 .  size  - the initial size of the stash.
8146 -  bsize - the initial size of the block-stash(if used).
8147 
8148    Options Database Keys:
8149 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
8150 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
8151 
8152    Level: intermediate
8153 
8154    Notes:
8155      The block-stash is used for values set with MatSetValuesBlocked() while
8156      the stash is used for values set with MatSetValues()
8157 
8158      Run with the option -info and look for output of the form
8159      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
8160      to determine the appropriate value, MM, to use for size and
8161      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
8162      to determine the value, BMM to use for bsize
8163 
8164    Concepts: stash^setting matrix size
8165    Concepts: matrices^stash
8166 
8167 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
8168 
8169 @*/
8170 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
8171 {
8172   PetscErrorCode ierr;
8173 
8174   PetscFunctionBegin;
8175   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8176   PetscValidType(mat,1);
8177   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
8178   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
8179   PetscFunctionReturn(0);
8180 }
8181 
8182 /*@
8183    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
8184      the matrix
8185 
8186    Neighbor-wise Collective on Mat
8187 
8188    Input Parameters:
8189 +  mat   - the matrix
8190 .  x,y - the vectors
8191 -  w - where the result is stored
8192 
8193    Level: intermediate
8194 
8195    Notes:
8196     w may be the same vector as y.
8197 
8198     This allows one to use either the restriction or interpolation (its transpose)
8199     matrix to do the interpolation
8200 
8201     Concepts: interpolation
8202 
8203 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
8204 
8205 @*/
8206 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
8207 {
8208   PetscErrorCode ierr;
8209   PetscInt       M,N,Ny;
8210 
8211   PetscFunctionBegin;
8212   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8213   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8214   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8215   PetscValidHeaderSpecific(w,VEC_CLASSID,4);
8216   PetscValidType(A,1);
8217   MatCheckPreallocated(A,1);
8218   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8219   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8220   if (M == Ny) {
8221     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
8222   } else {
8223     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
8224   }
8225   PetscFunctionReturn(0);
8226 }
8227 
8228 /*@
8229    MatInterpolate - y = A*x or A'*x depending on the shape of
8230      the matrix
8231 
8232    Neighbor-wise Collective on Mat
8233 
8234    Input Parameters:
8235 +  mat   - the matrix
8236 -  x,y - the vectors
8237 
8238    Level: intermediate
8239 
8240    Notes:
8241     This allows one to use either the restriction or interpolation (its transpose)
8242     matrix to do the interpolation
8243 
8244    Concepts: matrices^interpolation
8245 
8246 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
8247 
8248 @*/
8249 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
8250 {
8251   PetscErrorCode ierr;
8252   PetscInt       M,N,Ny;
8253 
8254   PetscFunctionBegin;
8255   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8256   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8257   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8258   PetscValidType(A,1);
8259   MatCheckPreallocated(A,1);
8260   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8261   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8262   if (M == Ny) {
8263     ierr = MatMult(A,x,y);CHKERRQ(ierr);
8264   } else {
8265     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
8266   }
8267   PetscFunctionReturn(0);
8268 }
8269 
8270 /*@
8271    MatRestrict - y = A*x or A'*x
8272 
8273    Neighbor-wise Collective on Mat
8274 
8275    Input Parameters:
8276 +  mat   - the matrix
8277 -  x,y - the vectors
8278 
8279    Level: intermediate
8280 
8281    Notes:
8282     This allows one to use either the restriction or interpolation (its transpose)
8283     matrix to do the restriction
8284 
8285    Concepts: matrices^restriction
8286 
8287 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
8288 
8289 @*/
8290 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
8291 {
8292   PetscErrorCode ierr;
8293   PetscInt       M,N,Ny;
8294 
8295   PetscFunctionBegin;
8296   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8297   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8298   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8299   PetscValidType(A,1);
8300   MatCheckPreallocated(A,1);
8301 
8302   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8303   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8304   if (M == Ny) {
8305     ierr = MatMult(A,x,y);CHKERRQ(ierr);
8306   } else {
8307     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
8308   }
8309   PetscFunctionReturn(0);
8310 }
8311 
8312 /*@
8313    MatGetNullSpace - retrieves the null space of a matrix.
8314 
8315    Logically Collective on Mat and MatNullSpace
8316 
8317    Input Parameters:
8318 +  mat - the matrix
8319 -  nullsp - the null space object
8320 
8321    Level: developer
8322 
8323    Concepts: null space^attaching to matrix
8324 
8325 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace()
8326 @*/
8327 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
8328 {
8329   PetscFunctionBegin;
8330   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8331   PetscValidPointer(nullsp,2);
8332   *nullsp = (mat->symmetric_set && mat->symmetric && !mat->nullsp) ? mat->transnullsp : mat->nullsp;
8333   PetscFunctionReturn(0);
8334 }
8335 
8336 /*@
8337    MatSetNullSpace - attaches a null space to a matrix.
8338 
8339    Logically Collective on Mat and MatNullSpace
8340 
8341    Input Parameters:
8342 +  mat - the matrix
8343 -  nullsp - the null space object
8344 
8345    Level: advanced
8346 
8347    Notes:
8348       This null space is used by the linear solvers. Overwrites any previous null space that may have been attached
8349 
8350       For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should
8351       call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense.
8352 
8353       You can remove the null space by calling this routine with an nullsp of NULL
8354 
8355 
8356       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8357    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).
8358    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
8359    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
8360    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).
8361 
8362       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8363 
8364     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
8365     routine also automatically calls MatSetTransposeNullSpace().
8366 
8367    Concepts: null space^attaching to matrix
8368 
8369 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8370 @*/
8371 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp)
8372 {
8373   PetscErrorCode ierr;
8374 
8375   PetscFunctionBegin;
8376   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8377   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8378   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8379   ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr);
8380   mat->nullsp = nullsp;
8381   if (mat->symmetric_set && mat->symmetric) {
8382     ierr = MatSetTransposeNullSpace(mat,nullsp);CHKERRQ(ierr);
8383   }
8384   PetscFunctionReturn(0);
8385 }
8386 
8387 /*@
8388    MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix.
8389 
8390    Logically Collective on Mat and MatNullSpace
8391 
8392    Input Parameters:
8393 +  mat - the matrix
8394 -  nullsp - the null space object
8395 
8396    Level: developer
8397 
8398    Concepts: null space^attaching to matrix
8399 
8400 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace()
8401 @*/
8402 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp)
8403 {
8404   PetscFunctionBegin;
8405   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8406   PetscValidType(mat,1);
8407   PetscValidPointer(nullsp,2);
8408   *nullsp = (mat->symmetric_set && mat->symmetric && !mat->transnullsp) ? mat->nullsp : mat->transnullsp;
8409   PetscFunctionReturn(0);
8410 }
8411 
8412 /*@
8413    MatSetTransposeNullSpace - attaches a null space to 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: advanced
8422 
8423    Notes:
8424       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.
8425       You must also call MatSetNullSpace()
8426 
8427 
8428       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8429    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).
8430    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
8431    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
8432    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).
8433 
8434       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8435 
8436    Concepts: null space^attaching to matrix
8437 
8438 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8439 @*/
8440 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp)
8441 {
8442   PetscErrorCode ierr;
8443 
8444   PetscFunctionBegin;
8445   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8446   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8447   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8448   ierr = MatNullSpaceDestroy(&mat->transnullsp);CHKERRQ(ierr);
8449   mat->transnullsp = nullsp;
8450   PetscFunctionReturn(0);
8451 }
8452 
8453 /*@
8454    MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions
8455         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.
8456 
8457    Logically Collective on Mat and MatNullSpace
8458 
8459    Input Parameters:
8460 +  mat - the matrix
8461 -  nullsp - the null space object
8462 
8463    Level: advanced
8464 
8465    Notes:
8466       Overwrites any previous near null space that may have been attached
8467 
8468       You can remove the null space by calling this routine with an nullsp of NULL
8469 
8470    Concepts: null space^attaching to matrix
8471 
8472 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace()
8473 @*/
8474 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
8475 {
8476   PetscErrorCode ierr;
8477 
8478   PetscFunctionBegin;
8479   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8480   PetscValidType(mat,1);
8481   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8482   MatCheckPreallocated(mat,1);
8483   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8484   ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr);
8485   mat->nearnullsp = nullsp;
8486   PetscFunctionReturn(0);
8487 }
8488 
8489 /*@
8490    MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()
8491 
8492    Not Collective
8493 
8494    Input Parameters:
8495 .  mat - the matrix
8496 
8497    Output Parameters:
8498 .  nullsp - the null space object, NULL if not set
8499 
8500    Level: developer
8501 
8502    Concepts: null space^attaching to matrix
8503 
8504 .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate()
8505 @*/
8506 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
8507 {
8508   PetscFunctionBegin;
8509   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8510   PetscValidType(mat,1);
8511   PetscValidPointer(nullsp,2);
8512   MatCheckPreallocated(mat,1);
8513   *nullsp = mat->nearnullsp;
8514   PetscFunctionReturn(0);
8515 }
8516 
8517 /*@C
8518    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
8519 
8520    Collective on Mat
8521 
8522    Input Parameters:
8523 +  mat - the matrix
8524 .  row - row/column permutation
8525 .  fill - expected fill factor >= 1.0
8526 -  level - level of fill, for ICC(k)
8527 
8528    Notes:
8529    Probably really in-place only when level of fill is zero, otherwise allocates
8530    new space to store factored matrix and deletes previous memory.
8531 
8532    Most users should employ the simplified KSP interface for linear solvers
8533    instead of working directly with matrix algebra routines such as this.
8534    See, e.g., KSPCreate().
8535 
8536    Level: developer
8537 
8538    Concepts: matrices^incomplete Cholesky factorization
8539    Concepts: Cholesky factorization
8540 
8541 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
8542 
8543     Developer Note: fortran interface is not autogenerated as the f90
8544     interface defintion cannot be generated correctly [due to MatFactorInfo]
8545 
8546 @*/
8547 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
8548 {
8549   PetscErrorCode ierr;
8550 
8551   PetscFunctionBegin;
8552   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8553   PetscValidType(mat,1);
8554   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
8555   PetscValidPointer(info,3);
8556   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
8557   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8558   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8559   if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8560   MatCheckPreallocated(mat,1);
8561   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
8562   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8563   PetscFunctionReturn(0);
8564 }
8565 
8566 /*@
8567    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
8568          ghosted ones.
8569 
8570    Not Collective
8571 
8572    Input Parameters:
8573 +  mat - the matrix
8574 -  diag = the diagonal values, including ghost ones
8575 
8576    Level: developer
8577 
8578    Notes:
8579     Works only for MPIAIJ and MPIBAIJ matrices
8580 
8581 .seealso: MatDiagonalScale()
8582 @*/
8583 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
8584 {
8585   PetscErrorCode ierr;
8586   PetscMPIInt    size;
8587 
8588   PetscFunctionBegin;
8589   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8590   PetscValidHeaderSpecific(diag,VEC_CLASSID,2);
8591   PetscValidType(mat,1);
8592 
8593   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8594   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8595   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
8596   if (size == 1) {
8597     PetscInt n,m;
8598     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
8599     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
8600     if (m == n) {
8601       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
8602     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
8603   } else {
8604     ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr);
8605   }
8606   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8607   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8608   PetscFunctionReturn(0);
8609 }
8610 
8611 /*@
8612    MatGetInertia - Gets the inertia from a factored matrix
8613 
8614    Collective on Mat
8615 
8616    Input Parameter:
8617 .  mat - the matrix
8618 
8619    Output Parameters:
8620 +   nneg - number of negative eigenvalues
8621 .   nzero - number of zero eigenvalues
8622 -   npos - number of positive eigenvalues
8623 
8624    Level: advanced
8625 
8626    Notes:
8627     Matrix must have been factored by MatCholeskyFactor()
8628 
8629 
8630 @*/
8631 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
8632 {
8633   PetscErrorCode ierr;
8634 
8635   PetscFunctionBegin;
8636   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8637   PetscValidType(mat,1);
8638   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8639   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
8640   if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8641   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
8642   PetscFunctionReturn(0);
8643 }
8644 
8645 /* ----------------------------------------------------------------*/
8646 /*@C
8647    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
8648 
8649    Neighbor-wise Collective on Mat and Vecs
8650 
8651    Input Parameters:
8652 +  mat - the factored matrix
8653 -  b - the right-hand-side vectors
8654 
8655    Output Parameter:
8656 .  x - the result vectors
8657 
8658    Notes:
8659    The vectors b and x cannot be the same.  I.e., one cannot
8660    call MatSolves(A,x,x).
8661 
8662    Notes:
8663    Most users should employ the simplified KSP interface for linear solvers
8664    instead of working directly with matrix algebra routines such as this.
8665    See, e.g., KSPCreate().
8666 
8667    Level: developer
8668 
8669    Concepts: matrices^triangular solves
8670 
8671 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
8672 @*/
8673 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
8674 {
8675   PetscErrorCode ierr;
8676 
8677   PetscFunctionBegin;
8678   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8679   PetscValidType(mat,1);
8680   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
8681   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8682   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
8683 
8684   if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8685   MatCheckPreallocated(mat,1);
8686   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8687   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
8688   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8689   PetscFunctionReturn(0);
8690 }
8691 
8692 /*@
8693    MatIsSymmetric - Test whether a matrix is symmetric
8694 
8695    Collective on Mat
8696 
8697    Input Parameter:
8698 +  A - the matrix to test
8699 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
8700 
8701    Output Parameters:
8702 .  flg - the result
8703 
8704    Notes:
8705     For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
8706 
8707    Level: intermediate
8708 
8709    Concepts: matrix^symmetry
8710 
8711 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
8712 @*/
8713 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
8714 {
8715   PetscErrorCode ierr;
8716 
8717   PetscFunctionBegin;
8718   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8719   PetscValidPointer(flg,2);
8720 
8721   if (!A->symmetric_set) {
8722     if (!A->ops->issymmetric) {
8723       MatType mattype;
8724       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8725       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8726     }
8727     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8728     if (!tol) {
8729       A->symmetric_set = PETSC_TRUE;
8730       A->symmetric     = *flg;
8731       if (A->symmetric) {
8732         A->structurally_symmetric_set = PETSC_TRUE;
8733         A->structurally_symmetric     = PETSC_TRUE;
8734       }
8735     }
8736   } else if (A->symmetric) {
8737     *flg = PETSC_TRUE;
8738   } else if (!tol) {
8739     *flg = PETSC_FALSE;
8740   } else {
8741     if (!A->ops->issymmetric) {
8742       MatType mattype;
8743       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8744       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8745     }
8746     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8747   }
8748   PetscFunctionReturn(0);
8749 }
8750 
8751 /*@
8752    MatIsHermitian - Test whether a matrix is Hermitian
8753 
8754    Collective on Mat
8755 
8756    Input Parameter:
8757 +  A - the matrix to test
8758 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
8759 
8760    Output Parameters:
8761 .  flg - the result
8762 
8763    Level: intermediate
8764 
8765    Concepts: matrix^symmetry
8766 
8767 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
8768           MatIsSymmetricKnown(), MatIsSymmetric()
8769 @*/
8770 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
8771 {
8772   PetscErrorCode ierr;
8773 
8774   PetscFunctionBegin;
8775   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8776   PetscValidPointer(flg,2);
8777 
8778   if (!A->hermitian_set) {
8779     if (!A->ops->ishermitian) {
8780       MatType mattype;
8781       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8782       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8783     }
8784     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8785     if (!tol) {
8786       A->hermitian_set = PETSC_TRUE;
8787       A->hermitian     = *flg;
8788       if (A->hermitian) {
8789         A->structurally_symmetric_set = PETSC_TRUE;
8790         A->structurally_symmetric     = PETSC_TRUE;
8791       }
8792     }
8793   } else if (A->hermitian) {
8794     *flg = PETSC_TRUE;
8795   } else if (!tol) {
8796     *flg = PETSC_FALSE;
8797   } else {
8798     if (!A->ops->ishermitian) {
8799       MatType mattype;
8800       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8801       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8802     }
8803     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8804   }
8805   PetscFunctionReturn(0);
8806 }
8807 
8808 /*@
8809    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
8810 
8811    Not Collective
8812 
8813    Input Parameter:
8814 .  A - the matrix to check
8815 
8816    Output Parameters:
8817 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
8818 -  flg - the result
8819 
8820    Level: advanced
8821 
8822    Concepts: matrix^symmetry
8823 
8824    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
8825          if you want it explicitly checked
8826 
8827 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8828 @*/
8829 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8830 {
8831   PetscFunctionBegin;
8832   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8833   PetscValidPointer(set,2);
8834   PetscValidPointer(flg,3);
8835   if (A->symmetric_set) {
8836     *set = PETSC_TRUE;
8837     *flg = A->symmetric;
8838   } else {
8839     *set = PETSC_FALSE;
8840   }
8841   PetscFunctionReturn(0);
8842 }
8843 
8844 /*@
8845    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
8846 
8847    Not Collective
8848 
8849    Input Parameter:
8850 .  A - the matrix to check
8851 
8852    Output Parameters:
8853 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8854 -  flg - the result
8855 
8856    Level: advanced
8857 
8858    Concepts: matrix^symmetry
8859 
8860    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8861          if you want it explicitly checked
8862 
8863 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8864 @*/
8865 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8866 {
8867   PetscFunctionBegin;
8868   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8869   PetscValidPointer(set,2);
8870   PetscValidPointer(flg,3);
8871   if (A->hermitian_set) {
8872     *set = PETSC_TRUE;
8873     *flg = A->hermitian;
8874   } else {
8875     *set = PETSC_FALSE;
8876   }
8877   PetscFunctionReturn(0);
8878 }
8879 
8880 /*@
8881    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
8882 
8883    Collective on Mat
8884 
8885    Input Parameter:
8886 .  A - the matrix to test
8887 
8888    Output Parameters:
8889 .  flg - the result
8890 
8891    Level: intermediate
8892 
8893    Concepts: matrix^symmetry
8894 
8895 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8896 @*/
8897 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
8898 {
8899   PetscErrorCode ierr;
8900 
8901   PetscFunctionBegin;
8902   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8903   PetscValidPointer(flg,2);
8904   if (!A->structurally_symmetric_set) {
8905     if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8906     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
8907 
8908     A->structurally_symmetric_set = PETSC_TRUE;
8909   }
8910   *flg = A->structurally_symmetric;
8911   PetscFunctionReturn(0);
8912 }
8913 
8914 /*@
8915    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8916        to be communicated to other processors during the MatAssemblyBegin/End() process
8917 
8918     Not collective
8919 
8920    Input Parameter:
8921 .   vec - the vector
8922 
8923    Output Parameters:
8924 +   nstash   - the size of the stash
8925 .   reallocs - the number of additional mallocs incurred.
8926 .   bnstash   - the size of the block stash
8927 -   breallocs - the number of additional mallocs incurred.in the block stash
8928 
8929    Level: advanced
8930 
8931 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
8932 
8933 @*/
8934 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8935 {
8936   PetscErrorCode ierr;
8937 
8938   PetscFunctionBegin;
8939   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
8940   ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
8941   PetscFunctionReturn(0);
8942 }
8943 
8944 /*@C
8945    MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same
8946      parallel layout
8947 
8948    Collective on Mat
8949 
8950    Input Parameter:
8951 .  mat - the matrix
8952 
8953    Output Parameter:
8954 +   right - (optional) vector that the matrix can be multiplied against
8955 -   left - (optional) vector that the matrix vector product can be stored in
8956 
8957    Notes:
8958     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().
8959 
8960   Notes:
8961     These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed
8962 
8963   Level: advanced
8964 
8965 .seealso: MatCreate(), VecDestroy()
8966 @*/
8967 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left)
8968 {
8969   PetscErrorCode ierr;
8970 
8971   PetscFunctionBegin;
8972   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8973   PetscValidType(mat,1);
8974   if (mat->ops->getvecs) {
8975     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
8976   } else {
8977     PetscInt rbs,cbs;
8978     ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr);
8979     if (right) {
8980       if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup");
8981       ierr = VecCreate(PetscObjectComm((PetscObject)mat),right);CHKERRQ(ierr);
8982       ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8983       ierr = VecSetBlockSize(*right,cbs);CHKERRQ(ierr);
8984       ierr = VecSetType(*right,mat->defaultvectype);CHKERRQ(ierr);
8985       ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr);
8986     }
8987     if (left) {
8988       if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup");
8989       ierr = VecCreate(PetscObjectComm((PetscObject)mat),left);CHKERRQ(ierr);
8990       ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8991       ierr = VecSetBlockSize(*left,rbs);CHKERRQ(ierr);
8992       ierr = VecSetType(*left,mat->defaultvectype);CHKERRQ(ierr);
8993       ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr);
8994     }
8995   }
8996   PetscFunctionReturn(0);
8997 }
8998 
8999 /*@C
9000    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
9001      with default values.
9002 
9003    Not Collective
9004 
9005    Input Parameters:
9006 .    info - the MatFactorInfo data structure
9007 
9008 
9009    Notes:
9010     The solvers are generally used through the KSP and PC objects, for example
9011           PCLU, PCILU, PCCHOLESKY, PCICC
9012 
9013    Level: developer
9014 
9015 .seealso: MatFactorInfo
9016 
9017     Developer Note: fortran interface is not autogenerated as the f90
9018     interface defintion cannot be generated correctly [due to MatFactorInfo]
9019 
9020 @*/
9021 
9022 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
9023 {
9024   PetscErrorCode ierr;
9025 
9026   PetscFunctionBegin;
9027   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
9028   PetscFunctionReturn(0);
9029 }
9030 
9031 /*@
9032    MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed
9033 
9034    Collective on Mat
9035 
9036    Input Parameters:
9037 +  mat - the factored matrix
9038 -  is - the index set defining the Schur indices (0-based)
9039 
9040    Notes:
9041     Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system.
9042 
9043    You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call.
9044 
9045    Level: developer
9046 
9047    Concepts:
9048 
9049 .seealso: MatGetFactor(), MatFactorGetSchurComplement(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSolveSchurComplement(),
9050           MatFactorSolveSchurComplementTranspose(), MatFactorSolveSchurComplement()
9051 
9052 @*/
9053 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is)
9054 {
9055   PetscErrorCode ierr,(*f)(Mat,IS);
9056 
9057   PetscFunctionBegin;
9058   PetscValidType(mat,1);
9059   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9060   PetscValidType(is,2);
9061   PetscValidHeaderSpecific(is,IS_CLASSID,2);
9062   PetscCheckSameComm(mat,1,is,2);
9063   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
9064   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);CHKERRQ(ierr);
9065   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");
9066   if (mat->schur) {
9067     ierr = MatDestroy(&mat->schur);CHKERRQ(ierr);
9068   }
9069   ierr = (*f)(mat,is);CHKERRQ(ierr);
9070   if (!mat->schur) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created");
9071   ierr = MatFactorSetUpInPlaceSchur_Private(mat);CHKERRQ(ierr);
9072   PetscFunctionReturn(0);
9073 }
9074 
9075 /*@
9076   MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step
9077 
9078    Logically Collective on Mat
9079 
9080    Input Parameters:
9081 +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
9082 .  S - location where to return the Schur complement, can be NULL
9083 -  status - the status of the Schur complement matrix, can be NULL
9084 
9085    Notes:
9086    You must call MatFactorSetSchurIS() before calling this routine.
9087 
9088    The routine provides a copy of the Schur matrix stored within the solver data structures.
9089    The caller must destroy the object when it is no longer needed.
9090    If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse.
9091 
9092    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)
9093 
9094    Developer Notes:
9095     The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc
9096    matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix.
9097 
9098    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
9099 
9100    Level: advanced
9101 
9102    References:
9103 
9104 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorSchurStatus
9105 @*/
9106 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
9107 {
9108   PetscErrorCode ierr;
9109 
9110   PetscFunctionBegin;
9111   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9112   if (S) PetscValidPointer(S,2);
9113   if (status) PetscValidPointer(status,3);
9114   if (S) {
9115     PetscErrorCode (*f)(Mat,Mat*);
9116 
9117     ierr = PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f);CHKERRQ(ierr);
9118     if (f) {
9119       ierr = (*f)(F,S);CHKERRQ(ierr);
9120     } else {
9121       ierr = MatDuplicate(F->schur,MAT_COPY_VALUES,S);CHKERRQ(ierr);
9122     }
9123   }
9124   if (status) *status = F->schur_status;
9125   PetscFunctionReturn(0);
9126 }
9127 
9128 /*@
9129   MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix
9130 
9131    Logically Collective on Mat
9132 
9133    Input Parameters:
9134 +  F - the factored matrix obtained by calling MatGetFactor()
9135 .  *S - location where to return the Schur complement, can be NULL
9136 -  status - the status of the Schur complement matrix, can be NULL
9137 
9138    Notes:
9139    You must call MatFactorSetSchurIS() before calling this routine.
9140 
9141    Schur complement mode is currently implemented for sequential matrices.
9142    The routine returns a the Schur Complement stored within the data strutures of the solver.
9143    If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement.
9144    The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed.
9145 
9146    Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix
9147 
9148    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
9149 
9150    Level: advanced
9151 
9152    References:
9153 
9154 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
9155 @*/
9156 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
9157 {
9158   PetscFunctionBegin;
9159   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9160   if (S) PetscValidPointer(S,2);
9161   if (status) PetscValidPointer(status,3);
9162   if (S) *S = F->schur;
9163   if (status) *status = F->schur_status;
9164   PetscFunctionReturn(0);
9165 }
9166 
9167 /*@
9168   MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement
9169 
9170    Logically Collective on Mat
9171 
9172    Input Parameters:
9173 +  F - the factored matrix obtained by calling MatGetFactor()
9174 .  *S - location where the Schur complement is stored
9175 -  status - the status of the Schur complement matrix (see MatFactorSchurStatus)
9176 
9177    Notes:
9178 
9179    Level: advanced
9180 
9181    References:
9182 
9183 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
9184 @*/
9185 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status)
9186 {
9187   PetscErrorCode ierr;
9188 
9189   PetscFunctionBegin;
9190   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9191   if (S) {
9192     PetscValidHeaderSpecific(*S,MAT_CLASSID,2);
9193     *S = NULL;
9194   }
9195   F->schur_status = status;
9196   ierr = MatFactorUpdateSchurStatus_Private(F);CHKERRQ(ierr);
9197   PetscFunctionReturn(0);
9198 }
9199 
9200 /*@
9201   MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step
9202 
9203    Logically Collective on Mat
9204 
9205    Input Parameters:
9206 +  F - the factored matrix obtained by calling MatGetFactor()
9207 .  rhs - location where the right hand side of the Schur complement system is stored
9208 -  sol - location where the solution of the Schur complement system has to be returned
9209 
9210    Notes:
9211    The sizes of the vectors should match the size of the Schur complement
9212 
9213    Must be called after MatFactorSetSchurIS()
9214 
9215    Level: advanced
9216 
9217    References:
9218 
9219 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplement()
9220 @*/
9221 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol)
9222 {
9223   PetscErrorCode ierr;
9224 
9225   PetscFunctionBegin;
9226   PetscValidType(F,1);
9227   PetscValidType(rhs,2);
9228   PetscValidType(sol,3);
9229   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9230   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
9231   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
9232   PetscCheckSameComm(F,1,rhs,2);
9233   PetscCheckSameComm(F,1,sol,3);
9234   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9235   switch (F->schur_status) {
9236   case MAT_FACTOR_SCHUR_FACTORED:
9237     ierr = MatSolveTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
9238     break;
9239   case MAT_FACTOR_SCHUR_INVERTED:
9240     ierr = MatMultTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
9241     break;
9242   default:
9243     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9244     break;
9245   }
9246   PetscFunctionReturn(0);
9247 }
9248 
9249 /*@
9250   MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step
9251 
9252    Logically Collective on Mat
9253 
9254    Input Parameters:
9255 +  F - the factored matrix obtained by calling MatGetFactor()
9256 .  rhs - location where the right hand side of the Schur complement system is stored
9257 -  sol - location where the solution of the Schur complement system has to be returned
9258 
9259    Notes:
9260    The sizes of the vectors should match the size of the Schur complement
9261 
9262    Must be called after MatFactorSetSchurIS()
9263 
9264    Level: advanced
9265 
9266    References:
9267 
9268 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplementTranspose()
9269 @*/
9270 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol)
9271 {
9272   PetscErrorCode ierr;
9273 
9274   PetscFunctionBegin;
9275   PetscValidType(F,1);
9276   PetscValidType(rhs,2);
9277   PetscValidType(sol,3);
9278   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9279   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
9280   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
9281   PetscCheckSameComm(F,1,rhs,2);
9282   PetscCheckSameComm(F,1,sol,3);
9283   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9284   switch (F->schur_status) {
9285   case MAT_FACTOR_SCHUR_FACTORED:
9286     ierr = MatSolve(F->schur,rhs,sol);CHKERRQ(ierr);
9287     break;
9288   case MAT_FACTOR_SCHUR_INVERTED:
9289     ierr = MatMult(F->schur,rhs,sol);CHKERRQ(ierr);
9290     break;
9291   default:
9292     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9293     break;
9294   }
9295   PetscFunctionReturn(0);
9296 }
9297 
9298 /*@
9299   MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step
9300 
9301    Logically Collective on Mat
9302 
9303    Input Parameters:
9304 +  F - the factored matrix obtained by calling MatGetFactor()
9305 
9306    Notes:
9307     Must be called after MatFactorSetSchurIS().
9308 
9309    Call MatFactorGetSchurComplement() or  MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it.
9310 
9311    Level: advanced
9312 
9313    References:
9314 
9315 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorCreateSchurComplement()
9316 @*/
9317 PetscErrorCode MatFactorInvertSchurComplement(Mat F)
9318 {
9319   PetscErrorCode ierr;
9320 
9321   PetscFunctionBegin;
9322   PetscValidType(F,1);
9323   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9324   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0);
9325   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9326   ierr = MatFactorInvertSchurComplement_Private(F);CHKERRQ(ierr);
9327   F->schur_status = MAT_FACTOR_SCHUR_INVERTED;
9328   PetscFunctionReturn(0);
9329 }
9330 
9331 /*@
9332   MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step
9333 
9334    Logically Collective on Mat
9335 
9336    Input Parameters:
9337 +  F - the factored matrix obtained by calling MatGetFactor()
9338 
9339    Notes:
9340     Must be called after MatFactorSetSchurIS().
9341 
9342    Level: advanced
9343 
9344    References:
9345 
9346 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorInvertSchurComplement()
9347 @*/
9348 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F)
9349 {
9350   PetscErrorCode ierr;
9351 
9352   PetscFunctionBegin;
9353   PetscValidType(F,1);
9354   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9355   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0);
9356   ierr = MatFactorFactorizeSchurComplement_Private(F);CHKERRQ(ierr);
9357   F->schur_status = MAT_FACTOR_SCHUR_FACTORED;
9358   PetscFunctionReturn(0);
9359 }
9360 
9361 /*@
9362    MatPtAP - Creates the matrix product C = P^T * A * P
9363 
9364    Neighbor-wise Collective on Mat
9365 
9366    Input Parameters:
9367 +  A - the matrix
9368 .  P - the projection matrix
9369 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9370 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate
9371           if the result is a dense matrix this is irrelevent
9372 
9373    Output Parameters:
9374 .  C - the product matrix
9375 
9376    Notes:
9377    C will be created and must be destroyed by the user with MatDestroy().
9378 
9379    This routine is currently only implemented for pairs of sequential dense matrices, AIJ matrices and classes
9380    which inherit from AIJ.
9381 
9382    Level: intermediate
9383 
9384 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
9385 @*/
9386 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
9387 {
9388   PetscErrorCode ierr;
9389   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9390   PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
9391   PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9392   PetscBool      sametype;
9393 
9394   PetscFunctionBegin;
9395   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9396   PetscValidType(A,1);
9397   MatCheckPreallocated(A,1);
9398   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9399   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9400   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9401   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9402   PetscValidType(P,2);
9403   MatCheckPreallocated(P,2);
9404   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9405   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9406 
9407   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);
9408   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);
9409   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9410   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9411 
9412   if (scall == MAT_REUSE_MATRIX) {
9413     PetscValidPointer(*C,5);
9414     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9415 
9416     if (!(*C)->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You cannot use MAT_REUSE_MATRIX");
9417     ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9418     ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9419     ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr);
9420     ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9421     ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9422     PetscFunctionReturn(0);
9423   }
9424 
9425   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9426   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9427 
9428   fA = A->ops->ptap;
9429   fP = P->ops->ptap;
9430   ierr = PetscStrcmp(((PetscObject)A)->type_name,((PetscObject)P)->type_name,&sametype);CHKERRQ(ierr);
9431   if (fP == fA && sametype) {
9432     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name);
9433     ptap = fA;
9434   } else {
9435     /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
9436     char ptapname[256];
9437     ierr = PetscStrncpy(ptapname,"MatPtAP_",sizeof(ptapname));CHKERRQ(ierr);
9438     ierr = PetscStrlcat(ptapname,((PetscObject)A)->type_name,sizeof(ptapname));CHKERRQ(ierr);
9439     ierr = PetscStrlcat(ptapname,"_",sizeof(ptapname));CHKERRQ(ierr);
9440     ierr = PetscStrlcat(ptapname,((PetscObject)P)->type_name,sizeof(ptapname));CHKERRQ(ierr);
9441     ierr = PetscStrlcat(ptapname,"_C",sizeof(ptapname));CHKERRQ(ierr); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
9442     ierr = PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);CHKERRQ(ierr);
9443     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);
9444   }
9445 
9446   ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9447   ierr = (*ptap)(A,P,scall,fill,C);CHKERRQ(ierr);
9448   ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9449   if (A->symmetric_set && A->symmetric) {
9450     ierr = MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
9451   }
9452   PetscFunctionReturn(0);
9453 }
9454 
9455 /*@
9456    MatPtAPNumeric - Computes the matrix product C = P^T * A * P
9457 
9458    Neighbor-wise Collective on Mat
9459 
9460    Input Parameters:
9461 +  A - the matrix
9462 -  P - the projection matrix
9463 
9464    Output Parameters:
9465 .  C - the product matrix
9466 
9467    Notes:
9468    C must have been created by calling MatPtAPSymbolic and must be destroyed by
9469    the user using MatDeatroy().
9470 
9471    This routine is currently only implemented for pairs of AIJ matrices and classes
9472    which inherit from AIJ.  C will be of type MATAIJ.
9473 
9474    Level: intermediate
9475 
9476 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
9477 @*/
9478 PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C)
9479 {
9480   PetscErrorCode ierr;
9481 
9482   PetscFunctionBegin;
9483   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9484   PetscValidType(A,1);
9485   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9486   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9487   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9488   PetscValidType(P,2);
9489   MatCheckPreallocated(P,2);
9490   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9491   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9492   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9493   PetscValidType(C,3);
9494   MatCheckPreallocated(C,3);
9495   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9496   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);
9497   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);
9498   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);
9499   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);
9500   MatCheckPreallocated(A,1);
9501 
9502   if (!C->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You should call MatPtAPSymbolic first");
9503   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9504   ierr = (*C->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr);
9505   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9506   PetscFunctionReturn(0);
9507 }
9508 
9509 /*@
9510    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P
9511 
9512    Neighbor-wise Collective on Mat
9513 
9514    Input Parameters:
9515 +  A - the matrix
9516 -  P - the projection matrix
9517 
9518    Output Parameters:
9519 .  C - the (i,j) structure of the product matrix
9520 
9521    Notes:
9522    C will be created and must be destroyed by the user with MatDestroy().
9523 
9524    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9525    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9526    this (i,j) structure by calling MatPtAPNumeric().
9527 
9528    Level: intermediate
9529 
9530 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
9531 @*/
9532 PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
9533 {
9534   PetscErrorCode ierr;
9535 
9536   PetscFunctionBegin;
9537   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9538   PetscValidType(A,1);
9539   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9540   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9541   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9542   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9543   PetscValidType(P,2);
9544   MatCheckPreallocated(P,2);
9545   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9546   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9547   PetscValidPointer(C,3);
9548 
9549   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);
9550   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);
9551   MatCheckPreallocated(A,1);
9552 
9553   if (!A->ops->ptapsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatType %s",((PetscObject)A)->type_name);
9554   ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
9555   ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr);
9556   ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
9557 
9558   /* ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); NO! this is not always true -ma */
9559   PetscFunctionReturn(0);
9560 }
9561 
9562 /*@
9563    MatRARt - Creates the matrix product C = R * A * R^T
9564 
9565    Neighbor-wise Collective on Mat
9566 
9567    Input Parameters:
9568 +  A - the matrix
9569 .  R - the projection matrix
9570 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9571 -  fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate
9572           if the result is a dense matrix this is irrelevent
9573 
9574    Output Parameters:
9575 .  C - the product matrix
9576 
9577    Notes:
9578    C will be created and must be destroyed by the user with MatDestroy().
9579 
9580    This routine is currently only implemented for pairs of AIJ matrices and classes
9581    which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes,
9582    parallel MatRARt is implemented via explicit transpose of R, which could be very expensive.
9583    We recommend using MatPtAP().
9584 
9585    Level: intermediate
9586 
9587 .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
9588 @*/
9589 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
9590 {
9591   PetscErrorCode ierr;
9592 
9593   PetscFunctionBegin;
9594   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9595   PetscValidType(A,1);
9596   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9597   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9598   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9599   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9600   PetscValidType(R,2);
9601   MatCheckPreallocated(R,2);
9602   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9603   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9604   PetscValidPointer(C,3);
9605   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);
9606 
9607   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9608   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9609   MatCheckPreallocated(A,1);
9610 
9611   if (!A->ops->rart) {
9612     Mat Rt;
9613     ierr = MatTranspose(R,MAT_INITIAL_MATRIX,&Rt);CHKERRQ(ierr);
9614     ierr = MatMatMatMult(R,A,Rt,scall,fill,C);CHKERRQ(ierr);
9615     ierr = MatDestroy(&Rt);CHKERRQ(ierr);
9616     PetscFunctionReturn(0);
9617   }
9618   ierr = PetscLogEventBegin(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
9619   ierr = (*A->ops->rart)(A,R,scall,fill,C);CHKERRQ(ierr);
9620   ierr = PetscLogEventEnd(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
9621   PetscFunctionReturn(0);
9622 }
9623 
9624 /*@
9625    MatRARtNumeric - Computes the matrix product C = R * A * R^T
9626 
9627    Neighbor-wise Collective on Mat
9628 
9629    Input Parameters:
9630 +  A - the matrix
9631 -  R - the projection matrix
9632 
9633    Output Parameters:
9634 .  C - the product matrix
9635 
9636    Notes:
9637    C must have been created by calling MatRARtSymbolic and must be destroyed by
9638    the user using MatDestroy().
9639 
9640    This routine is currently only implemented for pairs of AIJ matrices and classes
9641    which inherit from AIJ.  C will be of type MATAIJ.
9642 
9643    Level: intermediate
9644 
9645 .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
9646 @*/
9647 PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C)
9648 {
9649   PetscErrorCode ierr;
9650 
9651   PetscFunctionBegin;
9652   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9653   PetscValidType(A,1);
9654   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9655   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9656   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9657   PetscValidType(R,2);
9658   MatCheckPreallocated(R,2);
9659   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9660   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9661   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9662   PetscValidType(C,3);
9663   MatCheckPreallocated(C,3);
9664   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9665   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);
9666   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);
9667   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);
9668   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);
9669   MatCheckPreallocated(A,1);
9670 
9671   ierr = PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
9672   ierr = (*A->ops->rartnumeric)(A,R,C);CHKERRQ(ierr);
9673   ierr = PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
9674   PetscFunctionReturn(0);
9675 }
9676 
9677 /*@
9678    MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T
9679 
9680    Neighbor-wise Collective on Mat
9681 
9682    Input Parameters:
9683 +  A - the matrix
9684 -  R - the projection matrix
9685 
9686    Output Parameters:
9687 .  C - the (i,j) structure of the product matrix
9688 
9689    Notes:
9690    C will be created and must be destroyed by the user with MatDestroy().
9691 
9692    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9693    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9694    this (i,j) structure by calling MatRARtNumeric().
9695 
9696    Level: intermediate
9697 
9698 .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
9699 @*/
9700 PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
9701 {
9702   PetscErrorCode ierr;
9703 
9704   PetscFunctionBegin;
9705   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9706   PetscValidType(A,1);
9707   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9708   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9709   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9710   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9711   PetscValidType(R,2);
9712   MatCheckPreallocated(R,2);
9713   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9714   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9715   PetscValidPointer(C,3);
9716 
9717   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);
9718   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);
9719   MatCheckPreallocated(A,1);
9720   ierr = PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
9721   ierr = (*A->ops->rartsymbolic)(A,R,fill,C);CHKERRQ(ierr);
9722   ierr = PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
9723 
9724   ierr = MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));CHKERRQ(ierr);
9725   PetscFunctionReturn(0);
9726 }
9727 
9728 /*@
9729    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
9730 
9731    Neighbor-wise Collective on Mat
9732 
9733    Input Parameters:
9734 +  A - the left matrix
9735 .  B - the right matrix
9736 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9737 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
9738           if the result is a dense matrix this is irrelevent
9739 
9740    Output Parameters:
9741 .  C - the product matrix
9742 
9743    Notes:
9744    Unless scall is MAT_REUSE_MATRIX C will be created.
9745 
9746    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
9747    call to this function with either MAT_INITIAL_MATRIX or MatMatMultSymbolic()
9748 
9749    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9750    actually needed.
9751 
9752    If you have many matrices with the same non-zero structure to multiply, you
9753    should either
9754 $   1) use MAT_REUSE_MATRIX in all calls but the first or
9755 $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
9756    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
9757    with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse.
9758 
9759    Level: intermediate
9760 
9761 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(),  MatMatTransposeMult(), MatPtAP()
9762 @*/
9763 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9764 {
9765   PetscErrorCode ierr;
9766   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9767   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9768   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9769 
9770   PetscFunctionBegin;
9771   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9772   PetscValidType(A,1);
9773   MatCheckPreallocated(A,1);
9774   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9775   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9776   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9777   PetscValidType(B,2);
9778   MatCheckPreallocated(B,2);
9779   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9780   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9781   PetscValidPointer(C,3);
9782   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9783   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);
9784   if (scall == MAT_REUSE_MATRIX) {
9785     PetscValidPointer(*C,5);
9786     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9787     ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9788     ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9789     ierr = (*(*C)->ops->matmultnumeric)(A,B,*C);CHKERRQ(ierr);
9790     ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9791     ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9792     PetscFunctionReturn(0);
9793   }
9794   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9795   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9796 
9797   fA = A->ops->matmult;
9798   fB = B->ops->matmult;
9799   if (fB == fA) {
9800     if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
9801     mult = fB;
9802   } else {
9803     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9804     char multname[256];
9805     ierr = PetscStrncpy(multname,"MatMatMult_",sizeof(multname));CHKERRQ(ierr);
9806     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
9807     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
9808     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
9809     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9810     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
9811     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);
9812   }
9813   ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9814   ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr);
9815   ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9816   PetscFunctionReturn(0);
9817 }
9818 
9819 /*@
9820    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
9821    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().
9822 
9823    Neighbor-wise Collective on Mat
9824 
9825    Input Parameters:
9826 +  A - the left matrix
9827 .  B - the right matrix
9828 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
9829       if C is a dense matrix this is irrelevent
9830 
9831    Output Parameters:
9832 .  C - the product matrix
9833 
9834    Notes:
9835    Unless scall is MAT_REUSE_MATRIX C will be created.
9836 
9837    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9838    actually needed.
9839 
9840    This routine is currently implemented for
9841     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
9842     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9843     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9844 
9845    Level: intermediate
9846 
9847    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
9848      We should incorporate them into PETSc.
9849 
9850 .seealso: MatMatMult(), MatMatMultNumeric()
9851 @*/
9852 PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
9853 {
9854   PetscErrorCode ierr;
9855   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*);
9856   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*);
9857   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL;
9858 
9859   PetscFunctionBegin;
9860   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9861   PetscValidType(A,1);
9862   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9863   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9864 
9865   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9866   PetscValidType(B,2);
9867   MatCheckPreallocated(B,2);
9868   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9869   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9870   PetscValidPointer(C,3);
9871 
9872   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);
9873   if (fill == PETSC_DEFAULT) fill = 2.0;
9874   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9875   MatCheckPreallocated(A,1);
9876 
9877   Asymbolic = A->ops->matmultsymbolic;
9878   Bsymbolic = B->ops->matmultsymbolic;
9879   if (Asymbolic == Bsymbolic) {
9880     if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
9881     symbolic = Bsymbolic;
9882   } else { /* dispatch based on the type of A and B */
9883     char symbolicname[256];
9884     ierr = PetscStrncpy(symbolicname,"MatMatMultSymbolic_",sizeof(symbolicname));CHKERRQ(ierr);
9885     ierr = PetscStrlcat(symbolicname,((PetscObject)A)->type_name,sizeof(symbolicname));CHKERRQ(ierr);
9886     ierr = PetscStrlcat(symbolicname,"_",sizeof(symbolicname));CHKERRQ(ierr);
9887     ierr = PetscStrlcat(symbolicname,((PetscObject)B)->type_name,sizeof(symbolicname));CHKERRQ(ierr);
9888     ierr = PetscStrlcat(symbolicname,"_C",sizeof(symbolicname));CHKERRQ(ierr);
9889     ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);CHKERRQ(ierr);
9890     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);
9891   }
9892   ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9893   ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr);
9894   ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9895   PetscFunctionReturn(0);
9896 }
9897 
9898 /*@
9899    MatMatMultNumeric - Performs the numeric matrix-matrix product.
9900    Call this routine after first calling MatMatMultSymbolic().
9901 
9902    Neighbor-wise Collective on Mat
9903 
9904    Input Parameters:
9905 +  A - the left matrix
9906 -  B - the right matrix
9907 
9908    Output Parameters:
9909 .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
9910 
9911    Notes:
9912    C must have been created with MatMatMultSymbolic().
9913 
9914    This routine is currently implemented for
9915     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
9916     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9917     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9918 
9919    Level: intermediate
9920 
9921 .seealso: MatMatMult(), MatMatMultSymbolic()
9922 @*/
9923 PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C)
9924 {
9925   PetscErrorCode ierr;
9926 
9927   PetscFunctionBegin;
9928   ierr = MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);CHKERRQ(ierr);
9929   PetscFunctionReturn(0);
9930 }
9931 
9932 /*@
9933    MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.
9934 
9935    Neighbor-wise Collective on Mat
9936 
9937    Input Parameters:
9938 +  A - the left matrix
9939 .  B - the right matrix
9940 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9941 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9942 
9943    Output Parameters:
9944 .  C - the product matrix
9945 
9946    Notes:
9947    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9948 
9949    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9950 
9951   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9952    actually needed.
9953 
9954    This routine is currently only implemented for pairs of SeqAIJ matrices, for the SeqDense class,
9955    and for pairs of MPIDense matrices.
9956 
9957    Options Database Keys:
9958 +  -matmattransmult_mpidense_mpidense_via {allgatherv,cyclic} - Choose between algorthims for MPIDense matrices: the
9959                                                                 first redundantly copies the transposed B matrix on each process and requiers O(log P) communication complexity;
9960                                                                 the second never stores more than one portion of the B matrix at a time by requires O(P) communication complexity.
9961 
9962    Level: intermediate
9963 
9964 .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
9965 @*/
9966 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9967 {
9968   PetscErrorCode ierr;
9969   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9970   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9971 
9972   PetscFunctionBegin;
9973   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9974   PetscValidType(A,1);
9975   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9976   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9977   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9978   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9979   PetscValidType(B,2);
9980   MatCheckPreallocated(B,2);
9981   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9982   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9983   PetscValidPointer(C,3);
9984   if (B->cmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, AN %D != BN %D",A->cmap->N,B->cmap->N);
9985   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9986   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9987   MatCheckPreallocated(A,1);
9988 
9989   fA = A->ops->mattransposemult;
9990   if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
9991   fB = B->ops->mattransposemult;
9992   if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
9993   if (fB!=fA) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatTransposeMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
9994 
9995   ierr = PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
9996   if (scall == MAT_INITIAL_MATRIX) {
9997     ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9998     ierr = (*A->ops->mattransposemultsymbolic)(A,B,fill,C);CHKERRQ(ierr);
9999     ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
10000   }
10001   ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
10002   ierr = (*A->ops->mattransposemultnumeric)(A,B,*C);CHKERRQ(ierr);
10003   ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
10004   ierr = PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
10005   PetscFunctionReturn(0);
10006 }
10007 
10008 /*@
10009    MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.
10010 
10011    Neighbor-wise Collective on Mat
10012 
10013    Input Parameters:
10014 +  A - the left matrix
10015 .  B - the right matrix
10016 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10017 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
10018 
10019    Output Parameters:
10020 .  C - the product matrix
10021 
10022    Notes:
10023    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
10024 
10025    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
10026 
10027   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
10028    actually needed.
10029 
10030    This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
10031    which inherit from SeqAIJ.  C will be of same type as the input matrices.
10032 
10033    Level: intermediate
10034 
10035 .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
10036 @*/
10037 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
10038 {
10039   PetscErrorCode ierr;
10040   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
10041   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
10042   PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL;
10043 
10044   PetscFunctionBegin;
10045   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
10046   PetscValidType(A,1);
10047   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10048   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10049   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10050   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
10051   PetscValidType(B,2);
10052   MatCheckPreallocated(B,2);
10053   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10054   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10055   PetscValidPointer(C,3);
10056   if (B->rmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->rmap->N);
10057   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
10058   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
10059   MatCheckPreallocated(A,1);
10060 
10061   fA = A->ops->transposematmult;
10062   fB = B->ops->transposematmult;
10063   if (fB==fA) {
10064     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
10065     transposematmult = fA;
10066   } else {
10067     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
10068     char multname[256];
10069     ierr = PetscStrncpy(multname,"MatTransposeMatMult_",sizeof(multname));CHKERRQ(ierr);
10070     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
10071     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
10072     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
10073     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
10074     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);CHKERRQ(ierr);
10075     if (!transposematmult) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatTransposeMatMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
10076   }
10077   ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
10078   ierr = (*transposematmult)(A,B,scall,fill,C);CHKERRQ(ierr);
10079   ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
10080   PetscFunctionReturn(0);
10081 }
10082 
10083 /*@
10084    MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.
10085 
10086    Neighbor-wise Collective on Mat
10087 
10088    Input Parameters:
10089 +  A - the left matrix
10090 .  B - the middle matrix
10091 .  C - the right matrix
10092 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10093 -  fill - expected fill as ratio of nnz(D)/(nnz(A) + nnz(B)+nnz(C)), use PETSC_DEFAULT if you do not have a good estimate
10094           if the result is a dense matrix this is irrelevent
10095 
10096    Output Parameters:
10097 .  D - the product matrix
10098 
10099    Notes:
10100    Unless scall is MAT_REUSE_MATRIX D will be created.
10101 
10102    MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call
10103 
10104    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
10105    actually needed.
10106 
10107    If you have many matrices with the same non-zero structure to multiply, you
10108    should use MAT_REUSE_MATRIX in all calls but the first or
10109 
10110    Level: intermediate
10111 
10112 .seealso: MatMatMult, MatPtAP()
10113 @*/
10114 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
10115 {
10116   PetscErrorCode ierr;
10117   PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
10118   PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
10119   PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
10120   PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
10121 
10122   PetscFunctionBegin;
10123   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
10124   PetscValidType(A,1);
10125   MatCheckPreallocated(A,1);
10126   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10127   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10128   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10129   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
10130   PetscValidType(B,2);
10131   MatCheckPreallocated(B,2);
10132   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10133   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10134   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
10135   PetscValidPointer(C,3);
10136   MatCheckPreallocated(C,3);
10137   if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10138   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10139   if (B->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
10140   if (C->rmap->N!=B->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",C->rmap->N,B->cmap->N);
10141   if (scall == MAT_REUSE_MATRIX) {
10142     PetscValidPointer(*D,6);
10143     PetscValidHeaderSpecific(*D,MAT_CLASSID,6);
10144     ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10145     ierr = (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
10146     ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10147     PetscFunctionReturn(0);
10148   }
10149   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
10150   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
10151 
10152   fA = A->ops->matmatmult;
10153   fB = B->ops->matmatmult;
10154   fC = C->ops->matmatmult;
10155   if (fA == fB && fA == fC) {
10156     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name);
10157     mult = fA;
10158   } else {
10159     /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */
10160     char multname[256];
10161     ierr = PetscStrncpy(multname,"MatMatMatMult_",sizeof(multname));CHKERRQ(ierr);
10162     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
10163     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
10164     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
10165     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
10166     ierr = PetscStrlcat(multname,((PetscObject)C)->type_name,sizeof(multname));CHKERRQ(ierr);
10167     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr);
10168     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
10169     if (!mult) SETERRQ3(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatMatMult requires A, %s, to be compatible with B, %s, C, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name,((PetscObject)C)->type_name);
10170   }
10171   ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10172   ierr = (*mult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
10173   ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10174   PetscFunctionReturn(0);
10175 }
10176 
10177 /*@
10178    MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
10179 
10180    Collective on Mat
10181 
10182    Input Parameters:
10183 +  mat - the matrix
10184 .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
10185 .  subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used)
10186 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10187 
10188    Output Parameter:
10189 .  matredundant - redundant matrix
10190 
10191    Notes:
10192    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
10193    original matrix has not changed from that last call to MatCreateRedundantMatrix().
10194 
10195    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
10196    calling it.
10197 
10198    Level: advanced
10199 
10200    Concepts: subcommunicator
10201    Concepts: duplicate matrix
10202 
10203 .seealso: MatDestroy()
10204 @*/
10205 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant)
10206 {
10207   PetscErrorCode ierr;
10208   MPI_Comm       comm;
10209   PetscMPIInt    size;
10210   PetscInt       mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs;
10211   Mat_Redundant  *redund=NULL;
10212   PetscSubcomm   psubcomm=NULL;
10213   MPI_Comm       subcomm_in=subcomm;
10214   Mat            *matseq;
10215   IS             isrow,iscol;
10216   PetscBool      newsubcomm=PETSC_FALSE;
10217 
10218   PetscFunctionBegin;
10219   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10220   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
10221     PetscValidPointer(*matredundant,5);
10222     PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5);
10223   }
10224 
10225   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
10226   if (size == 1 || nsubcomm == 1) {
10227     if (reuse == MAT_INITIAL_MATRIX) {
10228       ierr = MatDuplicate(mat,MAT_COPY_VALUES,matredundant);CHKERRQ(ierr);
10229     } else {
10230       if (*matredundant == mat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MAT_REUSE_MATRIX means reuse the matrix passed in as the final argument, not the original matrix");
10231       ierr = MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
10232     }
10233     PetscFunctionReturn(0);
10234   }
10235 
10236   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10237   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10238   MatCheckPreallocated(mat,1);
10239 
10240   ierr = PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
10241   if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */
10242     /* create psubcomm, then get subcomm */
10243     ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
10244     ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
10245     if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size);
10246 
10247     ierr = PetscSubcommCreate(comm,&psubcomm);CHKERRQ(ierr);
10248     ierr = PetscSubcommSetNumber(psubcomm,nsubcomm);CHKERRQ(ierr);
10249     ierr = PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);CHKERRQ(ierr);
10250     ierr = PetscSubcommSetFromOptions(psubcomm);CHKERRQ(ierr);
10251     ierr = PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);CHKERRQ(ierr);
10252     newsubcomm = PETSC_TRUE;
10253     ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr);
10254   }
10255 
10256   /* get isrow, iscol and a local sequential matrix matseq[0] */
10257   if (reuse == MAT_INITIAL_MATRIX) {
10258     mloc_sub = PETSC_DECIDE;
10259     nloc_sub = PETSC_DECIDE;
10260     if (bs < 1) {
10261       ierr = PetscSplitOwnership(subcomm,&mloc_sub,&M);CHKERRQ(ierr);
10262       ierr = PetscSplitOwnership(subcomm,&nloc_sub,&N);CHKERRQ(ierr);
10263     } else {
10264       ierr = PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);CHKERRQ(ierr);
10265       ierr = PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N);CHKERRQ(ierr);
10266     }
10267     ierr = MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);CHKERRQ(ierr);
10268     rstart = rend - mloc_sub;
10269     ierr = ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);CHKERRQ(ierr);
10270     ierr = ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);CHKERRQ(ierr);
10271   } else { /* reuse == MAT_REUSE_MATRIX */
10272     if (*matredundant == mat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MAT_REUSE_MATRIX means reuse the matrix passed in as the final argument, not the original matrix");
10273     /* retrieve subcomm */
10274     ierr = PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);CHKERRQ(ierr);
10275     redund = (*matredundant)->redundant;
10276     isrow  = redund->isrow;
10277     iscol  = redund->iscol;
10278     matseq = redund->matseq;
10279   }
10280   ierr = MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);CHKERRQ(ierr);
10281 
10282   /* get matredundant over subcomm */
10283   if (reuse == MAT_INITIAL_MATRIX) {
10284     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant);CHKERRQ(ierr);
10285 
10286     /* create a supporting struct and attach it to C for reuse */
10287     ierr = PetscNewLog(*matredundant,&redund);CHKERRQ(ierr);
10288     (*matredundant)->redundant = redund;
10289     redund->isrow              = isrow;
10290     redund->iscol              = iscol;
10291     redund->matseq             = matseq;
10292     if (newsubcomm) {
10293       redund->subcomm          = subcomm;
10294     } else {
10295       redund->subcomm          = MPI_COMM_NULL;
10296     }
10297   } else {
10298     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);CHKERRQ(ierr);
10299   }
10300   ierr = PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
10301   PetscFunctionReturn(0);
10302 }
10303 
10304 /*@C
10305    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
10306    a given 'mat' object. Each submatrix can span multiple procs.
10307 
10308    Collective on Mat
10309 
10310    Input Parameters:
10311 +  mat - the matrix
10312 .  subcomm - the subcommunicator obtained by com_split(comm)
10313 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10314 
10315    Output Parameter:
10316 .  subMat - 'parallel submatrices each spans a given subcomm
10317 
10318   Notes:
10319   The submatrix partition across processors is dictated by 'subComm' a
10320   communicator obtained by com_split(comm). The comm_split
10321   is not restriced to be grouped with consecutive original ranks.
10322 
10323   Due the comm_split() usage, the parallel layout of the submatrices
10324   map directly to the layout of the original matrix [wrt the local
10325   row,col partitioning]. So the original 'DiagonalMat' naturally maps
10326   into the 'DiagonalMat' of the subMat, hence it is used directly from
10327   the subMat. However the offDiagMat looses some columns - and this is
10328   reconstructed with MatSetValues()
10329 
10330   Level: advanced
10331 
10332   Concepts: subcommunicator
10333   Concepts: submatrices
10334 
10335 .seealso: MatCreateSubMatrices()
10336 @*/
10337 PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
10338 {
10339   PetscErrorCode ierr;
10340   PetscMPIInt    commsize,subCommSize;
10341 
10342   PetscFunctionBegin;
10343   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRQ(ierr);
10344   ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr);
10345   if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
10346 
10347   if (scall == MAT_REUSE_MATRIX && *subMat == mat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MAT_REUSE_MATRIX means reuse the matrix passed in as the final argument, not the original matrix");
10348   ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10349   ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr);
10350   ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10351   PetscFunctionReturn(0);
10352 }
10353 
10354 /*@
10355    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
10356 
10357    Not Collective
10358 
10359    Input Arguments:
10360    mat - matrix to extract local submatrix from
10361    isrow - local row indices for submatrix
10362    iscol - local column indices for submatrix
10363 
10364    Output Arguments:
10365    submat - the submatrix
10366 
10367    Level: intermediate
10368 
10369    Notes:
10370    The submat should be returned with MatRestoreLocalSubMatrix().
10371 
10372    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
10373    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
10374 
10375    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
10376    MatSetValuesBlockedLocal() will also be implemented.
10377 
10378    The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that
10379    matrices obtained with DMCreateMatrix() generally already have the local to global mapping provided.
10380 
10381 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping()
10382 @*/
10383 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10384 {
10385   PetscErrorCode ierr;
10386 
10387   PetscFunctionBegin;
10388   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10389   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10390   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10391   PetscCheckSameComm(isrow,2,iscol,3);
10392   PetscValidPointer(submat,4);
10393   if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call");
10394 
10395   if (mat->ops->getlocalsubmatrix) {
10396     ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10397   } else {
10398     ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr);
10399   }
10400   PetscFunctionReturn(0);
10401 }
10402 
10403 /*@
10404    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
10405 
10406    Not Collective
10407 
10408    Input Arguments:
10409    mat - matrix to extract local submatrix from
10410    isrow - local row indices for submatrix
10411    iscol - local column indices for submatrix
10412    submat - the submatrix
10413 
10414    Level: intermediate
10415 
10416 .seealso: MatGetLocalSubMatrix()
10417 @*/
10418 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10419 {
10420   PetscErrorCode ierr;
10421 
10422   PetscFunctionBegin;
10423   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10424   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10425   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10426   PetscCheckSameComm(isrow,2,iscol,3);
10427   PetscValidPointer(submat,4);
10428   if (*submat) {
10429     PetscValidHeaderSpecific(*submat,MAT_CLASSID,4);
10430   }
10431 
10432   if (mat->ops->restorelocalsubmatrix) {
10433     ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10434   } else {
10435     ierr = MatDestroy(submat);CHKERRQ(ierr);
10436   }
10437   *submat = NULL;
10438   PetscFunctionReturn(0);
10439 }
10440 
10441 /* --------------------------------------------------------*/
10442 /*@
10443    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix
10444 
10445    Collective on Mat
10446 
10447    Input Parameter:
10448 .  mat - the matrix
10449 
10450    Output Parameter:
10451 .  is - if any rows have zero diagonals this contains the list of them
10452 
10453    Level: developer
10454 
10455    Concepts: matrix-vector product
10456 
10457 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10458 @*/
10459 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is)
10460 {
10461   PetscErrorCode ierr;
10462 
10463   PetscFunctionBegin;
10464   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10465   PetscValidType(mat,1);
10466   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10467   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10468 
10469   if (!mat->ops->findzerodiagonals) {
10470     Vec                diag;
10471     const PetscScalar *a;
10472     PetscInt          *rows;
10473     PetscInt           rStart, rEnd, r, nrow = 0;
10474 
10475     ierr = MatCreateVecs(mat, &diag, NULL);CHKERRQ(ierr);
10476     ierr = MatGetDiagonal(mat, diag);CHKERRQ(ierr);
10477     ierr = MatGetOwnershipRange(mat, &rStart, &rEnd);CHKERRQ(ierr);
10478     ierr = VecGetArrayRead(diag, &a);CHKERRQ(ierr);
10479     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow;
10480     ierr = PetscMalloc1(nrow, &rows);CHKERRQ(ierr);
10481     nrow = 0;
10482     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart;
10483     ierr = VecRestoreArrayRead(diag, &a);CHKERRQ(ierr);
10484     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10485     ierr = ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);CHKERRQ(ierr);
10486   } else {
10487     ierr = (*mat->ops->findzerodiagonals)(mat, is);CHKERRQ(ierr);
10488   }
10489   PetscFunctionReturn(0);
10490 }
10491 
10492 /*@
10493    MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size)
10494 
10495    Collective on Mat
10496 
10497    Input Parameter:
10498 .  mat - the matrix
10499 
10500    Output Parameter:
10501 .  is - contains the list of rows with off block diagonal entries
10502 
10503    Level: developer
10504 
10505    Concepts: matrix-vector product
10506 
10507 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10508 @*/
10509 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is)
10510 {
10511   PetscErrorCode ierr;
10512 
10513   PetscFunctionBegin;
10514   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10515   PetscValidType(mat,1);
10516   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10517   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10518 
10519   if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined");
10520   ierr = (*mat->ops->findoffblockdiagonalentries)(mat,is);CHKERRQ(ierr);
10521   PetscFunctionReturn(0);
10522 }
10523 
10524 /*@C
10525   MatInvertBlockDiagonal - Inverts the block diagonal entries.
10526 
10527   Collective on Mat
10528 
10529   Input Parameters:
10530 . mat - the matrix
10531 
10532   Output Parameters:
10533 . values - the block inverses in column major order (FORTRAN-like)
10534 
10535    Note:
10536    This routine is not available from Fortran.
10537 
10538   Level: advanced
10539 
10540 .seealso: MatInvertBockDiagonalMat
10541 @*/
10542 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
10543 {
10544   PetscErrorCode ierr;
10545 
10546   PetscFunctionBegin;
10547   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10548   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10549   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10550   if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
10551   ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr);
10552   PetscFunctionReturn(0);
10553 }
10554 
10555 /*@C
10556   MatInvertVariableBlockDiagonal - Inverts the block diagonal entries.
10557 
10558   Collective on Mat
10559 
10560   Input Parameters:
10561 + mat - the matrix
10562 . nblocks - the number of blocks
10563 - bsizes - the size of each block
10564 
10565   Output Parameters:
10566 . values - the block inverses in column major order (FORTRAN-like)
10567 
10568    Note:
10569    This routine is not available from Fortran.
10570 
10571   Level: advanced
10572 
10573 .seealso: MatInvertBockDiagonal()
10574 @*/
10575 PetscErrorCode MatInvertVariableBlockDiagonal(Mat mat,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *values)
10576 {
10577   PetscErrorCode ierr;
10578 
10579   PetscFunctionBegin;
10580   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10581   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10582   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10583   if (!mat->ops->invertvariableblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
10584   ierr = (*mat->ops->invertvariableblockdiagonal)(mat,nblocks,bsizes,values);CHKERRQ(ierr);
10585   PetscFunctionReturn(0);
10586 }
10587 
10588 /*@
10589   MatInvertBlockDiagonalMat - set matrix C to be the inverted block diagonal of matrix A
10590 
10591   Collective on Mat
10592 
10593   Input Parameters:
10594 . A - the matrix
10595 
10596   Output Parameters:
10597 . C - matrix with inverted block diagonal of A.  This matrix should be created and may have its type set.
10598 
10599   Notes: the blocksize of the matrix is used to determine the blocks on the diagonal of C
10600 
10601   Level: advanced
10602 
10603 .seealso: MatInvertBockDiagonal()
10604 @*/
10605 PetscErrorCode MatInvertBlockDiagonalMat(Mat A,Mat C)
10606 {
10607   PetscErrorCode     ierr;
10608   const PetscScalar *vals;
10609   PetscInt          *dnnz;
10610   PetscInt           M,N,m,n,rstart,rend,bs,i,j;
10611 
10612   PetscFunctionBegin;
10613   ierr = MatInvertBlockDiagonal(A,&vals);CHKERRQ(ierr);
10614   ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr);
10615   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
10616   ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr);
10617   ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr);
10618   ierr = MatSetBlockSize(C,bs);CHKERRQ(ierr);
10619   ierr = PetscMalloc1(m/bs,&dnnz);CHKERRQ(ierr);
10620   for (j = 0; j < m/bs; j++) dnnz[j] = 1;
10621   ierr = MatXAIJSetPreallocation(C,bs,dnnz,NULL,NULL,NULL);CHKERRQ(ierr);
10622   ierr = PetscFree(dnnz);CHKERRQ(ierr);
10623   ierr = MatGetOwnershipRange(C,&rstart,&rend);CHKERRQ(ierr);
10624   ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr);
10625   for (i = rstart/bs; i < rend/bs; i++) {
10626     ierr = MatSetValuesBlocked(C,1,&i,1,&i,&vals[(i-rstart/bs)*bs*bs],INSERT_VALUES);CHKERRQ(ierr);
10627   }
10628   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10629   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10630   ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr);
10631   PetscFunctionReturn(0);
10632 }
10633 
10634 /*@C
10635     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
10636     via MatTransposeColoringCreate().
10637 
10638     Collective on MatTransposeColoring
10639 
10640     Input Parameter:
10641 .   c - coloring context
10642 
10643     Level: intermediate
10644 
10645 .seealso: MatTransposeColoringCreate()
10646 @*/
10647 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c)
10648 {
10649   PetscErrorCode       ierr;
10650   MatTransposeColoring matcolor=*c;
10651 
10652   PetscFunctionBegin;
10653   if (!matcolor) PetscFunctionReturn(0);
10654   if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; PetscFunctionReturn(0);}
10655 
10656   ierr = PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);CHKERRQ(ierr);
10657   ierr = PetscFree(matcolor->rows);CHKERRQ(ierr);
10658   ierr = PetscFree(matcolor->den2sp);CHKERRQ(ierr);
10659   ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr);
10660   ierr = PetscFree(matcolor->columns);CHKERRQ(ierr);
10661   if (matcolor->brows>0) {
10662     ierr = PetscFree(matcolor->lstart);CHKERRQ(ierr);
10663   }
10664   ierr = PetscHeaderDestroy(c);CHKERRQ(ierr);
10665   PetscFunctionReturn(0);
10666 }
10667 
10668 /*@C
10669     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
10670     a MatTransposeColoring context has been created, computes a dense B^T by Apply
10671     MatTransposeColoring to sparse B.
10672 
10673     Collective on MatTransposeColoring
10674 
10675     Input Parameters:
10676 +   B - sparse matrix B
10677 .   Btdense - symbolic dense matrix B^T
10678 -   coloring - coloring context created with MatTransposeColoringCreate()
10679 
10680     Output Parameter:
10681 .   Btdense - dense matrix B^T
10682 
10683     Level: advanced
10684 
10685      Notes:
10686     These are used internally for some implementations of MatRARt()
10687 
10688 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplyDenToSp()
10689 
10690 .keywords: coloring
10691 @*/
10692 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
10693 {
10694   PetscErrorCode ierr;
10695 
10696   PetscFunctionBegin;
10697   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
10698   PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2);
10699   PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3);
10700 
10701   if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
10702   ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr);
10703   PetscFunctionReturn(0);
10704 }
10705 
10706 /*@C
10707     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
10708     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
10709     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
10710     Csp from Cden.
10711 
10712     Collective on MatTransposeColoring
10713 
10714     Input Parameters:
10715 +   coloring - coloring context created with MatTransposeColoringCreate()
10716 -   Cden - matrix product of a sparse matrix and a dense matrix Btdense
10717 
10718     Output Parameter:
10719 .   Csp - sparse matrix
10720 
10721     Level: advanced
10722 
10723      Notes:
10724     These are used internally for some implementations of MatRARt()
10725 
10726 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()
10727 
10728 .keywords: coloring
10729 @*/
10730 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
10731 {
10732   PetscErrorCode ierr;
10733 
10734   PetscFunctionBegin;
10735   PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1);
10736   PetscValidHeaderSpecific(Cden,MAT_CLASSID,2);
10737   PetscValidHeaderSpecific(Csp,MAT_CLASSID,3);
10738 
10739   if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
10740   ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr);
10741   PetscFunctionReturn(0);
10742 }
10743 
10744 /*@C
10745    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.
10746 
10747    Collective on Mat
10748 
10749    Input Parameters:
10750 +  mat - the matrix product C
10751 -  iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring()
10752 
10753     Output Parameter:
10754 .   color - the new coloring context
10755 
10756     Level: intermediate
10757 
10758 .seealso: MatTransposeColoringDestroy(),  MatTransColoringApplySpToDen(),
10759            MatTransColoringApplyDenToSp()
10760 @*/
10761 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
10762 {
10763   MatTransposeColoring c;
10764   MPI_Comm             comm;
10765   PetscErrorCode       ierr;
10766 
10767   PetscFunctionBegin;
10768   ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10769   ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
10770   ierr = PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);CHKERRQ(ierr);
10771 
10772   c->ctype = iscoloring->ctype;
10773   if (mat->ops->transposecoloringcreate) {
10774     ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr);
10775   } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type");
10776 
10777   *color = c;
10778   ierr   = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10779   PetscFunctionReturn(0);
10780 }
10781 
10782 /*@
10783       MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the
10784         matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the
10785         same, otherwise it will be larger
10786 
10787      Not Collective
10788 
10789   Input Parameter:
10790 .    A  - the matrix
10791 
10792   Output Parameter:
10793 .    state - the current state
10794 
10795   Notes:
10796     You can only compare states from two different calls to the SAME matrix, you cannot compare calls between
10797          different matrices
10798 
10799   Level: intermediate
10800 
10801 @*/
10802 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state)
10803 {
10804   PetscFunctionBegin;
10805   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10806   *state = mat->nonzerostate;
10807   PetscFunctionReturn(0);
10808 }
10809 
10810 /*@
10811       MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential
10812                  matrices from each processor
10813 
10814     Collective on MPI_Comm
10815 
10816    Input Parameters:
10817 +    comm - the communicators the parallel matrix will live on
10818 .    seqmat - the input sequential matrices
10819 .    n - number of local columns (or PETSC_DECIDE)
10820 -    reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10821 
10822    Output Parameter:
10823 .    mpimat - the parallel matrix generated
10824 
10825     Level: advanced
10826 
10827    Notes:
10828     The number of columns of the matrix in EACH processor MUST be the same.
10829 
10830 @*/
10831 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat)
10832 {
10833   PetscErrorCode ierr;
10834 
10835   PetscFunctionBegin;
10836   if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name);
10837   if (reuse == MAT_REUSE_MATRIX && seqmat == *mpimat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MAT_REUSE_MATRIX means reuse the matrix passed in as the final argument, not the original matrix");
10838 
10839   ierr = PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10840   ierr = (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);CHKERRQ(ierr);
10841   ierr = PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10842   PetscFunctionReturn(0);
10843 }
10844 
10845 /*@
10846      MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent
10847                  ranks' ownership ranges.
10848 
10849     Collective on A
10850 
10851    Input Parameters:
10852 +    A   - the matrix to create subdomains from
10853 -    N   - requested number of subdomains
10854 
10855 
10856    Output Parameters:
10857 +    n   - number of subdomains resulting on this rank
10858 -    iss - IS list with indices of subdomains on this rank
10859 
10860     Level: advanced
10861 
10862     Notes:
10863     number of subdomains must be smaller than the communicator size
10864 @*/
10865 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[])
10866 {
10867   MPI_Comm        comm,subcomm;
10868   PetscMPIInt     size,rank,color;
10869   PetscInt        rstart,rend,k;
10870   PetscErrorCode  ierr;
10871 
10872   PetscFunctionBegin;
10873   ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr);
10874   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
10875   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
10876   if (N < 1 || N >= (PetscInt)size) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"number of subdomains must be > 0 and < %D, got N = %D",size,N);
10877   *n = 1;
10878   k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */
10879   color = rank/k;
10880   ierr = MPI_Comm_split(comm,color,rank,&subcomm);CHKERRQ(ierr);
10881   ierr = PetscMalloc1(1,iss);CHKERRQ(ierr);
10882   ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
10883   ierr = ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);CHKERRQ(ierr);
10884   ierr = MPI_Comm_free(&subcomm);CHKERRQ(ierr);
10885   PetscFunctionReturn(0);
10886 }
10887 
10888 /*@
10889    MatGalerkin - Constructs the coarse grid problem via Galerkin projection.
10890 
10891    If the interpolation and restriction operators are the same, uses MatPtAP.
10892    If they are not the same, use MatMatMatMult.
10893 
10894    Once the coarse grid problem is constructed, correct for interpolation operators
10895    that are not of full rank, which can legitimately happen in the case of non-nested
10896    geometric multigrid.
10897 
10898    Input Parameters:
10899 +  restrct - restriction operator
10900 .  dA - fine grid matrix
10901 .  interpolate - interpolation operator
10902 .  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10903 -  fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate
10904 
10905    Output Parameters:
10906 .  A - the Galerkin coarse matrix
10907 
10908    Options Database Key:
10909 .  -pc_mg_galerkin <both,pmat,mat,none>
10910 
10911    Level: developer
10912 
10913 .keywords: MG, multigrid, Galerkin
10914 
10915 .seealso: MatPtAP(), MatMatMatMult()
10916 @*/
10917 PetscErrorCode  MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A)
10918 {
10919   PetscErrorCode ierr;
10920   IS             zerorows;
10921   Vec            diag;
10922 
10923   PetscFunctionBegin;
10924   if (reuse == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10925   /* Construct the coarse grid matrix */
10926   if (interpolate == restrct) {
10927     ierr = MatPtAP(dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10928   } else {
10929     ierr = MatMatMatMult(restrct,dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10930   }
10931 
10932   /* If the interpolation matrix is not of full rank, A will have zero rows.
10933      This can legitimately happen in the case of non-nested geometric multigrid.
10934      In that event, we set the rows of the matrix to the rows of the identity,
10935      ignoring the equations (as the RHS will also be zero). */
10936 
10937   ierr = MatFindZeroRows(*A, &zerorows);CHKERRQ(ierr);
10938 
10939   if (zerorows != NULL) { /* if there are any zero rows */
10940     ierr = MatCreateVecs(*A, &diag, NULL);CHKERRQ(ierr);
10941     ierr = MatGetDiagonal(*A, diag);CHKERRQ(ierr);
10942     ierr = VecISSet(diag, zerorows, 1.0);CHKERRQ(ierr);
10943     ierr = MatDiagonalSet(*A, diag, INSERT_VALUES);CHKERRQ(ierr);
10944     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10945     ierr = ISDestroy(&zerorows);CHKERRQ(ierr);
10946   }
10947   PetscFunctionReturn(0);
10948 }
10949 
10950 /*@C
10951     MatSetOperation - Allows user to set a matrix operation for any matrix type
10952 
10953    Logically Collective on Mat
10954 
10955     Input Parameters:
10956 +   mat - the matrix
10957 .   op - the name of the operation
10958 -   f - the function that provides the operation
10959 
10960    Level: developer
10961 
10962     Usage:
10963 $      extern PetscErrorCode usermult(Mat,Vec,Vec);
10964 $      ierr = MatCreateXXX(comm,...&A);
10965 $      ierr = MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult);
10966 
10967     Notes:
10968     See the file include/petscmat.h for a complete list of matrix
10969     operations, which all have the form MATOP_<OPERATION>, where
10970     <OPERATION> is the name (in all capital letters) of the
10971     user interface routine (e.g., MatMult() -> MATOP_MULT).
10972 
10973     All user-provided functions (except for MATOP_DESTROY) should have the same calling
10974     sequence as the usual matrix interface routines, since they
10975     are intended to be accessed via the usual matrix interface
10976     routines, e.g.,
10977 $       MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec)
10978 
10979     In particular each function MUST return an error code of 0 on success and
10980     nonzero on failure.
10981 
10982     This routine is distinct from MatShellSetOperation() in that it can be called on any matrix type.
10983 
10984 .keywords: matrix, set, operation
10985 
10986 .seealso: MatGetOperation(), MatCreateShell(), MatShellSetContext(), MatShellSetOperation()
10987 @*/
10988 PetscErrorCode MatSetOperation(Mat mat,MatOperation op,void (*f)(void))
10989 {
10990   PetscFunctionBegin;
10991   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10992   if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) {
10993     mat->ops->viewnative = mat->ops->view;
10994   }
10995   (((void(**)(void))mat->ops)[op]) = f;
10996   PetscFunctionReturn(0);
10997 }
10998 
10999 /*@C
11000     MatGetOperation - Gets a matrix operation for any matrix type.
11001 
11002     Not Collective
11003 
11004     Input Parameters:
11005 +   mat - the matrix
11006 -   op - the name of the operation
11007 
11008     Output Parameter:
11009 .   f - the function that provides the operation
11010 
11011     Level: developer
11012 
11013     Usage:
11014 $      PetscErrorCode (*usermult)(Mat,Vec,Vec);
11015 $      ierr = MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult);
11016 
11017     Notes:
11018     See the file include/petscmat.h for a complete list of matrix
11019     operations, which all have the form MATOP_<OPERATION>, where
11020     <OPERATION> is the name (in all capital letters) of the
11021     user interface routine (e.g., MatMult() -> MATOP_MULT).
11022 
11023     This routine is distinct from MatShellGetOperation() in that it can be called on any matrix type.
11024 
11025 .keywords: matrix, get, operation
11026 
11027 .seealso: MatSetOperation(), MatCreateShell(), MatShellGetContext(), MatShellGetOperation()
11028 @*/
11029 PetscErrorCode MatGetOperation(Mat mat,MatOperation op,void(**f)(void))
11030 {
11031   PetscFunctionBegin;
11032   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
11033   *f = (((void (**)(void))mat->ops)[op]);
11034   PetscFunctionReturn(0);
11035 }
11036 
11037 /*@
11038     MatHasOperation - Determines whether the given matrix supports the particular
11039     operation.
11040 
11041    Not Collective
11042 
11043    Input Parameters:
11044 +  mat - the matrix
11045 -  op - the operation, for example, MATOP_GET_DIAGONAL
11046 
11047    Output Parameter:
11048 .  has - either PETSC_TRUE or PETSC_FALSE
11049 
11050    Level: advanced
11051 
11052    Notes:
11053    See the file include/petscmat.h for a complete list of matrix
11054    operations, which all have the form MATOP_<OPERATION>, where
11055    <OPERATION> is the name (in all capital letters) of the
11056    user-level routine.  E.g., MatNorm() -> MATOP_NORM.
11057 
11058 .keywords: matrix, has, operation
11059 
11060 .seealso: MatCreateShell()
11061 @*/
11062 PetscErrorCode MatHasOperation(Mat mat,MatOperation op,PetscBool *has)
11063 {
11064   PetscErrorCode ierr;
11065 
11066   PetscFunctionBegin;
11067   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
11068   PetscValidType(mat,1);
11069   PetscValidPointer(has,3);
11070   if (mat->ops->hasoperation) {
11071     ierr = (*mat->ops->hasoperation)(mat,op,has);CHKERRQ(ierr);
11072   } else {
11073     if (((void**)mat->ops)[op]) *has =  PETSC_TRUE;
11074     else {
11075       *has = PETSC_FALSE;
11076       if (op == MATOP_CREATE_SUBMATRIX) {
11077         PetscMPIInt size;
11078 
11079         ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
11080         if (size == 1) {
11081           ierr = MatHasOperation(mat,MATOP_CREATE_SUBMATRICES,has);CHKERRQ(ierr);
11082         }
11083       }
11084     }
11085   }
11086   PetscFunctionReturn(0);
11087 }
11088 
11089 /*@
11090     MatHasCongruentLayouts - Determines whether the rows and columns layouts
11091     of the matrix are congruent
11092 
11093    Collective on mat
11094 
11095    Input Parameters:
11096 .  mat - the matrix
11097 
11098    Output Parameter:
11099 .  cong - either PETSC_TRUE or PETSC_FALSE
11100 
11101    Level: beginner
11102 
11103    Notes:
11104 
11105 .keywords: matrix, has
11106 
11107 .seealso: MatCreate(), MatSetSizes()
11108 @*/
11109 PetscErrorCode MatHasCongruentLayouts(Mat mat,PetscBool *cong)
11110 {
11111   PetscErrorCode ierr;
11112 
11113   PetscFunctionBegin;
11114   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
11115   PetscValidType(mat,1);
11116   PetscValidPointer(cong,2);
11117   if (!mat->rmap || !mat->cmap) {
11118     *cong = mat->rmap == mat->cmap ? PETSC_TRUE : PETSC_FALSE;
11119     PetscFunctionReturn(0);
11120   }
11121   if (mat->congruentlayouts == PETSC_DECIDE) { /* first time we compare rows and cols layouts */
11122     ierr = PetscLayoutCompare(mat->rmap,mat->cmap,cong);CHKERRQ(ierr);
11123     if (*cong) mat->congruentlayouts = 1;
11124     else       mat->congruentlayouts = 0;
11125   } else *cong = mat->congruentlayouts ? PETSC_TRUE : PETSC_FALSE;
11126   PetscFunctionReturn(0);
11127 }
11128 
11129 /*@
11130     MatFreeIntermediateDataStructures - Free intermediate data structures created for reuse,
11131     e.g., matrx product of MatPtAP.
11132 
11133    Collective on mat
11134 
11135    Input Parameters:
11136 .  mat - the matrix
11137 
11138    Output Parameter:
11139 .  mat - the matrix with intermediate data structures released
11140 
11141    Level: advanced
11142 
11143    Notes:
11144 
11145 .keywords: matrix
11146 
11147 .seealso: MatPtAP(), MatMatMult()
11148 @*/
11149 PetscErrorCode MatFreeIntermediateDataStructures(Mat mat)
11150 {
11151   PetscErrorCode ierr;
11152 
11153   PetscFunctionBegin;
11154   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
11155   PetscValidType(mat,1);
11156   if (mat->ops->freeintermediatedatastructures) {
11157     ierr = (*mat->ops->freeintermediatedatastructures)(mat);CHKERRQ(ierr);
11158   }
11159   PetscFunctionReturn(0);
11160 }
11161