xref: /petsc/src/mat/interface/matrix.c (revision 8bdb3c7198ea5356e1f89a0cd9c0e235dea4448a)
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->subsetoffprocentries = flg;
5619     PetscFunctionReturn(0);
5620   case MAT_NO_OFF_PROC_ZERO_ROWS:
5621     mat->nooffproczerorows = flg;
5622     PetscFunctionReturn(0);
5623     break;
5624   case MAT_SPD:
5625     mat->spd_set = PETSC_TRUE;
5626     mat->spd     = flg;
5627     if (flg) {
5628       mat->symmetric                  = PETSC_TRUE;
5629       mat->structurally_symmetric     = PETSC_TRUE;
5630       mat->symmetric_set              = PETSC_TRUE;
5631       mat->structurally_symmetric_set = PETSC_TRUE;
5632     }
5633     break;
5634   case MAT_SYMMETRIC:
5635     mat->symmetric = flg;
5636     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5637     mat->symmetric_set              = PETSC_TRUE;
5638     mat->structurally_symmetric_set = flg;
5639 #if !defined(PETSC_USE_COMPLEX)
5640     mat->hermitian     = flg;
5641     mat->hermitian_set = PETSC_TRUE;
5642 #endif
5643     break;
5644   case MAT_HERMITIAN:
5645     mat->hermitian = flg;
5646     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5647     mat->hermitian_set              = PETSC_TRUE;
5648     mat->structurally_symmetric_set = flg;
5649 #if !defined(PETSC_USE_COMPLEX)
5650     mat->symmetric     = flg;
5651     mat->symmetric_set = PETSC_TRUE;
5652 #endif
5653     break;
5654   case MAT_STRUCTURALLY_SYMMETRIC:
5655     mat->structurally_symmetric     = flg;
5656     mat->structurally_symmetric_set = PETSC_TRUE;
5657     break;
5658   case MAT_SYMMETRY_ETERNAL:
5659     mat->symmetric_eternal = flg;
5660     break;
5661   case MAT_STRUCTURE_ONLY:
5662     mat->structure_only = flg;
5663     break;
5664   default:
5665     break;
5666   }
5667   if (mat->ops->setoption) {
5668     ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr);
5669   }
5670   PetscFunctionReturn(0);
5671 }
5672 
5673 /*@
5674    MatGetOption - Gets a parameter option that has been set for a matrix.
5675 
5676    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5677 
5678    Input Parameters:
5679 +  mat - the matrix
5680 -  option - the option, this only responds to certain options, check the code for which ones
5681 
5682    Output Parameter:
5683 .  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5684 
5685     Notes:
5686     Can only be called after MatSetSizes() and MatSetType() have been set.
5687 
5688    Level: intermediate
5689 
5690    Concepts: matrices^setting options
5691 
5692 .seealso:  MatOption, MatSetOption()
5693 
5694 @*/
5695 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg)
5696 {
5697   PetscFunctionBegin;
5698   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5699   PetscValidType(mat,1);
5700 
5701   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);
5702   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()");
5703 
5704   switch (op) {
5705   case MAT_NO_OFF_PROC_ENTRIES:
5706     *flg = mat->nooffprocentries;
5707     break;
5708   case MAT_NO_OFF_PROC_ZERO_ROWS:
5709     *flg = mat->nooffproczerorows;
5710     break;
5711   case MAT_SYMMETRIC:
5712     *flg = mat->symmetric;
5713     break;
5714   case MAT_HERMITIAN:
5715     *flg = mat->hermitian;
5716     break;
5717   case MAT_STRUCTURALLY_SYMMETRIC:
5718     *flg = mat->structurally_symmetric;
5719     break;
5720   case MAT_SYMMETRY_ETERNAL:
5721     *flg = mat->symmetric_eternal;
5722     break;
5723   case MAT_SPD:
5724     *flg = mat->spd;
5725     break;
5726   default:
5727     break;
5728   }
5729   PetscFunctionReturn(0);
5730 }
5731 
5732 /*@
5733    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5734    this routine retains the old nonzero structure.
5735 
5736    Logically Collective on Mat
5737 
5738    Input Parameters:
5739 .  mat - the matrix
5740 
5741    Level: intermediate
5742 
5743    Notes:
5744     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.
5745    See the Performance chapter of the users manual for information on preallocating matrices.
5746 
5747    Concepts: matrices^zeroing
5748 
5749 .seealso: MatZeroRows()
5750 @*/
5751 PetscErrorCode MatZeroEntries(Mat mat)
5752 {
5753   PetscErrorCode ierr;
5754 
5755   PetscFunctionBegin;
5756   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5757   PetscValidType(mat,1);
5758   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5759   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");
5760   if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5761   MatCheckPreallocated(mat,1);
5762 
5763   ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5764   ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
5765   ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5766   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5767 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5768   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5769     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5770   }
5771 #endif
5772   PetscFunctionReturn(0);
5773 }
5774 
5775 /*@
5776    MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal)
5777    of a set of rows and columns of a matrix.
5778 
5779    Collective on Mat
5780 
5781    Input Parameters:
5782 +  mat - the matrix
5783 .  numRows - the number of rows to remove
5784 .  rows - the global row indices
5785 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5786 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5787 -  b - optional vector of right hand side, that will be adjusted by provided solution
5788 
5789    Notes:
5790    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5791 
5792    The user can set a value in the diagonal entry (or for the AIJ and
5793    row formats can optionally remove the main diagonal entry from the
5794    nonzero structure as well, by passing 0.0 as the final argument).
5795 
5796    For the parallel case, all processes that share the matrix (i.e.,
5797    those in the communicator used for matrix creation) MUST call this
5798    routine, regardless of whether any rows being zeroed are owned by
5799    them.
5800 
5801    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5802    list only rows local to itself).
5803 
5804    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5805 
5806    Level: intermediate
5807 
5808    Concepts: matrices^zeroing rows
5809 
5810 .seealso: MatZeroRowsIS(), MatZeroRows(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5811           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5812 @*/
5813 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5814 {
5815   PetscErrorCode ierr;
5816 
5817   PetscFunctionBegin;
5818   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5819   PetscValidType(mat,1);
5820   if (numRows) PetscValidIntPointer(rows,3);
5821   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5822   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5823   if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5824   MatCheckPreallocated(mat,1);
5825 
5826   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5827   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5828   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5829 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5830   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5831     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5832   }
5833 #endif
5834   PetscFunctionReturn(0);
5835 }
5836 
5837 /*@
5838    MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
5839    of a set of rows and columns of a matrix.
5840 
5841    Collective on Mat
5842 
5843    Input Parameters:
5844 +  mat - the matrix
5845 .  is - the rows to zero
5846 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5847 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5848 -  b - optional vector of right hand side, that will be adjusted by provided solution
5849 
5850    Notes:
5851    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5852 
5853    The user can set a value in the diagonal entry (or for the AIJ and
5854    row formats can optionally remove the main diagonal entry from the
5855    nonzero structure as well, by passing 0.0 as the final argument).
5856 
5857    For the parallel case, all processes that share the matrix (i.e.,
5858    those in the communicator used for matrix creation) MUST call this
5859    routine, regardless of whether any rows being zeroed are owned by
5860    them.
5861 
5862    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5863    list only rows local to itself).
5864 
5865    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5866 
5867    Level: intermediate
5868 
5869    Concepts: matrices^zeroing rows
5870 
5871 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5872           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRows(), MatZeroRowsColumnsStencil()
5873 @*/
5874 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5875 {
5876   PetscErrorCode ierr;
5877   PetscInt       numRows;
5878   const PetscInt *rows;
5879 
5880   PetscFunctionBegin;
5881   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5882   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5883   PetscValidType(mat,1);
5884   PetscValidType(is,2);
5885   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5886   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5887   ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5888   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5889   PetscFunctionReturn(0);
5890 }
5891 
5892 /*@
5893    MatZeroRows - Zeros all entries (except possibly the main diagonal)
5894    of a set of rows of a matrix.
5895 
5896    Collective on Mat
5897 
5898    Input Parameters:
5899 +  mat - the matrix
5900 .  numRows - the number of rows to remove
5901 .  rows - the global row indices
5902 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5903 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5904 -  b - optional vector of right hand side, that will be adjusted by provided solution
5905 
5906    Notes:
5907    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5908    but does not release memory.  For the dense and block diagonal
5909    formats this does not alter the nonzero structure.
5910 
5911    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5912    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5913    merely zeroed.
5914 
5915    The user can set a value in the diagonal entry (or for the AIJ and
5916    row formats can optionally remove the main diagonal entry from the
5917    nonzero structure as well, by passing 0.0 as the final argument).
5918 
5919    For the parallel case, all processes that share the matrix (i.e.,
5920    those in the communicator used for matrix creation) MUST call this
5921    routine, regardless of whether any rows being zeroed are owned by
5922    them.
5923 
5924    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5925    list only rows local to itself).
5926 
5927    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5928    owns that are to be zeroed. This saves a global synchronization in the implementation.
5929 
5930    Level: intermediate
5931 
5932    Concepts: matrices^zeroing rows
5933 
5934 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5935           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5936 @*/
5937 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5938 {
5939   PetscErrorCode ierr;
5940 
5941   PetscFunctionBegin;
5942   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5943   PetscValidType(mat,1);
5944   if (numRows) PetscValidIntPointer(rows,3);
5945   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5946   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5947   if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5948   MatCheckPreallocated(mat,1);
5949 
5950   ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5951   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5952   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5953 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5954   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5955     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5956   }
5957 #endif
5958   PetscFunctionReturn(0);
5959 }
5960 
5961 /*@
5962    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5963    of a set of rows of a matrix.
5964 
5965    Collective on Mat
5966 
5967    Input Parameters:
5968 +  mat - the matrix
5969 .  is - index set of rows to remove
5970 .  diag - value put in all diagonals of eliminated rows
5971 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5972 -  b - optional vector of right hand side, that will be adjusted by provided solution
5973 
5974    Notes:
5975    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5976    but does not release memory.  For the dense and block diagonal
5977    formats this does not alter the nonzero structure.
5978 
5979    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5980    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5981    merely zeroed.
5982 
5983    The user can set a value in the diagonal entry (or for the AIJ and
5984    row formats can optionally remove the main diagonal entry from the
5985    nonzero structure as well, by passing 0.0 as the final argument).
5986 
5987    For the parallel case, all processes that share the matrix (i.e.,
5988    those in the communicator used for matrix creation) MUST call this
5989    routine, regardless of whether any rows being zeroed are owned by
5990    them.
5991 
5992    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5993    list only rows local to itself).
5994 
5995    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5996    owns that are to be zeroed. This saves a global synchronization in the implementation.
5997 
5998    Level: intermediate
5999 
6000    Concepts: matrices^zeroing rows
6001 
6002 .seealso: MatZeroRows(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6003           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6004 @*/
6005 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6006 {
6007   PetscInt       numRows;
6008   const PetscInt *rows;
6009   PetscErrorCode ierr;
6010 
6011   PetscFunctionBegin;
6012   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6013   PetscValidType(mat,1);
6014   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6015   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6016   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6017   ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6018   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6019   PetscFunctionReturn(0);
6020 }
6021 
6022 /*@
6023    MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
6024    of a set of rows of a matrix. These rows must be local to the process.
6025 
6026    Collective on Mat
6027 
6028    Input Parameters:
6029 +  mat - the matrix
6030 .  numRows - the number of rows to remove
6031 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
6032 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
6033 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6034 -  b - optional vector of right hand side, that will be adjusted by provided solution
6035 
6036    Notes:
6037    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
6038    but does not release memory.  For the dense and block diagonal
6039    formats this does not alter the nonzero structure.
6040 
6041    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6042    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6043    merely zeroed.
6044 
6045    The user can set a value in the diagonal entry (or for the AIJ and
6046    row formats can optionally remove the main diagonal entry from the
6047    nonzero structure as well, by passing 0.0 as the final argument).
6048 
6049    For the parallel case, all processes that share the matrix (i.e.,
6050    those in the communicator used for matrix creation) MUST call this
6051    routine, regardless of whether any rows being zeroed are owned by
6052    them.
6053 
6054    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
6055    list only rows local to itself).
6056 
6057    The grid coordinates are across the entire grid, not just the local portion
6058 
6059    In Fortran idxm and idxn should be declared as
6060 $     MatStencil idxm(4,m)
6061    and the values inserted using
6062 $    idxm(MatStencil_i,1) = i
6063 $    idxm(MatStencil_j,1) = j
6064 $    idxm(MatStencil_k,1) = k
6065 $    idxm(MatStencil_c,1) = c
6066    etc
6067 
6068    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
6069    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
6070    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
6071    DM_BOUNDARY_PERIODIC boundary type.
6072 
6073    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
6074    a single value per point) you can skip filling those indices.
6075 
6076    Level: intermediate
6077 
6078    Concepts: matrices^zeroing rows
6079 
6080 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsl(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6081           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6082 @*/
6083 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
6084 {
6085   PetscInt       dim     = mat->stencil.dim;
6086   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
6087   PetscInt       *dims   = mat->stencil.dims+1;
6088   PetscInt       *starts = mat->stencil.starts;
6089   PetscInt       *dxm    = (PetscInt*) rows;
6090   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
6091   PetscErrorCode ierr;
6092 
6093   PetscFunctionBegin;
6094   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6095   PetscValidType(mat,1);
6096   if (numRows) PetscValidIntPointer(rows,3);
6097 
6098   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
6099   for (i = 0; i < numRows; ++i) {
6100     /* Skip unused dimensions (they are ordered k, j, i, c) */
6101     for (j = 0; j < 3-sdim; ++j) dxm++;
6102     /* Local index in X dir */
6103     tmp = *dxm++ - starts[0];
6104     /* Loop over remaining dimensions */
6105     for (j = 0; j < dim-1; ++j) {
6106       /* If nonlocal, set index to be negative */
6107       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6108       /* Update local index */
6109       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6110     }
6111     /* Skip component slot if necessary */
6112     if (mat->stencil.noc) dxm++;
6113     /* Local row number */
6114     if (tmp >= 0) {
6115       jdxm[numNewRows++] = tmp;
6116     }
6117   }
6118   ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
6119   ierr = PetscFree(jdxm);CHKERRQ(ierr);
6120   PetscFunctionReturn(0);
6121 }
6122 
6123 /*@
6124    MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal)
6125    of a set of rows and columns of a matrix.
6126 
6127    Collective on Mat
6128 
6129    Input Parameters:
6130 +  mat - the matrix
6131 .  numRows - the number of rows/columns to remove
6132 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
6133 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
6134 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6135 -  b - optional vector of right hand side, that will be adjusted by provided solution
6136 
6137    Notes:
6138    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
6139    but does not release memory.  For the dense and block diagonal
6140    formats this does not alter the nonzero structure.
6141 
6142    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6143    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6144    merely zeroed.
6145 
6146    The user can set a value in the diagonal entry (or for the AIJ and
6147    row formats can optionally remove the main diagonal entry from the
6148    nonzero structure as well, by passing 0.0 as the final argument).
6149 
6150    For the parallel case, all processes that share the matrix (i.e.,
6151    those in the communicator used for matrix creation) MUST call this
6152    routine, regardless of whether any rows being zeroed are owned by
6153    them.
6154 
6155    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
6156    list only rows local to itself, but the row/column numbers are given in local numbering).
6157 
6158    The grid coordinates are across the entire grid, not just the local portion
6159 
6160    In Fortran idxm and idxn should be declared as
6161 $     MatStencil idxm(4,m)
6162    and the values inserted using
6163 $    idxm(MatStencil_i,1) = i
6164 $    idxm(MatStencil_j,1) = j
6165 $    idxm(MatStencil_k,1) = k
6166 $    idxm(MatStencil_c,1) = c
6167    etc
6168 
6169    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
6170    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
6171    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
6172    DM_BOUNDARY_PERIODIC boundary type.
6173 
6174    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
6175    a single value per point) you can skip filling those indices.
6176 
6177    Level: intermediate
6178 
6179    Concepts: matrices^zeroing rows
6180 
6181 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6182           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRows()
6183 @*/
6184 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
6185 {
6186   PetscInt       dim     = mat->stencil.dim;
6187   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
6188   PetscInt       *dims   = mat->stencil.dims+1;
6189   PetscInt       *starts = mat->stencil.starts;
6190   PetscInt       *dxm    = (PetscInt*) rows;
6191   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
6192   PetscErrorCode ierr;
6193 
6194   PetscFunctionBegin;
6195   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6196   PetscValidType(mat,1);
6197   if (numRows) PetscValidIntPointer(rows,3);
6198 
6199   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
6200   for (i = 0; i < numRows; ++i) {
6201     /* Skip unused dimensions (they are ordered k, j, i, c) */
6202     for (j = 0; j < 3-sdim; ++j) dxm++;
6203     /* Local index in X dir */
6204     tmp = *dxm++ - starts[0];
6205     /* Loop over remaining dimensions */
6206     for (j = 0; j < dim-1; ++j) {
6207       /* If nonlocal, set index to be negative */
6208       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6209       /* Update local index */
6210       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6211     }
6212     /* Skip component slot if necessary */
6213     if (mat->stencil.noc) dxm++;
6214     /* Local row number */
6215     if (tmp >= 0) {
6216       jdxm[numNewRows++] = tmp;
6217     }
6218   }
6219   ierr = MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
6220   ierr = PetscFree(jdxm);CHKERRQ(ierr);
6221   PetscFunctionReturn(0);
6222 }
6223 
6224 /*@C
6225    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
6226    of a set of rows of a matrix; using local numbering of rows.
6227 
6228    Collective on Mat
6229 
6230    Input Parameters:
6231 +  mat - the matrix
6232 .  numRows - the number of rows to remove
6233 .  rows - the global row indices
6234 .  diag - value put in all diagonals of eliminated rows
6235 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6236 -  b - optional vector of right hand side, that will be adjusted by provided solution
6237 
6238    Notes:
6239    Before calling MatZeroRowsLocal(), the user must first set the
6240    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6241 
6242    For the AIJ matrix formats this removes the old nonzero structure,
6243    but does not release memory.  For the dense and block diagonal
6244    formats this does not alter the nonzero structure.
6245 
6246    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6247    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6248    merely zeroed.
6249 
6250    The user can set a value in the diagonal entry (or for the AIJ and
6251    row formats can optionally remove the main diagonal entry from the
6252    nonzero structure as well, by passing 0.0 as the final argument).
6253 
6254    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6255    owns that are to be zeroed. This saves a global synchronization in the implementation.
6256 
6257    Level: intermediate
6258 
6259    Concepts: matrices^zeroing
6260 
6261 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRows(), MatSetOption(),
6262           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6263 @*/
6264 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6265 {
6266   PetscErrorCode ierr;
6267 
6268   PetscFunctionBegin;
6269   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6270   PetscValidType(mat,1);
6271   if (numRows) PetscValidIntPointer(rows,3);
6272   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6273   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6274   MatCheckPreallocated(mat,1);
6275 
6276   if (mat->ops->zerorowslocal) {
6277     ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6278   } else {
6279     IS             is, newis;
6280     const PetscInt *newRows;
6281 
6282     if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6283     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6284     ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr);
6285     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6286     ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6287     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6288     ierr = ISDestroy(&newis);CHKERRQ(ierr);
6289     ierr = ISDestroy(&is);CHKERRQ(ierr);
6290   }
6291   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6292 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
6293   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
6294     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
6295   }
6296 #endif
6297   PetscFunctionReturn(0);
6298 }
6299 
6300 /*@
6301    MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
6302    of a set of rows of a matrix; using local numbering of rows.
6303 
6304    Collective on Mat
6305 
6306    Input Parameters:
6307 +  mat - the matrix
6308 .  is - index set of rows to remove
6309 .  diag - value put in all diagonals of eliminated rows
6310 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6311 -  b - optional vector of right hand side, that will be adjusted by provided solution
6312 
6313    Notes:
6314    Before calling MatZeroRowsLocalIS(), the user must first set the
6315    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6316 
6317    For the AIJ matrix formats this removes the old nonzero structure,
6318    but does not release memory.  For the dense and block diagonal
6319    formats this does not alter the nonzero structure.
6320 
6321    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6322    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6323    merely zeroed.
6324 
6325    The user can set a value in the diagonal entry (or for the AIJ and
6326    row formats can optionally remove the main diagonal entry from the
6327    nonzero structure as well, by passing 0.0 as the final argument).
6328 
6329    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6330    owns that are to be zeroed. This saves a global synchronization in the implementation.
6331 
6332    Level: intermediate
6333 
6334    Concepts: matrices^zeroing
6335 
6336 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6337           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6338 @*/
6339 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6340 {
6341   PetscErrorCode ierr;
6342   PetscInt       numRows;
6343   const PetscInt *rows;
6344 
6345   PetscFunctionBegin;
6346   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6347   PetscValidType(mat,1);
6348   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6349   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6350   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6351   MatCheckPreallocated(mat,1);
6352 
6353   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6354   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6355   ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6356   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6357   PetscFunctionReturn(0);
6358 }
6359 
6360 /*@
6361    MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
6362    of a set of rows and columns of a matrix; using local numbering of rows.
6363 
6364    Collective on Mat
6365 
6366    Input Parameters:
6367 +  mat - the matrix
6368 .  numRows - the number of rows to remove
6369 .  rows - the global row indices
6370 .  diag - value put in all diagonals of eliminated rows
6371 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6372 -  b - optional vector of right hand side, that will be adjusted by provided solution
6373 
6374    Notes:
6375    Before calling MatZeroRowsColumnsLocal(), the user must first set the
6376    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6377 
6378    The user can set a value in the diagonal entry (or for the AIJ and
6379    row formats can optionally remove the main diagonal entry from the
6380    nonzero structure as well, by passing 0.0 as the final argument).
6381 
6382    Level: intermediate
6383 
6384    Concepts: matrices^zeroing
6385 
6386 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6387           MatZeroRows(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6388 @*/
6389 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6390 {
6391   PetscErrorCode ierr;
6392   IS             is, newis;
6393   const PetscInt *newRows;
6394 
6395   PetscFunctionBegin;
6396   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6397   PetscValidType(mat,1);
6398   if (numRows) PetscValidIntPointer(rows,3);
6399   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6400   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6401   MatCheckPreallocated(mat,1);
6402 
6403   if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6404   ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6405   ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr);
6406   ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6407   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6408   ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6409   ierr = ISDestroy(&newis);CHKERRQ(ierr);
6410   ierr = ISDestroy(&is);CHKERRQ(ierr);
6411   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6412 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
6413   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
6414     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
6415   }
6416 #endif
6417   PetscFunctionReturn(0);
6418 }
6419 
6420 /*@
6421    MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
6422    of a set of rows and columns of a matrix; using local numbering of rows.
6423 
6424    Collective on Mat
6425 
6426    Input Parameters:
6427 +  mat - the matrix
6428 .  is - index set of rows to remove
6429 .  diag - value put in all diagonals of eliminated rows
6430 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6431 -  b - optional vector of right hand side, that will be adjusted by provided solution
6432 
6433    Notes:
6434    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
6435    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6436 
6437    The user can set a value in the diagonal entry (or for the AIJ and
6438    row formats can optionally remove the main diagonal entry from the
6439    nonzero structure as well, by passing 0.0 as the final argument).
6440 
6441    Level: intermediate
6442 
6443    Concepts: matrices^zeroing
6444 
6445 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6446           MatZeroRowsColumnsLocal(), MatZeroRows(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6447 @*/
6448 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6449 {
6450   PetscErrorCode ierr;
6451   PetscInt       numRows;
6452   const PetscInt *rows;
6453 
6454   PetscFunctionBegin;
6455   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6456   PetscValidType(mat,1);
6457   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6458   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6459   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6460   MatCheckPreallocated(mat,1);
6461 
6462   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6463   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6464   ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6465   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6466   PetscFunctionReturn(0);
6467 }
6468 
6469 /*@C
6470    MatGetSize - Returns the numbers of rows and columns in a matrix.
6471 
6472    Not Collective
6473 
6474    Input Parameter:
6475 .  mat - the matrix
6476 
6477    Output Parameters:
6478 +  m - the number of global rows
6479 -  n - the number of global columns
6480 
6481    Note: both output parameters can be NULL on input.
6482 
6483    Level: beginner
6484 
6485    Concepts: matrices^size
6486 
6487 .seealso: MatGetLocalSize()
6488 @*/
6489 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
6490 {
6491   PetscFunctionBegin;
6492   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6493   if (m) *m = mat->rmap->N;
6494   if (n) *n = mat->cmap->N;
6495   PetscFunctionReturn(0);
6496 }
6497 
6498 /*@C
6499    MatGetLocalSize - Returns the number of rows and columns in a matrix
6500    stored locally.  This information may be implementation dependent, so
6501    use with care.
6502 
6503    Not Collective
6504 
6505    Input Parameters:
6506 .  mat - the matrix
6507 
6508    Output Parameters:
6509 +  m - the number of local rows
6510 -  n - the number of local columns
6511 
6512    Note: both output parameters can be NULL on input.
6513 
6514    Level: beginner
6515 
6516    Concepts: matrices^local size
6517 
6518 .seealso: MatGetSize()
6519 @*/
6520 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
6521 {
6522   PetscFunctionBegin;
6523   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6524   if (m) PetscValidIntPointer(m,2);
6525   if (n) PetscValidIntPointer(n,3);
6526   if (m) *m = mat->rmap->n;
6527   if (n) *n = mat->cmap->n;
6528   PetscFunctionReturn(0);
6529 }
6530 
6531 /*@C
6532    MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6533    this processor. (The columns of the "diagonal block")
6534 
6535    Not Collective, unless matrix has not been allocated, then collective on Mat
6536 
6537    Input Parameters:
6538 .  mat - the matrix
6539 
6540    Output Parameters:
6541 +  m - the global index of the first local column
6542 -  n - one more than the global index of the last local column
6543 
6544    Notes:
6545     both output parameters can be NULL on input.
6546 
6547    Level: developer
6548 
6549    Concepts: matrices^column ownership
6550 
6551 .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
6552 
6553 @*/
6554 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
6555 {
6556   PetscFunctionBegin;
6557   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6558   PetscValidType(mat,1);
6559   if (m) PetscValidIntPointer(m,2);
6560   if (n) PetscValidIntPointer(n,3);
6561   MatCheckPreallocated(mat,1);
6562   if (m) *m = mat->cmap->rstart;
6563   if (n) *n = mat->cmap->rend;
6564   PetscFunctionReturn(0);
6565 }
6566 
6567 /*@C
6568    MatGetOwnershipRange - Returns the range of matrix rows owned by
6569    this processor, assuming that the matrix is laid out with the first
6570    n1 rows on the first processor, the next n2 rows on the second, etc.
6571    For certain parallel layouts this range may not be well defined.
6572 
6573    Not Collective
6574 
6575    Input Parameters:
6576 .  mat - the matrix
6577 
6578    Output Parameters:
6579 +  m - the global index of the first local row
6580 -  n - one more than the global index of the last local row
6581 
6582    Note: Both output parameters can be NULL on input.
6583 $  This function requires that the matrix be preallocated. If you have not preallocated, consider using
6584 $    PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
6585 $  and then MPI_Scan() to calculate prefix sums of the local sizes.
6586 
6587    Level: beginner
6588 
6589    Concepts: matrices^row ownership
6590 
6591 .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()
6592 
6593 @*/
6594 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6595 {
6596   PetscFunctionBegin;
6597   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6598   PetscValidType(mat,1);
6599   if (m) PetscValidIntPointer(m,2);
6600   if (n) PetscValidIntPointer(n,3);
6601   MatCheckPreallocated(mat,1);
6602   if (m) *m = mat->rmap->rstart;
6603   if (n) *n = mat->rmap->rend;
6604   PetscFunctionReturn(0);
6605 }
6606 
6607 /*@C
6608    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6609    each process
6610 
6611    Not Collective, unless matrix has not been allocated, then collective on Mat
6612 
6613    Input Parameters:
6614 .  mat - the matrix
6615 
6616    Output Parameters:
6617 .  ranges - start of each processors portion plus one more than the total length at the end
6618 
6619    Level: beginner
6620 
6621    Concepts: matrices^row ownership
6622 
6623 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
6624 
6625 @*/
6626 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6627 {
6628   PetscErrorCode ierr;
6629 
6630   PetscFunctionBegin;
6631   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6632   PetscValidType(mat,1);
6633   MatCheckPreallocated(mat,1);
6634   ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr);
6635   PetscFunctionReturn(0);
6636 }
6637 
6638 /*@C
6639    MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6640    this processor. (The columns of the "diagonal blocks" for each process)
6641 
6642    Not Collective, unless matrix has not been allocated, then collective on Mat
6643 
6644    Input Parameters:
6645 .  mat - the matrix
6646 
6647    Output Parameters:
6648 .  ranges - start of each processors portion plus one more then the total length at the end
6649 
6650    Level: beginner
6651 
6652    Concepts: matrices^column ownership
6653 
6654 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
6655 
6656 @*/
6657 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6658 {
6659   PetscErrorCode ierr;
6660 
6661   PetscFunctionBegin;
6662   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6663   PetscValidType(mat,1);
6664   MatCheckPreallocated(mat,1);
6665   ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr);
6666   PetscFunctionReturn(0);
6667 }
6668 
6669 /*@C
6670    MatGetOwnershipIS - Get row and column ownership as index sets
6671 
6672    Not Collective
6673 
6674    Input Arguments:
6675 .  A - matrix of type Elemental
6676 
6677    Output Arguments:
6678 +  rows - rows in which this process owns elements
6679 .  cols - columns in which this process owns elements
6680 
6681    Level: intermediate
6682 
6683 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL
6684 @*/
6685 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6686 {
6687   PetscErrorCode ierr,(*f)(Mat,IS*,IS*);
6688 
6689   PetscFunctionBegin;
6690   MatCheckPreallocated(A,1);
6691   ierr = PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);CHKERRQ(ierr);
6692   if (f) {
6693     ierr = (*f)(A,rows,cols);CHKERRQ(ierr);
6694   } else {   /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6695     if (rows) {ierr = ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);CHKERRQ(ierr);}
6696     if (cols) {ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);CHKERRQ(ierr);}
6697   }
6698   PetscFunctionReturn(0);
6699 }
6700 
6701 /*@C
6702    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6703    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6704    to complete the factorization.
6705 
6706    Collective on Mat
6707 
6708    Input Parameters:
6709 +  mat - the matrix
6710 .  row - row permutation
6711 .  column - column permutation
6712 -  info - structure containing
6713 $      levels - number of levels of fill.
6714 $      expected fill - as ratio of original fill.
6715 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6716                 missing diagonal entries)
6717 
6718    Output Parameters:
6719 .  fact - new matrix that has been symbolically factored
6720 
6721    Notes:
6722     See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
6723 
6724    Most users should employ the simplified KSP interface for linear solvers
6725    instead of working directly with matrix algebra routines such as this.
6726    See, e.g., KSPCreate().
6727 
6728    Level: developer
6729 
6730   Concepts: matrices^symbolic LU factorization
6731   Concepts: matrices^factorization
6732   Concepts: LU^symbolic factorization
6733 
6734 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6735           MatGetOrdering(), MatFactorInfo
6736 
6737     Note: this uses the definition of level of fill as in Y. Saad, 2003
6738 
6739     Developer Note: fortran interface is not autogenerated as the f90
6740     interface defintion cannot be generated correctly [due to MatFactorInfo]
6741 
6742    References:
6743      Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003
6744 @*/
6745 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6746 {
6747   PetscErrorCode ierr;
6748 
6749   PetscFunctionBegin;
6750   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6751   PetscValidType(mat,1);
6752   PetscValidHeaderSpecific(row,IS_CLASSID,2);
6753   PetscValidHeaderSpecific(col,IS_CLASSID,3);
6754   PetscValidPointer(info,4);
6755   PetscValidPointer(fact,5);
6756   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6757   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6758   if (!(fact)->ops->ilufactorsymbolic) {
6759     MatSolverType spackage;
6760     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
6761     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6762   }
6763   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6764   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6765   MatCheckPreallocated(mat,2);
6766 
6767   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6768   ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
6769   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6770   PetscFunctionReturn(0);
6771 }
6772 
6773 /*@C
6774    MatICCFactorSymbolic - Performs symbolic incomplete
6775    Cholesky factorization for a symmetric matrix.  Use
6776    MatCholeskyFactorNumeric() to complete the factorization.
6777 
6778    Collective on Mat
6779 
6780    Input Parameters:
6781 +  mat - the matrix
6782 .  perm - row and column permutation
6783 -  info - structure containing
6784 $      levels - number of levels of fill.
6785 $      expected fill - as ratio of original fill.
6786 
6787    Output Parameter:
6788 .  fact - the factored matrix
6789 
6790    Notes:
6791    Most users should employ the KSP interface for linear solvers
6792    instead of working directly with matrix algebra routines such as this.
6793    See, e.g., KSPCreate().
6794 
6795    Level: developer
6796 
6797   Concepts: matrices^symbolic incomplete Cholesky factorization
6798   Concepts: matrices^factorization
6799   Concepts: Cholsky^symbolic factorization
6800 
6801 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
6802 
6803     Note: this uses the definition of level of fill as in Y. Saad, 2003
6804 
6805     Developer Note: fortran interface is not autogenerated as the f90
6806     interface defintion cannot be generated correctly [due to MatFactorInfo]
6807 
6808    References:
6809      Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003
6810 @*/
6811 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6812 {
6813   PetscErrorCode ierr;
6814 
6815   PetscFunctionBegin;
6816   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6817   PetscValidType(mat,1);
6818   PetscValidHeaderSpecific(perm,IS_CLASSID,2);
6819   PetscValidPointer(info,3);
6820   PetscValidPointer(fact,4);
6821   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6822   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6823   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6824   if (!(fact)->ops->iccfactorsymbolic) {
6825     MatSolverType spackage;
6826     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
6827     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6828   }
6829   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6830   MatCheckPreallocated(mat,2);
6831 
6832   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6833   ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
6834   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6835   PetscFunctionReturn(0);
6836 }
6837 
6838 /*@C
6839    MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat
6840    points to an array of valid matrices, they may be reused to store the new
6841    submatrices.
6842 
6843    Collective on Mat
6844 
6845    Input Parameters:
6846 +  mat - the matrix
6847 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6848 .  irow, icol - index sets of rows and columns to extract
6849 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6850 
6851    Output Parameter:
6852 .  submat - the array of submatrices
6853 
6854    Notes:
6855    MatCreateSubMatrices() can extract ONLY sequential submatrices
6856    (from both sequential and parallel matrices). Use MatCreateSubMatrix()
6857    to extract a parallel submatrix.
6858 
6859    Some matrix types place restrictions on the row and column
6860    indices, such as that they be sorted or that they be equal to each other.
6861 
6862    The index sets may not have duplicate entries.
6863 
6864    When extracting submatrices from a parallel matrix, each processor can
6865    form a different submatrix by setting the rows and columns of its
6866    individual index sets according to the local submatrix desired.
6867 
6868    When finished using the submatrices, the user should destroy
6869    them with MatDestroySubMatrices().
6870 
6871    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6872    original matrix has not changed from that last call to MatCreateSubMatrices().
6873 
6874    This routine creates the matrices in submat; you should NOT create them before
6875    calling it. It also allocates the array of matrix pointers submat.
6876 
6877    For BAIJ matrices the index sets must respect the block structure, that is if they
6878    request one row/column in a block, they must request all rows/columns that are in
6879    that block. For example, if the block size is 2 you cannot request just row 0 and
6880    column 0.
6881 
6882    Fortran Note:
6883    The Fortran interface is slightly different from that given below; it
6884    requires one to pass in  as submat a Mat (integer) array of size at least n+1.
6885 
6886    Level: advanced
6887 
6888    Concepts: matrices^accessing submatrices
6889    Concepts: submatrices
6890 
6891 .seealso: MatDestroySubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6892 @*/
6893 PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6894 {
6895   PetscErrorCode ierr;
6896   PetscInt       i;
6897   PetscBool      eq;
6898 
6899   PetscFunctionBegin;
6900   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6901   PetscValidType(mat,1);
6902   if (n) {
6903     PetscValidPointer(irow,3);
6904     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6905     PetscValidPointer(icol,4);
6906     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6907   }
6908   PetscValidPointer(submat,6);
6909   if (n && scall == MAT_REUSE_MATRIX) {
6910     PetscValidPointer(*submat,6);
6911     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6912   }
6913   if (!mat->ops->createsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6914   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6915   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6916   MatCheckPreallocated(mat,1);
6917 
6918   ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6919   ierr = (*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6920   ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6921   for (i=0; i<n; i++) {
6922     (*submat)[i]->factortype = MAT_FACTOR_NONE;  /* in case in place factorization was previously done on submatrix */
6923     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6924       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6925       if (eq) {
6926         if (mat->symmetric) {
6927           ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6928         } else if (mat->hermitian) {
6929           ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6930         } else if (mat->structurally_symmetric) {
6931           ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6932         }
6933       }
6934     }
6935   }
6936   PetscFunctionReturn(0);
6937 }
6938 
6939 /*@C
6940    MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms).
6941 
6942    Collective on Mat
6943 
6944    Input Parameters:
6945 +  mat - the matrix
6946 .  n   - the number of submatrixes to be extracted
6947 .  irow, icol - index sets of rows and columns to extract
6948 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6949 
6950    Output Parameter:
6951 .  submat - the array of submatrices
6952 
6953    Level: advanced
6954 
6955    Concepts: matrices^accessing submatrices
6956    Concepts: submatrices
6957 
6958 .seealso: MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6959 @*/
6960 PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6961 {
6962   PetscErrorCode ierr;
6963   PetscInt       i;
6964   PetscBool      eq;
6965 
6966   PetscFunctionBegin;
6967   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6968   PetscValidType(mat,1);
6969   if (n) {
6970     PetscValidPointer(irow,3);
6971     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6972     PetscValidPointer(icol,4);
6973     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6974   }
6975   PetscValidPointer(submat,6);
6976   if (n && scall == MAT_REUSE_MATRIX) {
6977     PetscValidPointer(*submat,6);
6978     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6979   }
6980   if (!mat->ops->createsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6981   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6982   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6983   MatCheckPreallocated(mat,1);
6984 
6985   ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6986   ierr = (*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6987   ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6988   for (i=0; i<n; i++) {
6989     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6990       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6991       if (eq) {
6992         if (mat->symmetric) {
6993           ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6994         } else if (mat->hermitian) {
6995           ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6996         } else if (mat->structurally_symmetric) {
6997           ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6998         }
6999       }
7000     }
7001   }
7002   PetscFunctionReturn(0);
7003 }
7004 
7005 /*@C
7006    MatDestroyMatrices - Destroys an array of matrices.
7007 
7008    Collective on Mat
7009 
7010    Input Parameters:
7011 +  n - the number of local matrices
7012 -  mat - the matrices (note that this is a pointer to the array of matrices)
7013 
7014    Level: advanced
7015 
7016     Notes:
7017     Frees not only the matrices, but also the array that contains the matrices
7018            In Fortran will not free the array.
7019 
7020 .seealso: MatCreateSubMatrices() MatDestroySubMatrices()
7021 @*/
7022 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
7023 {
7024   PetscErrorCode ierr;
7025   PetscInt       i;
7026 
7027   PetscFunctionBegin;
7028   if (!*mat) PetscFunctionReturn(0);
7029   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
7030   PetscValidPointer(mat,2);
7031 
7032   for (i=0; i<n; i++) {
7033     ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr);
7034   }
7035 
7036   /* memory is allocated even if n = 0 */
7037   ierr = PetscFree(*mat);CHKERRQ(ierr);
7038   PetscFunctionReturn(0);
7039 }
7040 
7041 /*@C
7042    MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices().
7043 
7044    Collective on Mat
7045 
7046    Input Parameters:
7047 +  n - the number of local matrices
7048 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
7049                        sequence of MatCreateSubMatrices())
7050 
7051    Level: advanced
7052 
7053     Notes:
7054     Frees not only the matrices, but also the array that contains the matrices
7055            In Fortran will not free the array.
7056 
7057 .seealso: MatCreateSubMatrices()
7058 @*/
7059 PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[])
7060 {
7061   PetscErrorCode ierr;
7062   Mat            mat0;
7063 
7064   PetscFunctionBegin;
7065   if (!*mat) PetscFunctionReturn(0);
7066   /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */
7067   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
7068   PetscValidPointer(mat,2);
7069 
7070   mat0 = (*mat)[0];
7071   if (mat0 && mat0->ops->destroysubmatrices) {
7072     ierr = (mat0->ops->destroysubmatrices)(n,mat);CHKERRQ(ierr);
7073   } else {
7074     ierr = MatDestroyMatrices(n,mat);CHKERRQ(ierr);
7075   }
7076   PetscFunctionReturn(0);
7077 }
7078 
7079 /*@C
7080    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
7081 
7082    Collective on Mat
7083 
7084    Input Parameters:
7085 .  mat - the matrix
7086 
7087    Output Parameter:
7088 .  matstruct - the sequential matrix with the nonzero structure of mat
7089 
7090   Level: intermediate
7091 
7092 .seealso: MatDestroySeqNonzeroStructure(), MatCreateSubMatrices(), MatDestroyMatrices()
7093 @*/
7094 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
7095 {
7096   PetscErrorCode ierr;
7097 
7098   PetscFunctionBegin;
7099   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7100   PetscValidPointer(matstruct,2);
7101 
7102   PetscValidType(mat,1);
7103   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7104   MatCheckPreallocated(mat,1);
7105 
7106   if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
7107   ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
7108   ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr);
7109   ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
7110   PetscFunctionReturn(0);
7111 }
7112 
7113 /*@C
7114    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
7115 
7116    Collective on Mat
7117 
7118    Input Parameters:
7119 .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
7120                        sequence of MatGetSequentialNonzeroStructure())
7121 
7122    Level: advanced
7123 
7124     Notes:
7125     Frees not only the matrices, but also the array that contains the matrices
7126 
7127 .seealso: MatGetSeqNonzeroStructure()
7128 @*/
7129 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
7130 {
7131   PetscErrorCode ierr;
7132 
7133   PetscFunctionBegin;
7134   PetscValidPointer(mat,1);
7135   ierr = MatDestroy(mat);CHKERRQ(ierr);
7136   PetscFunctionReturn(0);
7137 }
7138 
7139 /*@
7140    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
7141    replaces the index sets by larger ones that represent submatrices with
7142    additional overlap.
7143 
7144    Collective on Mat
7145 
7146    Input Parameters:
7147 +  mat - the matrix
7148 .  n   - the number of index sets
7149 .  is  - the array of index sets (these index sets will changed during the call)
7150 -  ov  - the additional overlap requested
7151 
7152    Options Database:
7153 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
7154 
7155    Level: developer
7156 
7157    Concepts: overlap
7158    Concepts: ASM^computing overlap
7159 
7160 .seealso: MatCreateSubMatrices()
7161 @*/
7162 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
7163 {
7164   PetscErrorCode ierr;
7165 
7166   PetscFunctionBegin;
7167   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7168   PetscValidType(mat,1);
7169   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
7170   if (n) {
7171     PetscValidPointer(is,3);
7172     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
7173   }
7174   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7175   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7176   MatCheckPreallocated(mat,1);
7177 
7178   if (!ov) PetscFunctionReturn(0);
7179   if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7180   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7181   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
7182   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7183   PetscFunctionReturn(0);
7184 }
7185 
7186 
7187 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt);
7188 
7189 /*@
7190    MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across
7191    a sub communicator, replaces the index sets by larger ones that represent submatrices with
7192    additional overlap.
7193 
7194    Collective on Mat
7195 
7196    Input Parameters:
7197 +  mat - the matrix
7198 .  n   - the number of index sets
7199 .  is  - the array of index sets (these index sets will changed during the call)
7200 -  ov  - the additional overlap requested
7201 
7202    Options Database:
7203 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
7204 
7205    Level: developer
7206 
7207    Concepts: overlap
7208    Concepts: ASM^computing overlap
7209 
7210 .seealso: MatCreateSubMatrices()
7211 @*/
7212 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov)
7213 {
7214   PetscInt       i;
7215   PetscErrorCode ierr;
7216 
7217   PetscFunctionBegin;
7218   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7219   PetscValidType(mat,1);
7220   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
7221   if (n) {
7222     PetscValidPointer(is,3);
7223     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
7224   }
7225   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7226   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7227   MatCheckPreallocated(mat,1);
7228   if (!ov) PetscFunctionReturn(0);
7229   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7230   for(i=0; i<n; i++){
7231 	ierr =  MatIncreaseOverlapSplit_Single(mat,&is[i],ov);CHKERRQ(ierr);
7232   }
7233   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7234   PetscFunctionReturn(0);
7235 }
7236 
7237 
7238 
7239 
7240 /*@
7241    MatGetBlockSize - Returns the matrix block size.
7242 
7243    Not Collective
7244 
7245    Input Parameter:
7246 .  mat - the matrix
7247 
7248    Output Parameter:
7249 .  bs - block size
7250 
7251    Notes:
7252     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7253 
7254    If the block size has not been set yet this routine returns 1.
7255 
7256    Level: intermediate
7257 
7258    Concepts: matrices^block size
7259 
7260 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
7261 @*/
7262 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
7263 {
7264   PetscFunctionBegin;
7265   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7266   PetscValidIntPointer(bs,2);
7267   *bs = PetscAbs(mat->rmap->bs);
7268   PetscFunctionReturn(0);
7269 }
7270 
7271 /*@
7272    MatGetBlockSizes - Returns the matrix block row and column sizes.
7273 
7274    Not Collective
7275 
7276    Input Parameter:
7277 .  mat - the matrix
7278 
7279    Output Parameter:
7280 .  rbs - row block size
7281 .  cbs - column block size
7282 
7283    Notes:
7284     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7285     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7286 
7287    If a block size has not been set yet this routine returns 1.
7288 
7289    Level: intermediate
7290 
7291    Concepts: matrices^block size
7292 
7293 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes()
7294 @*/
7295 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
7296 {
7297   PetscFunctionBegin;
7298   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7299   if (rbs) PetscValidIntPointer(rbs,2);
7300   if (cbs) PetscValidIntPointer(cbs,3);
7301   if (rbs) *rbs = PetscAbs(mat->rmap->bs);
7302   if (cbs) *cbs = PetscAbs(mat->cmap->bs);
7303   PetscFunctionReturn(0);
7304 }
7305 
7306 /*@
7307    MatSetBlockSize - Sets the matrix block size.
7308 
7309    Logically Collective on Mat
7310 
7311    Input Parameters:
7312 +  mat - the matrix
7313 -  bs - block size
7314 
7315    Notes:
7316     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7317     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later.
7318 
7319     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size
7320     is compatible with the matrix local sizes.
7321 
7322    Level: intermediate
7323 
7324    Concepts: matrices^block size
7325 
7326 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes()
7327 @*/
7328 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
7329 {
7330   PetscErrorCode ierr;
7331 
7332   PetscFunctionBegin;
7333   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7334   PetscValidLogicalCollectiveInt(mat,bs,2);
7335   ierr = MatSetBlockSizes(mat,bs,bs);CHKERRQ(ierr);
7336   PetscFunctionReturn(0);
7337 }
7338 
7339 /*@
7340    MatSetVariableBlockSizes - Sets a diagonal blocks of the matrix that need not be of the same size
7341 
7342    Logically Collective on Mat
7343 
7344    Input Parameters:
7345 +  mat - the matrix
7346 .  nblocks - the number of blocks on this process
7347 -  bsizes - the block sizes
7348 
7349    Notes:
7350     Currently used by PCVPBJACOBI for SeqAIJ matrices
7351 
7352    Level: intermediate
7353 
7354    Concepts: matrices^block size
7355 
7356 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatGetVariableBlockSizes()
7357 @*/
7358 PetscErrorCode MatSetVariableBlockSizes(Mat mat,PetscInt nblocks,PetscInt *bsizes)
7359 {
7360   PetscErrorCode ierr;
7361   PetscInt       i,ncnt = 0, nlocal;
7362 
7363   PetscFunctionBegin;
7364   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7365   if (nblocks < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number of local blocks must be great than or equal to zero");
7366   ierr = MatGetLocalSize(mat,&nlocal,NULL);CHKERRQ(ierr);
7367   for (i=0; i<nblocks; i++) ncnt += bsizes[i];
7368   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);
7369   ierr = PetscFree(mat->bsizes);CHKERRQ(ierr);
7370   mat->nblocks = nblocks;
7371   ierr = PetscMalloc1(nblocks,&mat->bsizes);CHKERRQ(ierr);
7372   ierr = PetscMemcpy(mat->bsizes,bsizes,nblocks*sizeof(PetscInt));CHKERRQ(ierr);
7373   PetscFunctionReturn(0);
7374 }
7375 
7376 /*@C
7377    MatGetVariableBlockSizes - Gets a diagonal blocks of the matrix that need not be of the same size
7378 
7379    Logically Collective on Mat
7380 
7381    Input Parameters:
7382 .  mat - the matrix
7383 
7384    Output Parameters:
7385 +  nblocks - the number of blocks on this process
7386 -  bsizes - the block sizes
7387 
7388    Notes: Currently not supported from Fortran
7389 
7390    Level: intermediate
7391 
7392    Concepts: matrices^block size
7393 
7394 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatSetVariableBlockSizes()
7395 @*/
7396 PetscErrorCode MatGetVariableBlockSizes(Mat mat,PetscInt *nblocks,const PetscInt **bsizes)
7397 {
7398   PetscFunctionBegin;
7399   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7400   *nblocks = mat->nblocks;
7401   *bsizes  = mat->bsizes;
7402   PetscFunctionReturn(0);
7403 }
7404 
7405 /*@
7406    MatSetBlockSizes - Sets the matrix block row and column sizes.
7407 
7408    Logically Collective on Mat
7409 
7410    Input Parameters:
7411 +  mat - the matrix
7412 -  rbs - row block size
7413 -  cbs - column block size
7414 
7415    Notes:
7416     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7417     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7418     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later
7419 
7420     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes
7421     are compatible with the matrix local sizes.
7422 
7423     The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs().
7424 
7425    Level: intermediate
7426 
7427    Concepts: matrices^block size
7428 
7429 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes()
7430 @*/
7431 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
7432 {
7433   PetscErrorCode ierr;
7434 
7435   PetscFunctionBegin;
7436   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7437   PetscValidLogicalCollectiveInt(mat,rbs,2);
7438   PetscValidLogicalCollectiveInt(mat,cbs,3);
7439   if (mat->ops->setblocksizes) {
7440     ierr = (*mat->ops->setblocksizes)(mat,rbs,cbs);CHKERRQ(ierr);
7441   }
7442   if (mat->rmap->refcnt) {
7443     ISLocalToGlobalMapping l2g = NULL;
7444     PetscLayout            nmap = NULL;
7445 
7446     ierr = PetscLayoutDuplicate(mat->rmap,&nmap);CHKERRQ(ierr);
7447     if (mat->rmap->mapping) {
7448       ierr = ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g);CHKERRQ(ierr);
7449     }
7450     ierr = PetscLayoutDestroy(&mat->rmap);CHKERRQ(ierr);
7451     mat->rmap = nmap;
7452     mat->rmap->mapping = l2g;
7453   }
7454   if (mat->cmap->refcnt) {
7455     ISLocalToGlobalMapping l2g = NULL;
7456     PetscLayout            nmap = NULL;
7457 
7458     ierr = PetscLayoutDuplicate(mat->cmap,&nmap);CHKERRQ(ierr);
7459     if (mat->cmap->mapping) {
7460       ierr = ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g);CHKERRQ(ierr);
7461     }
7462     ierr = PetscLayoutDestroy(&mat->cmap);CHKERRQ(ierr);
7463     mat->cmap = nmap;
7464     mat->cmap->mapping = l2g;
7465   }
7466   ierr = PetscLayoutSetBlockSize(mat->rmap,rbs);CHKERRQ(ierr);
7467   ierr = PetscLayoutSetBlockSize(mat->cmap,cbs);CHKERRQ(ierr);
7468   PetscFunctionReturn(0);
7469 }
7470 
7471 /*@
7472    MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices
7473 
7474    Logically Collective on Mat
7475 
7476    Input Parameters:
7477 +  mat - the matrix
7478 .  fromRow - matrix from which to copy row block size
7479 -  fromCol - matrix from which to copy column block size (can be same as fromRow)
7480 
7481    Level: developer
7482 
7483    Concepts: matrices^block size
7484 
7485 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes()
7486 @*/
7487 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)
7488 {
7489   PetscErrorCode ierr;
7490 
7491   PetscFunctionBegin;
7492   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7493   PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2);
7494   PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3);
7495   if (fromRow->rmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);CHKERRQ(ierr);}
7496   if (fromCol->cmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);CHKERRQ(ierr);}
7497   PetscFunctionReturn(0);
7498 }
7499 
7500 /*@
7501    MatResidual - Default routine to calculate the residual.
7502 
7503    Collective on Mat and Vec
7504 
7505    Input Parameters:
7506 +  mat - the matrix
7507 .  b   - the right-hand-side
7508 -  x   - the approximate solution
7509 
7510    Output Parameter:
7511 .  r - location to store the residual
7512 
7513    Level: developer
7514 
7515 .keywords: MG, default, multigrid, residual
7516 
7517 .seealso: PCMGSetResidual()
7518 @*/
7519 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r)
7520 {
7521   PetscErrorCode ierr;
7522 
7523   PetscFunctionBegin;
7524   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7525   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
7526   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
7527   PetscValidHeaderSpecific(r,VEC_CLASSID,4);
7528   PetscValidType(mat,1);
7529   MatCheckPreallocated(mat,1);
7530   ierr  = PetscLogEventBegin(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7531   if (!mat->ops->residual) {
7532     ierr = MatMult(mat,x,r);CHKERRQ(ierr);
7533     ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr);
7534   } else {
7535     ierr  = (*mat->ops->residual)(mat,b,x,r);CHKERRQ(ierr);
7536   }
7537   ierr  = PetscLogEventEnd(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7538   PetscFunctionReturn(0);
7539 }
7540 
7541 /*@C
7542     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
7543 
7544    Collective on Mat
7545 
7546     Input Parameters:
7547 +   mat - the matrix
7548 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
7549 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
7550 -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
7551                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7552                  always used.
7553 
7554     Output Parameters:
7555 +   n - number of rows in the (possibly compressed) matrix
7556 .   ia - the row pointers; that is ia[0] = 0, ia[row] = ia[row-1] + number of elements in that row of the matrix
7557 .   ja - the column indices
7558 -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
7559            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
7560 
7561     Level: developer
7562 
7563     Notes:
7564     You CANNOT change any of the ia[] or ja[] values.
7565 
7566     Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values.
7567 
7568     Fortran Notes:
7569     In Fortran use
7570 $
7571 $      PetscInt ia(1), ja(1)
7572 $      PetscOffset iia, jja
7573 $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
7574 $      ! Access the ith and jth entries via ia(iia + i) and ja(jja + j)
7575 
7576      or
7577 $
7578 $    PetscInt, pointer :: ia(:),ja(:)
7579 $    call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
7580 $    ! Access the ith and jth entries via ia(i) and ja(j)
7581 
7582 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
7583 @*/
7584 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7585 {
7586   PetscErrorCode ierr;
7587 
7588   PetscFunctionBegin;
7589   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7590   PetscValidType(mat,1);
7591   PetscValidIntPointer(n,5);
7592   if (ia) PetscValidIntPointer(ia,6);
7593   if (ja) PetscValidIntPointer(ja,7);
7594   PetscValidIntPointer(done,8);
7595   MatCheckPreallocated(mat,1);
7596   if (!mat->ops->getrowij) *done = PETSC_FALSE;
7597   else {
7598     *done = PETSC_TRUE;
7599     ierr  = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7600     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7601     ierr  = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7602   }
7603   PetscFunctionReturn(0);
7604 }
7605 
7606 /*@C
7607     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
7608 
7609     Collective on Mat
7610 
7611     Input Parameters:
7612 +   mat - the matrix
7613 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7614 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7615                 symmetrized
7616 .   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7617                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7618                  always used.
7619 .   n - number of columns in the (possibly compressed) matrix
7620 .   ia - the column pointers; that is ia[0] = 0, ia[col] = i[col-1] + number of elements in that col of the matrix
7621 -   ja - the row indices
7622 
7623     Output Parameters:
7624 .   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
7625 
7626     Level: developer
7627 
7628 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7629 @*/
7630 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7631 {
7632   PetscErrorCode ierr;
7633 
7634   PetscFunctionBegin;
7635   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7636   PetscValidType(mat,1);
7637   PetscValidIntPointer(n,4);
7638   if (ia) PetscValidIntPointer(ia,5);
7639   if (ja) PetscValidIntPointer(ja,6);
7640   PetscValidIntPointer(done,7);
7641   MatCheckPreallocated(mat,1);
7642   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
7643   else {
7644     *done = PETSC_TRUE;
7645     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7646   }
7647   PetscFunctionReturn(0);
7648 }
7649 
7650 /*@C
7651     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
7652     MatGetRowIJ().
7653 
7654     Collective on Mat
7655 
7656     Input Parameters:
7657 +   mat - the matrix
7658 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7659 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7660                 symmetrized
7661 .   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7662                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7663                  always used.
7664 .   n - size of (possibly compressed) matrix
7665 .   ia - the row pointers
7666 -   ja - the column indices
7667 
7668     Output Parameters:
7669 .   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7670 
7671     Note:
7672     This routine zeros out n, ia, and ja. This is to prevent accidental
7673     us of the array after it has been restored. If you pass NULL, it will
7674     not zero the pointers.  Use of ia or ja after MatRestoreRowIJ() is invalid.
7675 
7676     Level: developer
7677 
7678 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7679 @*/
7680 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7681 {
7682   PetscErrorCode ierr;
7683 
7684   PetscFunctionBegin;
7685   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7686   PetscValidType(mat,1);
7687   if (ia) PetscValidIntPointer(ia,6);
7688   if (ja) PetscValidIntPointer(ja,7);
7689   PetscValidIntPointer(done,8);
7690   MatCheckPreallocated(mat,1);
7691 
7692   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
7693   else {
7694     *done = PETSC_TRUE;
7695     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7696     if (n)  *n = 0;
7697     if (ia) *ia = NULL;
7698     if (ja) *ja = NULL;
7699   }
7700   PetscFunctionReturn(0);
7701 }
7702 
7703 /*@C
7704     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
7705     MatGetColumnIJ().
7706 
7707     Collective on Mat
7708 
7709     Input Parameters:
7710 +   mat - the matrix
7711 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7712 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7713                 symmetrized
7714 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7715                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7716                  always used.
7717 
7718     Output Parameters:
7719 +   n - size of (possibly compressed) matrix
7720 .   ia - the column pointers
7721 .   ja - the row indices
7722 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7723 
7724     Level: developer
7725 
7726 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
7727 @*/
7728 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7729 {
7730   PetscErrorCode ierr;
7731 
7732   PetscFunctionBegin;
7733   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7734   PetscValidType(mat,1);
7735   if (ia) PetscValidIntPointer(ia,5);
7736   if (ja) PetscValidIntPointer(ja,6);
7737   PetscValidIntPointer(done,7);
7738   MatCheckPreallocated(mat,1);
7739 
7740   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
7741   else {
7742     *done = PETSC_TRUE;
7743     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7744     if (n)  *n = 0;
7745     if (ia) *ia = NULL;
7746     if (ja) *ja = NULL;
7747   }
7748   PetscFunctionReturn(0);
7749 }
7750 
7751 /*@C
7752     MatColoringPatch -Used inside matrix coloring routines that
7753     use MatGetRowIJ() and/or MatGetColumnIJ().
7754 
7755     Collective on Mat
7756 
7757     Input Parameters:
7758 +   mat - the matrix
7759 .   ncolors - max color value
7760 .   n   - number of entries in colorarray
7761 -   colorarray - array indicating color for each column
7762 
7763     Output Parameters:
7764 .   iscoloring - coloring generated using colorarray information
7765 
7766     Level: developer
7767 
7768 .seealso: MatGetRowIJ(), MatGetColumnIJ()
7769 
7770 @*/
7771 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7772 {
7773   PetscErrorCode ierr;
7774 
7775   PetscFunctionBegin;
7776   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7777   PetscValidType(mat,1);
7778   PetscValidIntPointer(colorarray,4);
7779   PetscValidPointer(iscoloring,5);
7780   MatCheckPreallocated(mat,1);
7781 
7782   if (!mat->ops->coloringpatch) {
7783     ierr = ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);CHKERRQ(ierr);
7784   } else {
7785     ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
7786   }
7787   PetscFunctionReturn(0);
7788 }
7789 
7790 
7791 /*@
7792    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
7793 
7794    Logically Collective on Mat
7795 
7796    Input Parameter:
7797 .  mat - the factored matrix to be reset
7798 
7799    Notes:
7800    This routine should be used only with factored matrices formed by in-place
7801    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7802    format).  This option can save memory, for example, when solving nonlinear
7803    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7804    ILU(0) preconditioner.
7805 
7806    Note that one can specify in-place ILU(0) factorization by calling
7807 .vb
7808      PCType(pc,PCILU);
7809      PCFactorSeUseInPlace(pc);
7810 .ve
7811    or by using the options -pc_type ilu -pc_factor_in_place
7812 
7813    In-place factorization ILU(0) can also be used as a local
7814    solver for the blocks within the block Jacobi or additive Schwarz
7815    methods (runtime option: -sub_pc_factor_in_place).  See Users-Manual: ch_pc
7816    for details on setting local solver options.
7817 
7818    Most users should employ the simplified KSP interface for linear solvers
7819    instead of working directly with matrix algebra routines such as this.
7820    See, e.g., KSPCreate().
7821 
7822    Level: developer
7823 
7824 .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace()
7825 
7826    Concepts: matrices^unfactored
7827 
7828 @*/
7829 PetscErrorCode MatSetUnfactored(Mat mat)
7830 {
7831   PetscErrorCode ierr;
7832 
7833   PetscFunctionBegin;
7834   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7835   PetscValidType(mat,1);
7836   MatCheckPreallocated(mat,1);
7837   mat->factortype = MAT_FACTOR_NONE;
7838   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
7839   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
7840   PetscFunctionReturn(0);
7841 }
7842 
7843 /*MC
7844     MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.
7845 
7846     Synopsis:
7847     MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7848 
7849     Not collective
7850 
7851     Input Parameter:
7852 .   x - matrix
7853 
7854     Output Parameters:
7855 +   xx_v - the Fortran90 pointer to the array
7856 -   ierr - error code
7857 
7858     Example of Usage:
7859 .vb
7860       PetscScalar, pointer xx_v(:,:)
7861       ....
7862       call MatDenseGetArrayF90(x,xx_v,ierr)
7863       a = xx_v(3)
7864       call MatDenseRestoreArrayF90(x,xx_v,ierr)
7865 .ve
7866 
7867     Level: advanced
7868 
7869 .seealso:  MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90()
7870 
7871     Concepts: matrices^accessing array
7872 
7873 M*/
7874 
7875 /*MC
7876     MatDenseRestoreArrayF90 - Restores a matrix array that has been
7877     accessed with MatDenseGetArrayF90().
7878 
7879     Synopsis:
7880     MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7881 
7882     Not collective
7883 
7884     Input Parameters:
7885 +   x - matrix
7886 -   xx_v - the Fortran90 pointer to the array
7887 
7888     Output Parameter:
7889 .   ierr - error code
7890 
7891     Example of Usage:
7892 .vb
7893        PetscScalar, pointer xx_v(:,:)
7894        ....
7895        call MatDenseGetArrayF90(x,xx_v,ierr)
7896        a = xx_v(3)
7897        call MatDenseRestoreArrayF90(x,xx_v,ierr)
7898 .ve
7899 
7900     Level: advanced
7901 
7902 .seealso:  MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90()
7903 
7904 M*/
7905 
7906 
7907 /*MC
7908     MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.
7909 
7910     Synopsis:
7911     MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7912 
7913     Not collective
7914 
7915     Input Parameter:
7916 .   x - matrix
7917 
7918     Output Parameters:
7919 +   xx_v - the Fortran90 pointer to the array
7920 -   ierr - error code
7921 
7922     Example of Usage:
7923 .vb
7924       PetscScalar, pointer xx_v(:)
7925       ....
7926       call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7927       a = xx_v(3)
7928       call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7929 .ve
7930 
7931     Level: advanced
7932 
7933 .seealso:  MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90()
7934 
7935     Concepts: matrices^accessing array
7936 
7937 M*/
7938 
7939 /*MC
7940     MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7941     accessed with MatSeqAIJGetArrayF90().
7942 
7943     Synopsis:
7944     MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7945 
7946     Not collective
7947 
7948     Input Parameters:
7949 +   x - matrix
7950 -   xx_v - the Fortran90 pointer to the array
7951 
7952     Output Parameter:
7953 .   ierr - error code
7954 
7955     Example of Usage:
7956 .vb
7957        PetscScalar, pointer xx_v(:)
7958        ....
7959        call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7960        a = xx_v(3)
7961        call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7962 .ve
7963 
7964     Level: advanced
7965 
7966 .seealso:  MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90()
7967 
7968 M*/
7969 
7970 
7971 /*@
7972     MatCreateSubMatrix - Gets a single submatrix on the same number of processors
7973                       as the original matrix.
7974 
7975     Collective on Mat
7976 
7977     Input Parameters:
7978 +   mat - the original matrix
7979 .   isrow - parallel IS containing the rows this processor should obtain
7980 .   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.
7981 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7982 
7983     Output Parameter:
7984 .   newmat - the new submatrix, of the same type as the old
7985 
7986     Level: advanced
7987 
7988     Notes:
7989     The submatrix will be able to be multiplied with vectors using the same layout as iscol.
7990 
7991     Some matrix types place restrictions on the row and column indices, such
7992     as that they be sorted or that they be equal to each other.
7993 
7994     The index sets may not have duplicate entries.
7995 
7996       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7997    the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls
7998    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7999    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
8000    you are finished using it.
8001 
8002     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
8003     the input matrix.
8004 
8005     If iscol is NULL then all columns are obtained (not supported in Fortran).
8006 
8007    Example usage:
8008    Consider the following 8x8 matrix with 34 non-zero values, that is
8009    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
8010    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
8011    as follows:
8012 
8013 .vb
8014             1  2  0  |  0  3  0  |  0  4
8015     Proc0   0  5  6  |  7  0  0  |  8  0
8016             9  0 10  | 11  0  0  | 12  0
8017     -------------------------------------
8018            13  0 14  | 15 16 17  |  0  0
8019     Proc1   0 18  0  | 19 20 21  |  0  0
8020             0  0  0  | 22 23  0  | 24  0
8021     -------------------------------------
8022     Proc2  25 26 27  |  0  0 28  | 29  0
8023            30  0  0  | 31 32 33  |  0 34
8024 .ve
8025 
8026     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is
8027 
8028 .vb
8029             2  0  |  0  3  0  |  0
8030     Proc0   5  6  |  7  0  0  |  8
8031     -------------------------------
8032     Proc1  18  0  | 19 20 21  |  0
8033     -------------------------------
8034     Proc2  26 27  |  0  0 28  | 29
8035             0  0  | 31 32 33  |  0
8036 .ve
8037 
8038 
8039     Concepts: matrices^submatrices
8040 
8041 .seealso: MatCreateSubMatrices()
8042 @*/
8043 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
8044 {
8045   PetscErrorCode ierr;
8046   PetscMPIInt    size;
8047   Mat            *local;
8048   IS             iscoltmp;
8049 
8050   PetscFunctionBegin;
8051   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8052   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
8053   if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
8054   PetscValidPointer(newmat,5);
8055   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5);
8056   PetscValidType(mat,1);
8057   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8058   if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX");
8059 
8060   MatCheckPreallocated(mat,1);
8061   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
8062 
8063   if (!iscol || isrow == iscol) {
8064     PetscBool   stride;
8065     PetscMPIInt grabentirematrix = 0,grab;
8066     ierr = PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);CHKERRQ(ierr);
8067     if (stride) {
8068       PetscInt first,step,n,rstart,rend;
8069       ierr = ISStrideGetInfo(isrow,&first,&step);CHKERRQ(ierr);
8070       if (step == 1) {
8071         ierr = MatGetOwnershipRange(mat,&rstart,&rend);CHKERRQ(ierr);
8072         if (rstart == first) {
8073           ierr = ISGetLocalSize(isrow,&n);CHKERRQ(ierr);
8074           if (n == rend-rstart) {
8075             grabentirematrix = 1;
8076           }
8077         }
8078       }
8079     }
8080     ierr = MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr);
8081     if (grab) {
8082       ierr = PetscInfo(mat,"Getting entire matrix as submatrix\n");CHKERRQ(ierr);
8083       if (cll == MAT_INITIAL_MATRIX) {
8084         *newmat = mat;
8085         ierr    = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr);
8086       }
8087       PetscFunctionReturn(0);
8088     }
8089   }
8090 
8091   if (!iscol) {
8092     ierr = ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr);
8093   } else {
8094     iscoltmp = iscol;
8095   }
8096 
8097   /* if original matrix is on just one processor then use submatrix generated */
8098   if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
8099     ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
8100     goto setproperties;
8101   } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) {
8102     ierr    = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
8103     *newmat = *local;
8104     ierr    = PetscFree(local);CHKERRQ(ierr);
8105     goto setproperties;
8106   } else if (!mat->ops->createsubmatrix) {
8107     /* Create a new matrix type that implements the operation using the full matrix */
8108     ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8109     switch (cll) {
8110     case MAT_INITIAL_MATRIX:
8111       ierr = MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr);
8112       break;
8113     case MAT_REUSE_MATRIX:
8114       ierr = MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr);
8115       break;
8116     default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
8117     }
8118     ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8119     goto setproperties;
8120   }
8121 
8122   if (!mat->ops->createsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8123   ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8124   ierr = (*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr);
8125   ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8126 
8127   /* Propagate symmetry information for diagonal blocks */
8128 setproperties:
8129   if (isrow == iscoltmp) {
8130     if (mat->symmetric_set && mat->symmetric) {
8131       ierr = MatSetOption(*newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
8132     }
8133     if (mat->structurally_symmetric_set && mat->structurally_symmetric) {
8134       ierr = MatSetOption(*newmat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
8135     }
8136     if (mat->hermitian_set && mat->hermitian) {
8137       ierr = MatSetOption(*newmat,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
8138     }
8139     if (mat->spd_set && mat->spd) {
8140       ierr = MatSetOption(*newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr);
8141     }
8142   }
8143 
8144   if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
8145   if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);}
8146   PetscFunctionReturn(0);
8147 }
8148 
8149 /*@
8150    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
8151    used during the assembly process to store values that belong to
8152    other processors.
8153 
8154    Not Collective
8155 
8156    Input Parameters:
8157 +  mat   - the matrix
8158 .  size  - the initial size of the stash.
8159 -  bsize - the initial size of the block-stash(if used).
8160 
8161    Options Database Keys:
8162 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
8163 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
8164 
8165    Level: intermediate
8166 
8167    Notes:
8168      The block-stash is used for values set with MatSetValuesBlocked() while
8169      the stash is used for values set with MatSetValues()
8170 
8171      Run with the option -info and look for output of the form
8172      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
8173      to determine the appropriate value, MM, to use for size and
8174      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
8175      to determine the value, BMM to use for bsize
8176 
8177    Concepts: stash^setting matrix size
8178    Concepts: matrices^stash
8179 
8180 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
8181 
8182 @*/
8183 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
8184 {
8185   PetscErrorCode ierr;
8186 
8187   PetscFunctionBegin;
8188   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8189   PetscValidType(mat,1);
8190   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
8191   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
8192   PetscFunctionReturn(0);
8193 }
8194 
8195 /*@
8196    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
8197      the matrix
8198 
8199    Neighbor-wise Collective on Mat
8200 
8201    Input Parameters:
8202 +  mat   - the matrix
8203 .  x,y - the vectors
8204 -  w - where the result is stored
8205 
8206    Level: intermediate
8207 
8208    Notes:
8209     w may be the same vector as y.
8210 
8211     This allows one to use either the restriction or interpolation (its transpose)
8212     matrix to do the interpolation
8213 
8214     Concepts: interpolation
8215 
8216 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
8217 
8218 @*/
8219 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
8220 {
8221   PetscErrorCode ierr;
8222   PetscInt       M,N,Ny;
8223 
8224   PetscFunctionBegin;
8225   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8226   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8227   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8228   PetscValidHeaderSpecific(w,VEC_CLASSID,4);
8229   PetscValidType(A,1);
8230   MatCheckPreallocated(A,1);
8231   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8232   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8233   if (M == Ny) {
8234     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
8235   } else {
8236     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
8237   }
8238   PetscFunctionReturn(0);
8239 }
8240 
8241 /*@
8242    MatInterpolate - y = A*x or A'*x depending on the shape of
8243      the matrix
8244 
8245    Neighbor-wise Collective on Mat
8246 
8247    Input Parameters:
8248 +  mat   - the matrix
8249 -  x,y - the vectors
8250 
8251    Level: intermediate
8252 
8253    Notes:
8254     This allows one to use either the restriction or interpolation (its transpose)
8255     matrix to do the interpolation
8256 
8257    Concepts: matrices^interpolation
8258 
8259 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
8260 
8261 @*/
8262 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
8263 {
8264   PetscErrorCode ierr;
8265   PetscInt       M,N,Ny;
8266 
8267   PetscFunctionBegin;
8268   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8269   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8270   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8271   PetscValidType(A,1);
8272   MatCheckPreallocated(A,1);
8273   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8274   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8275   if (M == Ny) {
8276     ierr = MatMult(A,x,y);CHKERRQ(ierr);
8277   } else {
8278     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
8279   }
8280   PetscFunctionReturn(0);
8281 }
8282 
8283 /*@
8284    MatRestrict - y = A*x or A'*x
8285 
8286    Neighbor-wise Collective on Mat
8287 
8288    Input Parameters:
8289 +  mat   - the matrix
8290 -  x,y - the vectors
8291 
8292    Level: intermediate
8293 
8294    Notes:
8295     This allows one to use either the restriction or interpolation (its transpose)
8296     matrix to do the restriction
8297 
8298    Concepts: matrices^restriction
8299 
8300 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
8301 
8302 @*/
8303 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
8304 {
8305   PetscErrorCode ierr;
8306   PetscInt       M,N,Ny;
8307 
8308   PetscFunctionBegin;
8309   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8310   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8311   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8312   PetscValidType(A,1);
8313   MatCheckPreallocated(A,1);
8314 
8315   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8316   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8317   if (M == Ny) {
8318     ierr = MatMult(A,x,y);CHKERRQ(ierr);
8319   } else {
8320     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
8321   }
8322   PetscFunctionReturn(0);
8323 }
8324 
8325 /*@
8326    MatGetNullSpace - retrieves the null space of a matrix.
8327 
8328    Logically Collective on Mat and MatNullSpace
8329 
8330    Input Parameters:
8331 +  mat - the matrix
8332 -  nullsp - the null space object
8333 
8334    Level: developer
8335 
8336    Concepts: null space^attaching to matrix
8337 
8338 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace()
8339 @*/
8340 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
8341 {
8342   PetscFunctionBegin;
8343   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8344   PetscValidPointer(nullsp,2);
8345   *nullsp = (mat->symmetric_set && mat->symmetric && !mat->nullsp) ? mat->transnullsp : mat->nullsp;
8346   PetscFunctionReturn(0);
8347 }
8348 
8349 /*@
8350    MatSetNullSpace - attaches a null space to a matrix.
8351 
8352    Logically Collective on Mat and MatNullSpace
8353 
8354    Input Parameters:
8355 +  mat - the matrix
8356 -  nullsp - the null space object
8357 
8358    Level: advanced
8359 
8360    Notes:
8361       This null space is used by the linear solvers. Overwrites any previous null space that may have been attached
8362 
8363       For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should
8364       call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense.
8365 
8366       You can remove the null space by calling this routine with an nullsp of NULL
8367 
8368 
8369       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8370    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).
8371    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
8372    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
8373    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).
8374 
8375       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8376 
8377     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
8378     routine also automatically calls MatSetTransposeNullSpace().
8379 
8380    Concepts: null space^attaching to matrix
8381 
8382 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8383 @*/
8384 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp)
8385 {
8386   PetscErrorCode ierr;
8387 
8388   PetscFunctionBegin;
8389   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8390   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8391   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8392   ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr);
8393   mat->nullsp = nullsp;
8394   if (mat->symmetric_set && mat->symmetric) {
8395     ierr = MatSetTransposeNullSpace(mat,nullsp);CHKERRQ(ierr);
8396   }
8397   PetscFunctionReturn(0);
8398 }
8399 
8400 /*@
8401    MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix.
8402 
8403    Logically Collective on Mat and MatNullSpace
8404 
8405    Input Parameters:
8406 +  mat - the matrix
8407 -  nullsp - the null space object
8408 
8409    Level: developer
8410 
8411    Concepts: null space^attaching to matrix
8412 
8413 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace()
8414 @*/
8415 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp)
8416 {
8417   PetscFunctionBegin;
8418   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8419   PetscValidType(mat,1);
8420   PetscValidPointer(nullsp,2);
8421   *nullsp = (mat->symmetric_set && mat->symmetric && !mat->transnullsp) ? mat->nullsp : mat->transnullsp;
8422   PetscFunctionReturn(0);
8423 }
8424 
8425 /*@
8426    MatSetTransposeNullSpace - attaches a null space to a matrix.
8427 
8428    Logically Collective on Mat and MatNullSpace
8429 
8430    Input Parameters:
8431 +  mat - the matrix
8432 -  nullsp - the null space object
8433 
8434    Level: advanced
8435 
8436    Notes:
8437       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.
8438       You must also call MatSetNullSpace()
8439 
8440 
8441       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8442    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).
8443    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
8444    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
8445    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).
8446 
8447       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8448 
8449    Concepts: null space^attaching to matrix
8450 
8451 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8452 @*/
8453 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp)
8454 {
8455   PetscErrorCode ierr;
8456 
8457   PetscFunctionBegin;
8458   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8459   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8460   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8461   ierr = MatNullSpaceDestroy(&mat->transnullsp);CHKERRQ(ierr);
8462   mat->transnullsp = nullsp;
8463   PetscFunctionReturn(0);
8464 }
8465 
8466 /*@
8467    MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions
8468         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.
8469 
8470    Logically Collective on Mat and MatNullSpace
8471 
8472    Input Parameters:
8473 +  mat - the matrix
8474 -  nullsp - the null space object
8475 
8476    Level: advanced
8477 
8478    Notes:
8479       Overwrites any previous near null space that may have been attached
8480 
8481       You can remove the null space by calling this routine with an nullsp of NULL
8482 
8483    Concepts: null space^attaching to matrix
8484 
8485 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace()
8486 @*/
8487 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
8488 {
8489   PetscErrorCode ierr;
8490 
8491   PetscFunctionBegin;
8492   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8493   PetscValidType(mat,1);
8494   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8495   MatCheckPreallocated(mat,1);
8496   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8497   ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr);
8498   mat->nearnullsp = nullsp;
8499   PetscFunctionReturn(0);
8500 }
8501 
8502 /*@
8503    MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()
8504 
8505    Not Collective
8506 
8507    Input Parameters:
8508 .  mat - the matrix
8509 
8510    Output Parameters:
8511 .  nullsp - the null space object, NULL if not set
8512 
8513    Level: developer
8514 
8515    Concepts: null space^attaching to matrix
8516 
8517 .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate()
8518 @*/
8519 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
8520 {
8521   PetscFunctionBegin;
8522   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8523   PetscValidType(mat,1);
8524   PetscValidPointer(nullsp,2);
8525   MatCheckPreallocated(mat,1);
8526   *nullsp = mat->nearnullsp;
8527   PetscFunctionReturn(0);
8528 }
8529 
8530 /*@C
8531    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
8532 
8533    Collective on Mat
8534 
8535    Input Parameters:
8536 +  mat - the matrix
8537 .  row - row/column permutation
8538 .  fill - expected fill factor >= 1.0
8539 -  level - level of fill, for ICC(k)
8540 
8541    Notes:
8542    Probably really in-place only when level of fill is zero, otherwise allocates
8543    new space to store factored matrix and deletes previous memory.
8544 
8545    Most users should employ the simplified KSP interface for linear solvers
8546    instead of working directly with matrix algebra routines such as this.
8547    See, e.g., KSPCreate().
8548 
8549    Level: developer
8550 
8551    Concepts: matrices^incomplete Cholesky factorization
8552    Concepts: Cholesky factorization
8553 
8554 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
8555 
8556     Developer Note: fortran interface is not autogenerated as the f90
8557     interface defintion cannot be generated correctly [due to MatFactorInfo]
8558 
8559 @*/
8560 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
8561 {
8562   PetscErrorCode ierr;
8563 
8564   PetscFunctionBegin;
8565   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8566   PetscValidType(mat,1);
8567   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
8568   PetscValidPointer(info,3);
8569   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
8570   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8571   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8572   if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8573   MatCheckPreallocated(mat,1);
8574   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
8575   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8576   PetscFunctionReturn(0);
8577 }
8578 
8579 /*@
8580    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
8581          ghosted ones.
8582 
8583    Not Collective
8584 
8585    Input Parameters:
8586 +  mat - the matrix
8587 -  diag = the diagonal values, including ghost ones
8588 
8589    Level: developer
8590 
8591    Notes:
8592     Works only for MPIAIJ and MPIBAIJ matrices
8593 
8594 .seealso: MatDiagonalScale()
8595 @*/
8596 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
8597 {
8598   PetscErrorCode ierr;
8599   PetscMPIInt    size;
8600 
8601   PetscFunctionBegin;
8602   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8603   PetscValidHeaderSpecific(diag,VEC_CLASSID,2);
8604   PetscValidType(mat,1);
8605 
8606   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8607   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8608   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
8609   if (size == 1) {
8610     PetscInt n,m;
8611     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
8612     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
8613     if (m == n) {
8614       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
8615     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
8616   } else {
8617     ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr);
8618   }
8619   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8620   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8621   PetscFunctionReturn(0);
8622 }
8623 
8624 /*@
8625    MatGetInertia - Gets the inertia from a factored matrix
8626 
8627    Collective on Mat
8628 
8629    Input Parameter:
8630 .  mat - the matrix
8631 
8632    Output Parameters:
8633 +   nneg - number of negative eigenvalues
8634 .   nzero - number of zero eigenvalues
8635 -   npos - number of positive eigenvalues
8636 
8637    Level: advanced
8638 
8639    Notes:
8640     Matrix must have been factored by MatCholeskyFactor()
8641 
8642 
8643 @*/
8644 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
8645 {
8646   PetscErrorCode ierr;
8647 
8648   PetscFunctionBegin;
8649   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8650   PetscValidType(mat,1);
8651   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8652   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
8653   if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8654   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
8655   PetscFunctionReturn(0);
8656 }
8657 
8658 /* ----------------------------------------------------------------*/
8659 /*@C
8660    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
8661 
8662    Neighbor-wise Collective on Mat and Vecs
8663 
8664    Input Parameters:
8665 +  mat - the factored matrix
8666 -  b - the right-hand-side vectors
8667 
8668    Output Parameter:
8669 .  x - the result vectors
8670 
8671    Notes:
8672    The vectors b and x cannot be the same.  I.e., one cannot
8673    call MatSolves(A,x,x).
8674 
8675    Notes:
8676    Most users should employ the simplified KSP interface for linear solvers
8677    instead of working directly with matrix algebra routines such as this.
8678    See, e.g., KSPCreate().
8679 
8680    Level: developer
8681 
8682    Concepts: matrices^triangular solves
8683 
8684 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
8685 @*/
8686 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
8687 {
8688   PetscErrorCode ierr;
8689 
8690   PetscFunctionBegin;
8691   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8692   PetscValidType(mat,1);
8693   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
8694   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8695   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
8696 
8697   if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8698   MatCheckPreallocated(mat,1);
8699   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8700   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
8701   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8702   PetscFunctionReturn(0);
8703 }
8704 
8705 /*@
8706    MatIsSymmetric - Test whether a matrix is symmetric
8707 
8708    Collective on Mat
8709 
8710    Input Parameter:
8711 +  A - the matrix to test
8712 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
8713 
8714    Output Parameters:
8715 .  flg - the result
8716 
8717    Notes:
8718     For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
8719 
8720    Level: intermediate
8721 
8722    Concepts: matrix^symmetry
8723 
8724 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
8725 @*/
8726 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
8727 {
8728   PetscErrorCode ierr;
8729 
8730   PetscFunctionBegin;
8731   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8732   PetscValidPointer(flg,2);
8733 
8734   if (!A->symmetric_set) {
8735     if (!A->ops->issymmetric) {
8736       MatType mattype;
8737       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8738       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8739     }
8740     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8741     if (!tol) {
8742       A->symmetric_set = PETSC_TRUE;
8743       A->symmetric     = *flg;
8744       if (A->symmetric) {
8745         A->structurally_symmetric_set = PETSC_TRUE;
8746         A->structurally_symmetric     = PETSC_TRUE;
8747       }
8748     }
8749   } else if (A->symmetric) {
8750     *flg = PETSC_TRUE;
8751   } else if (!tol) {
8752     *flg = PETSC_FALSE;
8753   } else {
8754     if (!A->ops->issymmetric) {
8755       MatType mattype;
8756       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8757       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8758     }
8759     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8760   }
8761   PetscFunctionReturn(0);
8762 }
8763 
8764 /*@
8765    MatIsHermitian - Test whether a matrix is Hermitian
8766 
8767    Collective on Mat
8768 
8769    Input Parameter:
8770 +  A - the matrix to test
8771 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
8772 
8773    Output Parameters:
8774 .  flg - the result
8775 
8776    Level: intermediate
8777 
8778    Concepts: matrix^symmetry
8779 
8780 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
8781           MatIsSymmetricKnown(), MatIsSymmetric()
8782 @*/
8783 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
8784 {
8785   PetscErrorCode ierr;
8786 
8787   PetscFunctionBegin;
8788   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8789   PetscValidPointer(flg,2);
8790 
8791   if (!A->hermitian_set) {
8792     if (!A->ops->ishermitian) {
8793       MatType mattype;
8794       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8795       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8796     }
8797     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8798     if (!tol) {
8799       A->hermitian_set = PETSC_TRUE;
8800       A->hermitian     = *flg;
8801       if (A->hermitian) {
8802         A->structurally_symmetric_set = PETSC_TRUE;
8803         A->structurally_symmetric     = PETSC_TRUE;
8804       }
8805     }
8806   } else if (A->hermitian) {
8807     *flg = PETSC_TRUE;
8808   } else if (!tol) {
8809     *flg = PETSC_FALSE;
8810   } else {
8811     if (!A->ops->ishermitian) {
8812       MatType mattype;
8813       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8814       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8815     }
8816     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8817   }
8818   PetscFunctionReturn(0);
8819 }
8820 
8821 /*@
8822    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
8823 
8824    Not Collective
8825 
8826    Input Parameter:
8827 .  A - the matrix to check
8828 
8829    Output Parameters:
8830 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
8831 -  flg - the result
8832 
8833    Level: advanced
8834 
8835    Concepts: matrix^symmetry
8836 
8837    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
8838          if you want it explicitly checked
8839 
8840 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8841 @*/
8842 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8843 {
8844   PetscFunctionBegin;
8845   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8846   PetscValidPointer(set,2);
8847   PetscValidPointer(flg,3);
8848   if (A->symmetric_set) {
8849     *set = PETSC_TRUE;
8850     *flg = A->symmetric;
8851   } else {
8852     *set = PETSC_FALSE;
8853   }
8854   PetscFunctionReturn(0);
8855 }
8856 
8857 /*@
8858    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
8859 
8860    Not Collective
8861 
8862    Input Parameter:
8863 .  A - the matrix to check
8864 
8865    Output Parameters:
8866 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8867 -  flg - the result
8868 
8869    Level: advanced
8870 
8871    Concepts: matrix^symmetry
8872 
8873    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8874          if you want it explicitly checked
8875 
8876 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8877 @*/
8878 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8879 {
8880   PetscFunctionBegin;
8881   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8882   PetscValidPointer(set,2);
8883   PetscValidPointer(flg,3);
8884   if (A->hermitian_set) {
8885     *set = PETSC_TRUE;
8886     *flg = A->hermitian;
8887   } else {
8888     *set = PETSC_FALSE;
8889   }
8890   PetscFunctionReturn(0);
8891 }
8892 
8893 /*@
8894    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
8895 
8896    Collective on Mat
8897 
8898    Input Parameter:
8899 .  A - the matrix to test
8900 
8901    Output Parameters:
8902 .  flg - the result
8903 
8904    Level: intermediate
8905 
8906    Concepts: matrix^symmetry
8907 
8908 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8909 @*/
8910 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
8911 {
8912   PetscErrorCode ierr;
8913 
8914   PetscFunctionBegin;
8915   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8916   PetscValidPointer(flg,2);
8917   if (!A->structurally_symmetric_set) {
8918     if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8919     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
8920 
8921     A->structurally_symmetric_set = PETSC_TRUE;
8922   }
8923   *flg = A->structurally_symmetric;
8924   PetscFunctionReturn(0);
8925 }
8926 
8927 /*@
8928    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8929        to be communicated to other processors during the MatAssemblyBegin/End() process
8930 
8931     Not collective
8932 
8933    Input Parameter:
8934 .   vec - the vector
8935 
8936    Output Parameters:
8937 +   nstash   - the size of the stash
8938 .   reallocs - the number of additional mallocs incurred.
8939 .   bnstash   - the size of the block stash
8940 -   breallocs - the number of additional mallocs incurred.in the block stash
8941 
8942    Level: advanced
8943 
8944 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
8945 
8946 @*/
8947 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8948 {
8949   PetscErrorCode ierr;
8950 
8951   PetscFunctionBegin;
8952   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
8953   ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
8954   PetscFunctionReturn(0);
8955 }
8956 
8957 /*@C
8958    MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same
8959      parallel layout
8960 
8961    Collective on Mat
8962 
8963    Input Parameter:
8964 .  mat - the matrix
8965 
8966    Output Parameter:
8967 +   right - (optional) vector that the matrix can be multiplied against
8968 -   left - (optional) vector that the matrix vector product can be stored in
8969 
8970    Notes:
8971     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().
8972 
8973   Notes:
8974     These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed
8975 
8976   Level: advanced
8977 
8978 .seealso: MatCreate(), VecDestroy()
8979 @*/
8980 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left)
8981 {
8982   PetscErrorCode ierr;
8983 
8984   PetscFunctionBegin;
8985   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8986   PetscValidType(mat,1);
8987   if (mat->ops->getvecs) {
8988     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
8989   } else {
8990     PetscInt rbs,cbs;
8991     ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr);
8992     if (right) {
8993       if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup");
8994       ierr = VecCreate(PetscObjectComm((PetscObject)mat),right);CHKERRQ(ierr);
8995       ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8996       ierr = VecSetBlockSize(*right,cbs);CHKERRQ(ierr);
8997       ierr = VecSetType(*right,mat->defaultvectype);CHKERRQ(ierr);
8998       ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr);
8999     }
9000     if (left) {
9001       if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup");
9002       ierr = VecCreate(PetscObjectComm((PetscObject)mat),left);CHKERRQ(ierr);
9003       ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
9004       ierr = VecSetBlockSize(*left,rbs);CHKERRQ(ierr);
9005       ierr = VecSetType(*left,mat->defaultvectype);CHKERRQ(ierr);
9006       ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr);
9007     }
9008   }
9009   PetscFunctionReturn(0);
9010 }
9011 
9012 /*@C
9013    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
9014      with default values.
9015 
9016    Not Collective
9017 
9018    Input Parameters:
9019 .    info - the MatFactorInfo data structure
9020 
9021 
9022    Notes:
9023     The solvers are generally used through the KSP and PC objects, for example
9024           PCLU, PCILU, PCCHOLESKY, PCICC
9025 
9026    Level: developer
9027 
9028 .seealso: MatFactorInfo
9029 
9030     Developer Note: fortran interface is not autogenerated as the f90
9031     interface defintion cannot be generated correctly [due to MatFactorInfo]
9032 
9033 @*/
9034 
9035 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
9036 {
9037   PetscErrorCode ierr;
9038 
9039   PetscFunctionBegin;
9040   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
9041   PetscFunctionReturn(0);
9042 }
9043 
9044 /*@
9045    MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed
9046 
9047    Collective on Mat
9048 
9049    Input Parameters:
9050 +  mat - the factored matrix
9051 -  is - the index set defining the Schur indices (0-based)
9052 
9053    Notes:
9054     Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system.
9055 
9056    You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call.
9057 
9058    Level: developer
9059 
9060    Concepts:
9061 
9062 .seealso: MatGetFactor(), MatFactorGetSchurComplement(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSolveSchurComplement(),
9063           MatFactorSolveSchurComplementTranspose(), MatFactorSolveSchurComplement()
9064 
9065 @*/
9066 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is)
9067 {
9068   PetscErrorCode ierr,(*f)(Mat,IS);
9069 
9070   PetscFunctionBegin;
9071   PetscValidType(mat,1);
9072   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9073   PetscValidType(is,2);
9074   PetscValidHeaderSpecific(is,IS_CLASSID,2);
9075   PetscCheckSameComm(mat,1,is,2);
9076   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
9077   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);CHKERRQ(ierr);
9078   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");
9079   if (mat->schur) {
9080     ierr = MatDestroy(&mat->schur);CHKERRQ(ierr);
9081   }
9082   ierr = (*f)(mat,is);CHKERRQ(ierr);
9083   if (!mat->schur) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created");
9084   ierr = MatFactorSetUpInPlaceSchur_Private(mat);CHKERRQ(ierr);
9085   PetscFunctionReturn(0);
9086 }
9087 
9088 /*@
9089   MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step
9090 
9091    Logically Collective on Mat
9092 
9093    Input Parameters:
9094 +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
9095 .  S - location where to return the Schur complement, can be NULL
9096 -  status - the status of the Schur complement matrix, can be NULL
9097 
9098    Notes:
9099    You must call MatFactorSetSchurIS() before calling this routine.
9100 
9101    The routine provides a copy of the Schur matrix stored within the solver data structures.
9102    The caller must destroy the object when it is no longer needed.
9103    If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse.
9104 
9105    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)
9106 
9107    Developer Notes:
9108     The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc
9109    matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix.
9110 
9111    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
9112 
9113    Level: advanced
9114 
9115    References:
9116 
9117 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorSchurStatus
9118 @*/
9119 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
9120 {
9121   PetscErrorCode ierr;
9122 
9123   PetscFunctionBegin;
9124   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9125   if (S) PetscValidPointer(S,2);
9126   if (status) PetscValidPointer(status,3);
9127   if (S) {
9128     PetscErrorCode (*f)(Mat,Mat*);
9129 
9130     ierr = PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f);CHKERRQ(ierr);
9131     if (f) {
9132       ierr = (*f)(F,S);CHKERRQ(ierr);
9133     } else {
9134       ierr = MatDuplicate(F->schur,MAT_COPY_VALUES,S);CHKERRQ(ierr);
9135     }
9136   }
9137   if (status) *status = F->schur_status;
9138   PetscFunctionReturn(0);
9139 }
9140 
9141 /*@
9142   MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix
9143 
9144    Logically Collective on Mat
9145 
9146    Input Parameters:
9147 +  F - the factored matrix obtained by calling MatGetFactor()
9148 .  *S - location where to return the Schur complement, can be NULL
9149 -  status - the status of the Schur complement matrix, can be NULL
9150 
9151    Notes:
9152    You must call MatFactorSetSchurIS() before calling this routine.
9153 
9154    Schur complement mode is currently implemented for sequential matrices.
9155    The routine returns a the Schur Complement stored within the data strutures of the solver.
9156    If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement.
9157    The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed.
9158 
9159    Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix
9160 
9161    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
9162 
9163    Level: advanced
9164 
9165    References:
9166 
9167 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
9168 @*/
9169 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
9170 {
9171   PetscFunctionBegin;
9172   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9173   if (S) PetscValidPointer(S,2);
9174   if (status) PetscValidPointer(status,3);
9175   if (S) *S = F->schur;
9176   if (status) *status = F->schur_status;
9177   PetscFunctionReturn(0);
9178 }
9179 
9180 /*@
9181   MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement
9182 
9183    Logically Collective on Mat
9184 
9185    Input Parameters:
9186 +  F - the factored matrix obtained by calling MatGetFactor()
9187 .  *S - location where the Schur complement is stored
9188 -  status - the status of the Schur complement matrix (see MatFactorSchurStatus)
9189 
9190    Notes:
9191 
9192    Level: advanced
9193 
9194    References:
9195 
9196 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
9197 @*/
9198 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status)
9199 {
9200   PetscErrorCode ierr;
9201 
9202   PetscFunctionBegin;
9203   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9204   if (S) {
9205     PetscValidHeaderSpecific(*S,MAT_CLASSID,2);
9206     *S = NULL;
9207   }
9208   F->schur_status = status;
9209   ierr = MatFactorUpdateSchurStatus_Private(F);CHKERRQ(ierr);
9210   PetscFunctionReturn(0);
9211 }
9212 
9213 /*@
9214   MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step
9215 
9216    Logically Collective on Mat
9217 
9218    Input Parameters:
9219 +  F - the factored matrix obtained by calling MatGetFactor()
9220 .  rhs - location where the right hand side of the Schur complement system is stored
9221 -  sol - location where the solution of the Schur complement system has to be returned
9222 
9223    Notes:
9224    The sizes of the vectors should match the size of the Schur complement
9225 
9226    Must be called after MatFactorSetSchurIS()
9227 
9228    Level: advanced
9229 
9230    References:
9231 
9232 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplement()
9233 @*/
9234 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol)
9235 {
9236   PetscErrorCode ierr;
9237 
9238   PetscFunctionBegin;
9239   PetscValidType(F,1);
9240   PetscValidType(rhs,2);
9241   PetscValidType(sol,3);
9242   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9243   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
9244   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
9245   PetscCheckSameComm(F,1,rhs,2);
9246   PetscCheckSameComm(F,1,sol,3);
9247   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9248   switch (F->schur_status) {
9249   case MAT_FACTOR_SCHUR_FACTORED:
9250     ierr = MatSolveTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
9251     break;
9252   case MAT_FACTOR_SCHUR_INVERTED:
9253     ierr = MatMultTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
9254     break;
9255   default:
9256     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9257     break;
9258   }
9259   PetscFunctionReturn(0);
9260 }
9261 
9262 /*@
9263   MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step
9264 
9265    Logically Collective on Mat
9266 
9267    Input Parameters:
9268 +  F - the factored matrix obtained by calling MatGetFactor()
9269 .  rhs - location where the right hand side of the Schur complement system is stored
9270 -  sol - location where the solution of the Schur complement system has to be returned
9271 
9272    Notes:
9273    The sizes of the vectors should match the size of the Schur complement
9274 
9275    Must be called after MatFactorSetSchurIS()
9276 
9277    Level: advanced
9278 
9279    References:
9280 
9281 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplementTranspose()
9282 @*/
9283 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol)
9284 {
9285   PetscErrorCode ierr;
9286 
9287   PetscFunctionBegin;
9288   PetscValidType(F,1);
9289   PetscValidType(rhs,2);
9290   PetscValidType(sol,3);
9291   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9292   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
9293   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
9294   PetscCheckSameComm(F,1,rhs,2);
9295   PetscCheckSameComm(F,1,sol,3);
9296   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9297   switch (F->schur_status) {
9298   case MAT_FACTOR_SCHUR_FACTORED:
9299     ierr = MatSolve(F->schur,rhs,sol);CHKERRQ(ierr);
9300     break;
9301   case MAT_FACTOR_SCHUR_INVERTED:
9302     ierr = MatMult(F->schur,rhs,sol);CHKERRQ(ierr);
9303     break;
9304   default:
9305     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9306     break;
9307   }
9308   PetscFunctionReturn(0);
9309 }
9310 
9311 /*@
9312   MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step
9313 
9314    Logically Collective on Mat
9315 
9316    Input Parameters:
9317 +  F - the factored matrix obtained by calling MatGetFactor()
9318 
9319    Notes:
9320     Must be called after MatFactorSetSchurIS().
9321 
9322    Call MatFactorGetSchurComplement() or  MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it.
9323 
9324    Level: advanced
9325 
9326    References:
9327 
9328 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorCreateSchurComplement()
9329 @*/
9330 PetscErrorCode MatFactorInvertSchurComplement(Mat F)
9331 {
9332   PetscErrorCode ierr;
9333 
9334   PetscFunctionBegin;
9335   PetscValidType(F,1);
9336   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9337   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0);
9338   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9339   ierr = MatFactorInvertSchurComplement_Private(F);CHKERRQ(ierr);
9340   F->schur_status = MAT_FACTOR_SCHUR_INVERTED;
9341   PetscFunctionReturn(0);
9342 }
9343 
9344 /*@
9345   MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step
9346 
9347    Logically Collective on Mat
9348 
9349    Input Parameters:
9350 +  F - the factored matrix obtained by calling MatGetFactor()
9351 
9352    Notes:
9353     Must be called after MatFactorSetSchurIS().
9354 
9355    Level: advanced
9356 
9357    References:
9358 
9359 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorInvertSchurComplement()
9360 @*/
9361 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F)
9362 {
9363   PetscErrorCode ierr;
9364 
9365   PetscFunctionBegin;
9366   PetscValidType(F,1);
9367   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9368   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0);
9369   ierr = MatFactorFactorizeSchurComplement_Private(F);CHKERRQ(ierr);
9370   F->schur_status = MAT_FACTOR_SCHUR_FACTORED;
9371   PetscFunctionReturn(0);
9372 }
9373 
9374 /*@
9375    MatPtAP - Creates the matrix product C = P^T * A * P
9376 
9377    Neighbor-wise Collective on Mat
9378 
9379    Input Parameters:
9380 +  A - the matrix
9381 .  P - the projection matrix
9382 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9383 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate
9384           if the result is a dense matrix this is irrelevent
9385 
9386    Output Parameters:
9387 .  C - the product matrix
9388 
9389    Notes:
9390    C will be created and must be destroyed by the user with MatDestroy().
9391 
9392    This routine is currently only implemented for pairs of sequential dense matrices, AIJ matrices and classes
9393    which inherit from AIJ.
9394 
9395    Level: intermediate
9396 
9397 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
9398 @*/
9399 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
9400 {
9401   PetscErrorCode ierr;
9402   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9403   PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
9404   PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9405   PetscBool      sametype;
9406 
9407   PetscFunctionBegin;
9408   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9409   PetscValidType(A,1);
9410   MatCheckPreallocated(A,1);
9411   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9412   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9413   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9414   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9415   PetscValidType(P,2);
9416   MatCheckPreallocated(P,2);
9417   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9418   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9419 
9420   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);
9421   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);
9422   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9423   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9424 
9425   if (scall == MAT_REUSE_MATRIX) {
9426     PetscValidPointer(*C,5);
9427     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9428 
9429     if (!(*C)->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You cannot use MAT_REUSE_MATRIX");
9430     ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9431     ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9432     ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr);
9433     ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9434     ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9435     PetscFunctionReturn(0);
9436   }
9437 
9438   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9439   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9440 
9441   fA = A->ops->ptap;
9442   fP = P->ops->ptap;
9443   ierr = PetscStrcmp(((PetscObject)A)->type_name,((PetscObject)P)->type_name,&sametype);CHKERRQ(ierr);
9444   if (fP == fA && sametype) {
9445     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name);
9446     ptap = fA;
9447   } else {
9448     /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
9449     char ptapname[256];
9450     ierr = PetscStrncpy(ptapname,"MatPtAP_",sizeof(ptapname));CHKERRQ(ierr);
9451     ierr = PetscStrlcat(ptapname,((PetscObject)A)->type_name,sizeof(ptapname));CHKERRQ(ierr);
9452     ierr = PetscStrlcat(ptapname,"_",sizeof(ptapname));CHKERRQ(ierr);
9453     ierr = PetscStrlcat(ptapname,((PetscObject)P)->type_name,sizeof(ptapname));CHKERRQ(ierr);
9454     ierr = PetscStrlcat(ptapname,"_C",sizeof(ptapname));CHKERRQ(ierr); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
9455     ierr = PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);CHKERRQ(ierr);
9456     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);
9457   }
9458 
9459   ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9460   ierr = (*ptap)(A,P,scall,fill,C);CHKERRQ(ierr);
9461   ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9462   if (A->symmetric_set && A->symmetric) {
9463     ierr = MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
9464   }
9465   PetscFunctionReturn(0);
9466 }
9467 
9468 /*@
9469    MatPtAPNumeric - Computes the matrix product C = P^T * A * P
9470 
9471    Neighbor-wise Collective on Mat
9472 
9473    Input Parameters:
9474 +  A - the matrix
9475 -  P - the projection matrix
9476 
9477    Output Parameters:
9478 .  C - the product matrix
9479 
9480    Notes:
9481    C must have been created by calling MatPtAPSymbolic and must be destroyed by
9482    the user using MatDeatroy().
9483 
9484    This routine is currently only implemented for pairs of AIJ matrices and classes
9485    which inherit from AIJ.  C will be of type MATAIJ.
9486 
9487    Level: intermediate
9488 
9489 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
9490 @*/
9491 PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C)
9492 {
9493   PetscErrorCode ierr;
9494 
9495   PetscFunctionBegin;
9496   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9497   PetscValidType(A,1);
9498   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9499   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9500   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9501   PetscValidType(P,2);
9502   MatCheckPreallocated(P,2);
9503   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9504   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9505   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9506   PetscValidType(C,3);
9507   MatCheckPreallocated(C,3);
9508   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9509   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);
9510   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);
9511   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);
9512   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);
9513   MatCheckPreallocated(A,1);
9514 
9515   if (!C->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You should call MatPtAPSymbolic first");
9516   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9517   ierr = (*C->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr);
9518   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9519   PetscFunctionReturn(0);
9520 }
9521 
9522 /*@
9523    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P
9524 
9525    Neighbor-wise Collective on Mat
9526 
9527    Input Parameters:
9528 +  A - the matrix
9529 -  P - the projection matrix
9530 
9531    Output Parameters:
9532 .  C - the (i,j) structure of the product matrix
9533 
9534    Notes:
9535    C will be created and must be destroyed by the user with MatDestroy().
9536 
9537    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9538    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9539    this (i,j) structure by calling MatPtAPNumeric().
9540 
9541    Level: intermediate
9542 
9543 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
9544 @*/
9545 PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
9546 {
9547   PetscErrorCode ierr;
9548 
9549   PetscFunctionBegin;
9550   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9551   PetscValidType(A,1);
9552   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9553   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9554   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9555   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9556   PetscValidType(P,2);
9557   MatCheckPreallocated(P,2);
9558   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9559   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9560   PetscValidPointer(C,3);
9561 
9562   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);
9563   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);
9564   MatCheckPreallocated(A,1);
9565 
9566   if (!A->ops->ptapsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatType %s",((PetscObject)A)->type_name);
9567   ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
9568   ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr);
9569   ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
9570 
9571   /* ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); NO! this is not always true -ma */
9572   PetscFunctionReturn(0);
9573 }
9574 
9575 /*@
9576    MatRARt - Creates the matrix product C = R * A * R^T
9577 
9578    Neighbor-wise Collective on Mat
9579 
9580    Input Parameters:
9581 +  A - the matrix
9582 .  R - the projection matrix
9583 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9584 -  fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate
9585           if the result is a dense matrix this is irrelevent
9586 
9587    Output Parameters:
9588 .  C - the product matrix
9589 
9590    Notes:
9591    C will be created and must be destroyed by the user with MatDestroy().
9592 
9593    This routine is currently only implemented for pairs of AIJ matrices and classes
9594    which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes,
9595    parallel MatRARt is implemented via explicit transpose of R, which could be very expensive.
9596    We recommend using MatPtAP().
9597 
9598    Level: intermediate
9599 
9600 .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
9601 @*/
9602 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
9603 {
9604   PetscErrorCode ierr;
9605 
9606   PetscFunctionBegin;
9607   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9608   PetscValidType(A,1);
9609   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9610   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9611   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9612   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9613   PetscValidType(R,2);
9614   MatCheckPreallocated(R,2);
9615   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9616   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9617   PetscValidPointer(C,3);
9618   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);
9619 
9620   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9621   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9622   MatCheckPreallocated(A,1);
9623 
9624   if (!A->ops->rart) {
9625     Mat Rt;
9626     ierr = MatTranspose(R,MAT_INITIAL_MATRIX,&Rt);CHKERRQ(ierr);
9627     ierr = MatMatMatMult(R,A,Rt,scall,fill,C);CHKERRQ(ierr);
9628     ierr = MatDestroy(&Rt);CHKERRQ(ierr);
9629     PetscFunctionReturn(0);
9630   }
9631   ierr = PetscLogEventBegin(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
9632   ierr = (*A->ops->rart)(A,R,scall,fill,C);CHKERRQ(ierr);
9633   ierr = PetscLogEventEnd(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
9634   PetscFunctionReturn(0);
9635 }
9636 
9637 /*@
9638    MatRARtNumeric - Computes the matrix product C = R * A * R^T
9639 
9640    Neighbor-wise Collective on Mat
9641 
9642    Input Parameters:
9643 +  A - the matrix
9644 -  R - the projection matrix
9645 
9646    Output Parameters:
9647 .  C - the product matrix
9648 
9649    Notes:
9650    C must have been created by calling MatRARtSymbolic and must be destroyed by
9651    the user using MatDestroy().
9652 
9653    This routine is currently only implemented for pairs of AIJ matrices and classes
9654    which inherit from AIJ.  C will be of type MATAIJ.
9655 
9656    Level: intermediate
9657 
9658 .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
9659 @*/
9660 PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C)
9661 {
9662   PetscErrorCode ierr;
9663 
9664   PetscFunctionBegin;
9665   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9666   PetscValidType(A,1);
9667   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9668   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9669   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9670   PetscValidType(R,2);
9671   MatCheckPreallocated(R,2);
9672   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9673   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9674   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9675   PetscValidType(C,3);
9676   MatCheckPreallocated(C,3);
9677   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9678   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);
9679   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);
9680   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);
9681   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);
9682   MatCheckPreallocated(A,1);
9683 
9684   ierr = PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
9685   ierr = (*A->ops->rartnumeric)(A,R,C);CHKERRQ(ierr);
9686   ierr = PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
9687   PetscFunctionReturn(0);
9688 }
9689 
9690 /*@
9691    MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T
9692 
9693    Neighbor-wise Collective on Mat
9694 
9695    Input Parameters:
9696 +  A - the matrix
9697 -  R - the projection matrix
9698 
9699    Output Parameters:
9700 .  C - the (i,j) structure of the product matrix
9701 
9702    Notes:
9703    C will be created and must be destroyed by the user with MatDestroy().
9704 
9705    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9706    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9707    this (i,j) structure by calling MatRARtNumeric().
9708 
9709    Level: intermediate
9710 
9711 .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
9712 @*/
9713 PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
9714 {
9715   PetscErrorCode ierr;
9716 
9717   PetscFunctionBegin;
9718   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9719   PetscValidType(A,1);
9720   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9721   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9722   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9723   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9724   PetscValidType(R,2);
9725   MatCheckPreallocated(R,2);
9726   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9727   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9728   PetscValidPointer(C,3);
9729 
9730   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);
9731   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);
9732   MatCheckPreallocated(A,1);
9733   ierr = PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
9734   ierr = (*A->ops->rartsymbolic)(A,R,fill,C);CHKERRQ(ierr);
9735   ierr = PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
9736 
9737   ierr = MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));CHKERRQ(ierr);
9738   PetscFunctionReturn(0);
9739 }
9740 
9741 /*@
9742    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
9743 
9744    Neighbor-wise Collective on Mat
9745 
9746    Input Parameters:
9747 +  A - the left matrix
9748 .  B - the right matrix
9749 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9750 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
9751           if the result is a dense matrix this is irrelevent
9752 
9753    Output Parameters:
9754 .  C - the product matrix
9755 
9756    Notes:
9757    Unless scall is MAT_REUSE_MATRIX C will be created.
9758 
9759    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
9760    call to this function with either MAT_INITIAL_MATRIX or MatMatMultSymbolic()
9761 
9762    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9763    actually needed.
9764 
9765    If you have many matrices with the same non-zero structure to multiply, you
9766    should either
9767 $   1) use MAT_REUSE_MATRIX in all calls but the first or
9768 $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
9769    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
9770    with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse.
9771 
9772    Level: intermediate
9773 
9774 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(),  MatMatTransposeMult(), MatPtAP()
9775 @*/
9776 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9777 {
9778   PetscErrorCode ierr;
9779   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9780   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9781   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9782 
9783   PetscFunctionBegin;
9784   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9785   PetscValidType(A,1);
9786   MatCheckPreallocated(A,1);
9787   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9788   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9789   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9790   PetscValidType(B,2);
9791   MatCheckPreallocated(B,2);
9792   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9793   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9794   PetscValidPointer(C,3);
9795   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9796   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);
9797   if (scall == MAT_REUSE_MATRIX) {
9798     PetscValidPointer(*C,5);
9799     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9800     ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9801     ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9802     ierr = (*(*C)->ops->matmultnumeric)(A,B,*C);CHKERRQ(ierr);
9803     ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9804     ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9805     PetscFunctionReturn(0);
9806   }
9807   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9808   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9809 
9810   fA = A->ops->matmult;
9811   fB = B->ops->matmult;
9812   if (fB == fA) {
9813     if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
9814     mult = fB;
9815   } else {
9816     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9817     char multname[256];
9818     ierr = PetscStrncpy(multname,"MatMatMult_",sizeof(multname));CHKERRQ(ierr);
9819     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
9820     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
9821     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
9822     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9823     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
9824     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);
9825   }
9826   ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9827   ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr);
9828   ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9829   PetscFunctionReturn(0);
9830 }
9831 
9832 /*@
9833    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
9834    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().
9835 
9836    Neighbor-wise Collective on Mat
9837 
9838    Input Parameters:
9839 +  A - the left matrix
9840 .  B - the right matrix
9841 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
9842       if C is a dense matrix this is irrelevent
9843 
9844    Output Parameters:
9845 .  C - the product matrix
9846 
9847    Notes:
9848    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9849    actually needed.
9850 
9851    This routine is currently implemented for
9852     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
9853     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9854     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9855 
9856    Level: intermediate
9857 
9858    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
9859      We should incorporate them into PETSc.
9860 
9861 .seealso: MatMatMult(), MatMatMultNumeric()
9862 @*/
9863 PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
9864 {
9865   PetscErrorCode ierr;
9866   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*);
9867   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*);
9868   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL;
9869 
9870   PetscFunctionBegin;
9871   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9872   PetscValidType(A,1);
9873   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9874   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9875 
9876   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9877   PetscValidType(B,2);
9878   MatCheckPreallocated(B,2);
9879   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9880   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9881   PetscValidPointer(C,3);
9882 
9883   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);
9884   if (fill == PETSC_DEFAULT) fill = 2.0;
9885   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9886   MatCheckPreallocated(A,1);
9887 
9888   Asymbolic = A->ops->matmultsymbolic;
9889   Bsymbolic = B->ops->matmultsymbolic;
9890   if (Asymbolic == Bsymbolic) {
9891     if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
9892     symbolic = Bsymbolic;
9893   } else { /* dispatch based on the type of A and B */
9894     char symbolicname[256];
9895     ierr = PetscStrncpy(symbolicname,"MatMatMultSymbolic_",sizeof(symbolicname));CHKERRQ(ierr);
9896     ierr = PetscStrlcat(symbolicname,((PetscObject)A)->type_name,sizeof(symbolicname));CHKERRQ(ierr);
9897     ierr = PetscStrlcat(symbolicname,"_",sizeof(symbolicname));CHKERRQ(ierr);
9898     ierr = PetscStrlcat(symbolicname,((PetscObject)B)->type_name,sizeof(symbolicname));CHKERRQ(ierr);
9899     ierr = PetscStrlcat(symbolicname,"_C",sizeof(symbolicname));CHKERRQ(ierr);
9900     ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);CHKERRQ(ierr);
9901     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);
9902   }
9903   ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9904   ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr);
9905   ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9906   PetscFunctionReturn(0);
9907 }
9908 
9909 /*@
9910    MatMatMultNumeric - Performs the numeric matrix-matrix product.
9911    Call this routine after first calling MatMatMultSymbolic().
9912 
9913    Neighbor-wise Collective on Mat
9914 
9915    Input Parameters:
9916 +  A - the left matrix
9917 -  B - the right matrix
9918 
9919    Output Parameters:
9920 .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
9921 
9922    Notes:
9923    C must have been created with MatMatMultSymbolic().
9924 
9925    This routine is currently implemented for
9926     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
9927     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9928     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9929 
9930    Level: intermediate
9931 
9932 .seealso: MatMatMult(), MatMatMultSymbolic()
9933 @*/
9934 PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C)
9935 {
9936   PetscErrorCode ierr;
9937 
9938   PetscFunctionBegin;
9939   ierr = MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);CHKERRQ(ierr);
9940   PetscFunctionReturn(0);
9941 }
9942 
9943 /*@
9944    MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.
9945 
9946    Neighbor-wise Collective on Mat
9947 
9948    Input Parameters:
9949 +  A - the left matrix
9950 .  B - the right matrix
9951 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9952 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9953 
9954    Output Parameters:
9955 .  C - the product matrix
9956 
9957    Notes:
9958    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9959 
9960    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9961 
9962   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9963    actually needed.
9964 
9965    This routine is currently only implemented for pairs of SeqAIJ matrices, for the SeqDense class,
9966    and for pairs of MPIDense matrices.
9967 
9968    Options Database Keys:
9969 +  -matmattransmult_mpidense_mpidense_via {allgatherv,cyclic} - Choose between algorthims for MPIDense matrices: the
9970                                                                 first redundantly copies the transposed B matrix on each process and requiers O(log P) communication complexity;
9971                                                                 the second never stores more than one portion of the B matrix at a time by requires O(P) communication complexity.
9972 
9973    Level: intermediate
9974 
9975 .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
9976 @*/
9977 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9978 {
9979   PetscErrorCode ierr;
9980   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9981   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9982 
9983   PetscFunctionBegin;
9984   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9985   PetscValidType(A,1);
9986   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9987   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9988   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9989   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9990   PetscValidType(B,2);
9991   MatCheckPreallocated(B,2);
9992   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9993   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9994   PetscValidPointer(C,3);
9995   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);
9996   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9997   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9998   MatCheckPreallocated(A,1);
9999 
10000   fA = A->ops->mattransposemult;
10001   if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
10002   fB = B->ops->mattransposemult;
10003   if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
10004   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);
10005 
10006   ierr = PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
10007   if (scall == MAT_INITIAL_MATRIX) {
10008     ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
10009     ierr = (*A->ops->mattransposemultsymbolic)(A,B,fill,C);CHKERRQ(ierr);
10010     ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
10011   }
10012   ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
10013   ierr = (*A->ops->mattransposemultnumeric)(A,B,*C);CHKERRQ(ierr);
10014   ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
10015   ierr = PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
10016   PetscFunctionReturn(0);
10017 }
10018 
10019 /*@
10020    MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.
10021 
10022    Neighbor-wise Collective on Mat
10023 
10024    Input Parameters:
10025 +  A - the left matrix
10026 .  B - the right matrix
10027 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10028 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
10029 
10030    Output Parameters:
10031 .  C - the product matrix
10032 
10033    Notes:
10034    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
10035 
10036    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
10037 
10038   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
10039    actually needed.
10040 
10041    This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
10042    which inherit from SeqAIJ.  C will be of same type as the input matrices.
10043 
10044    Level: intermediate
10045 
10046 .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
10047 @*/
10048 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
10049 {
10050   PetscErrorCode ierr;
10051   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
10052   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
10053   PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL;
10054 
10055   PetscFunctionBegin;
10056   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
10057   PetscValidType(A,1);
10058   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10059   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10060   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10061   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
10062   PetscValidType(B,2);
10063   MatCheckPreallocated(B,2);
10064   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10065   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10066   PetscValidPointer(C,3);
10067   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);
10068   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
10069   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
10070   MatCheckPreallocated(A,1);
10071 
10072   fA = A->ops->transposematmult;
10073   fB = B->ops->transposematmult;
10074   if (fB==fA) {
10075     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
10076     transposematmult = fA;
10077   } else {
10078     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
10079     char multname[256];
10080     ierr = PetscStrncpy(multname,"MatTransposeMatMult_",sizeof(multname));CHKERRQ(ierr);
10081     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
10082     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
10083     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
10084     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
10085     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);CHKERRQ(ierr);
10086     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);
10087   }
10088   ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
10089   ierr = (*transposematmult)(A,B,scall,fill,C);CHKERRQ(ierr);
10090   ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
10091   PetscFunctionReturn(0);
10092 }
10093 
10094 /*@
10095    MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.
10096 
10097    Neighbor-wise Collective on Mat
10098 
10099    Input Parameters:
10100 +  A - the left matrix
10101 .  B - the middle matrix
10102 .  C - the right matrix
10103 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10104 -  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
10105           if the result is a dense matrix this is irrelevent
10106 
10107    Output Parameters:
10108 .  D - the product matrix
10109 
10110    Notes:
10111    Unless scall is MAT_REUSE_MATRIX D will be created.
10112 
10113    MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call
10114 
10115    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
10116    actually needed.
10117 
10118    If you have many matrices with the same non-zero structure to multiply, you
10119    should use MAT_REUSE_MATRIX in all calls but the first or
10120 
10121    Level: intermediate
10122 
10123 .seealso: MatMatMult, MatPtAP()
10124 @*/
10125 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
10126 {
10127   PetscErrorCode ierr;
10128   PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
10129   PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
10130   PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
10131   PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
10132 
10133   PetscFunctionBegin;
10134   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
10135   PetscValidType(A,1);
10136   MatCheckPreallocated(A,1);
10137   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10138   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10139   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10140   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
10141   PetscValidType(B,2);
10142   MatCheckPreallocated(B,2);
10143   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10144   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10145   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
10146   PetscValidPointer(C,3);
10147   MatCheckPreallocated(C,3);
10148   if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10149   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10150   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);
10151   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);
10152   if (scall == MAT_REUSE_MATRIX) {
10153     PetscValidPointer(*D,6);
10154     PetscValidHeaderSpecific(*D,MAT_CLASSID,6);
10155     ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10156     ierr = (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
10157     ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10158     PetscFunctionReturn(0);
10159   }
10160   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
10161   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
10162 
10163   fA = A->ops->matmatmult;
10164   fB = B->ops->matmatmult;
10165   fC = C->ops->matmatmult;
10166   if (fA == fB && fA == fC) {
10167     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name);
10168     mult = fA;
10169   } else {
10170     /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */
10171     char multname[256];
10172     ierr = PetscStrncpy(multname,"MatMatMatMult_",sizeof(multname));CHKERRQ(ierr);
10173     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
10174     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
10175     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
10176     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
10177     ierr = PetscStrlcat(multname,((PetscObject)C)->type_name,sizeof(multname));CHKERRQ(ierr);
10178     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr);
10179     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
10180     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);
10181   }
10182   ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10183   ierr = (*mult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
10184   ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10185   PetscFunctionReturn(0);
10186 }
10187 
10188 /*@
10189    MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
10190 
10191    Collective on Mat
10192 
10193    Input Parameters:
10194 +  mat - the matrix
10195 .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
10196 .  subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used)
10197 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10198 
10199    Output Parameter:
10200 .  matredundant - redundant matrix
10201 
10202    Notes:
10203    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
10204    original matrix has not changed from that last call to MatCreateRedundantMatrix().
10205 
10206    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
10207    calling it.
10208 
10209    Level: advanced
10210 
10211    Concepts: subcommunicator
10212    Concepts: duplicate matrix
10213 
10214 .seealso: MatDestroy()
10215 @*/
10216 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant)
10217 {
10218   PetscErrorCode ierr;
10219   MPI_Comm       comm;
10220   PetscMPIInt    size;
10221   PetscInt       mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs;
10222   Mat_Redundant  *redund=NULL;
10223   PetscSubcomm   psubcomm=NULL;
10224   MPI_Comm       subcomm_in=subcomm;
10225   Mat            *matseq;
10226   IS             isrow,iscol;
10227   PetscBool      newsubcomm=PETSC_FALSE;
10228 
10229   PetscFunctionBegin;
10230   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10231   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
10232     PetscValidPointer(*matredundant,5);
10233     PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5);
10234   }
10235 
10236   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
10237   if (size == 1 || nsubcomm == 1) {
10238     if (reuse == MAT_INITIAL_MATRIX) {
10239       ierr = MatDuplicate(mat,MAT_COPY_VALUES,matredundant);CHKERRQ(ierr);
10240     } else {
10241       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");
10242       ierr = MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
10243     }
10244     PetscFunctionReturn(0);
10245   }
10246 
10247   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10248   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10249   MatCheckPreallocated(mat,1);
10250 
10251   ierr = PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
10252   if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */
10253     /* create psubcomm, then get subcomm */
10254     ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
10255     ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
10256     if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size);
10257 
10258     ierr = PetscSubcommCreate(comm,&psubcomm);CHKERRQ(ierr);
10259     ierr = PetscSubcommSetNumber(psubcomm,nsubcomm);CHKERRQ(ierr);
10260     ierr = PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);CHKERRQ(ierr);
10261     ierr = PetscSubcommSetFromOptions(psubcomm);CHKERRQ(ierr);
10262     ierr = PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);CHKERRQ(ierr);
10263     newsubcomm = PETSC_TRUE;
10264     ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr);
10265   }
10266 
10267   /* get isrow, iscol and a local sequential matrix matseq[0] */
10268   if (reuse == MAT_INITIAL_MATRIX) {
10269     mloc_sub = PETSC_DECIDE;
10270     nloc_sub = PETSC_DECIDE;
10271     if (bs < 1) {
10272       ierr = PetscSplitOwnership(subcomm,&mloc_sub,&M);CHKERRQ(ierr);
10273       ierr = PetscSplitOwnership(subcomm,&nloc_sub,&N);CHKERRQ(ierr);
10274     } else {
10275       ierr = PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);CHKERRQ(ierr);
10276       ierr = PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N);CHKERRQ(ierr);
10277     }
10278     ierr = MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);CHKERRQ(ierr);
10279     rstart = rend - mloc_sub;
10280     ierr = ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);CHKERRQ(ierr);
10281     ierr = ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);CHKERRQ(ierr);
10282   } else { /* reuse == MAT_REUSE_MATRIX */
10283     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");
10284     /* retrieve subcomm */
10285     ierr = PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);CHKERRQ(ierr);
10286     redund = (*matredundant)->redundant;
10287     isrow  = redund->isrow;
10288     iscol  = redund->iscol;
10289     matseq = redund->matseq;
10290   }
10291   ierr = MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);CHKERRQ(ierr);
10292 
10293   /* get matredundant over subcomm */
10294   if (reuse == MAT_INITIAL_MATRIX) {
10295     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant);CHKERRQ(ierr);
10296 
10297     /* create a supporting struct and attach it to C for reuse */
10298     ierr = PetscNewLog(*matredundant,&redund);CHKERRQ(ierr);
10299     (*matredundant)->redundant = redund;
10300     redund->isrow              = isrow;
10301     redund->iscol              = iscol;
10302     redund->matseq             = matseq;
10303     if (newsubcomm) {
10304       redund->subcomm          = subcomm;
10305     } else {
10306       redund->subcomm          = MPI_COMM_NULL;
10307     }
10308   } else {
10309     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);CHKERRQ(ierr);
10310   }
10311   ierr = PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
10312   PetscFunctionReturn(0);
10313 }
10314 
10315 /*@C
10316    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
10317    a given 'mat' object. Each submatrix can span multiple procs.
10318 
10319    Collective on Mat
10320 
10321    Input Parameters:
10322 +  mat - the matrix
10323 .  subcomm - the subcommunicator obtained by com_split(comm)
10324 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10325 
10326    Output Parameter:
10327 .  subMat - 'parallel submatrices each spans a given subcomm
10328 
10329   Notes:
10330   The submatrix partition across processors is dictated by 'subComm' a
10331   communicator obtained by com_split(comm). The comm_split
10332   is not restriced to be grouped with consecutive original ranks.
10333 
10334   Due the comm_split() usage, the parallel layout of the submatrices
10335   map directly to the layout of the original matrix [wrt the local
10336   row,col partitioning]. So the original 'DiagonalMat' naturally maps
10337   into the 'DiagonalMat' of the subMat, hence it is used directly from
10338   the subMat. However the offDiagMat looses some columns - and this is
10339   reconstructed with MatSetValues()
10340 
10341   Level: advanced
10342 
10343   Concepts: subcommunicator
10344   Concepts: submatrices
10345 
10346 .seealso: MatCreateSubMatrices()
10347 @*/
10348 PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
10349 {
10350   PetscErrorCode ierr;
10351   PetscMPIInt    commsize,subCommSize;
10352 
10353   PetscFunctionBegin;
10354   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRQ(ierr);
10355   ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr);
10356   if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
10357 
10358   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");
10359   ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10360   ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr);
10361   ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10362   PetscFunctionReturn(0);
10363 }
10364 
10365 /*@
10366    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
10367 
10368    Not Collective
10369 
10370    Input Arguments:
10371    mat - matrix to extract local submatrix from
10372    isrow - local row indices for submatrix
10373    iscol - local column indices for submatrix
10374 
10375    Output Arguments:
10376    submat - the submatrix
10377 
10378    Level: intermediate
10379 
10380    Notes:
10381    The submat should be returned with MatRestoreLocalSubMatrix().
10382 
10383    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
10384    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
10385 
10386    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
10387    MatSetValuesBlockedLocal() will also be implemented.
10388 
10389    The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that
10390    matrices obtained with DMCreateMatrix() generally already have the local to global mapping provided.
10391 
10392 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping()
10393 @*/
10394 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10395 {
10396   PetscErrorCode ierr;
10397 
10398   PetscFunctionBegin;
10399   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10400   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10401   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10402   PetscCheckSameComm(isrow,2,iscol,3);
10403   PetscValidPointer(submat,4);
10404   if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call");
10405 
10406   if (mat->ops->getlocalsubmatrix) {
10407     ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10408   } else {
10409     ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr);
10410   }
10411   PetscFunctionReturn(0);
10412 }
10413 
10414 /*@
10415    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
10416 
10417    Not Collective
10418 
10419    Input Arguments:
10420    mat - matrix to extract local submatrix from
10421    isrow - local row indices for submatrix
10422    iscol - local column indices for submatrix
10423    submat - the submatrix
10424 
10425    Level: intermediate
10426 
10427 .seealso: MatGetLocalSubMatrix()
10428 @*/
10429 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10430 {
10431   PetscErrorCode ierr;
10432 
10433   PetscFunctionBegin;
10434   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10435   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10436   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10437   PetscCheckSameComm(isrow,2,iscol,3);
10438   PetscValidPointer(submat,4);
10439   if (*submat) {
10440     PetscValidHeaderSpecific(*submat,MAT_CLASSID,4);
10441   }
10442 
10443   if (mat->ops->restorelocalsubmatrix) {
10444     ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10445   } else {
10446     ierr = MatDestroy(submat);CHKERRQ(ierr);
10447   }
10448   *submat = NULL;
10449   PetscFunctionReturn(0);
10450 }
10451 
10452 /* --------------------------------------------------------*/
10453 /*@
10454    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix
10455 
10456    Collective on Mat
10457 
10458    Input Parameter:
10459 .  mat - the matrix
10460 
10461    Output Parameter:
10462 .  is - if any rows have zero diagonals this contains the list of them
10463 
10464    Level: developer
10465 
10466    Concepts: matrix-vector product
10467 
10468 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10469 @*/
10470 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is)
10471 {
10472   PetscErrorCode ierr;
10473 
10474   PetscFunctionBegin;
10475   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10476   PetscValidType(mat,1);
10477   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10478   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10479 
10480   if (!mat->ops->findzerodiagonals) {
10481     Vec                diag;
10482     const PetscScalar *a;
10483     PetscInt          *rows;
10484     PetscInt           rStart, rEnd, r, nrow = 0;
10485 
10486     ierr = MatCreateVecs(mat, &diag, NULL);CHKERRQ(ierr);
10487     ierr = MatGetDiagonal(mat, diag);CHKERRQ(ierr);
10488     ierr = MatGetOwnershipRange(mat, &rStart, &rEnd);CHKERRQ(ierr);
10489     ierr = VecGetArrayRead(diag, &a);CHKERRQ(ierr);
10490     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow;
10491     ierr = PetscMalloc1(nrow, &rows);CHKERRQ(ierr);
10492     nrow = 0;
10493     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart;
10494     ierr = VecRestoreArrayRead(diag, &a);CHKERRQ(ierr);
10495     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10496     ierr = ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);CHKERRQ(ierr);
10497   } else {
10498     ierr = (*mat->ops->findzerodiagonals)(mat, is);CHKERRQ(ierr);
10499   }
10500   PetscFunctionReturn(0);
10501 }
10502 
10503 /*@
10504    MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size)
10505 
10506    Collective on Mat
10507 
10508    Input Parameter:
10509 .  mat - the matrix
10510 
10511    Output Parameter:
10512 .  is - contains the list of rows with off block diagonal entries
10513 
10514    Level: developer
10515 
10516    Concepts: matrix-vector product
10517 
10518 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10519 @*/
10520 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is)
10521 {
10522   PetscErrorCode ierr;
10523 
10524   PetscFunctionBegin;
10525   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10526   PetscValidType(mat,1);
10527   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10528   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10529 
10530   if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined");
10531   ierr = (*mat->ops->findoffblockdiagonalentries)(mat,is);CHKERRQ(ierr);
10532   PetscFunctionReturn(0);
10533 }
10534 
10535 /*@C
10536   MatInvertBlockDiagonal - Inverts the block diagonal entries.
10537 
10538   Collective on Mat
10539 
10540   Input Parameters:
10541 . mat - the matrix
10542 
10543   Output Parameters:
10544 . values - the block inverses in column major order (FORTRAN-like)
10545 
10546    Note:
10547    This routine is not available from Fortran.
10548 
10549   Level: advanced
10550 
10551 .seealso: MatInvertBockDiagonalMat
10552 @*/
10553 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
10554 {
10555   PetscErrorCode ierr;
10556 
10557   PetscFunctionBegin;
10558   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10559   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10560   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10561   if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
10562   ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr);
10563   PetscFunctionReturn(0);
10564 }
10565 
10566 /*@C
10567   MatInvertVariableBlockDiagonal - Inverts the block diagonal entries.
10568 
10569   Collective on Mat
10570 
10571   Input Parameters:
10572 + mat - the matrix
10573 . nblocks - the number of blocks
10574 - bsizes - the size of each block
10575 
10576   Output Parameters:
10577 . values - the block inverses in column major order (FORTRAN-like)
10578 
10579    Note:
10580    This routine is not available from Fortran.
10581 
10582   Level: advanced
10583 
10584 .seealso: MatInvertBockDiagonal()
10585 @*/
10586 PetscErrorCode MatInvertVariableBlockDiagonal(Mat mat,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *values)
10587 {
10588   PetscErrorCode ierr;
10589 
10590   PetscFunctionBegin;
10591   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10592   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10593   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10594   if (!mat->ops->invertvariableblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
10595   ierr = (*mat->ops->invertvariableblockdiagonal)(mat,nblocks,bsizes,values);CHKERRQ(ierr);
10596   PetscFunctionReturn(0);
10597 }
10598 
10599 /*@
10600   MatInvertBlockDiagonalMat - set matrix C to be the inverted block diagonal of matrix A
10601 
10602   Collective on Mat
10603 
10604   Input Parameters:
10605 . A - the matrix
10606 
10607   Output Parameters:
10608 . C - matrix with inverted block diagonal of A.  This matrix should be created and may have its type set.
10609 
10610   Notes: the blocksize of the matrix is used to determine the blocks on the diagonal of C
10611 
10612   Level: advanced
10613 
10614 .seealso: MatInvertBockDiagonal()
10615 @*/
10616 PetscErrorCode MatInvertBlockDiagonalMat(Mat A,Mat C)
10617 {
10618   PetscErrorCode     ierr;
10619   const PetscScalar *vals;
10620   PetscInt          *dnnz;
10621   PetscInt           M,N,m,n,rstart,rend,bs,i,j;
10622 
10623   PetscFunctionBegin;
10624   ierr = MatInvertBlockDiagonal(A,&vals);CHKERRQ(ierr);
10625   ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr);
10626   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
10627   ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr);
10628   ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr);
10629   ierr = MatSetBlockSize(C,bs);CHKERRQ(ierr);
10630   ierr = PetscMalloc1(m/bs,&dnnz);CHKERRQ(ierr);
10631   for (j = 0; j < m/bs; j++) dnnz[j] = 1;
10632   ierr = MatXAIJSetPreallocation(C,bs,dnnz,NULL,NULL,NULL);CHKERRQ(ierr);
10633   ierr = PetscFree(dnnz);CHKERRQ(ierr);
10634   ierr = MatGetOwnershipRange(C,&rstart,&rend);CHKERRQ(ierr);
10635   ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr);
10636   for (i = rstart/bs; i < rend/bs; i++) {
10637     ierr = MatSetValuesBlocked(C,1,&i,1,&i,&vals[(i-rstart/bs)*bs*bs],INSERT_VALUES);CHKERRQ(ierr);
10638   }
10639   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10640   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10641   ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr);
10642   PetscFunctionReturn(0);
10643 }
10644 
10645 /*@C
10646     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
10647     via MatTransposeColoringCreate().
10648 
10649     Collective on MatTransposeColoring
10650 
10651     Input Parameter:
10652 .   c - coloring context
10653 
10654     Level: intermediate
10655 
10656 .seealso: MatTransposeColoringCreate()
10657 @*/
10658 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c)
10659 {
10660   PetscErrorCode       ierr;
10661   MatTransposeColoring matcolor=*c;
10662 
10663   PetscFunctionBegin;
10664   if (!matcolor) PetscFunctionReturn(0);
10665   if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; PetscFunctionReturn(0);}
10666 
10667   ierr = PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);CHKERRQ(ierr);
10668   ierr = PetscFree(matcolor->rows);CHKERRQ(ierr);
10669   ierr = PetscFree(matcolor->den2sp);CHKERRQ(ierr);
10670   ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr);
10671   ierr = PetscFree(matcolor->columns);CHKERRQ(ierr);
10672   if (matcolor->brows>0) {
10673     ierr = PetscFree(matcolor->lstart);CHKERRQ(ierr);
10674   }
10675   ierr = PetscHeaderDestroy(c);CHKERRQ(ierr);
10676   PetscFunctionReturn(0);
10677 }
10678 
10679 /*@C
10680     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
10681     a MatTransposeColoring context has been created, computes a dense B^T by Apply
10682     MatTransposeColoring to sparse B.
10683 
10684     Collective on MatTransposeColoring
10685 
10686     Input Parameters:
10687 +   B - sparse matrix B
10688 .   Btdense - symbolic dense matrix B^T
10689 -   coloring - coloring context created with MatTransposeColoringCreate()
10690 
10691     Output Parameter:
10692 .   Btdense - dense matrix B^T
10693 
10694     Level: advanced
10695 
10696      Notes:
10697     These are used internally for some implementations of MatRARt()
10698 
10699 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplyDenToSp()
10700 
10701 .keywords: coloring
10702 @*/
10703 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
10704 {
10705   PetscErrorCode ierr;
10706 
10707   PetscFunctionBegin;
10708   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
10709   PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2);
10710   PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3);
10711 
10712   if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
10713   ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr);
10714   PetscFunctionReturn(0);
10715 }
10716 
10717 /*@C
10718     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
10719     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
10720     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
10721     Csp from Cden.
10722 
10723     Collective on MatTransposeColoring
10724 
10725     Input Parameters:
10726 +   coloring - coloring context created with MatTransposeColoringCreate()
10727 -   Cden - matrix product of a sparse matrix and a dense matrix Btdense
10728 
10729     Output Parameter:
10730 .   Csp - sparse matrix
10731 
10732     Level: advanced
10733 
10734      Notes:
10735     These are used internally for some implementations of MatRARt()
10736 
10737 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()
10738 
10739 .keywords: coloring
10740 @*/
10741 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
10742 {
10743   PetscErrorCode ierr;
10744 
10745   PetscFunctionBegin;
10746   PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1);
10747   PetscValidHeaderSpecific(Cden,MAT_CLASSID,2);
10748   PetscValidHeaderSpecific(Csp,MAT_CLASSID,3);
10749 
10750   if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
10751   ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr);
10752   PetscFunctionReturn(0);
10753 }
10754 
10755 /*@C
10756    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.
10757 
10758    Collective on Mat
10759 
10760    Input Parameters:
10761 +  mat - the matrix product C
10762 -  iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring()
10763 
10764     Output Parameter:
10765 .   color - the new coloring context
10766 
10767     Level: intermediate
10768 
10769 .seealso: MatTransposeColoringDestroy(),  MatTransColoringApplySpToDen(),
10770            MatTransColoringApplyDenToSp()
10771 @*/
10772 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
10773 {
10774   MatTransposeColoring c;
10775   MPI_Comm             comm;
10776   PetscErrorCode       ierr;
10777 
10778   PetscFunctionBegin;
10779   ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10780   ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
10781   ierr = PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);CHKERRQ(ierr);
10782 
10783   c->ctype = iscoloring->ctype;
10784   if (mat->ops->transposecoloringcreate) {
10785     ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr);
10786   } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type");
10787 
10788   *color = c;
10789   ierr   = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10790   PetscFunctionReturn(0);
10791 }
10792 
10793 /*@
10794       MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the
10795         matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the
10796         same, otherwise it will be larger
10797 
10798      Not Collective
10799 
10800   Input Parameter:
10801 .    A  - the matrix
10802 
10803   Output Parameter:
10804 .    state - the current state
10805 
10806   Notes:
10807     You can only compare states from two different calls to the SAME matrix, you cannot compare calls between
10808          different matrices
10809 
10810   Level: intermediate
10811 
10812 @*/
10813 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state)
10814 {
10815   PetscFunctionBegin;
10816   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10817   *state = mat->nonzerostate;
10818   PetscFunctionReturn(0);
10819 }
10820 
10821 /*@
10822       MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential
10823                  matrices from each processor
10824 
10825     Collective on MPI_Comm
10826 
10827    Input Parameters:
10828 +    comm - the communicators the parallel matrix will live on
10829 .    seqmat - the input sequential matrices
10830 .    n - number of local columns (or PETSC_DECIDE)
10831 -    reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10832 
10833    Output Parameter:
10834 .    mpimat - the parallel matrix generated
10835 
10836     Level: advanced
10837 
10838    Notes:
10839     The number of columns of the matrix in EACH processor MUST be the same.
10840 
10841 @*/
10842 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat)
10843 {
10844   PetscErrorCode ierr;
10845 
10846   PetscFunctionBegin;
10847   if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name);
10848   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");
10849 
10850   ierr = PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10851   ierr = (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);CHKERRQ(ierr);
10852   ierr = PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10853   PetscFunctionReturn(0);
10854 }
10855 
10856 /*@
10857      MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent
10858                  ranks' ownership ranges.
10859 
10860     Collective on A
10861 
10862    Input Parameters:
10863 +    A   - the matrix to create subdomains from
10864 -    N   - requested number of subdomains
10865 
10866 
10867    Output Parameters:
10868 +    n   - number of subdomains resulting on this rank
10869 -    iss - IS list with indices of subdomains on this rank
10870 
10871     Level: advanced
10872 
10873     Notes:
10874     number of subdomains must be smaller than the communicator size
10875 @*/
10876 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[])
10877 {
10878   MPI_Comm        comm,subcomm;
10879   PetscMPIInt     size,rank,color;
10880   PetscInt        rstart,rend,k;
10881   PetscErrorCode  ierr;
10882 
10883   PetscFunctionBegin;
10884   ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr);
10885   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
10886   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
10887   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);
10888   *n = 1;
10889   k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */
10890   color = rank/k;
10891   ierr = MPI_Comm_split(comm,color,rank,&subcomm);CHKERRQ(ierr);
10892   ierr = PetscMalloc1(1,iss);CHKERRQ(ierr);
10893   ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
10894   ierr = ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);CHKERRQ(ierr);
10895   ierr = MPI_Comm_free(&subcomm);CHKERRQ(ierr);
10896   PetscFunctionReturn(0);
10897 }
10898 
10899 /*@
10900    MatGalerkin - Constructs the coarse grid problem via Galerkin projection.
10901 
10902    If the interpolation and restriction operators are the same, uses MatPtAP.
10903    If they are not the same, use MatMatMatMult.
10904 
10905    Once the coarse grid problem is constructed, correct for interpolation operators
10906    that are not of full rank, which can legitimately happen in the case of non-nested
10907    geometric multigrid.
10908 
10909    Input Parameters:
10910 +  restrct - restriction operator
10911 .  dA - fine grid matrix
10912 .  interpolate - interpolation operator
10913 .  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10914 -  fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate
10915 
10916    Output Parameters:
10917 .  A - the Galerkin coarse matrix
10918 
10919    Options Database Key:
10920 .  -pc_mg_galerkin <both,pmat,mat,none>
10921 
10922    Level: developer
10923 
10924 .keywords: MG, multigrid, Galerkin
10925 
10926 .seealso: MatPtAP(), MatMatMatMult()
10927 @*/
10928 PetscErrorCode  MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A)
10929 {
10930   PetscErrorCode ierr;
10931   IS             zerorows;
10932   Vec            diag;
10933 
10934   PetscFunctionBegin;
10935   if (reuse == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10936   /* Construct the coarse grid matrix */
10937   if (interpolate == restrct) {
10938     ierr = MatPtAP(dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10939   } else {
10940     ierr = MatMatMatMult(restrct,dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10941   }
10942 
10943   /* If the interpolation matrix is not of full rank, A will have zero rows.
10944      This can legitimately happen in the case of non-nested geometric multigrid.
10945      In that event, we set the rows of the matrix to the rows of the identity,
10946      ignoring the equations (as the RHS will also be zero). */
10947 
10948   ierr = MatFindZeroRows(*A, &zerorows);CHKERRQ(ierr);
10949 
10950   if (zerorows != NULL) { /* if there are any zero rows */
10951     ierr = MatCreateVecs(*A, &diag, NULL);CHKERRQ(ierr);
10952     ierr = MatGetDiagonal(*A, diag);CHKERRQ(ierr);
10953     ierr = VecISSet(diag, zerorows, 1.0);CHKERRQ(ierr);
10954     ierr = MatDiagonalSet(*A, diag, INSERT_VALUES);CHKERRQ(ierr);
10955     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10956     ierr = ISDestroy(&zerorows);CHKERRQ(ierr);
10957   }
10958   PetscFunctionReturn(0);
10959 }
10960 
10961 /*@C
10962     MatSetOperation - Allows user to set a matrix operation for any matrix type
10963 
10964    Logically Collective on Mat
10965 
10966     Input Parameters:
10967 +   mat - the matrix
10968 .   op - the name of the operation
10969 -   f - the function that provides the operation
10970 
10971    Level: developer
10972 
10973     Usage:
10974 $      extern PetscErrorCode usermult(Mat,Vec,Vec);
10975 $      ierr = MatCreateXXX(comm,...&A);
10976 $      ierr = MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult);
10977 
10978     Notes:
10979     See the file include/petscmat.h for a complete list of matrix
10980     operations, which all have the form MATOP_<OPERATION>, where
10981     <OPERATION> is the name (in all capital letters) of the
10982     user interface routine (e.g., MatMult() -> MATOP_MULT).
10983 
10984     All user-provided functions (except for MATOP_DESTROY) should have the same calling
10985     sequence as the usual matrix interface routines, since they
10986     are intended to be accessed via the usual matrix interface
10987     routines, e.g.,
10988 $       MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec)
10989 
10990     In particular each function MUST return an error code of 0 on success and
10991     nonzero on failure.
10992 
10993     This routine is distinct from MatShellSetOperation() in that it can be called on any matrix type.
10994 
10995 .keywords: matrix, set, operation
10996 
10997 .seealso: MatGetOperation(), MatCreateShell(), MatShellSetContext(), MatShellSetOperation()
10998 @*/
10999 PetscErrorCode MatSetOperation(Mat mat,MatOperation op,void (*f)(void))
11000 {
11001   PetscFunctionBegin;
11002   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
11003   if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) {
11004     mat->ops->viewnative = mat->ops->view;
11005   }
11006   (((void(**)(void))mat->ops)[op]) = f;
11007   PetscFunctionReturn(0);
11008 }
11009 
11010 /*@C
11011     MatGetOperation - Gets a matrix operation for any matrix type.
11012 
11013     Not Collective
11014 
11015     Input Parameters:
11016 +   mat - the matrix
11017 -   op - the name of the operation
11018 
11019     Output Parameter:
11020 .   f - the function that provides the operation
11021 
11022     Level: developer
11023 
11024     Usage:
11025 $      PetscErrorCode (*usermult)(Mat,Vec,Vec);
11026 $      ierr = MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult);
11027 
11028     Notes:
11029     See the file include/petscmat.h for a complete list of matrix
11030     operations, which all have the form MATOP_<OPERATION>, where
11031     <OPERATION> is the name (in all capital letters) of the
11032     user interface routine (e.g., MatMult() -> MATOP_MULT).
11033 
11034     This routine is distinct from MatShellGetOperation() in that it can be called on any matrix type.
11035 
11036 .keywords: matrix, get, operation
11037 
11038 .seealso: MatSetOperation(), MatCreateShell(), MatShellGetContext(), MatShellGetOperation()
11039 @*/
11040 PetscErrorCode MatGetOperation(Mat mat,MatOperation op,void(**f)(void))
11041 {
11042   PetscFunctionBegin;
11043   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
11044   *f = (((void (**)(void))mat->ops)[op]);
11045   PetscFunctionReturn(0);
11046 }
11047 
11048 /*@
11049     MatHasOperation - Determines whether the given matrix supports the particular
11050     operation.
11051 
11052    Not Collective
11053 
11054    Input Parameters:
11055 +  mat - the matrix
11056 -  op - the operation, for example, MATOP_GET_DIAGONAL
11057 
11058    Output Parameter:
11059 .  has - either PETSC_TRUE or PETSC_FALSE
11060 
11061    Level: advanced
11062 
11063    Notes:
11064    See the file include/petscmat.h for a complete list of matrix
11065    operations, which all have the form MATOP_<OPERATION>, where
11066    <OPERATION> is the name (in all capital letters) of the
11067    user-level routine.  E.g., MatNorm() -> MATOP_NORM.
11068 
11069 .keywords: matrix, has, operation
11070 
11071 .seealso: MatCreateShell()
11072 @*/
11073 PetscErrorCode MatHasOperation(Mat mat,MatOperation op,PetscBool *has)
11074 {
11075   PetscErrorCode ierr;
11076 
11077   PetscFunctionBegin;
11078   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
11079   PetscValidType(mat,1);
11080   PetscValidPointer(has,3);
11081   if (mat->ops->hasoperation) {
11082     ierr = (*mat->ops->hasoperation)(mat,op,has);CHKERRQ(ierr);
11083   } else {
11084     if (((void**)mat->ops)[op]) *has =  PETSC_TRUE;
11085     else {
11086       *has = PETSC_FALSE;
11087       if (op == MATOP_CREATE_SUBMATRIX) {
11088         PetscMPIInt size;
11089 
11090         ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
11091         if (size == 1) {
11092           ierr = MatHasOperation(mat,MATOP_CREATE_SUBMATRICES,has);CHKERRQ(ierr);
11093         }
11094       }
11095     }
11096   }
11097   PetscFunctionReturn(0);
11098 }
11099 
11100 /*@
11101     MatHasCongruentLayouts - Determines whether the rows and columns layouts
11102     of the matrix are congruent
11103 
11104    Collective on mat
11105 
11106    Input Parameters:
11107 .  mat - the matrix
11108 
11109    Output Parameter:
11110 .  cong - either PETSC_TRUE or PETSC_FALSE
11111 
11112    Level: beginner
11113 
11114    Notes:
11115 
11116 .keywords: matrix, has
11117 
11118 .seealso: MatCreate(), MatSetSizes()
11119 @*/
11120 PetscErrorCode MatHasCongruentLayouts(Mat mat,PetscBool *cong)
11121 {
11122   PetscErrorCode ierr;
11123 
11124   PetscFunctionBegin;
11125   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
11126   PetscValidType(mat,1);
11127   PetscValidPointer(cong,2);
11128   if (!mat->rmap || !mat->cmap) {
11129     *cong = mat->rmap == mat->cmap ? PETSC_TRUE : PETSC_FALSE;
11130     PetscFunctionReturn(0);
11131   }
11132   if (mat->congruentlayouts == PETSC_DECIDE) { /* first time we compare rows and cols layouts */
11133     ierr = PetscLayoutCompare(mat->rmap,mat->cmap,cong);CHKERRQ(ierr);
11134     if (*cong) mat->congruentlayouts = 1;
11135     else       mat->congruentlayouts = 0;
11136   } else *cong = mat->congruentlayouts ? PETSC_TRUE : PETSC_FALSE;
11137   PetscFunctionReturn(0);
11138 }
11139 
11140 /*@
11141     MatFreeIntermediateDataStructures - Free intermediate data structures created for reuse,
11142     e.g., matrx product of MatPtAP.
11143 
11144    Collective on mat
11145 
11146    Input Parameters:
11147 .  mat - the matrix
11148 
11149    Output Parameter:
11150 .  mat - the matrix with intermediate data structures released
11151 
11152    Level: advanced
11153 
11154    Notes:
11155 
11156 .keywords: matrix
11157 
11158 .seealso: MatPtAP(), MatMatMult()
11159 @*/
11160 PetscErrorCode MatFreeIntermediateDataStructures(Mat mat)
11161 {
11162   PetscErrorCode ierr;
11163 
11164   PetscFunctionBegin;
11165   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
11166   PetscValidType(mat,1);
11167   if (mat->ops->freeintermediatedatastructures) {
11168     ierr = (*mat->ops->freeintermediatedatastructures)(mat);CHKERRQ(ierr);
11169   }
11170   PetscFunctionReturn(0);
11171 }
11172