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