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