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