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