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