xref: /petsc/src/mat/interface/matrix.c (revision e5a36eccef3d6b83a2c625c30d0dfd5adb4001f2)
1 
2 /*
3    This is where the abstract matrix operations are defined
4 */
5 
6 #include <petsc/private/matimpl.h>        /*I "petscmat.h" I*/
7 #include <petsc/private/isimpl.h>
8 #include <petsc/private/vecimpl.h>
9 
10 /* Logging support */
11 PetscClassId MAT_CLASSID;
12 PetscClassId MAT_COLORING_CLASSID;
13 PetscClassId MAT_FDCOLORING_CLASSID;
14 PetscClassId MAT_TRANSPOSECOLORING_CLASSID;
15 
16 PetscLogEvent MAT_Mult, MAT_Mults, MAT_MultConstrained, MAT_MultAdd, MAT_MultTranspose;
17 PetscLogEvent MAT_MultTransposeConstrained, MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve,MAT_MatTrSolve;
18 PetscLogEvent MAT_SolveTransposeAdd, MAT_SOR, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic;
19 PetscLogEvent MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor;
20 PetscLogEvent MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin;
21 PetscLogEvent MAT_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetRowIJ, MAT_CreateSubMats, MAT_GetOrdering, MAT_RedundantMat, MAT_GetSeqNonzeroStructure;
22 PetscLogEvent MAT_IncreaseOverlap, MAT_Partitioning, MAT_PartitioningND, MAT_Coarsen, MAT_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate;
23 PetscLogEvent MAT_FDColoringSetUp, MAT_FDColoringApply,MAT_Transpose,MAT_FDColoringFunction, MAT_CreateSubMat;
24 PetscLogEvent MAT_TransposeColoringCreate;
25 PetscLogEvent MAT_MatMult, MAT_MatMultSymbolic, MAT_MatMultNumeric;
26 PetscLogEvent MAT_PtAP, MAT_PtAPSymbolic, MAT_PtAPNumeric,MAT_RARt, MAT_RARtSymbolic, MAT_RARtNumeric;
27 PetscLogEvent MAT_MatTransposeMult, MAT_MatTransposeMultSymbolic, MAT_MatTransposeMultNumeric;
28 PetscLogEvent MAT_TransposeMatMult, MAT_TransposeMatMultSymbolic, MAT_TransposeMatMultNumeric;
29 PetscLogEvent MAT_MatMatMult, MAT_MatMatMultSymbolic, MAT_MatMatMultNumeric;
30 PetscLogEvent MAT_MultHermitianTranspose,MAT_MultHermitianTransposeAdd;
31 PetscLogEvent MAT_Getsymtranspose, MAT_Getsymtransreduced, MAT_Transpose_SeqAIJ, MAT_GetBrowsOfAcols;
32 PetscLogEvent MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym;
33 PetscLogEvent MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure;
34 PetscLogEvent MAT_GetMultiProcBlock;
35 PetscLogEvent MAT_CUSPARSECopyToGPU, MAT_SetValuesBatch;
36 PetscLogEvent MAT_ViennaCLCopyToGPU;
37 PetscLogEvent MAT_Merge,MAT_Residual,MAT_SetRandom;
38 PetscLogEvent MATCOLORING_Apply,MATCOLORING_Comm,MATCOLORING_Local,MATCOLORING_ISCreate,MATCOLORING_SetUp,MATCOLORING_Weights;
39 
40 const char *const MatFactorTypes[] = {"NONE","LU","CHOLESKY","ILU","ICC","ILUDT","MatFactorType","MAT_FACTOR_",0};
41 
42 /*@
43    MatSetRandom - Sets all components of a matrix to random numbers. For sparse matrices that have been preallocated it randomly selects appropriate locations
44 
45    Logically Collective on Mat
46 
47    Input Parameters:
48 +  x  - the matrix
49 -  rctx - the random number context, formed by PetscRandomCreate(), or NULL and
50           it will create one internally.
51 
52    Output Parameter:
53 .  x  - the matrix
54 
55    Example of Usage:
56 .vb
57      PetscRandomCreate(PETSC_COMM_WORLD,&rctx);
58      MatSetRandom(x,rctx);
59      PetscRandomDestroy(rctx);
60 .ve
61 
62    Level: intermediate
63 
64    Concepts: matrix^setting to random
65    Concepts: random^matrix
66 
67 .seealso: MatZeroEntries(), MatSetValues(), PetscRandomCreate(), PetscRandomDestroy()
68 @*/
69 PetscErrorCode MatSetRandom(Mat x,PetscRandom rctx)
70 {
71   PetscErrorCode ierr;
72   PetscRandom    randObj = NULL;
73 
74   PetscFunctionBegin;
75   PetscValidHeaderSpecific(x,MAT_CLASSID,1);
76   if (rctx) PetscValidHeaderSpecific(rctx,PETSC_RANDOM_CLASSID,2);
77   PetscValidType(x,1);
78 
79   if (!x->ops->setrandom) SETERRQ1(PetscObjectComm((PetscObject)x),PETSC_ERR_SUP,"Mat type %s",((PetscObject)x)->type_name);
80 
81   if (!rctx) {
82     MPI_Comm comm;
83     ierr = PetscObjectGetComm((PetscObject)x,&comm);CHKERRQ(ierr);
84     ierr = PetscRandomCreate(comm,&randObj);CHKERRQ(ierr);
85     ierr = PetscRandomSetFromOptions(randObj);CHKERRQ(ierr);
86     rctx = randObj;
87   }
88 
89   ierr = PetscLogEventBegin(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr);
90   ierr = (*x->ops->setrandom)(x,rctx);CHKERRQ(ierr);
91   ierr = PetscLogEventEnd(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr);
92 
93   ierr = MatAssemblyBegin(x, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
94   ierr = MatAssemblyEnd(x, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
95   ierr = PetscRandomDestroy(&randObj);CHKERRQ(ierr);
96   PetscFunctionReturn(0);
97 }
98 
99 /*@
100    MatFactorGetErrorZeroPivot - returns the pivot value that was determined to be zero and the row it occurred in
101 
102    Logically Collective on Mat
103 
104    Input Parameters:
105 .  mat - the factored matrix
106 
107    Output Parameter:
108 +  pivot - the pivot value computed
109 -  row - the row that the zero pivot occurred. Note that this row must be interpreted carefully due to row reorderings and which processes
110          the share the matrix
111 
112    Level: advanced
113 
114    Notes:
115     This routine does not work for factorizations done with external packages.
116    This routine should only be called if MatGetFactorError() returns a value of MAT_FACTOR_NUMERIC_ZEROPIVOT
117 
118    This can be called on non-factored matrices that come from, for example, matrices used in SOR.
119 
120 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot()
121 @*/
122 PetscErrorCode MatFactorGetErrorZeroPivot(Mat mat,PetscReal *pivot,PetscInt *row)
123 {
124   PetscFunctionBegin;
125   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
126   *pivot = mat->factorerror_zeropivot_value;
127   *row   = mat->factorerror_zeropivot_row;
128   PetscFunctionReturn(0);
129 }
130 
131 /*@
132    MatFactorGetError - gets the error code from a factorization
133 
134    Logically Collective on Mat
135 
136    Input Parameters:
137 .  mat - the factored matrix
138 
139    Output Parameter:
140 .  err  - the error code
141 
142    Level: advanced
143 
144    Notes:
145     This can be called on non-factored matrices that come from, for example, matrices used in SOR.
146 
147 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot()
148 @*/
149 PetscErrorCode MatFactorGetError(Mat mat,MatFactorError *err)
150 {
151   PetscFunctionBegin;
152   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
153   *err = mat->factorerrortype;
154   PetscFunctionReturn(0);
155 }
156 
157 /*@
158    MatFactorClearError - clears the error code in a factorization
159 
160    Logically Collective on Mat
161 
162    Input Parameter:
163 .  mat - the factored matrix
164 
165    Level: developer
166 
167    Notes:
168     This can be called on non-factored matrices that come from, for example, matrices used in SOR.
169 
170 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorGetError(), MatFactorGetErrorZeroPivot()
171 @*/
172 PetscErrorCode MatFactorClearError(Mat mat)
173 {
174   PetscFunctionBegin;
175   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
176   mat->factorerrortype             = MAT_FACTOR_NOERROR;
177   mat->factorerror_zeropivot_value = 0.0;
178   mat->factorerror_zeropivot_row   = 0;
179   PetscFunctionReturn(0);
180 }
181 
182 PETSC_INTERN PetscErrorCode MatFindNonzeroRowsOrCols_Basic(Mat mat,PetscBool cols,PetscReal tol,IS *nonzero)
183 {
184   PetscErrorCode    ierr;
185   Vec               r,l;
186   const PetscScalar *al;
187   PetscInt          i,nz,gnz,N,n;
188 
189   PetscFunctionBegin;
190   ierr = MatCreateVecs(mat,&r,&l);CHKERRQ(ierr);
191   if (!cols) { /* nonzero rows */
192     ierr = MatGetSize(mat,&N,NULL);CHKERRQ(ierr);
193     ierr = MatGetLocalSize(mat,&n,NULL);CHKERRQ(ierr);
194     ierr = VecSet(l,0.0);CHKERRQ(ierr);
195     ierr = VecSetRandom(r,NULL);CHKERRQ(ierr);
196     ierr = MatMult(mat,r,l);CHKERRQ(ierr);
197     ierr = VecGetArrayRead(l,&al);CHKERRQ(ierr);
198   } else { /* nonzero columns */
199     ierr = MatGetSize(mat,NULL,&N);CHKERRQ(ierr);
200     ierr = MatGetLocalSize(mat,NULL,&n);CHKERRQ(ierr);
201     ierr = VecSet(r,0.0);CHKERRQ(ierr);
202     ierr = VecSetRandom(l,NULL);CHKERRQ(ierr);
203     ierr = MatMultTranspose(mat,l,r);CHKERRQ(ierr);
204     ierr = VecGetArrayRead(r,&al);CHKERRQ(ierr);
205   }
206   if (tol <= 0.0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nz++; }
207   else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nz++; }
208   ierr = MPIU_Allreduce(&nz,&gnz,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr);
209   if (gnz != N) {
210     PetscInt *nzr;
211     ierr = PetscMalloc1(nz,&nzr);CHKERRQ(ierr);
212     if (nz) {
213       if (tol < 0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nzr[nz++] = i; }
214       else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nzr[nz++] = i; }
215     }
216     ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),nz,nzr,PETSC_OWN_POINTER,nonzero);CHKERRQ(ierr);
217   } else *nonzero = NULL;
218   if (!cols) { /* nonzero rows */
219     ierr = VecRestoreArrayRead(l,&al);CHKERRQ(ierr);
220   } else {
221     ierr = VecRestoreArrayRead(r,&al);CHKERRQ(ierr);
222   }
223   ierr = VecDestroy(&l);CHKERRQ(ierr);
224   ierr = VecDestroy(&r);CHKERRQ(ierr);
225   PetscFunctionReturn(0);
226 }
227 
228 /*@
229       MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix
230 
231   Input Parameter:
232 .    A  - the matrix
233 
234   Output Parameter:
235 .    keptrows - the rows that are not completely zero
236 
237   Notes:
238     keptrows is set to NULL if all rows are nonzero.
239 
240   Level: intermediate
241 
242  @*/
243 PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows)
244 {
245   PetscErrorCode ierr;
246 
247   PetscFunctionBegin;
248   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
249   PetscValidType(mat,1);
250   PetscValidPointer(keptrows,2);
251   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
252   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
253   if (!mat->ops->findnonzerorows) {
254     ierr = MatFindNonzeroRowsOrCols_Basic(mat,PETSC_FALSE,0.0,keptrows);CHKERRQ(ierr);
255   } else {
256     ierr = (*mat->ops->findnonzerorows)(mat,keptrows);CHKERRQ(ierr);
257   }
258   PetscFunctionReturn(0);
259 }
260 
261 /*@
262       MatFindZeroRows - Locate all rows that are completely zero in the matrix
263 
264   Input Parameter:
265 .    A  - the matrix
266 
267   Output Parameter:
268 .    zerorows - the rows that are completely zero
269 
270   Notes:
271     zerorows is set to NULL if no rows are zero.
272 
273   Level: intermediate
274 
275  @*/
276 PetscErrorCode MatFindZeroRows(Mat mat,IS *zerorows)
277 {
278   PetscErrorCode ierr;
279   IS keptrows;
280   PetscInt m, n;
281 
282   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
283   PetscValidType(mat,1);
284 
285   ierr = MatFindNonzeroRows(mat, &keptrows);CHKERRQ(ierr);
286   /* MatFindNonzeroRows sets keptrows to NULL if there are no zero rows.
287      In keeping with this convention, we set zerorows to NULL if there are no zero
288      rows. */
289   if (keptrows == NULL) {
290     *zerorows = NULL;
291   } else {
292     ierr = MatGetOwnershipRange(mat,&m,&n);CHKERRQ(ierr);
293     ierr = ISComplement(keptrows,m,n,zerorows);CHKERRQ(ierr);
294     ierr = ISDestroy(&keptrows);CHKERRQ(ierr);
295   }
296   PetscFunctionReturn(0);
297 }
298 
299 /*@
300    MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling
301 
302    Not Collective
303 
304    Input Parameters:
305 .   A - the matrix
306 
307    Output Parameters:
308 .   a - the diagonal part (which is a SEQUENTIAL matrix)
309 
310    Notes:
311     see the manual page for MatCreateAIJ() for more information on the "diagonal part" of the matrix.
312           Use caution, as the reference count on the returned matrix is not incremented and it is used as
313 	  part of the containing MPI Mat's normal operation.
314 
315    Level: advanced
316 
317 @*/
318 PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a)
319 {
320   PetscErrorCode ierr;
321 
322   PetscFunctionBegin;
323   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
324   PetscValidType(A,1);
325   PetscValidPointer(a,3);
326   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
327   if (!A->ops->getdiagonalblock) {
328     PetscMPIInt size;
329     ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);CHKERRQ(ierr);
330     if (size == 1) {
331       *a = A;
332       PetscFunctionReturn(0);
333     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Not coded for this matrix type");
334   }
335   ierr = (*A->ops->getdiagonalblock)(A,a);CHKERRQ(ierr);
336   PetscFunctionReturn(0);
337 }
338 
339 /*@
340    MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries.
341 
342    Collective on Mat
343 
344    Input Parameters:
345 .  mat - the matrix
346 
347    Output Parameter:
348 .   trace - the sum of the diagonal entries
349 
350    Level: advanced
351 
352 @*/
353 PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace)
354 {
355   PetscErrorCode ierr;
356   Vec            diag;
357 
358   PetscFunctionBegin;
359   ierr = MatCreateVecs(mat,&diag,NULL);CHKERRQ(ierr);
360   ierr = MatGetDiagonal(mat,diag);CHKERRQ(ierr);
361   ierr = VecSum(diag,trace);CHKERRQ(ierr);
362   ierr = VecDestroy(&diag);CHKERRQ(ierr);
363   PetscFunctionReturn(0);
364 }
365 
366 /*@
367    MatRealPart - Zeros out the imaginary part of the matrix
368 
369    Logically Collective on Mat
370 
371    Input Parameters:
372 .  mat - the matrix
373 
374    Level: advanced
375 
376 
377 .seealso: MatImaginaryPart()
378 @*/
379 PetscErrorCode MatRealPart(Mat mat)
380 {
381   PetscErrorCode ierr;
382 
383   PetscFunctionBegin;
384   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
385   PetscValidType(mat,1);
386   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
387   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
388   if (!mat->ops->realpart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
389   MatCheckPreallocated(mat,1);
390   ierr = (*mat->ops->realpart)(mat);CHKERRQ(ierr);
391 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
392   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
393     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
394   }
395 #endif
396   PetscFunctionReturn(0);
397 }
398 
399 /*@C
400    MatGetGhosts - Get the global index of all ghost nodes defined by the sparse matrix
401 
402    Collective on Mat
403 
404    Input Parameter:
405 .  mat - the matrix
406 
407    Output Parameters:
408 +   nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block)
409 -   ghosts - the global indices of the ghost points
410 
411    Notes:
412     the nghosts and ghosts are suitable to pass into VecCreateGhost()
413 
414    Level: advanced
415 
416 @*/
417 PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[])
418 {
419   PetscErrorCode ierr;
420 
421   PetscFunctionBegin;
422   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
423   PetscValidType(mat,1);
424   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
425   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
426   if (!mat->ops->getghosts) {
427     if (nghosts) *nghosts = 0;
428     if (ghosts) *ghosts = 0;
429   } else {
430     ierr = (*mat->ops->getghosts)(mat,nghosts,ghosts);CHKERRQ(ierr);
431   }
432   PetscFunctionReturn(0);
433 }
434 
435 
436 /*@
437    MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part
438 
439    Logically Collective on Mat
440 
441    Input Parameters:
442 .  mat - the matrix
443 
444    Level: advanced
445 
446 
447 .seealso: MatRealPart()
448 @*/
449 PetscErrorCode MatImaginaryPart(Mat mat)
450 {
451   PetscErrorCode ierr;
452 
453   PetscFunctionBegin;
454   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
455   PetscValidType(mat,1);
456   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
457   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
458   if (!mat->ops->imaginarypart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
459   MatCheckPreallocated(mat,1);
460   ierr = (*mat->ops->imaginarypart)(mat);CHKERRQ(ierr);
461 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
462   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
463     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
464   }
465 #endif
466   PetscFunctionReturn(0);
467 }
468 
469 /*@
470    MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices)
471 
472    Not Collective
473 
474    Input Parameter:
475 .  mat - the matrix
476 
477    Output Parameters:
478 +  missing - is any diagonal missing
479 -  dd - first diagonal entry that is missing (optional) on this process
480 
481    Level: advanced
482 
483 
484 .seealso: MatRealPart()
485 @*/
486 PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd)
487 {
488   PetscErrorCode ierr;
489 
490   PetscFunctionBegin;
491   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
492   PetscValidType(mat,1);
493   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
494   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
495   if (!mat->ops->missingdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
496   ierr = (*mat->ops->missingdiagonal)(mat,missing,dd);CHKERRQ(ierr);
497   PetscFunctionReturn(0);
498 }
499 
500 /*@C
501    MatGetRow - Gets a row of a matrix.  You MUST call MatRestoreRow()
502    for each row that you get to ensure that your application does
503    not bleed memory.
504 
505    Not Collective
506 
507    Input Parameters:
508 +  mat - the matrix
509 -  row - the row to get
510 
511    Output Parameters:
512 +  ncols -  if not NULL, the number of nonzeros in the row
513 .  cols - if not NULL, the column numbers
514 -  vals - if not NULL, the values
515 
516    Notes:
517    This routine is provided for people who need to have direct access
518    to the structure of a matrix.  We hope that we provide enough
519    high-level matrix routines that few users will need it.
520 
521    MatGetRow() always returns 0-based column indices, regardless of
522    whether the internal representation is 0-based (default) or 1-based.
523 
524    For better efficiency, set cols and/or vals to NULL if you do
525    not wish to extract these quantities.
526 
527    The user can only examine the values extracted with MatGetRow();
528    the values cannot be altered.  To change the matrix entries, one
529    must use MatSetValues().
530 
531    You can only have one call to MatGetRow() outstanding for a particular
532    matrix at a time, per processor. MatGetRow() can only obtain rows
533    associated with the given processor, it cannot get rows from the
534    other processors; for that we suggest using MatCreateSubMatrices(), then
535    MatGetRow() on the submatrix. The row index passed to MatGetRow()
536    is in the global number of rows.
537 
538    Fortran Notes:
539    The calling sequence from Fortran is
540 .vb
541    MatGetRow(matrix,row,ncols,cols,values,ierr)
542          Mat     matrix (input)
543          integer row    (input)
544          integer ncols  (output)
545          integer cols(maxcols) (output)
546          double precision (or double complex) values(maxcols) output
547 .ve
548    where maxcols >= maximum nonzeros in any row of the matrix.
549 
550 
551    Caution:
552    Do not try to change the contents of the output arrays (cols and vals).
553    In some cases, this may corrupt the matrix.
554 
555    Level: advanced
556 
557    Concepts: matrices^row access
558 
559 .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatCreateSubMatrices(), MatGetDiagonal()
560 @*/
561 PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
562 {
563   PetscErrorCode ierr;
564   PetscInt       incols;
565 
566   PetscFunctionBegin;
567   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
568   PetscValidType(mat,1);
569   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
570   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
571   if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
572   MatCheckPreallocated(mat,1);
573   ierr = PetscLogEventBegin(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr);
574   ierr = (*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals);CHKERRQ(ierr);
575   if (ncols) *ncols = incols;
576   ierr = PetscLogEventEnd(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr);
577   PetscFunctionReturn(0);
578 }
579 
580 /*@
581    MatConjugate - replaces the matrix values with their complex conjugates
582 
583    Logically Collective on Mat
584 
585    Input Parameters:
586 .  mat - the matrix
587 
588    Level: advanced
589 
590 .seealso:  VecConjugate()
591 @*/
592 PetscErrorCode MatConjugate(Mat mat)
593 {
594 #if defined(PETSC_USE_COMPLEX)
595   PetscErrorCode ierr;
596 
597   PetscFunctionBegin;
598   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
599   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
600   if (!mat->ops->conjugate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not provided for this matrix format, send email to petsc-maint@mcs.anl.gov");
601   ierr = (*mat->ops->conjugate)(mat);CHKERRQ(ierr);
602 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
603   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
604     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
605   }
606 #endif
607   PetscFunctionReturn(0);
608 #else
609   return 0;
610 #endif
611 }
612 
613 /*@C
614    MatRestoreRow - Frees any temporary space allocated by MatGetRow().
615 
616    Not Collective
617 
618    Input Parameters:
619 +  mat - the matrix
620 .  row - the row to get
621 .  ncols, cols - the number of nonzeros and their columns
622 -  vals - if nonzero the column values
623 
624    Notes:
625    This routine should be called after you have finished examining the entries.
626 
627    This routine zeros out ncols, cols, and vals. This is to prevent accidental
628    us of the array after it has been restored. If you pass NULL, it will
629    not zero the pointers.  Use of cols or vals after MatRestoreRow is invalid.
630 
631    Fortran Notes:
632    The calling sequence from Fortran is
633 .vb
634    MatRestoreRow(matrix,row,ncols,cols,values,ierr)
635       Mat     matrix (input)
636       integer row    (input)
637       integer ncols  (output)
638       integer cols(maxcols) (output)
639       double precision (or double complex) values(maxcols) output
640 .ve
641    Where maxcols >= maximum nonzeros in any row of the matrix.
642 
643    In Fortran MatRestoreRow() MUST be called after MatGetRow()
644    before another call to MatGetRow() can be made.
645 
646    Level: advanced
647 
648 .seealso:  MatGetRow()
649 @*/
650 PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
651 {
652   PetscErrorCode ierr;
653 
654   PetscFunctionBegin;
655   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
656   if (ncols) PetscValidIntPointer(ncols,3);
657   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
658   if (!mat->ops->restorerow) PetscFunctionReturn(0);
659   ierr = (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);CHKERRQ(ierr);
660   if (ncols) *ncols = 0;
661   if (cols)  *cols = NULL;
662   if (vals)  *vals = NULL;
663   PetscFunctionReturn(0);
664 }
665 
666 /*@
667    MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format.
668    You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag.
669 
670    Not Collective
671 
672    Input Parameters:
673 +  mat - the matrix
674 
675    Notes:
676    The flag is to ensure that users are aware of MatGetRow() only provides the upper trianglular part of the row for the matrices in MATSBAIJ format.
677 
678    Level: advanced
679 
680    Concepts: matrices^row access
681 
682 .seealso: MatRestoreRowRowUpperTriangular()
683 @*/
684 PetscErrorCode MatGetRowUpperTriangular(Mat mat)
685 {
686   PetscErrorCode ierr;
687 
688   PetscFunctionBegin;
689   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
690   PetscValidType(mat,1);
691   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
692   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
693   if (!mat->ops->getrowuppertriangular) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
694   MatCheckPreallocated(mat,1);
695   ierr = (*mat->ops->getrowuppertriangular)(mat);CHKERRQ(ierr);
696   PetscFunctionReturn(0);
697 }
698 
699 /*@
700    MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format.
701 
702    Not Collective
703 
704    Input Parameters:
705 +  mat - the matrix
706 
707    Notes:
708    This routine should be called after you have finished MatGetRow/MatRestoreRow().
709 
710 
711    Level: advanced
712 
713 .seealso:  MatGetRowUpperTriangular()
714 @*/
715 PetscErrorCode MatRestoreRowUpperTriangular(Mat mat)
716 {
717   PetscErrorCode ierr;
718 
719   PetscFunctionBegin;
720   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
721   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
722   if (!mat->ops->restorerowuppertriangular) PetscFunctionReturn(0);
723   ierr = (*mat->ops->restorerowuppertriangular)(mat);CHKERRQ(ierr);
724   PetscFunctionReturn(0);
725 }
726 
727 /*@C
728    MatSetOptionsPrefix - Sets the prefix used for searching for all
729    Mat options in the database.
730 
731    Logically Collective on Mat
732 
733    Input Parameter:
734 +  A - the Mat context
735 -  prefix - the prefix to prepend to all option names
736 
737    Notes:
738    A hyphen (-) must NOT be given at the beginning of the prefix name.
739    The first character of all runtime options is AUTOMATICALLY the hyphen.
740 
741    Level: advanced
742 
743 .keywords: Mat, set, options, prefix, database
744 
745 .seealso: MatSetFromOptions()
746 @*/
747 PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[])
748 {
749   PetscErrorCode ierr;
750 
751   PetscFunctionBegin;
752   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
753   ierr = PetscObjectSetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
754   PetscFunctionReturn(0);
755 }
756 
757 /*@C
758    MatAppendOptionsPrefix - Appends to the prefix used for searching for all
759    Mat options in the database.
760 
761    Logically Collective on Mat
762 
763    Input Parameters:
764 +  A - the Mat context
765 -  prefix - the prefix to prepend to all option names
766 
767    Notes:
768    A hyphen (-) must NOT be given at the beginning of the prefix name.
769    The first character of all runtime options is AUTOMATICALLY the hyphen.
770 
771    Level: advanced
772 
773 .keywords: Mat, append, options, prefix, database
774 
775 .seealso: MatGetOptionsPrefix()
776 @*/
777 PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[])
778 {
779   PetscErrorCode ierr;
780 
781   PetscFunctionBegin;
782   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
783   ierr = PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
784   PetscFunctionReturn(0);
785 }
786 
787 /*@C
788    MatGetOptionsPrefix - Sets the prefix used for searching for all
789    Mat options in the database.
790 
791    Not Collective
792 
793    Input Parameter:
794 .  A - the Mat context
795 
796    Output Parameter:
797 .  prefix - pointer to the prefix string used
798 
799    Notes:
800     On the fortran side, the user should pass in a string 'prefix' of
801    sufficient length to hold the prefix.
802 
803    Level: advanced
804 
805 .keywords: Mat, get, options, prefix, database
806 
807 .seealso: MatAppendOptionsPrefix()
808 @*/
809 PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[])
810 {
811   PetscErrorCode ierr;
812 
813   PetscFunctionBegin;
814   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
815   ierr = PetscObjectGetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
816   PetscFunctionReturn(0);
817 }
818 
819 /*@
820    MatResetPreallocation - Reset mat to use the original nonzero pattern provided by users.
821 
822    Collective on Mat
823 
824    Input Parameters:
825 .  A - the Mat context
826 
827    Notes:
828    The allocated memory will be shrunk after calling MatAssembly with MAT_FINAL_ASSEMBLY. Users can reset the preallocation to access the original memory.
829    Currently support MPIAIJ and SEQAIJ.
830 
831    Level: beginner
832 
833 .keywords: Mat, ResetPreallocation
834 
835 .seealso: MatSeqAIJSetPreallocation(), MatMPIAIJSetPreallocation(), MatXAIJSetPreallocation()
836 @*/
837 PetscErrorCode MatResetPreallocation(Mat A)
838 {
839   PetscErrorCode ierr;
840 
841   PetscFunctionBegin;
842   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
843   PetscValidType(A,1);
844   ierr = PetscUseMethod(A,"MatResetPreallocation_C",(Mat),(A));CHKERRQ(ierr);
845   PetscFunctionReturn(0);
846 }
847 
848 
849 /*@
850    MatSetUp - Sets up the internal matrix data structures for the later use.
851 
852    Collective on Mat
853 
854    Input Parameters:
855 .  A - the Mat context
856 
857    Notes:
858    If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used.
859 
860    If a suitable preallocation routine is used, this function does not need to be called.
861 
862    See the Performance chapter of the PETSc users manual for how to preallocate matrices
863 
864    Level: beginner
865 
866 .keywords: Mat, setup
867 
868 .seealso: MatCreate(), MatDestroy()
869 @*/
870 PetscErrorCode MatSetUp(Mat A)
871 {
872   PetscMPIInt    size;
873   PetscErrorCode ierr;
874 
875   PetscFunctionBegin;
876   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
877   if (!((PetscObject)A)->type_name) {
878     ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A), &size);CHKERRQ(ierr);
879     if (size == 1) {
880       ierr = MatSetType(A, MATSEQAIJ);CHKERRQ(ierr);
881     } else {
882       ierr = MatSetType(A, MATMPIAIJ);CHKERRQ(ierr);
883     }
884   }
885   if (!A->preallocated && A->ops->setup) {
886     ierr = PetscInfo(A,"Warning not preallocating matrix storage\n");CHKERRQ(ierr);
887     ierr = (*A->ops->setup)(A);CHKERRQ(ierr);
888   }
889   ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr);
890   ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr);
891   A->preallocated = PETSC_TRUE;
892   PetscFunctionReturn(0);
893 }
894 
895 #if defined(PETSC_HAVE_SAWS)
896 #include <petscviewersaws.h>
897 #endif
898 /*@C
899    MatView - Visualizes a matrix object.
900 
901    Collective on Mat
902 
903    Input Parameters:
904 +  mat - the matrix
905 -  viewer - visualization context
906 
907   Notes:
908   The available visualization contexts include
909 +    PETSC_VIEWER_STDOUT_SELF - for sequential matrices
910 .    PETSC_VIEWER_STDOUT_WORLD - for parallel matrices created on PETSC_COMM_WORLD
911 .    PETSC_VIEWER_STDOUT_(comm) - for matrices created on MPI communicator comm
912 -     PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure
913 
914    The user can open alternative visualization contexts with
915 +    PetscViewerASCIIOpen() - Outputs matrix to a specified file
916 .    PetscViewerBinaryOpen() - Outputs matrix in binary to a
917          specified file; corresponding input uses MatLoad()
918 .    PetscViewerDrawOpen() - Outputs nonzero matrix structure to
919          an X window display
920 -    PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
921          Currently only the sequential dense and AIJ
922          matrix types support the Socket viewer.
923 
924    The user can call PetscViewerPushFormat() to specify the output
925    format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
926    PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen).  Available formats include
927 +    PETSC_VIEWER_DEFAULT - default, prints matrix contents
928 .    PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
929 .    PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
930 .    PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse
931          format common among all matrix types
932 .    PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific
933          format (which is in many cases the same as the default)
934 .    PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
935          size and structure (not the matrix entries)
936 -    PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about
937          the matrix structure
938 
939    Options Database Keys:
940 +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatAssemblyEnd()
941 .  -mat_view ::ascii_info_detail - Prints more detailed info
942 .  -mat_view - Prints matrix in ASCII format
943 .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
944 .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
945 .  -display <name> - Sets display name (default is host)
946 .  -draw_pause <sec> - Sets number of seconds to pause after display
947 .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: ch_matlab for details)
948 .  -viewer_socket_machine <machine> -
949 .  -viewer_socket_port <port> -
950 .  -mat_view binary - save matrix to file in binary format
951 -  -viewer_binary_filename <name> -
952    Level: beginner
953 
954    Notes:
955     The ASCII viewers are only recommended for small matrices on at most a moderate number of processes,
956     the program will seemingly hang and take hours for larger matrices, for larger matrices one should use the binary format.
957 
958     See the manual page for MatLoad() for the exact format of the binary file when the binary
959       viewer is used.
960 
961       See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary
962       viewer is used.
963 
964       One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure,
965       and then use the following mouse functions.
966 + left mouse: zoom in
967 . middle mouse: zoom out
968 - right mouse: continue with the simulation
969 
970    Concepts: matrices^viewing
971    Concepts: matrices^plotting
972    Concepts: matrices^printing
973 
974 .seealso: PetscViewerPushFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(),
975           PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
976 @*/
977 PetscErrorCode MatView(Mat mat,PetscViewer viewer)
978 {
979   PetscErrorCode    ierr;
980   PetscInt          rows,cols,rbs,cbs;
981   PetscBool         iascii,ibinary;
982   PetscViewerFormat format;
983   PetscMPIInt       size;
984 #if defined(PETSC_HAVE_SAWS)
985   PetscBool         issaws;
986 #endif
987 
988   PetscFunctionBegin;
989   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
990   PetscValidType(mat,1);
991   if (!viewer) {
992     ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);CHKERRQ(ierr);
993   }
994   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
995   PetscCheckSameComm(mat,1,viewer,2);
996   MatCheckPreallocated(mat,1);
997   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
998   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
999   if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(0);
1000   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr);
1001   if (ibinary) {
1002     PetscBool mpiio;
1003     ierr = PetscViewerBinaryGetUseMPIIO(viewer,&mpiio);CHKERRQ(ierr);
1004     if (mpiio) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"PETSc matrix viewers do not support using MPI-IO, turn off that flag");
1005   }
1006 
1007   ierr = PetscLogEventBegin(MAT_View,mat,viewer,0,0);CHKERRQ(ierr);
1008   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1009   if ((!iascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) {
1010     SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detailed");
1011   }
1012 
1013 #if defined(PETSC_HAVE_SAWS)
1014   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr);
1015 #endif
1016   if (iascii) {
1017     if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
1018     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer);CHKERRQ(ierr);
1019     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
1020       MatNullSpace nullsp,transnullsp;
1021 
1022       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1023       ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr);
1024       ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr);
1025       if (rbs != 1 || cbs != 1) {
1026         if (rbs != cbs) {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, rbs=%D, cbs = %D\n",rows,cols,rbs,cbs);CHKERRQ(ierr);}
1027         else            {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,rbs);CHKERRQ(ierr);}
1028       } else {
1029         ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);CHKERRQ(ierr);
1030       }
1031       if (mat->factortype) {
1032         MatSolverType solver;
1033         ierr = MatFactorGetSolverType(mat,&solver);CHKERRQ(ierr);
1034         ierr = PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);CHKERRQ(ierr);
1035       }
1036       if (mat->ops->getinfo) {
1037         MatInfo info;
1038         ierr = MatGetInfo(mat,MAT_GLOBAL_SUM,&info);CHKERRQ(ierr);
1039         ierr = PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated);CHKERRQ(ierr);
1040         ierr = PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls =%D\n",(PetscInt)info.mallocs);CHKERRQ(ierr);
1041       }
1042       ierr = MatGetNullSpace(mat,&nullsp);CHKERRQ(ierr);
1043       ierr = MatGetTransposeNullSpace(mat,&transnullsp);CHKERRQ(ierr);
1044       if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer,"  has attached null space\n");CHKERRQ(ierr);}
1045       if (transnullsp && transnullsp != nullsp) {ierr = PetscViewerASCIIPrintf(viewer,"  has attached transposed null space\n");CHKERRQ(ierr);}
1046       ierr = MatGetNearNullSpace(mat,&nullsp);CHKERRQ(ierr);
1047       if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer,"  has attached near null space\n");CHKERRQ(ierr);}
1048     }
1049 #if defined(PETSC_HAVE_SAWS)
1050   } else if (issaws) {
1051     PetscMPIInt rank;
1052 
1053     ierr = PetscObjectName((PetscObject)mat);CHKERRQ(ierr);
1054     ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
1055     if (!((PetscObject)mat)->amsmem && !rank) {
1056       ierr = PetscObjectViewSAWs((PetscObject)mat,viewer);CHKERRQ(ierr);
1057     }
1058 #endif
1059   }
1060   if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && mat->ops->viewnative) {
1061     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1062     ierr = (*mat->ops->viewnative)(mat,viewer);CHKERRQ(ierr);
1063     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1064   } else if (mat->ops->view) {
1065     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1066     ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr);
1067     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1068   }
1069   if (iascii) {
1070     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1071     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
1072       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1073     }
1074   }
1075   ierr = PetscLogEventEnd(MAT_View,mat,viewer,0,0);CHKERRQ(ierr);
1076   PetscFunctionReturn(0);
1077 }
1078 
1079 #if defined(PETSC_USE_DEBUG)
1080 #include <../src/sys/totalview/tv_data_display.h>
1081 PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat)
1082 {
1083   TV_add_row("Local rows", "int", &mat->rmap->n);
1084   TV_add_row("Local columns", "int", &mat->cmap->n);
1085   TV_add_row("Global rows", "int", &mat->rmap->N);
1086   TV_add_row("Global columns", "int", &mat->cmap->N);
1087   TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name);
1088   return TV_format_OK;
1089 }
1090 #endif
1091 
1092 /*@C
1093    MatLoad - Loads a matrix that has been stored in binary/HDF5 format
1094    with MatView().  The matrix format is determined from the options database.
1095    Generates a parallel MPI matrix if the communicator has more than one
1096    processor.  The default matrix type is AIJ.
1097 
1098    Collective on PetscViewer
1099 
1100    Input Parameters:
1101 +  newmat - the newly loaded matrix, this needs to have been created with MatCreate()
1102             or some related function before a call to MatLoad()
1103 -  viewer - binary/HDF5 file viewer
1104 
1105    Options Database Keys:
1106    Used with block matrix formats (MATSEQBAIJ,  ...) to specify
1107    block size
1108 .    -matload_block_size <bs>
1109 
1110    Level: beginner
1111 
1112    Notes:
1113    If the Mat type has not yet been given then MATAIJ is used, call MatSetFromOptions() on the
1114    Mat before calling this routine if you wish to set it from the options database.
1115 
1116    MatLoad() automatically loads into the options database any options
1117    given in the file filename.info where filename is the name of the file
1118    that was passed to the PetscViewerBinaryOpen(). The options in the info
1119    file will be ignored if you use the -viewer_binary_skip_info option.
1120 
1121    If the type or size of newmat is not set before a call to MatLoad, PETSc
1122    sets the default matrix type AIJ and sets the local and global sizes.
1123    If type and/or size is already set, then the same are used.
1124 
1125    In parallel, each processor can load a subset of rows (or the
1126    entire matrix).  This routine is especially useful when a large
1127    matrix is stored on disk and only part of it is desired on each
1128    processor.  For example, a parallel solver may access only some of
1129    the rows from each processor.  The algorithm used here reads
1130    relatively small blocks of data rather than reading the entire
1131    matrix and then subsetting it.
1132 
1133    Viewer's PetscViewerType must be either PETSCVIEWERBINARY or PETSCVIEWERHDF5.
1134    Such viewer can be created using PetscViewerBinaryOpen()/PetscViewerHDF5Open(),
1135    or the sequence like
1136 $    PetscViewer v;
1137 $    PetscViewerCreate(PETSC_COMM_WORLD,&v);
1138 $    PetscViewerSetType(v,PETSCVIEWERBINARY);
1139 $    PetscViewerSetFromOptions(v);
1140 $    PetscViewerFileSetMode(v,FILE_MODE_READ);
1141 $    PetscViewerFileSetName(v,"datafile");
1142    The optional PetscViewerSetFromOptions() call allows to override PetscViewerSetType() using option
1143 $ -viewer_type {binary,hdf5}
1144 
1145    See the example src/ksp/ksp/examples/tutorials/ex27.c with the first approach,
1146    and src/mat/examples/tutorials/ex10.c with the second approach.
1147 
1148    Notes about the PETSc binary format:
1149    In case of PETSCVIEWERBINARY, a native PETSc binary format is used. Each of the blocks
1150    is read onto rank 0 and then shipped to its destination rank, one after another.
1151    Multiple objects, both matrices and vectors, can be stored within the same file.
1152    Their PetscObject name is ignored; they are loaded in the order of their storage.
1153 
1154    Most users should not need to know the details of the binary storage
1155    format, since MatLoad() and MatView() completely hide these details.
1156    But for anyone who's interested, the standard binary matrix storage
1157    format is
1158 
1159 $    int    MAT_FILE_CLASSID
1160 $    int    number of rows
1161 $    int    number of columns
1162 $    int    total number of nonzeros
1163 $    int    *number nonzeros in each row
1164 $    int    *column indices of all nonzeros (starting index is zero)
1165 $    PetscScalar *values of all nonzeros
1166 
1167    PETSc automatically does the byte swapping for
1168 machines that store the bytes reversed, e.g.  DEC alpha, freebsd,
1169 linux, Windows and the paragon; thus if you write your own binary
1170 read/write routines you have to swap the bytes; see PetscBinaryRead()
1171 and PetscBinaryWrite() to see how this may be done.
1172 
1173    Notes about the HDF5 (MATLAB MAT-File Version 7.3) format:
1174    In case of PETSCVIEWERHDF5, a parallel HDF5 reader is used.
1175    Each processor's chunk is loaded independently by its owning rank.
1176    Multiple objects, both matrices and vectors, can be stored within the same file.
1177    They are looked up by their PetscObject name.
1178 
1179    As the MATLAB MAT-File Version 7.3 format is also a HDF5 flavor, we decided to use
1180    by default the same structure and naming of the AIJ arrays and column count
1181    (see PetscViewerHDF5SetAIJNames())
1182    within the HDF5 file. This means that a MAT file saved with -v7.3 flag, e.g.
1183 $    save example.mat A b -v7.3
1184    can be directly read by this routine (see Reference 1 for details).
1185    Note that depending on your MATLAB version, this format might be a default,
1186    otherwise you can set it as default in Preferences.
1187 
1188    Unless -nocompression flag is used to save the file in MATLAB,
1189    PETSc must be configured with ZLIB package.
1190 
1191    See also examples src/mat/examples/tutorials/ex10.c and src/ksp/ksp/examples/tutorials/ex27.c
1192 
1193    Current HDF5 (MAT-File) limitations:
1194    This reader currently supports only real MATSEQAIJ and MATMPIAIJ matrices.
1195 
1196    Corresponding MatView() is not yet implemented.
1197 
1198    The loaded matrix is actually a transpose of the original one in MATLAB,
1199    unless you push PETSC_VIEWER_HDF5_MAT format (see examples above).
1200    With this format, matrix is automatically transposed by PETSc,
1201    unless the matrix is marked as SPD or symmetric
1202    (see MatSetOption(), MAT_SPD, MAT_SYMMETRIC).
1203 
1204    References:
1205 1. MATLAB(R) Documentation, manual page of save(), https://www.mathworks.com/help/matlab/ref/save.html#btox10b-1-version
1206 
1207 .keywords: matrix, load, binary, input, HDF5
1208 
1209 .seealso: PetscViewerBinaryOpen(), PetscViewerSetType(), PetscViewerHDF5SetAIJNames(), MatView(), VecLoad()
1210 
1211  @*/
1212 PetscErrorCode MatLoad(Mat newmat,PetscViewer viewer)
1213 {
1214   PetscErrorCode ierr;
1215   PetscBool      flg;
1216 
1217   PetscFunctionBegin;
1218   PetscValidHeaderSpecific(newmat,MAT_CLASSID,1);
1219   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1220 
1221   if (!((PetscObject)newmat)->type_name) {
1222     ierr = MatSetType(newmat,MATAIJ);CHKERRQ(ierr);
1223   }
1224 
1225   flg  = PETSC_FALSE;
1226   ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,NULL);CHKERRQ(ierr);
1227   if (flg) {
1228     ierr = MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
1229     ierr = MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);CHKERRQ(ierr);
1230   }
1231   flg  = PETSC_FALSE;
1232   ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_spd",&flg,NULL);CHKERRQ(ierr);
1233   if (flg) {
1234     ierr = MatSetOption(newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr);
1235   }
1236 
1237   if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type");
1238   ierr = PetscLogEventBegin(MAT_Load,viewer,0,0,0);CHKERRQ(ierr);
1239   ierr = (*newmat->ops->load)(newmat,viewer);CHKERRQ(ierr);
1240   ierr = PetscLogEventEnd(MAT_Load,viewer,0,0,0);CHKERRQ(ierr);
1241   PetscFunctionReturn(0);
1242 }
1243 
1244 PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant)
1245 {
1246   PetscErrorCode ierr;
1247   Mat_Redundant  *redund = *redundant;
1248   PetscInt       i;
1249 
1250   PetscFunctionBegin;
1251   if (redund){
1252     if (redund->matseq) { /* via MatCreateSubMatrices()  */
1253       ierr = ISDestroy(&redund->isrow);CHKERRQ(ierr);
1254       ierr = ISDestroy(&redund->iscol);CHKERRQ(ierr);
1255       ierr = MatDestroySubMatrices(1,&redund->matseq);CHKERRQ(ierr);
1256     } else {
1257       ierr = PetscFree2(redund->send_rank,redund->recv_rank);CHKERRQ(ierr);
1258       ierr = PetscFree(redund->sbuf_j);CHKERRQ(ierr);
1259       ierr = PetscFree(redund->sbuf_a);CHKERRQ(ierr);
1260       for (i=0; i<redund->nrecvs; i++) {
1261         ierr = PetscFree(redund->rbuf_j[i]);CHKERRQ(ierr);
1262         ierr = PetscFree(redund->rbuf_a[i]);CHKERRQ(ierr);
1263       }
1264       ierr = PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a);CHKERRQ(ierr);
1265     }
1266 
1267     if (redund->subcomm) {
1268       ierr = PetscCommDestroy(&redund->subcomm);CHKERRQ(ierr);
1269     }
1270     ierr = PetscFree(redund);CHKERRQ(ierr);
1271   }
1272   PetscFunctionReturn(0);
1273 }
1274 
1275 /*@
1276    MatDestroy - Frees space taken by a matrix.
1277 
1278    Collective on Mat
1279 
1280    Input Parameter:
1281 .  A - the matrix
1282 
1283    Level: beginner
1284 
1285 @*/
1286 PetscErrorCode MatDestroy(Mat *A)
1287 {
1288   PetscErrorCode ierr;
1289 
1290   PetscFunctionBegin;
1291   if (!*A) PetscFunctionReturn(0);
1292   PetscValidHeaderSpecific(*A,MAT_CLASSID,1);
1293   if (--((PetscObject)(*A))->refct > 0) {*A = NULL; PetscFunctionReturn(0);}
1294 
1295   /* if memory was published with SAWs then destroy it */
1296   ierr = PetscObjectSAWsViewOff((PetscObject)*A);CHKERRQ(ierr);
1297   if ((*A)->ops->destroy) {
1298     ierr = (*(*A)->ops->destroy)(*A);CHKERRQ(ierr);
1299   }
1300 
1301   ierr = PetscFree((*A)->defaultvectype);CHKERRQ(ierr);
1302   ierr = PetscFree((*A)->bsizes);CHKERRQ(ierr);
1303   ierr = PetscFree((*A)->solvertype);CHKERRQ(ierr);
1304   ierr = MatDestroy_Redundant(&(*A)->redundant);CHKERRQ(ierr);
1305   ierr = MatNullSpaceDestroy(&(*A)->nullsp);CHKERRQ(ierr);
1306   ierr = MatNullSpaceDestroy(&(*A)->transnullsp);CHKERRQ(ierr);
1307   ierr = MatNullSpaceDestroy(&(*A)->nearnullsp);CHKERRQ(ierr);
1308   ierr = MatDestroy(&(*A)->schur);CHKERRQ(ierr);
1309   ierr = PetscLayoutDestroy(&(*A)->rmap);CHKERRQ(ierr);
1310   ierr = PetscLayoutDestroy(&(*A)->cmap);CHKERRQ(ierr);
1311   ierr = PetscHeaderDestroy(A);CHKERRQ(ierr);
1312   PetscFunctionReturn(0);
1313 }
1314 
1315 /*@C
1316    MatSetValues - Inserts or adds a block of values into a matrix.
1317    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1318    MUST be called after all calls to MatSetValues() have been completed.
1319 
1320    Not Collective
1321 
1322    Input Parameters:
1323 +  mat - the matrix
1324 .  v - a logically two-dimensional array of values
1325 .  m, idxm - the number of rows and their global indices
1326 .  n, idxn - the number of columns and their global indices
1327 -  addv - either ADD_VALUES or INSERT_VALUES, where
1328    ADD_VALUES adds values to any existing entries, and
1329    INSERT_VALUES replaces existing entries with new values
1330 
1331    Notes:
1332    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
1333       MatSetUp() before using this routine
1334 
1335    By default the values, v, are row-oriented. See MatSetOption() for other options.
1336 
1337    Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
1338    options cannot be mixed without intervening calls to the assembly
1339    routines.
1340 
1341    MatSetValues() uses 0-based row and column numbers in Fortran
1342    as well as in C.
1343 
1344    Negative indices may be passed in idxm and idxn, these rows and columns are
1345    simply ignored. This allows easily inserting element stiffness matrices
1346    with homogeneous Dirchlet boundary conditions that you don't want represented
1347    in the matrix.
1348 
1349    Efficiency Alert:
1350    The routine MatSetValuesBlocked() may offer much better efficiency
1351    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1352 
1353    Level: beginner
1354 
1355    Developer Notes:
1356     This is labeled with C so does not automatically generate Fortran stubs and interfaces
1357                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
1358 
1359    Concepts: matrices^putting entries in
1360 
1361 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1362           InsertMode, INSERT_VALUES, ADD_VALUES
1363 @*/
1364 PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1365 {
1366   PetscErrorCode ierr;
1367 #if defined(PETSC_USE_DEBUG)
1368   PetscInt       i,j;
1369 #endif
1370 
1371   PetscFunctionBeginHot;
1372   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1373   PetscValidType(mat,1);
1374   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1375   PetscValidIntPointer(idxm,3);
1376   PetscValidIntPointer(idxn,5);
1377   PetscValidScalarPointer(v,6);
1378   MatCheckPreallocated(mat,1);
1379   if (mat->insertmode == NOT_SET_VALUES) {
1380     mat->insertmode = addv;
1381   }
1382 #if defined(PETSC_USE_DEBUG)
1383   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1384   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1385   if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1386 
1387   for (i=0; i<m; i++) {
1388     for (j=0; j<n; j++) {
1389       if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j]))
1390 #if defined(PETSC_USE_COMPLEX)
1391         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]);
1392 #else
1393         SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%D,%D)",(double)v[i*n+j],idxm[i],idxn[j]);
1394 #endif
1395     }
1396   }
1397 #endif
1398 
1399   if (mat->assembled) {
1400     mat->was_assembled = PETSC_TRUE;
1401     mat->assembled     = PETSC_FALSE;
1402   }
1403   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1404   ierr = (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
1405   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1406 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1407   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1408     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1409   }
1410 #endif
1411   PetscFunctionReturn(0);
1412 }
1413 
1414 
1415 /*@
1416    MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
1417         values into a matrix
1418 
1419    Not Collective
1420 
1421    Input Parameters:
1422 +  mat - the matrix
1423 .  row - the (block) row to set
1424 -  v - a logically two-dimensional array of values
1425 
1426    Notes:
1427    By the values, v, are column-oriented (for the block version) and sorted
1428 
1429    All the nonzeros in the row must be provided
1430 
1431    The matrix must have previously had its column indices set
1432 
1433    The row must belong to this process
1434 
1435    Level: intermediate
1436 
1437    Concepts: matrices^putting entries in
1438 
1439 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1440           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping()
1441 @*/
1442 PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
1443 {
1444   PetscErrorCode ierr;
1445   PetscInt       globalrow;
1446 
1447   PetscFunctionBegin;
1448   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1449   PetscValidType(mat,1);
1450   PetscValidScalarPointer(v,2);
1451   ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);CHKERRQ(ierr);
1452   ierr = MatSetValuesRow(mat,globalrow,v);CHKERRQ(ierr);
1453 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1454   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1455     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1456   }
1457 #endif
1458   PetscFunctionReturn(0);
1459 }
1460 
1461 /*@
1462    MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
1463         values into a matrix
1464 
1465    Not Collective
1466 
1467    Input Parameters:
1468 +  mat - the matrix
1469 .  row - the (block) row to set
1470 -  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
1471 
1472    Notes:
1473    The values, v, are column-oriented for the block version.
1474 
1475    All the nonzeros in the row must be provided
1476 
1477    THE MATRIX MUST HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually MatSetValues() is used.
1478 
1479    The row must belong to this process
1480 
1481    Level: advanced
1482 
1483    Concepts: matrices^putting entries in
1484 
1485 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1486           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1487 @*/
1488 PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
1489 {
1490   PetscErrorCode ierr;
1491 
1492   PetscFunctionBeginHot;
1493   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1494   PetscValidType(mat,1);
1495   MatCheckPreallocated(mat,1);
1496   PetscValidScalarPointer(v,2);
1497 #if defined(PETSC_USE_DEBUG)
1498   if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
1499   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1500 #endif
1501   mat->insertmode = INSERT_VALUES;
1502 
1503   if (mat->assembled) {
1504     mat->was_assembled = PETSC_TRUE;
1505     mat->assembled     = PETSC_FALSE;
1506   }
1507   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1508   if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1509   ierr = (*mat->ops->setvaluesrow)(mat,row,v);CHKERRQ(ierr);
1510   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1511 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1512   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1513     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1514   }
1515 #endif
1516   PetscFunctionReturn(0);
1517 }
1518 
1519 /*@
1520    MatSetValuesStencil - Inserts or adds a block of values into a matrix.
1521      Using structured grid indexing
1522 
1523    Not Collective
1524 
1525    Input Parameters:
1526 +  mat - the matrix
1527 .  m - number of rows being entered
1528 .  idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
1529 .  n - number of columns being entered
1530 .  idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered
1531 .  v - a logically two-dimensional array of values
1532 -  addv - either ADD_VALUES or INSERT_VALUES, where
1533    ADD_VALUES adds values to any existing entries, and
1534    INSERT_VALUES replaces existing entries with new values
1535 
1536    Notes:
1537    By default the values, v, are row-oriented.  See MatSetOption() for other options.
1538 
1539    Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
1540    options cannot be mixed without intervening calls to the assembly
1541    routines.
1542 
1543    The grid coordinates are across the entire grid, not just the local portion
1544 
1545    MatSetValuesStencil() uses 0-based row and column numbers in Fortran
1546    as well as in C.
1547 
1548    For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1549 
1550    In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1551    or call MatSetLocalToGlobalMapping() and MatSetStencil() first.
1552 
1553    The columns and rows in the stencil passed in MUST be contained within the
1554    ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1555    if you create a DMDA with an overlap of one grid level and on a particular process its first
1556    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1557    first i index you can use in your column and row indices in MatSetStencil() is 5.
1558 
1559    In Fortran idxm and idxn should be declared as
1560 $     MatStencil idxm(4,m),idxn(4,n)
1561    and the values inserted using
1562 $    idxm(MatStencil_i,1) = i
1563 $    idxm(MatStencil_j,1) = j
1564 $    idxm(MatStencil_k,1) = k
1565 $    idxm(MatStencil_c,1) = c
1566    etc
1567 
1568    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
1569    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
1570    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
1571    DM_BOUNDARY_PERIODIC boundary type.
1572 
1573    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
1574    a single value per point) you can skip filling those indices.
1575 
1576    Inspired by the structured grid interface to the HYPRE package
1577    (http://www.llnl.gov/CASC/hypre)
1578 
1579    Efficiency Alert:
1580    The routine MatSetValuesBlockedStencil() may offer much better efficiency
1581    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1582 
1583    Level: beginner
1584 
1585    Concepts: matrices^putting entries in
1586 
1587 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1588           MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil
1589 @*/
1590 PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1591 {
1592   PetscErrorCode ierr;
1593   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1594   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1595   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1596 
1597   PetscFunctionBegin;
1598   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1599   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1600   PetscValidType(mat,1);
1601   PetscValidIntPointer(idxm,3);
1602   PetscValidIntPointer(idxn,5);
1603   PetscValidScalarPointer(v,6);
1604 
1605   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1606     jdxm = buf; jdxn = buf+m;
1607   } else {
1608     ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr);
1609     jdxm = bufm; jdxn = bufn;
1610   }
1611   for (i=0; i<m; i++) {
1612     for (j=0; j<3-sdim; j++) dxm++;
1613     tmp = *dxm++ - starts[0];
1614     for (j=0; j<dim-1; j++) {
1615       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1616       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1617     }
1618     if (mat->stencil.noc) dxm++;
1619     jdxm[i] = tmp;
1620   }
1621   for (i=0; i<n; i++) {
1622     for (j=0; j<3-sdim; j++) dxn++;
1623     tmp = *dxn++ - starts[0];
1624     for (j=0; j<dim-1; j++) {
1625       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1626       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1627     }
1628     if (mat->stencil.noc) dxn++;
1629     jdxn[i] = tmp;
1630   }
1631   ierr = MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr);
1632   ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr);
1633   PetscFunctionReturn(0);
1634 }
1635 
1636 /*@
1637    MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1638      Using structured grid indexing
1639 
1640    Not Collective
1641 
1642    Input Parameters:
1643 +  mat - the matrix
1644 .  m - number of rows being entered
1645 .  idxm - grid coordinates for matrix rows being entered
1646 .  n - number of columns being entered
1647 .  idxn - grid coordinates for matrix columns being entered
1648 .  v - a logically two-dimensional array of values
1649 -  addv - either ADD_VALUES or INSERT_VALUES, where
1650    ADD_VALUES adds values to any existing entries, and
1651    INSERT_VALUES replaces existing entries with new values
1652 
1653    Notes:
1654    By default the values, v, are row-oriented and unsorted.
1655    See MatSetOption() for other options.
1656 
1657    Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
1658    options cannot be mixed without intervening calls to the assembly
1659    routines.
1660 
1661    The grid coordinates are across the entire grid, not just the local portion
1662 
1663    MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran
1664    as well as in C.
1665 
1666    For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1667 
1668    In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1669    or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first.
1670 
1671    The columns and rows in the stencil passed in MUST be contained within the
1672    ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1673    if you create a DMDA with an overlap of one grid level and on a particular process its first
1674    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1675    first i index you can use in your column and row indices in MatSetStencil() is 5.
1676 
1677    In Fortran idxm and idxn should be declared as
1678 $     MatStencil idxm(4,m),idxn(4,n)
1679    and the values inserted using
1680 $    idxm(MatStencil_i,1) = i
1681 $    idxm(MatStencil_j,1) = j
1682 $    idxm(MatStencil_k,1) = k
1683    etc
1684 
1685    Negative indices may be passed in idxm and idxn, these rows and columns are
1686    simply ignored. This allows easily inserting element stiffness matrices
1687    with homogeneous Dirchlet boundary conditions that you don't want represented
1688    in the matrix.
1689 
1690    Inspired by the structured grid interface to the HYPRE package
1691    (http://www.llnl.gov/CASC/hypre)
1692 
1693    Level: beginner
1694 
1695    Concepts: matrices^putting entries in
1696 
1697 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1698           MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil,
1699           MatSetBlockSize(), MatSetLocalToGlobalMapping()
1700 @*/
1701 PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1702 {
1703   PetscErrorCode ierr;
1704   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1705   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1706   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1707 
1708   PetscFunctionBegin;
1709   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1710   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1711   PetscValidType(mat,1);
1712   PetscValidIntPointer(idxm,3);
1713   PetscValidIntPointer(idxn,5);
1714   PetscValidScalarPointer(v,6);
1715 
1716   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1717     jdxm = buf; jdxn = buf+m;
1718   } else {
1719     ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr);
1720     jdxm = bufm; jdxn = bufn;
1721   }
1722   for (i=0; i<m; i++) {
1723     for (j=0; j<3-sdim; j++) dxm++;
1724     tmp = *dxm++ - starts[0];
1725     for (j=0; j<sdim-1; j++) {
1726       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1727       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1728     }
1729     dxm++;
1730     jdxm[i] = tmp;
1731   }
1732   for (i=0; i<n; i++) {
1733     for (j=0; j<3-sdim; j++) dxn++;
1734     tmp = *dxn++ - starts[0];
1735     for (j=0; j<sdim-1; j++) {
1736       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1737       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1738     }
1739     dxn++;
1740     jdxn[i] = tmp;
1741   }
1742   ierr = MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr);
1743   ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr);
1744 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1745   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1746     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1747   }
1748 #endif
1749   PetscFunctionReturn(0);
1750 }
1751 
1752 /*@
1753    MatSetStencil - Sets the grid information for setting values into a matrix via
1754         MatSetValuesStencil()
1755 
1756    Not Collective
1757 
1758    Input Parameters:
1759 +  mat - the matrix
1760 .  dim - dimension of the grid 1, 2, or 3
1761 .  dims - number of grid points in x, y, and z direction, including ghost points on your processor
1762 .  starts - starting point of ghost nodes on your processor in x, y, and z direction
1763 -  dof - number of degrees of freedom per node
1764 
1765 
1766    Inspired by the structured grid interface to the HYPRE package
1767    (www.llnl.gov/CASC/hyper)
1768 
1769    For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the
1770    user.
1771 
1772    Level: beginner
1773 
1774    Concepts: matrices^putting entries in
1775 
1776 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1777           MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
1778 @*/
1779 PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1780 {
1781   PetscInt i;
1782 
1783   PetscFunctionBegin;
1784   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1785   PetscValidIntPointer(dims,3);
1786   PetscValidIntPointer(starts,4);
1787 
1788   mat->stencil.dim = dim + (dof > 1);
1789   for (i=0; i<dim; i++) {
1790     mat->stencil.dims[i]   = dims[dim-i-1];      /* copy the values in backwards */
1791     mat->stencil.starts[i] = starts[dim-i-1];
1792   }
1793   mat->stencil.dims[dim]   = dof;
1794   mat->stencil.starts[dim] = 0;
1795   mat->stencil.noc         = (PetscBool)(dof == 1);
1796   PetscFunctionReturn(0);
1797 }
1798 
1799 /*@C
1800    MatSetValuesBlocked - Inserts or adds a block of values into a matrix.
1801 
1802    Not Collective
1803 
1804    Input Parameters:
1805 +  mat - the matrix
1806 .  v - a logically two-dimensional array of values
1807 .  m, idxm - the number of block rows and their global block indices
1808 .  n, idxn - the number of block columns and their global block indices
1809 -  addv - either ADD_VALUES or INSERT_VALUES, where
1810    ADD_VALUES adds values to any existing entries, and
1811    INSERT_VALUES replaces existing entries with new values
1812 
1813    Notes:
1814    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call
1815    MatXXXXSetPreallocation() or MatSetUp() before using this routine.
1816 
1817    The m and n count the NUMBER of blocks in the row direction and column direction,
1818    NOT the total number of rows/columns; for example, if the block size is 2 and
1819    you are passing in values for rows 2,3,4,5  then m would be 2 (not 4).
1820    The values in idxm would be 1 2; that is the first index for each block divided by
1821    the block size.
1822 
1823    Note that you must call MatSetBlockSize() when constructing this matrix (before
1824    preallocating it).
1825 
1826    By default the values, v, are row-oriented, so the layout of
1827    v is the same as for MatSetValues(). See MatSetOption() for other options.
1828 
1829    Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
1830    options cannot be mixed without intervening calls to the assembly
1831    routines.
1832 
1833    MatSetValuesBlocked() uses 0-based row and column numbers in Fortran
1834    as well as in C.
1835 
1836    Negative indices may be passed in idxm and idxn, these rows and columns are
1837    simply ignored. This allows easily inserting element stiffness matrices
1838    with homogeneous Dirchlet boundary conditions that you don't want represented
1839    in the matrix.
1840 
1841    Each time an entry is set within a sparse matrix via MatSetValues(),
1842    internal searching must be done to determine where to place the
1843    data in the matrix storage space.  By instead inserting blocks of
1844    entries via MatSetValuesBlocked(), the overhead of matrix assembly is
1845    reduced.
1846 
1847    Example:
1848 $   Suppose m=n=2 and block size(bs) = 2 The array is
1849 $
1850 $   1  2  | 3  4
1851 $   5  6  | 7  8
1852 $   - - - | - - -
1853 $   9  10 | 11 12
1854 $   13 14 | 15 16
1855 $
1856 $   v[] should be passed in like
1857 $   v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
1858 $
1859 $  If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then
1860 $   v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16]
1861 
1862    Level: intermediate
1863 
1864    Concepts: matrices^putting entries in blocked
1865 
1866 .seealso: MatSetBlockSize(), MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal()
1867 @*/
1868 PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1869 {
1870   PetscErrorCode ierr;
1871 
1872   PetscFunctionBeginHot;
1873   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1874   PetscValidType(mat,1);
1875   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1876   PetscValidIntPointer(idxm,3);
1877   PetscValidIntPointer(idxn,5);
1878   PetscValidScalarPointer(v,6);
1879   MatCheckPreallocated(mat,1);
1880   if (mat->insertmode == NOT_SET_VALUES) {
1881     mat->insertmode = addv;
1882   }
1883 #if defined(PETSC_USE_DEBUG)
1884   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1885   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1886   if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1887 #endif
1888 
1889   if (mat->assembled) {
1890     mat->was_assembled = PETSC_TRUE;
1891     mat->assembled     = PETSC_FALSE;
1892   }
1893   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1894   if (mat->ops->setvaluesblocked) {
1895     ierr = (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
1896   } else {
1897     PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn;
1898     PetscInt i,j,bs,cbs;
1899     ierr = MatGetBlockSizes(mat,&bs,&cbs);CHKERRQ(ierr);
1900     if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1901       iidxm = buf; iidxn = buf + m*bs;
1902     } else {
1903       ierr  = PetscMalloc2(m*bs,&bufr,n*cbs,&bufc);CHKERRQ(ierr);
1904       iidxm = bufr; iidxn = bufc;
1905     }
1906     for (i=0; i<m; i++) {
1907       for (j=0; j<bs; j++) {
1908         iidxm[i*bs+j] = bs*idxm[i] + j;
1909       }
1910     }
1911     for (i=0; i<n; i++) {
1912       for (j=0; j<cbs; j++) {
1913         iidxn[i*cbs+j] = cbs*idxn[i] + j;
1914       }
1915     }
1916     ierr = MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv);CHKERRQ(ierr);
1917     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
1918   }
1919   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1920 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1921   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1922     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1923   }
1924 #endif
1925   PetscFunctionReturn(0);
1926 }
1927 
1928 /*@
1929    MatGetValues - Gets a block of values from a matrix.
1930 
1931    Not Collective; currently only returns a local block
1932 
1933    Input Parameters:
1934 +  mat - the matrix
1935 .  v - a logically two-dimensional array for storing the values
1936 .  m, idxm - the number of rows and their global indices
1937 -  n, idxn - the number of columns and their global indices
1938 
1939    Notes:
1940    The user must allocate space (m*n PetscScalars) for the values, v.
1941    The values, v, are then returned in a row-oriented format,
1942    analogous to that used by default in MatSetValues().
1943 
1944    MatGetValues() uses 0-based row and column numbers in
1945    Fortran as well as in C.
1946 
1947    MatGetValues() requires that the matrix has been assembled
1948    with MatAssemblyBegin()/MatAssemblyEnd().  Thus, calls to
1949    MatSetValues() and MatGetValues() CANNOT be made in succession
1950    without intermediate matrix assembly.
1951 
1952    Negative row or column indices will be ignored and those locations in v[] will be
1953    left unchanged.
1954 
1955    Level: advanced
1956 
1957    Concepts: matrices^accessing values
1958 
1959 .seealso: MatGetRow(), MatCreateSubMatrices(), MatSetValues()
1960 @*/
1961 PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1962 {
1963   PetscErrorCode ierr;
1964 
1965   PetscFunctionBegin;
1966   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1967   PetscValidType(mat,1);
1968   if (!m || !n) PetscFunctionReturn(0);
1969   PetscValidIntPointer(idxm,3);
1970   PetscValidIntPointer(idxn,5);
1971   PetscValidScalarPointer(v,6);
1972   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1973   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1974   if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1975   MatCheckPreallocated(mat,1);
1976 
1977   ierr = PetscLogEventBegin(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
1978   ierr = (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);CHKERRQ(ierr);
1979   ierr = PetscLogEventEnd(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
1980   PetscFunctionReturn(0);
1981 }
1982 
1983 /*@
1984   MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and
1985   the same size. Currently, this can only be called once and creates the given matrix.
1986 
1987   Not Collective
1988 
1989   Input Parameters:
1990 + mat - the matrix
1991 . nb - the number of blocks
1992 . bs - the number of rows (and columns) in each block
1993 . rows - a concatenation of the rows for each block
1994 - v - a concatenation of logically two-dimensional arrays of values
1995 
1996   Notes:
1997   In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix.
1998 
1999   Level: advanced
2000 
2001   Concepts: matrices^putting entries in
2002 
2003 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
2004           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
2005 @*/
2006 PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[])
2007 {
2008   PetscErrorCode ierr;
2009 
2010   PetscFunctionBegin;
2011   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2012   PetscValidType(mat,1);
2013   PetscValidScalarPointer(rows,4);
2014   PetscValidScalarPointer(v,5);
2015 #if defined(PETSC_USE_DEBUG)
2016   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2017 #endif
2018 
2019   ierr = PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr);
2020   if (mat->ops->setvaluesbatch) {
2021     ierr = (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);CHKERRQ(ierr);
2022   } else {
2023     PetscInt b;
2024     for (b = 0; b < nb; ++b) {
2025       ierr = MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);CHKERRQ(ierr);
2026     }
2027   }
2028   ierr = PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr);
2029   PetscFunctionReturn(0);
2030 }
2031 
2032 /*@
2033    MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
2034    the routine MatSetValuesLocal() to allow users to insert matrix entries
2035    using a local (per-processor) numbering.
2036 
2037    Not Collective
2038 
2039    Input Parameters:
2040 +  x - the matrix
2041 .  rmapping - row mapping created with ISLocalToGlobalMappingCreate()   or ISLocalToGlobalMappingCreateIS()
2042 - cmapping - column mapping
2043 
2044    Level: intermediate
2045 
2046    Concepts: matrices^local to global mapping
2047    Concepts: local to global mapping^for matrices
2048 
2049 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
2050 @*/
2051 PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
2052 {
2053   PetscErrorCode ierr;
2054 
2055   PetscFunctionBegin;
2056   PetscValidHeaderSpecific(x,MAT_CLASSID,1);
2057   PetscValidType(x,1);
2058   PetscValidHeaderSpecific(rmapping,IS_LTOGM_CLASSID,2);
2059   PetscValidHeaderSpecific(cmapping,IS_LTOGM_CLASSID,3);
2060 
2061   if (x->ops->setlocaltoglobalmapping) {
2062     ierr = (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);CHKERRQ(ierr);
2063   } else {
2064     ierr = PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);CHKERRQ(ierr);
2065     ierr = PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);CHKERRQ(ierr);
2066   }
2067   PetscFunctionReturn(0);
2068 }
2069 
2070 
2071 /*@
2072    MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping()
2073 
2074    Not Collective
2075 
2076    Input Parameters:
2077 .  A - the matrix
2078 
2079    Output Parameters:
2080 + rmapping - row mapping
2081 - cmapping - column mapping
2082 
2083    Level: advanced
2084 
2085    Concepts: matrices^local to global mapping
2086    Concepts: local to global mapping^for matrices
2087 
2088 .seealso:  MatSetValuesLocal()
2089 @*/
2090 PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
2091 {
2092   PetscFunctionBegin;
2093   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2094   PetscValidType(A,1);
2095   if (rmapping) PetscValidPointer(rmapping,2);
2096   if (cmapping) PetscValidPointer(cmapping,3);
2097   if (rmapping) *rmapping = A->rmap->mapping;
2098   if (cmapping) *cmapping = A->cmap->mapping;
2099   PetscFunctionReturn(0);
2100 }
2101 
2102 /*@
2103    MatGetLayouts - Gets the PetscLayout objects for rows and columns
2104 
2105    Not Collective
2106 
2107    Input Parameters:
2108 .  A - the matrix
2109 
2110    Output Parameters:
2111 + rmap - row layout
2112 - cmap - column layout
2113 
2114    Level: advanced
2115 
2116 .seealso:  MatCreateVecs(), MatGetLocalToGlobalMapping()
2117 @*/
2118 PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap)
2119 {
2120   PetscFunctionBegin;
2121   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2122   PetscValidType(A,1);
2123   if (rmap) PetscValidPointer(rmap,2);
2124   if (cmap) PetscValidPointer(cmap,3);
2125   if (rmap) *rmap = A->rmap;
2126   if (cmap) *cmap = A->cmap;
2127   PetscFunctionReturn(0);
2128 }
2129 
2130 /*@C
2131    MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
2132    using a local ordering of the nodes.
2133 
2134    Not Collective
2135 
2136    Input Parameters:
2137 +  mat - the matrix
2138 .  nrow, irow - number of rows and their local indices
2139 .  ncol, icol - number of columns and their local indices
2140 .  y -  a logically two-dimensional array of values
2141 -  addv - either INSERT_VALUES or ADD_VALUES, where
2142    ADD_VALUES adds values to any existing entries, and
2143    INSERT_VALUES replaces existing entries with new values
2144 
2145    Notes:
2146    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
2147       MatSetUp() before using this routine
2148 
2149    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine
2150 
2151    Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
2152    options cannot be mixed without intervening calls to the assembly
2153    routines.
2154 
2155    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2156    MUST be called after all calls to MatSetValuesLocal() have been completed.
2157 
2158    Level: intermediate
2159 
2160    Concepts: matrices^putting entries in with local numbering
2161 
2162    Developer Notes:
2163     This is labeled with C so does not automatically generate Fortran stubs and interfaces
2164                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
2165 
2166 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
2167            MatSetValueLocal()
2168 @*/
2169 PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2170 {
2171   PetscErrorCode ierr;
2172 
2173   PetscFunctionBeginHot;
2174   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2175   PetscValidType(mat,1);
2176   MatCheckPreallocated(mat,1);
2177   if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */
2178   PetscValidIntPointer(irow,3);
2179   PetscValidIntPointer(icol,5);
2180   PetscValidScalarPointer(y,6);
2181   if (mat->insertmode == NOT_SET_VALUES) {
2182     mat->insertmode = addv;
2183   }
2184 #if defined(PETSC_USE_DEBUG)
2185   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2186   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2187   if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2188 #endif
2189 
2190   if (mat->assembled) {
2191     mat->was_assembled = PETSC_TRUE;
2192     mat->assembled     = PETSC_FALSE;
2193   }
2194   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2195   if (mat->ops->setvalueslocal) {
2196     ierr = (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr);
2197   } else {
2198     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2199     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2200       irowm = buf; icolm = buf+nrow;
2201     } else {
2202       ierr  = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr);
2203       irowm = bufr; icolm = bufc;
2204     }
2205     ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr);
2206     ierr = ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr);
2207     ierr = MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
2208     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
2209   }
2210   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2211 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
2212   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
2213     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
2214   }
2215 #endif
2216   PetscFunctionReturn(0);
2217 }
2218 
2219 /*@C
2220    MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix,
2221    using a local ordering of the nodes a block at a time.
2222 
2223    Not Collective
2224 
2225    Input Parameters:
2226 +  x - the matrix
2227 .  nrow, irow - number of rows and their local indices
2228 .  ncol, icol - number of columns and their local indices
2229 .  y -  a logically two-dimensional array of values
2230 -  addv - either INSERT_VALUES or ADD_VALUES, where
2231    ADD_VALUES adds values to any existing entries, and
2232    INSERT_VALUES replaces existing entries with new values
2233 
2234    Notes:
2235    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
2236       MatSetUp() before using this routine
2237 
2238    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMapping()
2239       before using this routineBefore calling MatSetValuesLocal(), the user must first set the
2240 
2241    Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
2242    options cannot be mixed without intervening calls to the assembly
2243    routines.
2244 
2245    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2246    MUST be called after all calls to MatSetValuesBlockedLocal() have been completed.
2247 
2248    Level: intermediate
2249 
2250    Developer Notes:
2251     This is labeled with C so does not automatically generate Fortran stubs and interfaces
2252                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
2253 
2254    Concepts: matrices^putting blocked values in with local numbering
2255 
2256 .seealso:  MatSetBlockSize(), MatSetLocalToGlobalMapping(), MatAssemblyBegin(), MatAssemblyEnd(),
2257            MatSetValuesLocal(),  MatSetValuesBlocked()
2258 @*/
2259 PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2260 {
2261   PetscErrorCode ierr;
2262 
2263   PetscFunctionBeginHot;
2264   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2265   PetscValidType(mat,1);
2266   MatCheckPreallocated(mat,1);
2267   if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */
2268   PetscValidIntPointer(irow,3);
2269   PetscValidIntPointer(icol,5);
2270   PetscValidScalarPointer(y,6);
2271   if (mat->insertmode == NOT_SET_VALUES) {
2272     mat->insertmode = addv;
2273   }
2274 #if defined(PETSC_USE_DEBUG)
2275   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2276   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2277   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);
2278 #endif
2279 
2280   if (mat->assembled) {
2281     mat->was_assembled = PETSC_TRUE;
2282     mat->assembled     = PETSC_FALSE;
2283   }
2284   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2285   if (mat->ops->setvaluesblockedlocal) {
2286     ierr = (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr);
2287   } else {
2288     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2289     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2290       irowm = buf; icolm = buf + nrow;
2291     } else {
2292       ierr  = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr);
2293       irowm = bufr; icolm = bufc;
2294     }
2295     ierr = ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr);
2296     ierr = ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr);
2297     ierr = MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
2298     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
2299   }
2300   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2301 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
2302   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
2303     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
2304   }
2305 #endif
2306   PetscFunctionReturn(0);
2307 }
2308 
2309 /*@
2310    MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal
2311 
2312    Collective on Mat and Vec
2313 
2314    Input Parameters:
2315 +  mat - the matrix
2316 -  x   - the vector to be multiplied
2317 
2318    Output Parameters:
2319 .  y - the result
2320 
2321    Notes:
2322    The vectors x and y cannot be the same.  I.e., one cannot
2323    call MatMult(A,y,y).
2324 
2325    Level: developer
2326 
2327    Concepts: matrix-vector product
2328 
2329 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2330 @*/
2331 PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y)
2332 {
2333   PetscErrorCode ierr;
2334 
2335   PetscFunctionBegin;
2336   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2337   PetscValidType(mat,1);
2338   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2339   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2340 
2341   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2342   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2343   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2344   MatCheckPreallocated(mat,1);
2345 
2346   if (!mat->ops->multdiagonalblock) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2347   ierr = (*mat->ops->multdiagonalblock)(mat,x,y);CHKERRQ(ierr);
2348   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2349   PetscFunctionReturn(0);
2350 }
2351 
2352 /* --------------------------------------------------------*/
2353 /*@
2354    MatMult - Computes the matrix-vector product, y = Ax.
2355 
2356    Neighbor-wise Collective on Mat and Vec
2357 
2358    Input Parameters:
2359 +  mat - the matrix
2360 -  x   - the vector to be multiplied
2361 
2362    Output Parameters:
2363 .  y - the result
2364 
2365    Notes:
2366    The vectors x and y cannot be the same.  I.e., one cannot
2367    call MatMult(A,y,y).
2368 
2369    Level: beginner
2370 
2371    Concepts: matrix-vector product
2372 
2373 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2374 @*/
2375 PetscErrorCode MatMult(Mat mat,Vec x,Vec y)
2376 {
2377   PetscErrorCode ierr;
2378 
2379   PetscFunctionBegin;
2380   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2381   PetscValidType(mat,1);
2382   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2383   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2384   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2385   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2386   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2387 #if !defined(PETSC_HAVE_CONSTRAINTS)
2388   if (mat->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);
2389   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);
2390   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);
2391 #endif
2392   ierr = VecSetErrorIfLocked(y,3);CHKERRQ(ierr);
2393   if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);}
2394   MatCheckPreallocated(mat,1);
2395 
2396   ierr = VecLockReadPush(x);CHKERRQ(ierr);
2397   if (!mat->ops->mult) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2398   ierr = PetscLogEventBegin(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
2399   ierr = (*mat->ops->mult)(mat,x,y);CHKERRQ(ierr);
2400   ierr = PetscLogEventEnd(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
2401   if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);}
2402   ierr = VecLockReadPop(x);CHKERRQ(ierr);
2403   PetscFunctionReturn(0);
2404 }
2405 
2406 /*@
2407    MatMultTranspose - Computes matrix transpose times a vector y = A^T * x.
2408 
2409    Neighbor-wise Collective on Mat and Vec
2410 
2411    Input Parameters:
2412 +  mat - the matrix
2413 -  x   - the vector to be multiplied
2414 
2415    Output Parameters:
2416 .  y - the result
2417 
2418    Notes:
2419    The vectors x and y cannot be the same.  I.e., one cannot
2420    call MatMultTranspose(A,y,y).
2421 
2422    For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple,
2423    use MatMultHermitianTranspose()
2424 
2425    Level: beginner
2426 
2427    Concepts: matrix vector product^transpose
2428 
2429 .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose()
2430 @*/
2431 PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y)
2432 {
2433   PetscErrorCode ierr;
2434 
2435   PetscFunctionBegin;
2436   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2437   PetscValidType(mat,1);
2438   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2439   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2440 
2441   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2442   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2443   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2444 #if !defined(PETSC_HAVE_CONSTRAINTS)
2445   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);
2446   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);
2447 #endif
2448   if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);}
2449   MatCheckPreallocated(mat,1);
2450 
2451   if (!mat->ops->multtranspose) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply transpose defined");
2452   ierr = PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
2453   ierr = VecLockReadPush(x);CHKERRQ(ierr);
2454   ierr = (*mat->ops->multtranspose)(mat,x,y);CHKERRQ(ierr);
2455   ierr = VecLockReadPop(x);CHKERRQ(ierr);
2456   ierr = PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
2457   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2458   if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);}
2459   PetscFunctionReturn(0);
2460 }
2461 
2462 /*@
2463    MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.
2464 
2465    Neighbor-wise Collective on Mat and Vec
2466 
2467    Input Parameters:
2468 +  mat - the matrix
2469 -  x   - the vector to be multilplied
2470 
2471    Output Parameters:
2472 .  y - the result
2473 
2474    Notes:
2475    The vectors x and y cannot be the same.  I.e., one cannot
2476    call MatMultHermitianTranspose(A,y,y).
2477 
2478    Also called the conjugate transpose, complex conjugate transpose, or adjoint.
2479 
2480    For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical.
2481 
2482    Level: beginner
2483 
2484    Concepts: matrix vector product^transpose
2485 
2486 .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose()
2487 @*/
2488 PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y)
2489 {
2490   PetscErrorCode ierr;
2491   Vec            w;
2492 
2493   PetscFunctionBegin;
2494   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2495   PetscValidType(mat,1);
2496   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2497   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2498 
2499   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2500   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2501   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2502 #if !defined(PETSC_HAVE_CONSTRAINTS)
2503   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);
2504   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);
2505 #endif
2506   MatCheckPreallocated(mat,1);
2507 
2508   ierr = PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr);
2509   if (mat->ops->multhermitiantranspose) {
2510     ierr = VecLockReadPush(x);CHKERRQ(ierr);
2511     ierr = (*mat->ops->multhermitiantranspose)(mat,x,y);CHKERRQ(ierr);
2512     ierr = VecLockReadPop(x);CHKERRQ(ierr);
2513   } else {
2514     ierr = VecDuplicate(x,&w);CHKERRQ(ierr);
2515     ierr = VecCopy(x,w);CHKERRQ(ierr);
2516     ierr = VecConjugate(w);CHKERRQ(ierr);
2517     ierr = MatMultTranspose(mat,w,y);CHKERRQ(ierr);
2518     ierr = VecDestroy(&w);CHKERRQ(ierr);
2519     ierr = VecConjugate(y);CHKERRQ(ierr);
2520   }
2521   ierr = PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr);
2522   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2523   PetscFunctionReturn(0);
2524 }
2525 
2526 /*@
2527     MatMultAdd -  Computes v3 = v2 + A * v1.
2528 
2529     Neighbor-wise Collective on Mat and Vec
2530 
2531     Input Parameters:
2532 +   mat - the matrix
2533 -   v1, v2 - the vectors
2534 
2535     Output Parameters:
2536 .   v3 - the result
2537 
2538     Notes:
2539     The vectors v1 and v3 cannot be the same.  I.e., one cannot
2540     call MatMultAdd(A,v1,v2,v1).
2541 
2542     Level: beginner
2543 
2544     Concepts: matrix vector product^addition
2545 
2546 .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
2547 @*/
2548 PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2549 {
2550   PetscErrorCode ierr;
2551 
2552   PetscFunctionBegin;
2553   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2554   PetscValidType(mat,1);
2555   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2556   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2557   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2558 
2559   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2560   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2561   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);
2562   /* 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);
2563      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); */
2564   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);
2565   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);
2566   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2567   MatCheckPreallocated(mat,1);
2568 
2569   if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name);
2570   ierr = PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2571   ierr = VecLockReadPush(v1);CHKERRQ(ierr);
2572   ierr = (*mat->ops->multadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2573   ierr = VecLockReadPop(v1);CHKERRQ(ierr);
2574   ierr = PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2575   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2576   PetscFunctionReturn(0);
2577 }
2578 
2579 /*@
2580    MatMultTransposeAdd - Computes v3 = v2 + A' * v1.
2581 
2582    Neighbor-wise Collective on Mat and Vec
2583 
2584    Input Parameters:
2585 +  mat - the matrix
2586 -  v1, v2 - the vectors
2587 
2588    Output Parameters:
2589 .  v3 - the result
2590 
2591    Notes:
2592    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2593    call MatMultTransposeAdd(A,v1,v2,v1).
2594 
2595    Level: beginner
2596 
2597    Concepts: matrix vector product^transpose and addition
2598 
2599 .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
2600 @*/
2601 PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2602 {
2603   PetscErrorCode ierr;
2604 
2605   PetscFunctionBegin;
2606   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2607   PetscValidType(mat,1);
2608   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2609   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2610   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2611 
2612   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2613   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2614   if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2615   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2616   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);
2617   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);
2618   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);
2619   MatCheckPreallocated(mat,1);
2620 
2621   ierr = PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2622   ierr = VecLockReadPush(v1);CHKERRQ(ierr);
2623   ierr = (*mat->ops->multtransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2624   ierr = VecLockReadPop(v1);CHKERRQ(ierr);
2625   ierr = PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2626   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2627   PetscFunctionReturn(0);
2628 }
2629 
2630 /*@
2631    MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1.
2632 
2633    Neighbor-wise Collective on Mat and Vec
2634 
2635    Input Parameters:
2636 +  mat - the matrix
2637 -  v1, v2 - the vectors
2638 
2639    Output Parameters:
2640 .  v3 - the result
2641 
2642    Notes:
2643    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2644    call MatMultHermitianTransposeAdd(A,v1,v2,v1).
2645 
2646    Level: beginner
2647 
2648    Concepts: matrix vector product^transpose and addition
2649 
2650 .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult()
2651 @*/
2652 PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2653 {
2654   PetscErrorCode ierr;
2655 
2656   PetscFunctionBegin;
2657   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2658   PetscValidType(mat,1);
2659   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2660   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2661   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2662 
2663   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2664   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2665   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2666   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);
2667   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);
2668   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);
2669   MatCheckPreallocated(mat,1);
2670 
2671   ierr = PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2672   ierr = VecLockReadPush(v1);CHKERRQ(ierr);
2673   if (mat->ops->multhermitiantransposeadd) {
2674     ierr = (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2675   } else {
2676     Vec w,z;
2677     ierr = VecDuplicate(v1,&w);CHKERRQ(ierr);
2678     ierr = VecCopy(v1,w);CHKERRQ(ierr);
2679     ierr = VecConjugate(w);CHKERRQ(ierr);
2680     ierr = VecDuplicate(v3,&z);CHKERRQ(ierr);
2681     ierr = MatMultTranspose(mat,w,z);CHKERRQ(ierr);
2682     ierr = VecDestroy(&w);CHKERRQ(ierr);
2683     ierr = VecConjugate(z);CHKERRQ(ierr);
2684     if (v2 != v3) {
2685       ierr = VecWAXPY(v3,1.0,v2,z);CHKERRQ(ierr);
2686     } else {
2687       ierr = VecAXPY(v3,1.0,z);CHKERRQ(ierr);
2688     }
2689     ierr = VecDestroy(&z);CHKERRQ(ierr);
2690   }
2691   ierr = VecLockReadPop(v1);CHKERRQ(ierr);
2692   ierr = PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2693   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2694   PetscFunctionReturn(0);
2695 }
2696 
2697 /*@
2698    MatMultConstrained - The inner multiplication routine for a
2699    constrained matrix P^T A P.
2700 
2701    Neighbor-wise Collective on Mat and Vec
2702 
2703    Input Parameters:
2704 +  mat - the matrix
2705 -  x   - the vector to be multilplied
2706 
2707    Output Parameters:
2708 .  y - the result
2709 
2710    Notes:
2711    The vectors x and y cannot be the same.  I.e., one cannot
2712    call MatMult(A,y,y).
2713 
2714    Level: beginner
2715 
2716 .keywords: matrix, multiply, matrix-vector product, constraint
2717 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2718 @*/
2719 PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y)
2720 {
2721   PetscErrorCode ierr;
2722 
2723   PetscFunctionBegin;
2724   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2725   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2726   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2727   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2728   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2729   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2730   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);
2731   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);
2732   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);
2733 
2734   ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2735   ierr = VecLockReadPush(x);CHKERRQ(ierr);
2736   ierr = (*mat->ops->multconstrained)(mat,x,y);CHKERRQ(ierr);
2737   ierr = VecLockReadPop(x);CHKERRQ(ierr);
2738   ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2739   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2740   PetscFunctionReturn(0);
2741 }
2742 
2743 /*@
2744    MatMultTransposeConstrained - The inner multiplication routine for a
2745    constrained matrix P^T A^T P.
2746 
2747    Neighbor-wise Collective on Mat and Vec
2748 
2749    Input Parameters:
2750 +  mat - the matrix
2751 -  x   - the vector to be multilplied
2752 
2753    Output Parameters:
2754 .  y - the result
2755 
2756    Notes:
2757    The vectors x and y cannot be the same.  I.e., one cannot
2758    call MatMult(A,y,y).
2759 
2760    Level: beginner
2761 
2762 .keywords: matrix, multiply, matrix-vector product, constraint
2763 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2764 @*/
2765 PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2766 {
2767   PetscErrorCode ierr;
2768 
2769   PetscFunctionBegin;
2770   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2771   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2772   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2773   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2774   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2775   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2776   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);
2777   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);
2778 
2779   ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2780   ierr = (*mat->ops->multtransposeconstrained)(mat,x,y);CHKERRQ(ierr);
2781   ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2782   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2783   PetscFunctionReturn(0);
2784 }
2785 
2786 /*@C
2787    MatGetFactorType - gets the type of factorization it is
2788 
2789    Not Collective
2790 
2791    Input Parameters:
2792 .  mat - the matrix
2793 
2794    Output Parameters:
2795 .  t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT
2796 
2797    Level: intermediate
2798 
2799 .seealso: MatFactorType, MatGetFactor(), MatSetFactorType()
2800 @*/
2801 PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t)
2802 {
2803   PetscFunctionBegin;
2804   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2805   PetscValidType(mat,1);
2806   PetscValidPointer(t,2);
2807   *t = mat->factortype;
2808   PetscFunctionReturn(0);
2809 }
2810 
2811 /*@C
2812    MatSetFactorType - sets the type of factorization it is
2813 
2814    Logically Collective on Mat
2815 
2816    Input Parameters:
2817 +  mat - the matrix
2818 -  t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT
2819 
2820    Level: intermediate
2821 
2822 .seealso: MatFactorType, MatGetFactor(), MatGetFactorType()
2823 @*/
2824 PetscErrorCode MatSetFactorType(Mat mat, MatFactorType t)
2825 {
2826   PetscFunctionBegin;
2827   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2828   PetscValidType(mat,1);
2829   mat->factortype = t;
2830   PetscFunctionReturn(0);
2831 }
2832 
2833 /* ------------------------------------------------------------*/
2834 /*@C
2835    MatGetInfo - Returns information about matrix storage (number of
2836    nonzeros, memory, etc.).
2837 
2838    Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag
2839 
2840    Input Parameters:
2841 .  mat - the matrix
2842 
2843    Output Parameters:
2844 +  flag - flag indicating the type of parameters to be returned
2845    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2846    MAT_GLOBAL_SUM - sum over all processors)
2847 -  info - matrix information context
2848 
2849    Notes:
2850    The MatInfo context contains a variety of matrix data, including
2851    number of nonzeros allocated and used, number of mallocs during
2852    matrix assembly, etc.  Additional information for factored matrices
2853    is provided (such as the fill ratio, number of mallocs during
2854    factorization, etc.).  Much of this info is printed to PETSC_STDOUT
2855    when using the runtime options
2856 $       -info -mat_view ::ascii_info
2857 
2858    Example for C/C++ Users:
2859    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2860    data within the MatInfo context.  For example,
2861 .vb
2862       MatInfo info;
2863       Mat     A;
2864       double  mal, nz_a, nz_u;
2865 
2866       MatGetInfo(A,MAT_LOCAL,&info);
2867       mal  = info.mallocs;
2868       nz_a = info.nz_allocated;
2869 .ve
2870 
2871    Example for Fortran Users:
2872    Fortran users should declare info as a double precision
2873    array of dimension MAT_INFO_SIZE, and then extract the parameters
2874    of interest.  See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h
2875    a complete list of parameter names.
2876 .vb
2877       double  precision info(MAT_INFO_SIZE)
2878       double  precision mal, nz_a
2879       Mat     A
2880       integer ierr
2881 
2882       call MatGetInfo(A,MAT_LOCAL,info,ierr)
2883       mal = info(MAT_INFO_MALLOCS)
2884       nz_a = info(MAT_INFO_NZ_ALLOCATED)
2885 .ve
2886 
2887     Level: intermediate
2888 
2889     Concepts: matrices^getting information on
2890 
2891     Developer Note: fortran interface is not autogenerated as the f90
2892     interface defintion cannot be generated correctly [due to MatInfo]
2893 
2894 .seealso: MatStashGetInfo()
2895 
2896 @*/
2897 PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2898 {
2899   PetscErrorCode ierr;
2900 
2901   PetscFunctionBegin;
2902   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2903   PetscValidType(mat,1);
2904   PetscValidPointer(info,3);
2905   if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2906   MatCheckPreallocated(mat,1);
2907   ierr = (*mat->ops->getinfo)(mat,flag,info);CHKERRQ(ierr);
2908   PetscFunctionReturn(0);
2909 }
2910 
2911 /*
2912    This is used by external packages where it is not easy to get the info from the actual
2913    matrix factorization.
2914 */
2915 PetscErrorCode MatGetInfo_External(Mat A,MatInfoType flag,MatInfo *info)
2916 {
2917   PetscErrorCode ierr;
2918 
2919   PetscFunctionBegin;
2920   ierr = PetscMemzero(info,sizeof(MatInfo));CHKERRQ(ierr);
2921   PetscFunctionReturn(0);
2922 }
2923 
2924 /* ----------------------------------------------------------*/
2925 
2926 /*@C
2927    MatLUFactor - Performs in-place LU factorization of matrix.
2928 
2929    Collective on Mat
2930 
2931    Input Parameters:
2932 +  mat - the matrix
2933 .  row - row permutation
2934 .  col - column permutation
2935 -  info - options for factorization, includes
2936 $          fill - expected fill as ratio of original fill.
2937 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2938 $                   Run with the option -info to determine an optimal value to use
2939 
2940    Notes:
2941    Most users should employ the simplified KSP interface for linear solvers
2942    instead of working directly with matrix algebra routines such as this.
2943    See, e.g., KSPCreate().
2944 
2945    This changes the state of the matrix to a factored matrix; it cannot be used
2946    for example with MatSetValues() unless one first calls MatSetUnfactored().
2947 
2948    Level: developer
2949 
2950    Concepts: matrices^LU factorization
2951 
2952 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2953           MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor()
2954 
2955     Developer Note: fortran interface is not autogenerated as the f90
2956     interface defintion cannot be generated correctly [due to MatFactorInfo]
2957 
2958 @*/
2959 PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2960 {
2961   PetscErrorCode ierr;
2962   MatFactorInfo  tinfo;
2963 
2964   PetscFunctionBegin;
2965   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2966   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
2967   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
2968   if (info) PetscValidPointer(info,4);
2969   PetscValidType(mat,1);
2970   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2971   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2972   if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2973   MatCheckPreallocated(mat,1);
2974   if (!info) {
2975     ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr);
2976     info = &tinfo;
2977   }
2978 
2979   ierr = PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
2980   ierr = (*mat->ops->lufactor)(mat,row,col,info);CHKERRQ(ierr);
2981   ierr = PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
2982   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
2983   PetscFunctionReturn(0);
2984 }
2985 
2986 /*@C
2987    MatILUFactor - Performs in-place ILU factorization of matrix.
2988 
2989    Collective on Mat
2990 
2991    Input Parameters:
2992 +  mat - the matrix
2993 .  row - row permutation
2994 .  col - column permutation
2995 -  info - structure containing
2996 $      levels - number of levels of fill.
2997 $      expected fill - as ratio of original fill.
2998 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2999                 missing diagonal entries)
3000 
3001    Notes:
3002    Probably really in-place only when level of fill is zero, otherwise allocates
3003    new space to store factored matrix and deletes previous memory.
3004 
3005    Most users should employ the simplified KSP interface for linear solvers
3006    instead of working directly with matrix algebra routines such as this.
3007    See, e.g., KSPCreate().
3008 
3009    Level: developer
3010 
3011    Concepts: matrices^ILU factorization
3012 
3013 .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
3014 
3015     Developer Note: fortran interface is not autogenerated as the f90
3016     interface defintion cannot be generated correctly [due to MatFactorInfo]
3017 
3018 @*/
3019 PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
3020 {
3021   PetscErrorCode ierr;
3022 
3023   PetscFunctionBegin;
3024   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3025   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
3026   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
3027   PetscValidPointer(info,4);
3028   PetscValidType(mat,1);
3029   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
3030   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3031   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3032   if (!mat->ops->ilufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3033   MatCheckPreallocated(mat,1);
3034 
3035   ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
3036   ierr = (*mat->ops->ilufactor)(mat,row,col,info);CHKERRQ(ierr);
3037   ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
3038   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
3039   PetscFunctionReturn(0);
3040 }
3041 
3042 /*@C
3043    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
3044    Call this routine before calling MatLUFactorNumeric().
3045 
3046    Collective on Mat
3047 
3048    Input Parameters:
3049 +  fact - the factor matrix obtained with MatGetFactor()
3050 .  mat - the matrix
3051 .  row, col - row and column permutations
3052 -  info - options for factorization, includes
3053 $          fill - expected fill as ratio of original fill.
3054 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3055 $                   Run with the option -info to determine an optimal value to use
3056 
3057 
3058    Notes:
3059     See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
3060 
3061    Most users should employ the simplified KSP interface for linear solvers
3062    instead of working directly with matrix algebra routines such as this.
3063    See, e.g., KSPCreate().
3064 
3065    Level: developer
3066 
3067    Concepts: matrices^LU symbolic factorization
3068 
3069 .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo, MatFactorInfoInitialize()
3070 
3071     Developer Note: fortran interface is not autogenerated as the f90
3072     interface defintion cannot be generated correctly [due to MatFactorInfo]
3073 
3074 @*/
3075 PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
3076 {
3077   PetscErrorCode ierr;
3078 
3079   PetscFunctionBegin;
3080   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3081   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
3082   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
3083   if (info) PetscValidPointer(info,4);
3084   PetscValidType(mat,1);
3085   PetscValidPointer(fact,5);
3086   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3087   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3088   if (!(fact)->ops->lufactorsymbolic) {
3089     MatSolverType spackage;
3090     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
3091     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage);
3092   }
3093   MatCheckPreallocated(mat,2);
3094 
3095   ierr = PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
3096   ierr = (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
3097   ierr = PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
3098   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3099   PetscFunctionReturn(0);
3100 }
3101 
3102 /*@C
3103    MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
3104    Call this routine after first calling MatLUFactorSymbolic().
3105 
3106    Collective on Mat
3107 
3108    Input Parameters:
3109 +  fact - the factor matrix obtained with MatGetFactor()
3110 .  mat - the matrix
3111 -  info - options for factorization
3112 
3113    Notes:
3114    See MatLUFactor() for in-place factorization.  See
3115    MatCholeskyFactorNumeric() for the symmetric, positive definite case.
3116 
3117    Most users should employ the simplified KSP interface for linear solvers
3118    instead of working directly with matrix algebra routines such as this.
3119    See, e.g., KSPCreate().
3120 
3121    Level: developer
3122 
3123    Concepts: matrices^LU numeric factorization
3124 
3125 .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()
3126 
3127     Developer Note: fortran interface is not autogenerated as the f90
3128     interface defintion cannot be generated correctly [due to MatFactorInfo]
3129 
3130 @*/
3131 PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3132 {
3133   PetscErrorCode ierr;
3134 
3135   PetscFunctionBegin;
3136   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3137   PetscValidType(mat,1);
3138   PetscValidPointer(fact,2);
3139   PetscValidHeaderSpecific(fact,MAT_CLASSID,2);
3140   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3141   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);
3142 
3143   if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name);
3144   MatCheckPreallocated(mat,2);
3145   ierr = PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3146   ierr = (fact->ops->lufactornumeric)(fact,mat,info);CHKERRQ(ierr);
3147   ierr = PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3148   ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr);
3149   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3150   PetscFunctionReturn(0);
3151 }
3152 
3153 /*@C
3154    MatCholeskyFactor - Performs in-place Cholesky factorization of a
3155    symmetric matrix.
3156 
3157    Collective on Mat
3158 
3159    Input Parameters:
3160 +  mat - the matrix
3161 .  perm - row and column permutations
3162 -  f - expected fill as ratio of original fill
3163 
3164    Notes:
3165    See MatLUFactor() for the nonsymmetric case.  See also
3166    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().
3167 
3168    Most users should employ the simplified KSP interface for linear solvers
3169    instead of working directly with matrix algebra routines such as this.
3170    See, e.g., KSPCreate().
3171 
3172    Level: developer
3173 
3174    Concepts: matrices^Cholesky factorization
3175 
3176 .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
3177           MatGetOrdering()
3178 
3179     Developer Note: fortran interface is not autogenerated as the f90
3180     interface defintion cannot be generated correctly [due to MatFactorInfo]
3181 
3182 @*/
3183 PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
3184 {
3185   PetscErrorCode ierr;
3186 
3187   PetscFunctionBegin;
3188   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3189   PetscValidType(mat,1);
3190   if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2);
3191   if (info) PetscValidPointer(info,3);
3192   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3193   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3194   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3195   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);
3196   MatCheckPreallocated(mat,1);
3197 
3198   ierr = PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
3199   ierr = (*mat->ops->choleskyfactor)(mat,perm,info);CHKERRQ(ierr);
3200   ierr = PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
3201   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
3202   PetscFunctionReturn(0);
3203 }
3204 
3205 /*@C
3206    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
3207    of a symmetric matrix.
3208 
3209    Collective on Mat
3210 
3211    Input Parameters:
3212 +  fact - the factor matrix obtained with MatGetFactor()
3213 .  mat - the matrix
3214 .  perm - row and column permutations
3215 -  info - options for factorization, includes
3216 $          fill - expected fill as ratio of original fill.
3217 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3218 $                   Run with the option -info to determine an optimal value to use
3219 
3220    Notes:
3221    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
3222    MatCholeskyFactor() and MatCholeskyFactorNumeric().
3223 
3224    Most users should employ the simplified KSP interface for linear solvers
3225    instead of working directly with matrix algebra routines such as this.
3226    See, e.g., KSPCreate().
3227 
3228    Level: developer
3229 
3230    Concepts: matrices^Cholesky symbolic factorization
3231 
3232 .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
3233           MatGetOrdering()
3234 
3235     Developer Note: fortran interface is not autogenerated as the f90
3236     interface defintion cannot be generated correctly [due to MatFactorInfo]
3237 
3238 @*/
3239 PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
3240 {
3241   PetscErrorCode ierr;
3242 
3243   PetscFunctionBegin;
3244   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3245   PetscValidType(mat,1);
3246   if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2);
3247   if (info) PetscValidPointer(info,3);
3248   PetscValidPointer(fact,4);
3249   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3250   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3251   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3252   if (!(fact)->ops->choleskyfactorsymbolic) {
3253     MatSolverType spackage;
3254     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
3255     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage);
3256   }
3257   MatCheckPreallocated(mat,2);
3258 
3259   ierr = PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
3260   ierr = (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
3261   ierr = PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
3262   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3263   PetscFunctionReturn(0);
3264 }
3265 
3266 /*@C
3267    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
3268    of a symmetric matrix. Call this routine after first calling
3269    MatCholeskyFactorSymbolic().
3270 
3271    Collective on Mat
3272 
3273    Input Parameters:
3274 +  fact - the factor matrix obtained with MatGetFactor()
3275 .  mat - the initial matrix
3276 .  info - options for factorization
3277 -  fact - the symbolic factor of mat
3278 
3279 
3280    Notes:
3281    Most users should employ the simplified KSP interface for linear solvers
3282    instead of working directly with matrix algebra routines such as this.
3283    See, e.g., KSPCreate().
3284 
3285    Level: developer
3286 
3287    Concepts: matrices^Cholesky numeric factorization
3288 
3289 .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
3290 
3291     Developer Note: fortran interface is not autogenerated as the f90
3292     interface defintion cannot be generated correctly [due to MatFactorInfo]
3293 
3294 @*/
3295 PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3296 {
3297   PetscErrorCode ierr;
3298 
3299   PetscFunctionBegin;
3300   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3301   PetscValidType(mat,1);
3302   PetscValidPointer(fact,2);
3303   PetscValidHeaderSpecific(fact,MAT_CLASSID,2);
3304   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3305   if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name);
3306   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);
3307   MatCheckPreallocated(mat,2);
3308 
3309   ierr = PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3310   ierr = (fact->ops->choleskyfactornumeric)(fact,mat,info);CHKERRQ(ierr);
3311   ierr = PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3312   ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr);
3313   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3314   PetscFunctionReturn(0);
3315 }
3316 
3317 /* ----------------------------------------------------------------*/
3318 /*@
3319    MatSolve - Solves A x = b, given a factored matrix.
3320 
3321    Neighbor-wise Collective on Mat and Vec
3322 
3323    Input Parameters:
3324 +  mat - the factored matrix
3325 -  b - the right-hand-side vector
3326 
3327    Output Parameter:
3328 .  x - the result vector
3329 
3330    Notes:
3331    The vectors b and x cannot be the same.  I.e., one cannot
3332    call MatSolve(A,x,x).
3333 
3334    Notes:
3335    Most users should employ the simplified KSP interface for linear solvers
3336    instead of working directly with matrix algebra routines such as this.
3337    See, e.g., KSPCreate().
3338 
3339    Level: developer
3340 
3341    Concepts: matrices^triangular solves
3342 
3343 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
3344 @*/
3345 PetscErrorCode MatSolve(Mat mat,Vec b,Vec x)
3346 {
3347   PetscErrorCode ierr;
3348 
3349   PetscFunctionBegin;
3350   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3351   PetscValidType(mat,1);
3352   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3353   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3354   PetscCheckSameComm(mat,1,b,2);
3355   PetscCheckSameComm(mat,1,x,3);
3356   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3357   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);
3358   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);
3359   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);
3360   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3361   if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3362   MatCheckPreallocated(mat,1);
3363 
3364   ierr = PetscLogEventBegin(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
3365   if (mat->factorerrortype) {
3366     ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3367     ierr = VecSetInf(x);CHKERRQ(ierr);
3368   } else {
3369     if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3370     ierr = (*mat->ops->solve)(mat,b,x);CHKERRQ(ierr);
3371   }
3372   ierr = PetscLogEventEnd(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
3373   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3374   PetscFunctionReturn(0);
3375 }
3376 
3377 static PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X, PetscBool trans)
3378 {
3379   PetscErrorCode ierr;
3380   Vec            b,x;
3381   PetscInt       m,N,i;
3382   PetscScalar    *bb,*xx;
3383   PetscBool      flg;
3384 
3385   PetscFunctionBegin;
3386   ierr = PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr);
3387   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
3388   ierr = PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr);
3389   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");
3390 
3391   ierr = MatDenseGetArray(B,&bb);CHKERRQ(ierr);
3392   ierr = MatDenseGetArray(X,&xx);CHKERRQ(ierr);
3393   ierr = MatGetLocalSize(B,&m,NULL);CHKERRQ(ierr);  /* number local rows */
3394   ierr = MatGetSize(B,NULL,&N);CHKERRQ(ierr);       /* total columns in dense matrix */
3395   ierr = MatCreateVecs(A,&x,&b);CHKERRQ(ierr);
3396   for (i=0; i<N; i++) {
3397     ierr = VecPlaceArray(b,bb + i*m);CHKERRQ(ierr);
3398     ierr = VecPlaceArray(x,xx + i*m);CHKERRQ(ierr);
3399     if (trans) {
3400       ierr = MatSolveTranspose(A,b,x);CHKERRQ(ierr);
3401     } else {
3402       ierr = MatSolve(A,b,x);CHKERRQ(ierr);
3403     }
3404     ierr = VecResetArray(x);CHKERRQ(ierr);
3405     ierr = VecResetArray(b);CHKERRQ(ierr);
3406   }
3407   ierr = VecDestroy(&b);CHKERRQ(ierr);
3408   ierr = VecDestroy(&x);CHKERRQ(ierr);
3409   ierr = MatDenseRestoreArray(B,&bb);CHKERRQ(ierr);
3410   ierr = MatDenseRestoreArray(X,&xx);CHKERRQ(ierr);
3411   PetscFunctionReturn(0);
3412 }
3413 
3414 /*@
3415    MatMatSolve - Solves A X = B, given a factored matrix.
3416 
3417    Neighbor-wise Collective on Mat
3418 
3419    Input Parameters:
3420 +  A - the factored matrix
3421 -  B - the right-hand-side matrix  (dense matrix)
3422 
3423    Output Parameter:
3424 .  X - the result matrix (dense matrix)
3425 
3426    Notes:
3427    The matrices b and x cannot be the same.  I.e., one cannot
3428    call MatMatSolve(A,x,x).
3429 
3430    Notes:
3431    Most users should usually employ the simplified KSP interface for linear solvers
3432    instead of working directly with matrix algebra routines such as this.
3433    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3434    at a time.
3435 
3436    When using SuperLU_Dist as a parallel solver PETSc will use the SuperLU_Dist functionality to solve multiple right hand sides simultaneously. For MUMPS
3437    it calls a separate solve for each right hand side since MUMPS does not yet support distributed right hand sides.
3438 
3439    Since the resulting matrix X must always be dense we do not support sparse representation of the matrix B.
3440 
3441    Level: developer
3442 
3443    Concepts: matrices^triangular solves
3444 
3445 .seealso: MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor()
3446 @*/
3447 PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X)
3448 {
3449   PetscErrorCode ierr;
3450 
3451   PetscFunctionBegin;
3452   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3453   PetscValidType(A,1);
3454   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3455   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3456   PetscCheckSameComm(A,1,B,2);
3457   PetscCheckSameComm(A,1,X,3);
3458   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3459   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);
3460   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);
3461   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");
3462   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3463   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3464   MatCheckPreallocated(A,1);
3465 
3466   ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3467   if (!A->ops->matsolve) {
3468     ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name);CHKERRQ(ierr);
3469     ierr = MatMatSolve_Basic(A,B,X,PETSC_FALSE);CHKERRQ(ierr);
3470   } else {
3471     ierr = (*A->ops->matsolve)(A,B,X);CHKERRQ(ierr);
3472   }
3473   ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3474   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3475   PetscFunctionReturn(0);
3476 }
3477 
3478 /*@
3479    MatMatSolveTranspose - Solves A^T X = B, given a factored matrix.
3480 
3481    Neighbor-wise Collective on Mat
3482 
3483    Input Parameters:
3484 +  A - the factored matrix
3485 -  B - the right-hand-side matrix  (dense matrix)
3486 
3487    Output Parameter:
3488 .  X - the result matrix (dense matrix)
3489 
3490    Notes:
3491    The matrices B and X cannot be the same.  I.e., one cannot
3492    call MatMatSolveTranspose(A,X,X).
3493 
3494    Notes:
3495    Most users should usually employ the simplified KSP interface for linear solvers
3496    instead of working directly with matrix algebra routines such as this.
3497    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3498    at a time.
3499 
3500    When using SuperLU_Dist or MUMPS as a parallel solver, PETSc will use their functionality to solve multiple right hand sides simultaneously.
3501 
3502    Level: developer
3503 
3504    Concepts: matrices^triangular solves
3505 
3506 .seealso: MatMatSolve(), MatLUFactor(), MatCholeskyFactor()
3507 @*/
3508 PetscErrorCode MatMatSolveTranspose(Mat A,Mat B,Mat X)
3509 {
3510   PetscErrorCode ierr;
3511 
3512   PetscFunctionBegin;
3513   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3514   PetscValidType(A,1);
3515   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3516   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3517   PetscCheckSameComm(A,1,B,2);
3518   PetscCheckSameComm(A,1,X,3);
3519   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3520   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);
3521   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);
3522   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);
3523   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");
3524   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3525   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3526   MatCheckPreallocated(A,1);
3527 
3528   ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3529   if (!A->ops->matsolvetranspose) {
3530     ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolveTranspose\n",((PetscObject)A)->type_name);CHKERRQ(ierr);
3531     ierr = MatMatSolve_Basic(A,B,X,PETSC_TRUE);CHKERRQ(ierr);
3532   } else {
3533     ierr = (*A->ops->matsolvetranspose)(A,B,X);CHKERRQ(ierr);
3534   }
3535   ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3536   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3537   PetscFunctionReturn(0);
3538 }
3539 
3540 /*@
3541    MatMatTransposeSolve - Solves A X = B^T, given a factored matrix.
3542 
3543    Neighbor-wise Collective on Mat
3544 
3545    Input Parameters:
3546 +  A - the factored matrix
3547 -  Bt - the transpose of right-hand-side matrix
3548 
3549    Output Parameter:
3550 .  X - the result matrix (dense matrix)
3551 
3552    Notes:
3553    Most users should usually employ the simplified KSP interface for linear solvers
3554    instead of working directly with matrix algebra routines such as this.
3555    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3556    at a time.
3557 
3558    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().
3559 
3560    Level: developer
3561 
3562    Concepts: matrices^triangular solves
3563 
3564 .seealso: MatMatSolve(), MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor()
3565 @*/
3566 PetscErrorCode MatMatTransposeSolve(Mat A,Mat Bt,Mat X)
3567 {
3568   PetscErrorCode ierr;
3569 
3570   PetscFunctionBegin;
3571   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3572   PetscValidType(A,1);
3573   PetscValidHeaderSpecific(Bt,MAT_CLASSID,2);
3574   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3575   PetscCheckSameComm(A,1,Bt,2);
3576   PetscCheckSameComm(A,1,X,3);
3577 
3578   if (X == Bt) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3579   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);
3580   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);
3581   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");
3582   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3583   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3584   MatCheckPreallocated(A,1);
3585 
3586   if (!A->ops->mattransposesolve) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
3587   ierr = PetscLogEventBegin(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr);
3588   ierr = (*A->ops->mattransposesolve)(A,Bt,X);CHKERRQ(ierr);
3589   ierr = PetscLogEventEnd(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr);
3590   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3591   PetscFunctionReturn(0);
3592 }
3593 
3594 /*@
3595    MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or
3596                             U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U,
3597 
3598    Neighbor-wise Collective on Mat and Vec
3599 
3600    Input Parameters:
3601 +  mat - the factored matrix
3602 -  b - the right-hand-side vector
3603 
3604    Output Parameter:
3605 .  x - the result vector
3606 
3607    Notes:
3608    MatSolve() should be used for most applications, as it performs
3609    a forward solve followed by a backward solve.
3610 
3611    The vectors b and x cannot be the same,  i.e., one cannot
3612    call MatForwardSolve(A,x,x).
3613 
3614    For matrix in seqsbaij format with block size larger than 1,
3615    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3616    MatForwardSolve() solves U^T*D y = b, and
3617    MatBackwardSolve() solves U x = y.
3618    Thus they do not provide a symmetric preconditioner.
3619 
3620    Most users should employ the simplified KSP interface for linear solvers
3621    instead of working directly with matrix algebra routines such as this.
3622    See, e.g., KSPCreate().
3623 
3624    Level: developer
3625 
3626    Concepts: matrices^forward solves
3627 
3628 .seealso: MatSolve(), MatBackwardSolve()
3629 @*/
3630 PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x)
3631 {
3632   PetscErrorCode ierr;
3633 
3634   PetscFunctionBegin;
3635   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3636   PetscValidType(mat,1);
3637   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3638   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3639   PetscCheckSameComm(mat,1,b,2);
3640   PetscCheckSameComm(mat,1,x,3);
3641   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3642   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);
3643   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);
3644   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);
3645   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3646   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3647   MatCheckPreallocated(mat,1);
3648 
3649   if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3650   ierr = PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
3651   ierr = (*mat->ops->forwardsolve)(mat,b,x);CHKERRQ(ierr);
3652   ierr = PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
3653   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3654   PetscFunctionReturn(0);
3655 }
3656 
3657 /*@
3658    MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
3659                              D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U,
3660 
3661    Neighbor-wise Collective on Mat and Vec
3662 
3663    Input Parameters:
3664 +  mat - the factored matrix
3665 -  b - the right-hand-side vector
3666 
3667    Output Parameter:
3668 .  x - the result vector
3669 
3670    Notes:
3671    MatSolve() should be used for most applications, as it performs
3672    a forward solve followed by a backward solve.
3673 
3674    The vectors b and x cannot be the same.  I.e., one cannot
3675    call MatBackwardSolve(A,x,x).
3676 
3677    For matrix in seqsbaij format with block size larger than 1,
3678    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3679    MatForwardSolve() solves U^T*D y = b, and
3680    MatBackwardSolve() solves U x = y.
3681    Thus they do not provide a symmetric preconditioner.
3682 
3683    Most users should employ the simplified KSP interface for linear solvers
3684    instead of working directly with matrix algebra routines such as this.
3685    See, e.g., KSPCreate().
3686 
3687    Level: developer
3688 
3689    Concepts: matrices^backward solves
3690 
3691 .seealso: MatSolve(), MatForwardSolve()
3692 @*/
3693 PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x)
3694 {
3695   PetscErrorCode ierr;
3696 
3697   PetscFunctionBegin;
3698   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3699   PetscValidType(mat,1);
3700   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3701   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3702   PetscCheckSameComm(mat,1,b,2);
3703   PetscCheckSameComm(mat,1,x,3);
3704   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3705   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);
3706   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);
3707   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);
3708   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3709   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3710   MatCheckPreallocated(mat,1);
3711 
3712   if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3713   ierr = PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
3714   ierr = (*mat->ops->backwardsolve)(mat,b,x);CHKERRQ(ierr);
3715   ierr = PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
3716   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3717   PetscFunctionReturn(0);
3718 }
3719 
3720 /*@
3721    MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
3722 
3723    Neighbor-wise Collective on Mat and Vec
3724 
3725    Input Parameters:
3726 +  mat - the factored matrix
3727 .  b - the right-hand-side vector
3728 -  y - the vector to be added to
3729 
3730    Output Parameter:
3731 .  x - the result vector
3732 
3733    Notes:
3734    The vectors b and x cannot be the same.  I.e., one cannot
3735    call MatSolveAdd(A,x,y,x).
3736 
3737    Most users should employ the simplified KSP interface for linear solvers
3738    instead of working directly with matrix algebra routines such as this.
3739    See, e.g., KSPCreate().
3740 
3741    Level: developer
3742 
3743    Concepts: matrices^triangular solves
3744 
3745 .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3746 @*/
3747 PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3748 {
3749   PetscScalar    one = 1.0;
3750   Vec            tmp;
3751   PetscErrorCode ierr;
3752 
3753   PetscFunctionBegin;
3754   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3755   PetscValidType(mat,1);
3756   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3757   PetscValidHeaderSpecific(b,VEC_CLASSID,3);
3758   PetscValidHeaderSpecific(x,VEC_CLASSID,4);
3759   PetscCheckSameComm(mat,1,b,2);
3760   PetscCheckSameComm(mat,1,y,2);
3761   PetscCheckSameComm(mat,1,x,3);
3762   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3763   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);
3764   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);
3765   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);
3766   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);
3767   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);
3768   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3769   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3770   MatCheckPreallocated(mat,1);
3771 
3772   ierr = PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
3773   if (mat->ops->solveadd) {
3774     ierr = (*mat->ops->solveadd)(mat,b,y,x);CHKERRQ(ierr);
3775   } else {
3776     /* do the solve then the add manually */
3777     if (x != y) {
3778       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
3779       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
3780     } else {
3781       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
3782       ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr);
3783       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
3784       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
3785       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
3786       ierr = VecDestroy(&tmp);CHKERRQ(ierr);
3787     }
3788   }
3789   ierr = PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
3790   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3791   PetscFunctionReturn(0);
3792 }
3793 
3794 /*@
3795    MatSolveTranspose - Solves A' x = b, given a factored matrix.
3796 
3797    Neighbor-wise Collective on Mat and Vec
3798 
3799    Input Parameters:
3800 +  mat - the factored matrix
3801 -  b - the right-hand-side vector
3802 
3803    Output Parameter:
3804 .  x - the result vector
3805 
3806    Notes:
3807    The vectors b and x cannot be the same.  I.e., one cannot
3808    call MatSolveTranspose(A,x,x).
3809 
3810    Most users should employ the simplified KSP interface for linear solvers
3811    instead of working directly with matrix algebra routines such as this.
3812    See, e.g., KSPCreate().
3813 
3814    Level: developer
3815 
3816    Concepts: matrices^triangular solves
3817 
3818 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
3819 @*/
3820 PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x)
3821 {
3822   PetscErrorCode ierr;
3823 
3824   PetscFunctionBegin;
3825   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3826   PetscValidType(mat,1);
3827   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3828   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3829   PetscCheckSameComm(mat,1,b,2);
3830   PetscCheckSameComm(mat,1,x,3);
3831   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3832   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);
3833   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);
3834   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3835   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3836   MatCheckPreallocated(mat,1);
3837   ierr = PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
3838   if (mat->factorerrortype) {
3839     ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3840     ierr = VecSetInf(x);CHKERRQ(ierr);
3841   } else {
3842     if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3843     ierr = (*mat->ops->solvetranspose)(mat,b,x);CHKERRQ(ierr);
3844   }
3845   ierr = PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
3846   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3847   PetscFunctionReturn(0);
3848 }
3849 
3850 /*@
3851    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
3852                       factored matrix.
3853 
3854    Neighbor-wise Collective on Mat and Vec
3855 
3856    Input Parameters:
3857 +  mat - the factored matrix
3858 .  b - the right-hand-side vector
3859 -  y - the vector to be added to
3860 
3861    Output Parameter:
3862 .  x - the result vector
3863 
3864    Notes:
3865    The vectors b and x cannot be the same.  I.e., one cannot
3866    call MatSolveTransposeAdd(A,x,y,x).
3867 
3868    Most users should employ the simplified KSP interface for linear solvers
3869    instead of working directly with matrix algebra routines such as this.
3870    See, e.g., KSPCreate().
3871 
3872    Level: developer
3873 
3874    Concepts: matrices^triangular solves
3875 
3876 .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3877 @*/
3878 PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3879 {
3880   PetscScalar    one = 1.0;
3881   PetscErrorCode ierr;
3882   Vec            tmp;
3883 
3884   PetscFunctionBegin;
3885   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3886   PetscValidType(mat,1);
3887   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3888   PetscValidHeaderSpecific(b,VEC_CLASSID,3);
3889   PetscValidHeaderSpecific(x,VEC_CLASSID,4);
3890   PetscCheckSameComm(mat,1,b,2);
3891   PetscCheckSameComm(mat,1,y,3);
3892   PetscCheckSameComm(mat,1,x,4);
3893   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3894   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);
3895   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);
3896   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);
3897   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);
3898   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3899   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3900   MatCheckPreallocated(mat,1);
3901 
3902   ierr = PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
3903   if (mat->ops->solvetransposeadd) {
3904     if (mat->factorerrortype) {
3905       ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3906       ierr = VecSetInf(x);CHKERRQ(ierr);
3907     } else {
3908       ierr = (*mat->ops->solvetransposeadd)(mat,b,y,x);CHKERRQ(ierr);
3909     }
3910   } else {
3911     /* do the solve then the add manually */
3912     if (x != y) {
3913       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
3914       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
3915     } else {
3916       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
3917       ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr);
3918       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
3919       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
3920       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
3921       ierr = VecDestroy(&tmp);CHKERRQ(ierr);
3922     }
3923   }
3924   ierr = PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
3925   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3926   PetscFunctionReturn(0);
3927 }
3928 /* ----------------------------------------------------------------*/
3929 
3930 /*@
3931    MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps.
3932 
3933    Neighbor-wise Collective on Mat and Vec
3934 
3935    Input Parameters:
3936 +  mat - the matrix
3937 .  b - the right hand side
3938 .  omega - the relaxation factor
3939 .  flag - flag indicating the type of SOR (see below)
3940 .  shift -  diagonal shift
3941 .  its - the number of iterations
3942 -  lits - the number of local iterations
3943 
3944    Output Parameters:
3945 .  x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess)
3946 
3947    SOR Flags:
3948 .     SOR_FORWARD_SWEEP - forward SOR
3949 .     SOR_BACKWARD_SWEEP - backward SOR
3950 .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3951 .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR
3952 .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
3953 .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3954 .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
3955          upper/lower triangular part of matrix to
3956          vector (with omega)
3957 .     SOR_ZERO_INITIAL_GUESS - zero initial guess
3958 
3959    Notes:
3960    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3961    SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3962    on each processor.
3963 
3964    Application programmers will not generally use MatSOR() directly,
3965    but instead will employ the KSP/PC interface.
3966 
3967    Notes:
3968     for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing
3969 
3970    Notes for Advanced Users:
3971    The flags are implemented as bitwise inclusive or operations.
3972    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3973    to specify a zero initial guess for SSOR.
3974 
3975    Most users should employ the simplified KSP interface for linear solvers
3976    instead of working directly with matrix algebra routines such as this.
3977    See, e.g., KSPCreate().
3978 
3979    Vectors x and b CANNOT be the same
3980 
3981    Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes
3982 
3983    Level: developer
3984 
3985    Concepts: matrices^relaxation
3986    Concepts: matrices^SOR
3987    Concepts: matrices^Gauss-Seidel
3988 
3989 @*/
3990 PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3991 {
3992   PetscErrorCode ierr;
3993 
3994   PetscFunctionBegin;
3995   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3996   PetscValidType(mat,1);
3997   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3998   PetscValidHeaderSpecific(x,VEC_CLASSID,8);
3999   PetscCheckSameComm(mat,1,b,2);
4000   PetscCheckSameComm(mat,1,x,8);
4001   if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4002   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4003   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4004   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);
4005   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);
4006   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);
4007   if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
4008   if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
4009   if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");
4010 
4011   MatCheckPreallocated(mat,1);
4012   ierr = PetscLogEventBegin(MAT_SOR,mat,b,x,0);CHKERRQ(ierr);
4013   ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr);
4014   ierr = PetscLogEventEnd(MAT_SOR,mat,b,x,0);CHKERRQ(ierr);
4015   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
4016   PetscFunctionReturn(0);
4017 }
4018 
4019 /*
4020       Default matrix copy routine.
4021 */
4022 PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
4023 {
4024   PetscErrorCode    ierr;
4025   PetscInt          i,rstart = 0,rend = 0,nz;
4026   const PetscInt    *cwork;
4027   const PetscScalar *vwork;
4028 
4029   PetscFunctionBegin;
4030   if (B->assembled) {
4031     ierr = MatZeroEntries(B);CHKERRQ(ierr);
4032   }
4033   if (str == SAME_NONZERO_PATTERN) {
4034     ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
4035     for (i=rstart; i<rend; i++) {
4036       ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
4037       ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);CHKERRQ(ierr);
4038       ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
4039     }
4040   } else {
4041     ierr = MatAYPX(B,0.0,A,str);CHKERRQ(ierr);
4042   }
4043   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4044   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4045   PetscFunctionReturn(0);
4046 }
4047 
4048 /*@
4049    MatCopy - Copies a matrix to another matrix.
4050 
4051    Collective on Mat
4052 
4053    Input Parameters:
4054 +  A - the matrix
4055 -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
4056 
4057    Output Parameter:
4058 .  B - where the copy is put
4059 
4060    Notes:
4061    If you use SAME_NONZERO_PATTERN then the two matrices had better have the
4062    same nonzero pattern or the routine will crash.
4063 
4064    MatCopy() copies the matrix entries of a matrix to another existing
4065    matrix (after first zeroing the second matrix).  A related routine is
4066    MatConvert(), which first creates a new matrix and then copies the data.
4067 
4068    Level: intermediate
4069 
4070    Concepts: matrices^copying
4071 
4072 .seealso: MatConvert(), MatDuplicate()
4073 
4074 @*/
4075 PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str)
4076 {
4077   PetscErrorCode ierr;
4078   PetscInt       i;
4079 
4080   PetscFunctionBegin;
4081   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4082   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4083   PetscValidType(A,1);
4084   PetscValidType(B,2);
4085   PetscCheckSameComm(A,1,B,2);
4086   MatCheckPreallocated(B,2);
4087   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4088   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4089   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);
4090   MatCheckPreallocated(A,1);
4091   if (A == B) PetscFunctionReturn(0);
4092 
4093   ierr = PetscLogEventBegin(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
4094   if (A->ops->copy) {
4095     ierr = (*A->ops->copy)(A,B,str);CHKERRQ(ierr);
4096   } else { /* generic conversion */
4097     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
4098   }
4099 
4100   B->stencil.dim = A->stencil.dim;
4101   B->stencil.noc = A->stencil.noc;
4102   for (i=0; i<=A->stencil.dim; i++) {
4103     B->stencil.dims[i]   = A->stencil.dims[i];
4104     B->stencil.starts[i] = A->stencil.starts[i];
4105   }
4106 
4107   ierr = PetscLogEventEnd(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
4108   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
4109   PetscFunctionReturn(0);
4110 }
4111 
4112 /*@C
4113    MatConvert - Converts a matrix to another matrix, either of the same
4114    or different type.
4115 
4116    Collective on Mat
4117 
4118    Input Parameters:
4119 +  mat - the matrix
4120 .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
4121    same type as the original matrix.
4122 -  reuse - denotes if the destination matrix is to be created or reused.
4123    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
4124    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).
4125 
4126    Output Parameter:
4127 .  M - pointer to place new matrix
4128 
4129    Notes:
4130    MatConvert() first creates a new matrix and then copies the data from
4131    the first matrix.  A related routine is MatCopy(), which copies the matrix
4132    entries of one matrix to another already existing matrix context.
4133 
4134    Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
4135    the MPI communicator of the generated matrix is always the same as the communicator
4136    of the input matrix.
4137 
4138    Level: intermediate
4139 
4140    Concepts: matrices^converting between storage formats
4141 
4142 .seealso: MatCopy(), MatDuplicate()
4143 @*/
4144 PetscErrorCode MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M)
4145 {
4146   PetscErrorCode ierr;
4147   PetscBool      sametype,issame,flg;
4148   char           convname[256],mtype[256];
4149   Mat            B;
4150 
4151   PetscFunctionBegin;
4152   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4153   PetscValidType(mat,1);
4154   PetscValidPointer(M,3);
4155   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4156   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4157   MatCheckPreallocated(mat,1);
4158 
4159   ierr = PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);CHKERRQ(ierr);
4160   if (flg) {
4161     newtype = mtype;
4162   }
4163   ierr = PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);CHKERRQ(ierr);
4164   ierr = PetscStrcmp(newtype,"same",&issame);CHKERRQ(ierr);
4165   if ((reuse == MAT_INPLACE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix");
4166   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");
4167 
4168   if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) PetscFunctionReturn(0);
4169 
4170   if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
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       if (flg) {
4194         if (reuse == MAT_INPLACE_MATRIX) {
4195           PetscFunctionReturn(0);
4196         } else if (reuse == MAT_INITIAL_MATRIX && mat->ops->duplicate) {
4197           ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
4198           PetscFunctionReturn(0);
4199         } else if (reuse == MAT_REUSE_MATRIX && mat->ops->copy) {
4200           ierr = MatCopy(mat,*M,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
4201           PetscFunctionReturn(0);
4202         }
4203       }
4204     }
4205     /* 1) See if a specialized converter is known to the current matrix and the desired class */
4206     for (i=0; i<3; i++) {
4207       ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr);
4208       ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr);
4209       ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr);
4210       ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4211       ierr = PetscStrlcat(convname,issame ? ((PetscObject)mat)->type_name : newtype,sizeof(convname));CHKERRQ(ierr);
4212       ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr);
4213       ierr = PetscObjectQueryFunction((PetscObject)mat,convname,&conv);CHKERRQ(ierr);
4214       if (conv) goto foundconv;
4215     }
4216 
4217     /* 2)  See if a specialized converter is known to the desired matrix class. */
4218     ierr = MatCreate(PetscObjectComm((PetscObject)mat),&B);CHKERRQ(ierr);
4219     ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);CHKERRQ(ierr);
4220     ierr = MatSetType(B,newtype);CHKERRQ(ierr);
4221     for (i=0; i<3; i++) {
4222       ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr);
4223       ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr);
4224       ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr);
4225       ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4226       ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr);
4227       ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr);
4228       ierr = PetscObjectQueryFunction((PetscObject)B,convname,&conv);CHKERRQ(ierr);
4229       if (conv) {
4230         ierr = MatDestroy(&B);CHKERRQ(ierr);
4231         goto foundconv;
4232       }
4233     }
4234 
4235     /* 3) See if a good general converter is registered for the desired class */
4236     conv = B->ops->convertfrom;
4237     ierr = MatDestroy(&B);CHKERRQ(ierr);
4238     if (conv) goto foundconv;
4239 
4240     /* 4) See if a good general converter is known for the current matrix */
4241     if (mat->ops->convert) {
4242       conv = mat->ops->convert;
4243     }
4244     if (conv) goto foundconv;
4245 
4246     /* 5) Use a really basic converter. */
4247     conv = MatConvert_Basic;
4248 
4249 foundconv:
4250     ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4251     ierr = (*conv)(mat,newtype,reuse,M);CHKERRQ(ierr);
4252     if (mat->rmap->mapping && mat->cmap->mapping && !(*M)->rmap->mapping && !(*M)->cmap->mapping) {
4253       /* the block sizes must be same if the mappings are copied over */
4254       (*M)->rmap->bs = mat->rmap->bs;
4255       (*M)->cmap->bs = mat->cmap->bs;
4256       ierr = PetscObjectReference((PetscObject)mat->rmap->mapping);CHKERRQ(ierr);
4257       ierr = PetscObjectReference((PetscObject)mat->cmap->mapping);CHKERRQ(ierr);
4258       (*M)->rmap->mapping = mat->rmap->mapping;
4259       (*M)->cmap->mapping = mat->cmap->mapping;
4260     }
4261     (*M)->stencil.dim = mat->stencil.dim;
4262     (*M)->stencil.noc = mat->stencil.noc;
4263     for (i=0; i<=mat->stencil.dim; i++) {
4264       (*M)->stencil.dims[i]   = mat->stencil.dims[i];
4265       (*M)->stencil.starts[i] = mat->stencil.starts[i];
4266     }
4267     ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4268   }
4269   ierr = PetscObjectStateIncrease((PetscObject)*M);CHKERRQ(ierr);
4270 
4271   /* Copy Mat options */
4272   if (mat->symmetric) {ierr = MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);}
4273   if (mat->hermitian) {ierr = MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);}
4274   PetscFunctionReturn(0);
4275 }
4276 
4277 /*@C
4278    MatFactorGetSolverType - Returns name of the package providing the factorization routines
4279 
4280    Not Collective
4281 
4282    Input Parameter:
4283 .  mat - the matrix, must be a factored matrix
4284 
4285    Output Parameter:
4286 .   type - the string name of the package (do not free this string)
4287 
4288    Notes:
4289       In Fortran you pass in a empty string and the package name will be copied into it.
4290     (Make sure the string is long enough)
4291 
4292    Level: intermediate
4293 
4294 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
4295 @*/
4296 PetscErrorCode MatFactorGetSolverType(Mat mat, MatSolverType *type)
4297 {
4298   PetscErrorCode ierr, (*conv)(Mat,MatSolverType*);
4299 
4300   PetscFunctionBegin;
4301   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4302   PetscValidType(mat,1);
4303   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
4304   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverType_C",&conv);CHKERRQ(ierr);
4305   if (!conv) {
4306     *type = MATSOLVERPETSC;
4307   } else {
4308     ierr = (*conv)(mat,type);CHKERRQ(ierr);
4309   }
4310   PetscFunctionReturn(0);
4311 }
4312 
4313 typedef struct _MatSolverTypeForSpecifcType* MatSolverTypeForSpecifcType;
4314 struct _MatSolverTypeForSpecifcType {
4315   MatType                        mtype;
4316   PetscErrorCode                 (*getfactor[4])(Mat,MatFactorType,Mat*);
4317   MatSolverTypeForSpecifcType next;
4318 };
4319 
4320 typedef struct _MatSolverTypeHolder* MatSolverTypeHolder;
4321 struct _MatSolverTypeHolder {
4322   char                           *name;
4323   MatSolverTypeForSpecifcType handlers;
4324   MatSolverTypeHolder         next;
4325 };
4326 
4327 static MatSolverTypeHolder MatSolverTypeHolders = NULL;
4328 
4329 /*@C
4330    MatSolvePackageRegister - Registers a MatSolverType that works for a particular matrix type
4331 
4332    Input Parameters:
4333 +    package - name of the package, for example petsc or superlu
4334 .    mtype - the matrix type that works with this package
4335 .    ftype - the type of factorization supported by the package
4336 -    getfactor - routine that will create the factored matrix ready to be used
4337 
4338     Level: intermediate
4339 
4340 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4341 @*/
4342 PetscErrorCode MatSolverTypeRegister(MatSolverType package,MatType mtype,MatFactorType ftype,PetscErrorCode (*getfactor)(Mat,MatFactorType,Mat*))
4343 {
4344   PetscErrorCode              ierr;
4345   MatSolverTypeHolder         next = MatSolverTypeHolders,prev;
4346   PetscBool                   flg;
4347   MatSolverTypeForSpecifcType inext,iprev = NULL;
4348 
4349   PetscFunctionBegin;
4350   ierr = MatInitializePackage();CHKERRQ(ierr);
4351   if (!next) {
4352     ierr = PetscNew(&MatSolverTypeHolders);CHKERRQ(ierr);
4353     ierr = PetscStrallocpy(package,&MatSolverTypeHolders->name);CHKERRQ(ierr);
4354     ierr = PetscNew(&MatSolverTypeHolders->handlers);CHKERRQ(ierr);
4355     ierr = PetscStrallocpy(mtype,(char **)&MatSolverTypeHolders->handlers->mtype);CHKERRQ(ierr);
4356     MatSolverTypeHolders->handlers->getfactor[(int)ftype-1] = getfactor;
4357     PetscFunctionReturn(0);
4358   }
4359   while (next) {
4360     ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr);
4361     if (flg) {
4362       if (!next->handlers) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverTypeHolder is missing handlers");
4363       inext = next->handlers;
4364       while (inext) {
4365         ierr = PetscStrcasecmp(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4366         if (flg) {
4367           inext->getfactor[(int)ftype-1] = getfactor;
4368           PetscFunctionReturn(0);
4369         }
4370         iprev = inext;
4371         inext = inext->next;
4372       }
4373       ierr = PetscNew(&iprev->next);CHKERRQ(ierr);
4374       ierr = PetscStrallocpy(mtype,(char **)&iprev->next->mtype);CHKERRQ(ierr);
4375       iprev->next->getfactor[(int)ftype-1] = getfactor;
4376       PetscFunctionReturn(0);
4377     }
4378     prev = next;
4379     next = next->next;
4380   }
4381   ierr = PetscNew(&prev->next);CHKERRQ(ierr);
4382   ierr = PetscStrallocpy(package,&prev->next->name);CHKERRQ(ierr);
4383   ierr = PetscNew(&prev->next->handlers);CHKERRQ(ierr);
4384   ierr = PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);CHKERRQ(ierr);
4385   prev->next->handlers->getfactor[(int)ftype-1] = getfactor;
4386   PetscFunctionReturn(0);
4387 }
4388 
4389 /*@C
4390    MatSolvePackageGet - Get's the function that creates the factor matrix if it exist
4391 
4392    Input Parameters:
4393 +    package - name of the package, for example petsc or superlu
4394 .    ftype - the type of factorization supported by the package
4395 -    mtype - the matrix type that works with this package
4396 
4397    Output Parameters:
4398 +   foundpackage - PETSC_TRUE if the package was registered
4399 .   foundmtype - PETSC_TRUE if the package supports the requested mtype
4400 -   getfactor - routine that will create the factored matrix ready to be used or NULL if not found
4401 
4402     Level: intermediate
4403 
4404 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4405 @*/
4406 PetscErrorCode MatSolverTypeGet(MatSolverType package,MatType mtype,MatFactorType ftype,PetscBool *foundpackage,PetscBool *foundmtype,PetscErrorCode (**getfactor)(Mat,MatFactorType,Mat*))
4407 {
4408   PetscErrorCode                 ierr;
4409   MatSolverTypeHolder         next = MatSolverTypeHolders;
4410   PetscBool                      flg;
4411   MatSolverTypeForSpecifcType inext;
4412 
4413   PetscFunctionBegin;
4414   if (foundpackage) *foundpackage = PETSC_FALSE;
4415   if (foundmtype)   *foundmtype   = PETSC_FALSE;
4416   if (getfactor)    *getfactor    = NULL;
4417 
4418   if (package) {
4419     while (next) {
4420       ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr);
4421       if (flg) {
4422         if (foundpackage) *foundpackage = PETSC_TRUE;
4423         inext = next->handlers;
4424         while (inext) {
4425           ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4426           if (flg) {
4427             if (foundmtype) *foundmtype = PETSC_TRUE;
4428             if (getfactor)  *getfactor  = inext->getfactor[(int)ftype-1];
4429             PetscFunctionReturn(0);
4430           }
4431           inext = inext->next;
4432         }
4433       }
4434       next = next->next;
4435     }
4436   } else {
4437     while (next) {
4438       inext = next->handlers;
4439       while (inext) {
4440         ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4441         if (flg && inext->getfactor[(int)ftype-1]) {
4442           if (foundpackage) *foundpackage = PETSC_TRUE;
4443           if (foundmtype)   *foundmtype   = PETSC_TRUE;
4444           if (getfactor)    *getfactor    = inext->getfactor[(int)ftype-1];
4445           PetscFunctionReturn(0);
4446         }
4447         inext = inext->next;
4448       }
4449       next = next->next;
4450     }
4451   }
4452   PetscFunctionReturn(0);
4453 }
4454 
4455 PetscErrorCode MatSolverTypeDestroy(void)
4456 {
4457   PetscErrorCode              ierr;
4458   MatSolverTypeHolder         next = MatSolverTypeHolders,prev;
4459   MatSolverTypeForSpecifcType inext,iprev;
4460 
4461   PetscFunctionBegin;
4462   while (next) {
4463     ierr = PetscFree(next->name);CHKERRQ(ierr);
4464     inext = next->handlers;
4465     while (inext) {
4466       ierr = PetscFree(inext->mtype);CHKERRQ(ierr);
4467       iprev = inext;
4468       inext = inext->next;
4469       ierr = PetscFree(iprev);CHKERRQ(ierr);
4470     }
4471     prev = next;
4472     next = next->next;
4473     ierr = PetscFree(prev);CHKERRQ(ierr);
4474   }
4475   MatSolverTypeHolders = NULL;
4476   PetscFunctionReturn(0);
4477 }
4478 
4479 /*@C
4480    MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic()
4481 
4482    Collective on Mat
4483 
4484    Input Parameters:
4485 +  mat - the matrix
4486 .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4487 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4488 
4489    Output Parameters:
4490 .  f - the factor matrix used with MatXXFactorSymbolic() calls
4491 
4492    Notes:
4493       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4494      such as pastix, superlu, mumps etc.
4495 
4496       PETSc must have been ./configure to use the external solver, using the option --download-package
4497 
4498    Level: intermediate
4499 
4500 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4501 @*/
4502 PetscErrorCode MatGetFactor(Mat mat, MatSolverType type,MatFactorType ftype,Mat *f)
4503 {
4504   PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
4505   PetscBool      foundpackage,foundmtype;
4506 
4507   PetscFunctionBegin;
4508   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4509   PetscValidType(mat,1);
4510 
4511   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4512   MatCheckPreallocated(mat,1);
4513 
4514   ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,&foundpackage,&foundmtype,&conv);CHKERRQ(ierr);
4515   if (!foundpackage) {
4516     if (type) {
4517       SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver package %s. Perhaps you must ./configure with --download-%s",type,type);
4518     } else {
4519       SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate a solver package. Perhaps you must ./configure with --download-<package>");
4520     }
4521   }
4522 
4523   if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support matrix type %s",type,((PetscObject)mat)->type_name);
4524   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);
4525 
4526 #if defined(PETSC_USE_COMPLEX)
4527   if (mat->hermitian && !mat->symmetric && (ftype == MAT_FACTOR_CHOLESKY||ftype == MAT_FACTOR_ICC)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Hermitian CHOLESKY or ICC Factor is not supported");
4528 #endif
4529 
4530   ierr = (*conv)(mat,ftype,f);CHKERRQ(ierr);
4531   PetscFunctionReturn(0);
4532 }
4533 
4534 /*@C
4535    MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type
4536 
4537    Not Collective
4538 
4539    Input Parameters:
4540 +  mat - the matrix
4541 .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4542 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4543 
4544    Output Parameter:
4545 .    flg - PETSC_TRUE if the factorization is available
4546 
4547    Notes:
4548       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4549      such as pastix, superlu, mumps etc.
4550 
4551       PETSc must have been ./configure to use the external solver, using the option --download-package
4552 
4553    Level: intermediate
4554 
4555 .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
4556 @*/
4557 PetscErrorCode MatGetFactorAvailable(Mat mat, MatSolverType type,MatFactorType ftype,PetscBool  *flg)
4558 {
4559   PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*);
4560 
4561   PetscFunctionBegin;
4562   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4563   PetscValidType(mat,1);
4564 
4565   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4566   MatCheckPreallocated(mat,1);
4567 
4568   *flg = PETSC_FALSE;
4569   ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);CHKERRQ(ierr);
4570   if (gconv) {
4571     *flg = PETSC_TRUE;
4572   }
4573   PetscFunctionReturn(0);
4574 }
4575 
4576 #include <petscdmtypes.h>
4577 
4578 /*@
4579    MatDuplicate - Duplicates a matrix including the non-zero structure.
4580 
4581    Collective on Mat
4582 
4583    Input Parameters:
4584 +  mat - the matrix
4585 -  op - One of MAT_DO_NOT_COPY_VALUES, MAT_COPY_VALUES, or MAT_SHARE_NONZERO_PATTERN.
4586         See the manual page for MatDuplicateOption for an explanation of these options.
4587 
4588    Output Parameter:
4589 .  M - pointer to place new matrix
4590 
4591    Level: intermediate
4592 
4593    Concepts: matrices^duplicating
4594 
4595    Notes:
4596     You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN.
4597     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.
4598 
4599 .seealso: MatCopy(), MatConvert(), MatDuplicateOption
4600 @*/
4601 PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4602 {
4603   PetscErrorCode ierr;
4604   Mat            B;
4605   PetscInt       i;
4606   DM             dm;
4607   void           (*viewf)(void);
4608 
4609   PetscFunctionBegin;
4610   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4611   PetscValidType(mat,1);
4612   PetscValidPointer(M,3);
4613   if (op == MAT_COPY_VALUES && !mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MAT_COPY_VALUES not allowed for unassembled matrix");
4614   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4615   MatCheckPreallocated(mat,1);
4616 
4617   *M = 0;
4618   if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type");
4619   ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4620   ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr);
4621   B    = *M;
4622 
4623   ierr = MatGetOperation(mat,MATOP_VIEW,&viewf);CHKERRQ(ierr);
4624   if (viewf) {
4625     ierr = MatSetOperation(B,MATOP_VIEW,viewf);CHKERRQ(ierr);
4626   }
4627 
4628   B->stencil.dim = mat->stencil.dim;
4629   B->stencil.noc = mat->stencil.noc;
4630   for (i=0; i<=mat->stencil.dim; i++) {
4631     B->stencil.dims[i]   = mat->stencil.dims[i];
4632     B->stencil.starts[i] = mat->stencil.starts[i];
4633   }
4634 
4635   B->nooffproczerorows = mat->nooffproczerorows;
4636   B->nooffprocentries  = mat->nooffprocentries;
4637 
4638   ierr = PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);CHKERRQ(ierr);
4639   if (dm) {
4640     ierr = PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr);
4641   }
4642   ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4643   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
4644   PetscFunctionReturn(0);
4645 }
4646 
4647 /*@
4648    MatGetDiagonal - Gets the diagonal of a matrix.
4649 
4650    Logically Collective on Mat and Vec
4651 
4652    Input Parameters:
4653 +  mat - the matrix
4654 -  v - the vector for storing the diagonal
4655 
4656    Output Parameter:
4657 .  v - the diagonal of the matrix
4658 
4659    Level: intermediate
4660 
4661    Note:
4662    Currently only correct in parallel for square matrices.
4663 
4664    Concepts: matrices^accessing diagonals
4665 
4666 .seealso: MatGetRow(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs()
4667 @*/
4668 PetscErrorCode MatGetDiagonal(Mat mat,Vec v)
4669 {
4670   PetscErrorCode ierr;
4671 
4672   PetscFunctionBegin;
4673   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4674   PetscValidType(mat,1);
4675   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4676   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4677   if (!mat->ops->getdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4678   MatCheckPreallocated(mat,1);
4679 
4680   ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr);
4681   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4682   PetscFunctionReturn(0);
4683 }
4684 
4685 /*@C
4686    MatGetRowMin - Gets the minimum value (of the real part) of each
4687         row of the matrix
4688 
4689    Logically Collective on Mat and Vec
4690 
4691    Input Parameters:
4692 .  mat - the matrix
4693 
4694    Output Parameter:
4695 +  v - the vector for storing the maximums
4696 -  idx - the indices of the column found for each row (optional)
4697 
4698    Level: intermediate
4699 
4700    Notes:
4701     The result of this call are the same as if one converted the matrix to dense format
4702       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4703 
4704     This code is only implemented for a couple of matrix formats.
4705 
4706    Concepts: matrices^getting row maximums
4707 
4708 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(),
4709           MatGetRowMax()
4710 @*/
4711 PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4712 {
4713   PetscErrorCode ierr;
4714 
4715   PetscFunctionBegin;
4716   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4717   PetscValidType(mat,1);
4718   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4719   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4720   if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4721   MatCheckPreallocated(mat,1);
4722 
4723   ierr = (*mat->ops->getrowmin)(mat,v,idx);CHKERRQ(ierr);
4724   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4725   PetscFunctionReturn(0);
4726 }
4727 
4728 /*@C
4729    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4730         row of the matrix
4731 
4732    Logically Collective on Mat and Vec
4733 
4734    Input Parameters:
4735 .  mat - the matrix
4736 
4737    Output Parameter:
4738 +  v - the vector for storing the minimums
4739 -  idx - the indices of the column found for each row (or NULL if not needed)
4740 
4741    Level: intermediate
4742 
4743    Notes:
4744     if a row is completely empty or has only 0.0 values then the idx[] value for that
4745     row is 0 (the first column).
4746 
4747     This code is only implemented for a couple of matrix formats.
4748 
4749    Concepts: matrices^getting row maximums
4750 
4751 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4752 @*/
4753 PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4754 {
4755   PetscErrorCode ierr;
4756 
4757   PetscFunctionBegin;
4758   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4759   PetscValidType(mat,1);
4760   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4761   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4762   if (!mat->ops->getrowminabs) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4763   MatCheckPreallocated(mat,1);
4764   if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);}
4765 
4766   ierr = (*mat->ops->getrowminabs)(mat,v,idx);CHKERRQ(ierr);
4767   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4768   PetscFunctionReturn(0);
4769 }
4770 
4771 /*@C
4772    MatGetRowMax - Gets the maximum value (of the real part) of each
4773         row of the matrix
4774 
4775    Logically Collective on Mat and Vec
4776 
4777    Input Parameters:
4778 .  mat - the matrix
4779 
4780    Output Parameter:
4781 +  v - the vector for storing the maximums
4782 -  idx - the indices of the column found for each row (optional)
4783 
4784    Level: intermediate
4785 
4786    Notes:
4787     The result of this call are the same as if one converted the matrix to dense format
4788       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4789 
4790     This code is only implemented for a couple of matrix formats.
4791 
4792    Concepts: matrices^getting row maximums
4793 
4794 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4795 @*/
4796 PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4797 {
4798   PetscErrorCode ierr;
4799 
4800   PetscFunctionBegin;
4801   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4802   PetscValidType(mat,1);
4803   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4804   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4805   if (!mat->ops->getrowmax) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4806   MatCheckPreallocated(mat,1);
4807 
4808   ierr = (*mat->ops->getrowmax)(mat,v,idx);CHKERRQ(ierr);
4809   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4810   PetscFunctionReturn(0);
4811 }
4812 
4813 /*@C
4814    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4815         row of the matrix
4816 
4817    Logically Collective on Mat and Vec
4818 
4819    Input Parameters:
4820 .  mat - the matrix
4821 
4822    Output Parameter:
4823 +  v - the vector for storing the maximums
4824 -  idx - the indices of the column found for each row (or NULL if not needed)
4825 
4826    Level: intermediate
4827 
4828    Notes:
4829     if a row is completely empty or has only 0.0 values then the idx[] value for that
4830     row is 0 (the first column).
4831 
4832     This code is only implemented for a couple of matrix formats.
4833 
4834    Concepts: matrices^getting row maximums
4835 
4836 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
4837 @*/
4838 PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4839 {
4840   PetscErrorCode ierr;
4841 
4842   PetscFunctionBegin;
4843   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4844   PetscValidType(mat,1);
4845   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4846   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4847   if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4848   MatCheckPreallocated(mat,1);
4849   if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);}
4850 
4851   ierr = (*mat->ops->getrowmaxabs)(mat,v,idx);CHKERRQ(ierr);
4852   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4853   PetscFunctionReturn(0);
4854 }
4855 
4856 /*@
4857    MatGetRowSum - Gets the sum of each row of the matrix
4858 
4859    Logically or Neighborhood Collective on Mat and Vec
4860 
4861    Input Parameters:
4862 .  mat - the matrix
4863 
4864    Output Parameter:
4865 .  v - the vector for storing the sum of rows
4866 
4867    Level: intermediate
4868 
4869    Notes:
4870     This code is slow since it is not currently specialized for different formats
4871 
4872    Concepts: matrices^getting row sums
4873 
4874 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
4875 @*/
4876 PetscErrorCode MatGetRowSum(Mat mat, Vec v)
4877 {
4878   Vec            ones;
4879   PetscErrorCode ierr;
4880 
4881   PetscFunctionBegin;
4882   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4883   PetscValidType(mat,1);
4884   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4885   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4886   MatCheckPreallocated(mat,1);
4887   ierr = MatCreateVecs(mat,&ones,NULL);CHKERRQ(ierr);
4888   ierr = VecSet(ones,1.);CHKERRQ(ierr);
4889   ierr = MatMult(mat,ones,v);CHKERRQ(ierr);
4890   ierr = VecDestroy(&ones);CHKERRQ(ierr);
4891   PetscFunctionReturn(0);
4892 }
4893 
4894 /*@
4895    MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
4896 
4897    Collective on Mat
4898 
4899    Input Parameter:
4900 +  mat - the matrix to transpose
4901 -  reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX
4902 
4903    Output Parameters:
4904 .  B - the transpose
4905 
4906    Notes:
4907      If you use MAT_INPLACE_MATRIX then you must pass in &mat for B
4908 
4909      MAT_REUSE_MATRIX causes the B matrix from a previous call to this function with MAT_INITIAL_MATRIX to be used
4910 
4911      Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed.
4912 
4913    Level: intermediate
4914 
4915    Concepts: matrices^transposing
4916 
4917 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4918 @*/
4919 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4920 {
4921   PetscErrorCode ierr;
4922 
4923   PetscFunctionBegin;
4924   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4925   PetscValidType(mat,1);
4926   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4927   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4928   if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4929   if (reuse == MAT_INPLACE_MATRIX && mat != *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires last matrix to match first");
4930   if (reuse == MAT_REUSE_MATRIX && mat == *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Perhaps you mean MAT_INPLACE_MATRIX");
4931   MatCheckPreallocated(mat,1);
4932 
4933   ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4934   ierr = (*mat->ops->transpose)(mat,reuse,B);CHKERRQ(ierr);
4935   ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4936   if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);}
4937   PetscFunctionReturn(0);
4938 }
4939 
4940 /*@
4941    MatIsTranspose - Test whether a matrix is another one's transpose,
4942         or its own, in which case it tests symmetry.
4943 
4944    Collective on Mat
4945 
4946    Input Parameter:
4947 +  A - the matrix to test
4948 -  B - the matrix to test against, this can equal the first parameter
4949 
4950    Output Parameters:
4951 .  flg - the result
4952 
4953    Notes:
4954    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4955    has a running time of the order of the number of nonzeros; the parallel
4956    test involves parallel copies of the block-offdiagonal parts of the matrix.
4957 
4958    Level: intermediate
4959 
4960    Concepts: matrices^transposing, matrix^symmetry
4961 
4962 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4963 @*/
4964 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4965 {
4966   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4967 
4968   PetscFunctionBegin;
4969   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4970   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4971   PetscValidPointer(flg,3);
4972   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);CHKERRQ(ierr);
4973   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);CHKERRQ(ierr);
4974   *flg = PETSC_FALSE;
4975   if (f && g) {
4976     if (f == g) {
4977       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
4978     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4979   } else {
4980     MatType mattype;
4981     if (!f) {
4982       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
4983     } else {
4984       ierr = MatGetType(B,&mattype);CHKERRQ(ierr);
4985     }
4986     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
4987   }
4988   PetscFunctionReturn(0);
4989 }
4990 
4991 /*@
4992    MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate.
4993 
4994    Collective on Mat
4995 
4996    Input Parameter:
4997 +  mat - the matrix to transpose and complex conjugate
4998 -  reuse - MAT_INITIAL_MATRIX to create a new matrix, MAT_INPLACE_MATRIX to reuse the first argument to store the transpose
4999 
5000    Output Parameters:
5001 .  B - the Hermitian
5002 
5003    Level: intermediate
5004 
5005    Concepts: matrices^transposing, complex conjugatex
5006 
5007 .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
5008 @*/
5009 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
5010 {
5011   PetscErrorCode ierr;
5012 
5013   PetscFunctionBegin;
5014   ierr = MatTranspose(mat,reuse,B);CHKERRQ(ierr);
5015 #if defined(PETSC_USE_COMPLEX)
5016   ierr = MatConjugate(*B);CHKERRQ(ierr);
5017 #endif
5018   PetscFunctionReturn(0);
5019 }
5020 
5021 /*@
5022    MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,
5023 
5024    Collective on Mat
5025 
5026    Input Parameter:
5027 +  A - the matrix to test
5028 -  B - the matrix to test against, this can equal the first parameter
5029 
5030    Output Parameters:
5031 .  flg - the result
5032 
5033    Notes:
5034    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
5035    has a running time of the order of the number of nonzeros; the parallel
5036    test involves parallel copies of the block-offdiagonal parts of the matrix.
5037 
5038    Level: intermediate
5039 
5040    Concepts: matrices^transposing, matrix^symmetry
5041 
5042 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
5043 @*/
5044 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
5045 {
5046   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
5047 
5048   PetscFunctionBegin;
5049   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
5050   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
5051   PetscValidPointer(flg,3);
5052   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);CHKERRQ(ierr);
5053   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);CHKERRQ(ierr);
5054   if (f && g) {
5055     if (f==g) {
5056       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
5057     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
5058   }
5059   PetscFunctionReturn(0);
5060 }
5061 
5062 /*@
5063    MatPermute - Creates a new matrix with rows and columns permuted from the
5064    original.
5065 
5066    Collective on Mat
5067 
5068    Input Parameters:
5069 +  mat - the matrix to permute
5070 .  row - row permutation, each processor supplies only the permutation for its rows
5071 -  col - column permutation, each processor supplies only the permutation for its columns
5072 
5073    Output Parameters:
5074 .  B - the permuted matrix
5075 
5076    Level: advanced
5077 
5078    Note:
5079    The index sets map from row/col of permuted matrix to row/col of original matrix.
5080    The index sets should be on the same communicator as Mat and have the same local sizes.
5081 
5082    Concepts: matrices^permuting
5083 
5084 .seealso: MatGetOrdering(), ISAllGather()
5085 
5086 @*/
5087 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
5088 {
5089   PetscErrorCode ierr;
5090 
5091   PetscFunctionBegin;
5092   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5093   PetscValidType(mat,1);
5094   PetscValidHeaderSpecific(row,IS_CLASSID,2);
5095   PetscValidHeaderSpecific(col,IS_CLASSID,3);
5096   PetscValidPointer(B,4);
5097   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5098   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5099   if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
5100   MatCheckPreallocated(mat,1);
5101 
5102   ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr);
5103   ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);
5104   PetscFunctionReturn(0);
5105 }
5106 
5107 /*@
5108    MatEqual - Compares two matrices.
5109 
5110    Collective on Mat
5111 
5112    Input Parameters:
5113 +  A - the first matrix
5114 -  B - the second matrix
5115 
5116    Output Parameter:
5117 .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
5118 
5119    Level: intermediate
5120 
5121    Concepts: matrices^equality between
5122 @*/
5123 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool  *flg)
5124 {
5125   PetscErrorCode ierr;
5126 
5127   PetscFunctionBegin;
5128   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
5129   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
5130   PetscValidType(A,1);
5131   PetscValidType(B,2);
5132   PetscValidIntPointer(flg,3);
5133   PetscCheckSameComm(A,1,B,2);
5134   MatCheckPreallocated(B,2);
5135   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5136   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5137   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);
5138   if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
5139   if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
5140   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);
5141   MatCheckPreallocated(A,1);
5142 
5143   ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr);
5144   PetscFunctionReturn(0);
5145 }
5146 
5147 /*@
5148    MatDiagonalScale - Scales a matrix on the left and right by diagonal
5149    matrices that are stored as vectors.  Either of the two scaling
5150    matrices can be NULL.
5151 
5152    Collective on Mat
5153 
5154    Input Parameters:
5155 +  mat - the matrix to be scaled
5156 .  l - the left scaling vector (or NULL)
5157 -  r - the right scaling vector (or NULL)
5158 
5159    Notes:
5160    MatDiagonalScale() computes A = LAR, where
5161    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
5162    The L scales the rows of the matrix, the R scales the columns of the matrix.
5163 
5164    Level: intermediate
5165 
5166    Concepts: matrices^diagonal scaling
5167    Concepts: diagonal scaling of matrices
5168 
5169 .seealso: MatScale(), MatShift(), MatDiagonalSet()
5170 @*/
5171 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
5172 {
5173   PetscErrorCode ierr;
5174 
5175   PetscFunctionBegin;
5176   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5177   PetscValidType(mat,1);
5178   if (!mat->ops->diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5179   if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);}
5180   if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);}
5181   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5182   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5183   MatCheckPreallocated(mat,1);
5184 
5185   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5186   ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr);
5187   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5188   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5189 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5190   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5191     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5192   }
5193 #endif
5194   PetscFunctionReturn(0);
5195 }
5196 
5197 /*@
5198     MatScale - Scales all elements of a matrix by a given number.
5199 
5200     Logically Collective on Mat
5201 
5202     Input Parameters:
5203 +   mat - the matrix to be scaled
5204 -   a  - the scaling value
5205 
5206     Output Parameter:
5207 .   mat - the scaled matrix
5208 
5209     Level: intermediate
5210 
5211     Concepts: matrices^scaling all entries
5212 
5213 .seealso: MatDiagonalScale()
5214 @*/
5215 PetscErrorCode MatScale(Mat mat,PetscScalar a)
5216 {
5217   PetscErrorCode ierr;
5218 
5219   PetscFunctionBegin;
5220   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5221   PetscValidType(mat,1);
5222   if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5223   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5224   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5225   PetscValidLogicalCollectiveScalar(mat,a,2);
5226   MatCheckPreallocated(mat,1);
5227 
5228   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5229   if (a != (PetscScalar)1.0) {
5230     ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr);
5231     ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5232 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5233     if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5234       mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5235     }
5236 #endif
5237   }
5238   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5239   PetscFunctionReturn(0);
5240 }
5241 
5242 /*@
5243    MatNorm - Calculates various norms of a matrix.
5244 
5245    Collective on Mat
5246 
5247    Input Parameters:
5248 +  mat - the matrix
5249 -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
5250 
5251    Output Parameters:
5252 .  nrm - the resulting norm
5253 
5254    Level: intermediate
5255 
5256    Concepts: matrices^norm
5257    Concepts: norm^of matrix
5258 @*/
5259 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
5260 {
5261   PetscErrorCode ierr;
5262 
5263   PetscFunctionBegin;
5264   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5265   PetscValidType(mat,1);
5266   PetscValidScalarPointer(nrm,3);
5267 
5268   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5269   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5270   if (!mat->ops->norm) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5271   MatCheckPreallocated(mat,1);
5272 
5273   ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr);
5274   PetscFunctionReturn(0);
5275 }
5276 
5277 /*
5278      This variable is used to prevent counting of MatAssemblyBegin() that
5279    are called from within a MatAssemblyEnd().
5280 */
5281 static PetscInt MatAssemblyEnd_InUse = 0;
5282 /*@
5283    MatAssemblyBegin - Begins assembling the matrix.  This routine should
5284    be called after completing all calls to MatSetValues().
5285 
5286    Collective on Mat
5287 
5288    Input Parameters:
5289 +  mat - the matrix
5290 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5291 
5292    Notes:
5293    MatSetValues() generally caches the values.  The matrix is ready to
5294    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5295    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5296    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5297    using the matrix.
5298 
5299    ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the
5300    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
5301    a global collective operation requring all processes that share the matrix.
5302 
5303    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5304    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5305    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5306 
5307    Level: beginner
5308 
5309    Concepts: matrices^assembling
5310 
5311 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
5312 @*/
5313 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
5314 {
5315   PetscErrorCode ierr;
5316 
5317   PetscFunctionBegin;
5318   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5319   PetscValidType(mat,1);
5320   MatCheckPreallocated(mat,1);
5321   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
5322   if (mat->assembled) {
5323     mat->was_assembled = PETSC_TRUE;
5324     mat->assembled     = PETSC_FALSE;
5325   }
5326   if (!MatAssemblyEnd_InUse) {
5327     ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5328     if (mat->ops->assemblybegin) {ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
5329     ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5330   } else if (mat->ops->assemblybegin) {
5331     ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);
5332   }
5333   PetscFunctionReturn(0);
5334 }
5335 
5336 /*@
5337    MatAssembled - Indicates if a matrix has been assembled and is ready for
5338      use; for example, in matrix-vector product.
5339 
5340    Not Collective
5341 
5342    Input Parameter:
5343 .  mat - the matrix
5344 
5345    Output Parameter:
5346 .  assembled - PETSC_TRUE or PETSC_FALSE
5347 
5348    Level: advanced
5349 
5350    Concepts: matrices^assembled?
5351 
5352 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
5353 @*/
5354 PetscErrorCode MatAssembled(Mat mat,PetscBool  *assembled)
5355 {
5356   PetscFunctionBegin;
5357   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5358   PetscValidPointer(assembled,2);
5359   *assembled = mat->assembled;
5360   PetscFunctionReturn(0);
5361 }
5362 
5363 /*@
5364    MatAssemblyEnd - Completes assembling the matrix.  This routine should
5365    be called after MatAssemblyBegin().
5366 
5367    Collective on Mat
5368 
5369    Input Parameters:
5370 +  mat - the matrix
5371 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5372 
5373    Options Database Keys:
5374 +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
5375 .  -mat_view ::ascii_info_detail - Prints more detailed info
5376 .  -mat_view - Prints matrix in ASCII format
5377 .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
5378 .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
5379 .  -display <name> - Sets display name (default is host)
5380 .  -draw_pause <sec> - Sets number of seconds to pause after display
5381 .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab )
5382 .  -viewer_socket_machine <machine> - Machine to use for socket
5383 .  -viewer_socket_port <port> - Port number to use for socket
5384 -  -mat_view binary:filename[:append] - Save matrix to file in binary format
5385 
5386    Notes:
5387    MatSetValues() generally caches the values.  The matrix is ready to
5388    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5389    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5390    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5391    using the matrix.
5392 
5393    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5394    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5395    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5396 
5397    Level: beginner
5398 
5399 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
5400 @*/
5401 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
5402 {
5403   PetscErrorCode  ierr;
5404   static PetscInt inassm = 0;
5405   PetscBool       flg    = PETSC_FALSE;
5406 
5407   PetscFunctionBegin;
5408   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5409   PetscValidType(mat,1);
5410 
5411   inassm++;
5412   MatAssemblyEnd_InUse++;
5413   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
5414     ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5415     if (mat->ops->assemblyend) {
5416       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5417     }
5418     ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5419   } else if (mat->ops->assemblyend) {
5420     ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5421   }
5422 
5423   /* Flush assembly is not a true assembly */
5424   if (type != MAT_FLUSH_ASSEMBLY) {
5425     mat->assembled = PETSC_TRUE; mat->num_ass++;
5426   }
5427   mat->insertmode = NOT_SET_VALUES;
5428   MatAssemblyEnd_InUse--;
5429   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5430   if (!mat->symmetric_eternal) {
5431     mat->symmetric_set              = PETSC_FALSE;
5432     mat->hermitian_set              = PETSC_FALSE;
5433     mat->structurally_symmetric_set = PETSC_FALSE;
5434   }
5435 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5436   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5437     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5438   }
5439 #endif
5440   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
5441     ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5442 
5443     if (mat->checksymmetryonassembly) {
5444       ierr = MatIsSymmetric(mat,mat->checksymmetrytol,&flg);CHKERRQ(ierr);
5445       if (flg) {
5446         ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5447       } else {
5448         ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5449       }
5450     }
5451     if (mat->nullsp && mat->checknullspaceonassembly) {
5452       ierr = MatNullSpaceTest(mat->nullsp,mat,NULL);CHKERRQ(ierr);
5453     }
5454   }
5455   inassm--;
5456   PetscFunctionReturn(0);
5457 }
5458 
5459 /*@
5460    MatSetOption - Sets a parameter option for a matrix. Some options
5461    may be specific to certain storage formats.  Some options
5462    determine how values will be inserted (or added). Sorted,
5463    row-oriented input will generally assemble the fastest. The default
5464    is row-oriented.
5465 
5466    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5467 
5468    Input Parameters:
5469 +  mat - the matrix
5470 .  option - the option, one of those listed below (and possibly others),
5471 -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5472 
5473   Options Describing Matrix Structure:
5474 +    MAT_SPD - symmetric positive definite
5475 .    MAT_SYMMETRIC - symmetric in terms of both structure and value
5476 .    MAT_HERMITIAN - transpose is the complex conjugation
5477 .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5478 -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5479                             you set to be kept with all future use of the matrix
5480                             including after MatAssemblyBegin/End() which could
5481                             potentially change the symmetry structure, i.e. you
5482                             KNOW the matrix will ALWAYS have the property you set.
5483 
5484 
5485    Options For Use with MatSetValues():
5486    Insert a logically dense subblock, which can be
5487 .    MAT_ROW_ORIENTED - row-oriented (default)
5488 
5489    Note these options reflect the data you pass in with MatSetValues(); it has
5490    nothing to do with how the data is stored internally in the matrix
5491    data structure.
5492 
5493    When (re)assembling a matrix, we can restrict the input for
5494    efficiency/debugging purposes.  These options include:
5495 +    MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow)
5496 .    MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
5497 .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
5498 .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
5499 .    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
5500 .    MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
5501         any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
5502         performance for very large process counts.
5503 -    MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset
5504         of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly
5505         functions, instead sending only neighbor messages.
5506 
5507    Notes:
5508    Except for MAT_UNUSED_NONZERO_LOCATION_ERR and  MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg!
5509 
5510    Some options are relevant only for particular matrix types and
5511    are thus ignored by others.  Other options are not supported by
5512    certain matrix types and will generate an error message if set.
5513 
5514    If using a Fortran 77 module to compute a matrix, one may need to
5515    use the column-oriented option (or convert to the row-oriented
5516    format).
5517 
5518    MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
5519    that would generate a new entry in the nonzero structure is instead
5520    ignored.  Thus, if memory has not alredy been allocated for this particular
5521    data, then the insertion is ignored. For dense matrices, in which
5522    the entire array is allocated, no entries are ever ignored.
5523    Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5524 
5525    MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5526    that would generate a new entry in the nonzero structure instead produces
5527    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
5528 
5529    MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5530    that would generate a new entry that has not been preallocated will
5531    instead produce an error. (Currently supported for AIJ and BAIJ formats
5532    only.) This is a useful flag when debugging matrix memory preallocation.
5533    If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5534 
5535    MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for
5536    other processors should be dropped, rather than stashed.
5537    This is useful if you know that the "owning" processor is also
5538    always generating the correct matrix entries, so that PETSc need
5539    not transfer duplicate entries generated on another processor.
5540 
5541    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5542    searches during matrix assembly. When this flag is set, the hash table
5543    is created during the first Matrix Assembly. This hash table is
5544    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5545    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5546    should be used with MAT_USE_HASH_TABLE flag. This option is currently
5547    supported by MATMPIBAIJ format only.
5548 
5549    MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries
5550    are kept in the nonzero structure
5551 
5552    MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
5553    a zero location in the matrix
5554 
5555    MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types
5556 
5557    MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the
5558         zero row routines and thus improves performance for very large process counts.
5559 
5560    MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular
5561         part of the matrix (since they should match the upper triangular part).
5562 
5563    Notes:
5564     Can only be called after MatSetSizes() and MatSetType() have been set.
5565 
5566    Level: intermediate
5567 
5568    Concepts: matrices^setting options
5569 
5570 .seealso:  MatOption, Mat
5571 
5572 @*/
5573 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg)
5574 {
5575   PetscErrorCode ierr;
5576 
5577   PetscFunctionBegin;
5578   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5579   PetscValidType(mat,1);
5580   if (op > 0) {
5581     PetscValidLogicalCollectiveEnum(mat,op,2);
5582     PetscValidLogicalCollectiveBool(mat,flg,3);
5583   }
5584 
5585   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);
5586   if (!((PetscObject)mat)->type_name) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_TYPENOTSET,"Cannot set options until type and size have been set, see MatSetType() and MatSetSizes()");
5587 
5588   switch (op) {
5589   case MAT_NO_OFF_PROC_ENTRIES:
5590     mat->nooffprocentries = flg;
5591     PetscFunctionReturn(0);
5592     break;
5593   case MAT_SUBSET_OFF_PROC_ENTRIES:
5594     mat->subsetoffprocentries = flg;
5595     PetscFunctionReturn(0);
5596   case MAT_NO_OFF_PROC_ZERO_ROWS:
5597     mat->nooffproczerorows = flg;
5598     PetscFunctionReturn(0);
5599     break;
5600   case MAT_SPD:
5601     mat->spd_set = PETSC_TRUE;
5602     mat->spd     = flg;
5603     if (flg) {
5604       mat->symmetric                  = PETSC_TRUE;
5605       mat->structurally_symmetric     = PETSC_TRUE;
5606       mat->symmetric_set              = PETSC_TRUE;
5607       mat->structurally_symmetric_set = PETSC_TRUE;
5608     }
5609     break;
5610   case MAT_SYMMETRIC:
5611     mat->symmetric = flg;
5612     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5613     mat->symmetric_set              = PETSC_TRUE;
5614     mat->structurally_symmetric_set = flg;
5615 #if !defined(PETSC_USE_COMPLEX)
5616     mat->hermitian     = flg;
5617     mat->hermitian_set = PETSC_TRUE;
5618 #endif
5619     break;
5620   case MAT_HERMITIAN:
5621     mat->hermitian = flg;
5622     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5623     mat->hermitian_set              = PETSC_TRUE;
5624     mat->structurally_symmetric_set = flg;
5625 #if !defined(PETSC_USE_COMPLEX)
5626     mat->symmetric     = flg;
5627     mat->symmetric_set = PETSC_TRUE;
5628 #endif
5629     break;
5630   case MAT_STRUCTURALLY_SYMMETRIC:
5631     mat->structurally_symmetric     = flg;
5632     mat->structurally_symmetric_set = PETSC_TRUE;
5633     break;
5634   case MAT_SYMMETRY_ETERNAL:
5635     mat->symmetric_eternal = flg;
5636     break;
5637   case MAT_STRUCTURE_ONLY:
5638     mat->structure_only = flg;
5639     break;
5640   default:
5641     break;
5642   }
5643   if (mat->ops->setoption) {
5644     ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr);
5645   }
5646   PetscFunctionReturn(0);
5647 }
5648 
5649 /*@
5650    MatGetOption - Gets a parameter option that has been set for a matrix.
5651 
5652    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5653 
5654    Input Parameters:
5655 +  mat - the matrix
5656 -  option - the option, this only responds to certain options, check the code for which ones
5657 
5658    Output Parameter:
5659 .  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5660 
5661     Notes:
5662     Can only be called after MatSetSizes() and MatSetType() have been set.
5663 
5664    Level: intermediate
5665 
5666    Concepts: matrices^setting options
5667 
5668 .seealso:  MatOption, MatSetOption()
5669 
5670 @*/
5671 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg)
5672 {
5673   PetscFunctionBegin;
5674   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5675   PetscValidType(mat,1);
5676 
5677   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);
5678   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()");
5679 
5680   switch (op) {
5681   case MAT_NO_OFF_PROC_ENTRIES:
5682     *flg = mat->nooffprocentries;
5683     break;
5684   case MAT_NO_OFF_PROC_ZERO_ROWS:
5685     *flg = mat->nooffproczerorows;
5686     break;
5687   case MAT_SYMMETRIC:
5688     *flg = mat->symmetric;
5689     break;
5690   case MAT_HERMITIAN:
5691     *flg = mat->hermitian;
5692     break;
5693   case MAT_STRUCTURALLY_SYMMETRIC:
5694     *flg = mat->structurally_symmetric;
5695     break;
5696   case MAT_SYMMETRY_ETERNAL:
5697     *flg = mat->symmetric_eternal;
5698     break;
5699   case MAT_SPD:
5700     *flg = mat->spd;
5701     break;
5702   default:
5703     break;
5704   }
5705   PetscFunctionReturn(0);
5706 }
5707 
5708 /*@
5709    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5710    this routine retains the old nonzero structure.
5711 
5712    Logically Collective on Mat
5713 
5714    Input Parameters:
5715 .  mat - the matrix
5716 
5717    Level: intermediate
5718 
5719    Notes:
5720     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.
5721    See the Performance chapter of the users manual for information on preallocating matrices.
5722 
5723    Concepts: matrices^zeroing
5724 
5725 .seealso: MatZeroRows()
5726 @*/
5727 PetscErrorCode MatZeroEntries(Mat mat)
5728 {
5729   PetscErrorCode ierr;
5730 
5731   PetscFunctionBegin;
5732   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5733   PetscValidType(mat,1);
5734   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5735   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");
5736   if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5737   MatCheckPreallocated(mat,1);
5738 
5739   ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5740   ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
5741   ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5742   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5743 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5744   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5745     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5746   }
5747 #endif
5748   PetscFunctionReturn(0);
5749 }
5750 
5751 /*@
5752    MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal)
5753    of a set of rows and columns of a matrix.
5754 
5755    Collective on Mat
5756 
5757    Input Parameters:
5758 +  mat - the matrix
5759 .  numRows - the number of rows to remove
5760 .  rows - the global row indices
5761 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5762 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5763 -  b - optional vector of right hand side, that will be adjusted by provided solution
5764 
5765    Notes:
5766    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5767 
5768    The user can set a value in the diagonal entry (or for the AIJ and
5769    row formats can optionally remove the main diagonal entry from the
5770    nonzero structure as well, by passing 0.0 as the final argument).
5771 
5772    For the parallel case, all processes that share the matrix (i.e.,
5773    those in the communicator used for matrix creation) MUST call this
5774    routine, regardless of whether any rows being zeroed are owned by
5775    them.
5776 
5777    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5778    list only rows local to itself).
5779 
5780    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5781 
5782    Level: intermediate
5783 
5784    Concepts: matrices^zeroing rows
5785 
5786 .seealso: MatZeroRowsIS(), MatZeroRows(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5787           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5788 @*/
5789 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5790 {
5791   PetscErrorCode ierr;
5792 
5793   PetscFunctionBegin;
5794   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5795   PetscValidType(mat,1);
5796   if (numRows) PetscValidIntPointer(rows,3);
5797   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5798   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5799   if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5800   MatCheckPreallocated(mat,1);
5801 
5802   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5803   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5804   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5805 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5806   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5807     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5808   }
5809 #endif
5810   PetscFunctionReturn(0);
5811 }
5812 
5813 /*@
5814    MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
5815    of a set of rows and columns of a matrix.
5816 
5817    Collective on Mat
5818 
5819    Input Parameters:
5820 +  mat - the matrix
5821 .  is - the rows to zero
5822 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5823 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5824 -  b - optional vector of right hand side, that will be adjusted by provided solution
5825 
5826    Notes:
5827    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5828 
5829    The user can set a value in the diagonal entry (or for the AIJ and
5830    row formats can optionally remove the main diagonal entry from the
5831    nonzero structure as well, by passing 0.0 as the final argument).
5832 
5833    For the parallel case, all processes that share the matrix (i.e.,
5834    those in the communicator used for matrix creation) MUST call this
5835    routine, regardless of whether any rows being zeroed are owned by
5836    them.
5837 
5838    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5839    list only rows local to itself).
5840 
5841    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5842 
5843    Level: intermediate
5844 
5845    Concepts: matrices^zeroing rows
5846 
5847 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5848           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRows(), MatZeroRowsColumnsStencil()
5849 @*/
5850 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5851 {
5852   PetscErrorCode ierr;
5853   PetscInt       numRows;
5854   const PetscInt *rows;
5855 
5856   PetscFunctionBegin;
5857   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5858   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5859   PetscValidType(mat,1);
5860   PetscValidType(is,2);
5861   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5862   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5863   ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5864   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5865   PetscFunctionReturn(0);
5866 }
5867 
5868 /*@
5869    MatZeroRows - Zeros all entries (except possibly the main diagonal)
5870    of a set of rows of a matrix.
5871 
5872    Collective on Mat
5873 
5874    Input Parameters:
5875 +  mat - the matrix
5876 .  numRows - the number of rows to remove
5877 .  rows - the global row indices
5878 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5879 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5880 -  b - optional vector of right hand side, that will be adjusted by provided solution
5881 
5882    Notes:
5883    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5884    but does not release memory.  For the dense and block diagonal
5885    formats this does not alter the nonzero structure.
5886 
5887    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5888    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5889    merely zeroed.
5890 
5891    The user can set a value in the diagonal entry (or for the AIJ and
5892    row formats can optionally remove the main diagonal entry from the
5893    nonzero structure as well, by passing 0.0 as the final argument).
5894 
5895    For the parallel case, all processes that share the matrix (i.e.,
5896    those in the communicator used for matrix creation) MUST call this
5897    routine, regardless of whether any rows being zeroed are owned by
5898    them.
5899 
5900    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5901    list only rows local to itself).
5902 
5903    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5904    owns that are to be zeroed. This saves a global synchronization in the implementation.
5905 
5906    Level: intermediate
5907 
5908    Concepts: matrices^zeroing rows
5909 
5910 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5911           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5912 @*/
5913 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5914 {
5915   PetscErrorCode ierr;
5916 
5917   PetscFunctionBegin;
5918   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5919   PetscValidType(mat,1);
5920   if (numRows) PetscValidIntPointer(rows,3);
5921   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5922   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5923   if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5924   MatCheckPreallocated(mat,1);
5925 
5926   ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5927   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5928   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5929 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5930   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5931     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5932   }
5933 #endif
5934   PetscFunctionReturn(0);
5935 }
5936 
5937 /*@
5938    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5939    of a set of rows of a matrix.
5940 
5941    Collective on Mat
5942 
5943    Input Parameters:
5944 +  mat - the matrix
5945 .  is - index set of rows to remove
5946 .  diag - value put in all diagonals of eliminated rows
5947 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5948 -  b - optional vector of right hand side, that will be adjusted by provided solution
5949 
5950    Notes:
5951    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5952    but does not release memory.  For the dense and block diagonal
5953    formats this does not alter the nonzero structure.
5954 
5955    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5956    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5957    merely zeroed.
5958 
5959    The user can set a value in the diagonal entry (or for the AIJ and
5960    row formats can optionally remove the main diagonal entry from the
5961    nonzero structure as well, by passing 0.0 as the final argument).
5962 
5963    For the parallel case, all processes that share the matrix (i.e.,
5964    those in the communicator used for matrix creation) MUST call this
5965    routine, regardless of whether any rows being zeroed are owned by
5966    them.
5967 
5968    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5969    list only rows local to itself).
5970 
5971    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5972    owns that are to be zeroed. This saves a global synchronization in the implementation.
5973 
5974    Level: intermediate
5975 
5976    Concepts: matrices^zeroing rows
5977 
5978 .seealso: MatZeroRows(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5979           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5980 @*/
5981 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5982 {
5983   PetscInt       numRows;
5984   const PetscInt *rows;
5985   PetscErrorCode ierr;
5986 
5987   PetscFunctionBegin;
5988   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5989   PetscValidType(mat,1);
5990   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5991   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5992   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5993   ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5994   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5995   PetscFunctionReturn(0);
5996 }
5997 
5998 /*@
5999    MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
6000    of a set of rows of a matrix. These rows must be local to the process.
6001 
6002    Collective on Mat
6003 
6004    Input Parameters:
6005 +  mat - the matrix
6006 .  numRows - the number of rows to remove
6007 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
6008 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
6009 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6010 -  b - optional vector of right hand side, that will be adjusted by provided solution
6011 
6012    Notes:
6013    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
6014    but does not release memory.  For the dense and block diagonal
6015    formats this does not alter the nonzero structure.
6016 
6017    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6018    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6019    merely zeroed.
6020 
6021    The user can set a value in the diagonal entry (or for the AIJ and
6022    row formats can optionally remove the main diagonal entry from the
6023    nonzero structure as well, by passing 0.0 as the final argument).
6024 
6025    For the parallel case, all processes that share the matrix (i.e.,
6026    those in the communicator used for matrix creation) MUST call this
6027    routine, regardless of whether any rows being zeroed are owned by
6028    them.
6029 
6030    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
6031    list only rows local to itself).
6032 
6033    The grid coordinates are across the entire grid, not just the local portion
6034 
6035    In Fortran idxm and idxn should be declared as
6036 $     MatStencil idxm(4,m)
6037    and the values inserted using
6038 $    idxm(MatStencil_i,1) = i
6039 $    idxm(MatStencil_j,1) = j
6040 $    idxm(MatStencil_k,1) = k
6041 $    idxm(MatStencil_c,1) = c
6042    etc
6043 
6044    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
6045    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
6046    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
6047    DM_BOUNDARY_PERIODIC boundary type.
6048 
6049    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
6050    a single value per point) you can skip filling those indices.
6051 
6052    Level: intermediate
6053 
6054    Concepts: matrices^zeroing rows
6055 
6056 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsl(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6057           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6058 @*/
6059 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
6060 {
6061   PetscInt       dim     = mat->stencil.dim;
6062   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
6063   PetscInt       *dims   = mat->stencil.dims+1;
6064   PetscInt       *starts = mat->stencil.starts;
6065   PetscInt       *dxm    = (PetscInt*) rows;
6066   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
6067   PetscErrorCode ierr;
6068 
6069   PetscFunctionBegin;
6070   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6071   PetscValidType(mat,1);
6072   if (numRows) PetscValidIntPointer(rows,3);
6073 
6074   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
6075   for (i = 0; i < numRows; ++i) {
6076     /* Skip unused dimensions (they are ordered k, j, i, c) */
6077     for (j = 0; j < 3-sdim; ++j) dxm++;
6078     /* Local index in X dir */
6079     tmp = *dxm++ - starts[0];
6080     /* Loop over remaining dimensions */
6081     for (j = 0; j < dim-1; ++j) {
6082       /* If nonlocal, set index to be negative */
6083       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6084       /* Update local index */
6085       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6086     }
6087     /* Skip component slot if necessary */
6088     if (mat->stencil.noc) dxm++;
6089     /* Local row number */
6090     if (tmp >= 0) {
6091       jdxm[numNewRows++] = tmp;
6092     }
6093   }
6094   ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
6095   ierr = PetscFree(jdxm);CHKERRQ(ierr);
6096   PetscFunctionReturn(0);
6097 }
6098 
6099 /*@
6100    MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal)
6101    of a set of rows and columns of a matrix.
6102 
6103    Collective on Mat
6104 
6105    Input Parameters:
6106 +  mat - the matrix
6107 .  numRows - the number of rows/columns to remove
6108 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
6109 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
6110 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6111 -  b - optional vector of right hand side, that will be adjusted by provided solution
6112 
6113    Notes:
6114    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
6115    but does not release memory.  For the dense and block diagonal
6116    formats this does not alter the nonzero structure.
6117 
6118    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6119    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6120    merely zeroed.
6121 
6122    The user can set a value in the diagonal entry (or for the AIJ and
6123    row formats can optionally remove the main diagonal entry from the
6124    nonzero structure as well, by passing 0.0 as the final argument).
6125 
6126    For the parallel case, all processes that share the matrix (i.e.,
6127    those in the communicator used for matrix creation) MUST call this
6128    routine, regardless of whether any rows being zeroed are owned by
6129    them.
6130 
6131    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
6132    list only rows local to itself, but the row/column numbers are given in local numbering).
6133 
6134    The grid coordinates are across the entire grid, not just the local portion
6135 
6136    In Fortran idxm and idxn should be declared as
6137 $     MatStencil idxm(4,m)
6138    and the values inserted using
6139 $    idxm(MatStencil_i,1) = i
6140 $    idxm(MatStencil_j,1) = j
6141 $    idxm(MatStencil_k,1) = k
6142 $    idxm(MatStencil_c,1) = c
6143    etc
6144 
6145    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
6146    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
6147    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
6148    DM_BOUNDARY_PERIODIC boundary type.
6149 
6150    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
6151    a single value per point) you can skip filling those indices.
6152 
6153    Level: intermediate
6154 
6155    Concepts: matrices^zeroing rows
6156 
6157 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6158           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRows()
6159 @*/
6160 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
6161 {
6162   PetscInt       dim     = mat->stencil.dim;
6163   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
6164   PetscInt       *dims   = mat->stencil.dims+1;
6165   PetscInt       *starts = mat->stencil.starts;
6166   PetscInt       *dxm    = (PetscInt*) rows;
6167   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
6168   PetscErrorCode ierr;
6169 
6170   PetscFunctionBegin;
6171   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6172   PetscValidType(mat,1);
6173   if (numRows) PetscValidIntPointer(rows,3);
6174 
6175   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
6176   for (i = 0; i < numRows; ++i) {
6177     /* Skip unused dimensions (they are ordered k, j, i, c) */
6178     for (j = 0; j < 3-sdim; ++j) dxm++;
6179     /* Local index in X dir */
6180     tmp = *dxm++ - starts[0];
6181     /* Loop over remaining dimensions */
6182     for (j = 0; j < dim-1; ++j) {
6183       /* If nonlocal, set index to be negative */
6184       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6185       /* Update local index */
6186       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6187     }
6188     /* Skip component slot if necessary */
6189     if (mat->stencil.noc) dxm++;
6190     /* Local row number */
6191     if (tmp >= 0) {
6192       jdxm[numNewRows++] = tmp;
6193     }
6194   }
6195   ierr = MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
6196   ierr = PetscFree(jdxm);CHKERRQ(ierr);
6197   PetscFunctionReturn(0);
6198 }
6199 
6200 /*@C
6201    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
6202    of a set of rows of a matrix; using local numbering of rows.
6203 
6204    Collective on Mat
6205 
6206    Input Parameters:
6207 +  mat - the matrix
6208 .  numRows - the number of rows to remove
6209 .  rows - the global row indices
6210 .  diag - value put in all diagonals of eliminated rows
6211 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6212 -  b - optional vector of right hand side, that will be adjusted by provided solution
6213 
6214    Notes:
6215    Before calling MatZeroRowsLocal(), the user must first set the
6216    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6217 
6218    For the AIJ matrix formats this removes the old nonzero structure,
6219    but does not release memory.  For the dense and block diagonal
6220    formats this does not alter the nonzero structure.
6221 
6222    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6223    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6224    merely zeroed.
6225 
6226    The user can set a value in the diagonal entry (or for the AIJ and
6227    row formats can optionally remove the main diagonal entry from the
6228    nonzero structure as well, by passing 0.0 as the final argument).
6229 
6230    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6231    owns that are to be zeroed. This saves a global synchronization in the implementation.
6232 
6233    Level: intermediate
6234 
6235    Concepts: matrices^zeroing
6236 
6237 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRows(), MatSetOption(),
6238           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6239 @*/
6240 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6241 {
6242   PetscErrorCode ierr;
6243 
6244   PetscFunctionBegin;
6245   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6246   PetscValidType(mat,1);
6247   if (numRows) PetscValidIntPointer(rows,3);
6248   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6249   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6250   MatCheckPreallocated(mat,1);
6251 
6252   if (mat->ops->zerorowslocal) {
6253     ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6254   } else {
6255     IS             is, newis;
6256     const PetscInt *newRows;
6257 
6258     if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6259     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6260     ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr);
6261     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6262     ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6263     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6264     ierr = ISDestroy(&newis);CHKERRQ(ierr);
6265     ierr = ISDestroy(&is);CHKERRQ(ierr);
6266   }
6267   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6268 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
6269   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
6270     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
6271   }
6272 #endif
6273   PetscFunctionReturn(0);
6274 }
6275 
6276 /*@
6277    MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
6278    of a set of rows of a matrix; using local numbering of rows.
6279 
6280    Collective on Mat
6281 
6282    Input Parameters:
6283 +  mat - the matrix
6284 .  is - index set of rows to remove
6285 .  diag - value put in all diagonals of eliminated rows
6286 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6287 -  b - optional vector of right hand side, that will be adjusted by provided solution
6288 
6289    Notes:
6290    Before calling MatZeroRowsLocalIS(), the user must first set the
6291    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6292 
6293    For the AIJ matrix formats this removes the old nonzero structure,
6294    but does not release memory.  For the dense and block diagonal
6295    formats this does not alter the nonzero structure.
6296 
6297    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6298    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6299    merely zeroed.
6300 
6301    The user can set a value in the diagonal entry (or for the AIJ and
6302    row formats can optionally remove the main diagonal entry from the
6303    nonzero structure as well, by passing 0.0 as the final argument).
6304 
6305    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6306    owns that are to be zeroed. This saves a global synchronization in the implementation.
6307 
6308    Level: intermediate
6309 
6310    Concepts: matrices^zeroing
6311 
6312 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6313           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6314 @*/
6315 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6316 {
6317   PetscErrorCode ierr;
6318   PetscInt       numRows;
6319   const PetscInt *rows;
6320 
6321   PetscFunctionBegin;
6322   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6323   PetscValidType(mat,1);
6324   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6325   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6326   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6327   MatCheckPreallocated(mat,1);
6328 
6329   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6330   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6331   ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6332   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6333   PetscFunctionReturn(0);
6334 }
6335 
6336 /*@
6337    MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
6338    of a set of rows and columns of a matrix; using local numbering of rows.
6339 
6340    Collective on Mat
6341 
6342    Input Parameters:
6343 +  mat - the matrix
6344 .  numRows - the number of rows to remove
6345 .  rows - the global row indices
6346 .  diag - value put in all diagonals of eliminated rows
6347 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6348 -  b - optional vector of right hand side, that will be adjusted by provided solution
6349 
6350    Notes:
6351    Before calling MatZeroRowsColumnsLocal(), the user must first set the
6352    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6353 
6354    The user can set a value in the diagonal entry (or for the AIJ and
6355    row formats can optionally remove the main diagonal entry from the
6356    nonzero structure as well, by passing 0.0 as the final argument).
6357 
6358    Level: intermediate
6359 
6360    Concepts: matrices^zeroing
6361 
6362 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6363           MatZeroRows(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6364 @*/
6365 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6366 {
6367   PetscErrorCode ierr;
6368   IS             is, newis;
6369   const PetscInt *newRows;
6370 
6371   PetscFunctionBegin;
6372   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6373   PetscValidType(mat,1);
6374   if (numRows) PetscValidIntPointer(rows,3);
6375   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6376   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6377   MatCheckPreallocated(mat,1);
6378 
6379   if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6380   ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6381   ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr);
6382   ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6383   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6384   ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6385   ierr = ISDestroy(&newis);CHKERRQ(ierr);
6386   ierr = ISDestroy(&is);CHKERRQ(ierr);
6387   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6388 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
6389   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
6390     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
6391   }
6392 #endif
6393   PetscFunctionReturn(0);
6394 }
6395 
6396 /*@
6397    MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
6398    of a set of rows and columns of a matrix; using local numbering of rows.
6399 
6400    Collective on Mat
6401 
6402    Input Parameters:
6403 +  mat - the matrix
6404 .  is - index set of rows to remove
6405 .  diag - value put in all diagonals of eliminated rows
6406 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6407 -  b - optional vector of right hand side, that will be adjusted by provided solution
6408 
6409    Notes:
6410    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
6411    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6412 
6413    The user can set a value in the diagonal entry (or for the AIJ and
6414    row formats can optionally remove the main diagonal entry from the
6415    nonzero structure as well, by passing 0.0 as the final argument).
6416 
6417    Level: intermediate
6418 
6419    Concepts: matrices^zeroing
6420 
6421 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6422           MatZeroRowsColumnsLocal(), MatZeroRows(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6423 @*/
6424 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6425 {
6426   PetscErrorCode ierr;
6427   PetscInt       numRows;
6428   const PetscInt *rows;
6429 
6430   PetscFunctionBegin;
6431   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6432   PetscValidType(mat,1);
6433   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6434   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6435   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6436   MatCheckPreallocated(mat,1);
6437 
6438   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6439   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6440   ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6441   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6442   PetscFunctionReturn(0);
6443 }
6444 
6445 /*@C
6446    MatGetSize - Returns the numbers of rows and columns in a matrix.
6447 
6448    Not Collective
6449 
6450    Input Parameter:
6451 .  mat - the matrix
6452 
6453    Output Parameters:
6454 +  m - the number of global rows
6455 -  n - the number of global columns
6456 
6457    Note: both output parameters can be NULL on input.
6458 
6459    Level: beginner
6460 
6461    Concepts: matrices^size
6462 
6463 .seealso: MatGetLocalSize()
6464 @*/
6465 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
6466 {
6467   PetscFunctionBegin;
6468   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6469   if (m) *m = mat->rmap->N;
6470   if (n) *n = mat->cmap->N;
6471   PetscFunctionReturn(0);
6472 }
6473 
6474 /*@C
6475    MatGetLocalSize - Returns the number of rows and columns in a matrix
6476    stored locally.  This information may be implementation dependent, so
6477    use with care.
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    Concepts: matrices^local size
6493 
6494 .seealso: MatGetSize()
6495 @*/
6496 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
6497 {
6498   PetscFunctionBegin;
6499   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6500   if (m) PetscValidIntPointer(m,2);
6501   if (n) PetscValidIntPointer(n,3);
6502   if (m) *m = mat->rmap->n;
6503   if (n) *n = mat->cmap->n;
6504   PetscFunctionReturn(0);
6505 }
6506 
6507 /*@C
6508    MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6509    this processor. (The columns of the "diagonal block")
6510 
6511    Not Collective, unless matrix has not been allocated, then collective on Mat
6512 
6513    Input Parameters:
6514 .  mat - the matrix
6515 
6516    Output Parameters:
6517 +  m - the global index of the first local column
6518 -  n - one more than the global index of the last local column
6519 
6520    Notes:
6521     both output parameters can be NULL on input.
6522 
6523    Level: developer
6524 
6525    Concepts: matrices^column ownership
6526 
6527 .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
6528 
6529 @*/
6530 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
6531 {
6532   PetscFunctionBegin;
6533   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6534   PetscValidType(mat,1);
6535   if (m) PetscValidIntPointer(m,2);
6536   if (n) PetscValidIntPointer(n,3);
6537   MatCheckPreallocated(mat,1);
6538   if (m) *m = mat->cmap->rstart;
6539   if (n) *n = mat->cmap->rend;
6540   PetscFunctionReturn(0);
6541 }
6542 
6543 /*@C
6544    MatGetOwnershipRange - Returns the range of matrix rows owned by
6545    this processor, assuming that the matrix is laid out with the first
6546    n1 rows on the first processor, the next n2 rows on the second, etc.
6547    For certain parallel layouts this range may not be well defined.
6548 
6549    Not Collective
6550 
6551    Input Parameters:
6552 .  mat - the matrix
6553 
6554    Output Parameters:
6555 +  m - the global index of the first local row
6556 -  n - one more than the global index of the last local row
6557 
6558    Note: Both output parameters can be NULL on input.
6559 $  This function requires that the matrix be preallocated. If you have not preallocated, consider using
6560 $    PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
6561 $  and then MPI_Scan() to calculate prefix sums of the local sizes.
6562 
6563    Level: beginner
6564 
6565    Concepts: matrices^row ownership
6566 
6567 .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()
6568 
6569 @*/
6570 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6571 {
6572   PetscFunctionBegin;
6573   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6574   PetscValidType(mat,1);
6575   if (m) PetscValidIntPointer(m,2);
6576   if (n) PetscValidIntPointer(n,3);
6577   MatCheckPreallocated(mat,1);
6578   if (m) *m = mat->rmap->rstart;
6579   if (n) *n = mat->rmap->rend;
6580   PetscFunctionReturn(0);
6581 }
6582 
6583 /*@C
6584    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6585    each process
6586 
6587    Not Collective, unless matrix has not been allocated, then collective on Mat
6588 
6589    Input Parameters:
6590 .  mat - the matrix
6591 
6592    Output Parameters:
6593 .  ranges - start of each processors portion plus one more than the total length at the end
6594 
6595    Level: beginner
6596 
6597    Concepts: matrices^row ownership
6598 
6599 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
6600 
6601 @*/
6602 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6603 {
6604   PetscErrorCode ierr;
6605 
6606   PetscFunctionBegin;
6607   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6608   PetscValidType(mat,1);
6609   MatCheckPreallocated(mat,1);
6610   ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr);
6611   PetscFunctionReturn(0);
6612 }
6613 
6614 /*@C
6615    MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6616    this processor. (The columns of the "diagonal blocks" for each process)
6617 
6618    Not Collective, unless matrix has not been allocated, then collective on Mat
6619 
6620    Input Parameters:
6621 .  mat - the matrix
6622 
6623    Output Parameters:
6624 .  ranges - start of each processors portion plus one more then the total length at the end
6625 
6626    Level: beginner
6627 
6628    Concepts: matrices^column ownership
6629 
6630 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
6631 
6632 @*/
6633 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6634 {
6635   PetscErrorCode ierr;
6636 
6637   PetscFunctionBegin;
6638   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6639   PetscValidType(mat,1);
6640   MatCheckPreallocated(mat,1);
6641   ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr);
6642   PetscFunctionReturn(0);
6643 }
6644 
6645 /*@C
6646    MatGetOwnershipIS - Get row and column ownership as index sets
6647 
6648    Not Collective
6649 
6650    Input Arguments:
6651 .  A - matrix of type Elemental
6652 
6653    Output Arguments:
6654 +  rows - rows in which this process owns elements
6655 .  cols - columns in which this process owns elements
6656 
6657    Level: intermediate
6658 
6659 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL
6660 @*/
6661 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6662 {
6663   PetscErrorCode ierr,(*f)(Mat,IS*,IS*);
6664 
6665   PetscFunctionBegin;
6666   MatCheckPreallocated(A,1);
6667   ierr = PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);CHKERRQ(ierr);
6668   if (f) {
6669     ierr = (*f)(A,rows,cols);CHKERRQ(ierr);
6670   } else {   /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6671     if (rows) {ierr = ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);CHKERRQ(ierr);}
6672     if (cols) {ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);CHKERRQ(ierr);}
6673   }
6674   PetscFunctionReturn(0);
6675 }
6676 
6677 /*@C
6678    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6679    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6680    to complete the factorization.
6681 
6682    Collective on Mat
6683 
6684    Input Parameters:
6685 +  mat - the matrix
6686 .  row - row permutation
6687 .  column - column permutation
6688 -  info - structure containing
6689 $      levels - number of levels of fill.
6690 $      expected fill - as ratio of original fill.
6691 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6692                 missing diagonal entries)
6693 
6694    Output Parameters:
6695 .  fact - new matrix that has been symbolically factored
6696 
6697    Notes:
6698     See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
6699 
6700    Most users should employ the simplified KSP interface for linear solvers
6701    instead of working directly with matrix algebra routines such as this.
6702    See, e.g., KSPCreate().
6703 
6704    Level: developer
6705 
6706   Concepts: matrices^symbolic LU factorization
6707   Concepts: matrices^factorization
6708   Concepts: LU^symbolic factorization
6709 
6710 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6711           MatGetOrdering(), MatFactorInfo
6712 
6713     Note: this uses the definition of level of fill as in Y. Saad, 2003
6714 
6715     Developer Note: fortran interface is not autogenerated as the f90
6716     interface defintion cannot be generated correctly [due to MatFactorInfo]
6717 
6718    References:
6719      Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003
6720 @*/
6721 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6722 {
6723   PetscErrorCode ierr;
6724 
6725   PetscFunctionBegin;
6726   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6727   PetscValidType(mat,1);
6728   PetscValidHeaderSpecific(row,IS_CLASSID,2);
6729   PetscValidHeaderSpecific(col,IS_CLASSID,3);
6730   PetscValidPointer(info,4);
6731   PetscValidPointer(fact,5);
6732   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6733   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6734   if (!(fact)->ops->ilufactorsymbolic) {
6735     MatSolverType spackage;
6736     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
6737     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6738   }
6739   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6740   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6741   MatCheckPreallocated(mat,2);
6742 
6743   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6744   ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
6745   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6746   PetscFunctionReturn(0);
6747 }
6748 
6749 /*@C
6750    MatICCFactorSymbolic - Performs symbolic incomplete
6751    Cholesky factorization for a symmetric matrix.  Use
6752    MatCholeskyFactorNumeric() to complete the factorization.
6753 
6754    Collective on Mat
6755 
6756    Input Parameters:
6757 +  mat - the matrix
6758 .  perm - row and column permutation
6759 -  info - structure containing
6760 $      levels - number of levels of fill.
6761 $      expected fill - as ratio of original fill.
6762 
6763    Output Parameter:
6764 .  fact - the factored matrix
6765 
6766    Notes:
6767    Most users should employ the KSP interface for linear solvers
6768    instead of working directly with matrix algebra routines such as this.
6769    See, e.g., KSPCreate().
6770 
6771    Level: developer
6772 
6773   Concepts: matrices^symbolic incomplete Cholesky factorization
6774   Concepts: matrices^factorization
6775   Concepts: Cholsky^symbolic factorization
6776 
6777 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
6778 
6779     Note: this uses the definition of level of fill as in Y. Saad, 2003
6780 
6781     Developer Note: fortran interface is not autogenerated as the f90
6782     interface defintion cannot be generated correctly [due to MatFactorInfo]
6783 
6784    References:
6785      Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003
6786 @*/
6787 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6788 {
6789   PetscErrorCode ierr;
6790 
6791   PetscFunctionBegin;
6792   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6793   PetscValidType(mat,1);
6794   PetscValidHeaderSpecific(perm,IS_CLASSID,2);
6795   PetscValidPointer(info,3);
6796   PetscValidPointer(fact,4);
6797   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6798   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6799   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6800   if (!(fact)->ops->iccfactorsymbolic) {
6801     MatSolverType spackage;
6802     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
6803     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6804   }
6805   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6806   MatCheckPreallocated(mat,2);
6807 
6808   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6809   ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
6810   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6811   PetscFunctionReturn(0);
6812 }
6813 
6814 /*@C
6815    MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat
6816    points to an array of valid matrices, they may be reused to store the new
6817    submatrices.
6818 
6819    Collective on Mat
6820 
6821    Input Parameters:
6822 +  mat - the matrix
6823 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6824 .  irow, icol - index sets of rows and columns to extract
6825 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6826 
6827    Output Parameter:
6828 .  submat - the array of submatrices
6829 
6830    Notes:
6831    MatCreateSubMatrices() can extract ONLY sequential submatrices
6832    (from both sequential and parallel matrices). Use MatCreateSubMatrix()
6833    to extract a parallel submatrix.
6834 
6835    Some matrix types place restrictions on the row and column
6836    indices, such as that they be sorted or that they be equal to each other.
6837 
6838    The index sets may not have duplicate entries.
6839 
6840    When extracting submatrices from a parallel matrix, each processor can
6841    form a different submatrix by setting the rows and columns of its
6842    individual index sets according to the local submatrix desired.
6843 
6844    When finished using the submatrices, the user should destroy
6845    them with MatDestroySubMatrices().
6846 
6847    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6848    original matrix has not changed from that last call to MatCreateSubMatrices().
6849 
6850    This routine creates the matrices in submat; you should NOT create them before
6851    calling it. It also allocates the array of matrix pointers submat.
6852 
6853    For BAIJ matrices the index sets must respect the block structure, that is if they
6854    request one row/column in a block, they must request all rows/columns that are in
6855    that block. For example, if the block size is 2 you cannot request just row 0 and
6856    column 0.
6857 
6858    Fortran Note:
6859    The Fortran interface is slightly different from that given below; it
6860    requires one to pass in  as submat a Mat (integer) array of size at least n+1.
6861 
6862    Level: advanced
6863 
6864    Concepts: matrices^accessing submatrices
6865    Concepts: submatrices
6866 
6867 .seealso: MatDestroySubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6868 @*/
6869 PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6870 {
6871   PetscErrorCode ierr;
6872   PetscInt       i;
6873   PetscBool      eq;
6874 
6875   PetscFunctionBegin;
6876   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6877   PetscValidType(mat,1);
6878   if (n) {
6879     PetscValidPointer(irow,3);
6880     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6881     PetscValidPointer(icol,4);
6882     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6883   }
6884   PetscValidPointer(submat,6);
6885   if (n && scall == MAT_REUSE_MATRIX) {
6886     PetscValidPointer(*submat,6);
6887     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6888   }
6889   if (!mat->ops->createsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6890   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6891   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6892   MatCheckPreallocated(mat,1);
6893 
6894   ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6895   ierr = (*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6896   ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6897   for (i=0; i<n; i++) {
6898     (*submat)[i]->factortype = MAT_FACTOR_NONE;  /* in case in place factorization was previously done on submatrix */
6899     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6900       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6901       if (eq) {
6902         if (mat->symmetric) {
6903           ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6904         } else if (mat->hermitian) {
6905           ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6906         } else if (mat->structurally_symmetric) {
6907           ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6908         }
6909       }
6910     }
6911   }
6912   PetscFunctionReturn(0);
6913 }
6914 
6915 /*@C
6916    MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms).
6917 
6918    Collective on Mat
6919 
6920    Input Parameters:
6921 +  mat - the matrix
6922 .  n   - the number of submatrixes to be extracted
6923 .  irow, icol - index sets of rows and columns to extract
6924 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6925 
6926    Output Parameter:
6927 .  submat - the array of submatrices
6928 
6929    Level: advanced
6930 
6931    Concepts: matrices^accessing submatrices
6932    Concepts: submatrices
6933 
6934 .seealso: MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6935 @*/
6936 PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6937 {
6938   PetscErrorCode ierr;
6939   PetscInt       i;
6940   PetscBool      eq;
6941 
6942   PetscFunctionBegin;
6943   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6944   PetscValidType(mat,1);
6945   if (n) {
6946     PetscValidPointer(irow,3);
6947     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6948     PetscValidPointer(icol,4);
6949     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6950   }
6951   PetscValidPointer(submat,6);
6952   if (n && scall == MAT_REUSE_MATRIX) {
6953     PetscValidPointer(*submat,6);
6954     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6955   }
6956   if (!mat->ops->createsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6957   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6958   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6959   MatCheckPreallocated(mat,1);
6960 
6961   ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6962   ierr = (*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6963   ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6964   for (i=0; i<n; i++) {
6965     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6966       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6967       if (eq) {
6968         if (mat->symmetric) {
6969           ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6970         } else if (mat->hermitian) {
6971           ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6972         } else if (mat->structurally_symmetric) {
6973           ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6974         }
6975       }
6976     }
6977   }
6978   PetscFunctionReturn(0);
6979 }
6980 
6981 /*@C
6982    MatDestroyMatrices - Destroys an array of matrices.
6983 
6984    Collective on Mat
6985 
6986    Input Parameters:
6987 +  n - the number of local matrices
6988 -  mat - the matrices (note that this is a pointer to the array of matrices)
6989 
6990    Level: advanced
6991 
6992     Notes:
6993     Frees not only the matrices, but also the array that contains the matrices
6994            In Fortran will not free the array.
6995 
6996 .seealso: MatCreateSubMatrices() MatDestroySubMatrices()
6997 @*/
6998 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
6999 {
7000   PetscErrorCode ierr;
7001   PetscInt       i;
7002 
7003   PetscFunctionBegin;
7004   if (!*mat) PetscFunctionReturn(0);
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   for (i=0; i<n; i++) {
7009     ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr);
7010   }
7011 
7012   /* memory is allocated even if n = 0 */
7013   ierr = PetscFree(*mat);CHKERRQ(ierr);
7014   PetscFunctionReturn(0);
7015 }
7016 
7017 /*@C
7018    MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices().
7019 
7020    Collective on Mat
7021 
7022    Input Parameters:
7023 +  n - the number of local matrices
7024 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
7025                        sequence of MatCreateSubMatrices())
7026 
7027    Level: advanced
7028 
7029     Notes:
7030     Frees not only the matrices, but also the array that contains the matrices
7031            In Fortran will not free the array.
7032 
7033 .seealso: MatCreateSubMatrices()
7034 @*/
7035 PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[])
7036 {
7037   PetscErrorCode ierr;
7038   Mat            mat0;
7039 
7040   PetscFunctionBegin;
7041   if (!*mat) PetscFunctionReturn(0);
7042   /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */
7043   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
7044   PetscValidPointer(mat,2);
7045 
7046   mat0 = (*mat)[0];
7047   if (mat0 && mat0->ops->destroysubmatrices) {
7048     ierr = (mat0->ops->destroysubmatrices)(n,mat);CHKERRQ(ierr);
7049   } else {
7050     ierr = MatDestroyMatrices(n,mat);CHKERRQ(ierr);
7051   }
7052   PetscFunctionReturn(0);
7053 }
7054 
7055 /*@C
7056    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
7057 
7058    Collective on Mat
7059 
7060    Input Parameters:
7061 .  mat - the matrix
7062 
7063    Output Parameter:
7064 .  matstruct - the sequential matrix with the nonzero structure of mat
7065 
7066   Level: intermediate
7067 
7068 .seealso: MatDestroySeqNonzeroStructure(), MatCreateSubMatrices(), MatDestroyMatrices()
7069 @*/
7070 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
7071 {
7072   PetscErrorCode ierr;
7073 
7074   PetscFunctionBegin;
7075   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7076   PetscValidPointer(matstruct,2);
7077 
7078   PetscValidType(mat,1);
7079   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7080   MatCheckPreallocated(mat,1);
7081 
7082   if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
7083   ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
7084   ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr);
7085   ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
7086   PetscFunctionReturn(0);
7087 }
7088 
7089 /*@C
7090    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
7091 
7092    Collective on Mat
7093 
7094    Input Parameters:
7095 .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
7096                        sequence of MatGetSequentialNonzeroStructure())
7097 
7098    Level: advanced
7099 
7100     Notes:
7101     Frees not only the matrices, but also the array that contains the matrices
7102 
7103 .seealso: MatGetSeqNonzeroStructure()
7104 @*/
7105 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
7106 {
7107   PetscErrorCode ierr;
7108 
7109   PetscFunctionBegin;
7110   PetscValidPointer(mat,1);
7111   ierr = MatDestroy(mat);CHKERRQ(ierr);
7112   PetscFunctionReturn(0);
7113 }
7114 
7115 /*@
7116    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
7117    replaces the index sets by larger ones that represent submatrices with
7118    additional overlap.
7119 
7120    Collective on Mat
7121 
7122    Input Parameters:
7123 +  mat - the matrix
7124 .  n   - the number of index sets
7125 .  is  - the array of index sets (these index sets will changed during the call)
7126 -  ov  - the additional overlap requested
7127 
7128    Options Database:
7129 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
7130 
7131    Level: developer
7132 
7133    Concepts: overlap
7134    Concepts: ASM^computing overlap
7135 
7136 .seealso: MatCreateSubMatrices()
7137 @*/
7138 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
7139 {
7140   PetscErrorCode ierr;
7141 
7142   PetscFunctionBegin;
7143   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7144   PetscValidType(mat,1);
7145   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
7146   if (n) {
7147     PetscValidPointer(is,3);
7148     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
7149   }
7150   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7151   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7152   MatCheckPreallocated(mat,1);
7153 
7154   if (!ov) PetscFunctionReturn(0);
7155   if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7156   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7157   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
7158   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7159   PetscFunctionReturn(0);
7160 }
7161 
7162 
7163 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt);
7164 
7165 /*@
7166    MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across
7167    a sub communicator, replaces the index sets by larger ones that represent submatrices with
7168    additional overlap.
7169 
7170    Collective on Mat
7171 
7172    Input Parameters:
7173 +  mat - the matrix
7174 .  n   - the number of index sets
7175 .  is  - the array of index sets (these index sets will changed during the call)
7176 -  ov  - the additional overlap requested
7177 
7178    Options Database:
7179 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
7180 
7181    Level: developer
7182 
7183    Concepts: overlap
7184    Concepts: ASM^computing overlap
7185 
7186 .seealso: MatCreateSubMatrices()
7187 @*/
7188 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov)
7189 {
7190   PetscInt       i;
7191   PetscErrorCode ierr;
7192 
7193   PetscFunctionBegin;
7194   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7195   PetscValidType(mat,1);
7196   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
7197   if (n) {
7198     PetscValidPointer(is,3);
7199     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
7200   }
7201   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7202   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7203   MatCheckPreallocated(mat,1);
7204   if (!ov) PetscFunctionReturn(0);
7205   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7206   for(i=0; i<n; i++){
7207 	ierr =  MatIncreaseOverlapSplit_Single(mat,&is[i],ov);CHKERRQ(ierr);
7208   }
7209   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7210   PetscFunctionReturn(0);
7211 }
7212 
7213 
7214 
7215 
7216 /*@
7217    MatGetBlockSize - Returns the matrix block size.
7218 
7219    Not Collective
7220 
7221    Input Parameter:
7222 .  mat - the matrix
7223 
7224    Output Parameter:
7225 .  bs - block size
7226 
7227    Notes:
7228     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7229 
7230    If the block size has not been set yet this routine returns 1.
7231 
7232    Level: intermediate
7233 
7234    Concepts: matrices^block size
7235 
7236 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
7237 @*/
7238 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
7239 {
7240   PetscFunctionBegin;
7241   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7242   PetscValidIntPointer(bs,2);
7243   *bs = PetscAbs(mat->rmap->bs);
7244   PetscFunctionReturn(0);
7245 }
7246 
7247 /*@
7248    MatGetBlockSizes - Returns the matrix block row and column sizes.
7249 
7250    Not Collective
7251 
7252    Input Parameter:
7253 .  mat - the matrix
7254 
7255    Output Parameter:
7256 .  rbs - row block size
7257 .  cbs - column block size
7258 
7259    Notes:
7260     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7261     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7262 
7263    If a block size has not been set yet this routine returns 1.
7264 
7265    Level: intermediate
7266 
7267    Concepts: matrices^block size
7268 
7269 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes()
7270 @*/
7271 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
7272 {
7273   PetscFunctionBegin;
7274   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7275   if (rbs) PetscValidIntPointer(rbs,2);
7276   if (cbs) PetscValidIntPointer(cbs,3);
7277   if (rbs) *rbs = PetscAbs(mat->rmap->bs);
7278   if (cbs) *cbs = PetscAbs(mat->cmap->bs);
7279   PetscFunctionReturn(0);
7280 }
7281 
7282 /*@
7283    MatSetBlockSize - Sets the matrix block size.
7284 
7285    Logically Collective on Mat
7286 
7287    Input Parameters:
7288 +  mat - the matrix
7289 -  bs - block size
7290 
7291    Notes:
7292     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7293     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later.
7294 
7295     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size
7296     is compatible with the matrix local sizes.
7297 
7298    Level: intermediate
7299 
7300    Concepts: matrices^block size
7301 
7302 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes()
7303 @*/
7304 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
7305 {
7306   PetscErrorCode ierr;
7307 
7308   PetscFunctionBegin;
7309   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7310   PetscValidLogicalCollectiveInt(mat,bs,2);
7311   ierr = MatSetBlockSizes(mat,bs,bs);CHKERRQ(ierr);
7312   PetscFunctionReturn(0);
7313 }
7314 
7315 /*@
7316    MatSetVariableBlockSizes - Sets a diagonal blocks of the matrix that need not be of the same size
7317 
7318    Logically Collective on Mat
7319 
7320    Input Parameters:
7321 +  mat - the matrix
7322 .  nblocks - the number of blocks on this process
7323 -  bsizes - the block sizes
7324 
7325    Notes:
7326     Currently used by PCVPBJACOBI for SeqAIJ matrices
7327 
7328    Level: intermediate
7329 
7330    Concepts: matrices^block size
7331 
7332 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatGetVariableBlockSizes()
7333 @*/
7334 PetscErrorCode MatSetVariableBlockSizes(Mat mat,PetscInt nblocks,PetscInt *bsizes)
7335 {
7336   PetscErrorCode ierr;
7337   PetscInt       i,ncnt = 0, nlocal;
7338 
7339   PetscFunctionBegin;
7340   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7341   if (nblocks < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number of local blocks must be great than or equal to zero");
7342   ierr = MatGetLocalSize(mat,&nlocal,NULL);CHKERRQ(ierr);
7343   for (i=0; i<nblocks; i++) ncnt += bsizes[i];
7344   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);
7345   ierr = PetscFree(mat->bsizes);CHKERRQ(ierr);
7346   mat->nblocks = nblocks;
7347   ierr = PetscMalloc1(nblocks,&mat->bsizes);CHKERRQ(ierr);
7348   ierr = PetscMemcpy(mat->bsizes,bsizes,nblocks*sizeof(PetscInt));CHKERRQ(ierr);
7349   PetscFunctionReturn(0);
7350 }
7351 
7352 /*@C
7353    MatGetVariableBlockSizes - Gets a diagonal blocks of the matrix that need not be of the same size
7354 
7355    Logically Collective on Mat
7356 
7357    Input Parameters:
7358 .  mat - the matrix
7359 
7360    Output Parameters:
7361 +  nblocks - the number of blocks on this process
7362 -  bsizes - the block sizes
7363 
7364    Notes: Currently not supported from Fortran
7365 
7366    Level: intermediate
7367 
7368    Concepts: matrices^block size
7369 
7370 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatSetVariableBlockSizes()
7371 @*/
7372 PetscErrorCode MatGetVariableBlockSizes(Mat mat,PetscInt *nblocks,const PetscInt **bsizes)
7373 {
7374   PetscFunctionBegin;
7375   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7376   *nblocks = mat->nblocks;
7377   *bsizes  = mat->bsizes;
7378   PetscFunctionReturn(0);
7379 }
7380 
7381 /*@
7382    MatSetBlockSizes - Sets the matrix block row and column sizes.
7383 
7384    Logically Collective on Mat
7385 
7386    Input Parameters:
7387 +  mat - the matrix
7388 -  rbs - row block size
7389 -  cbs - column block size
7390 
7391    Notes:
7392     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7393     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7394     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later
7395 
7396     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes
7397     are compatible with the matrix local sizes.
7398 
7399     The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs().
7400 
7401    Level: intermediate
7402 
7403    Concepts: matrices^block size
7404 
7405 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes()
7406 @*/
7407 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
7408 {
7409   PetscErrorCode ierr;
7410 
7411   PetscFunctionBegin;
7412   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7413   PetscValidLogicalCollectiveInt(mat,rbs,2);
7414   PetscValidLogicalCollectiveInt(mat,cbs,3);
7415   if (mat->ops->setblocksizes) {
7416     ierr = (*mat->ops->setblocksizes)(mat,rbs,cbs);CHKERRQ(ierr);
7417   }
7418   if (mat->rmap->refcnt) {
7419     ISLocalToGlobalMapping l2g = NULL;
7420     PetscLayout            nmap = NULL;
7421 
7422     ierr = PetscLayoutDuplicate(mat->rmap,&nmap);CHKERRQ(ierr);
7423     if (mat->rmap->mapping) {
7424       ierr = ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g);CHKERRQ(ierr);
7425     }
7426     ierr = PetscLayoutDestroy(&mat->rmap);CHKERRQ(ierr);
7427     mat->rmap = nmap;
7428     mat->rmap->mapping = l2g;
7429   }
7430   if (mat->cmap->refcnt) {
7431     ISLocalToGlobalMapping l2g = NULL;
7432     PetscLayout            nmap = NULL;
7433 
7434     ierr = PetscLayoutDuplicate(mat->cmap,&nmap);CHKERRQ(ierr);
7435     if (mat->cmap->mapping) {
7436       ierr = ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g);CHKERRQ(ierr);
7437     }
7438     ierr = PetscLayoutDestroy(&mat->cmap);CHKERRQ(ierr);
7439     mat->cmap = nmap;
7440     mat->cmap->mapping = l2g;
7441   }
7442   ierr = PetscLayoutSetBlockSize(mat->rmap,rbs);CHKERRQ(ierr);
7443   ierr = PetscLayoutSetBlockSize(mat->cmap,cbs);CHKERRQ(ierr);
7444   PetscFunctionReturn(0);
7445 }
7446 
7447 /*@
7448    MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices
7449 
7450    Logically Collective on Mat
7451 
7452    Input Parameters:
7453 +  mat - the matrix
7454 .  fromRow - matrix from which to copy row block size
7455 -  fromCol - matrix from which to copy column block size (can be same as fromRow)
7456 
7457    Level: developer
7458 
7459    Concepts: matrices^block size
7460 
7461 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes()
7462 @*/
7463 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)
7464 {
7465   PetscErrorCode ierr;
7466 
7467   PetscFunctionBegin;
7468   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7469   PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2);
7470   PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3);
7471   if (fromRow->rmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);CHKERRQ(ierr);}
7472   if (fromCol->cmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);CHKERRQ(ierr);}
7473   PetscFunctionReturn(0);
7474 }
7475 
7476 /*@
7477    MatResidual - Default routine to calculate the residual.
7478 
7479    Collective on Mat and Vec
7480 
7481    Input Parameters:
7482 +  mat - the matrix
7483 .  b   - the right-hand-side
7484 -  x   - the approximate solution
7485 
7486    Output Parameter:
7487 .  r - location to store the residual
7488 
7489    Level: developer
7490 
7491 .keywords: MG, default, multigrid, residual
7492 
7493 .seealso: PCMGSetResidual()
7494 @*/
7495 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r)
7496 {
7497   PetscErrorCode ierr;
7498 
7499   PetscFunctionBegin;
7500   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7501   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
7502   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
7503   PetscValidHeaderSpecific(r,VEC_CLASSID,4);
7504   PetscValidType(mat,1);
7505   MatCheckPreallocated(mat,1);
7506   ierr  = PetscLogEventBegin(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7507   if (!mat->ops->residual) {
7508     ierr = MatMult(mat,x,r);CHKERRQ(ierr);
7509     ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr);
7510   } else {
7511     ierr  = (*mat->ops->residual)(mat,b,x,r);CHKERRQ(ierr);
7512   }
7513   ierr  = PetscLogEventEnd(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7514   PetscFunctionReturn(0);
7515 }
7516 
7517 /*@C
7518     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
7519 
7520    Collective on Mat
7521 
7522     Input Parameters:
7523 +   mat - the matrix
7524 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
7525 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
7526 -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
7527                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7528                  always used.
7529 
7530     Output Parameters:
7531 +   n - number of rows in the (possibly compressed) matrix
7532 .   ia - the row pointers; that is ia[0] = 0, ia[row] = ia[row-1] + number of elements in that row of the matrix
7533 .   ja - the column indices
7534 -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
7535            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
7536 
7537     Level: developer
7538 
7539     Notes:
7540     You CANNOT change any of the ia[] or ja[] values.
7541 
7542     Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values.
7543 
7544     Fortran Notes:
7545     In Fortran use
7546 $
7547 $      PetscInt ia(1), ja(1)
7548 $      PetscOffset iia, jja
7549 $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
7550 $      ! Access the ith and jth entries via ia(iia + i) and ja(jja + j)
7551 
7552      or
7553 $
7554 $    PetscInt, pointer :: ia(:),ja(:)
7555 $    call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
7556 $    ! Access the ith and jth entries via ia(i) and ja(j)
7557 
7558 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
7559 @*/
7560 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7561 {
7562   PetscErrorCode ierr;
7563 
7564   PetscFunctionBegin;
7565   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7566   PetscValidType(mat,1);
7567   PetscValidIntPointer(n,5);
7568   if (ia) PetscValidIntPointer(ia,6);
7569   if (ja) PetscValidIntPointer(ja,7);
7570   PetscValidIntPointer(done,8);
7571   MatCheckPreallocated(mat,1);
7572   if (!mat->ops->getrowij) *done = PETSC_FALSE;
7573   else {
7574     *done = PETSC_TRUE;
7575     ierr  = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7576     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7577     ierr  = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7578   }
7579   PetscFunctionReturn(0);
7580 }
7581 
7582 /*@C
7583     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
7584 
7585     Collective on Mat
7586 
7587     Input Parameters:
7588 +   mat - the matrix
7589 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7590 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7591                 symmetrized
7592 .   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7593                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7594                  always used.
7595 .   n - number of columns in the (possibly compressed) matrix
7596 .   ia - the column pointers; that is ia[0] = 0, ia[col] = i[col-1] + number of elements in that col of the matrix
7597 -   ja - the row indices
7598 
7599     Output Parameters:
7600 .   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
7601 
7602     Level: developer
7603 
7604 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7605 @*/
7606 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7607 {
7608   PetscErrorCode ierr;
7609 
7610   PetscFunctionBegin;
7611   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7612   PetscValidType(mat,1);
7613   PetscValidIntPointer(n,4);
7614   if (ia) PetscValidIntPointer(ia,5);
7615   if (ja) PetscValidIntPointer(ja,6);
7616   PetscValidIntPointer(done,7);
7617   MatCheckPreallocated(mat,1);
7618   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
7619   else {
7620     *done = PETSC_TRUE;
7621     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7622   }
7623   PetscFunctionReturn(0);
7624 }
7625 
7626 /*@C
7627     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
7628     MatGetRowIJ().
7629 
7630     Collective on Mat
7631 
7632     Input Parameters:
7633 +   mat - the matrix
7634 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7635 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7636                 symmetrized
7637 .   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7638                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7639                  always used.
7640 .   n - size of (possibly compressed) matrix
7641 .   ia - the row pointers
7642 -   ja - the column indices
7643 
7644     Output Parameters:
7645 .   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7646 
7647     Note:
7648     This routine zeros out n, ia, and ja. This is to prevent accidental
7649     us of the array after it has been restored. If you pass NULL, it will
7650     not zero the pointers.  Use of ia or ja after MatRestoreRowIJ() is invalid.
7651 
7652     Level: developer
7653 
7654 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7655 @*/
7656 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7657 {
7658   PetscErrorCode ierr;
7659 
7660   PetscFunctionBegin;
7661   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7662   PetscValidType(mat,1);
7663   if (ia) PetscValidIntPointer(ia,6);
7664   if (ja) PetscValidIntPointer(ja,7);
7665   PetscValidIntPointer(done,8);
7666   MatCheckPreallocated(mat,1);
7667 
7668   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
7669   else {
7670     *done = PETSC_TRUE;
7671     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7672     if (n)  *n = 0;
7673     if (ia) *ia = NULL;
7674     if (ja) *ja = NULL;
7675   }
7676   PetscFunctionReturn(0);
7677 }
7678 
7679 /*@C
7680     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
7681     MatGetColumnIJ().
7682 
7683     Collective on Mat
7684 
7685     Input Parameters:
7686 +   mat - the matrix
7687 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7688 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7689                 symmetrized
7690 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7691                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7692                  always used.
7693 
7694     Output Parameters:
7695 +   n - size of (possibly compressed) matrix
7696 .   ia - the column pointers
7697 .   ja - the row indices
7698 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7699 
7700     Level: developer
7701 
7702 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
7703 @*/
7704 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7705 {
7706   PetscErrorCode ierr;
7707 
7708   PetscFunctionBegin;
7709   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7710   PetscValidType(mat,1);
7711   if (ia) PetscValidIntPointer(ia,5);
7712   if (ja) PetscValidIntPointer(ja,6);
7713   PetscValidIntPointer(done,7);
7714   MatCheckPreallocated(mat,1);
7715 
7716   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
7717   else {
7718     *done = PETSC_TRUE;
7719     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7720     if (n)  *n = 0;
7721     if (ia) *ia = NULL;
7722     if (ja) *ja = NULL;
7723   }
7724   PetscFunctionReturn(0);
7725 }
7726 
7727 /*@C
7728     MatColoringPatch -Used inside matrix coloring routines that
7729     use MatGetRowIJ() and/or MatGetColumnIJ().
7730 
7731     Collective on Mat
7732 
7733     Input Parameters:
7734 +   mat - the matrix
7735 .   ncolors - max color value
7736 .   n   - number of entries in colorarray
7737 -   colorarray - array indicating color for each column
7738 
7739     Output Parameters:
7740 .   iscoloring - coloring generated using colorarray information
7741 
7742     Level: developer
7743 
7744 .seealso: MatGetRowIJ(), MatGetColumnIJ()
7745 
7746 @*/
7747 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7748 {
7749   PetscErrorCode ierr;
7750 
7751   PetscFunctionBegin;
7752   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7753   PetscValidType(mat,1);
7754   PetscValidIntPointer(colorarray,4);
7755   PetscValidPointer(iscoloring,5);
7756   MatCheckPreallocated(mat,1);
7757 
7758   if (!mat->ops->coloringpatch) {
7759     ierr = ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);CHKERRQ(ierr);
7760   } else {
7761     ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
7762   }
7763   PetscFunctionReturn(0);
7764 }
7765 
7766 
7767 /*@
7768    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
7769 
7770    Logically Collective on Mat
7771 
7772    Input Parameter:
7773 .  mat - the factored matrix to be reset
7774 
7775    Notes:
7776    This routine should be used only with factored matrices formed by in-place
7777    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7778    format).  This option can save memory, for example, when solving nonlinear
7779    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7780    ILU(0) preconditioner.
7781 
7782    Note that one can specify in-place ILU(0) factorization by calling
7783 .vb
7784      PCType(pc,PCILU);
7785      PCFactorSeUseInPlace(pc);
7786 .ve
7787    or by using the options -pc_type ilu -pc_factor_in_place
7788 
7789    In-place factorization ILU(0) can also be used as a local
7790    solver for the blocks within the block Jacobi or additive Schwarz
7791    methods (runtime option: -sub_pc_factor_in_place).  See Users-Manual: ch_pc
7792    for details on setting local solver options.
7793 
7794    Most users should employ the simplified KSP interface for linear solvers
7795    instead of working directly with matrix algebra routines such as this.
7796    See, e.g., KSPCreate().
7797 
7798    Level: developer
7799 
7800 .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace()
7801 
7802    Concepts: matrices^unfactored
7803 
7804 @*/
7805 PetscErrorCode MatSetUnfactored(Mat mat)
7806 {
7807   PetscErrorCode ierr;
7808 
7809   PetscFunctionBegin;
7810   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7811   PetscValidType(mat,1);
7812   MatCheckPreallocated(mat,1);
7813   mat->factortype = MAT_FACTOR_NONE;
7814   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
7815   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
7816   PetscFunctionReturn(0);
7817 }
7818 
7819 /*MC
7820     MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.
7821 
7822     Synopsis:
7823     MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7824 
7825     Not collective
7826 
7827     Input Parameter:
7828 .   x - matrix
7829 
7830     Output Parameters:
7831 +   xx_v - the Fortran90 pointer to the array
7832 -   ierr - error code
7833 
7834     Example of Usage:
7835 .vb
7836       PetscScalar, pointer xx_v(:,:)
7837       ....
7838       call MatDenseGetArrayF90(x,xx_v,ierr)
7839       a = xx_v(3)
7840       call MatDenseRestoreArrayF90(x,xx_v,ierr)
7841 .ve
7842 
7843     Level: advanced
7844 
7845 .seealso:  MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90()
7846 
7847     Concepts: matrices^accessing array
7848 
7849 M*/
7850 
7851 /*MC
7852     MatDenseRestoreArrayF90 - Restores a matrix array that has been
7853     accessed with MatDenseGetArrayF90().
7854 
7855     Synopsis:
7856     MatDenseRestoreArrayF90(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 MatDenseGetArrayF90(x,xx_v,ierr)
7872        a = xx_v(3)
7873        call MatDenseRestoreArrayF90(x,xx_v,ierr)
7874 .ve
7875 
7876     Level: advanced
7877 
7878 .seealso:  MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90()
7879 
7880 M*/
7881 
7882 
7883 /*MC
7884     MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.
7885 
7886     Synopsis:
7887     MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7888 
7889     Not collective
7890 
7891     Input Parameter:
7892 .   x - matrix
7893 
7894     Output Parameters:
7895 +   xx_v - the Fortran90 pointer to the array
7896 -   ierr - error code
7897 
7898     Example of Usage:
7899 .vb
7900       PetscScalar, pointer xx_v(:)
7901       ....
7902       call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7903       a = xx_v(3)
7904       call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7905 .ve
7906 
7907     Level: advanced
7908 
7909 .seealso:  MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90()
7910 
7911     Concepts: matrices^accessing array
7912 
7913 M*/
7914 
7915 /*MC
7916     MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7917     accessed with MatSeqAIJGetArrayF90().
7918 
7919     Synopsis:
7920     MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7921 
7922     Not collective
7923 
7924     Input Parameters:
7925 +   x - matrix
7926 -   xx_v - the Fortran90 pointer to the array
7927 
7928     Output Parameter:
7929 .   ierr - error code
7930 
7931     Example of Usage:
7932 .vb
7933        PetscScalar, pointer xx_v(:)
7934        ....
7935        call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7936        a = xx_v(3)
7937        call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7938 .ve
7939 
7940     Level: advanced
7941 
7942 .seealso:  MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90()
7943 
7944 M*/
7945 
7946 
7947 /*@
7948     MatCreateSubMatrix - Gets a single submatrix on the same number of processors
7949                       as the original matrix.
7950 
7951     Collective on Mat
7952 
7953     Input Parameters:
7954 +   mat - the original matrix
7955 .   isrow - parallel IS containing the rows this processor should obtain
7956 .   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.
7957 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7958 
7959     Output Parameter:
7960 .   newmat - the new submatrix, of the same type as the old
7961 
7962     Level: advanced
7963 
7964     Notes:
7965     The submatrix will be able to be multiplied with vectors using the same layout as iscol.
7966 
7967     Some matrix types place restrictions on the row and column indices, such
7968     as that they be sorted or that they be equal to each other.
7969 
7970     The index sets may not have duplicate entries.
7971 
7972       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7973    the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls
7974    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7975    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
7976    you are finished using it.
7977 
7978     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7979     the input matrix.
7980 
7981     If iscol is NULL then all columns are obtained (not supported in Fortran).
7982 
7983    Example usage:
7984    Consider the following 8x8 matrix with 34 non-zero values, that is
7985    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7986    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7987    as follows:
7988 
7989 .vb
7990             1  2  0  |  0  3  0  |  0  4
7991     Proc0   0  5  6  |  7  0  0  |  8  0
7992             9  0 10  | 11  0  0  | 12  0
7993     -------------------------------------
7994            13  0 14  | 15 16 17  |  0  0
7995     Proc1   0 18  0  | 19 20 21  |  0  0
7996             0  0  0  | 22 23  0  | 24  0
7997     -------------------------------------
7998     Proc2  25 26 27  |  0  0 28  | 29  0
7999            30  0  0  | 31 32 33  |  0 34
8000 .ve
8001 
8002     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is
8003 
8004 .vb
8005             2  0  |  0  3  0  |  0
8006     Proc0   5  6  |  7  0  0  |  8
8007     -------------------------------
8008     Proc1  18  0  | 19 20 21  |  0
8009     -------------------------------
8010     Proc2  26 27  |  0  0 28  | 29
8011             0  0  | 31 32 33  |  0
8012 .ve
8013 
8014 
8015     Concepts: matrices^submatrices
8016 
8017 .seealso: MatCreateSubMatrices()
8018 @*/
8019 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
8020 {
8021   PetscErrorCode ierr;
8022   PetscMPIInt    size;
8023   Mat            *local;
8024   IS             iscoltmp;
8025 
8026   PetscFunctionBegin;
8027   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8028   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
8029   if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
8030   PetscValidPointer(newmat,5);
8031   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5);
8032   PetscValidType(mat,1);
8033   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8034   if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX");
8035 
8036   MatCheckPreallocated(mat,1);
8037   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
8038 
8039   if (!iscol || isrow == iscol) {
8040     PetscBool   stride;
8041     PetscMPIInt grabentirematrix = 0,grab;
8042     ierr = PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);CHKERRQ(ierr);
8043     if (stride) {
8044       PetscInt first,step,n,rstart,rend;
8045       ierr = ISStrideGetInfo(isrow,&first,&step);CHKERRQ(ierr);
8046       if (step == 1) {
8047         ierr = MatGetOwnershipRange(mat,&rstart,&rend);CHKERRQ(ierr);
8048         if (rstart == first) {
8049           ierr = ISGetLocalSize(isrow,&n);CHKERRQ(ierr);
8050           if (n == rend-rstart) {
8051             grabentirematrix = 1;
8052           }
8053         }
8054       }
8055     }
8056     ierr = MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr);
8057     if (grab) {
8058       ierr = PetscInfo(mat,"Getting entire matrix as submatrix\n");CHKERRQ(ierr);
8059       if (cll == MAT_INITIAL_MATRIX) {
8060         *newmat = mat;
8061         ierr    = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr);
8062       }
8063       PetscFunctionReturn(0);
8064     }
8065   }
8066 
8067   if (!iscol) {
8068     ierr = ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr);
8069   } else {
8070     iscoltmp = iscol;
8071   }
8072 
8073   /* if original matrix is on just one processor then use submatrix generated */
8074   if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
8075     ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
8076     goto setproperties;
8077   } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) {
8078     ierr    = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
8079     *newmat = *local;
8080     ierr    = PetscFree(local);CHKERRQ(ierr);
8081     goto setproperties;
8082   } else if (!mat->ops->createsubmatrix) {
8083     /* Create a new matrix type that implements the operation using the full matrix */
8084     ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8085     switch (cll) {
8086     case MAT_INITIAL_MATRIX:
8087       ierr = MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr);
8088       break;
8089     case MAT_REUSE_MATRIX:
8090       ierr = MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr);
8091       break;
8092     default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
8093     }
8094     ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8095     goto setproperties;
8096   }
8097 
8098   if (!mat->ops->createsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8099   ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8100   ierr = (*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr);
8101   ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8102 
8103   /* Propagate symmetry information for diagonal blocks */
8104 setproperties:
8105   if (isrow == iscoltmp) {
8106     if (mat->symmetric_set && mat->symmetric) {
8107       ierr = MatSetOption(*newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
8108     }
8109     if (mat->structurally_symmetric_set && mat->structurally_symmetric) {
8110       ierr = MatSetOption(*newmat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
8111     }
8112     if (mat->hermitian_set && mat->hermitian) {
8113       ierr = MatSetOption(*newmat,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
8114     }
8115     if (mat->spd_set && mat->spd) {
8116       ierr = MatSetOption(*newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr);
8117     }
8118   }
8119 
8120   if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
8121   if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);}
8122   PetscFunctionReturn(0);
8123 }
8124 
8125 /*@
8126    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
8127    used during the assembly process to store values that belong to
8128    other processors.
8129 
8130    Not Collective
8131 
8132    Input Parameters:
8133 +  mat   - the matrix
8134 .  size  - the initial size of the stash.
8135 -  bsize - the initial size of the block-stash(if used).
8136 
8137    Options Database Keys:
8138 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
8139 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
8140 
8141    Level: intermediate
8142 
8143    Notes:
8144      The block-stash is used for values set with MatSetValuesBlocked() while
8145      the stash is used for values set with MatSetValues()
8146 
8147      Run with the option -info and look for output of the form
8148      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
8149      to determine the appropriate value, MM, to use for size and
8150      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
8151      to determine the value, BMM to use for bsize
8152 
8153    Concepts: stash^setting matrix size
8154    Concepts: matrices^stash
8155 
8156 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
8157 
8158 @*/
8159 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
8160 {
8161   PetscErrorCode ierr;
8162 
8163   PetscFunctionBegin;
8164   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8165   PetscValidType(mat,1);
8166   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
8167   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
8168   PetscFunctionReturn(0);
8169 }
8170 
8171 /*@
8172    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
8173      the matrix
8174 
8175    Neighbor-wise Collective on Mat
8176 
8177    Input Parameters:
8178 +  mat   - the matrix
8179 .  x,y - the vectors
8180 -  w - where the result is stored
8181 
8182    Level: intermediate
8183 
8184    Notes:
8185     w may be the same vector as y.
8186 
8187     This allows one to use either the restriction or interpolation (its transpose)
8188     matrix to do the interpolation
8189 
8190     Concepts: interpolation
8191 
8192 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
8193 
8194 @*/
8195 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
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   PetscValidHeaderSpecific(w,VEC_CLASSID,4);
8205   PetscValidType(A,1);
8206   MatCheckPreallocated(A,1);
8207   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8208   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8209   if (M == Ny) {
8210     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
8211   } else {
8212     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
8213   }
8214   PetscFunctionReturn(0);
8215 }
8216 
8217 /*@
8218    MatInterpolate - y = A*x or A'*x depending on the shape of
8219      the matrix
8220 
8221    Neighbor-wise Collective on Mat
8222 
8223    Input Parameters:
8224 +  mat   - the matrix
8225 -  x,y - the vectors
8226 
8227    Level: intermediate
8228 
8229    Notes:
8230     This allows one to use either the restriction or interpolation (its transpose)
8231     matrix to do the interpolation
8232 
8233    Concepts: matrices^interpolation
8234 
8235 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
8236 
8237 @*/
8238 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
8239 {
8240   PetscErrorCode ierr;
8241   PetscInt       M,N,Ny;
8242 
8243   PetscFunctionBegin;
8244   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8245   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8246   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8247   PetscValidType(A,1);
8248   MatCheckPreallocated(A,1);
8249   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8250   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8251   if (M == Ny) {
8252     ierr = MatMult(A,x,y);CHKERRQ(ierr);
8253   } else {
8254     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
8255   }
8256   PetscFunctionReturn(0);
8257 }
8258 
8259 /*@
8260    MatRestrict - y = A*x or A'*x
8261 
8262    Neighbor-wise Collective on Mat
8263 
8264    Input Parameters:
8265 +  mat   - the matrix
8266 -  x,y - the vectors
8267 
8268    Level: intermediate
8269 
8270    Notes:
8271     This allows one to use either the restriction or interpolation (its transpose)
8272     matrix to do the restriction
8273 
8274    Concepts: matrices^restriction
8275 
8276 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
8277 
8278 @*/
8279 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
8280 {
8281   PetscErrorCode ierr;
8282   PetscInt       M,N,Ny;
8283 
8284   PetscFunctionBegin;
8285   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8286   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8287   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8288   PetscValidType(A,1);
8289   MatCheckPreallocated(A,1);
8290 
8291   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8292   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8293   if (M == Ny) {
8294     ierr = MatMult(A,x,y);CHKERRQ(ierr);
8295   } else {
8296     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
8297   }
8298   PetscFunctionReturn(0);
8299 }
8300 
8301 /*@
8302    MatGetNullSpace - retrieves the null space of a matrix.
8303 
8304    Logically Collective on Mat and MatNullSpace
8305 
8306    Input Parameters:
8307 +  mat - the matrix
8308 -  nullsp - the null space object
8309 
8310    Level: developer
8311 
8312    Concepts: null space^attaching to matrix
8313 
8314 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace()
8315 @*/
8316 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
8317 {
8318   PetscFunctionBegin;
8319   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8320   PetscValidPointer(nullsp,2);
8321   *nullsp = (mat->symmetric_set && mat->symmetric && !mat->nullsp) ? mat->transnullsp : mat->nullsp;
8322   PetscFunctionReturn(0);
8323 }
8324 
8325 /*@
8326    MatSetNullSpace - attaches a null space to a matrix.
8327 
8328    Logically Collective on Mat and MatNullSpace
8329 
8330    Input Parameters:
8331 +  mat - the matrix
8332 -  nullsp - the null space object
8333 
8334    Level: advanced
8335 
8336    Notes:
8337       This null space is used by the linear solvers. Overwrites any previous null space that may have been attached
8338 
8339       For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should
8340       call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense.
8341 
8342       You can remove the null space by calling this routine with an nullsp of NULL
8343 
8344 
8345       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8346    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).
8347    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
8348    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
8349    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).
8350 
8351       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8352 
8353     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
8354     routine also automatically calls MatSetTransposeNullSpace().
8355 
8356    Concepts: null space^attaching to matrix
8357 
8358 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8359 @*/
8360 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp)
8361 {
8362   PetscErrorCode ierr;
8363 
8364   PetscFunctionBegin;
8365   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8366   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8367   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8368   ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr);
8369   mat->nullsp = nullsp;
8370   if (mat->symmetric_set && mat->symmetric) {
8371     ierr = MatSetTransposeNullSpace(mat,nullsp);CHKERRQ(ierr);
8372   }
8373   PetscFunctionReturn(0);
8374 }
8375 
8376 /*@
8377    MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix.
8378 
8379    Logically Collective on Mat and MatNullSpace
8380 
8381    Input Parameters:
8382 +  mat - the matrix
8383 -  nullsp - the null space object
8384 
8385    Level: developer
8386 
8387    Concepts: null space^attaching to matrix
8388 
8389 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace()
8390 @*/
8391 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp)
8392 {
8393   PetscFunctionBegin;
8394   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8395   PetscValidType(mat,1);
8396   PetscValidPointer(nullsp,2);
8397   *nullsp = (mat->symmetric_set && mat->symmetric && !mat->transnullsp) ? mat->nullsp : mat->transnullsp;
8398   PetscFunctionReturn(0);
8399 }
8400 
8401 /*@
8402    MatSetTransposeNullSpace - attaches a null space to a matrix.
8403 
8404    Logically Collective on Mat and MatNullSpace
8405 
8406    Input Parameters:
8407 +  mat - the matrix
8408 -  nullsp - the null space object
8409 
8410    Level: advanced
8411 
8412    Notes:
8413       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.
8414       You must also call MatSetNullSpace()
8415 
8416 
8417       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8418    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).
8419    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
8420    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
8421    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).
8422 
8423       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8424 
8425    Concepts: null space^attaching to matrix
8426 
8427 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8428 @*/
8429 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp)
8430 {
8431   PetscErrorCode ierr;
8432 
8433   PetscFunctionBegin;
8434   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8435   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8436   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8437   ierr = MatNullSpaceDestroy(&mat->transnullsp);CHKERRQ(ierr);
8438   mat->transnullsp = nullsp;
8439   PetscFunctionReturn(0);
8440 }
8441 
8442 /*@
8443    MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions
8444         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.
8445 
8446    Logically Collective on Mat and MatNullSpace
8447 
8448    Input Parameters:
8449 +  mat - the matrix
8450 -  nullsp - the null space object
8451 
8452    Level: advanced
8453 
8454    Notes:
8455       Overwrites any previous near null space that may have been attached
8456 
8457       You can remove the null space by calling this routine with an nullsp of NULL
8458 
8459    Concepts: null space^attaching to matrix
8460 
8461 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace()
8462 @*/
8463 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
8464 {
8465   PetscErrorCode ierr;
8466 
8467   PetscFunctionBegin;
8468   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8469   PetscValidType(mat,1);
8470   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8471   MatCheckPreallocated(mat,1);
8472   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8473   ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr);
8474   mat->nearnullsp = nullsp;
8475   PetscFunctionReturn(0);
8476 }
8477 
8478 /*@
8479    MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()
8480 
8481    Not Collective
8482 
8483    Input Parameters:
8484 .  mat - the matrix
8485 
8486    Output Parameters:
8487 .  nullsp - the null space object, NULL if not set
8488 
8489    Level: developer
8490 
8491    Concepts: null space^attaching to matrix
8492 
8493 .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate()
8494 @*/
8495 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
8496 {
8497   PetscFunctionBegin;
8498   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8499   PetscValidType(mat,1);
8500   PetscValidPointer(nullsp,2);
8501   MatCheckPreallocated(mat,1);
8502   *nullsp = mat->nearnullsp;
8503   PetscFunctionReturn(0);
8504 }
8505 
8506 /*@C
8507    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
8508 
8509    Collective on Mat
8510 
8511    Input Parameters:
8512 +  mat - the matrix
8513 .  row - row/column permutation
8514 .  fill - expected fill factor >= 1.0
8515 -  level - level of fill, for ICC(k)
8516 
8517    Notes:
8518    Probably really in-place only when level of fill is zero, otherwise allocates
8519    new space to store factored matrix and deletes previous memory.
8520 
8521    Most users should employ the simplified KSP interface for linear solvers
8522    instead of working directly with matrix algebra routines such as this.
8523    See, e.g., KSPCreate().
8524 
8525    Level: developer
8526 
8527    Concepts: matrices^incomplete Cholesky factorization
8528    Concepts: Cholesky factorization
8529 
8530 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
8531 
8532     Developer Note: fortran interface is not autogenerated as the f90
8533     interface defintion cannot be generated correctly [due to MatFactorInfo]
8534 
8535 @*/
8536 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
8537 {
8538   PetscErrorCode ierr;
8539 
8540   PetscFunctionBegin;
8541   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8542   PetscValidType(mat,1);
8543   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
8544   PetscValidPointer(info,3);
8545   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
8546   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8547   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8548   if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8549   MatCheckPreallocated(mat,1);
8550   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
8551   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8552   PetscFunctionReturn(0);
8553 }
8554 
8555 /*@
8556    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
8557          ghosted ones.
8558 
8559    Not Collective
8560 
8561    Input Parameters:
8562 +  mat - the matrix
8563 -  diag = the diagonal values, including ghost ones
8564 
8565    Level: developer
8566 
8567    Notes:
8568     Works only for MPIAIJ and MPIBAIJ matrices
8569 
8570 .seealso: MatDiagonalScale()
8571 @*/
8572 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
8573 {
8574   PetscErrorCode ierr;
8575   PetscMPIInt    size;
8576 
8577   PetscFunctionBegin;
8578   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8579   PetscValidHeaderSpecific(diag,VEC_CLASSID,2);
8580   PetscValidType(mat,1);
8581 
8582   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8583   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8584   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
8585   if (size == 1) {
8586     PetscInt n,m;
8587     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
8588     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
8589     if (m == n) {
8590       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
8591     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
8592   } else {
8593     ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr);
8594   }
8595   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8596   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8597   PetscFunctionReturn(0);
8598 }
8599 
8600 /*@
8601    MatGetInertia - Gets the inertia from a factored matrix
8602 
8603    Collective on Mat
8604 
8605    Input Parameter:
8606 .  mat - the matrix
8607 
8608    Output Parameters:
8609 +   nneg - number of negative eigenvalues
8610 .   nzero - number of zero eigenvalues
8611 -   npos - number of positive eigenvalues
8612 
8613    Level: advanced
8614 
8615    Notes:
8616     Matrix must have been factored by MatCholeskyFactor()
8617 
8618 
8619 @*/
8620 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
8621 {
8622   PetscErrorCode ierr;
8623 
8624   PetscFunctionBegin;
8625   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8626   PetscValidType(mat,1);
8627   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8628   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
8629   if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8630   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
8631   PetscFunctionReturn(0);
8632 }
8633 
8634 /* ----------------------------------------------------------------*/
8635 /*@C
8636    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
8637 
8638    Neighbor-wise Collective on Mat and Vecs
8639 
8640    Input Parameters:
8641 +  mat - the factored matrix
8642 -  b - the right-hand-side vectors
8643 
8644    Output Parameter:
8645 .  x - the result vectors
8646 
8647    Notes:
8648    The vectors b and x cannot be the same.  I.e., one cannot
8649    call MatSolves(A,x,x).
8650 
8651    Notes:
8652    Most users should employ the simplified KSP interface for linear solvers
8653    instead of working directly with matrix algebra routines such as this.
8654    See, e.g., KSPCreate().
8655 
8656    Level: developer
8657 
8658    Concepts: matrices^triangular solves
8659 
8660 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
8661 @*/
8662 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
8663 {
8664   PetscErrorCode ierr;
8665 
8666   PetscFunctionBegin;
8667   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8668   PetscValidType(mat,1);
8669   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
8670   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8671   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
8672 
8673   if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8674   MatCheckPreallocated(mat,1);
8675   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8676   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
8677   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8678   PetscFunctionReturn(0);
8679 }
8680 
8681 /*@
8682    MatIsSymmetric - Test whether a matrix is symmetric
8683 
8684    Collective on Mat
8685 
8686    Input Parameter:
8687 +  A - the matrix to test
8688 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
8689 
8690    Output Parameters:
8691 .  flg - the result
8692 
8693    Notes:
8694     For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
8695 
8696    Level: intermediate
8697 
8698    Concepts: matrix^symmetry
8699 
8700 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
8701 @*/
8702 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
8703 {
8704   PetscErrorCode ierr;
8705 
8706   PetscFunctionBegin;
8707   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8708   PetscValidPointer(flg,2);
8709 
8710   if (!A->symmetric_set) {
8711     if (!A->ops->issymmetric) {
8712       MatType mattype;
8713       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8714       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8715     }
8716     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8717     if (!tol) {
8718       A->symmetric_set = PETSC_TRUE;
8719       A->symmetric     = *flg;
8720       if (A->symmetric) {
8721         A->structurally_symmetric_set = PETSC_TRUE;
8722         A->structurally_symmetric     = PETSC_TRUE;
8723       }
8724     }
8725   } else if (A->symmetric) {
8726     *flg = PETSC_TRUE;
8727   } else if (!tol) {
8728     *flg = PETSC_FALSE;
8729   } else {
8730     if (!A->ops->issymmetric) {
8731       MatType mattype;
8732       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8733       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8734     }
8735     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8736   }
8737   PetscFunctionReturn(0);
8738 }
8739 
8740 /*@
8741    MatIsHermitian - Test whether a matrix is Hermitian
8742 
8743    Collective on Mat
8744 
8745    Input Parameter:
8746 +  A - the matrix to test
8747 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
8748 
8749    Output Parameters:
8750 .  flg - the result
8751 
8752    Level: intermediate
8753 
8754    Concepts: matrix^symmetry
8755 
8756 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
8757           MatIsSymmetricKnown(), MatIsSymmetric()
8758 @*/
8759 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
8760 {
8761   PetscErrorCode ierr;
8762 
8763   PetscFunctionBegin;
8764   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8765   PetscValidPointer(flg,2);
8766 
8767   if (!A->hermitian_set) {
8768     if (!A->ops->ishermitian) {
8769       MatType mattype;
8770       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8771       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8772     }
8773     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8774     if (!tol) {
8775       A->hermitian_set = PETSC_TRUE;
8776       A->hermitian     = *flg;
8777       if (A->hermitian) {
8778         A->structurally_symmetric_set = PETSC_TRUE;
8779         A->structurally_symmetric     = PETSC_TRUE;
8780       }
8781     }
8782   } else if (A->hermitian) {
8783     *flg = PETSC_TRUE;
8784   } else if (!tol) {
8785     *flg = PETSC_FALSE;
8786   } else {
8787     if (!A->ops->ishermitian) {
8788       MatType mattype;
8789       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8790       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8791     }
8792     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8793   }
8794   PetscFunctionReturn(0);
8795 }
8796 
8797 /*@
8798    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
8799 
8800    Not Collective
8801 
8802    Input Parameter:
8803 .  A - the matrix to check
8804 
8805    Output Parameters:
8806 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
8807 -  flg - the result
8808 
8809    Level: advanced
8810 
8811    Concepts: matrix^symmetry
8812 
8813    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
8814          if you want it explicitly checked
8815 
8816 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8817 @*/
8818 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8819 {
8820   PetscFunctionBegin;
8821   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8822   PetscValidPointer(set,2);
8823   PetscValidPointer(flg,3);
8824   if (A->symmetric_set) {
8825     *set = PETSC_TRUE;
8826     *flg = A->symmetric;
8827   } else {
8828     *set = PETSC_FALSE;
8829   }
8830   PetscFunctionReturn(0);
8831 }
8832 
8833 /*@
8834    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
8835 
8836    Not Collective
8837 
8838    Input Parameter:
8839 .  A - the matrix to check
8840 
8841    Output Parameters:
8842 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8843 -  flg - the result
8844 
8845    Level: advanced
8846 
8847    Concepts: matrix^symmetry
8848 
8849    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8850          if you want it explicitly checked
8851 
8852 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8853 @*/
8854 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8855 {
8856   PetscFunctionBegin;
8857   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8858   PetscValidPointer(set,2);
8859   PetscValidPointer(flg,3);
8860   if (A->hermitian_set) {
8861     *set = PETSC_TRUE;
8862     *flg = A->hermitian;
8863   } else {
8864     *set = PETSC_FALSE;
8865   }
8866   PetscFunctionReturn(0);
8867 }
8868 
8869 /*@
8870    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
8871 
8872    Collective on Mat
8873 
8874    Input Parameter:
8875 .  A - the matrix to test
8876 
8877    Output Parameters:
8878 .  flg - the result
8879 
8880    Level: intermediate
8881 
8882    Concepts: matrix^symmetry
8883 
8884 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8885 @*/
8886 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
8887 {
8888   PetscErrorCode ierr;
8889 
8890   PetscFunctionBegin;
8891   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8892   PetscValidPointer(flg,2);
8893   if (!A->structurally_symmetric_set) {
8894     if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8895     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
8896 
8897     A->structurally_symmetric_set = PETSC_TRUE;
8898   }
8899   *flg = A->structurally_symmetric;
8900   PetscFunctionReturn(0);
8901 }
8902 
8903 /*@
8904    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8905        to be communicated to other processors during the MatAssemblyBegin/End() process
8906 
8907     Not collective
8908 
8909    Input Parameter:
8910 .   vec - the vector
8911 
8912    Output Parameters:
8913 +   nstash   - the size of the stash
8914 .   reallocs - the number of additional mallocs incurred.
8915 .   bnstash   - the size of the block stash
8916 -   breallocs - the number of additional mallocs incurred.in the block stash
8917 
8918    Level: advanced
8919 
8920 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
8921 
8922 @*/
8923 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8924 {
8925   PetscErrorCode ierr;
8926 
8927   PetscFunctionBegin;
8928   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
8929   ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
8930   PetscFunctionReturn(0);
8931 }
8932 
8933 /*@C
8934    MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same
8935      parallel layout
8936 
8937    Collective on Mat
8938 
8939    Input Parameter:
8940 .  mat - the matrix
8941 
8942    Output Parameter:
8943 +   right - (optional) vector that the matrix can be multiplied against
8944 -   left - (optional) vector that the matrix vector product can be stored in
8945 
8946    Notes:
8947     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().
8948 
8949   Notes:
8950     These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed
8951 
8952   Level: advanced
8953 
8954 .seealso: MatCreate(), VecDestroy()
8955 @*/
8956 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left)
8957 {
8958   PetscErrorCode ierr;
8959 
8960   PetscFunctionBegin;
8961   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8962   PetscValidType(mat,1);
8963   if (mat->ops->getvecs) {
8964     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
8965   } else {
8966     PetscInt rbs,cbs;
8967     ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr);
8968     if (right) {
8969       if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup");
8970       ierr = VecCreate(PetscObjectComm((PetscObject)mat),right);CHKERRQ(ierr);
8971       ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8972       ierr = VecSetBlockSize(*right,cbs);CHKERRQ(ierr);
8973       ierr = VecSetType(*right,mat->defaultvectype);CHKERRQ(ierr);
8974       ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr);
8975     }
8976     if (left) {
8977       if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup");
8978       ierr = VecCreate(PetscObjectComm((PetscObject)mat),left);CHKERRQ(ierr);
8979       ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8980       ierr = VecSetBlockSize(*left,rbs);CHKERRQ(ierr);
8981       ierr = VecSetType(*left,mat->defaultvectype);CHKERRQ(ierr);
8982       ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr);
8983     }
8984   }
8985   PetscFunctionReturn(0);
8986 }
8987 
8988 /*@C
8989    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8990      with default values.
8991 
8992    Not Collective
8993 
8994    Input Parameters:
8995 .    info - the MatFactorInfo data structure
8996 
8997 
8998    Notes:
8999     The solvers are generally used through the KSP and PC objects, for example
9000           PCLU, PCILU, PCCHOLESKY, PCICC
9001 
9002    Level: developer
9003 
9004 .seealso: MatFactorInfo
9005 
9006     Developer Note: fortran interface is not autogenerated as the f90
9007     interface defintion cannot be generated correctly [due to MatFactorInfo]
9008 
9009 @*/
9010 
9011 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
9012 {
9013   PetscErrorCode ierr;
9014 
9015   PetscFunctionBegin;
9016   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
9017   PetscFunctionReturn(0);
9018 }
9019 
9020 /*@
9021    MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed
9022 
9023    Collective on Mat
9024 
9025    Input Parameters:
9026 +  mat - the factored matrix
9027 -  is - the index set defining the Schur indices (0-based)
9028 
9029    Notes:
9030     Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system.
9031 
9032    You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call.
9033 
9034    Level: developer
9035 
9036    Concepts:
9037 
9038 .seealso: MatGetFactor(), MatFactorGetSchurComplement(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSolveSchurComplement(),
9039           MatFactorSolveSchurComplementTranspose(), MatFactorSolveSchurComplement()
9040 
9041 @*/
9042 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is)
9043 {
9044   PetscErrorCode ierr,(*f)(Mat,IS);
9045 
9046   PetscFunctionBegin;
9047   PetscValidType(mat,1);
9048   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9049   PetscValidType(is,2);
9050   PetscValidHeaderSpecific(is,IS_CLASSID,2);
9051   PetscCheckSameComm(mat,1,is,2);
9052   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
9053   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);CHKERRQ(ierr);
9054   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");
9055   if (mat->schur) {
9056     ierr = MatDestroy(&mat->schur);CHKERRQ(ierr);
9057   }
9058   ierr = (*f)(mat,is);CHKERRQ(ierr);
9059   if (!mat->schur) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created");
9060   ierr = MatFactorSetUpInPlaceSchur_Private(mat);CHKERRQ(ierr);
9061   PetscFunctionReturn(0);
9062 }
9063 
9064 /*@
9065   MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step
9066 
9067    Logically Collective on Mat
9068 
9069    Input Parameters:
9070 +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
9071 .  S - location where to return the Schur complement, can be NULL
9072 -  status - the status of the Schur complement matrix, can be NULL
9073 
9074    Notes:
9075    You must call MatFactorSetSchurIS() before calling this routine.
9076 
9077    The routine provides a copy of the Schur matrix stored within the solver data structures.
9078    The caller must destroy the object when it is no longer needed.
9079    If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse.
9080 
9081    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)
9082 
9083    Developer Notes:
9084     The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc
9085    matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix.
9086 
9087    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
9088 
9089    Level: advanced
9090 
9091    References:
9092 
9093 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorSchurStatus
9094 @*/
9095 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
9096 {
9097   PetscErrorCode ierr;
9098 
9099   PetscFunctionBegin;
9100   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9101   if (S) PetscValidPointer(S,2);
9102   if (status) PetscValidPointer(status,3);
9103   if (S) {
9104     PetscErrorCode (*f)(Mat,Mat*);
9105 
9106     ierr = PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f);CHKERRQ(ierr);
9107     if (f) {
9108       ierr = (*f)(F,S);CHKERRQ(ierr);
9109     } else {
9110       ierr = MatDuplicate(F->schur,MAT_COPY_VALUES,S);CHKERRQ(ierr);
9111     }
9112   }
9113   if (status) *status = F->schur_status;
9114   PetscFunctionReturn(0);
9115 }
9116 
9117 /*@
9118   MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix
9119 
9120    Logically Collective on Mat
9121 
9122    Input Parameters:
9123 +  F - the factored matrix obtained by calling MatGetFactor()
9124 .  *S - location where to return the Schur complement, can be NULL
9125 -  status - the status of the Schur complement matrix, can be NULL
9126 
9127    Notes:
9128    You must call MatFactorSetSchurIS() before calling this routine.
9129 
9130    Schur complement mode is currently implemented for sequential matrices.
9131    The routine returns a the Schur Complement stored within the data strutures of the solver.
9132    If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement.
9133    The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed.
9134 
9135    Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix
9136 
9137    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
9138 
9139    Level: advanced
9140 
9141    References:
9142 
9143 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
9144 @*/
9145 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
9146 {
9147   PetscFunctionBegin;
9148   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9149   if (S) PetscValidPointer(S,2);
9150   if (status) PetscValidPointer(status,3);
9151   if (S) *S = F->schur;
9152   if (status) *status = F->schur_status;
9153   PetscFunctionReturn(0);
9154 }
9155 
9156 /*@
9157   MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement
9158 
9159    Logically Collective on Mat
9160 
9161    Input Parameters:
9162 +  F - the factored matrix obtained by calling MatGetFactor()
9163 .  *S - location where the Schur complement is stored
9164 -  status - the status of the Schur complement matrix (see MatFactorSchurStatus)
9165 
9166    Notes:
9167 
9168    Level: advanced
9169 
9170    References:
9171 
9172 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
9173 @*/
9174 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status)
9175 {
9176   PetscErrorCode ierr;
9177 
9178   PetscFunctionBegin;
9179   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9180   if (S) {
9181     PetscValidHeaderSpecific(*S,MAT_CLASSID,2);
9182     *S = NULL;
9183   }
9184   F->schur_status = status;
9185   ierr = MatFactorUpdateSchurStatus_Private(F);CHKERRQ(ierr);
9186   PetscFunctionReturn(0);
9187 }
9188 
9189 /*@
9190   MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step
9191 
9192    Logically Collective on Mat
9193 
9194    Input Parameters:
9195 +  F - the factored matrix obtained by calling MatGetFactor()
9196 .  rhs - location where the right hand side of the Schur complement system is stored
9197 -  sol - location where the solution of the Schur complement system has to be returned
9198 
9199    Notes:
9200    The sizes of the vectors should match the size of the Schur complement
9201 
9202    Must be called after MatFactorSetSchurIS()
9203 
9204    Level: advanced
9205 
9206    References:
9207 
9208 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplement()
9209 @*/
9210 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol)
9211 {
9212   PetscErrorCode ierr;
9213 
9214   PetscFunctionBegin;
9215   PetscValidType(F,1);
9216   PetscValidType(rhs,2);
9217   PetscValidType(sol,3);
9218   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9219   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
9220   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
9221   PetscCheckSameComm(F,1,rhs,2);
9222   PetscCheckSameComm(F,1,sol,3);
9223   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9224   switch (F->schur_status) {
9225   case MAT_FACTOR_SCHUR_FACTORED:
9226     ierr = MatSolveTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
9227     break;
9228   case MAT_FACTOR_SCHUR_INVERTED:
9229     ierr = MatMultTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
9230     break;
9231   default:
9232     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9233     break;
9234   }
9235   PetscFunctionReturn(0);
9236 }
9237 
9238 /*@
9239   MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step
9240 
9241    Logically Collective on Mat
9242 
9243    Input Parameters:
9244 +  F - the factored matrix obtained by calling MatGetFactor()
9245 .  rhs - location where the right hand side of the Schur complement system is stored
9246 -  sol - location where the solution of the Schur complement system has to be returned
9247 
9248    Notes:
9249    The sizes of the vectors should match the size of the Schur complement
9250 
9251    Must be called after MatFactorSetSchurIS()
9252 
9253    Level: advanced
9254 
9255    References:
9256 
9257 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplementTranspose()
9258 @*/
9259 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol)
9260 {
9261   PetscErrorCode ierr;
9262 
9263   PetscFunctionBegin;
9264   PetscValidType(F,1);
9265   PetscValidType(rhs,2);
9266   PetscValidType(sol,3);
9267   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9268   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
9269   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
9270   PetscCheckSameComm(F,1,rhs,2);
9271   PetscCheckSameComm(F,1,sol,3);
9272   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9273   switch (F->schur_status) {
9274   case MAT_FACTOR_SCHUR_FACTORED:
9275     ierr = MatSolve(F->schur,rhs,sol);CHKERRQ(ierr);
9276     break;
9277   case MAT_FACTOR_SCHUR_INVERTED:
9278     ierr = MatMult(F->schur,rhs,sol);CHKERRQ(ierr);
9279     break;
9280   default:
9281     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9282     break;
9283   }
9284   PetscFunctionReturn(0);
9285 }
9286 
9287 /*@
9288   MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step
9289 
9290    Logically Collective on Mat
9291 
9292    Input Parameters:
9293 +  F - the factored matrix obtained by calling MatGetFactor()
9294 
9295    Notes:
9296     Must be called after MatFactorSetSchurIS().
9297 
9298    Call MatFactorGetSchurComplement() or  MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it.
9299 
9300    Level: advanced
9301 
9302    References:
9303 
9304 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorCreateSchurComplement()
9305 @*/
9306 PetscErrorCode MatFactorInvertSchurComplement(Mat F)
9307 {
9308   PetscErrorCode ierr;
9309 
9310   PetscFunctionBegin;
9311   PetscValidType(F,1);
9312   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9313   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0);
9314   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9315   ierr = MatFactorInvertSchurComplement_Private(F);CHKERRQ(ierr);
9316   F->schur_status = MAT_FACTOR_SCHUR_INVERTED;
9317   PetscFunctionReturn(0);
9318 }
9319 
9320 /*@
9321   MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step
9322 
9323    Logically Collective on Mat
9324 
9325    Input Parameters:
9326 +  F - the factored matrix obtained by calling MatGetFactor()
9327 
9328    Notes:
9329     Must be called after MatFactorSetSchurIS().
9330 
9331    Level: advanced
9332 
9333    References:
9334 
9335 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorInvertSchurComplement()
9336 @*/
9337 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F)
9338 {
9339   PetscErrorCode ierr;
9340 
9341   PetscFunctionBegin;
9342   PetscValidType(F,1);
9343   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9344   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0);
9345   ierr = MatFactorFactorizeSchurComplement_Private(F);CHKERRQ(ierr);
9346   F->schur_status = MAT_FACTOR_SCHUR_FACTORED;
9347   PetscFunctionReturn(0);
9348 }
9349 
9350 /*@
9351    MatPtAP - Creates the matrix product C = P^T * A * P
9352 
9353    Neighbor-wise Collective on Mat
9354 
9355    Input Parameters:
9356 +  A - the matrix
9357 .  P - the projection matrix
9358 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9359 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate
9360           if the result is a dense matrix this is irrelevent
9361 
9362    Output Parameters:
9363 .  C - the product matrix
9364 
9365    Notes:
9366    C will be created and must be destroyed by the user with MatDestroy().
9367 
9368    This routine is currently only implemented for pairs of sequential dense matrices, AIJ matrices and classes
9369    which inherit from AIJ.
9370 
9371    Level: intermediate
9372 
9373 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
9374 @*/
9375 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
9376 {
9377   PetscErrorCode ierr;
9378   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9379   PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
9380   PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9381   PetscBool      sametype;
9382 
9383   PetscFunctionBegin;
9384   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9385   PetscValidType(A,1);
9386   MatCheckPreallocated(A,1);
9387   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9388   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9389   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9390   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9391   PetscValidType(P,2);
9392   MatCheckPreallocated(P,2);
9393   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9394   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9395 
9396   if (A->rmap->N != A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix A must be square, %D != %D",A->rmap->N,A->cmap->N);
9397   if (P->rmap->N != A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
9398   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9399   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9400 
9401   if (scall == MAT_REUSE_MATRIX) {
9402     PetscValidPointer(*C,5);
9403     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9404 
9405     if (!(*C)->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You cannot use MAT_REUSE_MATRIX");
9406     ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9407     ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9408     ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr);
9409     ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9410     ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9411     PetscFunctionReturn(0);
9412   }
9413 
9414   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9415   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9416 
9417   fA = A->ops->ptap;
9418   fP = P->ops->ptap;
9419   ierr = PetscStrcmp(((PetscObject)A)->type_name,((PetscObject)P)->type_name,&sametype);CHKERRQ(ierr);
9420   if (fP == fA && sametype) {
9421     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name);
9422     ptap = fA;
9423   } else {
9424     /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
9425     char ptapname[256];
9426     ierr = PetscStrncpy(ptapname,"MatPtAP_",sizeof(ptapname));CHKERRQ(ierr);
9427     ierr = PetscStrlcat(ptapname,((PetscObject)A)->type_name,sizeof(ptapname));CHKERRQ(ierr);
9428     ierr = PetscStrlcat(ptapname,"_",sizeof(ptapname));CHKERRQ(ierr);
9429     ierr = PetscStrlcat(ptapname,((PetscObject)P)->type_name,sizeof(ptapname));CHKERRQ(ierr);
9430     ierr = PetscStrlcat(ptapname,"_C",sizeof(ptapname));CHKERRQ(ierr); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
9431     ierr = PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);CHKERRQ(ierr);
9432     if (!ptap) SETERRQ3(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatPtAP requires A, %s, to be compatible with P, %s (Misses composed function %s)",((PetscObject)A)->type_name,((PetscObject)P)->type_name,ptapname);
9433   }
9434 
9435   ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9436   ierr = (*ptap)(A,P,scall,fill,C);CHKERRQ(ierr);
9437   ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9438   if (A->symmetric_set && A->symmetric) {
9439     ierr = MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
9440   }
9441   PetscFunctionReturn(0);
9442 }
9443 
9444 /*@
9445    MatPtAPNumeric - Computes the matrix product C = P^T * A * P
9446 
9447    Neighbor-wise Collective on Mat
9448 
9449    Input Parameters:
9450 +  A - the matrix
9451 -  P - the projection matrix
9452 
9453    Output Parameters:
9454 .  C - the product matrix
9455 
9456    Notes:
9457    C must have been created by calling MatPtAPSymbolic and must be destroyed by
9458    the user using MatDeatroy().
9459 
9460    This routine is currently only implemented for pairs of AIJ matrices and classes
9461    which inherit from AIJ.  C will be of type MATAIJ.
9462 
9463    Level: intermediate
9464 
9465 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
9466 @*/
9467 PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C)
9468 {
9469   PetscErrorCode ierr;
9470 
9471   PetscFunctionBegin;
9472   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9473   PetscValidType(A,1);
9474   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9475   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9476   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9477   PetscValidType(P,2);
9478   MatCheckPreallocated(P,2);
9479   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9480   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9481   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9482   PetscValidType(C,3);
9483   MatCheckPreallocated(C,3);
9484   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9485   if (P->cmap->N!=C->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->rmap->N);
9486   if (P->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
9487   if (A->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
9488   if (P->cmap->N!=C->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->cmap->N);
9489   MatCheckPreallocated(A,1);
9490 
9491   if (!C->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You should call MatPtAPSymbolic first");
9492   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9493   ierr = (*C->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr);
9494   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9495   PetscFunctionReturn(0);
9496 }
9497 
9498 /*@
9499    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P
9500 
9501    Neighbor-wise Collective on Mat
9502 
9503    Input Parameters:
9504 +  A - the matrix
9505 -  P - the projection matrix
9506 
9507    Output Parameters:
9508 .  C - the (i,j) structure of the product matrix
9509 
9510    Notes:
9511    C will be created and must be destroyed by the user with MatDestroy().
9512 
9513    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9514    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9515    this (i,j) structure by calling MatPtAPNumeric().
9516 
9517    Level: intermediate
9518 
9519 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
9520 @*/
9521 PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
9522 {
9523   PetscErrorCode ierr;
9524 
9525   PetscFunctionBegin;
9526   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9527   PetscValidType(A,1);
9528   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9529   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9530   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9531   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9532   PetscValidType(P,2);
9533   MatCheckPreallocated(P,2);
9534   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9535   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9536   PetscValidPointer(C,3);
9537 
9538   if (P->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
9539   if (A->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
9540   MatCheckPreallocated(A,1);
9541 
9542   if (!A->ops->ptapsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatType %s",((PetscObject)A)->type_name);
9543   ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
9544   ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr);
9545   ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
9546 
9547   /* ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); NO! this is not always true -ma */
9548   PetscFunctionReturn(0);
9549 }
9550 
9551 /*@
9552    MatRARt - Creates the matrix product C = R * A * R^T
9553 
9554    Neighbor-wise Collective on Mat
9555 
9556    Input Parameters:
9557 +  A - the matrix
9558 .  R - the projection matrix
9559 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9560 -  fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate
9561           if the result is a dense matrix this is irrelevent
9562 
9563    Output Parameters:
9564 .  C - the product matrix
9565 
9566    Notes:
9567    C will be created and must be destroyed by the user with MatDestroy().
9568 
9569    This routine is currently only implemented for pairs of AIJ matrices and classes
9570    which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes,
9571    parallel MatRARt is implemented via explicit transpose of R, which could be very expensive.
9572    We recommend using MatPtAP().
9573 
9574    Level: intermediate
9575 
9576 .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
9577 @*/
9578 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
9579 {
9580   PetscErrorCode ierr;
9581 
9582   PetscFunctionBegin;
9583   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9584   PetscValidType(A,1);
9585   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9586   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9587   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9588   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9589   PetscValidType(R,2);
9590   MatCheckPreallocated(R,2);
9591   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9592   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9593   PetscValidPointer(C,3);
9594   if (R->cmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)R),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N);
9595 
9596   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9597   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9598   MatCheckPreallocated(A,1);
9599 
9600   if (!A->ops->rart) {
9601     Mat Rt;
9602     ierr = MatTranspose(R,MAT_INITIAL_MATRIX,&Rt);CHKERRQ(ierr);
9603     ierr = MatMatMatMult(R,A,Rt,scall,fill,C);CHKERRQ(ierr);
9604     ierr = MatDestroy(&Rt);CHKERRQ(ierr);
9605     PetscFunctionReturn(0);
9606   }
9607   ierr = PetscLogEventBegin(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
9608   ierr = (*A->ops->rart)(A,R,scall,fill,C);CHKERRQ(ierr);
9609   ierr = PetscLogEventEnd(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
9610   PetscFunctionReturn(0);
9611 }
9612 
9613 /*@
9614    MatRARtNumeric - Computes the matrix product C = R * A * R^T
9615 
9616    Neighbor-wise Collective on Mat
9617 
9618    Input Parameters:
9619 +  A - the matrix
9620 -  R - the projection matrix
9621 
9622    Output Parameters:
9623 .  C - the product matrix
9624 
9625    Notes:
9626    C must have been created by calling MatRARtSymbolic and must be destroyed by
9627    the user using MatDestroy().
9628 
9629    This routine is currently only implemented for pairs of AIJ matrices and classes
9630    which inherit from AIJ.  C will be of type MATAIJ.
9631 
9632    Level: intermediate
9633 
9634 .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
9635 @*/
9636 PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C)
9637 {
9638   PetscErrorCode ierr;
9639 
9640   PetscFunctionBegin;
9641   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9642   PetscValidType(A,1);
9643   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9644   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9645   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9646   PetscValidType(R,2);
9647   MatCheckPreallocated(R,2);
9648   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9649   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9650   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9651   PetscValidType(C,3);
9652   MatCheckPreallocated(C,3);
9653   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9654   if (R->rmap->N!=C->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->rmap->N,C->rmap->N);
9655   if (R->cmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N);
9656   if (A->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
9657   if (R->rmap->N!=C->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->rmap->N,C->cmap->N);
9658   MatCheckPreallocated(A,1);
9659 
9660   ierr = PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
9661   ierr = (*A->ops->rartnumeric)(A,R,C);CHKERRQ(ierr);
9662   ierr = PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
9663   PetscFunctionReturn(0);
9664 }
9665 
9666 /*@
9667    MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T
9668 
9669    Neighbor-wise Collective on Mat
9670 
9671    Input Parameters:
9672 +  A - the matrix
9673 -  R - the projection matrix
9674 
9675    Output Parameters:
9676 .  C - the (i,j) structure of the product matrix
9677 
9678    Notes:
9679    C will be created and must be destroyed by the user with MatDestroy().
9680 
9681    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9682    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9683    this (i,j) structure by calling MatRARtNumeric().
9684 
9685    Level: intermediate
9686 
9687 .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
9688 @*/
9689 PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
9690 {
9691   PetscErrorCode ierr;
9692 
9693   PetscFunctionBegin;
9694   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9695   PetscValidType(A,1);
9696   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9697   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9698   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9699   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9700   PetscValidType(R,2);
9701   MatCheckPreallocated(R,2);
9702   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9703   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9704   PetscValidPointer(C,3);
9705 
9706   if (R->cmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N);
9707   if (A->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
9708   MatCheckPreallocated(A,1);
9709   ierr = PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
9710   ierr = (*A->ops->rartsymbolic)(A,R,fill,C);CHKERRQ(ierr);
9711   ierr = PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
9712 
9713   ierr = MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));CHKERRQ(ierr);
9714   PetscFunctionReturn(0);
9715 }
9716 
9717 /*@
9718    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
9719 
9720    Neighbor-wise Collective on Mat
9721 
9722    Input Parameters:
9723 +  A - the left matrix
9724 .  B - the right matrix
9725 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9726 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
9727           if the result is a dense matrix this is irrelevent
9728 
9729    Output Parameters:
9730 .  C - the product matrix
9731 
9732    Notes:
9733    Unless scall is MAT_REUSE_MATRIX C will be created.
9734 
9735    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
9736    call to this function with either MAT_INITIAL_MATRIX or MatMatMultSymbolic()
9737 
9738    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9739    actually needed.
9740 
9741    If you have many matrices with the same non-zero structure to multiply, you
9742    should either
9743 $   1) use MAT_REUSE_MATRIX in all calls but the first or
9744 $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
9745    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
9746    with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse.
9747 
9748    Level: intermediate
9749 
9750 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(),  MatMatTransposeMult(), MatPtAP()
9751 @*/
9752 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9753 {
9754   PetscErrorCode ierr;
9755   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9756   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9757   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9758 
9759   PetscFunctionBegin;
9760   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9761   PetscValidType(A,1);
9762   MatCheckPreallocated(A,1);
9763   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9764   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9765   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9766   PetscValidType(B,2);
9767   MatCheckPreallocated(B,2);
9768   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9769   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9770   PetscValidPointer(C,3);
9771   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9772   if (B->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
9773   if (scall == MAT_REUSE_MATRIX) {
9774     PetscValidPointer(*C,5);
9775     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9776     ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9777     ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9778     ierr = (*(*C)->ops->matmultnumeric)(A,B,*C);CHKERRQ(ierr);
9779     ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9780     ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9781     PetscFunctionReturn(0);
9782   }
9783   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9784   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9785 
9786   fA = A->ops->matmult;
9787   fB = B->ops->matmult;
9788   if (fB == fA) {
9789     if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
9790     mult = fB;
9791   } else {
9792     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9793     char multname[256];
9794     ierr = PetscStrncpy(multname,"MatMatMult_",sizeof(multname));CHKERRQ(ierr);
9795     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
9796     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
9797     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
9798     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9799     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
9800     if (!mult) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
9801   }
9802   ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9803   ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr);
9804   ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9805   PetscFunctionReturn(0);
9806 }
9807 
9808 /*@
9809    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
9810    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().
9811 
9812    Neighbor-wise Collective on Mat
9813 
9814    Input Parameters:
9815 +  A - the left matrix
9816 .  B - the right matrix
9817 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
9818       if C is a dense matrix this is irrelevent
9819 
9820    Output Parameters:
9821 .  C - the product matrix
9822 
9823    Notes:
9824    Unless scall is MAT_REUSE_MATRIX C will be created.
9825 
9826    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9827    actually needed.
9828 
9829    This routine is currently implemented for
9830     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
9831     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9832     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9833 
9834    Level: intermediate
9835 
9836    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
9837      We should incorporate them into PETSc.
9838 
9839 .seealso: MatMatMult(), MatMatMultNumeric()
9840 @*/
9841 PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
9842 {
9843   PetscErrorCode ierr;
9844   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*);
9845   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*);
9846   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL;
9847 
9848   PetscFunctionBegin;
9849   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9850   PetscValidType(A,1);
9851   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9852   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9853 
9854   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9855   PetscValidType(B,2);
9856   MatCheckPreallocated(B,2);
9857   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9858   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9859   PetscValidPointer(C,3);
9860 
9861   if (B->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
9862   if (fill == PETSC_DEFAULT) fill = 2.0;
9863   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9864   MatCheckPreallocated(A,1);
9865 
9866   Asymbolic = A->ops->matmultsymbolic;
9867   Bsymbolic = B->ops->matmultsymbolic;
9868   if (Asymbolic == Bsymbolic) {
9869     if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
9870     symbolic = Bsymbolic;
9871   } else { /* dispatch based on the type of A and B */
9872     char symbolicname[256];
9873     ierr = PetscStrncpy(symbolicname,"MatMatMultSymbolic_",sizeof(symbolicname));CHKERRQ(ierr);
9874     ierr = PetscStrlcat(symbolicname,((PetscObject)A)->type_name,sizeof(symbolicname));CHKERRQ(ierr);
9875     ierr = PetscStrlcat(symbolicname,"_",sizeof(symbolicname));CHKERRQ(ierr);
9876     ierr = PetscStrlcat(symbolicname,((PetscObject)B)->type_name,sizeof(symbolicname));CHKERRQ(ierr);
9877     ierr = PetscStrlcat(symbolicname,"_C",sizeof(symbolicname));CHKERRQ(ierr);
9878     ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);CHKERRQ(ierr);
9879     if (!symbolic) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatMultSymbolic requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
9880   }
9881   ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9882   ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr);
9883   ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9884   PetscFunctionReturn(0);
9885 }
9886 
9887 /*@
9888    MatMatMultNumeric - Performs the numeric matrix-matrix product.
9889    Call this routine after first calling MatMatMultSymbolic().
9890 
9891    Neighbor-wise Collective on Mat
9892 
9893    Input Parameters:
9894 +  A - the left matrix
9895 -  B - the right matrix
9896 
9897    Output Parameters:
9898 .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
9899 
9900    Notes:
9901    C must have been created with MatMatMultSymbolic().
9902 
9903    This routine is currently implemented for
9904     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
9905     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9906     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9907 
9908    Level: intermediate
9909 
9910 .seealso: MatMatMult(), MatMatMultSymbolic()
9911 @*/
9912 PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C)
9913 {
9914   PetscErrorCode ierr;
9915 
9916   PetscFunctionBegin;
9917   ierr = MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);CHKERRQ(ierr);
9918   PetscFunctionReturn(0);
9919 }
9920 
9921 /*@
9922    MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.
9923 
9924    Neighbor-wise Collective on Mat
9925 
9926    Input Parameters:
9927 +  A - the left matrix
9928 .  B - the right matrix
9929 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9930 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9931 
9932    Output Parameters:
9933 .  C - the product matrix
9934 
9935    Notes:
9936    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9937 
9938    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9939 
9940   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9941    actually needed.
9942 
9943    This routine is currently only implemented for pairs of SeqAIJ matrices, for the SeqDense class,
9944    and for pairs of MPIDense matrices.
9945 
9946    Options Database Keys:
9947 +  -matmattransmult_mpidense_mpidense_via {allgatherv,cyclic} - Choose between algorthims for MPIDense matrices: the
9948                                                                 first redundantly copies the transposed B matrix on each process and requiers O(log P) communication complexity;
9949                                                                 the second never stores more than one portion of the B matrix at a time by requires O(P) communication complexity.
9950 
9951    Level: intermediate
9952 
9953 .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
9954 @*/
9955 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9956 {
9957   PetscErrorCode ierr;
9958   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9959   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9960 
9961   PetscFunctionBegin;
9962   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9963   PetscValidType(A,1);
9964   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9965   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9966   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9967   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9968   PetscValidType(B,2);
9969   MatCheckPreallocated(B,2);
9970   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9971   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9972   PetscValidPointer(C,3);
9973   if (B->cmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, AN %D != BN %D",A->cmap->N,B->cmap->N);
9974   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9975   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9976   MatCheckPreallocated(A,1);
9977 
9978   fA = A->ops->mattransposemult;
9979   if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
9980   fB = B->ops->mattransposemult;
9981   if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
9982   if (fB!=fA) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatTransposeMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
9983 
9984   ierr = PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
9985   if (scall == MAT_INITIAL_MATRIX) {
9986     ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9987     ierr = (*A->ops->mattransposemultsymbolic)(A,B,fill,C);CHKERRQ(ierr);
9988     ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9989   }
9990   ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
9991   ierr = (*A->ops->mattransposemultnumeric)(A,B,*C);CHKERRQ(ierr);
9992   ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
9993   ierr = PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
9994   PetscFunctionReturn(0);
9995 }
9996 
9997 /*@
9998    MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.
9999 
10000    Neighbor-wise Collective on Mat
10001 
10002    Input Parameters:
10003 +  A - the left matrix
10004 .  B - the right matrix
10005 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10006 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
10007 
10008    Output Parameters:
10009 .  C - the product matrix
10010 
10011    Notes:
10012    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
10013 
10014    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
10015 
10016   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
10017    actually needed.
10018 
10019    This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
10020    which inherit from SeqAIJ.  C will be of same type as the input matrices.
10021 
10022    Level: intermediate
10023 
10024 .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
10025 @*/
10026 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
10027 {
10028   PetscErrorCode ierr;
10029   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
10030   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
10031   PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL;
10032 
10033   PetscFunctionBegin;
10034   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
10035   PetscValidType(A,1);
10036   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10037   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10038   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10039   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
10040   PetscValidType(B,2);
10041   MatCheckPreallocated(B,2);
10042   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10043   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10044   PetscValidPointer(C,3);
10045   if (B->rmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->rmap->N);
10046   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
10047   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
10048   MatCheckPreallocated(A,1);
10049 
10050   fA = A->ops->transposematmult;
10051   fB = B->ops->transposematmult;
10052   if (fB==fA) {
10053     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
10054     transposematmult = fA;
10055   } else {
10056     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
10057     char multname[256];
10058     ierr = PetscStrncpy(multname,"MatTransposeMatMult_",sizeof(multname));CHKERRQ(ierr);
10059     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
10060     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
10061     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
10062     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
10063     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);CHKERRQ(ierr);
10064     if (!transposematmult) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatTransposeMatMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
10065   }
10066   ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
10067   ierr = (*transposematmult)(A,B,scall,fill,C);CHKERRQ(ierr);
10068   ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
10069   PetscFunctionReturn(0);
10070 }
10071 
10072 /*@
10073    MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.
10074 
10075    Neighbor-wise Collective on Mat
10076 
10077    Input Parameters:
10078 +  A - the left matrix
10079 .  B - the middle matrix
10080 .  C - the right matrix
10081 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10082 -  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
10083           if the result is a dense matrix this is irrelevent
10084 
10085    Output Parameters:
10086 .  D - the product matrix
10087 
10088    Notes:
10089    Unless scall is MAT_REUSE_MATRIX D will be created.
10090 
10091    MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call
10092 
10093    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
10094    actually needed.
10095 
10096    If you have many matrices with the same non-zero structure to multiply, you
10097    should use MAT_REUSE_MATRIX in all calls but the first or
10098 
10099    Level: intermediate
10100 
10101 .seealso: MatMatMult, MatPtAP()
10102 @*/
10103 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
10104 {
10105   PetscErrorCode ierr;
10106   PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
10107   PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
10108   PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
10109   PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
10110 
10111   PetscFunctionBegin;
10112   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
10113   PetscValidType(A,1);
10114   MatCheckPreallocated(A,1);
10115   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10116   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10117   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10118   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
10119   PetscValidType(B,2);
10120   MatCheckPreallocated(B,2);
10121   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10122   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10123   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
10124   PetscValidPointer(C,3);
10125   MatCheckPreallocated(C,3);
10126   if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10127   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10128   if (B->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
10129   if (C->rmap->N!=B->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",C->rmap->N,B->cmap->N);
10130   if (scall == MAT_REUSE_MATRIX) {
10131     PetscValidPointer(*D,6);
10132     PetscValidHeaderSpecific(*D,MAT_CLASSID,6);
10133     ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10134     ierr = (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
10135     ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10136     PetscFunctionReturn(0);
10137   }
10138   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
10139   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
10140 
10141   fA = A->ops->matmatmult;
10142   fB = B->ops->matmatmult;
10143   fC = C->ops->matmatmult;
10144   if (fA == fB && fA == fC) {
10145     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name);
10146     mult = fA;
10147   } else {
10148     /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */
10149     char multname[256];
10150     ierr = PetscStrncpy(multname,"MatMatMatMult_",sizeof(multname));CHKERRQ(ierr);
10151     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
10152     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
10153     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
10154     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
10155     ierr = PetscStrlcat(multname,((PetscObject)C)->type_name,sizeof(multname));CHKERRQ(ierr);
10156     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr);
10157     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
10158     if (!mult) SETERRQ3(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatMatMult requires A, %s, to be compatible with B, %s, C, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name,((PetscObject)C)->type_name);
10159   }
10160   ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10161   ierr = (*mult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
10162   ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10163   PetscFunctionReturn(0);
10164 }
10165 
10166 /*@
10167    MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
10168 
10169    Collective on Mat
10170 
10171    Input Parameters:
10172 +  mat - the matrix
10173 .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
10174 .  subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used)
10175 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10176 
10177    Output Parameter:
10178 .  matredundant - redundant matrix
10179 
10180    Notes:
10181    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
10182    original matrix has not changed from that last call to MatCreateRedundantMatrix().
10183 
10184    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
10185    calling it.
10186 
10187    Level: advanced
10188 
10189    Concepts: subcommunicator
10190    Concepts: duplicate matrix
10191 
10192 .seealso: MatDestroy()
10193 @*/
10194 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant)
10195 {
10196   PetscErrorCode ierr;
10197   MPI_Comm       comm;
10198   PetscMPIInt    size;
10199   PetscInt       mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs;
10200   Mat_Redundant  *redund=NULL;
10201   PetscSubcomm   psubcomm=NULL;
10202   MPI_Comm       subcomm_in=subcomm;
10203   Mat            *matseq;
10204   IS             isrow,iscol;
10205   PetscBool      newsubcomm=PETSC_FALSE;
10206 
10207   PetscFunctionBegin;
10208   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10209   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
10210     PetscValidPointer(*matredundant,5);
10211     PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5);
10212   }
10213 
10214   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
10215   if (size == 1 || nsubcomm == 1) {
10216     if (reuse == MAT_INITIAL_MATRIX) {
10217       ierr = MatDuplicate(mat,MAT_COPY_VALUES,matredundant);CHKERRQ(ierr);
10218     } else {
10219       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");
10220       ierr = MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
10221     }
10222     PetscFunctionReturn(0);
10223   }
10224 
10225   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10226   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10227   MatCheckPreallocated(mat,1);
10228 
10229   ierr = PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
10230   if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */
10231     /* create psubcomm, then get subcomm */
10232     ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
10233     ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
10234     if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size);
10235 
10236     ierr = PetscSubcommCreate(comm,&psubcomm);CHKERRQ(ierr);
10237     ierr = PetscSubcommSetNumber(psubcomm,nsubcomm);CHKERRQ(ierr);
10238     ierr = PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);CHKERRQ(ierr);
10239     ierr = PetscSubcommSetFromOptions(psubcomm);CHKERRQ(ierr);
10240     ierr = PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);CHKERRQ(ierr);
10241     newsubcomm = PETSC_TRUE;
10242     ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr);
10243   }
10244 
10245   /* get isrow, iscol and a local sequential matrix matseq[0] */
10246   if (reuse == MAT_INITIAL_MATRIX) {
10247     mloc_sub = PETSC_DECIDE;
10248     nloc_sub = PETSC_DECIDE;
10249     if (bs < 1) {
10250       ierr = PetscSplitOwnership(subcomm,&mloc_sub,&M);CHKERRQ(ierr);
10251       ierr = PetscSplitOwnership(subcomm,&nloc_sub,&N);CHKERRQ(ierr);
10252     } else {
10253       ierr = PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);CHKERRQ(ierr);
10254       ierr = PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N);CHKERRQ(ierr);
10255     }
10256     ierr = MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);CHKERRQ(ierr);
10257     rstart = rend - mloc_sub;
10258     ierr = ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);CHKERRQ(ierr);
10259     ierr = ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);CHKERRQ(ierr);
10260   } else { /* reuse == MAT_REUSE_MATRIX */
10261     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");
10262     /* retrieve subcomm */
10263     ierr = PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);CHKERRQ(ierr);
10264     redund = (*matredundant)->redundant;
10265     isrow  = redund->isrow;
10266     iscol  = redund->iscol;
10267     matseq = redund->matseq;
10268   }
10269   ierr = MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);CHKERRQ(ierr);
10270 
10271   /* get matredundant over subcomm */
10272   if (reuse == MAT_INITIAL_MATRIX) {
10273     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant);CHKERRQ(ierr);
10274 
10275     /* create a supporting struct and attach it to C for reuse */
10276     ierr = PetscNewLog(*matredundant,&redund);CHKERRQ(ierr);
10277     (*matredundant)->redundant = redund;
10278     redund->isrow              = isrow;
10279     redund->iscol              = iscol;
10280     redund->matseq             = matseq;
10281     if (newsubcomm) {
10282       redund->subcomm          = subcomm;
10283     } else {
10284       redund->subcomm          = MPI_COMM_NULL;
10285     }
10286   } else {
10287     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);CHKERRQ(ierr);
10288   }
10289   ierr = PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
10290   PetscFunctionReturn(0);
10291 }
10292 
10293 /*@C
10294    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
10295    a given 'mat' object. Each submatrix can span multiple procs.
10296 
10297    Collective on Mat
10298 
10299    Input Parameters:
10300 +  mat - the matrix
10301 .  subcomm - the subcommunicator obtained by com_split(comm)
10302 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10303 
10304    Output Parameter:
10305 .  subMat - 'parallel submatrices each spans a given subcomm
10306 
10307   Notes:
10308   The submatrix partition across processors is dictated by 'subComm' a
10309   communicator obtained by com_split(comm). The comm_split
10310   is not restriced to be grouped with consecutive original ranks.
10311 
10312   Due the comm_split() usage, the parallel layout of the submatrices
10313   map directly to the layout of the original matrix [wrt the local
10314   row,col partitioning]. So the original 'DiagonalMat' naturally maps
10315   into the 'DiagonalMat' of the subMat, hence it is used directly from
10316   the subMat. However the offDiagMat looses some columns - and this is
10317   reconstructed with MatSetValues()
10318 
10319   Level: advanced
10320 
10321   Concepts: subcommunicator
10322   Concepts: submatrices
10323 
10324 .seealso: MatCreateSubMatrices()
10325 @*/
10326 PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
10327 {
10328   PetscErrorCode ierr;
10329   PetscMPIInt    commsize,subCommSize;
10330 
10331   PetscFunctionBegin;
10332   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRQ(ierr);
10333   ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr);
10334   if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
10335 
10336   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");
10337   ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10338   ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr);
10339   ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10340   PetscFunctionReturn(0);
10341 }
10342 
10343 /*@
10344    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
10345 
10346    Not Collective
10347 
10348    Input Arguments:
10349    mat - matrix to extract local submatrix from
10350    isrow - local row indices for submatrix
10351    iscol - local column indices for submatrix
10352 
10353    Output Arguments:
10354    submat - the submatrix
10355 
10356    Level: intermediate
10357 
10358    Notes:
10359    The submat should be returned with MatRestoreLocalSubMatrix().
10360 
10361    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
10362    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
10363 
10364    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
10365    MatSetValuesBlockedLocal() will also be implemented.
10366 
10367    The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that
10368    matrices obtained with DMCreateMatrix() generally already have the local to global mapping provided.
10369 
10370 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping()
10371 @*/
10372 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10373 {
10374   PetscErrorCode ierr;
10375 
10376   PetscFunctionBegin;
10377   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10378   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10379   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10380   PetscCheckSameComm(isrow,2,iscol,3);
10381   PetscValidPointer(submat,4);
10382   if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call");
10383 
10384   if (mat->ops->getlocalsubmatrix) {
10385     ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10386   } else {
10387     ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr);
10388   }
10389   PetscFunctionReturn(0);
10390 }
10391 
10392 /*@
10393    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
10394 
10395    Not Collective
10396 
10397    Input Arguments:
10398    mat - matrix to extract local submatrix from
10399    isrow - local row indices for submatrix
10400    iscol - local column indices for submatrix
10401    submat - the submatrix
10402 
10403    Level: intermediate
10404 
10405 .seealso: MatGetLocalSubMatrix()
10406 @*/
10407 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10408 {
10409   PetscErrorCode ierr;
10410 
10411   PetscFunctionBegin;
10412   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10413   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10414   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10415   PetscCheckSameComm(isrow,2,iscol,3);
10416   PetscValidPointer(submat,4);
10417   if (*submat) {
10418     PetscValidHeaderSpecific(*submat,MAT_CLASSID,4);
10419   }
10420 
10421   if (mat->ops->restorelocalsubmatrix) {
10422     ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10423   } else {
10424     ierr = MatDestroy(submat);CHKERRQ(ierr);
10425   }
10426   *submat = NULL;
10427   PetscFunctionReturn(0);
10428 }
10429 
10430 /* --------------------------------------------------------*/
10431 /*@
10432    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix
10433 
10434    Collective on Mat
10435 
10436    Input Parameter:
10437 .  mat - the matrix
10438 
10439    Output Parameter:
10440 .  is - if any rows have zero diagonals this contains the list of them
10441 
10442    Level: developer
10443 
10444    Concepts: matrix-vector product
10445 
10446 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10447 @*/
10448 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is)
10449 {
10450   PetscErrorCode ierr;
10451 
10452   PetscFunctionBegin;
10453   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10454   PetscValidType(mat,1);
10455   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10456   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10457 
10458   if (!mat->ops->findzerodiagonals) {
10459     Vec                diag;
10460     const PetscScalar *a;
10461     PetscInt          *rows;
10462     PetscInt           rStart, rEnd, r, nrow = 0;
10463 
10464     ierr = MatCreateVecs(mat, &diag, NULL);CHKERRQ(ierr);
10465     ierr = MatGetDiagonal(mat, diag);CHKERRQ(ierr);
10466     ierr = MatGetOwnershipRange(mat, &rStart, &rEnd);CHKERRQ(ierr);
10467     ierr = VecGetArrayRead(diag, &a);CHKERRQ(ierr);
10468     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow;
10469     ierr = PetscMalloc1(nrow, &rows);CHKERRQ(ierr);
10470     nrow = 0;
10471     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart;
10472     ierr = VecRestoreArrayRead(diag, &a);CHKERRQ(ierr);
10473     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10474     ierr = ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);CHKERRQ(ierr);
10475   } else {
10476     ierr = (*mat->ops->findzerodiagonals)(mat, is);CHKERRQ(ierr);
10477   }
10478   PetscFunctionReturn(0);
10479 }
10480 
10481 /*@
10482    MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size)
10483 
10484    Collective on Mat
10485 
10486    Input Parameter:
10487 .  mat - the matrix
10488 
10489    Output Parameter:
10490 .  is - contains the list of rows with off block diagonal entries
10491 
10492    Level: developer
10493 
10494    Concepts: matrix-vector product
10495 
10496 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10497 @*/
10498 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is)
10499 {
10500   PetscErrorCode ierr;
10501 
10502   PetscFunctionBegin;
10503   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10504   PetscValidType(mat,1);
10505   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10506   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10507 
10508   if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined");
10509   ierr = (*mat->ops->findoffblockdiagonalentries)(mat,is);CHKERRQ(ierr);
10510   PetscFunctionReturn(0);
10511 }
10512 
10513 /*@C
10514   MatInvertBlockDiagonal - Inverts the block diagonal entries.
10515 
10516   Collective on Mat
10517 
10518   Input Parameters:
10519 . mat - the matrix
10520 
10521   Output Parameters:
10522 . values - the block inverses in column major order (FORTRAN-like)
10523 
10524    Note:
10525    This routine is not available from Fortran.
10526 
10527   Level: advanced
10528 
10529 .seealso: MatInvertBockDiagonalMat
10530 @*/
10531 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
10532 {
10533   PetscErrorCode ierr;
10534 
10535   PetscFunctionBegin;
10536   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10537   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10538   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10539   if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
10540   ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr);
10541   PetscFunctionReturn(0);
10542 }
10543 
10544 /*@C
10545   MatInvertVariableBlockDiagonal - Inverts the block diagonal entries.
10546 
10547   Collective on Mat
10548 
10549   Input Parameters:
10550 + mat - the matrix
10551 . nblocks - the number of blocks
10552 - bsizes - the size of each block
10553 
10554   Output Parameters:
10555 . values - the block inverses in column major order (FORTRAN-like)
10556 
10557    Note:
10558    This routine is not available from Fortran.
10559 
10560   Level: advanced
10561 
10562 .seealso: MatInvertBockDiagonal()
10563 @*/
10564 PetscErrorCode MatInvertVariableBlockDiagonal(Mat mat,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *values)
10565 {
10566   PetscErrorCode ierr;
10567 
10568   PetscFunctionBegin;
10569   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10570   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10571   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10572   if (!mat->ops->invertvariableblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
10573   ierr = (*mat->ops->invertvariableblockdiagonal)(mat,nblocks,bsizes,values);CHKERRQ(ierr);
10574   PetscFunctionReturn(0);
10575 }
10576 
10577 /*@
10578   MatInvertBlockDiagonalMat - set matrix C to be the inverted block diagonal of matrix A
10579 
10580   Collective on Mat
10581 
10582   Input Parameters:
10583 . A - the matrix
10584 
10585   Output Parameters:
10586 . C - matrix with inverted block diagonal of A.  This matrix should be created and may have its type set.
10587 
10588   Notes: the blocksize of the matrix is used to determine the blocks on the diagonal of C
10589 
10590   Level: advanced
10591 
10592 .seealso: MatInvertBockDiagonal()
10593 @*/
10594 PetscErrorCode MatInvertBlockDiagonalMat(Mat A,Mat C)
10595 {
10596   PetscErrorCode     ierr;
10597   const PetscScalar *vals;
10598   PetscInt          *dnnz;
10599   PetscInt           M,N,m,n,rstart,rend,bs,i,j;
10600 
10601   PetscFunctionBegin;
10602   ierr = MatInvertBlockDiagonal(A,&vals);CHKERRQ(ierr);
10603   ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr);
10604   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
10605   ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr);
10606   ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr);
10607   ierr = MatSetBlockSize(C,bs);CHKERRQ(ierr);
10608   ierr = PetscMalloc1(m/bs,&dnnz);CHKERRQ(ierr);
10609   for (j = 0; j < m/bs; j++) dnnz[j] = 1;
10610   ierr = MatXAIJSetPreallocation(C,bs,dnnz,NULL,NULL,NULL);CHKERRQ(ierr);
10611   ierr = PetscFree(dnnz);CHKERRQ(ierr);
10612   ierr = MatGetOwnershipRange(C,&rstart,&rend);CHKERRQ(ierr);
10613   ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr);
10614   for (i = rstart/bs; i < rend/bs; i++) {
10615     ierr = MatSetValuesBlocked(C,1,&i,1,&i,&vals[(i-rstart/bs)*bs*bs],INSERT_VALUES);CHKERRQ(ierr);
10616   }
10617   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10618   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10619   ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr);
10620   PetscFunctionReturn(0);
10621 }
10622 
10623 /*@C
10624     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
10625     via MatTransposeColoringCreate().
10626 
10627     Collective on MatTransposeColoring
10628 
10629     Input Parameter:
10630 .   c - coloring context
10631 
10632     Level: intermediate
10633 
10634 .seealso: MatTransposeColoringCreate()
10635 @*/
10636 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c)
10637 {
10638   PetscErrorCode       ierr;
10639   MatTransposeColoring matcolor=*c;
10640 
10641   PetscFunctionBegin;
10642   if (!matcolor) PetscFunctionReturn(0);
10643   if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; PetscFunctionReturn(0);}
10644 
10645   ierr = PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);CHKERRQ(ierr);
10646   ierr = PetscFree(matcolor->rows);CHKERRQ(ierr);
10647   ierr = PetscFree(matcolor->den2sp);CHKERRQ(ierr);
10648   ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr);
10649   ierr = PetscFree(matcolor->columns);CHKERRQ(ierr);
10650   if (matcolor->brows>0) {
10651     ierr = PetscFree(matcolor->lstart);CHKERRQ(ierr);
10652   }
10653   ierr = PetscHeaderDestroy(c);CHKERRQ(ierr);
10654   PetscFunctionReturn(0);
10655 }
10656 
10657 /*@C
10658     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
10659     a MatTransposeColoring context has been created, computes a dense B^T by Apply
10660     MatTransposeColoring to sparse B.
10661 
10662     Collective on MatTransposeColoring
10663 
10664     Input Parameters:
10665 +   B - sparse matrix B
10666 .   Btdense - symbolic dense matrix B^T
10667 -   coloring - coloring context created with MatTransposeColoringCreate()
10668 
10669     Output Parameter:
10670 .   Btdense - dense matrix B^T
10671 
10672     Level: advanced
10673 
10674      Notes:
10675     These are used internally for some implementations of MatRARt()
10676 
10677 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplyDenToSp()
10678 
10679 .keywords: coloring
10680 @*/
10681 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
10682 {
10683   PetscErrorCode ierr;
10684 
10685   PetscFunctionBegin;
10686   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
10687   PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2);
10688   PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3);
10689 
10690   if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
10691   ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr);
10692   PetscFunctionReturn(0);
10693 }
10694 
10695 /*@C
10696     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
10697     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
10698     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
10699     Csp from Cden.
10700 
10701     Collective on MatTransposeColoring
10702 
10703     Input Parameters:
10704 +   coloring - coloring context created with MatTransposeColoringCreate()
10705 -   Cden - matrix product of a sparse matrix and a dense matrix Btdense
10706 
10707     Output Parameter:
10708 .   Csp - sparse matrix
10709 
10710     Level: advanced
10711 
10712      Notes:
10713     These are used internally for some implementations of MatRARt()
10714 
10715 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()
10716 
10717 .keywords: coloring
10718 @*/
10719 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
10720 {
10721   PetscErrorCode ierr;
10722 
10723   PetscFunctionBegin;
10724   PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1);
10725   PetscValidHeaderSpecific(Cden,MAT_CLASSID,2);
10726   PetscValidHeaderSpecific(Csp,MAT_CLASSID,3);
10727 
10728   if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
10729   ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr);
10730   PetscFunctionReturn(0);
10731 }
10732 
10733 /*@C
10734    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.
10735 
10736    Collective on Mat
10737 
10738    Input Parameters:
10739 +  mat - the matrix product C
10740 -  iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring()
10741 
10742     Output Parameter:
10743 .   color - the new coloring context
10744 
10745     Level: intermediate
10746 
10747 .seealso: MatTransposeColoringDestroy(),  MatTransColoringApplySpToDen(),
10748            MatTransColoringApplyDenToSp()
10749 @*/
10750 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
10751 {
10752   MatTransposeColoring c;
10753   MPI_Comm             comm;
10754   PetscErrorCode       ierr;
10755 
10756   PetscFunctionBegin;
10757   ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10758   ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
10759   ierr = PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);CHKERRQ(ierr);
10760 
10761   c->ctype = iscoloring->ctype;
10762   if (mat->ops->transposecoloringcreate) {
10763     ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr);
10764   } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type");
10765 
10766   *color = c;
10767   ierr   = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10768   PetscFunctionReturn(0);
10769 }
10770 
10771 /*@
10772       MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the
10773         matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the
10774         same, otherwise it will be larger
10775 
10776      Not Collective
10777 
10778   Input Parameter:
10779 .    A  - the matrix
10780 
10781   Output Parameter:
10782 .    state - the current state
10783 
10784   Notes:
10785     You can only compare states from two different calls to the SAME matrix, you cannot compare calls between
10786          different matrices
10787 
10788   Level: intermediate
10789 
10790 @*/
10791 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state)
10792 {
10793   PetscFunctionBegin;
10794   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10795   *state = mat->nonzerostate;
10796   PetscFunctionReturn(0);
10797 }
10798 
10799 /*@
10800       MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential
10801                  matrices from each processor
10802 
10803     Collective on MPI_Comm
10804 
10805    Input Parameters:
10806 +    comm - the communicators the parallel matrix will live on
10807 .    seqmat - the input sequential matrices
10808 .    n - number of local columns (or PETSC_DECIDE)
10809 -    reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10810 
10811    Output Parameter:
10812 .    mpimat - the parallel matrix generated
10813 
10814     Level: advanced
10815 
10816    Notes:
10817     The number of columns of the matrix in EACH processor MUST be the same.
10818 
10819 @*/
10820 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat)
10821 {
10822   PetscErrorCode ierr;
10823 
10824   PetscFunctionBegin;
10825   if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name);
10826   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");
10827 
10828   ierr = PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10829   ierr = (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);CHKERRQ(ierr);
10830   ierr = PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10831   PetscFunctionReturn(0);
10832 }
10833 
10834 /*@
10835      MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent
10836                  ranks' ownership ranges.
10837 
10838     Collective on A
10839 
10840    Input Parameters:
10841 +    A   - the matrix to create subdomains from
10842 -    N   - requested number of subdomains
10843 
10844 
10845    Output Parameters:
10846 +    n   - number of subdomains resulting on this rank
10847 -    iss - IS list with indices of subdomains on this rank
10848 
10849     Level: advanced
10850 
10851     Notes:
10852     number of subdomains must be smaller than the communicator size
10853 @*/
10854 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[])
10855 {
10856   MPI_Comm        comm,subcomm;
10857   PetscMPIInt     size,rank,color;
10858   PetscInt        rstart,rend,k;
10859   PetscErrorCode  ierr;
10860 
10861   PetscFunctionBegin;
10862   ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr);
10863   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
10864   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
10865   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);
10866   *n = 1;
10867   k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */
10868   color = rank/k;
10869   ierr = MPI_Comm_split(comm,color,rank,&subcomm);CHKERRQ(ierr);
10870   ierr = PetscMalloc1(1,iss);CHKERRQ(ierr);
10871   ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
10872   ierr = ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);CHKERRQ(ierr);
10873   ierr = MPI_Comm_free(&subcomm);CHKERRQ(ierr);
10874   PetscFunctionReturn(0);
10875 }
10876 
10877 /*@
10878    MatGalerkin - Constructs the coarse grid problem via Galerkin projection.
10879 
10880    If the interpolation and restriction operators are the same, uses MatPtAP.
10881    If they are not the same, use MatMatMatMult.
10882 
10883    Once the coarse grid problem is constructed, correct for interpolation operators
10884    that are not of full rank, which can legitimately happen in the case of non-nested
10885    geometric multigrid.
10886 
10887    Input Parameters:
10888 +  restrct - restriction operator
10889 .  dA - fine grid matrix
10890 .  interpolate - interpolation operator
10891 .  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10892 -  fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate
10893 
10894    Output Parameters:
10895 .  A - the Galerkin coarse matrix
10896 
10897    Options Database Key:
10898 .  -pc_mg_galerkin <both,pmat,mat,none>
10899 
10900    Level: developer
10901 
10902 .keywords: MG, multigrid, Galerkin
10903 
10904 .seealso: MatPtAP(), MatMatMatMult()
10905 @*/
10906 PetscErrorCode  MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A)
10907 {
10908   PetscErrorCode ierr;
10909   IS             zerorows;
10910   Vec            diag;
10911 
10912   PetscFunctionBegin;
10913   if (reuse == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10914   /* Construct the coarse grid matrix */
10915   if (interpolate == restrct) {
10916     ierr = MatPtAP(dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10917   } else {
10918     ierr = MatMatMatMult(restrct,dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10919   }
10920 
10921   /* If the interpolation matrix is not of full rank, A will have zero rows.
10922      This can legitimately happen in the case of non-nested geometric multigrid.
10923      In that event, we set the rows of the matrix to the rows of the identity,
10924      ignoring the equations (as the RHS will also be zero). */
10925 
10926   ierr = MatFindZeroRows(*A, &zerorows);CHKERRQ(ierr);
10927 
10928   if (zerorows != NULL) { /* if there are any zero rows */
10929     ierr = MatCreateVecs(*A, &diag, NULL);CHKERRQ(ierr);
10930     ierr = MatGetDiagonal(*A, diag);CHKERRQ(ierr);
10931     ierr = VecISSet(diag, zerorows, 1.0);CHKERRQ(ierr);
10932     ierr = MatDiagonalSet(*A, diag, INSERT_VALUES);CHKERRQ(ierr);
10933     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10934     ierr = ISDestroy(&zerorows);CHKERRQ(ierr);
10935   }
10936   PetscFunctionReturn(0);
10937 }
10938 
10939 /*@C
10940     MatSetOperation - Allows user to set a matrix operation for any matrix type
10941 
10942    Logically Collective on Mat
10943 
10944     Input Parameters:
10945 +   mat - the matrix
10946 .   op - the name of the operation
10947 -   f - the function that provides the operation
10948 
10949    Level: developer
10950 
10951     Usage:
10952 $      extern PetscErrorCode usermult(Mat,Vec,Vec);
10953 $      ierr = MatCreateXXX(comm,...&A);
10954 $      ierr = MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult);
10955 
10956     Notes:
10957     See the file include/petscmat.h for a complete list of matrix
10958     operations, which all have the form MATOP_<OPERATION>, where
10959     <OPERATION> is the name (in all capital letters) of the
10960     user interface routine (e.g., MatMult() -> MATOP_MULT).
10961 
10962     All user-provided functions (except for MATOP_DESTROY) should have the same calling
10963     sequence as the usual matrix interface routines, since they
10964     are intended to be accessed via the usual matrix interface
10965     routines, e.g.,
10966 $       MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec)
10967 
10968     In particular each function MUST return an error code of 0 on success and
10969     nonzero on failure.
10970 
10971     This routine is distinct from MatShellSetOperation() in that it can be called on any matrix type.
10972 
10973 .keywords: matrix, set, operation
10974 
10975 .seealso: MatGetOperation(), MatCreateShell(), MatShellSetContext(), MatShellSetOperation()
10976 @*/
10977 PetscErrorCode MatSetOperation(Mat mat,MatOperation op,void (*f)(void))
10978 {
10979   PetscFunctionBegin;
10980   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10981   if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) {
10982     mat->ops->viewnative = mat->ops->view;
10983   }
10984   (((void(**)(void))mat->ops)[op]) = f;
10985   PetscFunctionReturn(0);
10986 }
10987 
10988 /*@C
10989     MatGetOperation - Gets a matrix operation for any matrix type.
10990 
10991     Not Collective
10992 
10993     Input Parameters:
10994 +   mat - the matrix
10995 -   op - the name of the operation
10996 
10997     Output Parameter:
10998 .   f - the function that provides the operation
10999 
11000     Level: developer
11001 
11002     Usage:
11003 $      PetscErrorCode (*usermult)(Mat,Vec,Vec);
11004 $      ierr = MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult);
11005 
11006     Notes:
11007     See the file include/petscmat.h for a complete list of matrix
11008     operations, which all have the form MATOP_<OPERATION>, where
11009     <OPERATION> is the name (in all capital letters) of the
11010     user interface routine (e.g., MatMult() -> MATOP_MULT).
11011 
11012     This routine is distinct from MatShellGetOperation() in that it can be called on any matrix type.
11013 
11014 .keywords: matrix, get, operation
11015 
11016 .seealso: MatSetOperation(), MatCreateShell(), MatShellGetContext(), MatShellGetOperation()
11017 @*/
11018 PetscErrorCode MatGetOperation(Mat mat,MatOperation op,void(**f)(void))
11019 {
11020   PetscFunctionBegin;
11021   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
11022   *f = (((void (**)(void))mat->ops)[op]);
11023   PetscFunctionReturn(0);
11024 }
11025 
11026 /*@
11027     MatHasOperation - Determines whether the given matrix supports the particular
11028     operation.
11029 
11030    Not Collective
11031 
11032    Input Parameters:
11033 +  mat - the matrix
11034 -  op - the operation, for example, MATOP_GET_DIAGONAL
11035 
11036    Output Parameter:
11037 .  has - either PETSC_TRUE or PETSC_FALSE
11038 
11039    Level: advanced
11040 
11041    Notes:
11042    See the file include/petscmat.h for a complete list of matrix
11043    operations, which all have the form MATOP_<OPERATION>, where
11044    <OPERATION> is the name (in all capital letters) of the
11045    user-level routine.  E.g., MatNorm() -> MATOP_NORM.
11046 
11047 .keywords: matrix, has, operation
11048 
11049 .seealso: MatCreateShell()
11050 @*/
11051 PetscErrorCode MatHasOperation(Mat mat,MatOperation op,PetscBool *has)
11052 {
11053   PetscErrorCode ierr;
11054 
11055   PetscFunctionBegin;
11056   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
11057   PetscValidType(mat,1);
11058   PetscValidPointer(has,3);
11059   if (mat->ops->hasoperation) {
11060     ierr = (*mat->ops->hasoperation)(mat,op,has);CHKERRQ(ierr);
11061   } else {
11062     if (((void**)mat->ops)[op]) *has =  PETSC_TRUE;
11063     else {
11064       *has = PETSC_FALSE;
11065       if (op == MATOP_CREATE_SUBMATRIX) {
11066         PetscMPIInt size;
11067 
11068         ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
11069         if (size == 1) {
11070           ierr = MatHasOperation(mat,MATOP_CREATE_SUBMATRICES,has);CHKERRQ(ierr);
11071         }
11072       }
11073     }
11074   }
11075   PetscFunctionReturn(0);
11076 }
11077 
11078 /*@
11079     MatHasCongruentLayouts - Determines whether the rows and columns layouts
11080     of the matrix are congruent
11081 
11082    Collective on mat
11083 
11084    Input Parameters:
11085 .  mat - the matrix
11086 
11087    Output Parameter:
11088 .  cong - either PETSC_TRUE or PETSC_FALSE
11089 
11090    Level: beginner
11091 
11092    Notes:
11093 
11094 .keywords: matrix, has
11095 
11096 .seealso: MatCreate(), MatSetSizes()
11097 @*/
11098 PetscErrorCode MatHasCongruentLayouts(Mat mat,PetscBool *cong)
11099 {
11100   PetscErrorCode ierr;
11101 
11102   PetscFunctionBegin;
11103   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
11104   PetscValidType(mat,1);
11105   PetscValidPointer(cong,2);
11106   if (!mat->rmap || !mat->cmap) {
11107     *cong = mat->rmap == mat->cmap ? PETSC_TRUE : PETSC_FALSE;
11108     PetscFunctionReturn(0);
11109   }
11110   if (mat->congruentlayouts == PETSC_DECIDE) { /* first time we compare rows and cols layouts */
11111     ierr = PetscLayoutCompare(mat->rmap,mat->cmap,cong);CHKERRQ(ierr);
11112     if (*cong) mat->congruentlayouts = 1;
11113     else       mat->congruentlayouts = 0;
11114   } else *cong = mat->congruentlayouts ? PETSC_TRUE : PETSC_FALSE;
11115   PetscFunctionReturn(0);
11116 }
11117 
11118 /*@
11119     MatFreeIntermediateDataStructures - Free intermediate data structures created for reuse,
11120     e.g., matrx product of MatPtAP.
11121 
11122    Collective on mat
11123 
11124    Input Parameters:
11125 .  mat - the matrix
11126 
11127    Output Parameter:
11128 .  mat - the matrix with intermediate data structures released
11129 
11130    Level: advanced
11131 
11132    Notes:
11133 
11134 .keywords: matrix
11135 
11136 .seealso: MatPtAP(), MatMatMult()
11137 @*/
11138 PetscErrorCode MatFreeIntermediateDataStructures(Mat mat)
11139 {
11140   PetscErrorCode ierr;
11141 
11142   PetscFunctionBegin;
11143   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
11144   PetscValidType(mat,1);
11145   if (mat->ops->freeintermediatedatastructures) {
11146     ierr = (*mat->ops->freeintermediatedatastructures)(mat);CHKERRQ(ierr);
11147   }
11148   PetscFunctionReturn(0);
11149 }
11150