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