xref: /petsc/src/mat/interface/matrix.c (revision 07acc2aeea7a273014b10cda4fb272aa3ba8a1b1)
1 
2 /*
3    This is where the abstract matrix operations are defined
4 */
5 
6 #include <petsc/private/matimpl.h>        /*I "petscmat.h" I*/
7 #include <petsc/private/isimpl.h>
8 #include <petsc/private/vecimpl.h>
9 
10 /* Logging support */
11 PetscClassId MAT_CLASSID;
12 PetscClassId MAT_COLORING_CLASSID;
13 PetscClassId MAT_FDCOLORING_CLASSID;
14 PetscClassId MAT_TRANSPOSECOLORING_CLASSID;
15 
16 PetscLogEvent MAT_Mult, MAT_Mults, MAT_MultConstrained, MAT_MultAdd, MAT_MultTranspose;
17 PetscLogEvent MAT_MultTransposeConstrained, MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve,MAT_MatTrSolve;
18 PetscLogEvent MAT_SolveTransposeAdd, MAT_SOR, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic;
19 PetscLogEvent MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor;
20 PetscLogEvent MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin;
21 PetscLogEvent MAT_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetRowIJ, MAT_CreateSubMats, MAT_GetOrdering, MAT_RedundantMat, MAT_GetSeqNonzeroStructure;
22 PetscLogEvent MAT_IncreaseOverlap, MAT_Partitioning, MAT_PartitioningND, MAT_Coarsen, MAT_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate;
23 PetscLogEvent MAT_FDColoringSetUp, MAT_FDColoringApply,MAT_Transpose,MAT_FDColoringFunction, MAT_CreateSubMat;
24 PetscLogEvent MAT_TransposeColoringCreate;
25 PetscLogEvent MAT_MatMult, MAT_MatMultSymbolic, MAT_MatMultNumeric;
26 PetscLogEvent MAT_PtAP, MAT_PtAPSymbolic, MAT_PtAPNumeric,MAT_RARt, MAT_RARtSymbolic, MAT_RARtNumeric;
27 PetscLogEvent MAT_MatTransposeMult, MAT_MatTransposeMultSymbolic, MAT_MatTransposeMultNumeric;
28 PetscLogEvent MAT_TransposeMatMult, MAT_TransposeMatMultSymbolic, MAT_TransposeMatMultNumeric;
29 PetscLogEvent MAT_MatMatMult, MAT_MatMatMultSymbolic, MAT_MatMatMultNumeric;
30 PetscLogEvent MAT_MultHermitianTranspose,MAT_MultHermitianTransposeAdd;
31 PetscLogEvent MAT_Getsymtranspose, MAT_Getsymtransreduced, MAT_Transpose_SeqAIJ, MAT_GetBrowsOfAcols;
32 PetscLogEvent MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym;
33 PetscLogEvent MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure;
34 PetscLogEvent MAT_GetMultiProcBlock;
35 PetscLogEvent MAT_CUSPARSECopyToGPU, MAT_SetValuesBatch;
36 PetscLogEvent MAT_ViennaCLCopyToGPU;
37 PetscLogEvent MAT_Merge,MAT_Residual,MAT_SetRandom;
38 PetscLogEvent MATCOLORING_Apply,MATCOLORING_Comm,MATCOLORING_Local,MATCOLORING_ISCreate,MATCOLORING_SetUp,MATCOLORING_Weights;
39 
40 const char *const MatFactorTypes[] = {"NONE","LU","CHOLESKY","ILU","ICC","ILUDT","MatFactorType","MAT_FACTOR_",0};
41 
42 /*@
43    MatSetRandom - Sets all components of a matrix to random numbers. For sparse matrices that have been preallocated it randomly selects appropriate locations
44 
45    Logically Collective on Mat
46 
47    Input Parameters:
48 +  x  - the matrix
49 -  rctx - the random number context, formed by PetscRandomCreate(), or NULL and
50           it will create one internally.
51 
52    Output Parameter:
53 .  x  - the matrix
54 
55    Example of Usage:
56 .vb
57      PetscRandomCreate(PETSC_COMM_WORLD,&rctx);
58      MatSetRandom(x,rctx);
59      PetscRandomDestroy(rctx);
60 .ve
61 
62    Level: intermediate
63 
64    Concepts: matrix^setting to random
65    Concepts: random^matrix
66 
67 .seealso: MatZeroEntries(), MatSetValues(), PetscRandomCreate(), PetscRandomDestroy()
68 @*/
69 PetscErrorCode MatSetRandom(Mat x,PetscRandom rctx)
70 {
71   PetscErrorCode ierr;
72   PetscRandom    randObj = NULL;
73 
74   PetscFunctionBegin;
75   PetscValidHeaderSpecific(x,MAT_CLASSID,1);
76   if (rctx) PetscValidHeaderSpecific(rctx,PETSC_RANDOM_CLASSID,2);
77   PetscValidType(x,1);
78 
79   if (!x->ops->setrandom) SETERRQ1(PetscObjectComm((PetscObject)x),PETSC_ERR_SUP,"Mat type %s",((PetscObject)x)->type_name);
80 
81   if (!rctx) {
82     MPI_Comm comm;
83     ierr = PetscObjectGetComm((PetscObject)x,&comm);CHKERRQ(ierr);
84     ierr = PetscRandomCreate(comm,&randObj);CHKERRQ(ierr);
85     ierr = PetscRandomSetFromOptions(randObj);CHKERRQ(ierr);
86     rctx = randObj;
87   }
88 
89   ierr = PetscLogEventBegin(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr);
90   ierr = (*x->ops->setrandom)(x,rctx);CHKERRQ(ierr);
91   ierr = PetscLogEventEnd(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr);
92 
93   ierr = MatAssemblyBegin(x, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
94   ierr = MatAssemblyEnd(x, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
95   ierr = PetscRandomDestroy(&randObj);CHKERRQ(ierr);
96   PetscFunctionReturn(0);
97 }
98 
99 /*@
100    MatFactorGetErrorZeroPivot - returns the pivot value that was determined to be zero and the row it occurred in
101 
102    Logically Collective on Mat
103 
104    Input Parameters:
105 .  mat - the factored matrix
106 
107    Output Parameter:
108 +  pivot - the pivot value computed
109 -  row - the row that the zero pivot occurred. Note that this row must be interpreted carefully due to row reorderings and which processes
110          the share the matrix
111 
112    Level: advanced
113 
114    Notes:
115     This routine does not work for factorizations done with external packages.
116    This routine should only be called if MatGetFactorError() returns a value of MAT_FACTOR_NUMERIC_ZEROPIVOT
117 
118    This can be called on non-factored matrices that come from, for example, matrices used in SOR.
119 
120 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot()
121 @*/
122 PetscErrorCode MatFactorGetErrorZeroPivot(Mat mat,PetscReal *pivot,PetscInt *row)
123 {
124   PetscFunctionBegin;
125   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
126   *pivot = mat->factorerror_zeropivot_value;
127   *row   = mat->factorerror_zeropivot_row;
128   PetscFunctionReturn(0);
129 }
130 
131 /*@
132    MatFactorGetError - gets the error code from a factorization
133 
134    Logically Collective on Mat
135 
136    Input Parameters:
137 .  mat - the factored matrix
138 
139    Output Parameter:
140 .  err  - the error code
141 
142    Level: advanced
143 
144    Notes:
145     This can be called on non-factored matrices that come from, for example, matrices used in SOR.
146 
147 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot()
148 @*/
149 PetscErrorCode MatFactorGetError(Mat mat,MatFactorError *err)
150 {
151   PetscFunctionBegin;
152   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
153   *err = mat->factorerrortype;
154   PetscFunctionReturn(0);
155 }
156 
157 /*@
158    MatFactorClearError - clears the error code in a factorization
159 
160    Logically Collective on Mat
161 
162    Input Parameter:
163 .  mat - the factored matrix
164 
165    Level: developer
166 
167    Notes:
168     This can be called on non-factored matrices that come from, for example, matrices used in SOR.
169 
170 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorGetError(), MatFactorGetErrorZeroPivot()
171 @*/
172 PetscErrorCode MatFactorClearError(Mat mat)
173 {
174   PetscFunctionBegin;
175   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
176   mat->factorerrortype             = MAT_FACTOR_NOERROR;
177   mat->factorerror_zeropivot_value = 0.0;
178   mat->factorerror_zeropivot_row   = 0;
179   PetscFunctionReturn(0);
180 }
181 
182 PETSC_INTERN PetscErrorCode MatFindNonzeroRowsOrCols_Basic(Mat mat,PetscBool cols,PetscReal tol,IS *nonzero)
183 {
184   PetscErrorCode    ierr;
185   Vec               r,l;
186   const PetscScalar *al;
187   PetscInt          i,nz,gnz,N,n;
188 
189   PetscFunctionBegin;
190   ierr = MatCreateVecs(mat,&r,&l);CHKERRQ(ierr);
191   if (!cols) { /* nonzero rows */
192     ierr = MatGetSize(mat,&N,NULL);CHKERRQ(ierr);
193     ierr = MatGetLocalSize(mat,&n,NULL);CHKERRQ(ierr);
194     ierr = VecSet(l,0.0);CHKERRQ(ierr);
195     ierr = VecSetRandom(r,NULL);CHKERRQ(ierr);
196     ierr = MatMult(mat,r,l);CHKERRQ(ierr);
197     ierr = VecGetArrayRead(l,&al);CHKERRQ(ierr);
198   } else { /* nonzero columns */
199     ierr = MatGetSize(mat,NULL,&N);CHKERRQ(ierr);
200     ierr = MatGetLocalSize(mat,NULL,&n);CHKERRQ(ierr);
201     ierr = VecSet(r,0.0);CHKERRQ(ierr);
202     ierr = VecSetRandom(l,NULL);CHKERRQ(ierr);
203     ierr = MatMultTranspose(mat,l,r);CHKERRQ(ierr);
204     ierr = VecGetArrayRead(r,&al);CHKERRQ(ierr);
205   }
206   if (tol <= 0.0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nz++; }
207   else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nz++; }
208   ierr = MPIU_Allreduce(&nz,&gnz,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr);
209   if (gnz != N) {
210     PetscInt *nzr;
211     ierr = PetscMalloc1(nz,&nzr);CHKERRQ(ierr);
212     if (nz) {
213       if (tol < 0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nzr[nz++] = i; }
214       else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nzr[nz++] = i; }
215     }
216     ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),nz,nzr,PETSC_OWN_POINTER,nonzero);CHKERRQ(ierr);
217   } else *nonzero = NULL;
218   if (!cols) { /* nonzero rows */
219     ierr = VecRestoreArrayRead(l,&al);CHKERRQ(ierr);
220   } else {
221     ierr = VecRestoreArrayRead(r,&al);CHKERRQ(ierr);
222   }
223   ierr = VecDestroy(&l);CHKERRQ(ierr);
224   ierr = VecDestroy(&r);CHKERRQ(ierr);
225   PetscFunctionReturn(0);
226 }
227 
228 /*@
229       MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix
230 
231   Input Parameter:
232 .    A  - the matrix
233 
234   Output Parameter:
235 .    keptrows - the rows that are not completely zero
236 
237   Notes:
238     keptrows is set to NULL if all rows are nonzero.
239 
240   Level: intermediate
241 
242  @*/
243 PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows)
244 {
245   PetscErrorCode ierr;
246 
247   PetscFunctionBegin;
248   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
249   PetscValidType(mat,1);
250   PetscValidPointer(keptrows,2);
251   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
252   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
253   if (!mat->ops->findnonzerorows) {
254     ierr = MatFindNonzeroRowsOrCols_Basic(mat,PETSC_FALSE,0.0,keptrows);CHKERRQ(ierr);
255   } else {
256     ierr = (*mat->ops->findnonzerorows)(mat,keptrows);CHKERRQ(ierr);
257   }
258   PetscFunctionReturn(0);
259 }
260 
261 /*@
262       MatFindZeroRows - Locate all rows that are completely zero in the matrix
263 
264   Input Parameter:
265 .    A  - the matrix
266 
267   Output Parameter:
268 .    zerorows - the rows that are completely zero
269 
270   Notes:
271     zerorows is set to NULL if no rows are zero.
272 
273   Level: intermediate
274 
275  @*/
276 PetscErrorCode MatFindZeroRows(Mat mat,IS *zerorows)
277 {
278   PetscErrorCode ierr;
279   IS keptrows;
280   PetscInt m, n;
281 
282   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
283   PetscValidType(mat,1);
284 
285   ierr = MatFindNonzeroRows(mat, &keptrows);CHKERRQ(ierr);
286   /* MatFindNonzeroRows sets keptrows to NULL if there are no zero rows.
287      In keeping with this convention, we set zerorows to NULL if there are no zero
288      rows. */
289   if (keptrows == NULL) {
290     *zerorows = NULL;
291   } else {
292     ierr = MatGetOwnershipRange(mat,&m,&n);CHKERRQ(ierr);
293     ierr = ISComplement(keptrows,m,n,zerorows);CHKERRQ(ierr);
294     ierr = ISDestroy(&keptrows);CHKERRQ(ierr);
295   }
296   PetscFunctionReturn(0);
297 }
298 
299 /*@
300    MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling
301 
302    Not Collective
303 
304    Input Parameters:
305 .   A - the matrix
306 
307    Output Parameters:
308 .   a - the diagonal part (which is a SEQUENTIAL matrix)
309 
310    Notes:
311     see the manual page for MatCreateAIJ() for more information on the "diagonal part" of the matrix.
312           Use caution, as the reference count on the returned matrix is not incremented and it is used as
313 	  part of the containing MPI Mat's normal operation.
314 
315    Level: advanced
316 
317 @*/
318 PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a)
319 {
320   PetscErrorCode ierr;
321 
322   PetscFunctionBegin;
323   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
324   PetscValidType(A,1);
325   PetscValidPointer(a,3);
326   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
327   if (!A->ops->getdiagonalblock) {
328     PetscMPIInt size;
329     ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);CHKERRQ(ierr);
330     if (size == 1) {
331       *a = A;
332       PetscFunctionReturn(0);
333     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Not coded for this matrix type");
334   }
335   ierr = (*A->ops->getdiagonalblock)(A,a);CHKERRQ(ierr);
336   PetscFunctionReturn(0);
337 }
338 
339 /*@
340    MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries.
341 
342    Collective on Mat
343 
344    Input Parameters:
345 .  mat - the matrix
346 
347    Output Parameter:
348 .   trace - the sum of the diagonal entries
349 
350    Level: advanced
351 
352 @*/
353 PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace)
354 {
355   PetscErrorCode ierr;
356   Vec            diag;
357 
358   PetscFunctionBegin;
359   ierr = MatCreateVecs(mat,&diag,NULL);CHKERRQ(ierr);
360   ierr = MatGetDiagonal(mat,diag);CHKERRQ(ierr);
361   ierr = VecSum(diag,trace);CHKERRQ(ierr);
362   ierr = VecDestroy(&diag);CHKERRQ(ierr);
363   PetscFunctionReturn(0);
364 }
365 
366 /*@
367    MatRealPart - Zeros out the imaginary part of the matrix
368 
369    Logically Collective on Mat
370 
371    Input Parameters:
372 .  mat - the matrix
373 
374    Level: advanced
375 
376 
377 .seealso: MatImaginaryPart()
378 @*/
379 PetscErrorCode MatRealPart(Mat mat)
380 {
381   PetscErrorCode ierr;
382 
383   PetscFunctionBegin;
384   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
385   PetscValidType(mat,1);
386   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
387   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
388   if (!mat->ops->realpart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
389   MatCheckPreallocated(mat,1);
390   ierr = (*mat->ops->realpart)(mat);CHKERRQ(ierr);
391 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
392   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
393     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
394   }
395 #endif
396   PetscFunctionReturn(0);
397 }
398 
399 /*@C
400    MatGetGhosts - Get the global index of all ghost nodes defined by the sparse matrix
401 
402    Collective on Mat
403 
404    Input Parameter:
405 .  mat - the matrix
406 
407    Output Parameters:
408 +   nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block)
409 -   ghosts - the global indices of the ghost points
410 
411    Notes:
412     the nghosts and ghosts are suitable to pass into VecCreateGhost()
413 
414    Level: advanced
415 
416 @*/
417 PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[])
418 {
419   PetscErrorCode ierr;
420 
421   PetscFunctionBegin;
422   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
423   PetscValidType(mat,1);
424   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
425   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
426   if (!mat->ops->getghosts) {
427     if (nghosts) *nghosts = 0;
428     if (ghosts) *ghosts = 0;
429   } else {
430     ierr = (*mat->ops->getghosts)(mat,nghosts,ghosts);CHKERRQ(ierr);
431   }
432   PetscFunctionReturn(0);
433 }
434 
435 
436 /*@
437    MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part
438 
439    Logically Collective on Mat
440 
441    Input Parameters:
442 .  mat - the matrix
443 
444    Level: advanced
445 
446 
447 .seealso: MatRealPart()
448 @*/
449 PetscErrorCode MatImaginaryPart(Mat mat)
450 {
451   PetscErrorCode ierr;
452 
453   PetscFunctionBegin;
454   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
455   PetscValidType(mat,1);
456   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
457   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
458   if (!mat->ops->imaginarypart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
459   MatCheckPreallocated(mat,1);
460   ierr = (*mat->ops->imaginarypart)(mat);CHKERRQ(ierr);
461 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
462   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
463     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
464   }
465 #endif
466   PetscFunctionReturn(0);
467 }
468 
469 /*@
470    MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices)
471 
472    Not Collective
473 
474    Input Parameter:
475 .  mat - the matrix
476 
477    Output Parameters:
478 +  missing - is any diagonal missing
479 -  dd - first diagonal entry that is missing (optional) on this process
480 
481    Level: advanced
482 
483 
484 .seealso: MatRealPart()
485 @*/
486 PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd)
487 {
488   PetscErrorCode ierr;
489 
490   PetscFunctionBegin;
491   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
492   PetscValidType(mat,1);
493   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
494   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
495   if (!mat->ops->missingdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
496   ierr = (*mat->ops->missingdiagonal)(mat,missing,dd);CHKERRQ(ierr);
497   PetscFunctionReturn(0);
498 }
499 
500 /*@C
501    MatGetRow - Gets a row of a matrix.  You MUST call MatRestoreRow()
502    for each row that you get to ensure that your application does
503    not bleed memory.
504 
505    Not Collective
506 
507    Input Parameters:
508 +  mat - the matrix
509 -  row - the row to get
510 
511    Output Parameters:
512 +  ncols -  if not NULL, the number of nonzeros in the row
513 .  cols - if not NULL, the column numbers
514 -  vals - if not NULL, the values
515 
516    Notes:
517    This routine is provided for people who need to have direct access
518    to the structure of a matrix.  We hope that we provide enough
519    high-level matrix routines that few users will need it.
520 
521    MatGetRow() always returns 0-based column indices, regardless of
522    whether the internal representation is 0-based (default) or 1-based.
523 
524    For better efficiency, set cols and/or vals to NULL if you do
525    not wish to extract these quantities.
526 
527    The user can only examine the values extracted with MatGetRow();
528    the values cannot be altered.  To change the matrix entries, one
529    must use MatSetValues().
530 
531    You can only have one call to MatGetRow() outstanding for a particular
532    matrix at a time, per processor. MatGetRow() can only obtain rows
533    associated with the given processor, it cannot get rows from the
534    other processors; for that we suggest using MatCreateSubMatrices(), then
535    MatGetRow() on the submatrix. The row index passed to MatGetRow()
536    is in the global number of rows.
537 
538    Fortran Notes:
539    The calling sequence from Fortran is
540 .vb
541    MatGetRow(matrix,row,ncols,cols,values,ierr)
542          Mat     matrix (input)
543          integer row    (input)
544          integer ncols  (output)
545          integer cols(maxcols) (output)
546          double precision (or double complex) values(maxcols) output
547 .ve
548    where maxcols >= maximum nonzeros in any row of the matrix.
549 
550 
551    Caution:
552    Do not try to change the contents of the output arrays (cols and vals).
553    In some cases, this may corrupt the matrix.
554 
555    Level: advanced
556 
557    Concepts: matrices^row access
558 
559 .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatCreateSubMatrices(), MatGetDiagonal()
560 @*/
561 PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
562 {
563   PetscErrorCode ierr;
564   PetscInt       incols;
565 
566   PetscFunctionBegin;
567   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
568   PetscValidType(mat,1);
569   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
570   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
571   if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
572   MatCheckPreallocated(mat,1);
573   ierr = PetscLogEventBegin(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr);
574   ierr = (*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals);CHKERRQ(ierr);
575   if (ncols) *ncols = incols;
576   ierr = PetscLogEventEnd(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr);
577   PetscFunctionReturn(0);
578 }
579 
580 /*@
581    MatConjugate - replaces the matrix values with their complex conjugates
582 
583    Logically Collective on Mat
584 
585    Input Parameters:
586 .  mat - the matrix
587 
588    Level: advanced
589 
590 .seealso:  VecConjugate()
591 @*/
592 PetscErrorCode MatConjugate(Mat mat)
593 {
594 #if defined(PETSC_USE_COMPLEX)
595   PetscErrorCode ierr;
596 
597   PetscFunctionBegin;
598   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
599   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
600   if (!mat->ops->conjugate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not provided for this matrix format, send email to petsc-maint@mcs.anl.gov");
601   ierr = (*mat->ops->conjugate)(mat);CHKERRQ(ierr);
602 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
603   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
604     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
605   }
606 #endif
607   PetscFunctionReturn(0);
608 #else
609   return 0;
610 #endif
611 }
612 
613 /*@C
614    MatRestoreRow - Frees any temporary space allocated by MatGetRow().
615 
616    Not Collective
617 
618    Input Parameters:
619 +  mat - the matrix
620 .  row - the row to get
621 .  ncols, cols - the number of nonzeros and their columns
622 -  vals - if nonzero the column values
623 
624    Notes:
625    This routine should be called after you have finished examining the entries.
626 
627    This routine zeros out ncols, cols, and vals. This is to prevent accidental
628    us of the array after it has been restored. If you pass NULL, it will
629    not zero the pointers.  Use of cols or vals after MatRestoreRow is invalid.
630 
631    Fortran Notes:
632    The calling sequence from Fortran is
633 .vb
634    MatRestoreRow(matrix,row,ncols,cols,values,ierr)
635       Mat     matrix (input)
636       integer row    (input)
637       integer ncols  (output)
638       integer cols(maxcols) (output)
639       double precision (or double complex) values(maxcols) output
640 .ve
641    Where maxcols >= maximum nonzeros in any row of the matrix.
642 
643    In Fortran MatRestoreRow() MUST be called after MatGetRow()
644    before another call to MatGetRow() can be made.
645 
646    Level: advanced
647 
648 .seealso:  MatGetRow()
649 @*/
650 PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
651 {
652   PetscErrorCode ierr;
653 
654   PetscFunctionBegin;
655   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
656   if (ncols) PetscValidIntPointer(ncols,3);
657   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
658   if (!mat->ops->restorerow) PetscFunctionReturn(0);
659   ierr = (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);CHKERRQ(ierr);
660   if (ncols) *ncols = 0;
661   if (cols)  *cols = NULL;
662   if (vals)  *vals = NULL;
663   PetscFunctionReturn(0);
664 }
665 
666 /*@
667    MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format.
668    You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag.
669 
670    Not Collective
671 
672    Input Parameters:
673 +  mat - the matrix
674 
675    Notes:
676    The flag is to ensure that users are aware of MatGetRow() only provides the upper trianglular part of the row for the matrices in MATSBAIJ format.
677 
678    Level: advanced
679 
680    Concepts: matrices^row access
681 
682 .seealso: 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 .keywords: Mat, set, options, prefix, database
747 
748 .seealso: MatSetFromOptions()
749 @*/
750 PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[])
751 {
752   PetscErrorCode ierr;
753 
754   PetscFunctionBegin;
755   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
756   ierr = PetscObjectSetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
757   PetscFunctionReturn(0);
758 }
759 
760 /*@C
761    MatAppendOptionsPrefix - Appends to the prefix used for searching for all
762    Mat options in the database.
763 
764    Logically Collective on Mat
765 
766    Input Parameters:
767 +  A - the Mat context
768 -  prefix - the prefix to prepend to all option names
769 
770    Notes:
771    A hyphen (-) must NOT be given at the beginning of the prefix name.
772    The first character of all runtime options is AUTOMATICALLY the hyphen.
773 
774    Level: advanced
775 
776 .keywords: Mat, append, options, prefix, database
777 
778 .seealso: MatGetOptionsPrefix()
779 @*/
780 PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[])
781 {
782   PetscErrorCode ierr;
783 
784   PetscFunctionBegin;
785   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
786   ierr = PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
787   PetscFunctionReturn(0);
788 }
789 
790 /*@C
791    MatGetOptionsPrefix - Sets the prefix used for searching for all
792    Mat options in the database.
793 
794    Not Collective
795 
796    Input Parameter:
797 .  A - the Mat context
798 
799    Output Parameter:
800 .  prefix - pointer to the prefix string used
801 
802    Notes:
803     On the fortran side, the user should pass in a string 'prefix' of
804    sufficient length to hold the prefix.
805 
806    Level: advanced
807 
808 .keywords: Mat, get, options, prefix, database
809 
810 .seealso: MatAppendOptionsPrefix()
811 @*/
812 PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[])
813 {
814   PetscErrorCode ierr;
815 
816   PetscFunctionBegin;
817   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
818   ierr = PetscObjectGetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
819   PetscFunctionReturn(0);
820 }
821 
822 /*@
823    MatResetPreallocation - Reset mat to use the original nonzero pattern provided by users.
824 
825    Collective on Mat
826 
827    Input Parameters:
828 .  A - the Mat context
829 
830    Notes:
831    The allocated memory will be shrunk after calling MatAssembly with MAT_FINAL_ASSEMBLY. Users can reset the preallocation to access the original memory.
832    Currently support MPIAIJ and SEQAIJ.
833 
834    Level: beginner
835 
836 .keywords: Mat, ResetPreallocation
837 
838 .seealso: MatSeqAIJSetPreallocation(), MatMPIAIJSetPreallocation(), MatXAIJSetPreallocation()
839 @*/
840 PetscErrorCode MatResetPreallocation(Mat A)
841 {
842   PetscErrorCode ierr;
843 
844   PetscFunctionBegin;
845   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
846   PetscValidType(A,1);
847   ierr = PetscUseMethod(A,"MatResetPreallocation_C",(Mat),(A));CHKERRQ(ierr);
848   PetscFunctionReturn(0);
849 }
850 
851 
852 /*@
853    MatSetUp - Sets up the internal matrix data structures for the later use.
854 
855    Collective on Mat
856 
857    Input Parameters:
858 .  A - the Mat context
859 
860    Notes:
861    If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used.
862 
863    If a suitable preallocation routine is used, this function does not need to be called.
864 
865    See the Performance chapter of the PETSc users manual for how to preallocate matrices
866 
867    Level: beginner
868 
869 .keywords: Mat, setup
870 
871 .seealso: MatCreate(), MatDestroy()
872 @*/
873 PetscErrorCode MatSetUp(Mat A)
874 {
875   PetscMPIInt    size;
876   PetscErrorCode ierr;
877 
878   PetscFunctionBegin;
879   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
880   if (!((PetscObject)A)->type_name) {
881     ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A), &size);CHKERRQ(ierr);
882     if (size == 1) {
883       ierr = MatSetType(A, MATSEQAIJ);CHKERRQ(ierr);
884     } else {
885       ierr = MatSetType(A, MATMPIAIJ);CHKERRQ(ierr);
886     }
887   }
888   if (!A->preallocated && A->ops->setup) {
889     ierr = PetscInfo(A,"Warning not preallocating matrix storage\n");CHKERRQ(ierr);
890     ierr = (*A->ops->setup)(A);CHKERRQ(ierr);
891   }
892   ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr);
893   ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr);
894   A->preallocated = PETSC_TRUE;
895   PetscFunctionReturn(0);
896 }
897 
898 #if defined(PETSC_HAVE_SAWS)
899 #include <petscviewersaws.h>
900 #endif
901 /*@C
902    MatView - Visualizes a matrix object.
903 
904    Collective on Mat
905 
906    Input Parameters:
907 +  mat - the matrix
908 -  viewer - visualization context
909 
910   Notes:
911   The available visualization contexts include
912 +    PETSC_VIEWER_STDOUT_SELF - for sequential matrices
913 .    PETSC_VIEWER_STDOUT_WORLD - for parallel matrices created on PETSC_COMM_WORLD
914 .    PETSC_VIEWER_STDOUT_(comm) - for matrices created on MPI communicator comm
915 -     PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure
916 
917    The user can open alternative visualization contexts with
918 +    PetscViewerASCIIOpen() - Outputs matrix to a specified file
919 .    PetscViewerBinaryOpen() - Outputs matrix in binary to a
920          specified file; corresponding input uses MatLoad()
921 .    PetscViewerDrawOpen() - Outputs nonzero matrix structure to
922          an X window display
923 -    PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
924          Currently only the sequential dense and AIJ
925          matrix types support the Socket viewer.
926 
927    The user can call PetscViewerPushFormat() to specify the output
928    format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
929    PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen).  Available formats include
930 +    PETSC_VIEWER_DEFAULT - default, prints matrix contents
931 .    PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
932 .    PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
933 .    PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse
934          format common among all matrix types
935 .    PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific
936          format (which is in many cases the same as the default)
937 .    PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
938          size and structure (not the matrix entries)
939 -    PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about
940          the matrix structure
941 
942    Options Database Keys:
943 +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatAssemblyEnd()
944 .  -mat_view ::ascii_info_detail - Prints more detailed info
945 .  -mat_view - Prints matrix in ASCII format
946 .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
947 .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
948 .  -display <name> - Sets display name (default is host)
949 .  -draw_pause <sec> - Sets number of seconds to pause after display
950 .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: ch_matlab for details)
951 .  -viewer_socket_machine <machine> -
952 .  -viewer_socket_port <port> -
953 .  -mat_view binary - save matrix to file in binary format
954 -  -viewer_binary_filename <name> -
955    Level: beginner
956 
957    Notes:
958     The ASCII viewers are only recommended for small matrices on at most a moderate number of processes,
959     the program will seemingly hang and take hours for larger matrices, for larger matrices one should use the binary format.
960 
961     See the manual page for MatLoad() for the exact format of the binary file when the binary
962       viewer is used.
963 
964       See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary
965       viewer is used.
966 
967       One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure,
968       and then use the following mouse functions.
969 + left mouse: zoom in
970 . middle mouse: zoom out
971 - right mouse: continue with the simulation
972 
973    Concepts: matrices^viewing
974    Concepts: matrices^plotting
975    Concepts: matrices^printing
976 
977 .seealso: PetscViewerPushFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(),
978           PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
979 @*/
980 PetscErrorCode MatView(Mat mat,PetscViewer viewer)
981 {
982   PetscErrorCode    ierr;
983   PetscInt          rows,cols,rbs,cbs;
984   PetscBool         iascii,ibinary;
985   PetscViewerFormat format;
986   PetscMPIInt       size;
987 #if defined(PETSC_HAVE_SAWS)
988   PetscBool         issaws;
989 #endif
990 
991   PetscFunctionBegin;
992   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
993   PetscValidType(mat,1);
994   if (!viewer) {
995     ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);CHKERRQ(ierr);
996   }
997   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
998   PetscCheckSameComm(mat,1,viewer,2);
999   MatCheckPreallocated(mat,1);
1000   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1001   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
1002   if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(0);
1003   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr);
1004   if (ibinary) {
1005     PetscBool mpiio;
1006     ierr = PetscViewerBinaryGetUseMPIIO(viewer,&mpiio);CHKERRQ(ierr);
1007     if (mpiio) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"PETSc matrix viewers do not support using MPI-IO, turn off that flag");
1008   }
1009 
1010   ierr = PetscLogEventBegin(MAT_View,mat,viewer,0,0);CHKERRQ(ierr);
1011   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1012   if ((!iascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) {
1013     SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detailed");
1014   }
1015 
1016 #if defined(PETSC_HAVE_SAWS)
1017   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr);
1018 #endif
1019   if (iascii) {
1020     if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
1021     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer);CHKERRQ(ierr);
1022     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
1023       MatNullSpace nullsp,transnullsp;
1024 
1025       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1026       ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr);
1027       ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr);
1028       if (rbs != 1 || cbs != 1) {
1029         if (rbs != cbs) {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, rbs=%D, cbs = %D\n",rows,cols,rbs,cbs);CHKERRQ(ierr);}
1030         else            {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,rbs);CHKERRQ(ierr);}
1031       } else {
1032         ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);CHKERRQ(ierr);
1033       }
1034       if (mat->factortype) {
1035         MatSolverType solver;
1036         ierr = MatFactorGetSolverType(mat,&solver);CHKERRQ(ierr);
1037         ierr = PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);CHKERRQ(ierr);
1038       }
1039       if (mat->ops->getinfo) {
1040         MatInfo info;
1041         ierr = MatGetInfo(mat,MAT_GLOBAL_SUM,&info);CHKERRQ(ierr);
1042         ierr = PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated);CHKERRQ(ierr);
1043         ierr = PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls =%D\n",(PetscInt)info.mallocs);CHKERRQ(ierr);
1044       }
1045       ierr = MatGetNullSpace(mat,&nullsp);CHKERRQ(ierr);
1046       ierr = MatGetTransposeNullSpace(mat,&transnullsp);CHKERRQ(ierr);
1047       if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer,"  has attached null space\n");CHKERRQ(ierr);}
1048       if (transnullsp && transnullsp != nullsp) {ierr = PetscViewerASCIIPrintf(viewer,"  has attached transposed null space\n");CHKERRQ(ierr);}
1049       ierr = MatGetNearNullSpace(mat,&nullsp);CHKERRQ(ierr);
1050       if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer,"  has attached near null space\n");CHKERRQ(ierr);}
1051     }
1052 #if defined(PETSC_HAVE_SAWS)
1053   } else if (issaws) {
1054     PetscMPIInt rank;
1055 
1056     ierr = PetscObjectName((PetscObject)mat);CHKERRQ(ierr);
1057     ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
1058     if (!((PetscObject)mat)->amsmem && !rank) {
1059       ierr = PetscObjectViewSAWs((PetscObject)mat,viewer);CHKERRQ(ierr);
1060     }
1061 #endif
1062   }
1063   if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && mat->ops->viewnative) {
1064     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1065     ierr = (*mat->ops->viewnative)(mat,viewer);CHKERRQ(ierr);
1066     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1067   } else if (mat->ops->view) {
1068     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1069     ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr);
1070     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1071   }
1072   if (iascii) {
1073     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1074     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
1075       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1076     }
1077   }
1078   ierr = PetscLogEventEnd(MAT_View,mat,viewer,0,0);CHKERRQ(ierr);
1079   PetscFunctionReturn(0);
1080 }
1081 
1082 #if defined(PETSC_USE_DEBUG)
1083 #include <../src/sys/totalview/tv_data_display.h>
1084 PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat)
1085 {
1086   TV_add_row("Local rows", "int", &mat->rmap->n);
1087   TV_add_row("Local columns", "int", &mat->cmap->n);
1088   TV_add_row("Global rows", "int", &mat->rmap->N);
1089   TV_add_row("Global columns", "int", &mat->cmap->N);
1090   TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name);
1091   return TV_format_OK;
1092 }
1093 #endif
1094 
1095 /*@C
1096    MatLoad - Loads a matrix that has been stored in binary/HDF5 format
1097    with MatView().  The matrix format is determined from the options database.
1098    Generates a parallel MPI matrix if the communicator has more than one
1099    processor.  The default matrix type is AIJ.
1100 
1101    Collective on PetscViewer
1102 
1103    Input Parameters:
1104 +  newmat - the newly loaded matrix, this needs to have been created with MatCreate()
1105             or some related function before a call to MatLoad()
1106 -  viewer - binary/HDF5 file viewer
1107 
1108    Options Database Keys:
1109    Used with block matrix formats (MATSEQBAIJ,  ...) to specify
1110    block size
1111 .    -matload_block_size <bs>
1112 
1113    Level: beginner
1114 
1115    Notes:
1116    If the Mat type has not yet been given then MATAIJ is used, call MatSetFromOptions() on the
1117    Mat before calling this routine if you wish to set it from the options database.
1118 
1119    MatLoad() automatically loads into the options database any options
1120    given in the file filename.info where filename is the name of the file
1121    that was passed to the PetscViewerBinaryOpen(). The options in the info
1122    file will be ignored if you use the -viewer_binary_skip_info option.
1123 
1124    If the type or size of newmat is not set before a call to MatLoad, PETSc
1125    sets the default matrix type AIJ and sets the local and global sizes.
1126    If type and/or size is already set, then the same are used.
1127 
1128    In parallel, each processor can load a subset of rows (or the
1129    entire matrix).  This routine is especially useful when a large
1130    matrix is stored on disk and only part of it is desired on each
1131    processor.  For example, a parallel solver may access only some of
1132    the rows from each processor.  The algorithm used here reads
1133    relatively small blocks of data rather than reading the entire
1134    matrix and then subsetting it.
1135 
1136    Viewer's PetscViewerType must be either PETSCVIEWERBINARY or PETSCVIEWERHDF5.
1137    Such viewer can be created using PetscViewerBinaryOpen()/PetscViewerHDF5Open(),
1138    or the sequence like
1139 $    PetscViewer v;
1140 $    PetscViewerCreate(PETSC_COMM_WORLD,&v);
1141 $    PetscViewerSetType(v,PETSCVIEWERBINARY);
1142 $    PetscViewerSetFromOptions(v);
1143 $    PetscViewerFileSetMode(v,FILE_MODE_READ);
1144 $    PetscViewerFileSetName(v,"datafile");
1145    The optional PetscViewerSetFromOptions() call allows to override PetscViewerSetType() using option
1146 $ -viewer_type {binary,hdf5}
1147 
1148    See the example src/ksp/ksp/examples/tutorials/ex27.c with the first approach,
1149    and src/mat/examples/tutorials/ex10.c with the second approach.
1150 
1151    Notes about the PETSc binary format:
1152    In case of PETSCVIEWERBINARY, a native PETSc binary format is used. Each of the blocks
1153    is read onto rank 0 and then shipped to its destination rank, one after another.
1154    Multiple objects, both matrices and vectors, can be stored within the same file.
1155    Their PetscObject name is ignored; they are loaded in the order of their storage.
1156 
1157    Most users should not need to know the details of the binary storage
1158    format, since MatLoad() and MatView() completely hide these details.
1159    But for anyone who's interested, the standard binary matrix storage
1160    format is
1161 
1162 $    int    MAT_FILE_CLASSID
1163 $    int    number of rows
1164 $    int    number of columns
1165 $    int    total number of nonzeros
1166 $    int    *number nonzeros in each row
1167 $    int    *column indices of all nonzeros (starting index is zero)
1168 $    PetscScalar *values of all nonzeros
1169 
1170    PETSc automatically does the byte swapping for
1171 machines that store the bytes reversed, e.g.  DEC alpha, freebsd,
1172 linux, Windows and the paragon; thus if you write your own binary
1173 read/write routines you have to swap the bytes; see PetscBinaryRead()
1174 and PetscBinaryWrite() to see how this may be done.
1175 
1176    Notes about the HDF5 (MATLAB MAT-File Version 7.3) format:
1177    In case of PETSCVIEWERHDF5, a parallel HDF5 reader is used.
1178    Each processor's chunk is loaded independently by its owning rank.
1179    Multiple objects, both matrices and vectors, can be stored within the same file.
1180    They are looked up by their PetscObject name.
1181 
1182    As the MATLAB MAT-File Version 7.3 format is also a HDF5 flavor, we decided to use
1183    by default the same structure and naming of the AIJ arrays and column count
1184    (see PetscViewerHDF5SetAIJNames())
1185    within the HDF5 file. This means that a MAT file saved with -v7.3 flag, e.g.
1186 $    save example.mat A b -v7.3
1187    can be directly read by this routine (see Reference 1 for details).
1188    Note that depending on your MATLAB version, this format might be a default,
1189    otherwise you can set it as default in Preferences.
1190 
1191    Unless -nocompression flag is used to save the file in MATLAB,
1192    PETSc must be configured with ZLIB package.
1193 
1194    See also examples src/mat/examples/tutorials/ex10.c and src/ksp/ksp/examples/tutorials/ex27.c
1195 
1196    Current HDF5 (MAT-File) limitations:
1197    This reader currently supports only real MATSEQAIJ and MATMPIAIJ matrices.
1198 
1199    Corresponding MatView() is not yet implemented.
1200 
1201    The loaded matrix is actually a transpose of the original one in MATLAB,
1202    unless you push PETSC_VIEWER_HDF5_MAT format (see examples above).
1203    With this format, matrix is automatically transposed by PETSc,
1204    unless the matrix is marked as SPD or symmetric
1205    (see MatSetOption(), MAT_SPD, MAT_SYMMETRIC).
1206 
1207    References:
1208 1. MATLAB(R) Documentation, manual page of save(), https://www.mathworks.com/help/matlab/ref/save.html#btox10b-1-version
1209 
1210 .keywords: matrix, load, binary, input, HDF5
1211 
1212 .seealso: PetscViewerBinaryOpen(), PetscViewerSetType(), PetscViewerHDF5SetAIJNames(), MatView(), VecLoad()
1213 
1214  @*/
1215 PetscErrorCode MatLoad(Mat newmat,PetscViewer viewer)
1216 {
1217   PetscErrorCode ierr;
1218   PetscBool      flg;
1219 
1220   PetscFunctionBegin;
1221   PetscValidHeaderSpecific(newmat,MAT_CLASSID,1);
1222   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1223 
1224   if (!((PetscObject)newmat)->type_name) {
1225     ierr = MatSetType(newmat,MATAIJ);CHKERRQ(ierr);
1226   }
1227 
1228   flg  = PETSC_FALSE;
1229   ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,NULL);CHKERRQ(ierr);
1230   if (flg) {
1231     ierr = MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
1232     ierr = MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);CHKERRQ(ierr);
1233   }
1234   flg  = PETSC_FALSE;
1235   ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_spd",&flg,NULL);CHKERRQ(ierr);
1236   if (flg) {
1237     ierr = MatSetOption(newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr);
1238   }
1239 
1240   if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type");
1241   ierr = PetscLogEventBegin(MAT_Load,viewer,0,0,0);CHKERRQ(ierr);
1242   ierr = (*newmat->ops->load)(newmat,viewer);CHKERRQ(ierr);
1243   ierr = PetscLogEventEnd(MAT_Load,viewer,0,0,0);CHKERRQ(ierr);
1244   PetscFunctionReturn(0);
1245 }
1246 
1247 PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant)
1248 {
1249   PetscErrorCode ierr;
1250   Mat_Redundant  *redund = *redundant;
1251   PetscInt       i;
1252 
1253   PetscFunctionBegin;
1254   if (redund){
1255     if (redund->matseq) { /* via MatCreateSubMatrices()  */
1256       ierr = ISDestroy(&redund->isrow);CHKERRQ(ierr);
1257       ierr = ISDestroy(&redund->iscol);CHKERRQ(ierr);
1258       ierr = MatDestroySubMatrices(1,&redund->matseq);CHKERRQ(ierr);
1259     } else {
1260       ierr = PetscFree2(redund->send_rank,redund->recv_rank);CHKERRQ(ierr);
1261       ierr = PetscFree(redund->sbuf_j);CHKERRQ(ierr);
1262       ierr = PetscFree(redund->sbuf_a);CHKERRQ(ierr);
1263       for (i=0; i<redund->nrecvs; i++) {
1264         ierr = PetscFree(redund->rbuf_j[i]);CHKERRQ(ierr);
1265         ierr = PetscFree(redund->rbuf_a[i]);CHKERRQ(ierr);
1266       }
1267       ierr = PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a);CHKERRQ(ierr);
1268     }
1269 
1270     if (redund->subcomm) {
1271       ierr = PetscCommDestroy(&redund->subcomm);CHKERRQ(ierr);
1272     }
1273     ierr = PetscFree(redund);CHKERRQ(ierr);
1274   }
1275   PetscFunctionReturn(0);
1276 }
1277 
1278 /*@
1279    MatDestroy - Frees space taken by a matrix.
1280 
1281    Collective on Mat
1282 
1283    Input Parameter:
1284 .  A - the matrix
1285 
1286    Level: beginner
1287 
1288 @*/
1289 PetscErrorCode MatDestroy(Mat *A)
1290 {
1291   PetscErrorCode ierr;
1292 
1293   PetscFunctionBegin;
1294   if (!*A) PetscFunctionReturn(0);
1295   PetscValidHeaderSpecific(*A,MAT_CLASSID,1);
1296   if (--((PetscObject)(*A))->refct > 0) {*A = NULL; PetscFunctionReturn(0);}
1297 
1298   /* if memory was published with SAWs then destroy it */
1299   ierr = PetscObjectSAWsViewOff((PetscObject)*A);CHKERRQ(ierr);
1300   if ((*A)->ops->destroy) {
1301     ierr = (*(*A)->ops->destroy)(*A);CHKERRQ(ierr);
1302   }
1303 
1304   ierr = PetscFree((*A)->defaultvectype);CHKERRQ(ierr);
1305   ierr = PetscFree((*A)->bsizes);CHKERRQ(ierr);
1306   ierr = PetscFree((*A)->solvertype);CHKERRQ(ierr);
1307   ierr = MatDestroy_Redundant(&(*A)->redundant);CHKERRQ(ierr);
1308   ierr = MatNullSpaceDestroy(&(*A)->nullsp);CHKERRQ(ierr);
1309   ierr = MatNullSpaceDestroy(&(*A)->transnullsp);CHKERRQ(ierr);
1310   ierr = MatNullSpaceDestroy(&(*A)->nearnullsp);CHKERRQ(ierr);
1311   ierr = MatDestroy(&(*A)->schur);CHKERRQ(ierr);
1312   ierr = PetscLayoutDestroy(&(*A)->rmap);CHKERRQ(ierr);
1313   ierr = PetscLayoutDestroy(&(*A)->cmap);CHKERRQ(ierr);
1314   ierr = PetscHeaderDestroy(A);CHKERRQ(ierr);
1315   PetscFunctionReturn(0);
1316 }
1317 
1318 /*@C
1319    MatSetValues - Inserts or adds a block of values into a matrix.
1320    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1321    MUST be called after all calls to MatSetValues() have been completed.
1322 
1323    Not Collective
1324 
1325    Input Parameters:
1326 +  mat - the matrix
1327 .  v - a logically two-dimensional array of values
1328 .  m, idxm - the number of rows and their global indices
1329 .  n, idxn - the number of columns and their global indices
1330 -  addv - either ADD_VALUES or INSERT_VALUES, where
1331    ADD_VALUES adds values to any existing entries, and
1332    INSERT_VALUES replaces existing entries with new values
1333 
1334    Notes:
1335    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
1336       MatSetUp() before using this routine
1337 
1338    By default the values, v, are row-oriented. See MatSetOption() for other options.
1339 
1340    Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
1341    options cannot be mixed without intervening calls to the assembly
1342    routines.
1343 
1344    MatSetValues() uses 0-based row and column numbers in Fortran
1345    as well as in C.
1346 
1347    Negative indices may be passed in idxm and idxn, these rows and columns are
1348    simply ignored. This allows easily inserting element stiffness matrices
1349    with homogeneous Dirchlet boundary conditions that you don't want represented
1350    in the matrix.
1351 
1352    Efficiency Alert:
1353    The routine MatSetValuesBlocked() may offer much better efficiency
1354    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1355 
1356    Level: beginner
1357 
1358    Developer Notes:
1359     This is labeled with C so does not automatically generate Fortran stubs and interfaces
1360                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
1361 
1362    Concepts: matrices^putting entries in
1363 
1364 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1365           InsertMode, INSERT_VALUES, ADD_VALUES
1366 @*/
1367 PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1368 {
1369   PetscErrorCode ierr;
1370 #if defined(PETSC_USE_DEBUG)
1371   PetscInt       i,j;
1372 #endif
1373 
1374   PetscFunctionBeginHot;
1375   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1376   PetscValidType(mat,1);
1377   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1378   PetscValidIntPointer(idxm,3);
1379   PetscValidIntPointer(idxn,5);
1380   PetscValidScalarPointer(v,6);
1381   MatCheckPreallocated(mat,1);
1382   if (mat->insertmode == NOT_SET_VALUES) {
1383     mat->insertmode = addv;
1384   }
1385 #if defined(PETSC_USE_DEBUG)
1386   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1387   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1388   if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1389 
1390   for (i=0; i<m; i++) {
1391     for (j=0; j<n; j++) {
1392       if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j]))
1393 #if defined(PETSC_USE_COMPLEX)
1394         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]);
1395 #else
1396         SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%D,%D)",(double)v[i*n+j],idxm[i],idxn[j]);
1397 #endif
1398     }
1399   }
1400 #endif
1401 
1402   if (mat->assembled) {
1403     mat->was_assembled = PETSC_TRUE;
1404     mat->assembled     = PETSC_FALSE;
1405   }
1406   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1407   ierr = (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
1408   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1409 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1410   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1411     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1412   }
1413 #endif
1414   PetscFunctionReturn(0);
1415 }
1416 
1417 
1418 /*@
1419    MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
1420         values into a matrix
1421 
1422    Not Collective
1423 
1424    Input Parameters:
1425 +  mat - the matrix
1426 .  row - the (block) row to set
1427 -  v - a logically two-dimensional array of values
1428 
1429    Notes:
1430    By the values, v, are column-oriented (for the block version) and sorted
1431 
1432    All the nonzeros in the row must be provided
1433 
1434    The matrix must have previously had its column indices set
1435 
1436    The row must belong to this process
1437 
1438    Level: intermediate
1439 
1440    Concepts: matrices^putting entries in
1441 
1442 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1443           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping()
1444 @*/
1445 PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
1446 {
1447   PetscErrorCode ierr;
1448   PetscInt       globalrow;
1449 
1450   PetscFunctionBegin;
1451   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1452   PetscValidType(mat,1);
1453   PetscValidScalarPointer(v,2);
1454   ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);CHKERRQ(ierr);
1455   ierr = MatSetValuesRow(mat,globalrow,v);CHKERRQ(ierr);
1456 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1457   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1458     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1459   }
1460 #endif
1461   PetscFunctionReturn(0);
1462 }
1463 
1464 /*@
1465    MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
1466         values into a matrix
1467 
1468    Not Collective
1469 
1470    Input Parameters:
1471 +  mat - the matrix
1472 .  row - the (block) row to set
1473 -  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
1474 
1475    Notes:
1476    The values, v, are column-oriented for the block version.
1477 
1478    All the nonzeros in the row must be provided
1479 
1480    THE MATRIX MUST HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually MatSetValues() is used.
1481 
1482    The row must belong to this process
1483 
1484    Level: advanced
1485 
1486    Concepts: matrices^putting entries in
1487 
1488 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1489           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1490 @*/
1491 PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
1492 {
1493   PetscErrorCode ierr;
1494 
1495   PetscFunctionBeginHot;
1496   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1497   PetscValidType(mat,1);
1498   MatCheckPreallocated(mat,1);
1499   PetscValidScalarPointer(v,2);
1500 #if defined(PETSC_USE_DEBUG)
1501   if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
1502   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1503 #endif
1504   mat->insertmode = INSERT_VALUES;
1505 
1506   if (mat->assembled) {
1507     mat->was_assembled = PETSC_TRUE;
1508     mat->assembled     = PETSC_FALSE;
1509   }
1510   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1511   if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1512   ierr = (*mat->ops->setvaluesrow)(mat,row,v);CHKERRQ(ierr);
1513   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1514 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1515   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1516     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1517   }
1518 #endif
1519   PetscFunctionReturn(0);
1520 }
1521 
1522 /*@
1523    MatSetValuesStencil - Inserts or adds a block of values into a matrix.
1524      Using structured grid indexing
1525 
1526    Not Collective
1527 
1528    Input Parameters:
1529 +  mat - the matrix
1530 .  m - number of rows being entered
1531 .  idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
1532 .  n - number of columns being entered
1533 .  idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered
1534 .  v - a logically two-dimensional array of values
1535 -  addv - either ADD_VALUES or INSERT_VALUES, where
1536    ADD_VALUES adds values to any existing entries, and
1537    INSERT_VALUES replaces existing entries with new values
1538 
1539    Notes:
1540    By default the values, v, are row-oriented.  See MatSetOption() for other options.
1541 
1542    Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
1543    options cannot be mixed without intervening calls to the assembly
1544    routines.
1545 
1546    The grid coordinates are across the entire grid, not just the local portion
1547 
1548    MatSetValuesStencil() uses 0-based row and column numbers in Fortran
1549    as well as in C.
1550 
1551    For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1552 
1553    In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1554    or call MatSetLocalToGlobalMapping() and MatSetStencil() first.
1555 
1556    The columns and rows in the stencil passed in MUST be contained within the
1557    ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1558    if you create a DMDA with an overlap of one grid level and on a particular process its first
1559    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1560    first i index you can use in your column and row indices in MatSetStencil() is 5.
1561 
1562    In Fortran idxm and idxn should be declared as
1563 $     MatStencil idxm(4,m),idxn(4,n)
1564    and the values inserted using
1565 $    idxm(MatStencil_i,1) = i
1566 $    idxm(MatStencil_j,1) = j
1567 $    idxm(MatStencil_k,1) = k
1568 $    idxm(MatStencil_c,1) = c
1569    etc
1570 
1571    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
1572    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
1573    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
1574    DM_BOUNDARY_PERIODIC boundary type.
1575 
1576    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
1577    a single value per point) you can skip filling those indices.
1578 
1579    Inspired by the structured grid interface to the HYPRE package
1580    (http://www.llnl.gov/CASC/hypre)
1581 
1582    Efficiency Alert:
1583    The routine MatSetValuesBlockedStencil() may offer much better efficiency
1584    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1585 
1586    Level: beginner
1587 
1588    Concepts: matrices^putting entries in
1589 
1590 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1591           MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil
1592 @*/
1593 PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1594 {
1595   PetscErrorCode ierr;
1596   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1597   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1598   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1599 
1600   PetscFunctionBegin;
1601   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1602   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1603   PetscValidType(mat,1);
1604   PetscValidIntPointer(idxm,3);
1605   PetscValidIntPointer(idxn,5);
1606   PetscValidScalarPointer(v,6);
1607 
1608   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1609     jdxm = buf; jdxn = buf+m;
1610   } else {
1611     ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr);
1612     jdxm = bufm; jdxn = bufn;
1613   }
1614   for (i=0; i<m; i++) {
1615     for (j=0; j<3-sdim; j++) dxm++;
1616     tmp = *dxm++ - starts[0];
1617     for (j=0; j<dim-1; j++) {
1618       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1619       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1620     }
1621     if (mat->stencil.noc) dxm++;
1622     jdxm[i] = tmp;
1623   }
1624   for (i=0; i<n; i++) {
1625     for (j=0; j<3-sdim; j++) dxn++;
1626     tmp = *dxn++ - starts[0];
1627     for (j=0; j<dim-1; j++) {
1628       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1629       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1630     }
1631     if (mat->stencil.noc) dxn++;
1632     jdxn[i] = tmp;
1633   }
1634   ierr = MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr);
1635   ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr);
1636   PetscFunctionReturn(0);
1637 }
1638 
1639 /*@
1640    MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1641      Using structured grid indexing
1642 
1643    Not Collective
1644 
1645    Input Parameters:
1646 +  mat - the matrix
1647 .  m - number of rows being entered
1648 .  idxm - grid coordinates for matrix rows being entered
1649 .  n - number of columns being entered
1650 .  idxn - grid coordinates for matrix columns being entered
1651 .  v - a logically two-dimensional array of values
1652 -  addv - either ADD_VALUES or INSERT_VALUES, where
1653    ADD_VALUES adds values to any existing entries, and
1654    INSERT_VALUES replaces existing entries with new values
1655 
1656    Notes:
1657    By default the values, v, are row-oriented and unsorted.
1658    See MatSetOption() for other options.
1659 
1660    Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
1661    options cannot be mixed without intervening calls to the assembly
1662    routines.
1663 
1664    The grid coordinates are across the entire grid, not just the local portion
1665 
1666    MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran
1667    as well as in C.
1668 
1669    For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1670 
1671    In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1672    or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first.
1673 
1674    The columns and rows in the stencil passed in MUST be contained within the
1675    ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1676    if you create a DMDA with an overlap of one grid level and on a particular process its first
1677    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1678    first i index you can use in your column and row indices in MatSetStencil() is 5.
1679 
1680    In Fortran idxm and idxn should be declared as
1681 $     MatStencil idxm(4,m),idxn(4,n)
1682    and the values inserted using
1683 $    idxm(MatStencil_i,1) = i
1684 $    idxm(MatStencil_j,1) = j
1685 $    idxm(MatStencil_k,1) = k
1686    etc
1687 
1688    Negative indices may be passed in idxm and idxn, these rows and columns are
1689    simply ignored. This allows easily inserting element stiffness matrices
1690    with homogeneous Dirchlet boundary conditions that you don't want represented
1691    in the matrix.
1692 
1693    Inspired by the structured grid interface to the HYPRE package
1694    (http://www.llnl.gov/CASC/hypre)
1695 
1696    Level: beginner
1697 
1698    Concepts: matrices^putting entries in
1699 
1700 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1701           MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil,
1702           MatSetBlockSize(), MatSetLocalToGlobalMapping()
1703 @*/
1704 PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1705 {
1706   PetscErrorCode ierr;
1707   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1708   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1709   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1710 
1711   PetscFunctionBegin;
1712   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1713   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1714   PetscValidType(mat,1);
1715   PetscValidIntPointer(idxm,3);
1716   PetscValidIntPointer(idxn,5);
1717   PetscValidScalarPointer(v,6);
1718 
1719   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1720     jdxm = buf; jdxn = buf+m;
1721   } else {
1722     ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr);
1723     jdxm = bufm; jdxn = bufn;
1724   }
1725   for (i=0; i<m; i++) {
1726     for (j=0; j<3-sdim; j++) dxm++;
1727     tmp = *dxm++ - starts[0];
1728     for (j=0; j<sdim-1; j++) {
1729       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1730       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1731     }
1732     dxm++;
1733     jdxm[i] = tmp;
1734   }
1735   for (i=0; i<n; i++) {
1736     for (j=0; j<3-sdim; j++) dxn++;
1737     tmp = *dxn++ - starts[0];
1738     for (j=0; j<sdim-1; j++) {
1739       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1740       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1741     }
1742     dxn++;
1743     jdxn[i] = tmp;
1744   }
1745   ierr = MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr);
1746   ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr);
1747 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1748   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1749     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1750   }
1751 #endif
1752   PetscFunctionReturn(0);
1753 }
1754 
1755 /*@
1756    MatSetStencil - Sets the grid information for setting values into a matrix via
1757         MatSetValuesStencil()
1758 
1759    Not Collective
1760 
1761    Input Parameters:
1762 +  mat - the matrix
1763 .  dim - dimension of the grid 1, 2, or 3
1764 .  dims - number of grid points in x, y, and z direction, including ghost points on your processor
1765 .  starts - starting point of ghost nodes on your processor in x, y, and z direction
1766 -  dof - number of degrees of freedom per node
1767 
1768 
1769    Inspired by the structured grid interface to the HYPRE package
1770    (www.llnl.gov/CASC/hyper)
1771 
1772    For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the
1773    user.
1774 
1775    Level: beginner
1776 
1777    Concepts: matrices^putting entries in
1778 
1779 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1780           MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
1781 @*/
1782 PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1783 {
1784   PetscInt i;
1785 
1786   PetscFunctionBegin;
1787   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1788   PetscValidIntPointer(dims,3);
1789   PetscValidIntPointer(starts,4);
1790 
1791   mat->stencil.dim = dim + (dof > 1);
1792   for (i=0; i<dim; i++) {
1793     mat->stencil.dims[i]   = dims[dim-i-1];      /* copy the values in backwards */
1794     mat->stencil.starts[i] = starts[dim-i-1];
1795   }
1796   mat->stencil.dims[dim]   = dof;
1797   mat->stencil.starts[dim] = 0;
1798   mat->stencil.noc         = (PetscBool)(dof == 1);
1799   PetscFunctionReturn(0);
1800 }
1801 
1802 /*@C
1803    MatSetValuesBlocked - Inserts or adds a block of values into a matrix.
1804 
1805    Not Collective
1806 
1807    Input Parameters:
1808 +  mat - the matrix
1809 .  v - a logically two-dimensional array of values
1810 .  m, idxm - the number of block rows and their global block indices
1811 .  n, idxn - the number of block columns and their global block indices
1812 -  addv - either ADD_VALUES or INSERT_VALUES, where
1813    ADD_VALUES adds values to any existing entries, and
1814    INSERT_VALUES replaces existing entries with new values
1815 
1816    Notes:
1817    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call
1818    MatXXXXSetPreallocation() or MatSetUp() before using this routine.
1819 
1820    The m and n count the NUMBER of blocks in the row direction and column direction,
1821    NOT the total number of rows/columns; for example, if the block size is 2 and
1822    you are passing in values for rows 2,3,4,5  then m would be 2 (not 4).
1823    The values in idxm would be 1 2; that is the first index for each block divided by
1824    the block size.
1825 
1826    Note that you must call MatSetBlockSize() when constructing this matrix (before
1827    preallocating it).
1828 
1829    By default the values, v, are row-oriented, so the layout of
1830    v is the same as for MatSetValues(). See MatSetOption() for other options.
1831 
1832    Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
1833    options cannot be mixed without intervening calls to the assembly
1834    routines.
1835 
1836    MatSetValuesBlocked() uses 0-based row and column numbers in Fortran
1837    as well as in C.
1838 
1839    Negative indices may be passed in idxm and idxn, these rows and columns are
1840    simply ignored. This allows easily inserting element stiffness matrices
1841    with homogeneous Dirchlet boundary conditions that you don't want represented
1842    in the matrix.
1843 
1844    Each time an entry is set within a sparse matrix via MatSetValues(),
1845    internal searching must be done to determine where to place the
1846    data in the matrix storage space.  By instead inserting blocks of
1847    entries via MatSetValuesBlocked(), the overhead of matrix assembly is
1848    reduced.
1849 
1850    Example:
1851 $   Suppose m=n=2 and block size(bs) = 2 The array is
1852 $
1853 $   1  2  | 3  4
1854 $   5  6  | 7  8
1855 $   - - - | - - -
1856 $   9  10 | 11 12
1857 $   13 14 | 15 16
1858 $
1859 $   v[] should be passed in like
1860 $   v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
1861 $
1862 $  If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then
1863 $   v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16]
1864 
1865    Level: intermediate
1866 
1867    Concepts: matrices^putting entries in blocked
1868 
1869 .seealso: MatSetBlockSize(), MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal()
1870 @*/
1871 PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1872 {
1873   PetscErrorCode ierr;
1874 
1875   PetscFunctionBeginHot;
1876   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1877   PetscValidType(mat,1);
1878   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1879   PetscValidIntPointer(idxm,3);
1880   PetscValidIntPointer(idxn,5);
1881   PetscValidScalarPointer(v,6);
1882   MatCheckPreallocated(mat,1);
1883   if (mat->insertmode == NOT_SET_VALUES) {
1884     mat->insertmode = addv;
1885   }
1886 #if defined(PETSC_USE_DEBUG)
1887   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1888   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1889   if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1890 #endif
1891 
1892   if (mat->assembled) {
1893     mat->was_assembled = PETSC_TRUE;
1894     mat->assembled     = PETSC_FALSE;
1895   }
1896   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1897   if (mat->ops->setvaluesblocked) {
1898     ierr = (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
1899   } else {
1900     PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn;
1901     PetscInt i,j,bs,cbs;
1902     ierr = MatGetBlockSizes(mat,&bs,&cbs);CHKERRQ(ierr);
1903     if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1904       iidxm = buf; iidxn = buf + m*bs;
1905     } else {
1906       ierr  = PetscMalloc2(m*bs,&bufr,n*cbs,&bufc);CHKERRQ(ierr);
1907       iidxm = bufr; iidxn = bufc;
1908     }
1909     for (i=0; i<m; i++) {
1910       for (j=0; j<bs; j++) {
1911         iidxm[i*bs+j] = bs*idxm[i] + j;
1912       }
1913     }
1914     for (i=0; i<n; i++) {
1915       for (j=0; j<cbs; j++) {
1916         iidxn[i*cbs+j] = cbs*idxn[i] + j;
1917       }
1918     }
1919     ierr = MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv);CHKERRQ(ierr);
1920     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
1921   }
1922   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1923 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1924   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1925     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1926   }
1927 #endif
1928   PetscFunctionReturn(0);
1929 }
1930 
1931 /*@
1932    MatGetValues - Gets a block of values from a matrix.
1933 
1934    Not Collective; currently only returns a local block
1935 
1936    Input Parameters:
1937 +  mat - the matrix
1938 .  v - a logically two-dimensional array for storing the values
1939 .  m, idxm - the number of rows and their global indices
1940 -  n, idxn - the number of columns and their global indices
1941 
1942    Notes:
1943    The user must allocate space (m*n PetscScalars) for the values, v.
1944    The values, v, are then returned in a row-oriented format,
1945    analogous to that used by default in MatSetValues().
1946 
1947    MatGetValues() uses 0-based row and column numbers in
1948    Fortran as well as in C.
1949 
1950    MatGetValues() requires that the matrix has been assembled
1951    with MatAssemblyBegin()/MatAssemblyEnd().  Thus, calls to
1952    MatSetValues() and MatGetValues() CANNOT be made in succession
1953    without intermediate matrix assembly.
1954 
1955    Negative row or column indices will be ignored and those locations in v[] will be
1956    left unchanged.
1957 
1958    Level: advanced
1959 
1960    Concepts: matrices^accessing values
1961 
1962 .seealso: MatGetRow(), MatCreateSubMatrices(), MatSetValues()
1963 @*/
1964 PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1965 {
1966   PetscErrorCode ierr;
1967 
1968   PetscFunctionBegin;
1969   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1970   PetscValidType(mat,1);
1971   if (!m || !n) PetscFunctionReturn(0);
1972   PetscValidIntPointer(idxm,3);
1973   PetscValidIntPointer(idxn,5);
1974   PetscValidScalarPointer(v,6);
1975   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1976   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1977   if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1978   MatCheckPreallocated(mat,1);
1979 
1980   ierr = PetscLogEventBegin(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
1981   ierr = (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);CHKERRQ(ierr);
1982   ierr = PetscLogEventEnd(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
1983   PetscFunctionReturn(0);
1984 }
1985 
1986 /*@
1987   MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and
1988   the same size. Currently, this can only be called once and creates the given matrix.
1989 
1990   Not Collective
1991 
1992   Input Parameters:
1993 + mat - the matrix
1994 . nb - the number of blocks
1995 . bs - the number of rows (and columns) in each block
1996 . rows - a concatenation of the rows for each block
1997 - v - a concatenation of logically two-dimensional arrays of values
1998 
1999   Notes:
2000   In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix.
2001 
2002   Level: advanced
2003 
2004   Concepts: matrices^putting entries in
2005 
2006 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
2007           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
2008 @*/
2009 PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[])
2010 {
2011   PetscErrorCode ierr;
2012 
2013   PetscFunctionBegin;
2014   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2015   PetscValidType(mat,1);
2016   PetscValidScalarPointer(rows,4);
2017   PetscValidScalarPointer(v,5);
2018 #if defined(PETSC_USE_DEBUG)
2019   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2020 #endif
2021 
2022   ierr = PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr);
2023   if (mat->ops->setvaluesbatch) {
2024     ierr = (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);CHKERRQ(ierr);
2025   } else {
2026     PetscInt b;
2027     for (b = 0; b < nb; ++b) {
2028       ierr = MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);CHKERRQ(ierr);
2029     }
2030   }
2031   ierr = PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr);
2032   PetscFunctionReturn(0);
2033 }
2034 
2035 /*@
2036    MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
2037    the routine MatSetValuesLocal() to allow users to insert matrix entries
2038    using a local (per-processor) numbering.
2039 
2040    Not Collective
2041 
2042    Input Parameters:
2043 +  x - the matrix
2044 .  rmapping - row mapping created with ISLocalToGlobalMappingCreate()   or ISLocalToGlobalMappingCreateIS()
2045 - cmapping - column mapping
2046 
2047    Level: intermediate
2048 
2049    Concepts: matrices^local to global mapping
2050    Concepts: local to global mapping^for matrices
2051 
2052 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
2053 @*/
2054 PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
2055 {
2056   PetscErrorCode ierr;
2057 
2058   PetscFunctionBegin;
2059   PetscValidHeaderSpecific(x,MAT_CLASSID,1);
2060   PetscValidType(x,1);
2061   PetscValidHeaderSpecific(rmapping,IS_LTOGM_CLASSID,2);
2062   PetscValidHeaderSpecific(cmapping,IS_LTOGM_CLASSID,3);
2063 
2064   if (x->ops->setlocaltoglobalmapping) {
2065     ierr = (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);CHKERRQ(ierr);
2066   } else {
2067     ierr = PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);CHKERRQ(ierr);
2068     ierr = PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);CHKERRQ(ierr);
2069   }
2070   PetscFunctionReturn(0);
2071 }
2072 
2073 
2074 /*@
2075    MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping()
2076 
2077    Not Collective
2078 
2079    Input Parameters:
2080 .  A - the matrix
2081 
2082    Output Parameters:
2083 + rmapping - row mapping
2084 - cmapping - column mapping
2085 
2086    Level: advanced
2087 
2088    Concepts: matrices^local to global mapping
2089    Concepts: local to global mapping^for matrices
2090 
2091 .seealso:  MatSetValuesLocal()
2092 @*/
2093 PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
2094 {
2095   PetscFunctionBegin;
2096   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2097   PetscValidType(A,1);
2098   if (rmapping) PetscValidPointer(rmapping,2);
2099   if (cmapping) PetscValidPointer(cmapping,3);
2100   if (rmapping) *rmapping = A->rmap->mapping;
2101   if (cmapping) *cmapping = A->cmap->mapping;
2102   PetscFunctionReturn(0);
2103 }
2104 
2105 /*@
2106    MatGetLayouts - Gets the PetscLayout objects for rows and columns
2107 
2108    Not Collective
2109 
2110    Input Parameters:
2111 .  A - the matrix
2112 
2113    Output Parameters:
2114 + rmap - row layout
2115 - cmap - column layout
2116 
2117    Level: advanced
2118 
2119 .seealso:  MatCreateVecs(), MatGetLocalToGlobalMapping()
2120 @*/
2121 PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap)
2122 {
2123   PetscFunctionBegin;
2124   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2125   PetscValidType(A,1);
2126   if (rmap) PetscValidPointer(rmap,2);
2127   if (cmap) PetscValidPointer(cmap,3);
2128   if (rmap) *rmap = A->rmap;
2129   if (cmap) *cmap = A->cmap;
2130   PetscFunctionReturn(0);
2131 }
2132 
2133 /*@C
2134    MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
2135    using a local ordering of the nodes.
2136 
2137    Not Collective
2138 
2139    Input Parameters:
2140 +  mat - the matrix
2141 .  nrow, irow - number of rows and their local indices
2142 .  ncol, icol - number of columns and their local indices
2143 .  y -  a logically two-dimensional array of values
2144 -  addv - either INSERT_VALUES or ADD_VALUES, where
2145    ADD_VALUES adds values to any existing entries, and
2146    INSERT_VALUES replaces existing entries with new values
2147 
2148    Notes:
2149    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
2150       MatSetUp() before using this routine
2151 
2152    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine
2153 
2154    Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
2155    options cannot be mixed without intervening calls to the assembly
2156    routines.
2157 
2158    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2159    MUST be called after all calls to MatSetValuesLocal() have been completed.
2160 
2161    Level: intermediate
2162 
2163    Concepts: matrices^putting entries in with local numbering
2164 
2165    Developer Notes:
2166     This is labeled with C so does not automatically generate Fortran stubs and interfaces
2167                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
2168 
2169 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
2170            MatSetValueLocal()
2171 @*/
2172 PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2173 {
2174   PetscErrorCode ierr;
2175 
2176   PetscFunctionBeginHot;
2177   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2178   PetscValidType(mat,1);
2179   MatCheckPreallocated(mat,1);
2180   if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */
2181   PetscValidIntPointer(irow,3);
2182   PetscValidIntPointer(icol,5);
2183   PetscValidScalarPointer(y,6);
2184   if (mat->insertmode == NOT_SET_VALUES) {
2185     mat->insertmode = addv;
2186   }
2187 #if defined(PETSC_USE_DEBUG)
2188   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2189   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2190   if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2191 #endif
2192 
2193   if (mat->assembled) {
2194     mat->was_assembled = PETSC_TRUE;
2195     mat->assembled     = PETSC_FALSE;
2196   }
2197   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2198   if (mat->ops->setvalueslocal) {
2199     ierr = (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr);
2200   } else {
2201     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2202     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2203       irowm = buf; icolm = buf+nrow;
2204     } else {
2205       ierr  = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr);
2206       irowm = bufr; icolm = bufc;
2207     }
2208     ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr);
2209     ierr = ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr);
2210     ierr = MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
2211     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
2212   }
2213   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2214 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
2215   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
2216     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
2217   }
2218 #endif
2219   PetscFunctionReturn(0);
2220 }
2221 
2222 /*@C
2223    MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix,
2224    using a local ordering of the nodes a block at a time.
2225 
2226    Not Collective
2227 
2228    Input Parameters:
2229 +  x - the matrix
2230 .  nrow, irow - number of rows and their local indices
2231 .  ncol, icol - number of columns and their local indices
2232 .  y -  a logically two-dimensional array of values
2233 -  addv - either INSERT_VALUES or ADD_VALUES, where
2234    ADD_VALUES adds values to any existing entries, and
2235    INSERT_VALUES replaces existing entries with new values
2236 
2237    Notes:
2238    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
2239       MatSetUp() before using this routine
2240 
2241    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMapping()
2242       before using this routineBefore calling MatSetValuesLocal(), the user must first set the
2243 
2244    Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
2245    options cannot be mixed without intervening calls to the assembly
2246    routines.
2247 
2248    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2249    MUST be called after all calls to MatSetValuesBlockedLocal() have been completed.
2250 
2251    Level: intermediate
2252 
2253    Developer Notes:
2254     This is labeled with C so does not automatically generate Fortran stubs and interfaces
2255                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
2256 
2257    Concepts: matrices^putting blocked values in with local numbering
2258 
2259 .seealso:  MatSetBlockSize(), MatSetLocalToGlobalMapping(), MatAssemblyBegin(), MatAssemblyEnd(),
2260            MatSetValuesLocal(),  MatSetValuesBlocked()
2261 @*/
2262 PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2263 {
2264   PetscErrorCode ierr;
2265 
2266   PetscFunctionBeginHot;
2267   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2268   PetscValidType(mat,1);
2269   MatCheckPreallocated(mat,1);
2270   if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */
2271   PetscValidIntPointer(irow,3);
2272   PetscValidIntPointer(icol,5);
2273   PetscValidScalarPointer(y,6);
2274   if (mat->insertmode == NOT_SET_VALUES) {
2275     mat->insertmode = addv;
2276   }
2277 #if defined(PETSC_USE_DEBUG)
2278   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2279   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2280   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);
2281 #endif
2282 
2283   if (mat->assembled) {
2284     mat->was_assembled = PETSC_TRUE;
2285     mat->assembled     = PETSC_FALSE;
2286   }
2287 #if defined(PETSC_USE_DEBUG)
2288   /* Condition on the mapping existing, because MatSetValuesBlockedLocal_IS does not require it to be set. */
2289   if (mat->rmap->mapping) {
2290     PetscInt irbs, rbs;
2291     ierr = MatGetBlockSizes(mat, &rbs, NULL);CHKERRQ(ierr);
2292     ierr = ISLocalToGlobalMappingGetBlockSize(mat->rmap->mapping,&irbs);CHKERRQ(ierr);
2293     if (rbs != irbs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different row block sizes! mat %D, row l2g map %D",rbs,irbs);
2294   }
2295   if (mat->cmap->mapping) {
2296     PetscInt icbs, cbs;
2297     ierr = MatGetBlockSizes(mat,NULL,&cbs);CHKERRQ(ierr);
2298     ierr = ISLocalToGlobalMappingGetBlockSize(mat->cmap->mapping,&icbs);CHKERRQ(ierr);
2299     if (cbs != icbs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different col block sizes! mat %D, col l2g map %D",cbs,icbs);
2300   }
2301 #endif
2302   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2303   if (mat->ops->setvaluesblockedlocal) {
2304     ierr = (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr);
2305   } else {
2306     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2307     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2308       irowm = buf; icolm = buf + nrow;
2309     } else {
2310       ierr  = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr);
2311       irowm = bufr; icolm = bufc;
2312     }
2313     ierr = ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr);
2314     ierr = ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr);
2315     ierr = MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
2316     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
2317   }
2318   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2319 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
2320   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
2321     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
2322   }
2323 #endif
2324   PetscFunctionReturn(0);
2325 }
2326 
2327 /*@
2328    MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal
2329 
2330    Collective on Mat and Vec
2331 
2332    Input Parameters:
2333 +  mat - the matrix
2334 -  x   - the vector to be multiplied
2335 
2336    Output Parameters:
2337 .  y - the result
2338 
2339    Notes:
2340    The vectors x and y cannot be the same.  I.e., one cannot
2341    call MatMult(A,y,y).
2342 
2343    Level: developer
2344 
2345    Concepts: matrix-vector product
2346 
2347 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2348 @*/
2349 PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y)
2350 {
2351   PetscErrorCode ierr;
2352 
2353   PetscFunctionBegin;
2354   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2355   PetscValidType(mat,1);
2356   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2357   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2358 
2359   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2360   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2361   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2362   MatCheckPreallocated(mat,1);
2363 
2364   if (!mat->ops->multdiagonalblock) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2365   ierr = (*mat->ops->multdiagonalblock)(mat,x,y);CHKERRQ(ierr);
2366   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2367   PetscFunctionReturn(0);
2368 }
2369 
2370 /* --------------------------------------------------------*/
2371 /*@
2372    MatMult - Computes the matrix-vector product, y = Ax.
2373 
2374    Neighbor-wise Collective on Mat and Vec
2375 
2376    Input Parameters:
2377 +  mat - the matrix
2378 -  x   - the vector to be multiplied
2379 
2380    Output Parameters:
2381 .  y - the result
2382 
2383    Notes:
2384    The vectors x and y cannot be the same.  I.e., one cannot
2385    call MatMult(A,y,y).
2386 
2387    Level: beginner
2388 
2389    Concepts: matrix-vector product
2390 
2391 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2392 @*/
2393 PetscErrorCode MatMult(Mat mat,Vec x,Vec y)
2394 {
2395   PetscErrorCode ierr;
2396 
2397   PetscFunctionBegin;
2398   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2399   PetscValidType(mat,1);
2400   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2401   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2402   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2403   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2404   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2405 #if !defined(PETSC_HAVE_CONSTRAINTS)
2406   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);
2407   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);
2408   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);
2409 #endif
2410   ierr = VecSetErrorIfLocked(y,3);CHKERRQ(ierr);
2411   if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);}
2412   MatCheckPreallocated(mat,1);
2413 
2414   ierr = VecLockReadPush(x);CHKERRQ(ierr);
2415   if (!mat->ops->mult) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2416   ierr = PetscLogEventBegin(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
2417   ierr = (*mat->ops->mult)(mat,x,y);CHKERRQ(ierr);
2418   ierr = PetscLogEventEnd(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
2419   if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);}
2420   ierr = VecLockReadPop(x);CHKERRQ(ierr);
2421   PetscFunctionReturn(0);
2422 }
2423 
2424 /*@
2425    MatMultTranspose - Computes matrix transpose times a vector y = A^T * x.
2426 
2427    Neighbor-wise Collective on Mat and Vec
2428 
2429    Input Parameters:
2430 +  mat - the matrix
2431 -  x   - the vector to be multiplied
2432 
2433    Output Parameters:
2434 .  y - the result
2435 
2436    Notes:
2437    The vectors x and y cannot be the same.  I.e., one cannot
2438    call MatMultTranspose(A,y,y).
2439 
2440    For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple,
2441    use MatMultHermitianTranspose()
2442 
2443    Level: beginner
2444 
2445    Concepts: matrix vector product^transpose
2446 
2447 .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose()
2448 @*/
2449 PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y)
2450 {
2451   PetscErrorCode ierr;
2452 
2453   PetscFunctionBegin;
2454   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2455   PetscValidType(mat,1);
2456   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2457   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2458 
2459   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2460   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2461   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2462 #if !defined(PETSC_HAVE_CONSTRAINTS)
2463   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);
2464   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);
2465 #endif
2466   if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);}
2467   MatCheckPreallocated(mat,1);
2468 
2469   if (!mat->ops->multtranspose) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply transpose defined");
2470   ierr = PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
2471   ierr = VecLockReadPush(x);CHKERRQ(ierr);
2472   ierr = (*mat->ops->multtranspose)(mat,x,y);CHKERRQ(ierr);
2473   ierr = VecLockReadPop(x);CHKERRQ(ierr);
2474   ierr = PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
2475   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2476   if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);}
2477   PetscFunctionReturn(0);
2478 }
2479 
2480 /*@
2481    MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.
2482 
2483    Neighbor-wise Collective on Mat and Vec
2484 
2485    Input Parameters:
2486 +  mat - the matrix
2487 -  x   - the vector to be multilplied
2488 
2489    Output Parameters:
2490 .  y - the result
2491 
2492    Notes:
2493    The vectors x and y cannot be the same.  I.e., one cannot
2494    call MatMultHermitianTranspose(A,y,y).
2495 
2496    Also called the conjugate transpose, complex conjugate transpose, or adjoint.
2497 
2498    For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical.
2499 
2500    Level: beginner
2501 
2502    Concepts: matrix vector product^transpose
2503 
2504 .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose()
2505 @*/
2506 PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y)
2507 {
2508   PetscErrorCode ierr;
2509   Vec            w;
2510 
2511   PetscFunctionBegin;
2512   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2513   PetscValidType(mat,1);
2514   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2515   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2516 
2517   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2518   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2519   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2520 #if !defined(PETSC_HAVE_CONSTRAINTS)
2521   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);
2522   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);
2523 #endif
2524   MatCheckPreallocated(mat,1);
2525 
2526   ierr = PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr);
2527   if (mat->ops->multhermitiantranspose) {
2528     ierr = VecLockReadPush(x);CHKERRQ(ierr);
2529     ierr = (*mat->ops->multhermitiantranspose)(mat,x,y);CHKERRQ(ierr);
2530     ierr = VecLockReadPop(x);CHKERRQ(ierr);
2531   } else {
2532     ierr = VecDuplicate(x,&w);CHKERRQ(ierr);
2533     ierr = VecCopy(x,w);CHKERRQ(ierr);
2534     ierr = VecConjugate(w);CHKERRQ(ierr);
2535     ierr = MatMultTranspose(mat,w,y);CHKERRQ(ierr);
2536     ierr = VecDestroy(&w);CHKERRQ(ierr);
2537     ierr = VecConjugate(y);CHKERRQ(ierr);
2538   }
2539   ierr = PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr);
2540   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2541   PetscFunctionReturn(0);
2542 }
2543 
2544 /*@
2545     MatMultAdd -  Computes v3 = v2 + A * v1.
2546 
2547     Neighbor-wise Collective on Mat and Vec
2548 
2549     Input Parameters:
2550 +   mat - the matrix
2551 -   v1, v2 - the vectors
2552 
2553     Output Parameters:
2554 .   v3 - the result
2555 
2556     Notes:
2557     The vectors v1 and v3 cannot be the same.  I.e., one cannot
2558     call MatMultAdd(A,v1,v2,v1).
2559 
2560     Level: beginner
2561 
2562     Concepts: matrix vector product^addition
2563 
2564 .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
2565 @*/
2566 PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2567 {
2568   PetscErrorCode ierr;
2569 
2570   PetscFunctionBegin;
2571   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2572   PetscValidType(mat,1);
2573   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2574   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2575   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2576 
2577   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2578   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2579   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);
2580   /* 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);
2581      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); */
2582   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);
2583   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);
2584   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2585   MatCheckPreallocated(mat,1);
2586 
2587   if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name);
2588   ierr = PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2589   ierr = VecLockReadPush(v1);CHKERRQ(ierr);
2590   ierr = (*mat->ops->multadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2591   ierr = VecLockReadPop(v1);CHKERRQ(ierr);
2592   ierr = PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2593   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2594   PetscFunctionReturn(0);
2595 }
2596 
2597 /*@
2598    MatMultTransposeAdd - Computes v3 = v2 + A' * v1.
2599 
2600    Neighbor-wise Collective on Mat and Vec
2601 
2602    Input Parameters:
2603 +  mat - the matrix
2604 -  v1, v2 - the vectors
2605 
2606    Output Parameters:
2607 .  v3 - the result
2608 
2609    Notes:
2610    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2611    call MatMultTransposeAdd(A,v1,v2,v1).
2612 
2613    Level: beginner
2614 
2615    Concepts: matrix vector product^transpose and addition
2616 
2617 .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
2618 @*/
2619 PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2620 {
2621   PetscErrorCode ierr;
2622 
2623   PetscFunctionBegin;
2624   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2625   PetscValidType(mat,1);
2626   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2627   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2628   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2629 
2630   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2631   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2632   if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2633   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2634   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);
2635   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);
2636   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);
2637   MatCheckPreallocated(mat,1);
2638 
2639   ierr = PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2640   ierr = VecLockReadPush(v1);CHKERRQ(ierr);
2641   ierr = (*mat->ops->multtransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2642   ierr = VecLockReadPop(v1);CHKERRQ(ierr);
2643   ierr = PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2644   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2645   PetscFunctionReturn(0);
2646 }
2647 
2648 /*@
2649    MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1.
2650 
2651    Neighbor-wise Collective on Mat and Vec
2652 
2653    Input Parameters:
2654 +  mat - the matrix
2655 -  v1, v2 - the vectors
2656 
2657    Output Parameters:
2658 .  v3 - the result
2659 
2660    Notes:
2661    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2662    call MatMultHermitianTransposeAdd(A,v1,v2,v1).
2663 
2664    Level: beginner
2665 
2666    Concepts: matrix vector product^transpose and addition
2667 
2668 .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult()
2669 @*/
2670 PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2671 {
2672   PetscErrorCode ierr;
2673 
2674   PetscFunctionBegin;
2675   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2676   PetscValidType(mat,1);
2677   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2678   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2679   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2680 
2681   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2682   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2683   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2684   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);
2685   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);
2686   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);
2687   MatCheckPreallocated(mat,1);
2688 
2689   ierr = PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2690   ierr = VecLockReadPush(v1);CHKERRQ(ierr);
2691   if (mat->ops->multhermitiantransposeadd) {
2692     ierr = (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2693   } else {
2694     Vec w,z;
2695     ierr = VecDuplicate(v1,&w);CHKERRQ(ierr);
2696     ierr = VecCopy(v1,w);CHKERRQ(ierr);
2697     ierr = VecConjugate(w);CHKERRQ(ierr);
2698     ierr = VecDuplicate(v3,&z);CHKERRQ(ierr);
2699     ierr = MatMultTranspose(mat,w,z);CHKERRQ(ierr);
2700     ierr = VecDestroy(&w);CHKERRQ(ierr);
2701     ierr = VecConjugate(z);CHKERRQ(ierr);
2702     if (v2 != v3) {
2703       ierr = VecWAXPY(v3,1.0,v2,z);CHKERRQ(ierr);
2704     } else {
2705       ierr = VecAXPY(v3,1.0,z);CHKERRQ(ierr);
2706     }
2707     ierr = VecDestroy(&z);CHKERRQ(ierr);
2708   }
2709   ierr = VecLockReadPop(v1);CHKERRQ(ierr);
2710   ierr = PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2711   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2712   PetscFunctionReturn(0);
2713 }
2714 
2715 /*@
2716    MatMultConstrained - The inner multiplication routine for a
2717    constrained matrix P^T A P.
2718 
2719    Neighbor-wise Collective on Mat and Vec
2720 
2721    Input Parameters:
2722 +  mat - the matrix
2723 -  x   - the vector to be multilplied
2724 
2725    Output Parameters:
2726 .  y - the result
2727 
2728    Notes:
2729    The vectors x and y cannot be the same.  I.e., one cannot
2730    call MatMult(A,y,y).
2731 
2732    Level: beginner
2733 
2734 .keywords: matrix, multiply, matrix-vector product, constraint
2735 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2736 @*/
2737 PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y)
2738 {
2739   PetscErrorCode ierr;
2740 
2741   PetscFunctionBegin;
2742   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2743   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2744   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2745   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2746   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2747   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2748   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);
2749   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);
2750   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);
2751 
2752   ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2753   ierr = VecLockReadPush(x);CHKERRQ(ierr);
2754   ierr = (*mat->ops->multconstrained)(mat,x,y);CHKERRQ(ierr);
2755   ierr = VecLockReadPop(x);CHKERRQ(ierr);
2756   ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2757   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2758   PetscFunctionReturn(0);
2759 }
2760 
2761 /*@
2762    MatMultTransposeConstrained - The inner multiplication routine for a
2763    constrained matrix P^T A^T P.
2764 
2765    Neighbor-wise Collective on Mat and Vec
2766 
2767    Input Parameters:
2768 +  mat - the matrix
2769 -  x   - the vector to be multilplied
2770 
2771    Output Parameters:
2772 .  y - the result
2773 
2774    Notes:
2775    The vectors x and y cannot be the same.  I.e., one cannot
2776    call MatMult(A,y,y).
2777 
2778    Level: beginner
2779 
2780 .keywords: matrix, multiply, matrix-vector product, constraint
2781 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2782 @*/
2783 PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2784 {
2785   PetscErrorCode ierr;
2786 
2787   PetscFunctionBegin;
2788   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2789   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2790   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2791   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2792   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2793   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2794   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);
2795   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);
2796 
2797   ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2798   ierr = (*mat->ops->multtransposeconstrained)(mat,x,y);CHKERRQ(ierr);
2799   ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2800   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2801   PetscFunctionReturn(0);
2802 }
2803 
2804 /*@C
2805    MatGetFactorType - gets the type of factorization it is
2806 
2807    Not Collective
2808 
2809    Input Parameters:
2810 .  mat - the matrix
2811 
2812    Output Parameters:
2813 .  t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT
2814 
2815    Level: intermediate
2816 
2817 .seealso: MatFactorType, MatGetFactor(), MatSetFactorType()
2818 @*/
2819 PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t)
2820 {
2821   PetscFunctionBegin;
2822   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2823   PetscValidType(mat,1);
2824   PetscValidPointer(t,2);
2825   *t = mat->factortype;
2826   PetscFunctionReturn(0);
2827 }
2828 
2829 /*@C
2830    MatSetFactorType - sets the type of factorization it is
2831 
2832    Logically Collective on Mat
2833 
2834    Input Parameters:
2835 +  mat - the matrix
2836 -  t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT
2837 
2838    Level: intermediate
2839 
2840 .seealso: MatFactorType, MatGetFactor(), MatGetFactorType()
2841 @*/
2842 PetscErrorCode MatSetFactorType(Mat mat, MatFactorType t)
2843 {
2844   PetscFunctionBegin;
2845   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2846   PetscValidType(mat,1);
2847   mat->factortype = t;
2848   PetscFunctionReturn(0);
2849 }
2850 
2851 /* ------------------------------------------------------------*/
2852 /*@C
2853    MatGetInfo - Returns information about matrix storage (number of
2854    nonzeros, memory, etc.).
2855 
2856    Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag
2857 
2858    Input Parameters:
2859 .  mat - the matrix
2860 
2861    Output Parameters:
2862 +  flag - flag indicating the type of parameters to be returned
2863    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2864    MAT_GLOBAL_SUM - sum over all processors)
2865 -  info - matrix information context
2866 
2867    Notes:
2868    The MatInfo context contains a variety of matrix data, including
2869    number of nonzeros allocated and used, number of mallocs during
2870    matrix assembly, etc.  Additional information for factored matrices
2871    is provided (such as the fill ratio, number of mallocs during
2872    factorization, etc.).  Much of this info is printed to PETSC_STDOUT
2873    when using the runtime options
2874 $       -info -mat_view ::ascii_info
2875 
2876    Example for C/C++ Users:
2877    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2878    data within the MatInfo context.  For example,
2879 .vb
2880       MatInfo info;
2881       Mat     A;
2882       double  mal, nz_a, nz_u;
2883 
2884       MatGetInfo(A,MAT_LOCAL,&info);
2885       mal  = info.mallocs;
2886       nz_a = info.nz_allocated;
2887 .ve
2888 
2889    Example for Fortran Users:
2890    Fortran users should declare info as a double precision
2891    array of dimension MAT_INFO_SIZE, and then extract the parameters
2892    of interest.  See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h
2893    a complete list of parameter names.
2894 .vb
2895       double  precision info(MAT_INFO_SIZE)
2896       double  precision mal, nz_a
2897       Mat     A
2898       integer ierr
2899 
2900       call MatGetInfo(A,MAT_LOCAL,info,ierr)
2901       mal = info(MAT_INFO_MALLOCS)
2902       nz_a = info(MAT_INFO_NZ_ALLOCATED)
2903 .ve
2904 
2905     Level: intermediate
2906 
2907     Concepts: matrices^getting information on
2908 
2909     Developer Note: fortran interface is not autogenerated as the f90
2910     interface defintion cannot be generated correctly [due to MatInfo]
2911 
2912 .seealso: MatStashGetInfo()
2913 
2914 @*/
2915 PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2916 {
2917   PetscErrorCode ierr;
2918 
2919   PetscFunctionBegin;
2920   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2921   PetscValidType(mat,1);
2922   PetscValidPointer(info,3);
2923   if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2924   MatCheckPreallocated(mat,1);
2925   ierr = (*mat->ops->getinfo)(mat,flag,info);CHKERRQ(ierr);
2926   PetscFunctionReturn(0);
2927 }
2928 
2929 /*
2930    This is used by external packages where it is not easy to get the info from the actual
2931    matrix factorization.
2932 */
2933 PetscErrorCode MatGetInfo_External(Mat A,MatInfoType flag,MatInfo *info)
2934 {
2935   PetscErrorCode ierr;
2936 
2937   PetscFunctionBegin;
2938   ierr = PetscMemzero(info,sizeof(MatInfo));CHKERRQ(ierr);
2939   PetscFunctionReturn(0);
2940 }
2941 
2942 /* ----------------------------------------------------------*/
2943 
2944 /*@C
2945    MatLUFactor - Performs in-place LU factorization of matrix.
2946 
2947    Collective on Mat
2948 
2949    Input Parameters:
2950 +  mat - the matrix
2951 .  row - row permutation
2952 .  col - column permutation
2953 -  info - options for factorization, includes
2954 $          fill - expected fill as ratio of original fill.
2955 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2956 $                   Run with the option -info to determine an optimal value to use
2957 
2958    Notes:
2959    Most users should employ the simplified KSP interface for linear solvers
2960    instead of working directly with matrix algebra routines such as this.
2961    See, e.g., KSPCreate().
2962 
2963    This changes the state of the matrix to a factored matrix; it cannot be used
2964    for example with MatSetValues() unless one first calls MatSetUnfactored().
2965 
2966    Level: developer
2967 
2968    Concepts: matrices^LU factorization
2969 
2970 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2971           MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor()
2972 
2973     Developer Note: fortran interface is not autogenerated as the f90
2974     interface defintion cannot be generated correctly [due to MatFactorInfo]
2975 
2976 @*/
2977 PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2978 {
2979   PetscErrorCode ierr;
2980   MatFactorInfo  tinfo;
2981 
2982   PetscFunctionBegin;
2983   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2984   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
2985   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
2986   if (info) PetscValidPointer(info,4);
2987   PetscValidType(mat,1);
2988   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2989   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2990   if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2991   MatCheckPreallocated(mat,1);
2992   if (!info) {
2993     ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr);
2994     info = &tinfo;
2995   }
2996 
2997   ierr = PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
2998   ierr = (*mat->ops->lufactor)(mat,row,col,info);CHKERRQ(ierr);
2999   ierr = PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
3000   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
3001   PetscFunctionReturn(0);
3002 }
3003 
3004 /*@C
3005    MatILUFactor - Performs in-place ILU factorization of matrix.
3006 
3007    Collective on Mat
3008 
3009    Input Parameters:
3010 +  mat - the matrix
3011 .  row - row permutation
3012 .  col - column permutation
3013 -  info - structure containing
3014 $      levels - number of levels of fill.
3015 $      expected fill - as ratio of original fill.
3016 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
3017                 missing diagonal entries)
3018 
3019    Notes:
3020    Probably really in-place only when level of fill is zero, otherwise allocates
3021    new space to store factored matrix and deletes previous memory.
3022 
3023    Most users should employ the simplified KSP interface for linear solvers
3024    instead of working directly with matrix algebra routines such as this.
3025    See, e.g., KSPCreate().
3026 
3027    Level: developer
3028 
3029    Concepts: matrices^ILU factorization
3030 
3031 .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
3032 
3033     Developer Note: fortran interface is not autogenerated as the f90
3034     interface defintion cannot be generated correctly [due to MatFactorInfo]
3035 
3036 @*/
3037 PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
3038 {
3039   PetscErrorCode ierr;
3040 
3041   PetscFunctionBegin;
3042   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3043   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
3044   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
3045   PetscValidPointer(info,4);
3046   PetscValidType(mat,1);
3047   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
3048   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3049   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3050   if (!mat->ops->ilufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3051   MatCheckPreallocated(mat,1);
3052 
3053   ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
3054   ierr = (*mat->ops->ilufactor)(mat,row,col,info);CHKERRQ(ierr);
3055   ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
3056   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
3057   PetscFunctionReturn(0);
3058 }
3059 
3060 /*@C
3061    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
3062    Call this routine before calling MatLUFactorNumeric().
3063 
3064    Collective on Mat
3065 
3066    Input Parameters:
3067 +  fact - the factor matrix obtained with MatGetFactor()
3068 .  mat - the matrix
3069 .  row, col - row and column permutations
3070 -  info - options for factorization, includes
3071 $          fill - expected fill as ratio of original fill.
3072 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3073 $                   Run with the option -info to determine an optimal value to use
3074 
3075 
3076    Notes:
3077     See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
3078 
3079    Most users should employ the simplified KSP interface for linear solvers
3080    instead of working directly with matrix algebra routines such as this.
3081    See, e.g., KSPCreate().
3082 
3083    Level: developer
3084 
3085    Concepts: matrices^LU symbolic factorization
3086 
3087 .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo, MatFactorInfoInitialize()
3088 
3089     Developer Note: fortran interface is not autogenerated as the f90
3090     interface defintion cannot be generated correctly [due to MatFactorInfo]
3091 
3092 @*/
3093 PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
3094 {
3095   PetscErrorCode ierr;
3096 
3097   PetscFunctionBegin;
3098   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3099   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
3100   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
3101   if (info) PetscValidPointer(info,4);
3102   PetscValidType(mat,1);
3103   PetscValidPointer(fact,5);
3104   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3105   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3106   if (!(fact)->ops->lufactorsymbolic) {
3107     MatSolverType spackage;
3108     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
3109     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage);
3110   }
3111   MatCheckPreallocated(mat,2);
3112 
3113   ierr = PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
3114   ierr = (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
3115   ierr = PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
3116   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3117   PetscFunctionReturn(0);
3118 }
3119 
3120 /*@C
3121    MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
3122    Call this routine after first calling MatLUFactorSymbolic().
3123 
3124    Collective on Mat
3125 
3126    Input Parameters:
3127 +  fact - the factor matrix obtained with MatGetFactor()
3128 .  mat - the matrix
3129 -  info - options for factorization
3130 
3131    Notes:
3132    See MatLUFactor() for in-place factorization.  See
3133    MatCholeskyFactorNumeric() for the symmetric, positive definite case.
3134 
3135    Most users should employ the simplified KSP interface for linear solvers
3136    instead of working directly with matrix algebra routines such as this.
3137    See, e.g., KSPCreate().
3138 
3139    Level: developer
3140 
3141    Concepts: matrices^LU numeric factorization
3142 
3143 .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()
3144 
3145     Developer Note: fortran interface is not autogenerated as the f90
3146     interface defintion cannot be generated correctly [due to MatFactorInfo]
3147 
3148 @*/
3149 PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3150 {
3151   PetscErrorCode ierr;
3152 
3153   PetscFunctionBegin;
3154   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3155   PetscValidType(mat,1);
3156   PetscValidPointer(fact,2);
3157   PetscValidHeaderSpecific(fact,MAT_CLASSID,2);
3158   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3159   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);
3160 
3161   if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name);
3162   MatCheckPreallocated(mat,2);
3163   ierr = PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3164   ierr = (fact->ops->lufactornumeric)(fact,mat,info);CHKERRQ(ierr);
3165   ierr = PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3166   ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr);
3167   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3168   PetscFunctionReturn(0);
3169 }
3170 
3171 /*@C
3172    MatCholeskyFactor - Performs in-place Cholesky factorization of a
3173    symmetric matrix.
3174 
3175    Collective on Mat
3176 
3177    Input Parameters:
3178 +  mat - the matrix
3179 .  perm - row and column permutations
3180 -  f - expected fill as ratio of original fill
3181 
3182    Notes:
3183    See MatLUFactor() for the nonsymmetric case.  See also
3184    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().
3185 
3186    Most users should employ the simplified KSP interface for linear solvers
3187    instead of working directly with matrix algebra routines such as this.
3188    See, e.g., KSPCreate().
3189 
3190    Level: developer
3191 
3192    Concepts: matrices^Cholesky factorization
3193 
3194 .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
3195           MatGetOrdering()
3196 
3197     Developer Note: fortran interface is not autogenerated as the f90
3198     interface defintion cannot be generated correctly [due to MatFactorInfo]
3199 
3200 @*/
3201 PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
3202 {
3203   PetscErrorCode ierr;
3204 
3205   PetscFunctionBegin;
3206   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3207   PetscValidType(mat,1);
3208   if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2);
3209   if (info) PetscValidPointer(info,3);
3210   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3211   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3212   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3213   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);
3214   MatCheckPreallocated(mat,1);
3215 
3216   ierr = PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
3217   ierr = (*mat->ops->choleskyfactor)(mat,perm,info);CHKERRQ(ierr);
3218   ierr = PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
3219   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
3220   PetscFunctionReturn(0);
3221 }
3222 
3223 /*@C
3224    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
3225    of a symmetric matrix.
3226 
3227    Collective on Mat
3228 
3229    Input Parameters:
3230 +  fact - the factor matrix obtained with MatGetFactor()
3231 .  mat - the matrix
3232 .  perm - row and column permutations
3233 -  info - options for factorization, includes
3234 $          fill - expected fill as ratio of original fill.
3235 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3236 $                   Run with the option -info to determine an optimal value to use
3237 
3238    Notes:
3239    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
3240    MatCholeskyFactor() and MatCholeskyFactorNumeric().
3241 
3242    Most users should employ the simplified KSP interface for linear solvers
3243    instead of working directly with matrix algebra routines such as this.
3244    See, e.g., KSPCreate().
3245 
3246    Level: developer
3247 
3248    Concepts: matrices^Cholesky symbolic factorization
3249 
3250 .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
3251           MatGetOrdering()
3252 
3253     Developer Note: fortran interface is not autogenerated as the f90
3254     interface defintion cannot be generated correctly [due to MatFactorInfo]
3255 
3256 @*/
3257 PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
3258 {
3259   PetscErrorCode ierr;
3260 
3261   PetscFunctionBegin;
3262   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3263   PetscValidType(mat,1);
3264   if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2);
3265   if (info) PetscValidPointer(info,3);
3266   PetscValidPointer(fact,4);
3267   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3268   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3269   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3270   if (!(fact)->ops->choleskyfactorsymbolic) {
3271     MatSolverType spackage;
3272     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
3273     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage);
3274   }
3275   MatCheckPreallocated(mat,2);
3276 
3277   ierr = PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
3278   ierr = (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
3279   ierr = PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
3280   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3281   PetscFunctionReturn(0);
3282 }
3283 
3284 /*@C
3285    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
3286    of a symmetric matrix. Call this routine after first calling
3287    MatCholeskyFactorSymbolic().
3288 
3289    Collective on Mat
3290 
3291    Input Parameters:
3292 +  fact - the factor matrix obtained with MatGetFactor()
3293 .  mat - the initial matrix
3294 .  info - options for factorization
3295 -  fact - the symbolic factor of mat
3296 
3297 
3298    Notes:
3299    Most users should employ the simplified KSP interface for linear solvers
3300    instead of working directly with matrix algebra routines such as this.
3301    See, e.g., KSPCreate().
3302 
3303    Level: developer
3304 
3305    Concepts: matrices^Cholesky numeric factorization
3306 
3307 .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
3308 
3309     Developer Note: fortran interface is not autogenerated as the f90
3310     interface defintion cannot be generated correctly [due to MatFactorInfo]
3311 
3312 @*/
3313 PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3314 {
3315   PetscErrorCode ierr;
3316 
3317   PetscFunctionBegin;
3318   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3319   PetscValidType(mat,1);
3320   PetscValidPointer(fact,2);
3321   PetscValidHeaderSpecific(fact,MAT_CLASSID,2);
3322   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3323   if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name);
3324   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);
3325   MatCheckPreallocated(mat,2);
3326 
3327   ierr = PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3328   ierr = (fact->ops->choleskyfactornumeric)(fact,mat,info);CHKERRQ(ierr);
3329   ierr = PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3330   ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr);
3331   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3332   PetscFunctionReturn(0);
3333 }
3334 
3335 /* ----------------------------------------------------------------*/
3336 /*@
3337    MatSolve - Solves A x = b, given a factored matrix.
3338 
3339    Neighbor-wise Collective on Mat and Vec
3340 
3341    Input Parameters:
3342 +  mat - the factored matrix
3343 -  b - the right-hand-side vector
3344 
3345    Output Parameter:
3346 .  x - the result vector
3347 
3348    Notes:
3349    The vectors b and x cannot be the same.  I.e., one cannot
3350    call MatSolve(A,x,x).
3351 
3352    Notes:
3353    Most users should employ the simplified KSP interface for linear solvers
3354    instead of working directly with matrix algebra routines such as this.
3355    See, e.g., KSPCreate().
3356 
3357    Level: developer
3358 
3359    Concepts: matrices^triangular solves
3360 
3361 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
3362 @*/
3363 PetscErrorCode MatSolve(Mat mat,Vec b,Vec x)
3364 {
3365   PetscErrorCode ierr;
3366 
3367   PetscFunctionBegin;
3368   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3369   PetscValidType(mat,1);
3370   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3371   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3372   PetscCheckSameComm(mat,1,b,2);
3373   PetscCheckSameComm(mat,1,x,3);
3374   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3375   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);
3376   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);
3377   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);
3378   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3379   if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3380   MatCheckPreallocated(mat,1);
3381 
3382   ierr = PetscLogEventBegin(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
3383   if (mat->factorerrortype) {
3384     ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3385     ierr = VecSetInf(x);CHKERRQ(ierr);
3386   } else {
3387     if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3388     ierr = (*mat->ops->solve)(mat,b,x);CHKERRQ(ierr);
3389   }
3390   ierr = PetscLogEventEnd(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
3391   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3392   PetscFunctionReturn(0);
3393 }
3394 
3395 static PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X, PetscBool trans)
3396 {
3397   PetscErrorCode ierr;
3398   Vec            b,x;
3399   PetscInt       m,N,i;
3400   PetscScalar    *bb,*xx;
3401   PetscBool      flg;
3402 
3403   PetscFunctionBegin;
3404   ierr = PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr);
3405   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
3406   ierr = PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr);
3407   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");
3408 
3409   ierr = MatDenseGetArray(B,&bb);CHKERRQ(ierr);
3410   ierr = MatDenseGetArray(X,&xx);CHKERRQ(ierr);
3411   ierr = MatGetLocalSize(B,&m,NULL);CHKERRQ(ierr);  /* number local rows */
3412   ierr = MatGetSize(B,NULL,&N);CHKERRQ(ierr);       /* total columns in dense matrix */
3413   ierr = MatCreateVecs(A,&x,&b);CHKERRQ(ierr);
3414   for (i=0; i<N; i++) {
3415     ierr = VecPlaceArray(b,bb + i*m);CHKERRQ(ierr);
3416     ierr = VecPlaceArray(x,xx + i*m);CHKERRQ(ierr);
3417     if (trans) {
3418       ierr = MatSolveTranspose(A,b,x);CHKERRQ(ierr);
3419     } else {
3420       ierr = MatSolve(A,b,x);CHKERRQ(ierr);
3421     }
3422     ierr = VecResetArray(x);CHKERRQ(ierr);
3423     ierr = VecResetArray(b);CHKERRQ(ierr);
3424   }
3425   ierr = VecDestroy(&b);CHKERRQ(ierr);
3426   ierr = VecDestroy(&x);CHKERRQ(ierr);
3427   ierr = MatDenseRestoreArray(B,&bb);CHKERRQ(ierr);
3428   ierr = MatDenseRestoreArray(X,&xx);CHKERRQ(ierr);
3429   PetscFunctionReturn(0);
3430 }
3431 
3432 /*@
3433    MatMatSolve - Solves A X = B, given a factored matrix.
3434 
3435    Neighbor-wise Collective on Mat
3436 
3437    Input Parameters:
3438 +  A - the factored matrix
3439 -  B - the right-hand-side matrix  (dense matrix)
3440 
3441    Output Parameter:
3442 .  X - the result matrix (dense matrix)
3443 
3444    Notes:
3445    The matrices b and x cannot be the same.  I.e., one cannot
3446    call MatMatSolve(A,x,x).
3447 
3448    Notes:
3449    Most users should usually employ the simplified KSP interface for linear solvers
3450    instead of working directly with matrix algebra routines such as this.
3451    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3452    at a time.
3453 
3454    When using SuperLU_Dist as a parallel solver PETSc will use the SuperLU_Dist functionality to solve multiple right hand sides simultaneously. For MUMPS
3455    it calls a separate solve for each right hand side since MUMPS does not yet support distributed right hand sides.
3456 
3457    Since the resulting matrix X must always be dense we do not support sparse representation of the matrix B.
3458 
3459    Level: developer
3460 
3461    Concepts: matrices^triangular solves
3462 
3463 .seealso: MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor()
3464 @*/
3465 PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X)
3466 {
3467   PetscErrorCode ierr;
3468 
3469   PetscFunctionBegin;
3470   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3471   PetscValidType(A,1);
3472   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3473   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3474   PetscCheckSameComm(A,1,B,2);
3475   PetscCheckSameComm(A,1,X,3);
3476   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3477   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);
3478   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);
3479   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");
3480   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3481   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3482   MatCheckPreallocated(A,1);
3483 
3484   ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3485   if (!A->ops->matsolve) {
3486     ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name);CHKERRQ(ierr);
3487     ierr = MatMatSolve_Basic(A,B,X,PETSC_FALSE);CHKERRQ(ierr);
3488   } else {
3489     ierr = (*A->ops->matsolve)(A,B,X);CHKERRQ(ierr);
3490   }
3491   ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3492   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3493   PetscFunctionReturn(0);
3494 }
3495 
3496 /*@
3497    MatMatSolveTranspose - Solves A^T X = B, given a factored matrix.
3498 
3499    Neighbor-wise Collective on Mat
3500 
3501    Input Parameters:
3502 +  A - the factored matrix
3503 -  B - the right-hand-side matrix  (dense matrix)
3504 
3505    Output Parameter:
3506 .  X - the result matrix (dense matrix)
3507 
3508    Notes:
3509    The matrices B and X cannot be the same.  I.e., one cannot
3510    call MatMatSolveTranspose(A,X,X).
3511 
3512    Notes:
3513    Most users should usually employ the simplified KSP interface for linear solvers
3514    instead of working directly with matrix algebra routines such as this.
3515    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3516    at a time.
3517 
3518    When using SuperLU_Dist or MUMPS as a parallel solver, PETSc will use their functionality to solve multiple right hand sides simultaneously.
3519 
3520    Level: developer
3521 
3522    Concepts: matrices^triangular solves
3523 
3524 .seealso: MatMatSolve(), MatLUFactor(), MatCholeskyFactor()
3525 @*/
3526 PetscErrorCode MatMatSolveTranspose(Mat A,Mat B,Mat X)
3527 {
3528   PetscErrorCode ierr;
3529 
3530   PetscFunctionBegin;
3531   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3532   PetscValidType(A,1);
3533   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3534   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3535   PetscCheckSameComm(A,1,B,2);
3536   PetscCheckSameComm(A,1,X,3);
3537   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3538   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);
3539   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);
3540   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);
3541   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");
3542   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3543   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3544   MatCheckPreallocated(A,1);
3545 
3546   ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3547   if (!A->ops->matsolvetranspose) {
3548     ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolveTranspose\n",((PetscObject)A)->type_name);CHKERRQ(ierr);
3549     ierr = MatMatSolve_Basic(A,B,X,PETSC_TRUE);CHKERRQ(ierr);
3550   } else {
3551     ierr = (*A->ops->matsolvetranspose)(A,B,X);CHKERRQ(ierr);
3552   }
3553   ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3554   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3555   PetscFunctionReturn(0);
3556 }
3557 
3558 /*@
3559    MatMatTransposeSolve - Solves A X = B^T, given a factored matrix.
3560 
3561    Neighbor-wise Collective on Mat
3562 
3563    Input Parameters:
3564 +  A - the factored matrix
3565 -  Bt - the transpose of right-hand-side matrix
3566 
3567    Output Parameter:
3568 .  X - the result matrix (dense matrix)
3569 
3570    Notes:
3571    Most users should usually employ the simplified KSP interface for linear solvers
3572    instead of working directly with matrix algebra routines such as this.
3573    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3574    at a time.
3575 
3576    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().
3577 
3578    Level: developer
3579 
3580    Concepts: matrices^triangular solves
3581 
3582 .seealso: MatMatSolve(), MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor()
3583 @*/
3584 PetscErrorCode MatMatTransposeSolve(Mat A,Mat Bt,Mat X)
3585 {
3586   PetscErrorCode ierr;
3587 
3588   PetscFunctionBegin;
3589   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3590   PetscValidType(A,1);
3591   PetscValidHeaderSpecific(Bt,MAT_CLASSID,2);
3592   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3593   PetscCheckSameComm(A,1,Bt,2);
3594   PetscCheckSameComm(A,1,X,3);
3595 
3596   if (X == Bt) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3597   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);
3598   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);
3599   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");
3600   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3601   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3602   MatCheckPreallocated(A,1);
3603 
3604   if (!A->ops->mattransposesolve) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
3605   ierr = PetscLogEventBegin(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr);
3606   ierr = (*A->ops->mattransposesolve)(A,Bt,X);CHKERRQ(ierr);
3607   ierr = PetscLogEventEnd(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr);
3608   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3609   PetscFunctionReturn(0);
3610 }
3611 
3612 /*@
3613    MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or
3614                             U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U,
3615 
3616    Neighbor-wise Collective on Mat and Vec
3617 
3618    Input Parameters:
3619 +  mat - the factored matrix
3620 -  b - the right-hand-side vector
3621 
3622    Output Parameter:
3623 .  x - the result vector
3624 
3625    Notes:
3626    MatSolve() should be used for most applications, as it performs
3627    a forward solve followed by a backward solve.
3628 
3629    The vectors b and x cannot be the same,  i.e., one cannot
3630    call MatForwardSolve(A,x,x).
3631 
3632    For matrix in seqsbaij format with block size larger than 1,
3633    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3634    MatForwardSolve() solves U^T*D y = b, and
3635    MatBackwardSolve() solves U x = y.
3636    Thus they do not provide a symmetric preconditioner.
3637 
3638    Most users should employ the simplified KSP interface for linear solvers
3639    instead of working directly with matrix algebra routines such as this.
3640    See, e.g., KSPCreate().
3641 
3642    Level: developer
3643 
3644    Concepts: matrices^forward solves
3645 
3646 .seealso: MatSolve(), MatBackwardSolve()
3647 @*/
3648 PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x)
3649 {
3650   PetscErrorCode ierr;
3651 
3652   PetscFunctionBegin;
3653   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3654   PetscValidType(mat,1);
3655   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3656   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3657   PetscCheckSameComm(mat,1,b,2);
3658   PetscCheckSameComm(mat,1,x,3);
3659   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3660   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);
3661   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);
3662   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);
3663   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3664   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3665   MatCheckPreallocated(mat,1);
3666 
3667   if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3668   ierr = PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
3669   ierr = (*mat->ops->forwardsolve)(mat,b,x);CHKERRQ(ierr);
3670   ierr = PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
3671   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3672   PetscFunctionReturn(0);
3673 }
3674 
3675 /*@
3676    MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
3677                              D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U,
3678 
3679    Neighbor-wise Collective on Mat and Vec
3680 
3681    Input Parameters:
3682 +  mat - the factored matrix
3683 -  b - the right-hand-side vector
3684 
3685    Output Parameter:
3686 .  x - the result vector
3687 
3688    Notes:
3689    MatSolve() should be used for most applications, as it performs
3690    a forward solve followed by a backward solve.
3691 
3692    The vectors b and x cannot be the same.  I.e., one cannot
3693    call MatBackwardSolve(A,x,x).
3694 
3695    For matrix in seqsbaij format with block size larger than 1,
3696    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3697    MatForwardSolve() solves U^T*D y = b, and
3698    MatBackwardSolve() solves U x = y.
3699    Thus they do not provide a symmetric preconditioner.
3700 
3701    Most users should employ the simplified KSP interface for linear solvers
3702    instead of working directly with matrix algebra routines such as this.
3703    See, e.g., KSPCreate().
3704 
3705    Level: developer
3706 
3707    Concepts: matrices^backward solves
3708 
3709 .seealso: MatSolve(), MatForwardSolve()
3710 @*/
3711 PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x)
3712 {
3713   PetscErrorCode ierr;
3714 
3715   PetscFunctionBegin;
3716   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3717   PetscValidType(mat,1);
3718   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3719   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3720   PetscCheckSameComm(mat,1,b,2);
3721   PetscCheckSameComm(mat,1,x,3);
3722   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3723   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);
3724   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);
3725   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);
3726   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3727   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3728   MatCheckPreallocated(mat,1);
3729 
3730   if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3731   ierr = PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
3732   ierr = (*mat->ops->backwardsolve)(mat,b,x);CHKERRQ(ierr);
3733   ierr = PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
3734   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3735   PetscFunctionReturn(0);
3736 }
3737 
3738 /*@
3739    MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
3740 
3741    Neighbor-wise Collective on Mat and Vec
3742 
3743    Input Parameters:
3744 +  mat - the factored matrix
3745 .  b - the right-hand-side vector
3746 -  y - the vector to be added to
3747 
3748    Output Parameter:
3749 .  x - the result vector
3750 
3751    Notes:
3752    The vectors b and x cannot be the same.  I.e., one cannot
3753    call MatSolveAdd(A,x,y,x).
3754 
3755    Most users should employ the simplified KSP interface for linear solvers
3756    instead of working directly with matrix algebra routines such as this.
3757    See, e.g., KSPCreate().
3758 
3759    Level: developer
3760 
3761    Concepts: matrices^triangular solves
3762 
3763 .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3764 @*/
3765 PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3766 {
3767   PetscScalar    one = 1.0;
3768   Vec            tmp;
3769   PetscErrorCode ierr;
3770 
3771   PetscFunctionBegin;
3772   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3773   PetscValidType(mat,1);
3774   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3775   PetscValidHeaderSpecific(b,VEC_CLASSID,3);
3776   PetscValidHeaderSpecific(x,VEC_CLASSID,4);
3777   PetscCheckSameComm(mat,1,b,2);
3778   PetscCheckSameComm(mat,1,y,2);
3779   PetscCheckSameComm(mat,1,x,3);
3780   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3781   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);
3782   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);
3783   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);
3784   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);
3785   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);
3786   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3787   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3788   MatCheckPreallocated(mat,1);
3789 
3790   ierr = PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
3791   if (mat->ops->solveadd) {
3792     ierr = (*mat->ops->solveadd)(mat,b,y,x);CHKERRQ(ierr);
3793   } else {
3794     /* do the solve then the add manually */
3795     if (x != y) {
3796       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
3797       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
3798     } else {
3799       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
3800       ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr);
3801       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
3802       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
3803       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
3804       ierr = VecDestroy(&tmp);CHKERRQ(ierr);
3805     }
3806   }
3807   ierr = PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
3808   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3809   PetscFunctionReturn(0);
3810 }
3811 
3812 /*@
3813    MatSolveTranspose - Solves A' x = b, given a factored matrix.
3814 
3815    Neighbor-wise Collective on Mat and Vec
3816 
3817    Input Parameters:
3818 +  mat - the factored matrix
3819 -  b - the right-hand-side vector
3820 
3821    Output Parameter:
3822 .  x - the result vector
3823 
3824    Notes:
3825    The vectors b and x cannot be the same.  I.e., one cannot
3826    call MatSolveTranspose(A,x,x).
3827 
3828    Most users should employ the simplified KSP interface for linear solvers
3829    instead of working directly with matrix algebra routines such as this.
3830    See, e.g., KSPCreate().
3831 
3832    Level: developer
3833 
3834    Concepts: matrices^triangular solves
3835 
3836 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
3837 @*/
3838 PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x)
3839 {
3840   PetscErrorCode ierr;
3841 
3842   PetscFunctionBegin;
3843   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3844   PetscValidType(mat,1);
3845   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3846   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3847   PetscCheckSameComm(mat,1,b,2);
3848   PetscCheckSameComm(mat,1,x,3);
3849   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3850   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);
3851   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);
3852   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3853   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3854   MatCheckPreallocated(mat,1);
3855   ierr = PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
3856   if (mat->factorerrortype) {
3857     ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3858     ierr = VecSetInf(x);CHKERRQ(ierr);
3859   } else {
3860     if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3861     ierr = (*mat->ops->solvetranspose)(mat,b,x);CHKERRQ(ierr);
3862   }
3863   ierr = PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
3864   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3865   PetscFunctionReturn(0);
3866 }
3867 
3868 /*@
3869    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
3870                       factored matrix.
3871 
3872    Neighbor-wise Collective on Mat and Vec
3873 
3874    Input Parameters:
3875 +  mat - the factored matrix
3876 .  b - the right-hand-side vector
3877 -  y - the vector to be added to
3878 
3879    Output Parameter:
3880 .  x - the result vector
3881 
3882    Notes:
3883    The vectors b and x cannot be the same.  I.e., one cannot
3884    call MatSolveTransposeAdd(A,x,y,x).
3885 
3886    Most users should employ the simplified KSP interface for linear solvers
3887    instead of working directly with matrix algebra routines such as this.
3888    See, e.g., KSPCreate().
3889 
3890    Level: developer
3891 
3892    Concepts: matrices^triangular solves
3893 
3894 .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3895 @*/
3896 PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3897 {
3898   PetscScalar    one = 1.0;
3899   PetscErrorCode ierr;
3900   Vec            tmp;
3901 
3902   PetscFunctionBegin;
3903   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3904   PetscValidType(mat,1);
3905   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3906   PetscValidHeaderSpecific(b,VEC_CLASSID,3);
3907   PetscValidHeaderSpecific(x,VEC_CLASSID,4);
3908   PetscCheckSameComm(mat,1,b,2);
3909   PetscCheckSameComm(mat,1,y,3);
3910   PetscCheckSameComm(mat,1,x,4);
3911   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3912   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);
3913   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);
3914   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);
3915   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);
3916   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3917   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3918   MatCheckPreallocated(mat,1);
3919 
3920   ierr = PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
3921   if (mat->ops->solvetransposeadd) {
3922     if (mat->factorerrortype) {
3923       ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3924       ierr = VecSetInf(x);CHKERRQ(ierr);
3925     } else {
3926       ierr = (*mat->ops->solvetransposeadd)(mat,b,y,x);CHKERRQ(ierr);
3927     }
3928   } else {
3929     /* do the solve then the add manually */
3930     if (x != y) {
3931       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
3932       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
3933     } else {
3934       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
3935       ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr);
3936       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
3937       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
3938       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
3939       ierr = VecDestroy(&tmp);CHKERRQ(ierr);
3940     }
3941   }
3942   ierr = PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
3943   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3944   PetscFunctionReturn(0);
3945 }
3946 /* ----------------------------------------------------------------*/
3947 
3948 /*@
3949    MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps.
3950 
3951    Neighbor-wise Collective on Mat and Vec
3952 
3953    Input Parameters:
3954 +  mat - the matrix
3955 .  b - the right hand side
3956 .  omega - the relaxation factor
3957 .  flag - flag indicating the type of SOR (see below)
3958 .  shift -  diagonal shift
3959 .  its - the number of iterations
3960 -  lits - the number of local iterations
3961 
3962    Output Parameters:
3963 .  x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess)
3964 
3965    SOR Flags:
3966 .     SOR_FORWARD_SWEEP - forward SOR
3967 .     SOR_BACKWARD_SWEEP - backward SOR
3968 .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3969 .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR
3970 .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
3971 .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3972 .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
3973          upper/lower triangular part of matrix to
3974          vector (with omega)
3975 .     SOR_ZERO_INITIAL_GUESS - zero initial guess
3976 
3977    Notes:
3978    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3979    SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3980    on each processor.
3981 
3982    Application programmers will not generally use MatSOR() directly,
3983    but instead will employ the KSP/PC interface.
3984 
3985    Notes:
3986     for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing
3987 
3988    Notes for Advanced Users:
3989    The flags are implemented as bitwise inclusive or operations.
3990    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3991    to specify a zero initial guess for SSOR.
3992 
3993    Most users should employ the simplified KSP interface for linear solvers
3994    instead of working directly with matrix algebra routines such as this.
3995    See, e.g., KSPCreate().
3996 
3997    Vectors x and b CANNOT be the same
3998 
3999    Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes
4000 
4001    Level: developer
4002 
4003    Concepts: matrices^relaxation
4004    Concepts: matrices^SOR
4005    Concepts: matrices^Gauss-Seidel
4006 
4007 @*/
4008 PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
4009 {
4010   PetscErrorCode ierr;
4011 
4012   PetscFunctionBegin;
4013   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4014   PetscValidType(mat,1);
4015   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
4016   PetscValidHeaderSpecific(x,VEC_CLASSID,8);
4017   PetscCheckSameComm(mat,1,b,2);
4018   PetscCheckSameComm(mat,1,x,8);
4019   if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4020   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4021   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4022   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);
4023   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);
4024   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);
4025   if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
4026   if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
4027   if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");
4028 
4029   MatCheckPreallocated(mat,1);
4030   ierr = PetscLogEventBegin(MAT_SOR,mat,b,x,0);CHKERRQ(ierr);
4031   ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr);
4032   ierr = PetscLogEventEnd(MAT_SOR,mat,b,x,0);CHKERRQ(ierr);
4033   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
4034   PetscFunctionReturn(0);
4035 }
4036 
4037 /*
4038       Default matrix copy routine.
4039 */
4040 PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
4041 {
4042   PetscErrorCode    ierr;
4043   PetscInt          i,rstart = 0,rend = 0,nz;
4044   const PetscInt    *cwork;
4045   const PetscScalar *vwork;
4046 
4047   PetscFunctionBegin;
4048   if (B->assembled) {
4049     ierr = MatZeroEntries(B);CHKERRQ(ierr);
4050   }
4051   if (str == SAME_NONZERO_PATTERN) {
4052     ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
4053     for (i=rstart; i<rend; i++) {
4054       ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
4055       ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);CHKERRQ(ierr);
4056       ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
4057     }
4058   } else {
4059     ierr = MatAYPX(B,0.0,A,str);CHKERRQ(ierr);
4060   }
4061   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4062   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4063   PetscFunctionReturn(0);
4064 }
4065 
4066 /*@
4067    MatCopy - Copies a matrix to another matrix.
4068 
4069    Collective on Mat
4070 
4071    Input Parameters:
4072 +  A - the matrix
4073 -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
4074 
4075    Output Parameter:
4076 .  B - where the copy is put
4077 
4078    Notes:
4079    If you use SAME_NONZERO_PATTERN then the two matrices had better have the
4080    same nonzero pattern or the routine will crash.
4081 
4082    MatCopy() copies the matrix entries of a matrix to another existing
4083    matrix (after first zeroing the second matrix).  A related routine is
4084    MatConvert(), which first creates a new matrix and then copies the data.
4085 
4086    Level: intermediate
4087 
4088    Concepts: matrices^copying
4089 
4090 .seealso: MatConvert(), MatDuplicate()
4091 
4092 @*/
4093 PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str)
4094 {
4095   PetscErrorCode ierr;
4096   PetscInt       i;
4097 
4098   PetscFunctionBegin;
4099   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4100   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4101   PetscValidType(A,1);
4102   PetscValidType(B,2);
4103   PetscCheckSameComm(A,1,B,2);
4104   MatCheckPreallocated(B,2);
4105   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4106   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4107   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);
4108   MatCheckPreallocated(A,1);
4109   if (A == B) PetscFunctionReturn(0);
4110 
4111   ierr = PetscLogEventBegin(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
4112   if (A->ops->copy) {
4113     ierr = (*A->ops->copy)(A,B,str);CHKERRQ(ierr);
4114   } else { /* generic conversion */
4115     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
4116   }
4117 
4118   B->stencil.dim = A->stencil.dim;
4119   B->stencil.noc = A->stencil.noc;
4120   for (i=0; i<=A->stencil.dim; i++) {
4121     B->stencil.dims[i]   = A->stencil.dims[i];
4122     B->stencil.starts[i] = A->stencil.starts[i];
4123   }
4124 
4125   ierr = PetscLogEventEnd(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
4126   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
4127   PetscFunctionReturn(0);
4128 }
4129 
4130 /*@C
4131    MatConvert - Converts a matrix to another matrix, either of the same
4132    or different type.
4133 
4134    Collective on Mat
4135 
4136    Input Parameters:
4137 +  mat - the matrix
4138 .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
4139    same type as the original matrix.
4140 -  reuse - denotes if the destination matrix is to be created or reused.
4141    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
4142    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).
4143 
4144    Output Parameter:
4145 .  M - pointer to place new matrix
4146 
4147    Notes:
4148    MatConvert() first creates a new matrix and then copies the data from
4149    the first matrix.  A related routine is MatCopy(), which copies the matrix
4150    entries of one matrix to another already existing matrix context.
4151 
4152    Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
4153    the MPI communicator of the generated matrix is always the same as the communicator
4154    of the input matrix.
4155 
4156    Level: intermediate
4157 
4158    Concepts: matrices^converting between storage formats
4159 
4160 .seealso: MatCopy(), MatDuplicate()
4161 @*/
4162 PetscErrorCode MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M)
4163 {
4164   PetscErrorCode ierr;
4165   PetscBool      sametype,issame,flg;
4166   char           convname[256],mtype[256];
4167   Mat            B;
4168 
4169   PetscFunctionBegin;
4170   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4171   PetscValidType(mat,1);
4172   PetscValidPointer(M,3);
4173   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4174   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4175   MatCheckPreallocated(mat,1);
4176 
4177   ierr = PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);CHKERRQ(ierr);
4178   if (flg) {
4179     newtype = mtype;
4180   }
4181   ierr = PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);CHKERRQ(ierr);
4182   ierr = PetscStrcmp(newtype,"same",&issame);CHKERRQ(ierr);
4183   if ((reuse == MAT_INPLACE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix");
4184   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");
4185 
4186   if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) PetscFunctionReturn(0);
4187 
4188   if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
4189     ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
4190   } else {
4191     PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL;
4192     const char     *prefix[3] = {"seq","mpi",""};
4193     PetscInt       i;
4194     /*
4195        Order of precedence:
4196        0) See if newtype is a superclass of the current matrix.
4197        1) See if a specialized converter is known to the current matrix.
4198        2) See if a specialized converter is known to the desired matrix class.
4199        3) See if a good general converter is registered for the desired class
4200           (as of 6/27/03 only MATMPIADJ falls into this category).
4201        4) See if a good general converter is known for the current matrix.
4202        5) Use a really basic converter.
4203     */
4204 
4205     /* 0) See if newtype is a superclass of the current matrix.
4206           i.e mat is mpiaij and newtype is aij */
4207     for (i=0; i<2; i++) {
4208       ierr = PetscStrncpy(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4209       ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr);
4210       ierr = PetscStrcmp(convname,((PetscObject)mat)->type_name,&flg);CHKERRQ(ierr);
4211       ierr = PetscInfo3(mat,"Check superclass %s %s -> %d\n",convname,((PetscObject)mat)->type_name,flg);CHKERRQ(ierr);
4212       if (flg) {
4213         if (reuse == MAT_INPLACE_MATRIX) {
4214           PetscFunctionReturn(0);
4215         } else if (reuse == MAT_INITIAL_MATRIX && mat->ops->duplicate) {
4216           ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
4217           PetscFunctionReturn(0);
4218         } else if (reuse == MAT_REUSE_MATRIX && mat->ops->copy) {
4219           ierr = MatCopy(mat,*M,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
4220           PetscFunctionReturn(0);
4221         }
4222       }
4223     }
4224     /* 1) See if a specialized converter is known to the current matrix and the desired class */
4225     for (i=0; i<3; i++) {
4226       ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr);
4227       ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr);
4228       ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr);
4229       ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4230       ierr = PetscStrlcat(convname,issame ? ((PetscObject)mat)->type_name : newtype,sizeof(convname));CHKERRQ(ierr);
4231       ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr);
4232       ierr = PetscObjectQueryFunction((PetscObject)mat,convname,&conv);CHKERRQ(ierr);
4233       ierr = PetscInfo3(mat,"Check specialized (1) %s (%s) -> %d\n",convname,((PetscObject)mat)->type_name,!!conv);CHKERRQ(ierr);
4234       if (conv) goto foundconv;
4235     }
4236 
4237     /* 2)  See if a specialized converter is known to the desired matrix class. */
4238     ierr = MatCreate(PetscObjectComm((PetscObject)mat),&B);CHKERRQ(ierr);
4239     ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);CHKERRQ(ierr);
4240     ierr = MatSetType(B,newtype);CHKERRQ(ierr);
4241     for (i=0; i<3; i++) {
4242       ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr);
4243       ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr);
4244       ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr);
4245       ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4246       ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr);
4247       ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr);
4248       ierr = PetscObjectQueryFunction((PetscObject)B,convname,&conv);CHKERRQ(ierr);
4249       ierr = PetscInfo3(mat,"Check specialized (2) %s (%s) -> %d\n",convname,((PetscObject)B)->type_name,!!conv);CHKERRQ(ierr);
4250       if (conv) {
4251         ierr = MatDestroy(&B);CHKERRQ(ierr);
4252         goto foundconv;
4253       }
4254     }
4255 
4256     /* 3) See if a good general converter is registered for the desired class */
4257     conv = B->ops->convertfrom;
4258     ierr = PetscInfo2(mat,"Check convertfrom (%s) -> %d\n",((PetscObject)B)->type_name,!!conv);CHKERRQ(ierr);
4259     ierr = MatDestroy(&B);CHKERRQ(ierr);
4260     if (conv) goto foundconv;
4261 
4262     /* 4) See if a good general converter is known for the current matrix */
4263     if (mat->ops->convert) {
4264       conv = mat->ops->convert;
4265     }
4266     ierr = PetscInfo2(mat,"Check general convert (%s) -> %d\n",((PetscObject)mat)->type_name,!!conv);CHKERRQ(ierr);
4267     if (conv) goto foundconv;
4268 
4269     /* 5) Use a really basic converter. */
4270     ierr = PetscInfo(mat,"Using MatConvert_Basic\n");CHKERRQ(ierr);
4271     conv = MatConvert_Basic;
4272 
4273 foundconv:
4274     ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4275     ierr = (*conv)(mat,newtype,reuse,M);CHKERRQ(ierr);
4276     if (mat->rmap->mapping && mat->cmap->mapping && !(*M)->rmap->mapping && !(*M)->cmap->mapping) {
4277       /* the block sizes must be same if the mappings are copied over */
4278       (*M)->rmap->bs = mat->rmap->bs;
4279       (*M)->cmap->bs = mat->cmap->bs;
4280       ierr = PetscObjectReference((PetscObject)mat->rmap->mapping);CHKERRQ(ierr);
4281       ierr = PetscObjectReference((PetscObject)mat->cmap->mapping);CHKERRQ(ierr);
4282       (*M)->rmap->mapping = mat->rmap->mapping;
4283       (*M)->cmap->mapping = mat->cmap->mapping;
4284     }
4285     (*M)->stencil.dim = mat->stencil.dim;
4286     (*M)->stencil.noc = mat->stencil.noc;
4287     for (i=0; i<=mat->stencil.dim; i++) {
4288       (*M)->stencil.dims[i]   = mat->stencil.dims[i];
4289       (*M)->stencil.starts[i] = mat->stencil.starts[i];
4290     }
4291     ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4292   }
4293   ierr = PetscObjectStateIncrease((PetscObject)*M);CHKERRQ(ierr);
4294 
4295   /* Copy Mat options */
4296   if (mat->symmetric) {ierr = MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);}
4297   if (mat->hermitian) {ierr = MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);}
4298   PetscFunctionReturn(0);
4299 }
4300 
4301 /*@C
4302    MatFactorGetSolverType - Returns name of the package providing the factorization routines
4303 
4304    Not Collective
4305 
4306    Input Parameter:
4307 .  mat - the matrix, must be a factored matrix
4308 
4309    Output Parameter:
4310 .   type - the string name of the package (do not free this string)
4311 
4312    Notes:
4313       In Fortran you pass in a empty string and the package name will be copied into it.
4314     (Make sure the string is long enough)
4315 
4316    Level: intermediate
4317 
4318 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
4319 @*/
4320 PetscErrorCode MatFactorGetSolverType(Mat mat, MatSolverType *type)
4321 {
4322   PetscErrorCode ierr, (*conv)(Mat,MatSolverType*);
4323 
4324   PetscFunctionBegin;
4325   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4326   PetscValidType(mat,1);
4327   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
4328   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverType_C",&conv);CHKERRQ(ierr);
4329   if (!conv) {
4330     *type = MATSOLVERPETSC;
4331   } else {
4332     ierr = (*conv)(mat,type);CHKERRQ(ierr);
4333   }
4334   PetscFunctionReturn(0);
4335 }
4336 
4337 typedef struct _MatSolverTypeForSpecifcType* MatSolverTypeForSpecifcType;
4338 struct _MatSolverTypeForSpecifcType {
4339   MatType                        mtype;
4340   PetscErrorCode                 (*getfactor[4])(Mat,MatFactorType,Mat*);
4341   MatSolverTypeForSpecifcType next;
4342 };
4343 
4344 typedef struct _MatSolverTypeHolder* MatSolverTypeHolder;
4345 struct _MatSolverTypeHolder {
4346   char                           *name;
4347   MatSolverTypeForSpecifcType handlers;
4348   MatSolverTypeHolder         next;
4349 };
4350 
4351 static MatSolverTypeHolder MatSolverTypeHolders = NULL;
4352 
4353 /*@C
4354    MatSolvePackageRegister - Registers a MatSolverType that works for a particular matrix type
4355 
4356    Input Parameters:
4357 +    package - name of the package, for example petsc or superlu
4358 .    mtype - the matrix type that works with this package
4359 .    ftype - the type of factorization supported by the package
4360 -    getfactor - routine that will create the factored matrix ready to be used
4361 
4362     Level: intermediate
4363 
4364 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4365 @*/
4366 PetscErrorCode MatSolverTypeRegister(MatSolverType package,MatType mtype,MatFactorType ftype,PetscErrorCode (*getfactor)(Mat,MatFactorType,Mat*))
4367 {
4368   PetscErrorCode              ierr;
4369   MatSolverTypeHolder         next = MatSolverTypeHolders,prev;
4370   PetscBool                   flg;
4371   MatSolverTypeForSpecifcType inext,iprev = NULL;
4372 
4373   PetscFunctionBegin;
4374   ierr = MatInitializePackage();CHKERRQ(ierr);
4375   if (!next) {
4376     ierr = PetscNew(&MatSolverTypeHolders);CHKERRQ(ierr);
4377     ierr = PetscStrallocpy(package,&MatSolverTypeHolders->name);CHKERRQ(ierr);
4378     ierr = PetscNew(&MatSolverTypeHolders->handlers);CHKERRQ(ierr);
4379     ierr = PetscStrallocpy(mtype,(char **)&MatSolverTypeHolders->handlers->mtype);CHKERRQ(ierr);
4380     MatSolverTypeHolders->handlers->getfactor[(int)ftype-1] = getfactor;
4381     PetscFunctionReturn(0);
4382   }
4383   while (next) {
4384     ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr);
4385     if (flg) {
4386       if (!next->handlers) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverTypeHolder is missing handlers");
4387       inext = next->handlers;
4388       while (inext) {
4389         ierr = PetscStrcasecmp(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4390         if (flg) {
4391           inext->getfactor[(int)ftype-1] = getfactor;
4392           PetscFunctionReturn(0);
4393         }
4394         iprev = inext;
4395         inext = inext->next;
4396       }
4397       ierr = PetscNew(&iprev->next);CHKERRQ(ierr);
4398       ierr = PetscStrallocpy(mtype,(char **)&iprev->next->mtype);CHKERRQ(ierr);
4399       iprev->next->getfactor[(int)ftype-1] = getfactor;
4400       PetscFunctionReturn(0);
4401     }
4402     prev = next;
4403     next = next->next;
4404   }
4405   ierr = PetscNew(&prev->next);CHKERRQ(ierr);
4406   ierr = PetscStrallocpy(package,&prev->next->name);CHKERRQ(ierr);
4407   ierr = PetscNew(&prev->next->handlers);CHKERRQ(ierr);
4408   ierr = PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);CHKERRQ(ierr);
4409   prev->next->handlers->getfactor[(int)ftype-1] = getfactor;
4410   PetscFunctionReturn(0);
4411 }
4412 
4413 /*@C
4414    MatSolvePackageGet - Get's the function that creates the factor matrix if it exist
4415 
4416    Input Parameters:
4417 +    package - name of the package, for example petsc or superlu
4418 .    ftype - the type of factorization supported by the package
4419 -    mtype - the matrix type that works with this package
4420 
4421    Output Parameters:
4422 +   foundpackage - PETSC_TRUE if the package was registered
4423 .   foundmtype - PETSC_TRUE if the package supports the requested mtype
4424 -   getfactor - routine that will create the factored matrix ready to be used or NULL if not found
4425 
4426     Level: intermediate
4427 
4428 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4429 @*/
4430 PetscErrorCode MatSolverTypeGet(MatSolverType package,MatType mtype,MatFactorType ftype,PetscBool *foundpackage,PetscBool *foundmtype,PetscErrorCode (**getfactor)(Mat,MatFactorType,Mat*))
4431 {
4432   PetscErrorCode                 ierr;
4433   MatSolverTypeHolder         next = MatSolverTypeHolders;
4434   PetscBool                      flg;
4435   MatSolverTypeForSpecifcType inext;
4436 
4437   PetscFunctionBegin;
4438   if (foundpackage) *foundpackage = PETSC_FALSE;
4439   if (foundmtype)   *foundmtype   = PETSC_FALSE;
4440   if (getfactor)    *getfactor    = NULL;
4441 
4442   if (package) {
4443     while (next) {
4444       ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr);
4445       if (flg) {
4446         if (foundpackage) *foundpackage = PETSC_TRUE;
4447         inext = next->handlers;
4448         while (inext) {
4449           ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4450           if (flg) {
4451             if (foundmtype) *foundmtype = PETSC_TRUE;
4452             if (getfactor)  *getfactor  = inext->getfactor[(int)ftype-1];
4453             PetscFunctionReturn(0);
4454           }
4455           inext = inext->next;
4456         }
4457       }
4458       next = next->next;
4459     }
4460   } else {
4461     while (next) {
4462       inext = next->handlers;
4463       while (inext) {
4464         ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4465         if (flg && inext->getfactor[(int)ftype-1]) {
4466           if (foundpackage) *foundpackage = PETSC_TRUE;
4467           if (foundmtype)   *foundmtype   = PETSC_TRUE;
4468           if (getfactor)    *getfactor    = inext->getfactor[(int)ftype-1];
4469           PetscFunctionReturn(0);
4470         }
4471         inext = inext->next;
4472       }
4473       next = next->next;
4474     }
4475   }
4476   PetscFunctionReturn(0);
4477 }
4478 
4479 PetscErrorCode MatSolverTypeDestroy(void)
4480 {
4481   PetscErrorCode              ierr;
4482   MatSolverTypeHolder         next = MatSolverTypeHolders,prev;
4483   MatSolverTypeForSpecifcType inext,iprev;
4484 
4485   PetscFunctionBegin;
4486   while (next) {
4487     ierr = PetscFree(next->name);CHKERRQ(ierr);
4488     inext = next->handlers;
4489     while (inext) {
4490       ierr = PetscFree(inext->mtype);CHKERRQ(ierr);
4491       iprev = inext;
4492       inext = inext->next;
4493       ierr = PetscFree(iprev);CHKERRQ(ierr);
4494     }
4495     prev = next;
4496     next = next->next;
4497     ierr = PetscFree(prev);CHKERRQ(ierr);
4498   }
4499   MatSolverTypeHolders = NULL;
4500   PetscFunctionReturn(0);
4501 }
4502 
4503 /*@C
4504    MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic()
4505 
4506    Collective on Mat
4507 
4508    Input Parameters:
4509 +  mat - the matrix
4510 .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4511 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4512 
4513    Output Parameters:
4514 .  f - the factor matrix used with MatXXFactorSymbolic() calls
4515 
4516    Notes:
4517       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4518      such as pastix, superlu, mumps etc.
4519 
4520       PETSc must have been ./configure to use the external solver, using the option --download-package
4521 
4522    Level: intermediate
4523 
4524 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4525 @*/
4526 PetscErrorCode MatGetFactor(Mat mat, MatSolverType type,MatFactorType ftype,Mat *f)
4527 {
4528   PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
4529   PetscBool      foundpackage,foundmtype;
4530 
4531   PetscFunctionBegin;
4532   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4533   PetscValidType(mat,1);
4534 
4535   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4536   MatCheckPreallocated(mat,1);
4537 
4538   ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,&foundpackage,&foundmtype,&conv);CHKERRQ(ierr);
4539   if (!foundpackage) {
4540     if (type) {
4541       SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver package %s. Perhaps you must ./configure with --download-%s",type,type);
4542     } else {
4543       SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate a solver package. Perhaps you must ./configure with --download-<package>");
4544     }
4545   }
4546 
4547   if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support matrix type %s",type,((PetscObject)mat)->type_name);
4548   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);
4549 
4550 #if defined(PETSC_USE_COMPLEX)
4551   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");
4552 #endif
4553 
4554   ierr = (*conv)(mat,ftype,f);CHKERRQ(ierr);
4555   PetscFunctionReturn(0);
4556 }
4557 
4558 /*@C
4559    MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type
4560 
4561    Not Collective
4562 
4563    Input Parameters:
4564 +  mat - the matrix
4565 .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4566 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4567 
4568    Output Parameter:
4569 .    flg - PETSC_TRUE if the factorization is available
4570 
4571    Notes:
4572       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4573      such as pastix, superlu, mumps etc.
4574 
4575       PETSc must have been ./configure to use the external solver, using the option --download-package
4576 
4577    Level: intermediate
4578 
4579 .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
4580 @*/
4581 PetscErrorCode MatGetFactorAvailable(Mat mat, MatSolverType type,MatFactorType ftype,PetscBool  *flg)
4582 {
4583   PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*);
4584 
4585   PetscFunctionBegin;
4586   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4587   PetscValidType(mat,1);
4588 
4589   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4590   MatCheckPreallocated(mat,1);
4591 
4592   *flg = PETSC_FALSE;
4593   ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);CHKERRQ(ierr);
4594   if (gconv) {
4595     *flg = PETSC_TRUE;
4596   }
4597   PetscFunctionReturn(0);
4598 }
4599 
4600 #include <petscdmtypes.h>
4601 
4602 /*@
4603    MatDuplicate - Duplicates a matrix including the non-zero structure.
4604 
4605    Collective on Mat
4606 
4607    Input Parameters:
4608 +  mat - the matrix
4609 -  op - One of MAT_DO_NOT_COPY_VALUES, MAT_COPY_VALUES, or MAT_SHARE_NONZERO_PATTERN.
4610         See the manual page for MatDuplicateOption for an explanation of these options.
4611 
4612    Output Parameter:
4613 .  M - pointer to place new matrix
4614 
4615    Level: intermediate
4616 
4617    Concepts: matrices^duplicating
4618 
4619    Notes:
4620     You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN.
4621     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.
4622 
4623 .seealso: MatCopy(), MatConvert(), MatDuplicateOption
4624 @*/
4625 PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4626 {
4627   PetscErrorCode ierr;
4628   Mat            B;
4629   PetscInt       i;
4630   DM             dm;
4631   void           (*viewf)(void);
4632 
4633   PetscFunctionBegin;
4634   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4635   PetscValidType(mat,1);
4636   PetscValidPointer(M,3);
4637   if (op == MAT_COPY_VALUES && !mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MAT_COPY_VALUES not allowed for unassembled matrix");
4638   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4639   MatCheckPreallocated(mat,1);
4640 
4641   *M = 0;
4642   if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type");
4643   ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4644   ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr);
4645   B    = *M;
4646 
4647   ierr = MatGetOperation(mat,MATOP_VIEW,&viewf);CHKERRQ(ierr);
4648   if (viewf) {
4649     ierr = MatSetOperation(B,MATOP_VIEW,viewf);CHKERRQ(ierr);
4650   }
4651 
4652   B->stencil.dim = mat->stencil.dim;
4653   B->stencil.noc = mat->stencil.noc;
4654   for (i=0; i<=mat->stencil.dim; i++) {
4655     B->stencil.dims[i]   = mat->stencil.dims[i];
4656     B->stencil.starts[i] = mat->stencil.starts[i];
4657   }
4658 
4659   B->nooffproczerorows = mat->nooffproczerorows;
4660   B->nooffprocentries  = mat->nooffprocentries;
4661 
4662   ierr = PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);CHKERRQ(ierr);
4663   if (dm) {
4664     ierr = PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr);
4665   }
4666   ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4667   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
4668   PetscFunctionReturn(0);
4669 }
4670 
4671 /*@
4672    MatGetDiagonal - Gets the diagonal of a matrix.
4673 
4674    Logically Collective on Mat and Vec
4675 
4676    Input Parameters:
4677 +  mat - the matrix
4678 -  v - the vector for storing the diagonal
4679 
4680    Output Parameter:
4681 .  v - the diagonal of the matrix
4682 
4683    Level: intermediate
4684 
4685    Note:
4686    Currently only correct in parallel for square matrices.
4687 
4688    Concepts: matrices^accessing diagonals
4689 
4690 .seealso: MatGetRow(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs()
4691 @*/
4692 PetscErrorCode MatGetDiagonal(Mat mat,Vec v)
4693 {
4694   PetscErrorCode ierr;
4695 
4696   PetscFunctionBegin;
4697   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4698   PetscValidType(mat,1);
4699   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4700   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4701   if (!mat->ops->getdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4702   MatCheckPreallocated(mat,1);
4703 
4704   ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr);
4705   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4706   PetscFunctionReturn(0);
4707 }
4708 
4709 /*@C
4710    MatGetRowMin - Gets the minimum value (of the real part) of each
4711         row of the matrix
4712 
4713    Logically Collective on Mat and Vec
4714 
4715    Input Parameters:
4716 .  mat - the matrix
4717 
4718    Output Parameter:
4719 +  v - the vector for storing the maximums
4720 -  idx - the indices of the column found for each row (optional)
4721 
4722    Level: intermediate
4723 
4724    Notes:
4725     The result of this call are the same as if one converted the matrix to dense format
4726       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4727 
4728     This code is only implemented for a couple of matrix formats.
4729 
4730    Concepts: matrices^getting row maximums
4731 
4732 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(),
4733           MatGetRowMax()
4734 @*/
4735 PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4736 {
4737   PetscErrorCode ierr;
4738 
4739   PetscFunctionBegin;
4740   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4741   PetscValidType(mat,1);
4742   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4743   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4744   if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4745   MatCheckPreallocated(mat,1);
4746 
4747   ierr = (*mat->ops->getrowmin)(mat,v,idx);CHKERRQ(ierr);
4748   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4749   PetscFunctionReturn(0);
4750 }
4751 
4752 /*@C
4753    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4754         row of the matrix
4755 
4756    Logically Collective on Mat and Vec
4757 
4758    Input Parameters:
4759 .  mat - the matrix
4760 
4761    Output Parameter:
4762 +  v - the vector for storing the minimums
4763 -  idx - the indices of the column found for each row (or NULL if not needed)
4764 
4765    Level: intermediate
4766 
4767    Notes:
4768     if a row is completely empty or has only 0.0 values then the idx[] value for that
4769     row is 0 (the first column).
4770 
4771     This code is only implemented for a couple of matrix formats.
4772 
4773    Concepts: matrices^getting row maximums
4774 
4775 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4776 @*/
4777 PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4778 {
4779   PetscErrorCode ierr;
4780 
4781   PetscFunctionBegin;
4782   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4783   PetscValidType(mat,1);
4784   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4785   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4786   if (!mat->ops->getrowminabs) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4787   MatCheckPreallocated(mat,1);
4788   if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);}
4789 
4790   ierr = (*mat->ops->getrowminabs)(mat,v,idx);CHKERRQ(ierr);
4791   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4792   PetscFunctionReturn(0);
4793 }
4794 
4795 /*@C
4796    MatGetRowMax - Gets the maximum value (of the real part) of each
4797         row of the matrix
4798 
4799    Logically Collective on Mat and Vec
4800 
4801    Input Parameters:
4802 .  mat - the matrix
4803 
4804    Output Parameter:
4805 +  v - the vector for storing the maximums
4806 -  idx - the indices of the column found for each row (optional)
4807 
4808    Level: intermediate
4809 
4810    Notes:
4811     The result of this call are the same as if one converted the matrix to dense format
4812       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4813 
4814     This code is only implemented for a couple of matrix formats.
4815 
4816    Concepts: matrices^getting row maximums
4817 
4818 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4819 @*/
4820 PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4821 {
4822   PetscErrorCode ierr;
4823 
4824   PetscFunctionBegin;
4825   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4826   PetscValidType(mat,1);
4827   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4828   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4829   if (!mat->ops->getrowmax) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4830   MatCheckPreallocated(mat,1);
4831 
4832   ierr = (*mat->ops->getrowmax)(mat,v,idx);CHKERRQ(ierr);
4833   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4834   PetscFunctionReturn(0);
4835 }
4836 
4837 /*@C
4838    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4839         row of the matrix
4840 
4841    Logically Collective on Mat and Vec
4842 
4843    Input Parameters:
4844 .  mat - the matrix
4845 
4846    Output Parameter:
4847 +  v - the vector for storing the maximums
4848 -  idx - the indices of the column found for each row (or NULL if not needed)
4849 
4850    Level: intermediate
4851 
4852    Notes:
4853     if a row is completely empty or has only 0.0 values then the idx[] value for that
4854     row is 0 (the first column).
4855 
4856     This code is only implemented for a couple of matrix formats.
4857 
4858    Concepts: matrices^getting row maximums
4859 
4860 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
4861 @*/
4862 PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4863 {
4864   PetscErrorCode ierr;
4865 
4866   PetscFunctionBegin;
4867   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4868   PetscValidType(mat,1);
4869   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4870   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4871   if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4872   MatCheckPreallocated(mat,1);
4873   if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);}
4874 
4875   ierr = (*mat->ops->getrowmaxabs)(mat,v,idx);CHKERRQ(ierr);
4876   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4877   PetscFunctionReturn(0);
4878 }
4879 
4880 /*@
4881    MatGetRowSum - Gets the sum of each row of the matrix
4882 
4883    Logically or Neighborhood Collective on Mat and Vec
4884 
4885    Input Parameters:
4886 .  mat - the matrix
4887 
4888    Output Parameter:
4889 .  v - the vector for storing the sum of rows
4890 
4891    Level: intermediate
4892 
4893    Notes:
4894     This code is slow since it is not currently specialized for different formats
4895 
4896    Concepts: matrices^getting row sums
4897 
4898 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
4899 @*/
4900 PetscErrorCode MatGetRowSum(Mat mat, Vec v)
4901 {
4902   Vec            ones;
4903   PetscErrorCode ierr;
4904 
4905   PetscFunctionBegin;
4906   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4907   PetscValidType(mat,1);
4908   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4909   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4910   MatCheckPreallocated(mat,1);
4911   ierr = MatCreateVecs(mat,&ones,NULL);CHKERRQ(ierr);
4912   ierr = VecSet(ones,1.);CHKERRQ(ierr);
4913   ierr = MatMult(mat,ones,v);CHKERRQ(ierr);
4914   ierr = VecDestroy(&ones);CHKERRQ(ierr);
4915   PetscFunctionReturn(0);
4916 }
4917 
4918 /*@
4919    MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
4920 
4921    Collective on Mat
4922 
4923    Input Parameter:
4924 +  mat - the matrix to transpose
4925 -  reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX
4926 
4927    Output Parameters:
4928 .  B - the transpose
4929 
4930    Notes:
4931      If you use MAT_INPLACE_MATRIX then you must pass in &mat for B
4932 
4933      MAT_REUSE_MATRIX causes the B matrix from a previous call to this function with MAT_INITIAL_MATRIX to be used
4934 
4935      Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed.
4936 
4937    Level: intermediate
4938 
4939    Concepts: matrices^transposing
4940 
4941 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4942 @*/
4943 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4944 {
4945   PetscErrorCode ierr;
4946 
4947   PetscFunctionBegin;
4948   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4949   PetscValidType(mat,1);
4950   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4951   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4952   if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4953   if (reuse == MAT_INPLACE_MATRIX && mat != *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires last matrix to match first");
4954   if (reuse == MAT_REUSE_MATRIX && mat == *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Perhaps you mean MAT_INPLACE_MATRIX");
4955   MatCheckPreallocated(mat,1);
4956 
4957   ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4958   ierr = (*mat->ops->transpose)(mat,reuse,B);CHKERRQ(ierr);
4959   ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4960   if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);}
4961   PetscFunctionReturn(0);
4962 }
4963 
4964 /*@
4965    MatIsTranspose - Test whether a matrix is another one's transpose,
4966         or its own, in which case it tests symmetry.
4967 
4968    Collective on Mat
4969 
4970    Input Parameter:
4971 +  A - the matrix to test
4972 -  B - the matrix to test against, this can equal the first parameter
4973 
4974    Output Parameters:
4975 .  flg - the result
4976 
4977    Notes:
4978    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4979    has a running time of the order of the number of nonzeros; the parallel
4980    test involves parallel copies of the block-offdiagonal parts of the matrix.
4981 
4982    Level: intermediate
4983 
4984    Concepts: matrices^transposing, matrix^symmetry
4985 
4986 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4987 @*/
4988 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4989 {
4990   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4991 
4992   PetscFunctionBegin;
4993   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4994   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4995   PetscValidPointer(flg,3);
4996   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);CHKERRQ(ierr);
4997   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);CHKERRQ(ierr);
4998   *flg = PETSC_FALSE;
4999   if (f && g) {
5000     if (f == g) {
5001       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
5002     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
5003   } else {
5004     MatType mattype;
5005     if (!f) {
5006       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
5007     } else {
5008       ierr = MatGetType(B,&mattype);CHKERRQ(ierr);
5009     }
5010     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
5011   }
5012   PetscFunctionReturn(0);
5013 }
5014 
5015 /*@
5016    MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate.
5017 
5018    Collective on Mat
5019 
5020    Input Parameter:
5021 +  mat - the matrix to transpose and complex conjugate
5022 -  reuse - MAT_INITIAL_MATRIX to create a new matrix, MAT_INPLACE_MATRIX to reuse the first argument to store the transpose
5023 
5024    Output Parameters:
5025 .  B - the Hermitian
5026 
5027    Level: intermediate
5028 
5029    Concepts: matrices^transposing, complex conjugatex
5030 
5031 .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
5032 @*/
5033 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
5034 {
5035   PetscErrorCode ierr;
5036 
5037   PetscFunctionBegin;
5038   ierr = MatTranspose(mat,reuse,B);CHKERRQ(ierr);
5039 #if defined(PETSC_USE_COMPLEX)
5040   ierr = MatConjugate(*B);CHKERRQ(ierr);
5041 #endif
5042   PetscFunctionReturn(0);
5043 }
5044 
5045 /*@
5046    MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,
5047 
5048    Collective on Mat
5049 
5050    Input Parameter:
5051 +  A - the matrix to test
5052 -  B - the matrix to test against, this can equal the first parameter
5053 
5054    Output Parameters:
5055 .  flg - the result
5056 
5057    Notes:
5058    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
5059    has a running time of the order of the number of nonzeros; the parallel
5060    test involves parallel copies of the block-offdiagonal parts of the matrix.
5061 
5062    Level: intermediate
5063 
5064    Concepts: matrices^transposing, matrix^symmetry
5065 
5066 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
5067 @*/
5068 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
5069 {
5070   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
5071 
5072   PetscFunctionBegin;
5073   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
5074   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
5075   PetscValidPointer(flg,3);
5076   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);CHKERRQ(ierr);
5077   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);CHKERRQ(ierr);
5078   if (f && g) {
5079     if (f==g) {
5080       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
5081     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
5082   }
5083   PetscFunctionReturn(0);
5084 }
5085 
5086 /*@
5087    MatPermute - Creates a new matrix with rows and columns permuted from the
5088    original.
5089 
5090    Collective on Mat
5091 
5092    Input Parameters:
5093 +  mat - the matrix to permute
5094 .  row - row permutation, each processor supplies only the permutation for its rows
5095 -  col - column permutation, each processor supplies only the permutation for its columns
5096 
5097    Output Parameters:
5098 .  B - the permuted matrix
5099 
5100    Level: advanced
5101 
5102    Note:
5103    The index sets map from row/col of permuted matrix to row/col of original matrix.
5104    The index sets should be on the same communicator as Mat and have the same local sizes.
5105 
5106    Concepts: matrices^permuting
5107 
5108 .seealso: MatGetOrdering(), ISAllGather()
5109 
5110 @*/
5111 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
5112 {
5113   PetscErrorCode ierr;
5114 
5115   PetscFunctionBegin;
5116   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5117   PetscValidType(mat,1);
5118   PetscValidHeaderSpecific(row,IS_CLASSID,2);
5119   PetscValidHeaderSpecific(col,IS_CLASSID,3);
5120   PetscValidPointer(B,4);
5121   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5122   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5123   if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
5124   MatCheckPreallocated(mat,1);
5125 
5126   ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr);
5127   ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);
5128   PetscFunctionReturn(0);
5129 }
5130 
5131 /*@
5132    MatEqual - Compares two matrices.
5133 
5134    Collective on Mat
5135 
5136    Input Parameters:
5137 +  A - the first matrix
5138 -  B - the second matrix
5139 
5140    Output Parameter:
5141 .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
5142 
5143    Level: intermediate
5144 
5145    Concepts: matrices^equality between
5146 @*/
5147 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool  *flg)
5148 {
5149   PetscErrorCode ierr;
5150 
5151   PetscFunctionBegin;
5152   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
5153   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
5154   PetscValidType(A,1);
5155   PetscValidType(B,2);
5156   PetscValidIntPointer(flg,3);
5157   PetscCheckSameComm(A,1,B,2);
5158   MatCheckPreallocated(B,2);
5159   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5160   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5161   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);
5162   if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
5163   if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
5164   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);
5165   MatCheckPreallocated(A,1);
5166 
5167   ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr);
5168   PetscFunctionReturn(0);
5169 }
5170 
5171 /*@
5172    MatDiagonalScale - Scales a matrix on the left and right by diagonal
5173    matrices that are stored as vectors.  Either of the two scaling
5174    matrices can be NULL.
5175 
5176    Collective on Mat
5177 
5178    Input Parameters:
5179 +  mat - the matrix to be scaled
5180 .  l - the left scaling vector (or NULL)
5181 -  r - the right scaling vector (or NULL)
5182 
5183    Notes:
5184    MatDiagonalScale() computes A = LAR, where
5185    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
5186    The L scales the rows of the matrix, the R scales the columns of the matrix.
5187 
5188    Level: intermediate
5189 
5190    Concepts: matrices^diagonal scaling
5191    Concepts: diagonal scaling of matrices
5192 
5193 .seealso: MatScale(), MatShift(), MatDiagonalSet()
5194 @*/
5195 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
5196 {
5197   PetscErrorCode ierr;
5198 
5199   PetscFunctionBegin;
5200   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5201   PetscValidType(mat,1);
5202   if (!mat->ops->diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5203   if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);}
5204   if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);}
5205   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5206   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5207   MatCheckPreallocated(mat,1);
5208 
5209   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5210   ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr);
5211   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5212   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5213 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5214   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5215     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5216   }
5217 #endif
5218   PetscFunctionReturn(0);
5219 }
5220 
5221 /*@
5222     MatScale - Scales all elements of a matrix by a given number.
5223 
5224     Logically Collective on Mat
5225 
5226     Input Parameters:
5227 +   mat - the matrix to be scaled
5228 -   a  - the scaling value
5229 
5230     Output Parameter:
5231 .   mat - the scaled matrix
5232 
5233     Level: intermediate
5234 
5235     Concepts: matrices^scaling all entries
5236 
5237 .seealso: MatDiagonalScale()
5238 @*/
5239 PetscErrorCode MatScale(Mat mat,PetscScalar a)
5240 {
5241   PetscErrorCode ierr;
5242 
5243   PetscFunctionBegin;
5244   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5245   PetscValidType(mat,1);
5246   if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5247   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5248   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5249   PetscValidLogicalCollectiveScalar(mat,a,2);
5250   MatCheckPreallocated(mat,1);
5251 
5252   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5253   if (a != (PetscScalar)1.0) {
5254     ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr);
5255     ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5256 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5257     if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5258       mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5259     }
5260 #endif
5261   }
5262   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5263   PetscFunctionReturn(0);
5264 }
5265 
5266 /*@
5267    MatNorm - Calculates various norms of a matrix.
5268 
5269    Collective on Mat
5270 
5271    Input Parameters:
5272 +  mat - the matrix
5273 -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
5274 
5275    Output Parameters:
5276 .  nrm - the resulting norm
5277 
5278    Level: intermediate
5279 
5280    Concepts: matrices^norm
5281    Concepts: norm^of matrix
5282 @*/
5283 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
5284 {
5285   PetscErrorCode ierr;
5286 
5287   PetscFunctionBegin;
5288   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5289   PetscValidType(mat,1);
5290   PetscValidScalarPointer(nrm,3);
5291 
5292   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5293   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5294   if (!mat->ops->norm) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5295   MatCheckPreallocated(mat,1);
5296 
5297   ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr);
5298   PetscFunctionReturn(0);
5299 }
5300 
5301 /*
5302      This variable is used to prevent counting of MatAssemblyBegin() that
5303    are called from within a MatAssemblyEnd().
5304 */
5305 static PetscInt MatAssemblyEnd_InUse = 0;
5306 /*@
5307    MatAssemblyBegin - Begins assembling the matrix.  This routine should
5308    be called after completing all calls to MatSetValues().
5309 
5310    Collective on Mat
5311 
5312    Input Parameters:
5313 +  mat - the matrix
5314 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5315 
5316    Notes:
5317    MatSetValues() generally caches the values.  The matrix is ready to
5318    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5319    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5320    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5321    using the matrix.
5322 
5323    ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the
5324    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
5325    a global collective operation requring all processes that share the matrix.
5326 
5327    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5328    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5329    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5330 
5331    Level: beginner
5332 
5333    Concepts: matrices^assembling
5334 
5335 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
5336 @*/
5337 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
5338 {
5339   PetscErrorCode ierr;
5340 
5341   PetscFunctionBegin;
5342   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5343   PetscValidType(mat,1);
5344   MatCheckPreallocated(mat,1);
5345   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
5346   if (mat->assembled) {
5347     mat->was_assembled = PETSC_TRUE;
5348     mat->assembled     = PETSC_FALSE;
5349   }
5350   if (!MatAssemblyEnd_InUse) {
5351     ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5352     if (mat->ops->assemblybegin) {ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
5353     ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5354   } else if (mat->ops->assemblybegin) {
5355     ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);
5356   }
5357   PetscFunctionReturn(0);
5358 }
5359 
5360 /*@
5361    MatAssembled - Indicates if a matrix has been assembled and is ready for
5362      use; for example, in matrix-vector product.
5363 
5364    Not Collective
5365 
5366    Input Parameter:
5367 .  mat - the matrix
5368 
5369    Output Parameter:
5370 .  assembled - PETSC_TRUE or PETSC_FALSE
5371 
5372    Level: advanced
5373 
5374    Concepts: matrices^assembled?
5375 
5376 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
5377 @*/
5378 PetscErrorCode MatAssembled(Mat mat,PetscBool  *assembled)
5379 {
5380   PetscFunctionBegin;
5381   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5382   PetscValidPointer(assembled,2);
5383   *assembled = mat->assembled;
5384   PetscFunctionReturn(0);
5385 }
5386 
5387 /*@
5388    MatAssemblyEnd - Completes assembling the matrix.  This routine should
5389    be called after MatAssemblyBegin().
5390 
5391    Collective on Mat
5392 
5393    Input Parameters:
5394 +  mat - the matrix
5395 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5396 
5397    Options Database Keys:
5398 +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
5399 .  -mat_view ::ascii_info_detail - Prints more detailed info
5400 .  -mat_view - Prints matrix in ASCII format
5401 .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
5402 .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
5403 .  -display <name> - Sets display name (default is host)
5404 .  -draw_pause <sec> - Sets number of seconds to pause after display
5405 .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab )
5406 .  -viewer_socket_machine <machine> - Machine to use for socket
5407 .  -viewer_socket_port <port> - Port number to use for socket
5408 -  -mat_view binary:filename[:append] - Save matrix to file in binary format
5409 
5410    Notes:
5411    MatSetValues() generally caches the values.  The matrix is ready to
5412    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5413    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5414    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5415    using the matrix.
5416 
5417    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5418    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5419    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5420 
5421    Level: beginner
5422 
5423 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
5424 @*/
5425 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
5426 {
5427   PetscErrorCode  ierr;
5428   static PetscInt inassm = 0;
5429   PetscBool       flg    = PETSC_FALSE;
5430 
5431   PetscFunctionBegin;
5432   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5433   PetscValidType(mat,1);
5434 
5435   inassm++;
5436   MatAssemblyEnd_InUse++;
5437   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
5438     ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5439     if (mat->ops->assemblyend) {
5440       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5441     }
5442     ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5443   } else if (mat->ops->assemblyend) {
5444     ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5445   }
5446 
5447   /* Flush assembly is not a true assembly */
5448   if (type != MAT_FLUSH_ASSEMBLY) {
5449     mat->assembled = PETSC_TRUE; mat->num_ass++;
5450   }
5451   mat->insertmode = NOT_SET_VALUES;
5452   MatAssemblyEnd_InUse--;
5453   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5454   if (!mat->symmetric_eternal) {
5455     mat->symmetric_set              = PETSC_FALSE;
5456     mat->hermitian_set              = PETSC_FALSE;
5457     mat->structurally_symmetric_set = PETSC_FALSE;
5458   }
5459 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5460   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5461     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5462   }
5463 #endif
5464   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
5465     ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5466 
5467     if (mat->checksymmetryonassembly) {
5468       ierr = MatIsSymmetric(mat,mat->checksymmetrytol,&flg);CHKERRQ(ierr);
5469       if (flg) {
5470         ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5471       } else {
5472         ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5473       }
5474     }
5475     if (mat->nullsp && mat->checknullspaceonassembly) {
5476       ierr = MatNullSpaceTest(mat->nullsp,mat,NULL);CHKERRQ(ierr);
5477     }
5478   }
5479   inassm--;
5480   PetscFunctionReturn(0);
5481 }
5482 
5483 /*@
5484    MatSetOption - Sets a parameter option for a matrix. Some options
5485    may be specific to certain storage formats.  Some options
5486    determine how values will be inserted (or added). Sorted,
5487    row-oriented input will generally assemble the fastest. The default
5488    is row-oriented.
5489 
5490    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5491 
5492    Input Parameters:
5493 +  mat - the matrix
5494 .  option - the option, one of those listed below (and possibly others),
5495 -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5496 
5497   Options Describing Matrix Structure:
5498 +    MAT_SPD - symmetric positive definite
5499 .    MAT_SYMMETRIC - symmetric in terms of both structure and value
5500 .    MAT_HERMITIAN - transpose is the complex conjugation
5501 .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5502 -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5503                             you set to be kept with all future use of the matrix
5504                             including after MatAssemblyBegin/End() which could
5505                             potentially change the symmetry structure, i.e. you
5506                             KNOW the matrix will ALWAYS have the property you set.
5507 
5508 
5509    Options For Use with MatSetValues():
5510    Insert a logically dense subblock, which can be
5511 .    MAT_ROW_ORIENTED - row-oriented (default)
5512 
5513    Note these options reflect the data you pass in with MatSetValues(); it has
5514    nothing to do with how the data is stored internally in the matrix
5515    data structure.
5516 
5517    When (re)assembling a matrix, we can restrict the input for
5518    efficiency/debugging purposes.  These options include:
5519 +    MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow)
5520 .    MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
5521 .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
5522 .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
5523 .    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
5524 .    MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
5525         any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
5526         performance for very large process counts.
5527 -    MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset
5528         of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly
5529         functions, instead sending only neighbor messages.
5530 
5531    Notes:
5532    Except for MAT_UNUSED_NONZERO_LOCATION_ERR and  MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg!
5533 
5534    Some options are relevant only for particular matrix types and
5535    are thus ignored by others.  Other options are not supported by
5536    certain matrix types and will generate an error message if set.
5537 
5538    If using a Fortran 77 module to compute a matrix, one may need to
5539    use the column-oriented option (or convert to the row-oriented
5540    format).
5541 
5542    MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
5543    that would generate a new entry in the nonzero structure is instead
5544    ignored.  Thus, if memory has not alredy been allocated for this particular
5545    data, then the insertion is ignored. For dense matrices, in which
5546    the entire array is allocated, no entries are ever ignored.
5547    Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5548 
5549    MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5550    that would generate a new entry in the nonzero structure instead produces
5551    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
5552 
5553    MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5554    that would generate a new entry that has not been preallocated will
5555    instead produce an error. (Currently supported for AIJ and BAIJ formats
5556    only.) This is a useful flag when debugging matrix memory preallocation.
5557    If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5558 
5559    MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for
5560    other processors should be dropped, rather than stashed.
5561    This is useful if you know that the "owning" processor is also
5562    always generating the correct matrix entries, so that PETSc need
5563    not transfer duplicate entries generated on another processor.
5564 
5565    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5566    searches during matrix assembly. When this flag is set, the hash table
5567    is created during the first Matrix Assembly. This hash table is
5568    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5569    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5570    should be used with MAT_USE_HASH_TABLE flag. This option is currently
5571    supported by MATMPIBAIJ format only.
5572 
5573    MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries
5574    are kept in the nonzero structure
5575 
5576    MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
5577    a zero location in the matrix
5578 
5579    MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types
5580 
5581    MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the
5582         zero row routines and thus improves performance for very large process counts.
5583 
5584    MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular
5585         part of the matrix (since they should match the upper triangular part).
5586 
5587    Notes:
5588     Can only be called after MatSetSizes() and MatSetType() have been set.
5589 
5590    Level: intermediate
5591 
5592    Concepts: matrices^setting options
5593 
5594 .seealso:  MatOption, Mat
5595 
5596 @*/
5597 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg)
5598 {
5599   PetscErrorCode ierr;
5600 
5601   PetscFunctionBegin;
5602   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5603   PetscValidType(mat,1);
5604   if (op > 0) {
5605     PetscValidLogicalCollectiveEnum(mat,op,2);
5606     PetscValidLogicalCollectiveBool(mat,flg,3);
5607   }
5608 
5609   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);
5610   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()");
5611 
5612   switch (op) {
5613   case MAT_NO_OFF_PROC_ENTRIES:
5614     mat->nooffprocentries = flg;
5615     PetscFunctionReturn(0);
5616     break;
5617   case MAT_SUBSET_OFF_PROC_ENTRIES:
5618     mat->assembly_subset = flg;
5619     if (!mat->assembly_subset) { /* See the same logic in VecAssembly wrt VEC_SUBSET_OFF_PROC_ENTRIES */
5620 #if !defined(PETSC_HAVE_MPIUNI)
5621       ierr = MatStashScatterDestroy_BTS(&mat->stash);CHKERRQ(ierr);
5622 #endif
5623       mat->stash.first_assembly_done = PETSC_FALSE;
5624     }
5625     PetscFunctionReturn(0);
5626   case MAT_NO_OFF_PROC_ZERO_ROWS:
5627     mat->nooffproczerorows = flg;
5628     PetscFunctionReturn(0);
5629     break;
5630   case MAT_SPD:
5631     mat->spd_set = PETSC_TRUE;
5632     mat->spd     = flg;
5633     if (flg) {
5634       mat->symmetric                  = PETSC_TRUE;
5635       mat->structurally_symmetric     = PETSC_TRUE;
5636       mat->symmetric_set              = PETSC_TRUE;
5637       mat->structurally_symmetric_set = PETSC_TRUE;
5638     }
5639     break;
5640   case MAT_SYMMETRIC:
5641     mat->symmetric = flg;
5642     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5643     mat->symmetric_set              = PETSC_TRUE;
5644     mat->structurally_symmetric_set = flg;
5645 #if !defined(PETSC_USE_COMPLEX)
5646     mat->hermitian     = flg;
5647     mat->hermitian_set = PETSC_TRUE;
5648 #endif
5649     break;
5650   case MAT_HERMITIAN:
5651     mat->hermitian = flg;
5652     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5653     mat->hermitian_set              = PETSC_TRUE;
5654     mat->structurally_symmetric_set = flg;
5655 #if !defined(PETSC_USE_COMPLEX)
5656     mat->symmetric     = flg;
5657     mat->symmetric_set = PETSC_TRUE;
5658 #endif
5659     break;
5660   case MAT_STRUCTURALLY_SYMMETRIC:
5661     mat->structurally_symmetric     = flg;
5662     mat->structurally_symmetric_set = PETSC_TRUE;
5663     break;
5664   case MAT_SYMMETRY_ETERNAL:
5665     mat->symmetric_eternal = flg;
5666     break;
5667   case MAT_STRUCTURE_ONLY:
5668     mat->structure_only = flg;
5669     break;
5670   default:
5671     break;
5672   }
5673   if (mat->ops->setoption) {
5674     ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr);
5675   }
5676   PetscFunctionReturn(0);
5677 }
5678 
5679 /*@
5680    MatGetOption - Gets a parameter option that has been set for a matrix.
5681 
5682    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5683 
5684    Input Parameters:
5685 +  mat - the matrix
5686 -  option - the option, this only responds to certain options, check the code for which ones
5687 
5688    Output Parameter:
5689 .  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5690 
5691     Notes:
5692     Can only be called after MatSetSizes() and MatSetType() have been set.
5693 
5694    Level: intermediate
5695 
5696    Concepts: matrices^setting options
5697 
5698 .seealso:  MatOption, MatSetOption()
5699 
5700 @*/
5701 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg)
5702 {
5703   PetscFunctionBegin;
5704   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5705   PetscValidType(mat,1);
5706 
5707   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);
5708   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()");
5709 
5710   switch (op) {
5711   case MAT_NO_OFF_PROC_ENTRIES:
5712     *flg = mat->nooffprocentries;
5713     break;
5714   case MAT_NO_OFF_PROC_ZERO_ROWS:
5715     *flg = mat->nooffproczerorows;
5716     break;
5717   case MAT_SYMMETRIC:
5718     *flg = mat->symmetric;
5719     break;
5720   case MAT_HERMITIAN:
5721     *flg = mat->hermitian;
5722     break;
5723   case MAT_STRUCTURALLY_SYMMETRIC:
5724     *flg = mat->structurally_symmetric;
5725     break;
5726   case MAT_SYMMETRY_ETERNAL:
5727     *flg = mat->symmetric_eternal;
5728     break;
5729   case MAT_SPD:
5730     *flg = mat->spd;
5731     break;
5732   default:
5733     break;
5734   }
5735   PetscFunctionReturn(0);
5736 }
5737 
5738 /*@
5739    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5740    this routine retains the old nonzero structure.
5741 
5742    Logically Collective on Mat
5743 
5744    Input Parameters:
5745 .  mat - the matrix
5746 
5747    Level: intermediate
5748 
5749    Notes:
5750     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.
5751    See the Performance chapter of the users manual for information on preallocating matrices.
5752 
5753    Concepts: matrices^zeroing
5754 
5755 .seealso: MatZeroRows()
5756 @*/
5757 PetscErrorCode MatZeroEntries(Mat mat)
5758 {
5759   PetscErrorCode ierr;
5760 
5761   PetscFunctionBegin;
5762   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5763   PetscValidType(mat,1);
5764   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5765   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");
5766   if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5767   MatCheckPreallocated(mat,1);
5768 
5769   ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5770   ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
5771   ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5772   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5773 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5774   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5775     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5776   }
5777 #endif
5778   PetscFunctionReturn(0);
5779 }
5780 
5781 /*@
5782    MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal)
5783    of a set of rows and columns of a matrix.
5784 
5785    Collective on Mat
5786 
5787    Input Parameters:
5788 +  mat - the matrix
5789 .  numRows - the number of rows to remove
5790 .  rows - the global row indices
5791 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5792 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5793 -  b - optional vector of right hand side, that will be adjusted by provided solution
5794 
5795    Notes:
5796    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5797 
5798    The user can set a value in the diagonal entry (or for the AIJ and
5799    row formats can optionally remove the main diagonal entry from the
5800    nonzero structure as well, by passing 0.0 as the final argument).
5801 
5802    For the parallel case, all processes that share the matrix (i.e.,
5803    those in the communicator used for matrix creation) MUST call this
5804    routine, regardless of whether any rows being zeroed are owned by
5805    them.
5806 
5807    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5808    list only rows local to itself).
5809 
5810    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5811 
5812    Level: intermediate
5813 
5814    Concepts: matrices^zeroing rows
5815 
5816 .seealso: MatZeroRowsIS(), MatZeroRows(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5817           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5818 @*/
5819 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5820 {
5821   PetscErrorCode ierr;
5822 
5823   PetscFunctionBegin;
5824   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5825   PetscValidType(mat,1);
5826   if (numRows) PetscValidIntPointer(rows,3);
5827   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5828   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5829   if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5830   MatCheckPreallocated(mat,1);
5831 
5832   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5833   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5834   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5835 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5836   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5837     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5838   }
5839 #endif
5840   PetscFunctionReturn(0);
5841 }
5842 
5843 /*@
5844    MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
5845    of a set of rows and columns of a matrix.
5846 
5847    Collective on Mat
5848 
5849    Input Parameters:
5850 +  mat - the matrix
5851 .  is - the rows to zero
5852 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5853 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5854 -  b - optional vector of right hand side, that will be adjusted by provided solution
5855 
5856    Notes:
5857    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5858 
5859    The user can set a value in the diagonal entry (or for the AIJ and
5860    row formats can optionally remove the main diagonal entry from the
5861    nonzero structure as well, by passing 0.0 as the final argument).
5862 
5863    For the parallel case, all processes that share the matrix (i.e.,
5864    those in the communicator used for matrix creation) MUST call this
5865    routine, regardless of whether any rows being zeroed are owned by
5866    them.
5867 
5868    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5869    list only rows local to itself).
5870 
5871    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5872 
5873    Level: intermediate
5874 
5875    Concepts: matrices^zeroing rows
5876 
5877 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5878           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRows(), MatZeroRowsColumnsStencil()
5879 @*/
5880 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5881 {
5882   PetscErrorCode ierr;
5883   PetscInt       numRows;
5884   const PetscInt *rows;
5885 
5886   PetscFunctionBegin;
5887   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5888   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5889   PetscValidType(mat,1);
5890   PetscValidType(is,2);
5891   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5892   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5893   ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5894   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5895   PetscFunctionReturn(0);
5896 }
5897 
5898 /*@
5899    MatZeroRows - Zeros all entries (except possibly the main diagonal)
5900    of a set of rows of a matrix.
5901 
5902    Collective on Mat
5903 
5904    Input Parameters:
5905 +  mat - the matrix
5906 .  numRows - the number of rows to remove
5907 .  rows - the global row indices
5908 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5909 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5910 -  b - optional vector of right hand side, that will be adjusted by provided solution
5911 
5912    Notes:
5913    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5914    but does not release memory.  For the dense and block diagonal
5915    formats this does not alter the nonzero structure.
5916 
5917    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5918    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5919    merely zeroed.
5920 
5921    The user can set a value in the diagonal entry (or for the AIJ and
5922    row formats can optionally remove the main diagonal entry from the
5923    nonzero structure as well, by passing 0.0 as the final argument).
5924 
5925    For the parallel case, all processes that share the matrix (i.e.,
5926    those in the communicator used for matrix creation) MUST call this
5927    routine, regardless of whether any rows being zeroed are owned by
5928    them.
5929 
5930    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5931    list only rows local to itself).
5932 
5933    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5934    owns that are to be zeroed. This saves a global synchronization in the implementation.
5935 
5936    Level: intermediate
5937 
5938    Concepts: matrices^zeroing rows
5939 
5940 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5941           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5942 @*/
5943 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5944 {
5945   PetscErrorCode ierr;
5946 
5947   PetscFunctionBegin;
5948   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5949   PetscValidType(mat,1);
5950   if (numRows) PetscValidIntPointer(rows,3);
5951   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5952   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5953   if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5954   MatCheckPreallocated(mat,1);
5955 
5956   ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5957   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5958   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5959 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5960   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5961     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5962   }
5963 #endif
5964   PetscFunctionReturn(0);
5965 }
5966 
5967 /*@
5968    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5969    of a set of rows of a matrix.
5970 
5971    Collective on Mat
5972 
5973    Input Parameters:
5974 +  mat - the matrix
5975 .  is - index set of rows to remove
5976 .  diag - value put in all diagonals of eliminated rows
5977 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5978 -  b - optional vector of right hand side, that will be adjusted by provided solution
5979 
5980    Notes:
5981    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5982    but does not release memory.  For the dense and block diagonal
5983    formats this does not alter the nonzero structure.
5984 
5985    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5986    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5987    merely zeroed.
5988 
5989    The user can set a value in the diagonal entry (or for the AIJ and
5990    row formats can optionally remove the main diagonal entry from the
5991    nonzero structure as well, by passing 0.0 as the final argument).
5992 
5993    For the parallel case, all processes that share the matrix (i.e.,
5994    those in the communicator used for matrix creation) MUST call this
5995    routine, regardless of whether any rows being zeroed are owned by
5996    them.
5997 
5998    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5999    list only rows local to itself).
6000 
6001    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6002    owns that are to be zeroed. This saves a global synchronization in the implementation.
6003 
6004    Level: intermediate
6005 
6006    Concepts: matrices^zeroing rows
6007 
6008 .seealso: MatZeroRows(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6009           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6010 @*/
6011 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6012 {
6013   PetscInt       numRows;
6014   const PetscInt *rows;
6015   PetscErrorCode ierr;
6016 
6017   PetscFunctionBegin;
6018   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6019   PetscValidType(mat,1);
6020   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6021   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6022   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6023   ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6024   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6025   PetscFunctionReturn(0);
6026 }
6027 
6028 /*@
6029    MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
6030    of a set of rows of a matrix. These rows must be local to the process.
6031 
6032    Collective on Mat
6033 
6034    Input Parameters:
6035 +  mat - the matrix
6036 .  numRows - the number of rows to remove
6037 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
6038 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
6039 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6040 -  b - optional vector of right hand side, that will be adjusted by provided solution
6041 
6042    Notes:
6043    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
6044    but does not release memory.  For the dense and block diagonal
6045    formats this does not alter the nonzero structure.
6046 
6047    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6048    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6049    merely zeroed.
6050 
6051    The user can set a value in the diagonal entry (or for the AIJ and
6052    row formats can optionally remove the main diagonal entry from the
6053    nonzero structure as well, by passing 0.0 as the final argument).
6054 
6055    For the parallel case, all processes that share the matrix (i.e.,
6056    those in the communicator used for matrix creation) MUST call this
6057    routine, regardless of whether any rows being zeroed are owned by
6058    them.
6059 
6060    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
6061    list only rows local to itself).
6062 
6063    The grid coordinates are across the entire grid, not just the local portion
6064 
6065    In Fortran idxm and idxn should be declared as
6066 $     MatStencil idxm(4,m)
6067    and the values inserted using
6068 $    idxm(MatStencil_i,1) = i
6069 $    idxm(MatStencil_j,1) = j
6070 $    idxm(MatStencil_k,1) = k
6071 $    idxm(MatStencil_c,1) = c
6072    etc
6073 
6074    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
6075    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
6076    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
6077    DM_BOUNDARY_PERIODIC boundary type.
6078 
6079    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
6080    a single value per point) you can skip filling those indices.
6081 
6082    Level: intermediate
6083 
6084    Concepts: matrices^zeroing rows
6085 
6086 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsl(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6087           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6088 @*/
6089 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
6090 {
6091   PetscInt       dim     = mat->stencil.dim;
6092   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
6093   PetscInt       *dims   = mat->stencil.dims+1;
6094   PetscInt       *starts = mat->stencil.starts;
6095   PetscInt       *dxm    = (PetscInt*) rows;
6096   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
6097   PetscErrorCode ierr;
6098 
6099   PetscFunctionBegin;
6100   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6101   PetscValidType(mat,1);
6102   if (numRows) PetscValidIntPointer(rows,3);
6103 
6104   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
6105   for (i = 0; i < numRows; ++i) {
6106     /* Skip unused dimensions (they are ordered k, j, i, c) */
6107     for (j = 0; j < 3-sdim; ++j) dxm++;
6108     /* Local index in X dir */
6109     tmp = *dxm++ - starts[0];
6110     /* Loop over remaining dimensions */
6111     for (j = 0; j < dim-1; ++j) {
6112       /* If nonlocal, set index to be negative */
6113       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6114       /* Update local index */
6115       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6116     }
6117     /* Skip component slot if necessary */
6118     if (mat->stencil.noc) dxm++;
6119     /* Local row number */
6120     if (tmp >= 0) {
6121       jdxm[numNewRows++] = tmp;
6122     }
6123   }
6124   ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
6125   ierr = PetscFree(jdxm);CHKERRQ(ierr);
6126   PetscFunctionReturn(0);
6127 }
6128 
6129 /*@
6130    MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal)
6131    of a set of rows and columns of a matrix.
6132 
6133    Collective on Mat
6134 
6135    Input Parameters:
6136 +  mat - the matrix
6137 .  numRows - the number of rows/columns to remove
6138 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
6139 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
6140 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6141 -  b - optional vector of right hand side, that will be adjusted by provided solution
6142 
6143    Notes:
6144    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
6145    but does not release memory.  For the dense and block diagonal
6146    formats this does not alter the nonzero structure.
6147 
6148    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6149    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6150    merely zeroed.
6151 
6152    The user can set a value in the diagonal entry (or for the AIJ and
6153    row formats can optionally remove the main diagonal entry from the
6154    nonzero structure as well, by passing 0.0 as the final argument).
6155 
6156    For the parallel case, all processes that share the matrix (i.e.,
6157    those in the communicator used for matrix creation) MUST call this
6158    routine, regardless of whether any rows being zeroed are owned by
6159    them.
6160 
6161    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
6162    list only rows local to itself, but the row/column numbers are given in local numbering).
6163 
6164    The grid coordinates are across the entire grid, not just the local portion
6165 
6166    In Fortran idxm and idxn should be declared as
6167 $     MatStencil idxm(4,m)
6168    and the values inserted using
6169 $    idxm(MatStencil_i,1) = i
6170 $    idxm(MatStencil_j,1) = j
6171 $    idxm(MatStencil_k,1) = k
6172 $    idxm(MatStencil_c,1) = c
6173    etc
6174 
6175    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
6176    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
6177    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
6178    DM_BOUNDARY_PERIODIC boundary type.
6179 
6180    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
6181    a single value per point) you can skip filling those indices.
6182 
6183    Level: intermediate
6184 
6185    Concepts: matrices^zeroing rows
6186 
6187 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6188           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRows()
6189 @*/
6190 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
6191 {
6192   PetscInt       dim     = mat->stencil.dim;
6193   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
6194   PetscInt       *dims   = mat->stencil.dims+1;
6195   PetscInt       *starts = mat->stencil.starts;
6196   PetscInt       *dxm    = (PetscInt*) rows;
6197   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
6198   PetscErrorCode ierr;
6199 
6200   PetscFunctionBegin;
6201   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6202   PetscValidType(mat,1);
6203   if (numRows) PetscValidIntPointer(rows,3);
6204 
6205   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
6206   for (i = 0; i < numRows; ++i) {
6207     /* Skip unused dimensions (they are ordered k, j, i, c) */
6208     for (j = 0; j < 3-sdim; ++j) dxm++;
6209     /* Local index in X dir */
6210     tmp = *dxm++ - starts[0];
6211     /* Loop over remaining dimensions */
6212     for (j = 0; j < dim-1; ++j) {
6213       /* If nonlocal, set index to be negative */
6214       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6215       /* Update local index */
6216       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6217     }
6218     /* Skip component slot if necessary */
6219     if (mat->stencil.noc) dxm++;
6220     /* Local row number */
6221     if (tmp >= 0) {
6222       jdxm[numNewRows++] = tmp;
6223     }
6224   }
6225   ierr = MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
6226   ierr = PetscFree(jdxm);CHKERRQ(ierr);
6227   PetscFunctionReturn(0);
6228 }
6229 
6230 /*@C
6231    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
6232    of a set of rows of a matrix; using local numbering of rows.
6233 
6234    Collective on Mat
6235 
6236    Input Parameters:
6237 +  mat - the matrix
6238 .  numRows - the number of rows to remove
6239 .  rows - the global row indices
6240 .  diag - value put in all diagonals of eliminated rows
6241 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6242 -  b - optional vector of right hand side, that will be adjusted by provided solution
6243 
6244    Notes:
6245    Before calling MatZeroRowsLocal(), the user must first set the
6246    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6247 
6248    For the AIJ matrix formats this removes the old nonzero structure,
6249    but does not release memory.  For the dense and block diagonal
6250    formats this does not alter the nonzero structure.
6251 
6252    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6253    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6254    merely zeroed.
6255 
6256    The user can set a value in the diagonal entry (or for the AIJ and
6257    row formats can optionally remove the main diagonal entry from the
6258    nonzero structure as well, by passing 0.0 as the final argument).
6259 
6260    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6261    owns that are to be zeroed. This saves a global synchronization in the implementation.
6262 
6263    Level: intermediate
6264 
6265    Concepts: matrices^zeroing
6266 
6267 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRows(), MatSetOption(),
6268           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6269 @*/
6270 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6271 {
6272   PetscErrorCode ierr;
6273 
6274   PetscFunctionBegin;
6275   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6276   PetscValidType(mat,1);
6277   if (numRows) PetscValidIntPointer(rows,3);
6278   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6279   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6280   MatCheckPreallocated(mat,1);
6281 
6282   if (mat->ops->zerorowslocal) {
6283     ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6284   } else {
6285     IS             is, newis;
6286     const PetscInt *newRows;
6287 
6288     if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6289     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6290     ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr);
6291     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6292     ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6293     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6294     ierr = ISDestroy(&newis);CHKERRQ(ierr);
6295     ierr = ISDestroy(&is);CHKERRQ(ierr);
6296   }
6297   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6298 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
6299   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
6300     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
6301   }
6302 #endif
6303   PetscFunctionReturn(0);
6304 }
6305 
6306 /*@
6307    MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
6308    of a set of rows of a matrix; using local numbering of rows.
6309 
6310    Collective on Mat
6311 
6312    Input Parameters:
6313 +  mat - the matrix
6314 .  is - index set of rows to remove
6315 .  diag - value put in all diagonals of eliminated rows
6316 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6317 -  b - optional vector of right hand side, that will be adjusted by provided solution
6318 
6319    Notes:
6320    Before calling MatZeroRowsLocalIS(), the user must first set the
6321    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6322 
6323    For the AIJ matrix formats this removes the old nonzero structure,
6324    but does not release memory.  For the dense and block diagonal
6325    formats this does not alter the nonzero structure.
6326 
6327    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6328    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6329    merely zeroed.
6330 
6331    The user can set a value in the diagonal entry (or for the AIJ and
6332    row formats can optionally remove the main diagonal entry from the
6333    nonzero structure as well, by passing 0.0 as the final argument).
6334 
6335    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6336    owns that are to be zeroed. This saves a global synchronization in the implementation.
6337 
6338    Level: intermediate
6339 
6340    Concepts: matrices^zeroing
6341 
6342 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6343           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6344 @*/
6345 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6346 {
6347   PetscErrorCode ierr;
6348   PetscInt       numRows;
6349   const PetscInt *rows;
6350 
6351   PetscFunctionBegin;
6352   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6353   PetscValidType(mat,1);
6354   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6355   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6356   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6357   MatCheckPreallocated(mat,1);
6358 
6359   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6360   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6361   ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6362   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6363   PetscFunctionReturn(0);
6364 }
6365 
6366 /*@
6367    MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
6368    of a set of rows and columns of a matrix; using local numbering of rows.
6369 
6370    Collective on Mat
6371 
6372    Input Parameters:
6373 +  mat - the matrix
6374 .  numRows - the number of rows to remove
6375 .  rows - the global row indices
6376 .  diag - value put in all diagonals of eliminated rows
6377 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6378 -  b - optional vector of right hand side, that will be adjusted by provided solution
6379 
6380    Notes:
6381    Before calling MatZeroRowsColumnsLocal(), the user must first set the
6382    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6383 
6384    The user can set a value in the diagonal entry (or for the AIJ and
6385    row formats can optionally remove the main diagonal entry from the
6386    nonzero structure as well, by passing 0.0 as the final argument).
6387 
6388    Level: intermediate
6389 
6390    Concepts: matrices^zeroing
6391 
6392 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6393           MatZeroRows(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6394 @*/
6395 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6396 {
6397   PetscErrorCode ierr;
6398   IS             is, newis;
6399   const PetscInt *newRows;
6400 
6401   PetscFunctionBegin;
6402   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6403   PetscValidType(mat,1);
6404   if (numRows) PetscValidIntPointer(rows,3);
6405   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6406   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6407   MatCheckPreallocated(mat,1);
6408 
6409   if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6410   ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6411   ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr);
6412   ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6413   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6414   ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6415   ierr = ISDestroy(&newis);CHKERRQ(ierr);
6416   ierr = ISDestroy(&is);CHKERRQ(ierr);
6417   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6418 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
6419   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
6420     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
6421   }
6422 #endif
6423   PetscFunctionReturn(0);
6424 }
6425 
6426 /*@
6427    MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
6428    of a set of rows and columns of a matrix; using local numbering of rows.
6429 
6430    Collective on Mat
6431 
6432    Input Parameters:
6433 +  mat - the matrix
6434 .  is - index set of rows to remove
6435 .  diag - value put in all diagonals of eliminated rows
6436 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6437 -  b - optional vector of right hand side, that will be adjusted by provided solution
6438 
6439    Notes:
6440    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
6441    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6442 
6443    The user can set a value in the diagonal entry (or for the AIJ and
6444    row formats can optionally remove the main diagonal entry from the
6445    nonzero structure as well, by passing 0.0 as the final argument).
6446 
6447    Level: intermediate
6448 
6449    Concepts: matrices^zeroing
6450 
6451 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6452           MatZeroRowsColumnsLocal(), MatZeroRows(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6453 @*/
6454 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6455 {
6456   PetscErrorCode ierr;
6457   PetscInt       numRows;
6458   const PetscInt *rows;
6459 
6460   PetscFunctionBegin;
6461   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6462   PetscValidType(mat,1);
6463   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6464   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6465   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6466   MatCheckPreallocated(mat,1);
6467 
6468   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6469   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6470   ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6471   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6472   PetscFunctionReturn(0);
6473 }
6474 
6475 /*@C
6476    MatGetSize - Returns the numbers of rows and columns in a matrix.
6477 
6478    Not Collective
6479 
6480    Input Parameter:
6481 .  mat - the matrix
6482 
6483    Output Parameters:
6484 +  m - the number of global rows
6485 -  n - the number of global columns
6486 
6487    Note: both output parameters can be NULL on input.
6488 
6489    Level: beginner
6490 
6491    Concepts: matrices^size
6492 
6493 .seealso: MatGetLocalSize()
6494 @*/
6495 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
6496 {
6497   PetscFunctionBegin;
6498   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6499   if (m) *m = mat->rmap->N;
6500   if (n) *n = mat->cmap->N;
6501   PetscFunctionReturn(0);
6502 }
6503 
6504 /*@C
6505    MatGetLocalSize - Returns the number of rows and columns in a matrix
6506    stored locally.  This information may be implementation dependent, so
6507    use with care.
6508 
6509    Not Collective
6510 
6511    Input Parameters:
6512 .  mat - the matrix
6513 
6514    Output Parameters:
6515 +  m - the number of local rows
6516 -  n - the number of local columns
6517 
6518    Note: both output parameters can be NULL on input.
6519 
6520    Level: beginner
6521 
6522    Concepts: matrices^local size
6523 
6524 .seealso: MatGetSize()
6525 @*/
6526 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
6527 {
6528   PetscFunctionBegin;
6529   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6530   if (m) PetscValidIntPointer(m,2);
6531   if (n) PetscValidIntPointer(n,3);
6532   if (m) *m = mat->rmap->n;
6533   if (n) *n = mat->cmap->n;
6534   PetscFunctionReturn(0);
6535 }
6536 
6537 /*@C
6538    MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6539    this processor. (The columns of the "diagonal block")
6540 
6541    Not Collective, unless matrix has not been allocated, then collective on Mat
6542 
6543    Input Parameters:
6544 .  mat - the matrix
6545 
6546    Output Parameters:
6547 +  m - the global index of the first local column
6548 -  n - one more than the global index of the last local column
6549 
6550    Notes:
6551     both output parameters can be NULL on input.
6552 
6553    Level: developer
6554 
6555    Concepts: matrices^column ownership
6556 
6557 .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
6558 
6559 @*/
6560 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
6561 {
6562   PetscFunctionBegin;
6563   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6564   PetscValidType(mat,1);
6565   if (m) PetscValidIntPointer(m,2);
6566   if (n) PetscValidIntPointer(n,3);
6567   MatCheckPreallocated(mat,1);
6568   if (m) *m = mat->cmap->rstart;
6569   if (n) *n = mat->cmap->rend;
6570   PetscFunctionReturn(0);
6571 }
6572 
6573 /*@C
6574    MatGetOwnershipRange - Returns the range of matrix rows owned by
6575    this processor, assuming that the matrix is laid out with the first
6576    n1 rows on the first processor, the next n2 rows on the second, etc.
6577    For certain parallel layouts this range may not be well defined.
6578 
6579    Not Collective
6580 
6581    Input Parameters:
6582 .  mat - the matrix
6583 
6584    Output Parameters:
6585 +  m - the global index of the first local row
6586 -  n - one more than the global index of the last local row
6587 
6588    Note: Both output parameters can be NULL on input.
6589 $  This function requires that the matrix be preallocated. If you have not preallocated, consider using
6590 $    PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
6591 $  and then MPI_Scan() to calculate prefix sums of the local sizes.
6592 
6593    Level: beginner
6594 
6595    Concepts: matrices^row ownership
6596 
6597 .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()
6598 
6599 @*/
6600 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6601 {
6602   PetscFunctionBegin;
6603   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6604   PetscValidType(mat,1);
6605   if (m) PetscValidIntPointer(m,2);
6606   if (n) PetscValidIntPointer(n,3);
6607   MatCheckPreallocated(mat,1);
6608   if (m) *m = mat->rmap->rstart;
6609   if (n) *n = mat->rmap->rend;
6610   PetscFunctionReturn(0);
6611 }
6612 
6613 /*@C
6614    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6615    each process
6616 
6617    Not Collective, unless matrix has not been allocated, then collective on Mat
6618 
6619    Input Parameters:
6620 .  mat - the matrix
6621 
6622    Output Parameters:
6623 .  ranges - start of each processors portion plus one more than the total length at the end
6624 
6625    Level: beginner
6626 
6627    Concepts: matrices^row ownership
6628 
6629 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
6630 
6631 @*/
6632 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6633 {
6634   PetscErrorCode ierr;
6635 
6636   PetscFunctionBegin;
6637   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6638   PetscValidType(mat,1);
6639   MatCheckPreallocated(mat,1);
6640   ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr);
6641   PetscFunctionReturn(0);
6642 }
6643 
6644 /*@C
6645    MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6646    this processor. (The columns of the "diagonal blocks" for each process)
6647 
6648    Not Collective, unless matrix has not been allocated, then collective on Mat
6649 
6650    Input Parameters:
6651 .  mat - the matrix
6652 
6653    Output Parameters:
6654 .  ranges - start of each processors portion plus one more then the total length at the end
6655 
6656    Level: beginner
6657 
6658    Concepts: matrices^column ownership
6659 
6660 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
6661 
6662 @*/
6663 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6664 {
6665   PetscErrorCode ierr;
6666 
6667   PetscFunctionBegin;
6668   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6669   PetscValidType(mat,1);
6670   MatCheckPreallocated(mat,1);
6671   ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr);
6672   PetscFunctionReturn(0);
6673 }
6674 
6675 /*@C
6676    MatGetOwnershipIS - Get row and column ownership as index sets
6677 
6678    Not Collective
6679 
6680    Input Arguments:
6681 .  A - matrix of type Elemental
6682 
6683    Output Arguments:
6684 +  rows - rows in which this process owns elements
6685 .  cols - columns in which this process owns elements
6686 
6687    Level: intermediate
6688 
6689 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL
6690 @*/
6691 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6692 {
6693   PetscErrorCode ierr,(*f)(Mat,IS*,IS*);
6694 
6695   PetscFunctionBegin;
6696   MatCheckPreallocated(A,1);
6697   ierr = PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);CHKERRQ(ierr);
6698   if (f) {
6699     ierr = (*f)(A,rows,cols);CHKERRQ(ierr);
6700   } else {   /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6701     if (rows) {ierr = ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);CHKERRQ(ierr);}
6702     if (cols) {ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);CHKERRQ(ierr);}
6703   }
6704   PetscFunctionReturn(0);
6705 }
6706 
6707 /*@C
6708    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6709    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6710    to complete the factorization.
6711 
6712    Collective on Mat
6713 
6714    Input Parameters:
6715 +  mat - the matrix
6716 .  row - row permutation
6717 .  column - column permutation
6718 -  info - structure containing
6719 $      levels - number of levels of fill.
6720 $      expected fill - as ratio of original fill.
6721 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6722                 missing diagonal entries)
6723 
6724    Output Parameters:
6725 .  fact - new matrix that has been symbolically factored
6726 
6727    Notes:
6728     See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
6729 
6730    Most users should employ the simplified KSP interface for linear solvers
6731    instead of working directly with matrix algebra routines such as this.
6732    See, e.g., KSPCreate().
6733 
6734    Level: developer
6735 
6736   Concepts: matrices^symbolic LU factorization
6737   Concepts: matrices^factorization
6738   Concepts: LU^symbolic factorization
6739 
6740 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6741           MatGetOrdering(), MatFactorInfo
6742 
6743     Note: this uses the definition of level of fill as in Y. Saad, 2003
6744 
6745     Developer Note: fortran interface is not autogenerated as the f90
6746     interface defintion cannot be generated correctly [due to MatFactorInfo]
6747 
6748    References:
6749      Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003
6750 @*/
6751 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6752 {
6753   PetscErrorCode ierr;
6754 
6755   PetscFunctionBegin;
6756   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6757   PetscValidType(mat,1);
6758   PetscValidHeaderSpecific(row,IS_CLASSID,2);
6759   PetscValidHeaderSpecific(col,IS_CLASSID,3);
6760   PetscValidPointer(info,4);
6761   PetscValidPointer(fact,5);
6762   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6763   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6764   if (!(fact)->ops->ilufactorsymbolic) {
6765     MatSolverType spackage;
6766     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
6767     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6768   }
6769   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6770   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6771   MatCheckPreallocated(mat,2);
6772 
6773   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6774   ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
6775   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6776   PetscFunctionReturn(0);
6777 }
6778 
6779 /*@C
6780    MatICCFactorSymbolic - Performs symbolic incomplete
6781    Cholesky factorization for a symmetric matrix.  Use
6782    MatCholeskyFactorNumeric() to complete the factorization.
6783 
6784    Collective on Mat
6785 
6786    Input Parameters:
6787 +  mat - the matrix
6788 .  perm - row and column permutation
6789 -  info - structure containing
6790 $      levels - number of levels of fill.
6791 $      expected fill - as ratio of original fill.
6792 
6793    Output Parameter:
6794 .  fact - the factored matrix
6795 
6796    Notes:
6797    Most users should employ the KSP interface for linear solvers
6798    instead of working directly with matrix algebra routines such as this.
6799    See, e.g., KSPCreate().
6800 
6801    Level: developer
6802 
6803   Concepts: matrices^symbolic incomplete Cholesky factorization
6804   Concepts: matrices^factorization
6805   Concepts: Cholsky^symbolic factorization
6806 
6807 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
6808 
6809     Note: this uses the definition of level of fill as in Y. Saad, 2003
6810 
6811     Developer Note: fortran interface is not autogenerated as the f90
6812     interface defintion cannot be generated correctly [due to MatFactorInfo]
6813 
6814    References:
6815      Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003
6816 @*/
6817 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6818 {
6819   PetscErrorCode ierr;
6820 
6821   PetscFunctionBegin;
6822   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6823   PetscValidType(mat,1);
6824   PetscValidHeaderSpecific(perm,IS_CLASSID,2);
6825   PetscValidPointer(info,3);
6826   PetscValidPointer(fact,4);
6827   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6828   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6829   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6830   if (!(fact)->ops->iccfactorsymbolic) {
6831     MatSolverType spackage;
6832     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
6833     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6834   }
6835   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6836   MatCheckPreallocated(mat,2);
6837 
6838   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6839   ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
6840   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6841   PetscFunctionReturn(0);
6842 }
6843 
6844 /*@C
6845    MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat
6846    points to an array of valid matrices, they may be reused to store the new
6847    submatrices.
6848 
6849    Collective on Mat
6850 
6851    Input Parameters:
6852 +  mat - the matrix
6853 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6854 .  irow, icol - index sets of rows and columns to extract
6855 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6856 
6857    Output Parameter:
6858 .  submat - the array of submatrices
6859 
6860    Notes:
6861    MatCreateSubMatrices() can extract ONLY sequential submatrices
6862    (from both sequential and parallel matrices). Use MatCreateSubMatrix()
6863    to extract a parallel submatrix.
6864 
6865    Some matrix types place restrictions on the row and column
6866    indices, such as that they be sorted or that they be equal to each other.
6867 
6868    The index sets may not have duplicate entries.
6869 
6870    When extracting submatrices from a parallel matrix, each processor can
6871    form a different submatrix by setting the rows and columns of its
6872    individual index sets according to the local submatrix desired.
6873 
6874    When finished using the submatrices, the user should destroy
6875    them with MatDestroySubMatrices().
6876 
6877    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6878    original matrix has not changed from that last call to MatCreateSubMatrices().
6879 
6880    This routine creates the matrices in submat; you should NOT create them before
6881    calling it. It also allocates the array of matrix pointers submat.
6882 
6883    For BAIJ matrices the index sets must respect the block structure, that is if they
6884    request one row/column in a block, they must request all rows/columns that are in
6885    that block. For example, if the block size is 2 you cannot request just row 0 and
6886    column 0.
6887 
6888    Fortran Note:
6889    The Fortran interface is slightly different from that given below; it
6890    requires one to pass in  as submat a Mat (integer) array of size at least n+1.
6891 
6892    Level: advanced
6893 
6894    Concepts: matrices^accessing submatrices
6895    Concepts: submatrices
6896 
6897 .seealso: MatDestroySubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6898 @*/
6899 PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6900 {
6901   PetscErrorCode ierr;
6902   PetscInt       i;
6903   PetscBool      eq;
6904 
6905   PetscFunctionBegin;
6906   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6907   PetscValidType(mat,1);
6908   if (n) {
6909     PetscValidPointer(irow,3);
6910     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6911     PetscValidPointer(icol,4);
6912     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6913   }
6914   PetscValidPointer(submat,6);
6915   if (n && scall == MAT_REUSE_MATRIX) {
6916     PetscValidPointer(*submat,6);
6917     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6918   }
6919   if (!mat->ops->createsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6920   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6921   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6922   MatCheckPreallocated(mat,1);
6923 
6924   ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6925   ierr = (*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6926   ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6927   for (i=0; i<n; i++) {
6928     (*submat)[i]->factortype = MAT_FACTOR_NONE;  /* in case in place factorization was previously done on submatrix */
6929     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6930       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6931       if (eq) {
6932         if (mat->symmetric) {
6933           ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6934         } else if (mat->hermitian) {
6935           ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6936         } else if (mat->structurally_symmetric) {
6937           ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6938         }
6939       }
6940     }
6941   }
6942   PetscFunctionReturn(0);
6943 }
6944 
6945 /*@C
6946    MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms).
6947 
6948    Collective on Mat
6949 
6950    Input Parameters:
6951 +  mat - the matrix
6952 .  n   - the number of submatrixes to be extracted
6953 .  irow, icol - index sets of rows and columns to extract
6954 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6955 
6956    Output Parameter:
6957 .  submat - the array of submatrices
6958 
6959    Level: advanced
6960 
6961    Concepts: matrices^accessing submatrices
6962    Concepts: submatrices
6963 
6964 .seealso: MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6965 @*/
6966 PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6967 {
6968   PetscErrorCode ierr;
6969   PetscInt       i;
6970   PetscBool      eq;
6971 
6972   PetscFunctionBegin;
6973   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6974   PetscValidType(mat,1);
6975   if (n) {
6976     PetscValidPointer(irow,3);
6977     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6978     PetscValidPointer(icol,4);
6979     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6980   }
6981   PetscValidPointer(submat,6);
6982   if (n && scall == MAT_REUSE_MATRIX) {
6983     PetscValidPointer(*submat,6);
6984     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6985   }
6986   if (!mat->ops->createsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6987   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6988   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6989   MatCheckPreallocated(mat,1);
6990 
6991   ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6992   ierr = (*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6993   ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6994   for (i=0; i<n; i++) {
6995     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6996       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6997       if (eq) {
6998         if (mat->symmetric) {
6999           ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
7000         } else if (mat->hermitian) {
7001           ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
7002         } else if (mat->structurally_symmetric) {
7003           ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
7004         }
7005       }
7006     }
7007   }
7008   PetscFunctionReturn(0);
7009 }
7010 
7011 /*@C
7012    MatDestroyMatrices - Destroys an array of matrices.
7013 
7014    Collective on Mat
7015 
7016    Input Parameters:
7017 +  n - the number of local matrices
7018 -  mat - the matrices (note that this is a pointer to the array of matrices)
7019 
7020    Level: advanced
7021 
7022     Notes:
7023     Frees not only the matrices, but also the array that contains the matrices
7024            In Fortran will not free the array.
7025 
7026 .seealso: MatCreateSubMatrices() MatDestroySubMatrices()
7027 @*/
7028 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
7029 {
7030   PetscErrorCode ierr;
7031   PetscInt       i;
7032 
7033   PetscFunctionBegin;
7034   if (!*mat) PetscFunctionReturn(0);
7035   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
7036   PetscValidPointer(mat,2);
7037 
7038   for (i=0; i<n; i++) {
7039     ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr);
7040   }
7041 
7042   /* memory is allocated even if n = 0 */
7043   ierr = PetscFree(*mat);CHKERRQ(ierr);
7044   PetscFunctionReturn(0);
7045 }
7046 
7047 /*@C
7048    MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices().
7049 
7050    Collective on Mat
7051 
7052    Input Parameters:
7053 +  n - the number of local matrices
7054 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
7055                        sequence of MatCreateSubMatrices())
7056 
7057    Level: advanced
7058 
7059     Notes:
7060     Frees not only the matrices, but also the array that contains the matrices
7061            In Fortran will not free the array.
7062 
7063 .seealso: MatCreateSubMatrices()
7064 @*/
7065 PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[])
7066 {
7067   PetscErrorCode ierr;
7068   Mat            mat0;
7069 
7070   PetscFunctionBegin;
7071   if (!*mat) PetscFunctionReturn(0);
7072   /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */
7073   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
7074   PetscValidPointer(mat,2);
7075 
7076   mat0 = (*mat)[0];
7077   if (mat0 && mat0->ops->destroysubmatrices) {
7078     ierr = (mat0->ops->destroysubmatrices)(n,mat);CHKERRQ(ierr);
7079   } else {
7080     ierr = MatDestroyMatrices(n,mat);CHKERRQ(ierr);
7081   }
7082   PetscFunctionReturn(0);
7083 }
7084 
7085 /*@C
7086    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
7087 
7088    Collective on Mat
7089 
7090    Input Parameters:
7091 .  mat - the matrix
7092 
7093    Output Parameter:
7094 .  matstruct - the sequential matrix with the nonzero structure of mat
7095 
7096   Level: intermediate
7097 
7098 .seealso: MatDestroySeqNonzeroStructure(), MatCreateSubMatrices(), MatDestroyMatrices()
7099 @*/
7100 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
7101 {
7102   PetscErrorCode ierr;
7103 
7104   PetscFunctionBegin;
7105   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7106   PetscValidPointer(matstruct,2);
7107 
7108   PetscValidType(mat,1);
7109   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7110   MatCheckPreallocated(mat,1);
7111 
7112   if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
7113   ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
7114   ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr);
7115   ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
7116   PetscFunctionReturn(0);
7117 }
7118 
7119 /*@C
7120    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
7121 
7122    Collective on Mat
7123 
7124    Input Parameters:
7125 .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
7126                        sequence of MatGetSequentialNonzeroStructure())
7127 
7128    Level: advanced
7129 
7130     Notes:
7131     Frees not only the matrices, but also the array that contains the matrices
7132 
7133 .seealso: MatGetSeqNonzeroStructure()
7134 @*/
7135 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
7136 {
7137   PetscErrorCode ierr;
7138 
7139   PetscFunctionBegin;
7140   PetscValidPointer(mat,1);
7141   ierr = MatDestroy(mat);CHKERRQ(ierr);
7142   PetscFunctionReturn(0);
7143 }
7144 
7145 /*@
7146    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
7147    replaces the index sets by larger ones that represent submatrices with
7148    additional overlap.
7149 
7150    Collective on Mat
7151 
7152    Input Parameters:
7153 +  mat - the matrix
7154 .  n   - the number of index sets
7155 .  is  - the array of index sets (these index sets will changed during the call)
7156 -  ov  - the additional overlap requested
7157 
7158    Options Database:
7159 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
7160 
7161    Level: developer
7162 
7163    Concepts: overlap
7164    Concepts: ASM^computing overlap
7165 
7166 .seealso: MatCreateSubMatrices()
7167 @*/
7168 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
7169 {
7170   PetscErrorCode ierr;
7171 
7172   PetscFunctionBegin;
7173   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7174   PetscValidType(mat,1);
7175   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
7176   if (n) {
7177     PetscValidPointer(is,3);
7178     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
7179   }
7180   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7181   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7182   MatCheckPreallocated(mat,1);
7183 
7184   if (!ov) PetscFunctionReturn(0);
7185   if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7186   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7187   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
7188   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7189   PetscFunctionReturn(0);
7190 }
7191 
7192 
7193 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt);
7194 
7195 /*@
7196    MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across
7197    a sub communicator, replaces the index sets by larger ones that represent submatrices with
7198    additional overlap.
7199 
7200    Collective on Mat
7201 
7202    Input Parameters:
7203 +  mat - the matrix
7204 .  n   - the number of index sets
7205 .  is  - the array of index sets (these index sets will changed during the call)
7206 -  ov  - the additional overlap requested
7207 
7208    Options Database:
7209 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
7210 
7211    Level: developer
7212 
7213    Concepts: overlap
7214    Concepts: ASM^computing overlap
7215 
7216 .seealso: MatCreateSubMatrices()
7217 @*/
7218 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov)
7219 {
7220   PetscInt       i;
7221   PetscErrorCode ierr;
7222 
7223   PetscFunctionBegin;
7224   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7225   PetscValidType(mat,1);
7226   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
7227   if (n) {
7228     PetscValidPointer(is,3);
7229     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
7230   }
7231   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7232   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7233   MatCheckPreallocated(mat,1);
7234   if (!ov) PetscFunctionReturn(0);
7235   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7236   for(i=0; i<n; i++){
7237 	ierr =  MatIncreaseOverlapSplit_Single(mat,&is[i],ov);CHKERRQ(ierr);
7238   }
7239   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7240   PetscFunctionReturn(0);
7241 }
7242 
7243 
7244 
7245 
7246 /*@
7247    MatGetBlockSize - Returns the matrix block size.
7248 
7249    Not Collective
7250 
7251    Input Parameter:
7252 .  mat - the matrix
7253 
7254    Output Parameter:
7255 .  bs - block size
7256 
7257    Notes:
7258     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7259 
7260    If the block size has not been set yet this routine returns 1.
7261 
7262    Level: intermediate
7263 
7264    Concepts: matrices^block size
7265 
7266 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
7267 @*/
7268 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
7269 {
7270   PetscFunctionBegin;
7271   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7272   PetscValidIntPointer(bs,2);
7273   *bs = PetscAbs(mat->rmap->bs);
7274   PetscFunctionReturn(0);
7275 }
7276 
7277 /*@
7278    MatGetBlockSizes - Returns the matrix block row and column sizes.
7279 
7280    Not Collective
7281 
7282    Input Parameter:
7283 .  mat - the matrix
7284 
7285    Output Parameter:
7286 .  rbs - row block size
7287 .  cbs - column block size
7288 
7289    Notes:
7290     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7291     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7292 
7293    If a block size has not been set yet this routine returns 1.
7294 
7295    Level: intermediate
7296 
7297    Concepts: matrices^block size
7298 
7299 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes()
7300 @*/
7301 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
7302 {
7303   PetscFunctionBegin;
7304   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7305   if (rbs) PetscValidIntPointer(rbs,2);
7306   if (cbs) PetscValidIntPointer(cbs,3);
7307   if (rbs) *rbs = PetscAbs(mat->rmap->bs);
7308   if (cbs) *cbs = PetscAbs(mat->cmap->bs);
7309   PetscFunctionReturn(0);
7310 }
7311 
7312 /*@
7313    MatSetBlockSize - Sets the matrix block size.
7314 
7315    Logically Collective on Mat
7316 
7317    Input Parameters:
7318 +  mat - the matrix
7319 -  bs - block size
7320 
7321    Notes:
7322     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7323     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later.
7324 
7325     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size
7326     is compatible with the matrix local sizes.
7327 
7328    Level: intermediate
7329 
7330    Concepts: matrices^block size
7331 
7332 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes()
7333 @*/
7334 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
7335 {
7336   PetscErrorCode ierr;
7337 
7338   PetscFunctionBegin;
7339   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7340   PetscValidLogicalCollectiveInt(mat,bs,2);
7341   ierr = MatSetBlockSizes(mat,bs,bs);CHKERRQ(ierr);
7342   PetscFunctionReturn(0);
7343 }
7344 
7345 /*@
7346    MatSetVariableBlockSizes - Sets a diagonal blocks of the matrix that need not be of the same size
7347 
7348    Logically Collective on Mat
7349 
7350    Input Parameters:
7351 +  mat - the matrix
7352 .  nblocks - the number of blocks on this process
7353 -  bsizes - the block sizes
7354 
7355    Notes:
7356     Currently used by PCVPBJACOBI for SeqAIJ matrices
7357 
7358    Level: intermediate
7359 
7360    Concepts: matrices^block size
7361 
7362 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatGetVariableBlockSizes()
7363 @*/
7364 PetscErrorCode MatSetVariableBlockSizes(Mat mat,PetscInt nblocks,PetscInt *bsizes)
7365 {
7366   PetscErrorCode ierr;
7367   PetscInt       i,ncnt = 0, nlocal;
7368 
7369   PetscFunctionBegin;
7370   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7371   if (nblocks < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number of local blocks must be great than or equal to zero");
7372   ierr = MatGetLocalSize(mat,&nlocal,NULL);CHKERRQ(ierr);
7373   for (i=0; i<nblocks; i++) ncnt += bsizes[i];
7374   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);
7375   ierr = PetscFree(mat->bsizes);CHKERRQ(ierr);
7376   mat->nblocks = nblocks;
7377   ierr = PetscMalloc1(nblocks,&mat->bsizes);CHKERRQ(ierr);
7378   ierr = PetscMemcpy(mat->bsizes,bsizes,nblocks*sizeof(PetscInt));CHKERRQ(ierr);
7379   PetscFunctionReturn(0);
7380 }
7381 
7382 /*@C
7383    MatGetVariableBlockSizes - Gets a diagonal blocks of the matrix that need not be of the same size
7384 
7385    Logically Collective on Mat
7386 
7387    Input Parameters:
7388 .  mat - the matrix
7389 
7390    Output Parameters:
7391 +  nblocks - the number of blocks on this process
7392 -  bsizes - the block sizes
7393 
7394    Notes: Currently not supported from Fortran
7395 
7396    Level: intermediate
7397 
7398    Concepts: matrices^block size
7399 
7400 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatSetVariableBlockSizes()
7401 @*/
7402 PetscErrorCode MatGetVariableBlockSizes(Mat mat,PetscInt *nblocks,const PetscInt **bsizes)
7403 {
7404   PetscFunctionBegin;
7405   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7406   *nblocks = mat->nblocks;
7407   *bsizes  = mat->bsizes;
7408   PetscFunctionReturn(0);
7409 }
7410 
7411 /*@
7412    MatSetBlockSizes - Sets the matrix block row and column sizes.
7413 
7414    Logically Collective on Mat
7415 
7416    Input Parameters:
7417 +  mat - the matrix
7418 -  rbs - row block size
7419 -  cbs - column block size
7420 
7421    Notes:
7422     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7423     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7424     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later
7425 
7426     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes
7427     are compatible with the matrix local sizes.
7428 
7429     The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs().
7430 
7431    Level: intermediate
7432 
7433    Concepts: matrices^block size
7434 
7435 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes()
7436 @*/
7437 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
7438 {
7439   PetscErrorCode ierr;
7440 
7441   PetscFunctionBegin;
7442   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7443   PetscValidLogicalCollectiveInt(mat,rbs,2);
7444   PetscValidLogicalCollectiveInt(mat,cbs,3);
7445   if (mat->ops->setblocksizes) {
7446     ierr = (*mat->ops->setblocksizes)(mat,rbs,cbs);CHKERRQ(ierr);
7447   }
7448   if (mat->rmap->refcnt) {
7449     ISLocalToGlobalMapping l2g = NULL;
7450     PetscLayout            nmap = NULL;
7451 
7452     ierr = PetscLayoutDuplicate(mat->rmap,&nmap);CHKERRQ(ierr);
7453     if (mat->rmap->mapping) {
7454       ierr = ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g);CHKERRQ(ierr);
7455     }
7456     ierr = PetscLayoutDestroy(&mat->rmap);CHKERRQ(ierr);
7457     mat->rmap = nmap;
7458     mat->rmap->mapping = l2g;
7459   }
7460   if (mat->cmap->refcnt) {
7461     ISLocalToGlobalMapping l2g = NULL;
7462     PetscLayout            nmap = NULL;
7463 
7464     ierr = PetscLayoutDuplicate(mat->cmap,&nmap);CHKERRQ(ierr);
7465     if (mat->cmap->mapping) {
7466       ierr = ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g);CHKERRQ(ierr);
7467     }
7468     ierr = PetscLayoutDestroy(&mat->cmap);CHKERRQ(ierr);
7469     mat->cmap = nmap;
7470     mat->cmap->mapping = l2g;
7471   }
7472   ierr = PetscLayoutSetBlockSize(mat->rmap,rbs);CHKERRQ(ierr);
7473   ierr = PetscLayoutSetBlockSize(mat->cmap,cbs);CHKERRQ(ierr);
7474   PetscFunctionReturn(0);
7475 }
7476 
7477 /*@
7478    MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices
7479 
7480    Logically Collective on Mat
7481 
7482    Input Parameters:
7483 +  mat - the matrix
7484 .  fromRow - matrix from which to copy row block size
7485 -  fromCol - matrix from which to copy column block size (can be same as fromRow)
7486 
7487    Level: developer
7488 
7489    Concepts: matrices^block size
7490 
7491 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes()
7492 @*/
7493 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)
7494 {
7495   PetscErrorCode ierr;
7496 
7497   PetscFunctionBegin;
7498   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7499   PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2);
7500   PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3);
7501   if (fromRow->rmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);CHKERRQ(ierr);}
7502   if (fromCol->cmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);CHKERRQ(ierr);}
7503   PetscFunctionReturn(0);
7504 }
7505 
7506 /*@
7507    MatResidual - Default routine to calculate the residual.
7508 
7509    Collective on Mat and Vec
7510 
7511    Input Parameters:
7512 +  mat - the matrix
7513 .  b   - the right-hand-side
7514 -  x   - the approximate solution
7515 
7516    Output Parameter:
7517 .  r - location to store the residual
7518 
7519    Level: developer
7520 
7521 .keywords: MG, default, multigrid, residual
7522 
7523 .seealso: PCMGSetResidual()
7524 @*/
7525 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r)
7526 {
7527   PetscErrorCode ierr;
7528 
7529   PetscFunctionBegin;
7530   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7531   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
7532   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
7533   PetscValidHeaderSpecific(r,VEC_CLASSID,4);
7534   PetscValidType(mat,1);
7535   MatCheckPreallocated(mat,1);
7536   ierr  = PetscLogEventBegin(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7537   if (!mat->ops->residual) {
7538     ierr = MatMult(mat,x,r);CHKERRQ(ierr);
7539     ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr);
7540   } else {
7541     ierr  = (*mat->ops->residual)(mat,b,x,r);CHKERRQ(ierr);
7542   }
7543   ierr  = PetscLogEventEnd(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7544   PetscFunctionReturn(0);
7545 }
7546 
7547 /*@C
7548     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
7549 
7550    Collective on Mat
7551 
7552     Input Parameters:
7553 +   mat - the matrix
7554 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
7555 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
7556 -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
7557                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7558                  always used.
7559 
7560     Output Parameters:
7561 +   n - number of rows in the (possibly compressed) matrix
7562 .   ia - the row pointers; that is ia[0] = 0, ia[row] = ia[row-1] + number of elements in that row of the matrix
7563 .   ja - the column indices
7564 -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
7565            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
7566 
7567     Level: developer
7568 
7569     Notes:
7570     You CANNOT change any of the ia[] or ja[] values.
7571 
7572     Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values.
7573 
7574     Fortran Notes:
7575     In Fortran use
7576 $
7577 $      PetscInt ia(1), ja(1)
7578 $      PetscOffset iia, jja
7579 $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
7580 $      ! Access the ith and jth entries via ia(iia + i) and ja(jja + j)
7581 
7582      or
7583 $
7584 $    PetscInt, pointer :: ia(:),ja(:)
7585 $    call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
7586 $    ! Access the ith and jth entries via ia(i) and ja(j)
7587 
7588 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
7589 @*/
7590 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7591 {
7592   PetscErrorCode ierr;
7593 
7594   PetscFunctionBegin;
7595   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7596   PetscValidType(mat,1);
7597   PetscValidIntPointer(n,5);
7598   if (ia) PetscValidIntPointer(ia,6);
7599   if (ja) PetscValidIntPointer(ja,7);
7600   PetscValidIntPointer(done,8);
7601   MatCheckPreallocated(mat,1);
7602   if (!mat->ops->getrowij) *done = PETSC_FALSE;
7603   else {
7604     *done = PETSC_TRUE;
7605     ierr  = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7606     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7607     ierr  = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7608   }
7609   PetscFunctionReturn(0);
7610 }
7611 
7612 /*@C
7613     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
7614 
7615     Collective on Mat
7616 
7617     Input Parameters:
7618 +   mat - the matrix
7619 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7620 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7621                 symmetrized
7622 .   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7623                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7624                  always used.
7625 .   n - number of columns in the (possibly compressed) matrix
7626 .   ia - the column pointers; that is ia[0] = 0, ia[col] = i[col-1] + number of elements in that col of the matrix
7627 -   ja - the row indices
7628 
7629     Output Parameters:
7630 .   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
7631 
7632     Level: developer
7633 
7634 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7635 @*/
7636 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7637 {
7638   PetscErrorCode ierr;
7639 
7640   PetscFunctionBegin;
7641   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7642   PetscValidType(mat,1);
7643   PetscValidIntPointer(n,4);
7644   if (ia) PetscValidIntPointer(ia,5);
7645   if (ja) PetscValidIntPointer(ja,6);
7646   PetscValidIntPointer(done,7);
7647   MatCheckPreallocated(mat,1);
7648   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
7649   else {
7650     *done = PETSC_TRUE;
7651     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7652   }
7653   PetscFunctionReturn(0);
7654 }
7655 
7656 /*@C
7657     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
7658     MatGetRowIJ().
7659 
7660     Collective on Mat
7661 
7662     Input Parameters:
7663 +   mat - the matrix
7664 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7665 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7666                 symmetrized
7667 .   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7668                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7669                  always used.
7670 .   n - size of (possibly compressed) matrix
7671 .   ia - the row pointers
7672 -   ja - the column indices
7673 
7674     Output Parameters:
7675 .   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7676 
7677     Note:
7678     This routine zeros out n, ia, and ja. This is to prevent accidental
7679     us of the array after it has been restored. If you pass NULL, it will
7680     not zero the pointers.  Use of ia or ja after MatRestoreRowIJ() is invalid.
7681 
7682     Level: developer
7683 
7684 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7685 @*/
7686 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7687 {
7688   PetscErrorCode ierr;
7689 
7690   PetscFunctionBegin;
7691   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7692   PetscValidType(mat,1);
7693   if (ia) PetscValidIntPointer(ia,6);
7694   if (ja) PetscValidIntPointer(ja,7);
7695   PetscValidIntPointer(done,8);
7696   MatCheckPreallocated(mat,1);
7697 
7698   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
7699   else {
7700     *done = PETSC_TRUE;
7701     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7702     if (n)  *n = 0;
7703     if (ia) *ia = NULL;
7704     if (ja) *ja = NULL;
7705   }
7706   PetscFunctionReturn(0);
7707 }
7708 
7709 /*@C
7710     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
7711     MatGetColumnIJ().
7712 
7713     Collective on Mat
7714 
7715     Input Parameters:
7716 +   mat - the matrix
7717 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7718 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7719                 symmetrized
7720 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7721                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7722                  always used.
7723 
7724     Output Parameters:
7725 +   n - size of (possibly compressed) matrix
7726 .   ia - the column pointers
7727 .   ja - the row indices
7728 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7729 
7730     Level: developer
7731 
7732 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
7733 @*/
7734 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7735 {
7736   PetscErrorCode ierr;
7737 
7738   PetscFunctionBegin;
7739   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7740   PetscValidType(mat,1);
7741   if (ia) PetscValidIntPointer(ia,5);
7742   if (ja) PetscValidIntPointer(ja,6);
7743   PetscValidIntPointer(done,7);
7744   MatCheckPreallocated(mat,1);
7745 
7746   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
7747   else {
7748     *done = PETSC_TRUE;
7749     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7750     if (n)  *n = 0;
7751     if (ia) *ia = NULL;
7752     if (ja) *ja = NULL;
7753   }
7754   PetscFunctionReturn(0);
7755 }
7756 
7757 /*@C
7758     MatColoringPatch -Used inside matrix coloring routines that
7759     use MatGetRowIJ() and/or MatGetColumnIJ().
7760 
7761     Collective on Mat
7762 
7763     Input Parameters:
7764 +   mat - the matrix
7765 .   ncolors - max color value
7766 .   n   - number of entries in colorarray
7767 -   colorarray - array indicating color for each column
7768 
7769     Output Parameters:
7770 .   iscoloring - coloring generated using colorarray information
7771 
7772     Level: developer
7773 
7774 .seealso: MatGetRowIJ(), MatGetColumnIJ()
7775 
7776 @*/
7777 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7778 {
7779   PetscErrorCode ierr;
7780 
7781   PetscFunctionBegin;
7782   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7783   PetscValidType(mat,1);
7784   PetscValidIntPointer(colorarray,4);
7785   PetscValidPointer(iscoloring,5);
7786   MatCheckPreallocated(mat,1);
7787 
7788   if (!mat->ops->coloringpatch) {
7789     ierr = ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);CHKERRQ(ierr);
7790   } else {
7791     ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
7792   }
7793   PetscFunctionReturn(0);
7794 }
7795 
7796 
7797 /*@
7798    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
7799 
7800    Logically Collective on Mat
7801 
7802    Input Parameter:
7803 .  mat - the factored matrix to be reset
7804 
7805    Notes:
7806    This routine should be used only with factored matrices formed by in-place
7807    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7808    format).  This option can save memory, for example, when solving nonlinear
7809    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7810    ILU(0) preconditioner.
7811 
7812    Note that one can specify in-place ILU(0) factorization by calling
7813 .vb
7814      PCType(pc,PCILU);
7815      PCFactorSeUseInPlace(pc);
7816 .ve
7817    or by using the options -pc_type ilu -pc_factor_in_place
7818 
7819    In-place factorization ILU(0) can also be used as a local
7820    solver for the blocks within the block Jacobi or additive Schwarz
7821    methods (runtime option: -sub_pc_factor_in_place).  See Users-Manual: ch_pc
7822    for details on setting local solver options.
7823 
7824    Most users should employ the simplified KSP interface for linear solvers
7825    instead of working directly with matrix algebra routines such as this.
7826    See, e.g., KSPCreate().
7827 
7828    Level: developer
7829 
7830 .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace()
7831 
7832    Concepts: matrices^unfactored
7833 
7834 @*/
7835 PetscErrorCode MatSetUnfactored(Mat mat)
7836 {
7837   PetscErrorCode ierr;
7838 
7839   PetscFunctionBegin;
7840   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7841   PetscValidType(mat,1);
7842   MatCheckPreallocated(mat,1);
7843   mat->factortype = MAT_FACTOR_NONE;
7844   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
7845   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
7846   PetscFunctionReturn(0);
7847 }
7848 
7849 /*MC
7850     MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.
7851 
7852     Synopsis:
7853     MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7854 
7855     Not collective
7856 
7857     Input Parameter:
7858 .   x - matrix
7859 
7860     Output Parameters:
7861 +   xx_v - the Fortran90 pointer to the array
7862 -   ierr - error code
7863 
7864     Example of Usage:
7865 .vb
7866       PetscScalar, pointer xx_v(:,:)
7867       ....
7868       call MatDenseGetArrayF90(x,xx_v,ierr)
7869       a = xx_v(3)
7870       call MatDenseRestoreArrayF90(x,xx_v,ierr)
7871 .ve
7872 
7873     Level: advanced
7874 
7875 .seealso:  MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90()
7876 
7877     Concepts: matrices^accessing array
7878 
7879 M*/
7880 
7881 /*MC
7882     MatDenseRestoreArrayF90 - Restores a matrix array that has been
7883     accessed with MatDenseGetArrayF90().
7884 
7885     Synopsis:
7886     MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7887 
7888     Not collective
7889 
7890     Input Parameters:
7891 +   x - matrix
7892 -   xx_v - the Fortran90 pointer to the array
7893 
7894     Output Parameter:
7895 .   ierr - error code
7896 
7897     Example of Usage:
7898 .vb
7899        PetscScalar, pointer xx_v(:,:)
7900        ....
7901        call MatDenseGetArrayF90(x,xx_v,ierr)
7902        a = xx_v(3)
7903        call MatDenseRestoreArrayF90(x,xx_v,ierr)
7904 .ve
7905 
7906     Level: advanced
7907 
7908 .seealso:  MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90()
7909 
7910 M*/
7911 
7912 
7913 /*MC
7914     MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.
7915 
7916     Synopsis:
7917     MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7918 
7919     Not collective
7920 
7921     Input Parameter:
7922 .   x - matrix
7923 
7924     Output Parameters:
7925 +   xx_v - the Fortran90 pointer to the array
7926 -   ierr - error code
7927 
7928     Example of Usage:
7929 .vb
7930       PetscScalar, pointer xx_v(:)
7931       ....
7932       call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7933       a = xx_v(3)
7934       call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7935 .ve
7936 
7937     Level: advanced
7938 
7939 .seealso:  MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90()
7940 
7941     Concepts: matrices^accessing array
7942 
7943 M*/
7944 
7945 /*MC
7946     MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7947     accessed with MatSeqAIJGetArrayF90().
7948 
7949     Synopsis:
7950     MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7951 
7952     Not collective
7953 
7954     Input Parameters:
7955 +   x - matrix
7956 -   xx_v - the Fortran90 pointer to the array
7957 
7958     Output Parameter:
7959 .   ierr - error code
7960 
7961     Example of Usage:
7962 .vb
7963        PetscScalar, pointer xx_v(:)
7964        ....
7965        call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7966        a = xx_v(3)
7967        call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7968 .ve
7969 
7970     Level: advanced
7971 
7972 .seealso:  MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90()
7973 
7974 M*/
7975 
7976 
7977 /*@
7978     MatCreateSubMatrix - Gets a single submatrix on the same number of processors
7979                       as the original matrix.
7980 
7981     Collective on Mat
7982 
7983     Input Parameters:
7984 +   mat - the original matrix
7985 .   isrow - parallel IS containing the rows this processor should obtain
7986 .   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.
7987 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7988 
7989     Output Parameter:
7990 .   newmat - the new submatrix, of the same type as the old
7991 
7992     Level: advanced
7993 
7994     Notes:
7995     The submatrix will be able to be multiplied with vectors using the same layout as iscol.
7996 
7997     Some matrix types place restrictions on the row and column indices, such
7998     as that they be sorted or that they be equal to each other.
7999 
8000     The index sets may not have duplicate entries.
8001 
8002       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
8003    the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls
8004    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
8005    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
8006    you are finished using it.
8007 
8008     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
8009     the input matrix.
8010 
8011     If iscol is NULL then all columns are obtained (not supported in Fortran).
8012 
8013    Example usage:
8014    Consider the following 8x8 matrix with 34 non-zero values, that is
8015    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
8016    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
8017    as follows:
8018 
8019 .vb
8020             1  2  0  |  0  3  0  |  0  4
8021     Proc0   0  5  6  |  7  0  0  |  8  0
8022             9  0 10  | 11  0  0  | 12  0
8023     -------------------------------------
8024            13  0 14  | 15 16 17  |  0  0
8025     Proc1   0 18  0  | 19 20 21  |  0  0
8026             0  0  0  | 22 23  0  | 24  0
8027     -------------------------------------
8028     Proc2  25 26 27  |  0  0 28  | 29  0
8029            30  0  0  | 31 32 33  |  0 34
8030 .ve
8031 
8032     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is
8033 
8034 .vb
8035             2  0  |  0  3  0  |  0
8036     Proc0   5  6  |  7  0  0  |  8
8037     -------------------------------
8038     Proc1  18  0  | 19 20 21  |  0
8039     -------------------------------
8040     Proc2  26 27  |  0  0 28  | 29
8041             0  0  | 31 32 33  |  0
8042 .ve
8043 
8044 
8045     Concepts: matrices^submatrices
8046 
8047 .seealso: MatCreateSubMatrices()
8048 @*/
8049 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
8050 {
8051   PetscErrorCode ierr;
8052   PetscMPIInt    size;
8053   Mat            *local;
8054   IS             iscoltmp;
8055 
8056   PetscFunctionBegin;
8057   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8058   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
8059   if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
8060   PetscValidPointer(newmat,5);
8061   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5);
8062   PetscValidType(mat,1);
8063   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8064   if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX");
8065 
8066   MatCheckPreallocated(mat,1);
8067   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
8068 
8069   if (!iscol || isrow == iscol) {
8070     PetscBool   stride;
8071     PetscMPIInt grabentirematrix = 0,grab;
8072     ierr = PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);CHKERRQ(ierr);
8073     if (stride) {
8074       PetscInt first,step,n,rstart,rend;
8075       ierr = ISStrideGetInfo(isrow,&first,&step);CHKERRQ(ierr);
8076       if (step == 1) {
8077         ierr = MatGetOwnershipRange(mat,&rstart,&rend);CHKERRQ(ierr);
8078         if (rstart == first) {
8079           ierr = ISGetLocalSize(isrow,&n);CHKERRQ(ierr);
8080           if (n == rend-rstart) {
8081             grabentirematrix = 1;
8082           }
8083         }
8084       }
8085     }
8086     ierr = MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr);
8087     if (grab) {
8088       ierr = PetscInfo(mat,"Getting entire matrix as submatrix\n");CHKERRQ(ierr);
8089       if (cll == MAT_INITIAL_MATRIX) {
8090         *newmat = mat;
8091         ierr    = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr);
8092       }
8093       PetscFunctionReturn(0);
8094     }
8095   }
8096 
8097   if (!iscol) {
8098     ierr = ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr);
8099   } else {
8100     iscoltmp = iscol;
8101   }
8102 
8103   /* if original matrix is on just one processor then use submatrix generated */
8104   if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
8105     ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
8106     goto setproperties;
8107   } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) {
8108     ierr    = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
8109     *newmat = *local;
8110     ierr    = PetscFree(local);CHKERRQ(ierr);
8111     goto setproperties;
8112   } else if (!mat->ops->createsubmatrix) {
8113     /* Create a new matrix type that implements the operation using the full matrix */
8114     ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8115     switch (cll) {
8116     case MAT_INITIAL_MATRIX:
8117       ierr = MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr);
8118       break;
8119     case MAT_REUSE_MATRIX:
8120       ierr = MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr);
8121       break;
8122     default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
8123     }
8124     ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8125     goto setproperties;
8126   }
8127 
8128   if (!mat->ops->createsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8129   ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8130   ierr = (*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr);
8131   ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8132 
8133   /* Propagate symmetry information for diagonal blocks */
8134 setproperties:
8135   if (isrow == iscoltmp) {
8136     if (mat->symmetric_set && mat->symmetric) {
8137       ierr = MatSetOption(*newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
8138     }
8139     if (mat->structurally_symmetric_set && mat->structurally_symmetric) {
8140       ierr = MatSetOption(*newmat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
8141     }
8142     if (mat->hermitian_set && mat->hermitian) {
8143       ierr = MatSetOption(*newmat,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
8144     }
8145     if (mat->spd_set && mat->spd) {
8146       ierr = MatSetOption(*newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr);
8147     }
8148   }
8149 
8150   if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
8151   if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);}
8152   PetscFunctionReturn(0);
8153 }
8154 
8155 /*@
8156    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
8157    used during the assembly process to store values that belong to
8158    other processors.
8159 
8160    Not Collective
8161 
8162    Input Parameters:
8163 +  mat   - the matrix
8164 .  size  - the initial size of the stash.
8165 -  bsize - the initial size of the block-stash(if used).
8166 
8167    Options Database Keys:
8168 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
8169 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
8170 
8171    Level: intermediate
8172 
8173    Notes:
8174      The block-stash is used for values set with MatSetValuesBlocked() while
8175      the stash is used for values set with MatSetValues()
8176 
8177      Run with the option -info and look for output of the form
8178      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
8179      to determine the appropriate value, MM, to use for size and
8180      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
8181      to determine the value, BMM to use for bsize
8182 
8183    Concepts: stash^setting matrix size
8184    Concepts: matrices^stash
8185 
8186 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
8187 
8188 @*/
8189 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
8190 {
8191   PetscErrorCode ierr;
8192 
8193   PetscFunctionBegin;
8194   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8195   PetscValidType(mat,1);
8196   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
8197   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
8198   PetscFunctionReturn(0);
8199 }
8200 
8201 /*@
8202    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
8203      the matrix
8204 
8205    Neighbor-wise Collective on Mat
8206 
8207    Input Parameters:
8208 +  mat   - the matrix
8209 .  x,y - the vectors
8210 -  w - where the result is stored
8211 
8212    Level: intermediate
8213 
8214    Notes:
8215     w may be the same vector as y.
8216 
8217     This allows one to use either the restriction or interpolation (its transpose)
8218     matrix to do the interpolation
8219 
8220     Concepts: interpolation
8221 
8222 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
8223 
8224 @*/
8225 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
8226 {
8227   PetscErrorCode ierr;
8228   PetscInt       M,N,Ny;
8229 
8230   PetscFunctionBegin;
8231   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8232   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8233   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8234   PetscValidHeaderSpecific(w,VEC_CLASSID,4);
8235   PetscValidType(A,1);
8236   MatCheckPreallocated(A,1);
8237   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8238   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8239   if (M == Ny) {
8240     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
8241   } else {
8242     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
8243   }
8244   PetscFunctionReturn(0);
8245 }
8246 
8247 /*@
8248    MatInterpolate - y = A*x or A'*x depending on the shape of
8249      the matrix
8250 
8251    Neighbor-wise Collective on Mat
8252 
8253    Input Parameters:
8254 +  mat   - the matrix
8255 -  x,y - the vectors
8256 
8257    Level: intermediate
8258 
8259    Notes:
8260     This allows one to use either the restriction or interpolation (its transpose)
8261     matrix to do the interpolation
8262 
8263    Concepts: matrices^interpolation
8264 
8265 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
8266 
8267 @*/
8268 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
8269 {
8270   PetscErrorCode ierr;
8271   PetscInt       M,N,Ny;
8272 
8273   PetscFunctionBegin;
8274   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8275   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8276   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8277   PetscValidType(A,1);
8278   MatCheckPreallocated(A,1);
8279   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8280   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8281   if (M == Ny) {
8282     ierr = MatMult(A,x,y);CHKERRQ(ierr);
8283   } else {
8284     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
8285   }
8286   PetscFunctionReturn(0);
8287 }
8288 
8289 /*@
8290    MatRestrict - y = A*x or A'*x
8291 
8292    Neighbor-wise Collective on Mat
8293 
8294    Input Parameters:
8295 +  mat   - the matrix
8296 -  x,y - the vectors
8297 
8298    Level: intermediate
8299 
8300    Notes:
8301     This allows one to use either the restriction or interpolation (its transpose)
8302     matrix to do the restriction
8303 
8304    Concepts: matrices^restriction
8305 
8306 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
8307 
8308 @*/
8309 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
8310 {
8311   PetscErrorCode ierr;
8312   PetscInt       M,N,Ny;
8313 
8314   PetscFunctionBegin;
8315   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8316   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8317   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8318   PetscValidType(A,1);
8319   MatCheckPreallocated(A,1);
8320 
8321   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8322   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8323   if (M == Ny) {
8324     ierr = MatMult(A,x,y);CHKERRQ(ierr);
8325   } else {
8326     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
8327   }
8328   PetscFunctionReturn(0);
8329 }
8330 
8331 /*@
8332    MatGetNullSpace - retrieves the null space of a matrix.
8333 
8334    Logically Collective on Mat and MatNullSpace
8335 
8336    Input Parameters:
8337 +  mat - the matrix
8338 -  nullsp - the null space object
8339 
8340    Level: developer
8341 
8342    Concepts: null space^attaching to matrix
8343 
8344 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace()
8345 @*/
8346 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
8347 {
8348   PetscFunctionBegin;
8349   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8350   PetscValidPointer(nullsp,2);
8351   *nullsp = (mat->symmetric_set && mat->symmetric && !mat->nullsp) ? mat->transnullsp : mat->nullsp;
8352   PetscFunctionReturn(0);
8353 }
8354 
8355 /*@
8356    MatSetNullSpace - attaches a null space to a matrix.
8357 
8358    Logically Collective on Mat and MatNullSpace
8359 
8360    Input Parameters:
8361 +  mat - the matrix
8362 -  nullsp - the null space object
8363 
8364    Level: advanced
8365 
8366    Notes:
8367       This null space is used by the linear solvers. Overwrites any previous null space that may have been attached
8368 
8369       For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should
8370       call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense.
8371 
8372       You can remove the null space by calling this routine with an nullsp of NULL
8373 
8374 
8375       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8376    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).
8377    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
8378    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
8379    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).
8380 
8381       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8382 
8383     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
8384     routine also automatically calls MatSetTransposeNullSpace().
8385 
8386    Concepts: null space^attaching to matrix
8387 
8388 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8389 @*/
8390 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp)
8391 {
8392   PetscErrorCode ierr;
8393 
8394   PetscFunctionBegin;
8395   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8396   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8397   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8398   ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr);
8399   mat->nullsp = nullsp;
8400   if (mat->symmetric_set && mat->symmetric) {
8401     ierr = MatSetTransposeNullSpace(mat,nullsp);CHKERRQ(ierr);
8402   }
8403   PetscFunctionReturn(0);
8404 }
8405 
8406 /*@
8407    MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix.
8408 
8409    Logically Collective on Mat and MatNullSpace
8410 
8411    Input Parameters:
8412 +  mat - the matrix
8413 -  nullsp - the null space object
8414 
8415    Level: developer
8416 
8417    Concepts: null space^attaching to matrix
8418 
8419 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace()
8420 @*/
8421 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp)
8422 {
8423   PetscFunctionBegin;
8424   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8425   PetscValidType(mat,1);
8426   PetscValidPointer(nullsp,2);
8427   *nullsp = (mat->symmetric_set && mat->symmetric && !mat->transnullsp) ? mat->nullsp : mat->transnullsp;
8428   PetscFunctionReturn(0);
8429 }
8430 
8431 /*@
8432    MatSetTransposeNullSpace - attaches a null space to a matrix.
8433 
8434    Logically Collective on Mat and MatNullSpace
8435 
8436    Input Parameters:
8437 +  mat - the matrix
8438 -  nullsp - the null space object
8439 
8440    Level: advanced
8441 
8442    Notes:
8443       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.
8444       You must also call MatSetNullSpace()
8445 
8446 
8447       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8448    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).
8449    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
8450    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
8451    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).
8452 
8453       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8454 
8455    Concepts: null space^attaching to matrix
8456 
8457 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8458 @*/
8459 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp)
8460 {
8461   PetscErrorCode ierr;
8462 
8463   PetscFunctionBegin;
8464   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8465   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8466   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8467   ierr = MatNullSpaceDestroy(&mat->transnullsp);CHKERRQ(ierr);
8468   mat->transnullsp = nullsp;
8469   PetscFunctionReturn(0);
8470 }
8471 
8472 /*@
8473    MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions
8474         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.
8475 
8476    Logically Collective on Mat and MatNullSpace
8477 
8478    Input Parameters:
8479 +  mat - the matrix
8480 -  nullsp - the null space object
8481 
8482    Level: advanced
8483 
8484    Notes:
8485       Overwrites any previous near null space that may have been attached
8486 
8487       You can remove the null space by calling this routine with an nullsp of NULL
8488 
8489    Concepts: null space^attaching to matrix
8490 
8491 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace()
8492 @*/
8493 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
8494 {
8495   PetscErrorCode ierr;
8496 
8497   PetscFunctionBegin;
8498   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8499   PetscValidType(mat,1);
8500   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8501   MatCheckPreallocated(mat,1);
8502   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8503   ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr);
8504   mat->nearnullsp = nullsp;
8505   PetscFunctionReturn(0);
8506 }
8507 
8508 /*@
8509    MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()
8510 
8511    Not Collective
8512 
8513    Input Parameters:
8514 .  mat - the matrix
8515 
8516    Output Parameters:
8517 .  nullsp - the null space object, NULL if not set
8518 
8519    Level: developer
8520 
8521    Concepts: null space^attaching to matrix
8522 
8523 .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate()
8524 @*/
8525 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
8526 {
8527   PetscFunctionBegin;
8528   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8529   PetscValidType(mat,1);
8530   PetscValidPointer(nullsp,2);
8531   MatCheckPreallocated(mat,1);
8532   *nullsp = mat->nearnullsp;
8533   PetscFunctionReturn(0);
8534 }
8535 
8536 /*@C
8537    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
8538 
8539    Collective on Mat
8540 
8541    Input Parameters:
8542 +  mat - the matrix
8543 .  row - row/column permutation
8544 .  fill - expected fill factor >= 1.0
8545 -  level - level of fill, for ICC(k)
8546 
8547    Notes:
8548    Probably really in-place only when level of fill is zero, otherwise allocates
8549    new space to store factored matrix and deletes previous memory.
8550 
8551    Most users should employ the simplified KSP interface for linear solvers
8552    instead of working directly with matrix algebra routines such as this.
8553    See, e.g., KSPCreate().
8554 
8555    Level: developer
8556 
8557    Concepts: matrices^incomplete Cholesky factorization
8558    Concepts: Cholesky factorization
8559 
8560 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
8561 
8562     Developer Note: fortran interface is not autogenerated as the f90
8563     interface defintion cannot be generated correctly [due to MatFactorInfo]
8564 
8565 @*/
8566 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
8567 {
8568   PetscErrorCode ierr;
8569 
8570   PetscFunctionBegin;
8571   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8572   PetscValidType(mat,1);
8573   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
8574   PetscValidPointer(info,3);
8575   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
8576   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8577   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8578   if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8579   MatCheckPreallocated(mat,1);
8580   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
8581   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8582   PetscFunctionReturn(0);
8583 }
8584 
8585 /*@
8586    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
8587          ghosted ones.
8588 
8589    Not Collective
8590 
8591    Input Parameters:
8592 +  mat - the matrix
8593 -  diag = the diagonal values, including ghost ones
8594 
8595    Level: developer
8596 
8597    Notes:
8598     Works only for MPIAIJ and MPIBAIJ matrices
8599 
8600 .seealso: MatDiagonalScale()
8601 @*/
8602 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
8603 {
8604   PetscErrorCode ierr;
8605   PetscMPIInt    size;
8606 
8607   PetscFunctionBegin;
8608   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8609   PetscValidHeaderSpecific(diag,VEC_CLASSID,2);
8610   PetscValidType(mat,1);
8611 
8612   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8613   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8614   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
8615   if (size == 1) {
8616     PetscInt n,m;
8617     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
8618     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
8619     if (m == n) {
8620       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
8621     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
8622   } else {
8623     ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr);
8624   }
8625   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8626   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8627   PetscFunctionReturn(0);
8628 }
8629 
8630 /*@
8631    MatGetInertia - Gets the inertia from a factored matrix
8632 
8633    Collective on Mat
8634 
8635    Input Parameter:
8636 .  mat - the matrix
8637 
8638    Output Parameters:
8639 +   nneg - number of negative eigenvalues
8640 .   nzero - number of zero eigenvalues
8641 -   npos - number of positive eigenvalues
8642 
8643    Level: advanced
8644 
8645    Notes:
8646     Matrix must have been factored by MatCholeskyFactor()
8647 
8648 
8649 @*/
8650 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
8651 {
8652   PetscErrorCode ierr;
8653 
8654   PetscFunctionBegin;
8655   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8656   PetscValidType(mat,1);
8657   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8658   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
8659   if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8660   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
8661   PetscFunctionReturn(0);
8662 }
8663 
8664 /* ----------------------------------------------------------------*/
8665 /*@C
8666    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
8667 
8668    Neighbor-wise Collective on Mat and Vecs
8669 
8670    Input Parameters:
8671 +  mat - the factored matrix
8672 -  b - the right-hand-side vectors
8673 
8674    Output Parameter:
8675 .  x - the result vectors
8676 
8677    Notes:
8678    The vectors b and x cannot be the same.  I.e., one cannot
8679    call MatSolves(A,x,x).
8680 
8681    Notes:
8682    Most users should employ the simplified KSP interface for linear solvers
8683    instead of working directly with matrix algebra routines such as this.
8684    See, e.g., KSPCreate().
8685 
8686    Level: developer
8687 
8688    Concepts: matrices^triangular solves
8689 
8690 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
8691 @*/
8692 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
8693 {
8694   PetscErrorCode ierr;
8695 
8696   PetscFunctionBegin;
8697   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8698   PetscValidType(mat,1);
8699   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
8700   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8701   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
8702 
8703   if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8704   MatCheckPreallocated(mat,1);
8705   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8706   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
8707   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8708   PetscFunctionReturn(0);
8709 }
8710 
8711 /*@
8712    MatIsSymmetric - Test whether a matrix is symmetric
8713 
8714    Collective on Mat
8715 
8716    Input Parameter:
8717 +  A - the matrix to test
8718 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
8719 
8720    Output Parameters:
8721 .  flg - the result
8722 
8723    Notes:
8724     For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
8725 
8726    Level: intermediate
8727 
8728    Concepts: matrix^symmetry
8729 
8730 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
8731 @*/
8732 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
8733 {
8734   PetscErrorCode ierr;
8735 
8736   PetscFunctionBegin;
8737   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8738   PetscValidPointer(flg,2);
8739 
8740   if (!A->symmetric_set) {
8741     if (!A->ops->issymmetric) {
8742       MatType mattype;
8743       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8744       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8745     }
8746     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8747     if (!tol) {
8748       A->symmetric_set = PETSC_TRUE;
8749       A->symmetric     = *flg;
8750       if (A->symmetric) {
8751         A->structurally_symmetric_set = PETSC_TRUE;
8752         A->structurally_symmetric     = PETSC_TRUE;
8753       }
8754     }
8755   } else if (A->symmetric) {
8756     *flg = PETSC_TRUE;
8757   } else if (!tol) {
8758     *flg = PETSC_FALSE;
8759   } else {
8760     if (!A->ops->issymmetric) {
8761       MatType mattype;
8762       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8763       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8764     }
8765     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8766   }
8767   PetscFunctionReturn(0);
8768 }
8769 
8770 /*@
8771    MatIsHermitian - Test whether a matrix is Hermitian
8772 
8773    Collective on Mat
8774 
8775    Input Parameter:
8776 +  A - the matrix to test
8777 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
8778 
8779    Output Parameters:
8780 .  flg - the result
8781 
8782    Level: intermediate
8783 
8784    Concepts: matrix^symmetry
8785 
8786 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
8787           MatIsSymmetricKnown(), MatIsSymmetric()
8788 @*/
8789 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
8790 {
8791   PetscErrorCode ierr;
8792 
8793   PetscFunctionBegin;
8794   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8795   PetscValidPointer(flg,2);
8796 
8797   if (!A->hermitian_set) {
8798     if (!A->ops->ishermitian) {
8799       MatType mattype;
8800       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8801       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8802     }
8803     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8804     if (!tol) {
8805       A->hermitian_set = PETSC_TRUE;
8806       A->hermitian     = *flg;
8807       if (A->hermitian) {
8808         A->structurally_symmetric_set = PETSC_TRUE;
8809         A->structurally_symmetric     = PETSC_TRUE;
8810       }
8811     }
8812   } else if (A->hermitian) {
8813     *flg = PETSC_TRUE;
8814   } else if (!tol) {
8815     *flg = PETSC_FALSE;
8816   } else {
8817     if (!A->ops->ishermitian) {
8818       MatType mattype;
8819       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8820       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8821     }
8822     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8823   }
8824   PetscFunctionReturn(0);
8825 }
8826 
8827 /*@
8828    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
8829 
8830    Not Collective
8831 
8832    Input Parameter:
8833 .  A - the matrix to check
8834 
8835    Output Parameters:
8836 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
8837 -  flg - the result
8838 
8839    Level: advanced
8840 
8841    Concepts: matrix^symmetry
8842 
8843    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
8844          if you want it explicitly checked
8845 
8846 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8847 @*/
8848 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8849 {
8850   PetscFunctionBegin;
8851   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8852   PetscValidPointer(set,2);
8853   PetscValidPointer(flg,3);
8854   if (A->symmetric_set) {
8855     *set = PETSC_TRUE;
8856     *flg = A->symmetric;
8857   } else {
8858     *set = PETSC_FALSE;
8859   }
8860   PetscFunctionReturn(0);
8861 }
8862 
8863 /*@
8864    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
8865 
8866    Not Collective
8867 
8868    Input Parameter:
8869 .  A - the matrix to check
8870 
8871    Output Parameters:
8872 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8873 -  flg - the result
8874 
8875    Level: advanced
8876 
8877    Concepts: matrix^symmetry
8878 
8879    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8880          if you want it explicitly checked
8881 
8882 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8883 @*/
8884 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8885 {
8886   PetscFunctionBegin;
8887   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8888   PetscValidPointer(set,2);
8889   PetscValidPointer(flg,3);
8890   if (A->hermitian_set) {
8891     *set = PETSC_TRUE;
8892     *flg = A->hermitian;
8893   } else {
8894     *set = PETSC_FALSE;
8895   }
8896   PetscFunctionReturn(0);
8897 }
8898 
8899 /*@
8900    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
8901 
8902    Collective on Mat
8903 
8904    Input Parameter:
8905 .  A - the matrix to test
8906 
8907    Output Parameters:
8908 .  flg - the result
8909 
8910    Level: intermediate
8911 
8912    Concepts: matrix^symmetry
8913 
8914 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8915 @*/
8916 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
8917 {
8918   PetscErrorCode ierr;
8919 
8920   PetscFunctionBegin;
8921   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8922   PetscValidPointer(flg,2);
8923   if (!A->structurally_symmetric_set) {
8924     if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8925     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
8926 
8927     A->structurally_symmetric_set = PETSC_TRUE;
8928   }
8929   *flg = A->structurally_symmetric;
8930   PetscFunctionReturn(0);
8931 }
8932 
8933 /*@
8934    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8935        to be communicated to other processors during the MatAssemblyBegin/End() process
8936 
8937     Not collective
8938 
8939    Input Parameter:
8940 .   vec - the vector
8941 
8942    Output Parameters:
8943 +   nstash   - the size of the stash
8944 .   reallocs - the number of additional mallocs incurred.
8945 .   bnstash   - the size of the block stash
8946 -   breallocs - the number of additional mallocs incurred.in the block stash
8947 
8948    Level: advanced
8949 
8950 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
8951 
8952 @*/
8953 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8954 {
8955   PetscErrorCode ierr;
8956 
8957   PetscFunctionBegin;
8958   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
8959   ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
8960   PetscFunctionReturn(0);
8961 }
8962 
8963 /*@C
8964    MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same
8965      parallel layout
8966 
8967    Collective on Mat
8968 
8969    Input Parameter:
8970 .  mat - the matrix
8971 
8972    Output Parameter:
8973 +   right - (optional) vector that the matrix can be multiplied against
8974 -   left - (optional) vector that the matrix vector product can be stored in
8975 
8976    Notes:
8977     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().
8978 
8979   Notes:
8980     These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed
8981 
8982   Level: advanced
8983 
8984 .seealso: MatCreate(), VecDestroy()
8985 @*/
8986 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left)
8987 {
8988   PetscErrorCode ierr;
8989 
8990   PetscFunctionBegin;
8991   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8992   PetscValidType(mat,1);
8993   if (mat->ops->getvecs) {
8994     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
8995   } else {
8996     PetscInt rbs,cbs;
8997     ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr);
8998     if (right) {
8999       if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup");
9000       ierr = VecCreate(PetscObjectComm((PetscObject)mat),right);CHKERRQ(ierr);
9001       ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
9002       ierr = VecSetBlockSize(*right,cbs);CHKERRQ(ierr);
9003       ierr = VecSetType(*right,mat->defaultvectype);CHKERRQ(ierr);
9004       ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr);
9005     }
9006     if (left) {
9007       if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup");
9008       ierr = VecCreate(PetscObjectComm((PetscObject)mat),left);CHKERRQ(ierr);
9009       ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
9010       ierr = VecSetBlockSize(*left,rbs);CHKERRQ(ierr);
9011       ierr = VecSetType(*left,mat->defaultvectype);CHKERRQ(ierr);
9012       ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr);
9013     }
9014   }
9015   PetscFunctionReturn(0);
9016 }
9017 
9018 /*@C
9019    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
9020      with default values.
9021 
9022    Not Collective
9023 
9024    Input Parameters:
9025 .    info - the MatFactorInfo data structure
9026 
9027 
9028    Notes:
9029     The solvers are generally used through the KSP and PC objects, for example
9030           PCLU, PCILU, PCCHOLESKY, PCICC
9031 
9032    Level: developer
9033 
9034 .seealso: MatFactorInfo
9035 
9036     Developer Note: fortran interface is not autogenerated as the f90
9037     interface defintion cannot be generated correctly [due to MatFactorInfo]
9038 
9039 @*/
9040 
9041 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
9042 {
9043   PetscErrorCode ierr;
9044 
9045   PetscFunctionBegin;
9046   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
9047   PetscFunctionReturn(0);
9048 }
9049 
9050 /*@
9051    MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed
9052 
9053    Collective on Mat
9054 
9055    Input Parameters:
9056 +  mat - the factored matrix
9057 -  is - the index set defining the Schur indices (0-based)
9058 
9059    Notes:
9060     Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system.
9061 
9062    You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call.
9063 
9064    Level: developer
9065 
9066    Concepts:
9067 
9068 .seealso: MatGetFactor(), MatFactorGetSchurComplement(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSolveSchurComplement(),
9069           MatFactorSolveSchurComplementTranspose(), MatFactorSolveSchurComplement()
9070 
9071 @*/
9072 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is)
9073 {
9074   PetscErrorCode ierr,(*f)(Mat,IS);
9075 
9076   PetscFunctionBegin;
9077   PetscValidType(mat,1);
9078   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9079   PetscValidType(is,2);
9080   PetscValidHeaderSpecific(is,IS_CLASSID,2);
9081   PetscCheckSameComm(mat,1,is,2);
9082   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
9083   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);CHKERRQ(ierr);
9084   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");
9085   if (mat->schur) {
9086     ierr = MatDestroy(&mat->schur);CHKERRQ(ierr);
9087   }
9088   ierr = (*f)(mat,is);CHKERRQ(ierr);
9089   if (!mat->schur) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created");
9090   ierr = MatFactorSetUpInPlaceSchur_Private(mat);CHKERRQ(ierr);
9091   PetscFunctionReturn(0);
9092 }
9093 
9094 /*@
9095   MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step
9096 
9097    Logically Collective on Mat
9098 
9099    Input Parameters:
9100 +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
9101 .  S - location where to return the Schur complement, can be NULL
9102 -  status - the status of the Schur complement matrix, can be NULL
9103 
9104    Notes:
9105    You must call MatFactorSetSchurIS() before calling this routine.
9106 
9107    The routine provides a copy of the Schur matrix stored within the solver data structures.
9108    The caller must destroy the object when it is no longer needed.
9109    If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse.
9110 
9111    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)
9112 
9113    Developer Notes:
9114     The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc
9115    matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix.
9116 
9117    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
9118 
9119    Level: advanced
9120 
9121    References:
9122 
9123 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorSchurStatus
9124 @*/
9125 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
9126 {
9127   PetscErrorCode ierr;
9128 
9129   PetscFunctionBegin;
9130   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9131   if (S) PetscValidPointer(S,2);
9132   if (status) PetscValidPointer(status,3);
9133   if (S) {
9134     PetscErrorCode (*f)(Mat,Mat*);
9135 
9136     ierr = PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f);CHKERRQ(ierr);
9137     if (f) {
9138       ierr = (*f)(F,S);CHKERRQ(ierr);
9139     } else {
9140       ierr = MatDuplicate(F->schur,MAT_COPY_VALUES,S);CHKERRQ(ierr);
9141     }
9142   }
9143   if (status) *status = F->schur_status;
9144   PetscFunctionReturn(0);
9145 }
9146 
9147 /*@
9148   MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix
9149 
9150    Logically Collective on Mat
9151 
9152    Input Parameters:
9153 +  F - the factored matrix obtained by calling MatGetFactor()
9154 .  *S - location where to return the Schur complement, can be NULL
9155 -  status - the status of the Schur complement matrix, can be NULL
9156 
9157    Notes:
9158    You must call MatFactorSetSchurIS() before calling this routine.
9159 
9160    Schur complement mode is currently implemented for sequential matrices.
9161    The routine returns a the Schur Complement stored within the data strutures of the solver.
9162    If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement.
9163    The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed.
9164 
9165    Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix
9166 
9167    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
9168 
9169    Level: advanced
9170 
9171    References:
9172 
9173 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
9174 @*/
9175 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
9176 {
9177   PetscFunctionBegin;
9178   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9179   if (S) PetscValidPointer(S,2);
9180   if (status) PetscValidPointer(status,3);
9181   if (S) *S = F->schur;
9182   if (status) *status = F->schur_status;
9183   PetscFunctionReturn(0);
9184 }
9185 
9186 /*@
9187   MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement
9188 
9189    Logically Collective on Mat
9190 
9191    Input Parameters:
9192 +  F - the factored matrix obtained by calling MatGetFactor()
9193 .  *S - location where the Schur complement is stored
9194 -  status - the status of the Schur complement matrix (see MatFactorSchurStatus)
9195 
9196    Notes:
9197 
9198    Level: advanced
9199 
9200    References:
9201 
9202 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
9203 @*/
9204 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status)
9205 {
9206   PetscErrorCode ierr;
9207 
9208   PetscFunctionBegin;
9209   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9210   if (S) {
9211     PetscValidHeaderSpecific(*S,MAT_CLASSID,2);
9212     *S = NULL;
9213   }
9214   F->schur_status = status;
9215   ierr = MatFactorUpdateSchurStatus_Private(F);CHKERRQ(ierr);
9216   PetscFunctionReturn(0);
9217 }
9218 
9219 /*@
9220   MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step
9221 
9222    Logically Collective on Mat
9223 
9224    Input Parameters:
9225 +  F - the factored matrix obtained by calling MatGetFactor()
9226 .  rhs - location where the right hand side of the Schur complement system is stored
9227 -  sol - location where the solution of the Schur complement system has to be returned
9228 
9229    Notes:
9230    The sizes of the vectors should match the size of the Schur complement
9231 
9232    Must be called after MatFactorSetSchurIS()
9233 
9234    Level: advanced
9235 
9236    References:
9237 
9238 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplement()
9239 @*/
9240 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol)
9241 {
9242   PetscErrorCode ierr;
9243 
9244   PetscFunctionBegin;
9245   PetscValidType(F,1);
9246   PetscValidType(rhs,2);
9247   PetscValidType(sol,3);
9248   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9249   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
9250   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
9251   PetscCheckSameComm(F,1,rhs,2);
9252   PetscCheckSameComm(F,1,sol,3);
9253   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9254   switch (F->schur_status) {
9255   case MAT_FACTOR_SCHUR_FACTORED:
9256     ierr = MatSolveTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
9257     break;
9258   case MAT_FACTOR_SCHUR_INVERTED:
9259     ierr = MatMultTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
9260     break;
9261   default:
9262     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9263     break;
9264   }
9265   PetscFunctionReturn(0);
9266 }
9267 
9268 /*@
9269   MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step
9270 
9271    Logically Collective on Mat
9272 
9273    Input Parameters:
9274 +  F - the factored matrix obtained by calling MatGetFactor()
9275 .  rhs - location where the right hand side of the Schur complement system is stored
9276 -  sol - location where the solution of the Schur complement system has to be returned
9277 
9278    Notes:
9279    The sizes of the vectors should match the size of the Schur complement
9280 
9281    Must be called after MatFactorSetSchurIS()
9282 
9283    Level: advanced
9284 
9285    References:
9286 
9287 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplementTranspose()
9288 @*/
9289 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol)
9290 {
9291   PetscErrorCode ierr;
9292 
9293   PetscFunctionBegin;
9294   PetscValidType(F,1);
9295   PetscValidType(rhs,2);
9296   PetscValidType(sol,3);
9297   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9298   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
9299   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
9300   PetscCheckSameComm(F,1,rhs,2);
9301   PetscCheckSameComm(F,1,sol,3);
9302   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9303   switch (F->schur_status) {
9304   case MAT_FACTOR_SCHUR_FACTORED:
9305     ierr = MatSolve(F->schur,rhs,sol);CHKERRQ(ierr);
9306     break;
9307   case MAT_FACTOR_SCHUR_INVERTED:
9308     ierr = MatMult(F->schur,rhs,sol);CHKERRQ(ierr);
9309     break;
9310   default:
9311     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9312     break;
9313   }
9314   PetscFunctionReturn(0);
9315 }
9316 
9317 /*@
9318   MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step
9319 
9320    Logically Collective on Mat
9321 
9322    Input Parameters:
9323 +  F - the factored matrix obtained by calling MatGetFactor()
9324 
9325    Notes:
9326     Must be called after MatFactorSetSchurIS().
9327 
9328    Call MatFactorGetSchurComplement() or  MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it.
9329 
9330    Level: advanced
9331 
9332    References:
9333 
9334 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorCreateSchurComplement()
9335 @*/
9336 PetscErrorCode MatFactorInvertSchurComplement(Mat F)
9337 {
9338   PetscErrorCode ierr;
9339 
9340   PetscFunctionBegin;
9341   PetscValidType(F,1);
9342   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9343   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0);
9344   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9345   ierr = MatFactorInvertSchurComplement_Private(F);CHKERRQ(ierr);
9346   F->schur_status = MAT_FACTOR_SCHUR_INVERTED;
9347   PetscFunctionReturn(0);
9348 }
9349 
9350 /*@
9351   MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step
9352 
9353    Logically Collective on Mat
9354 
9355    Input Parameters:
9356 +  F - the factored matrix obtained by calling MatGetFactor()
9357 
9358    Notes:
9359     Must be called after MatFactorSetSchurIS().
9360 
9361    Level: advanced
9362 
9363    References:
9364 
9365 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorInvertSchurComplement()
9366 @*/
9367 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F)
9368 {
9369   PetscErrorCode ierr;
9370 
9371   PetscFunctionBegin;
9372   PetscValidType(F,1);
9373   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9374   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0);
9375   ierr = MatFactorFactorizeSchurComplement_Private(F);CHKERRQ(ierr);
9376   F->schur_status = MAT_FACTOR_SCHUR_FACTORED;
9377   PetscFunctionReturn(0);
9378 }
9379 
9380 /*@
9381    MatPtAP - Creates the matrix product C = P^T * A * P
9382 
9383    Neighbor-wise Collective on Mat
9384 
9385    Input Parameters:
9386 +  A - the matrix
9387 .  P - the projection matrix
9388 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9389 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate
9390           if the result is a dense matrix this is irrelevent
9391 
9392    Output Parameters:
9393 .  C - the product matrix
9394 
9395    Notes:
9396    C will be created and must be destroyed by the user with MatDestroy().
9397 
9398    This routine is currently only implemented for pairs of sequential dense matrices, AIJ matrices and classes
9399    which inherit from AIJ.
9400 
9401    Level: intermediate
9402 
9403 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
9404 @*/
9405 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
9406 {
9407   PetscErrorCode ierr;
9408   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9409   PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
9410   PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9411   PetscBool      sametype;
9412 
9413   PetscFunctionBegin;
9414   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9415   PetscValidType(A,1);
9416   MatCheckPreallocated(A,1);
9417   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9418   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9419   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9420   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9421   PetscValidType(P,2);
9422   MatCheckPreallocated(P,2);
9423   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9424   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9425 
9426   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);
9427   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);
9428   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9429   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9430 
9431   if (scall == MAT_REUSE_MATRIX) {
9432     PetscValidPointer(*C,5);
9433     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9434 
9435     if (!(*C)->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You cannot use MAT_REUSE_MATRIX");
9436     ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9437     ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9438     ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr);
9439     ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9440     ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9441     PetscFunctionReturn(0);
9442   }
9443 
9444   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9445   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9446 
9447   fA = A->ops->ptap;
9448   fP = P->ops->ptap;
9449   ierr = PetscStrcmp(((PetscObject)A)->type_name,((PetscObject)P)->type_name,&sametype);CHKERRQ(ierr);
9450   if (fP == fA && sametype) {
9451     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name);
9452     ptap = fA;
9453   } else {
9454     /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
9455     char ptapname[256];
9456     ierr = PetscStrncpy(ptapname,"MatPtAP_",sizeof(ptapname));CHKERRQ(ierr);
9457     ierr = PetscStrlcat(ptapname,((PetscObject)A)->type_name,sizeof(ptapname));CHKERRQ(ierr);
9458     ierr = PetscStrlcat(ptapname,"_",sizeof(ptapname));CHKERRQ(ierr);
9459     ierr = PetscStrlcat(ptapname,((PetscObject)P)->type_name,sizeof(ptapname));CHKERRQ(ierr);
9460     ierr = PetscStrlcat(ptapname,"_C",sizeof(ptapname));CHKERRQ(ierr); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
9461     ierr = PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);CHKERRQ(ierr);
9462     if (!ptap) SETERRQ3(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatPtAP requires A, %s, to be compatible with P, %s (Misses composed function %s)",((PetscObject)A)->type_name,((PetscObject)P)->type_name,ptapname);
9463   }
9464 
9465   ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9466   ierr = (*ptap)(A,P,scall,fill,C);CHKERRQ(ierr);
9467   ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9468   if (A->symmetric_set && A->symmetric) {
9469     ierr = MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
9470   }
9471   PetscFunctionReturn(0);
9472 }
9473 
9474 /*@
9475    MatPtAPNumeric - Computes the matrix product C = P^T * A * P
9476 
9477    Neighbor-wise Collective on Mat
9478 
9479    Input Parameters:
9480 +  A - the matrix
9481 -  P - the projection matrix
9482 
9483    Output Parameters:
9484 .  C - the product matrix
9485 
9486    Notes:
9487    C must have been created by calling MatPtAPSymbolic and must be destroyed by
9488    the user using MatDeatroy().
9489 
9490    This routine is currently only implemented for pairs of AIJ matrices and classes
9491    which inherit from AIJ.  C will be of type MATAIJ.
9492 
9493    Level: intermediate
9494 
9495 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
9496 @*/
9497 PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C)
9498 {
9499   PetscErrorCode ierr;
9500 
9501   PetscFunctionBegin;
9502   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9503   PetscValidType(A,1);
9504   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9505   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9506   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9507   PetscValidType(P,2);
9508   MatCheckPreallocated(P,2);
9509   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9510   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9511   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9512   PetscValidType(C,3);
9513   MatCheckPreallocated(C,3);
9514   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9515   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);
9516   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);
9517   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);
9518   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);
9519   MatCheckPreallocated(A,1);
9520 
9521   if (!C->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You should call MatPtAPSymbolic first");
9522   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9523   ierr = (*C->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr);
9524   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9525   PetscFunctionReturn(0);
9526 }
9527 
9528 /*@
9529    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P
9530 
9531    Neighbor-wise Collective on Mat
9532 
9533    Input Parameters:
9534 +  A - the matrix
9535 -  P - the projection matrix
9536 
9537    Output Parameters:
9538 .  C - the (i,j) structure of the product matrix
9539 
9540    Notes:
9541    C will be created and must be destroyed by the user with MatDestroy().
9542 
9543    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9544    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9545    this (i,j) structure by calling MatPtAPNumeric().
9546 
9547    Level: intermediate
9548 
9549 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
9550 @*/
9551 PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
9552 {
9553   PetscErrorCode ierr;
9554 
9555   PetscFunctionBegin;
9556   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9557   PetscValidType(A,1);
9558   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9559   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9560   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9561   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9562   PetscValidType(P,2);
9563   MatCheckPreallocated(P,2);
9564   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9565   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9566   PetscValidPointer(C,3);
9567 
9568   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);
9569   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);
9570   MatCheckPreallocated(A,1);
9571 
9572   if (!A->ops->ptapsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatType %s",((PetscObject)A)->type_name);
9573   ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
9574   ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr);
9575   ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
9576 
9577   /* ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); NO! this is not always true -ma */
9578   PetscFunctionReturn(0);
9579 }
9580 
9581 /*@
9582    MatRARt - Creates the matrix product C = R * A * R^T
9583 
9584    Neighbor-wise Collective on Mat
9585 
9586    Input Parameters:
9587 +  A - the matrix
9588 .  R - the projection matrix
9589 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9590 -  fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate
9591           if the result is a dense matrix this is irrelevent
9592 
9593    Output Parameters:
9594 .  C - the product matrix
9595 
9596    Notes:
9597    C will be created and must be destroyed by the user with MatDestroy().
9598 
9599    This routine is currently only implemented for pairs of AIJ matrices and classes
9600    which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes,
9601    parallel MatRARt is implemented via explicit transpose of R, which could be very expensive.
9602    We recommend using MatPtAP().
9603 
9604    Level: intermediate
9605 
9606 .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
9607 @*/
9608 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
9609 {
9610   PetscErrorCode ierr;
9611 
9612   PetscFunctionBegin;
9613   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9614   PetscValidType(A,1);
9615   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9616   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9617   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9618   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9619   PetscValidType(R,2);
9620   MatCheckPreallocated(R,2);
9621   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9622   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9623   PetscValidPointer(C,3);
9624   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);
9625 
9626   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9627   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9628   MatCheckPreallocated(A,1);
9629 
9630   if (!A->ops->rart) {
9631     Mat Rt;
9632     ierr = MatTranspose(R,MAT_INITIAL_MATRIX,&Rt);CHKERRQ(ierr);
9633     ierr = MatMatMatMult(R,A,Rt,scall,fill,C);CHKERRQ(ierr);
9634     ierr = MatDestroy(&Rt);CHKERRQ(ierr);
9635     PetscFunctionReturn(0);
9636   }
9637   ierr = PetscLogEventBegin(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
9638   ierr = (*A->ops->rart)(A,R,scall,fill,C);CHKERRQ(ierr);
9639   ierr = PetscLogEventEnd(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
9640   PetscFunctionReturn(0);
9641 }
9642 
9643 /*@
9644    MatRARtNumeric - Computes the matrix product C = R * A * R^T
9645 
9646    Neighbor-wise Collective on Mat
9647 
9648    Input Parameters:
9649 +  A - the matrix
9650 -  R - the projection matrix
9651 
9652    Output Parameters:
9653 .  C - the product matrix
9654 
9655    Notes:
9656    C must have been created by calling MatRARtSymbolic and must be destroyed by
9657    the user using MatDestroy().
9658 
9659    This routine is currently only implemented for pairs of AIJ matrices and classes
9660    which inherit from AIJ.  C will be of type MATAIJ.
9661 
9662    Level: intermediate
9663 
9664 .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
9665 @*/
9666 PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C)
9667 {
9668   PetscErrorCode ierr;
9669 
9670   PetscFunctionBegin;
9671   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9672   PetscValidType(A,1);
9673   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9674   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9675   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9676   PetscValidType(R,2);
9677   MatCheckPreallocated(R,2);
9678   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9679   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9680   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9681   PetscValidType(C,3);
9682   MatCheckPreallocated(C,3);
9683   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9684   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);
9685   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);
9686   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);
9687   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);
9688   MatCheckPreallocated(A,1);
9689 
9690   ierr = PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
9691   ierr = (*A->ops->rartnumeric)(A,R,C);CHKERRQ(ierr);
9692   ierr = PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
9693   PetscFunctionReturn(0);
9694 }
9695 
9696 /*@
9697    MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T
9698 
9699    Neighbor-wise Collective on Mat
9700 
9701    Input Parameters:
9702 +  A - the matrix
9703 -  R - the projection matrix
9704 
9705    Output Parameters:
9706 .  C - the (i,j) structure of the product matrix
9707 
9708    Notes:
9709    C will be created and must be destroyed by the user with MatDestroy().
9710 
9711    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9712    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9713    this (i,j) structure by calling MatRARtNumeric().
9714 
9715    Level: intermediate
9716 
9717 .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
9718 @*/
9719 PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
9720 {
9721   PetscErrorCode ierr;
9722 
9723   PetscFunctionBegin;
9724   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9725   PetscValidType(A,1);
9726   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9727   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9728   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9729   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9730   PetscValidType(R,2);
9731   MatCheckPreallocated(R,2);
9732   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9733   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9734   PetscValidPointer(C,3);
9735 
9736   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);
9737   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);
9738   MatCheckPreallocated(A,1);
9739   ierr = PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
9740   ierr = (*A->ops->rartsymbolic)(A,R,fill,C);CHKERRQ(ierr);
9741   ierr = PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
9742 
9743   ierr = MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));CHKERRQ(ierr);
9744   PetscFunctionReturn(0);
9745 }
9746 
9747 /*@
9748    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
9749 
9750    Neighbor-wise Collective on Mat
9751 
9752    Input Parameters:
9753 +  A - the left matrix
9754 .  B - the right matrix
9755 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9756 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
9757           if the result is a dense matrix this is irrelevent
9758 
9759    Output Parameters:
9760 .  C - the product matrix
9761 
9762    Notes:
9763    Unless scall is MAT_REUSE_MATRIX C will be created.
9764 
9765    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
9766    call to this function with either MAT_INITIAL_MATRIX or MatMatMultSymbolic()
9767 
9768    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9769    actually needed.
9770 
9771    If you have many matrices with the same non-zero structure to multiply, you
9772    should either
9773 $   1) use MAT_REUSE_MATRIX in all calls but the first or
9774 $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
9775    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
9776    with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse.
9777 
9778    Level: intermediate
9779 
9780 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(),  MatMatTransposeMult(), MatPtAP()
9781 @*/
9782 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9783 {
9784   PetscErrorCode ierr;
9785   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9786   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9787   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9788 
9789   PetscFunctionBegin;
9790   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9791   PetscValidType(A,1);
9792   MatCheckPreallocated(A,1);
9793   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9794   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9795   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9796   PetscValidType(B,2);
9797   MatCheckPreallocated(B,2);
9798   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9799   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9800   PetscValidPointer(C,3);
9801   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9802   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);
9803   if (scall == MAT_REUSE_MATRIX) {
9804     PetscValidPointer(*C,5);
9805     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9806     ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9807     ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9808     ierr = (*(*C)->ops->matmultnumeric)(A,B,*C);CHKERRQ(ierr);
9809     ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9810     ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9811     PetscFunctionReturn(0);
9812   }
9813   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9814   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9815 
9816   fA = A->ops->matmult;
9817   fB = B->ops->matmult;
9818   if (fB == fA) {
9819     if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
9820     mult = fB;
9821   } else {
9822     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9823     char multname[256];
9824     ierr = PetscStrncpy(multname,"MatMatMult_",sizeof(multname));CHKERRQ(ierr);
9825     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
9826     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
9827     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
9828     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9829     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
9830     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);
9831   }
9832   ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9833   ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr);
9834   ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9835   PetscFunctionReturn(0);
9836 }
9837 
9838 /*@
9839    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
9840    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().
9841 
9842    Neighbor-wise Collective on Mat
9843 
9844    Input Parameters:
9845 +  A - the left matrix
9846 .  B - the right matrix
9847 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
9848       if C is a dense matrix this is irrelevent
9849 
9850    Output Parameters:
9851 .  C - the product matrix
9852 
9853    Notes:
9854    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9855    actually needed.
9856 
9857    This routine is currently implemented for
9858     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
9859     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9860     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9861 
9862    Level: intermediate
9863 
9864    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
9865      We should incorporate them into PETSc.
9866 
9867 .seealso: MatMatMult(), MatMatMultNumeric()
9868 @*/
9869 PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
9870 {
9871   PetscErrorCode ierr;
9872   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*);
9873   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*);
9874   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL;
9875 
9876   PetscFunctionBegin;
9877   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9878   PetscValidType(A,1);
9879   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9880   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9881 
9882   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9883   PetscValidType(B,2);
9884   MatCheckPreallocated(B,2);
9885   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9886   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9887   PetscValidPointer(C,3);
9888 
9889   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);
9890   if (fill == PETSC_DEFAULT) fill = 2.0;
9891   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9892   MatCheckPreallocated(A,1);
9893 
9894   Asymbolic = A->ops->matmultsymbolic;
9895   Bsymbolic = B->ops->matmultsymbolic;
9896   if (Asymbolic == Bsymbolic) {
9897     if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
9898     symbolic = Bsymbolic;
9899   } else { /* dispatch based on the type of A and B */
9900     char symbolicname[256];
9901     ierr = PetscStrncpy(symbolicname,"MatMatMultSymbolic_",sizeof(symbolicname));CHKERRQ(ierr);
9902     ierr = PetscStrlcat(symbolicname,((PetscObject)A)->type_name,sizeof(symbolicname));CHKERRQ(ierr);
9903     ierr = PetscStrlcat(symbolicname,"_",sizeof(symbolicname));CHKERRQ(ierr);
9904     ierr = PetscStrlcat(symbolicname,((PetscObject)B)->type_name,sizeof(symbolicname));CHKERRQ(ierr);
9905     ierr = PetscStrlcat(symbolicname,"_C",sizeof(symbolicname));CHKERRQ(ierr);
9906     ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);CHKERRQ(ierr);
9907     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);
9908   }
9909   ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9910   ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr);
9911   ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9912   PetscFunctionReturn(0);
9913 }
9914 
9915 /*@
9916    MatMatMultNumeric - Performs the numeric matrix-matrix product.
9917    Call this routine after first calling MatMatMultSymbolic().
9918 
9919    Neighbor-wise Collective on Mat
9920 
9921    Input Parameters:
9922 +  A - the left matrix
9923 -  B - the right matrix
9924 
9925    Output Parameters:
9926 .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
9927 
9928    Notes:
9929    C must have been created with MatMatMultSymbolic().
9930 
9931    This routine is currently implemented for
9932     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
9933     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9934     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9935 
9936    Level: intermediate
9937 
9938 .seealso: MatMatMult(), MatMatMultSymbolic()
9939 @*/
9940 PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C)
9941 {
9942   PetscErrorCode ierr;
9943 
9944   PetscFunctionBegin;
9945   ierr = MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);CHKERRQ(ierr);
9946   PetscFunctionReturn(0);
9947 }
9948 
9949 /*@
9950    MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.
9951 
9952    Neighbor-wise Collective on Mat
9953 
9954    Input Parameters:
9955 +  A - the left matrix
9956 .  B - the right matrix
9957 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9958 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9959 
9960    Output Parameters:
9961 .  C - the product matrix
9962 
9963    Notes:
9964    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9965 
9966    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9967 
9968   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9969    actually needed.
9970 
9971    This routine is currently only implemented for pairs of SeqAIJ matrices, for the SeqDense class,
9972    and for pairs of MPIDense matrices.
9973 
9974    Options Database Keys:
9975 +  -matmattransmult_mpidense_mpidense_via {allgatherv,cyclic} - Choose between algorthims for MPIDense matrices: the
9976                                                                 first redundantly copies the transposed B matrix on each process and requiers O(log P) communication complexity;
9977                                                                 the second never stores more than one portion of the B matrix at a time by requires O(P) communication complexity.
9978 
9979    Level: intermediate
9980 
9981 .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
9982 @*/
9983 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9984 {
9985   PetscErrorCode ierr;
9986   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9987   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9988 
9989   PetscFunctionBegin;
9990   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9991   PetscValidType(A,1);
9992   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9993   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9994   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9995   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9996   PetscValidType(B,2);
9997   MatCheckPreallocated(B,2);
9998   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9999   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10000   PetscValidPointer(C,3);
10001   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);
10002   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
10003   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
10004   MatCheckPreallocated(A,1);
10005 
10006   fA = A->ops->mattransposemult;
10007   if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
10008   fB = B->ops->mattransposemult;
10009   if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
10010   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);
10011 
10012   ierr = PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
10013   if (scall == MAT_INITIAL_MATRIX) {
10014     ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
10015     ierr = (*A->ops->mattransposemultsymbolic)(A,B,fill,C);CHKERRQ(ierr);
10016     ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
10017   }
10018   ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
10019   ierr = (*A->ops->mattransposemultnumeric)(A,B,*C);CHKERRQ(ierr);
10020   ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
10021   ierr = PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
10022   PetscFunctionReturn(0);
10023 }
10024 
10025 /*@
10026    MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.
10027 
10028    Neighbor-wise Collective on Mat
10029 
10030    Input Parameters:
10031 +  A - the left matrix
10032 .  B - the right matrix
10033 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10034 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
10035 
10036    Output Parameters:
10037 .  C - the product matrix
10038 
10039    Notes:
10040    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
10041 
10042    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
10043 
10044   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
10045    actually needed.
10046 
10047    This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
10048    which inherit from SeqAIJ.  C will be of same type as the input matrices.
10049 
10050    Level: intermediate
10051 
10052 .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
10053 @*/
10054 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
10055 {
10056   PetscErrorCode ierr;
10057   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
10058   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
10059   PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL;
10060 
10061   PetscFunctionBegin;
10062   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
10063   PetscValidType(A,1);
10064   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10065   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10066   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10067   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
10068   PetscValidType(B,2);
10069   MatCheckPreallocated(B,2);
10070   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10071   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10072   PetscValidPointer(C,3);
10073   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);
10074   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
10075   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
10076   MatCheckPreallocated(A,1);
10077 
10078   fA = A->ops->transposematmult;
10079   fB = B->ops->transposematmult;
10080   if (fB==fA) {
10081     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
10082     transposematmult = fA;
10083   } else {
10084     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
10085     char multname[256];
10086     ierr = PetscStrncpy(multname,"MatTransposeMatMult_",sizeof(multname));CHKERRQ(ierr);
10087     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
10088     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
10089     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
10090     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
10091     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);CHKERRQ(ierr);
10092     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);
10093   }
10094   ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
10095   ierr = (*transposematmult)(A,B,scall,fill,C);CHKERRQ(ierr);
10096   ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
10097   PetscFunctionReturn(0);
10098 }
10099 
10100 /*@
10101    MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.
10102 
10103    Neighbor-wise Collective on Mat
10104 
10105    Input Parameters:
10106 +  A - the left matrix
10107 .  B - the middle matrix
10108 .  C - the right matrix
10109 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10110 -  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
10111           if the result is a dense matrix this is irrelevent
10112 
10113    Output Parameters:
10114 .  D - the product matrix
10115 
10116    Notes:
10117    Unless scall is MAT_REUSE_MATRIX D will be created.
10118 
10119    MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call
10120 
10121    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
10122    actually needed.
10123 
10124    If you have many matrices with the same non-zero structure to multiply, you
10125    should use MAT_REUSE_MATRIX in all calls but the first or
10126 
10127    Level: intermediate
10128 
10129 .seealso: MatMatMult, MatPtAP()
10130 @*/
10131 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
10132 {
10133   PetscErrorCode ierr;
10134   PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
10135   PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
10136   PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
10137   PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
10138 
10139   PetscFunctionBegin;
10140   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
10141   PetscValidType(A,1);
10142   MatCheckPreallocated(A,1);
10143   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10144   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10145   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10146   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
10147   PetscValidType(B,2);
10148   MatCheckPreallocated(B,2);
10149   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10150   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10151   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
10152   PetscValidPointer(C,3);
10153   MatCheckPreallocated(C,3);
10154   if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10155   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10156   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);
10157   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);
10158   if (scall == MAT_REUSE_MATRIX) {
10159     PetscValidPointer(*D,6);
10160     PetscValidHeaderSpecific(*D,MAT_CLASSID,6);
10161     ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10162     ierr = (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
10163     ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10164     PetscFunctionReturn(0);
10165   }
10166   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
10167   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
10168 
10169   fA = A->ops->matmatmult;
10170   fB = B->ops->matmatmult;
10171   fC = C->ops->matmatmult;
10172   if (fA == fB && fA == fC) {
10173     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name);
10174     mult = fA;
10175   } else {
10176     /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */
10177     char multname[256];
10178     ierr = PetscStrncpy(multname,"MatMatMatMult_",sizeof(multname));CHKERRQ(ierr);
10179     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
10180     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
10181     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
10182     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
10183     ierr = PetscStrlcat(multname,((PetscObject)C)->type_name,sizeof(multname));CHKERRQ(ierr);
10184     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr);
10185     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
10186     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);
10187   }
10188   ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10189   ierr = (*mult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
10190   ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10191   PetscFunctionReturn(0);
10192 }
10193 
10194 /*@
10195    MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
10196 
10197    Collective on Mat
10198 
10199    Input Parameters:
10200 +  mat - the matrix
10201 .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
10202 .  subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used)
10203 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10204 
10205    Output Parameter:
10206 .  matredundant - redundant matrix
10207 
10208    Notes:
10209    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
10210    original matrix has not changed from that last call to MatCreateRedundantMatrix().
10211 
10212    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
10213    calling it.
10214 
10215    Level: advanced
10216 
10217    Concepts: subcommunicator
10218    Concepts: duplicate matrix
10219 
10220 .seealso: MatDestroy()
10221 @*/
10222 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant)
10223 {
10224   PetscErrorCode ierr;
10225   MPI_Comm       comm;
10226   PetscMPIInt    size;
10227   PetscInt       mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs;
10228   Mat_Redundant  *redund=NULL;
10229   PetscSubcomm   psubcomm=NULL;
10230   MPI_Comm       subcomm_in=subcomm;
10231   Mat            *matseq;
10232   IS             isrow,iscol;
10233   PetscBool      newsubcomm=PETSC_FALSE;
10234 
10235   PetscFunctionBegin;
10236   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10237   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
10238     PetscValidPointer(*matredundant,5);
10239     PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5);
10240   }
10241 
10242   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
10243   if (size == 1 || nsubcomm == 1) {
10244     if (reuse == MAT_INITIAL_MATRIX) {
10245       ierr = MatDuplicate(mat,MAT_COPY_VALUES,matredundant);CHKERRQ(ierr);
10246     } else {
10247       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");
10248       ierr = MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
10249     }
10250     PetscFunctionReturn(0);
10251   }
10252 
10253   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10254   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10255   MatCheckPreallocated(mat,1);
10256 
10257   ierr = PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
10258   if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */
10259     /* create psubcomm, then get subcomm */
10260     ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
10261     ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
10262     if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size);
10263 
10264     ierr = PetscSubcommCreate(comm,&psubcomm);CHKERRQ(ierr);
10265     ierr = PetscSubcommSetNumber(psubcomm,nsubcomm);CHKERRQ(ierr);
10266     ierr = PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);CHKERRQ(ierr);
10267     ierr = PetscSubcommSetFromOptions(psubcomm);CHKERRQ(ierr);
10268     ierr = PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);CHKERRQ(ierr);
10269     newsubcomm = PETSC_TRUE;
10270     ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr);
10271   }
10272 
10273   /* get isrow, iscol and a local sequential matrix matseq[0] */
10274   if (reuse == MAT_INITIAL_MATRIX) {
10275     mloc_sub = PETSC_DECIDE;
10276     nloc_sub = PETSC_DECIDE;
10277     if (bs < 1) {
10278       ierr = PetscSplitOwnership(subcomm,&mloc_sub,&M);CHKERRQ(ierr);
10279       ierr = PetscSplitOwnership(subcomm,&nloc_sub,&N);CHKERRQ(ierr);
10280     } else {
10281       ierr = PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);CHKERRQ(ierr);
10282       ierr = PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N);CHKERRQ(ierr);
10283     }
10284     ierr = MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);CHKERRQ(ierr);
10285     rstart = rend - mloc_sub;
10286     ierr = ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);CHKERRQ(ierr);
10287     ierr = ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);CHKERRQ(ierr);
10288   } else { /* reuse == MAT_REUSE_MATRIX */
10289     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");
10290     /* retrieve subcomm */
10291     ierr = PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);CHKERRQ(ierr);
10292     redund = (*matredundant)->redundant;
10293     isrow  = redund->isrow;
10294     iscol  = redund->iscol;
10295     matseq = redund->matseq;
10296   }
10297   ierr = MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);CHKERRQ(ierr);
10298 
10299   /* get matredundant over subcomm */
10300   if (reuse == MAT_INITIAL_MATRIX) {
10301     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant);CHKERRQ(ierr);
10302 
10303     /* create a supporting struct and attach it to C for reuse */
10304     ierr = PetscNewLog(*matredundant,&redund);CHKERRQ(ierr);
10305     (*matredundant)->redundant = redund;
10306     redund->isrow              = isrow;
10307     redund->iscol              = iscol;
10308     redund->matseq             = matseq;
10309     if (newsubcomm) {
10310       redund->subcomm          = subcomm;
10311     } else {
10312       redund->subcomm          = MPI_COMM_NULL;
10313     }
10314   } else {
10315     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);CHKERRQ(ierr);
10316   }
10317   ierr = PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
10318   PetscFunctionReturn(0);
10319 }
10320 
10321 /*@C
10322    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
10323    a given 'mat' object. Each submatrix can span multiple procs.
10324 
10325    Collective on Mat
10326 
10327    Input Parameters:
10328 +  mat - the matrix
10329 .  subcomm - the subcommunicator obtained by com_split(comm)
10330 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10331 
10332    Output Parameter:
10333 .  subMat - 'parallel submatrices each spans a given subcomm
10334 
10335   Notes:
10336   The submatrix partition across processors is dictated by 'subComm' a
10337   communicator obtained by com_split(comm). The comm_split
10338   is not restriced to be grouped with consecutive original ranks.
10339 
10340   Due the comm_split() usage, the parallel layout of the submatrices
10341   map directly to the layout of the original matrix [wrt the local
10342   row,col partitioning]. So the original 'DiagonalMat' naturally maps
10343   into the 'DiagonalMat' of the subMat, hence it is used directly from
10344   the subMat. However the offDiagMat looses some columns - and this is
10345   reconstructed with MatSetValues()
10346 
10347   Level: advanced
10348 
10349   Concepts: subcommunicator
10350   Concepts: submatrices
10351 
10352 .seealso: MatCreateSubMatrices()
10353 @*/
10354 PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
10355 {
10356   PetscErrorCode ierr;
10357   PetscMPIInt    commsize,subCommSize;
10358 
10359   PetscFunctionBegin;
10360   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRQ(ierr);
10361   ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr);
10362   if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
10363 
10364   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");
10365   ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10366   ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr);
10367   ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10368   PetscFunctionReturn(0);
10369 }
10370 
10371 /*@
10372    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
10373 
10374    Not Collective
10375 
10376    Input Arguments:
10377    mat - matrix to extract local submatrix from
10378    isrow - local row indices for submatrix
10379    iscol - local column indices for submatrix
10380 
10381    Output Arguments:
10382    submat - the submatrix
10383 
10384    Level: intermediate
10385 
10386    Notes:
10387    The submat should be returned with MatRestoreLocalSubMatrix().
10388 
10389    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
10390    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
10391 
10392    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
10393    MatSetValuesBlockedLocal() will also be implemented.
10394 
10395    The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that
10396    matrices obtained with DMCreateMatrix() generally already have the local to global mapping provided.
10397 
10398 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping()
10399 @*/
10400 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10401 {
10402   PetscErrorCode ierr;
10403 
10404   PetscFunctionBegin;
10405   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10406   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10407   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10408   PetscCheckSameComm(isrow,2,iscol,3);
10409   PetscValidPointer(submat,4);
10410   if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call");
10411 
10412   if (mat->ops->getlocalsubmatrix) {
10413     ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10414   } else {
10415     ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr);
10416   }
10417   PetscFunctionReturn(0);
10418 }
10419 
10420 /*@
10421    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
10422 
10423    Not Collective
10424 
10425    Input Arguments:
10426    mat - matrix to extract local submatrix from
10427    isrow - local row indices for submatrix
10428    iscol - local column indices for submatrix
10429    submat - the submatrix
10430 
10431    Level: intermediate
10432 
10433 .seealso: MatGetLocalSubMatrix()
10434 @*/
10435 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10436 {
10437   PetscErrorCode ierr;
10438 
10439   PetscFunctionBegin;
10440   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10441   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10442   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10443   PetscCheckSameComm(isrow,2,iscol,3);
10444   PetscValidPointer(submat,4);
10445   if (*submat) {
10446     PetscValidHeaderSpecific(*submat,MAT_CLASSID,4);
10447   }
10448 
10449   if (mat->ops->restorelocalsubmatrix) {
10450     ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10451   } else {
10452     ierr = MatDestroy(submat);CHKERRQ(ierr);
10453   }
10454   *submat = NULL;
10455   PetscFunctionReturn(0);
10456 }
10457 
10458 /* --------------------------------------------------------*/
10459 /*@
10460    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix
10461 
10462    Collective on Mat
10463 
10464    Input Parameter:
10465 .  mat - the matrix
10466 
10467    Output Parameter:
10468 .  is - if any rows have zero diagonals this contains the list of them
10469 
10470    Level: developer
10471 
10472    Concepts: matrix-vector product
10473 
10474 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10475 @*/
10476 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is)
10477 {
10478   PetscErrorCode ierr;
10479 
10480   PetscFunctionBegin;
10481   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10482   PetscValidType(mat,1);
10483   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10484   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10485 
10486   if (!mat->ops->findzerodiagonals) {
10487     Vec                diag;
10488     const PetscScalar *a;
10489     PetscInt          *rows;
10490     PetscInt           rStart, rEnd, r, nrow = 0;
10491 
10492     ierr = MatCreateVecs(mat, &diag, NULL);CHKERRQ(ierr);
10493     ierr = MatGetDiagonal(mat, diag);CHKERRQ(ierr);
10494     ierr = MatGetOwnershipRange(mat, &rStart, &rEnd);CHKERRQ(ierr);
10495     ierr = VecGetArrayRead(diag, &a);CHKERRQ(ierr);
10496     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow;
10497     ierr = PetscMalloc1(nrow, &rows);CHKERRQ(ierr);
10498     nrow = 0;
10499     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart;
10500     ierr = VecRestoreArrayRead(diag, &a);CHKERRQ(ierr);
10501     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10502     ierr = ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);CHKERRQ(ierr);
10503   } else {
10504     ierr = (*mat->ops->findzerodiagonals)(mat, is);CHKERRQ(ierr);
10505   }
10506   PetscFunctionReturn(0);
10507 }
10508 
10509 /*@
10510    MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size)
10511 
10512    Collective on Mat
10513 
10514    Input Parameter:
10515 .  mat - the matrix
10516 
10517    Output Parameter:
10518 .  is - contains the list of rows with off block diagonal entries
10519 
10520    Level: developer
10521 
10522    Concepts: matrix-vector product
10523 
10524 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10525 @*/
10526 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is)
10527 {
10528   PetscErrorCode ierr;
10529 
10530   PetscFunctionBegin;
10531   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10532   PetscValidType(mat,1);
10533   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10534   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10535 
10536   if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined");
10537   ierr = (*mat->ops->findoffblockdiagonalentries)(mat,is);CHKERRQ(ierr);
10538   PetscFunctionReturn(0);
10539 }
10540 
10541 /*@C
10542   MatInvertBlockDiagonal - Inverts the block diagonal entries.
10543 
10544   Collective on Mat
10545 
10546   Input Parameters:
10547 . mat - the matrix
10548 
10549   Output Parameters:
10550 . values - the block inverses in column major order (FORTRAN-like)
10551 
10552    Note:
10553    This routine is not available from Fortran.
10554 
10555   Level: advanced
10556 
10557 .seealso: MatInvertBockDiagonalMat
10558 @*/
10559 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
10560 {
10561   PetscErrorCode ierr;
10562 
10563   PetscFunctionBegin;
10564   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10565   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10566   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10567   if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
10568   ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr);
10569   PetscFunctionReturn(0);
10570 }
10571 
10572 /*@C
10573   MatInvertVariableBlockDiagonal - Inverts the block diagonal entries.
10574 
10575   Collective on Mat
10576 
10577   Input Parameters:
10578 + mat - the matrix
10579 . nblocks - the number of blocks
10580 - bsizes - the size of each block
10581 
10582   Output Parameters:
10583 . values - the block inverses in column major order (FORTRAN-like)
10584 
10585    Note:
10586    This routine is not available from Fortran.
10587 
10588   Level: advanced
10589 
10590 .seealso: MatInvertBockDiagonal()
10591 @*/
10592 PetscErrorCode MatInvertVariableBlockDiagonal(Mat mat,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *values)
10593 {
10594   PetscErrorCode ierr;
10595 
10596   PetscFunctionBegin;
10597   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10598   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10599   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10600   if (!mat->ops->invertvariableblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
10601   ierr = (*mat->ops->invertvariableblockdiagonal)(mat,nblocks,bsizes,values);CHKERRQ(ierr);
10602   PetscFunctionReturn(0);
10603 }
10604 
10605 /*@
10606   MatInvertBlockDiagonalMat - set matrix C to be the inverted block diagonal of matrix A
10607 
10608   Collective on Mat
10609 
10610   Input Parameters:
10611 . A - the matrix
10612 
10613   Output Parameters:
10614 . C - matrix with inverted block diagonal of A.  This matrix should be created and may have its type set.
10615 
10616   Notes: the blocksize of the matrix is used to determine the blocks on the diagonal of C
10617 
10618   Level: advanced
10619 
10620 .seealso: MatInvertBockDiagonal()
10621 @*/
10622 PetscErrorCode MatInvertBlockDiagonalMat(Mat A,Mat C)
10623 {
10624   PetscErrorCode     ierr;
10625   const PetscScalar *vals;
10626   PetscInt          *dnnz;
10627   PetscInt           M,N,m,n,rstart,rend,bs,i,j;
10628 
10629   PetscFunctionBegin;
10630   ierr = MatInvertBlockDiagonal(A,&vals);CHKERRQ(ierr);
10631   ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr);
10632   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
10633   ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr);
10634   ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr);
10635   ierr = MatSetBlockSize(C,bs);CHKERRQ(ierr);
10636   ierr = PetscMalloc1(m/bs,&dnnz);CHKERRQ(ierr);
10637   for (j = 0; j < m/bs; j++) dnnz[j] = 1;
10638   ierr = MatXAIJSetPreallocation(C,bs,dnnz,NULL,NULL,NULL);CHKERRQ(ierr);
10639   ierr = PetscFree(dnnz);CHKERRQ(ierr);
10640   ierr = MatGetOwnershipRange(C,&rstart,&rend);CHKERRQ(ierr);
10641   ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr);
10642   for (i = rstart/bs; i < rend/bs; i++) {
10643     ierr = MatSetValuesBlocked(C,1,&i,1,&i,&vals[(i-rstart/bs)*bs*bs],INSERT_VALUES);CHKERRQ(ierr);
10644   }
10645   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10646   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10647   ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr);
10648   PetscFunctionReturn(0);
10649 }
10650 
10651 /*@C
10652     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
10653     via MatTransposeColoringCreate().
10654 
10655     Collective on MatTransposeColoring
10656 
10657     Input Parameter:
10658 .   c - coloring context
10659 
10660     Level: intermediate
10661 
10662 .seealso: MatTransposeColoringCreate()
10663 @*/
10664 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c)
10665 {
10666   PetscErrorCode       ierr;
10667   MatTransposeColoring matcolor=*c;
10668 
10669   PetscFunctionBegin;
10670   if (!matcolor) PetscFunctionReturn(0);
10671   if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; PetscFunctionReturn(0);}
10672 
10673   ierr = PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);CHKERRQ(ierr);
10674   ierr = PetscFree(matcolor->rows);CHKERRQ(ierr);
10675   ierr = PetscFree(matcolor->den2sp);CHKERRQ(ierr);
10676   ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr);
10677   ierr = PetscFree(matcolor->columns);CHKERRQ(ierr);
10678   if (matcolor->brows>0) {
10679     ierr = PetscFree(matcolor->lstart);CHKERRQ(ierr);
10680   }
10681   ierr = PetscHeaderDestroy(c);CHKERRQ(ierr);
10682   PetscFunctionReturn(0);
10683 }
10684 
10685 /*@C
10686     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
10687     a MatTransposeColoring context has been created, computes a dense B^T by Apply
10688     MatTransposeColoring to sparse B.
10689 
10690     Collective on MatTransposeColoring
10691 
10692     Input Parameters:
10693 +   B - sparse matrix B
10694 .   Btdense - symbolic dense matrix B^T
10695 -   coloring - coloring context created with MatTransposeColoringCreate()
10696 
10697     Output Parameter:
10698 .   Btdense - dense matrix B^T
10699 
10700     Level: advanced
10701 
10702      Notes:
10703     These are used internally for some implementations of MatRARt()
10704 
10705 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplyDenToSp()
10706 
10707 .keywords: coloring
10708 @*/
10709 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
10710 {
10711   PetscErrorCode ierr;
10712 
10713   PetscFunctionBegin;
10714   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
10715   PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2);
10716   PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3);
10717 
10718   if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
10719   ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr);
10720   PetscFunctionReturn(0);
10721 }
10722 
10723 /*@C
10724     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
10725     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
10726     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
10727     Csp from Cden.
10728 
10729     Collective on MatTransposeColoring
10730 
10731     Input Parameters:
10732 +   coloring - coloring context created with MatTransposeColoringCreate()
10733 -   Cden - matrix product of a sparse matrix and a dense matrix Btdense
10734 
10735     Output Parameter:
10736 .   Csp - sparse matrix
10737 
10738     Level: advanced
10739 
10740      Notes:
10741     These are used internally for some implementations of MatRARt()
10742 
10743 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()
10744 
10745 .keywords: coloring
10746 @*/
10747 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
10748 {
10749   PetscErrorCode ierr;
10750 
10751   PetscFunctionBegin;
10752   PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1);
10753   PetscValidHeaderSpecific(Cden,MAT_CLASSID,2);
10754   PetscValidHeaderSpecific(Csp,MAT_CLASSID,3);
10755 
10756   if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
10757   ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr);
10758   PetscFunctionReturn(0);
10759 }
10760 
10761 /*@C
10762    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.
10763 
10764    Collective on Mat
10765 
10766    Input Parameters:
10767 +  mat - the matrix product C
10768 -  iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring()
10769 
10770     Output Parameter:
10771 .   color - the new coloring context
10772 
10773     Level: intermediate
10774 
10775 .seealso: MatTransposeColoringDestroy(),  MatTransColoringApplySpToDen(),
10776            MatTransColoringApplyDenToSp()
10777 @*/
10778 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
10779 {
10780   MatTransposeColoring c;
10781   MPI_Comm             comm;
10782   PetscErrorCode       ierr;
10783 
10784   PetscFunctionBegin;
10785   ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10786   ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
10787   ierr = PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);CHKERRQ(ierr);
10788 
10789   c->ctype = iscoloring->ctype;
10790   if (mat->ops->transposecoloringcreate) {
10791     ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr);
10792   } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type");
10793 
10794   *color = c;
10795   ierr   = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10796   PetscFunctionReturn(0);
10797 }
10798 
10799 /*@
10800       MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the
10801         matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the
10802         same, otherwise it will be larger
10803 
10804      Not Collective
10805 
10806   Input Parameter:
10807 .    A  - the matrix
10808 
10809   Output Parameter:
10810 .    state - the current state
10811 
10812   Notes:
10813     You can only compare states from two different calls to the SAME matrix, you cannot compare calls between
10814          different matrices
10815 
10816   Level: intermediate
10817 
10818 @*/
10819 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state)
10820 {
10821   PetscFunctionBegin;
10822   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10823   *state = mat->nonzerostate;
10824   PetscFunctionReturn(0);
10825 }
10826 
10827 /*@
10828       MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential
10829                  matrices from each processor
10830 
10831     Collective on MPI_Comm
10832 
10833    Input Parameters:
10834 +    comm - the communicators the parallel matrix will live on
10835 .    seqmat - the input sequential matrices
10836 .    n - number of local columns (or PETSC_DECIDE)
10837 -    reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10838 
10839    Output Parameter:
10840 .    mpimat - the parallel matrix generated
10841 
10842     Level: advanced
10843 
10844    Notes:
10845     The number of columns of the matrix in EACH processor MUST be the same.
10846 
10847 @*/
10848 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat)
10849 {
10850   PetscErrorCode ierr;
10851 
10852   PetscFunctionBegin;
10853   if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name);
10854   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");
10855 
10856   ierr = PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10857   ierr = (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);CHKERRQ(ierr);
10858   ierr = PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10859   PetscFunctionReturn(0);
10860 }
10861 
10862 /*@
10863      MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent
10864                  ranks' ownership ranges.
10865 
10866     Collective on A
10867 
10868    Input Parameters:
10869 +    A   - the matrix to create subdomains from
10870 -    N   - requested number of subdomains
10871 
10872 
10873    Output Parameters:
10874 +    n   - number of subdomains resulting on this rank
10875 -    iss - IS list with indices of subdomains on this rank
10876 
10877     Level: advanced
10878 
10879     Notes:
10880     number of subdomains must be smaller than the communicator size
10881 @*/
10882 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[])
10883 {
10884   MPI_Comm        comm,subcomm;
10885   PetscMPIInt     size,rank,color;
10886   PetscInt        rstart,rend,k;
10887   PetscErrorCode  ierr;
10888 
10889   PetscFunctionBegin;
10890   ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr);
10891   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
10892   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
10893   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);
10894   *n = 1;
10895   k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */
10896   color = rank/k;
10897   ierr = MPI_Comm_split(comm,color,rank,&subcomm);CHKERRQ(ierr);
10898   ierr = PetscMalloc1(1,iss);CHKERRQ(ierr);
10899   ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
10900   ierr = ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);CHKERRQ(ierr);
10901   ierr = MPI_Comm_free(&subcomm);CHKERRQ(ierr);
10902   PetscFunctionReturn(0);
10903 }
10904 
10905 /*@
10906    MatGalerkin - Constructs the coarse grid problem via Galerkin projection.
10907 
10908    If the interpolation and restriction operators are the same, uses MatPtAP.
10909    If they are not the same, use MatMatMatMult.
10910 
10911    Once the coarse grid problem is constructed, correct for interpolation operators
10912    that are not of full rank, which can legitimately happen in the case of non-nested
10913    geometric multigrid.
10914 
10915    Input Parameters:
10916 +  restrct - restriction operator
10917 .  dA - fine grid matrix
10918 .  interpolate - interpolation operator
10919 .  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10920 -  fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate
10921 
10922    Output Parameters:
10923 .  A - the Galerkin coarse matrix
10924 
10925    Options Database Key:
10926 .  -pc_mg_galerkin <both,pmat,mat,none>
10927 
10928    Level: developer
10929 
10930 .keywords: MG, multigrid, Galerkin
10931 
10932 .seealso: MatPtAP(), MatMatMatMult()
10933 @*/
10934 PetscErrorCode  MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A)
10935 {
10936   PetscErrorCode ierr;
10937   IS             zerorows;
10938   Vec            diag;
10939 
10940   PetscFunctionBegin;
10941   if (reuse == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10942   /* Construct the coarse grid matrix */
10943   if (interpolate == restrct) {
10944     ierr = MatPtAP(dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10945   } else {
10946     ierr = MatMatMatMult(restrct,dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10947   }
10948 
10949   /* If the interpolation matrix is not of full rank, A will have zero rows.
10950      This can legitimately happen in the case of non-nested geometric multigrid.
10951      In that event, we set the rows of the matrix to the rows of the identity,
10952      ignoring the equations (as the RHS will also be zero). */
10953 
10954   ierr = MatFindZeroRows(*A, &zerorows);CHKERRQ(ierr);
10955 
10956   if (zerorows != NULL) { /* if there are any zero rows */
10957     ierr = MatCreateVecs(*A, &diag, NULL);CHKERRQ(ierr);
10958     ierr = MatGetDiagonal(*A, diag);CHKERRQ(ierr);
10959     ierr = VecISSet(diag, zerorows, 1.0);CHKERRQ(ierr);
10960     ierr = MatDiagonalSet(*A, diag, INSERT_VALUES);CHKERRQ(ierr);
10961     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10962     ierr = ISDestroy(&zerorows);CHKERRQ(ierr);
10963   }
10964   PetscFunctionReturn(0);
10965 }
10966 
10967 /*@C
10968     MatSetOperation - Allows user to set a matrix operation for any matrix type
10969 
10970    Logically Collective on Mat
10971 
10972     Input Parameters:
10973 +   mat - the matrix
10974 .   op - the name of the operation
10975 -   f - the function that provides the operation
10976 
10977    Level: developer
10978 
10979     Usage:
10980 $      extern PetscErrorCode usermult(Mat,Vec,Vec);
10981 $      ierr = MatCreateXXX(comm,...&A);
10982 $      ierr = MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult);
10983 
10984     Notes:
10985     See the file include/petscmat.h for a complete list of matrix
10986     operations, which all have the form MATOP_<OPERATION>, where
10987     <OPERATION> is the name (in all capital letters) of the
10988     user interface routine (e.g., MatMult() -> MATOP_MULT).
10989 
10990     All user-provided functions (except for MATOP_DESTROY) should have the same calling
10991     sequence as the usual matrix interface routines, since they
10992     are intended to be accessed via the usual matrix interface
10993     routines, e.g.,
10994 $       MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec)
10995 
10996     In particular each function MUST return an error code of 0 on success and
10997     nonzero on failure.
10998 
10999     This routine is distinct from MatShellSetOperation() in that it can be called on any matrix type.
11000 
11001 .keywords: matrix, set, operation
11002 
11003 .seealso: MatGetOperation(), MatCreateShell(), MatShellSetContext(), MatShellSetOperation()
11004 @*/
11005 PetscErrorCode MatSetOperation(Mat mat,MatOperation op,void (*f)(void))
11006 {
11007   PetscFunctionBegin;
11008   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
11009   if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) {
11010     mat->ops->viewnative = mat->ops->view;
11011   }
11012   (((void(**)(void))mat->ops)[op]) = f;
11013   PetscFunctionReturn(0);
11014 }
11015 
11016 /*@C
11017     MatGetOperation - Gets a matrix operation for any matrix type.
11018 
11019     Not Collective
11020 
11021     Input Parameters:
11022 +   mat - the matrix
11023 -   op - the name of the operation
11024 
11025     Output Parameter:
11026 .   f - the function that provides the operation
11027 
11028     Level: developer
11029 
11030     Usage:
11031 $      PetscErrorCode (*usermult)(Mat,Vec,Vec);
11032 $      ierr = MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult);
11033 
11034     Notes:
11035     See the file include/petscmat.h for a complete list of matrix
11036     operations, which all have the form MATOP_<OPERATION>, where
11037     <OPERATION> is the name (in all capital letters) of the
11038     user interface routine (e.g., MatMult() -> MATOP_MULT).
11039 
11040     This routine is distinct from MatShellGetOperation() in that it can be called on any matrix type.
11041 
11042 .keywords: matrix, get, operation
11043 
11044 .seealso: MatSetOperation(), MatCreateShell(), MatShellGetContext(), MatShellGetOperation()
11045 @*/
11046 PetscErrorCode MatGetOperation(Mat mat,MatOperation op,void(**f)(void))
11047 {
11048   PetscFunctionBegin;
11049   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
11050   *f = (((void (**)(void))mat->ops)[op]);
11051   PetscFunctionReturn(0);
11052 }
11053 
11054 /*@
11055     MatHasOperation - Determines whether the given matrix supports the particular
11056     operation.
11057 
11058    Not Collective
11059 
11060    Input Parameters:
11061 +  mat - the matrix
11062 -  op - the operation, for example, MATOP_GET_DIAGONAL
11063 
11064    Output Parameter:
11065 .  has - either PETSC_TRUE or PETSC_FALSE
11066 
11067    Level: advanced
11068 
11069    Notes:
11070    See the file include/petscmat.h for a complete list of matrix
11071    operations, which all have the form MATOP_<OPERATION>, where
11072    <OPERATION> is the name (in all capital letters) of the
11073    user-level routine.  E.g., MatNorm() -> MATOP_NORM.
11074 
11075 .keywords: matrix, has, operation
11076 
11077 .seealso: MatCreateShell()
11078 @*/
11079 PetscErrorCode MatHasOperation(Mat mat,MatOperation op,PetscBool *has)
11080 {
11081   PetscErrorCode ierr;
11082 
11083   PetscFunctionBegin;
11084   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
11085   PetscValidType(mat,1);
11086   PetscValidPointer(has,3);
11087   if (mat->ops->hasoperation) {
11088     ierr = (*mat->ops->hasoperation)(mat,op,has);CHKERRQ(ierr);
11089   } else {
11090     if (((void**)mat->ops)[op]) *has =  PETSC_TRUE;
11091     else {
11092       *has = PETSC_FALSE;
11093       if (op == MATOP_CREATE_SUBMATRIX) {
11094         PetscMPIInt size;
11095 
11096         ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
11097         if (size == 1) {
11098           ierr = MatHasOperation(mat,MATOP_CREATE_SUBMATRICES,has);CHKERRQ(ierr);
11099         }
11100       }
11101     }
11102   }
11103   PetscFunctionReturn(0);
11104 }
11105 
11106 /*@
11107     MatHasCongruentLayouts - Determines whether the rows and columns layouts
11108     of the matrix are congruent
11109 
11110    Collective on mat
11111 
11112    Input Parameters:
11113 .  mat - the matrix
11114 
11115    Output Parameter:
11116 .  cong - either PETSC_TRUE or PETSC_FALSE
11117 
11118    Level: beginner
11119 
11120    Notes:
11121 
11122 .keywords: matrix, has
11123 
11124 .seealso: MatCreate(), MatSetSizes()
11125 @*/
11126 PetscErrorCode MatHasCongruentLayouts(Mat mat,PetscBool *cong)
11127 {
11128   PetscErrorCode ierr;
11129 
11130   PetscFunctionBegin;
11131   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
11132   PetscValidType(mat,1);
11133   PetscValidPointer(cong,2);
11134   if (!mat->rmap || !mat->cmap) {
11135     *cong = mat->rmap == mat->cmap ? PETSC_TRUE : PETSC_FALSE;
11136     PetscFunctionReturn(0);
11137   }
11138   if (mat->congruentlayouts == PETSC_DECIDE) { /* first time we compare rows and cols layouts */
11139     ierr = PetscLayoutCompare(mat->rmap,mat->cmap,cong);CHKERRQ(ierr);
11140     if (*cong) mat->congruentlayouts = 1;
11141     else       mat->congruentlayouts = 0;
11142   } else *cong = mat->congruentlayouts ? PETSC_TRUE : PETSC_FALSE;
11143   PetscFunctionReturn(0);
11144 }
11145 
11146 /*@
11147     MatFreeIntermediateDataStructures - Free intermediate data structures created for reuse,
11148     e.g., matrx product of MatPtAP.
11149 
11150    Collective on mat
11151 
11152    Input Parameters:
11153 .  mat - the matrix
11154 
11155    Output Parameter:
11156 .  mat - the matrix with intermediate data structures released
11157 
11158    Level: advanced
11159 
11160    Notes:
11161 
11162 .keywords: matrix
11163 
11164 .seealso: MatPtAP(), MatMatMult()
11165 @*/
11166 PetscErrorCode MatFreeIntermediateDataStructures(Mat mat)
11167 {
11168   PetscErrorCode ierr;
11169 
11170   PetscFunctionBegin;
11171   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
11172   PetscValidType(mat,1);
11173   if (mat->ops->freeintermediatedatastructures) {
11174     ierr = (*mat->ops->freeintermediatedatastructures)(mat);CHKERRQ(ierr);
11175   }
11176   PetscFunctionReturn(0);
11177 }
11178