xref: /petsc/src/mat/interface/matrix.c (revision bfcb38ea38335faa6e7f8d97f6bc6ce9aa2a1dd1)
1 
2 /*
3    This is where the abstract matrix operations are defined
4 */
5 
6 #include <petsc/private/matimpl.h>        /*I "petscmat.h" I*/
7 #include <petsc/private/isimpl.h>
8 #include <petsc/private/vecimpl.h>
9 
10 /* Logging support */
11 PetscClassId MAT_CLASSID;
12 PetscClassId MAT_COLORING_CLASSID;
13 PetscClassId MAT_FDCOLORING_CLASSID;
14 PetscClassId MAT_TRANSPOSECOLORING_CLASSID;
15 
16 PetscLogEvent MAT_Mult, MAT_Mults, MAT_MultConstrained, MAT_MultAdd, MAT_MultTranspose;
17 PetscLogEvent MAT_MultTransposeConstrained, MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve,MAT_MatTrSolve;
18 PetscLogEvent MAT_SolveTransposeAdd, MAT_SOR, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic;
19 PetscLogEvent MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor;
20 PetscLogEvent MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin;
21 PetscLogEvent MAT_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetRowIJ, MAT_CreateSubMats, MAT_GetOrdering, MAT_RedundantMat, MAT_GetSeqNonzeroStructure;
22 PetscLogEvent MAT_IncreaseOverlap, MAT_Partitioning, MAT_PartitioningND, MAT_Coarsen, MAT_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate;
23 PetscLogEvent MAT_FDColoringSetUp, MAT_FDColoringApply,MAT_Transpose,MAT_FDColoringFunction, MAT_CreateSubMat;
24 PetscLogEvent MAT_TransposeColoringCreate;
25 PetscLogEvent MAT_MatMult, MAT_MatMultSymbolic, MAT_MatMultNumeric;
26 PetscLogEvent MAT_PtAP, MAT_PtAPSymbolic, MAT_PtAPNumeric,MAT_RARt, MAT_RARtSymbolic, MAT_RARtNumeric;
27 PetscLogEvent MAT_MatTransposeMult, MAT_MatTransposeMultSymbolic, MAT_MatTransposeMultNumeric;
28 PetscLogEvent MAT_TransposeMatMult, MAT_TransposeMatMultSymbolic, MAT_TransposeMatMultNumeric;
29 PetscLogEvent MAT_MatMatMult, MAT_MatMatMultSymbolic, MAT_MatMatMultNumeric;
30 PetscLogEvent MAT_MultHermitianTranspose,MAT_MultHermitianTransposeAdd;
31 PetscLogEvent MAT_Getsymtranspose, MAT_Getsymtransreduced, MAT_GetBrowsOfAcols;
32 PetscLogEvent MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym;
33 PetscLogEvent MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure;
34 PetscLogEvent MAT_GetMultiProcBlock;
35 PetscLogEvent MAT_CUSPARSECopyToGPU, MAT_SetValuesBatch;
36 PetscLogEvent MAT_ViennaCLCopyToGPU;
37 PetscLogEvent MAT_Merge,MAT_Residual,MAT_SetRandom;
38 PetscLogEvent MATCOLORING_Apply,MATCOLORING_Comm,MATCOLORING_Local,MATCOLORING_ISCreate,MATCOLORING_SetUp,MATCOLORING_Weights;
39 
40 const char *const MatFactorTypes[] = {"NONE","LU","CHOLESKY","ILU","ICC","ILUDT","MatFactorType","MAT_FACTOR_",0};
41 
42 /*@
43    MatSetRandom - Sets all components of a matrix to random numbers. For sparse matrices that have been preallocated but not been assembled it randomly selects appropriate locations
44 
45    Logically Collective on Mat
46 
47    Input Parameters:
48 +  x  - the matrix
49 -  rctx - the random number context, formed by PetscRandomCreate(), or NULL and
50           it will create one internally.
51 
52    Output Parameter:
53 .  x  - the matrix
54 
55    Example of Usage:
56 .vb
57      PetscRandomCreate(PETSC_COMM_WORLD,&rctx);
58      MatSetRandom(x,rctx);
59      PetscRandomDestroy(rctx);
60 .ve
61 
62    Level: intermediate
63 
64    Concepts: matrix^setting to random
65    Concepts: random^matrix
66 
67 .seealso: MatZeroEntries(), MatSetValues(), PetscRandomCreate(), PetscRandomDestroy()
68 @*/
69 PetscErrorCode MatSetRandom(Mat x,PetscRandom rctx)
70 {
71   PetscErrorCode ierr;
72   PetscRandom    randObj = NULL;
73 
74   PetscFunctionBegin;
75   PetscValidHeaderSpecific(x,MAT_CLASSID,1);
76   if (rctx) PetscValidHeaderSpecific(rctx,PETSC_RANDOM_CLASSID,2);
77   PetscValidType(x,1);
78 
79   if (!x->ops->setrandom) SETERRQ1(PetscObjectComm((PetscObject)x),PETSC_ERR_SUP,"Mat type %s",((PetscObject)x)->type_name);
80 
81   if (!rctx) {
82     MPI_Comm comm;
83     ierr = PetscObjectGetComm((PetscObject)x,&comm);CHKERRQ(ierr);
84     ierr = PetscRandomCreate(comm,&randObj);CHKERRQ(ierr);
85     ierr = PetscRandomSetFromOptions(randObj);CHKERRQ(ierr);
86     rctx = randObj;
87   }
88 
89   ierr = PetscLogEventBegin(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr);
90   ierr = (*x->ops->setrandom)(x,rctx);CHKERRQ(ierr);
91   ierr = PetscLogEventEnd(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr);
92 
93   ierr = MatAssemblyBegin(x, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
94   ierr = MatAssemblyEnd(x, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
95   ierr = PetscRandomDestroy(&randObj);CHKERRQ(ierr);
96   PetscFunctionReturn(0);
97 }
98 
99 /*@
100    MatFactorGetErrorZeroPivot - returns the pivot value that was determined to be zero and the row it occurred in
101 
102    Logically Collective on Mat
103 
104    Input Parameters:
105 .  mat - the factored matrix
106 
107    Output Parameter:
108 +  pivot - the pivot value computed
109 -  row - the row that the zero pivot occurred. Note that this row must be interpreted carefully due to row reorderings and which processes
110          the share the matrix
111 
112    Level: advanced
113 
114    Notes:
115     This routine does not work for factorizations done with external packages.
116    This routine should only be called if MatGetFactorError() returns a value of MAT_FACTOR_NUMERIC_ZEROPIVOT
117 
118    This can be called on non-factored matrices that come from, for example, matrices used in SOR.
119 
120 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot()
121 @*/
122 PetscErrorCode MatFactorGetErrorZeroPivot(Mat mat,PetscReal *pivot,PetscInt *row)
123 {
124   PetscFunctionBegin;
125   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
126   *pivot = mat->factorerror_zeropivot_value;
127   *row   = mat->factorerror_zeropivot_row;
128   PetscFunctionReturn(0);
129 }
130 
131 /*@
132    MatFactorGetError - gets the error code from a factorization
133 
134    Logically Collective on Mat
135 
136    Input Parameters:
137 .  mat - the factored matrix
138 
139    Output Parameter:
140 .  err  - the error code
141 
142    Level: advanced
143 
144    Notes:
145     This can be called on non-factored matrices that come from, for example, matrices used in SOR.
146 
147 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot()
148 @*/
149 PetscErrorCode MatFactorGetError(Mat mat,MatFactorError *err)
150 {
151   PetscFunctionBegin;
152   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
153   *err = mat->factorerrortype;
154   PetscFunctionReturn(0);
155 }
156 
157 /*@
158    MatFactorClearError - clears the error code in a factorization
159 
160    Logically Collective on Mat
161 
162    Input Parameter:
163 .  mat - the factored matrix
164 
165    Level: developer
166 
167    Notes:
168     This can be called on non-factored matrices that come from, for example, matrices used in SOR.
169 
170 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorGetError(), MatFactorGetErrorZeroPivot()
171 @*/
172 PetscErrorCode MatFactorClearError(Mat mat)
173 {
174   PetscFunctionBegin;
175   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
176   mat->factorerrortype             = MAT_FACTOR_NOERROR;
177   mat->factorerror_zeropivot_value = 0.0;
178   mat->factorerror_zeropivot_row   = 0;
179   PetscFunctionReturn(0);
180 }
181 
182 PETSC_INTERN PetscErrorCode MatFindNonzeroRowsOrCols_Basic(Mat mat,PetscBool cols,PetscReal tol,IS *nonzero)
183 {
184   PetscErrorCode    ierr;
185   Vec               r,l;
186   const PetscScalar *al;
187   PetscInt          i,nz,gnz,N,n;
188 
189   PetscFunctionBegin;
190   ierr = MatCreateVecs(mat,&r,&l);CHKERRQ(ierr);
191   if (!cols) { /* nonzero rows */
192     ierr = MatGetSize(mat,&N,NULL);CHKERRQ(ierr);
193     ierr = MatGetLocalSize(mat,&n,NULL);CHKERRQ(ierr);
194     ierr = VecSet(l,0.0);CHKERRQ(ierr);
195     ierr = VecSetRandom(r,NULL);CHKERRQ(ierr);
196     ierr = MatMult(mat,r,l);CHKERRQ(ierr);
197     ierr = VecGetArrayRead(l,&al);CHKERRQ(ierr);
198   } else { /* nonzero columns */
199     ierr = MatGetSize(mat,NULL,&N);CHKERRQ(ierr);
200     ierr = MatGetLocalSize(mat,NULL,&n);CHKERRQ(ierr);
201     ierr = VecSet(r,0.0);CHKERRQ(ierr);
202     ierr = VecSetRandom(l,NULL);CHKERRQ(ierr);
203     ierr = MatMultTranspose(mat,l,r);CHKERRQ(ierr);
204     ierr = VecGetArrayRead(r,&al);CHKERRQ(ierr);
205   }
206   if (tol <= 0.0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nz++; }
207   else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nz++; }
208   ierr = MPIU_Allreduce(&nz,&gnz,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr);
209   if (gnz != N) {
210     PetscInt *nzr;
211     ierr = PetscMalloc1(nz,&nzr);CHKERRQ(ierr);
212     if (nz) {
213       if (tol < 0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nzr[nz++] = i; }
214       else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nzr[nz++] = i; }
215     }
216     ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),nz,nzr,PETSC_OWN_POINTER,nonzero);CHKERRQ(ierr);
217   } else *nonzero = NULL;
218   if (!cols) { /* nonzero rows */
219     ierr = VecRestoreArrayRead(l,&al);CHKERRQ(ierr);
220   } else {
221     ierr = VecRestoreArrayRead(r,&al);CHKERRQ(ierr);
222   }
223   ierr = VecDestroy(&l);CHKERRQ(ierr);
224   ierr = VecDestroy(&r);CHKERRQ(ierr);
225   PetscFunctionReturn(0);
226 }
227 
228 /*@
229       MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix
230 
231   Input Parameter:
232 .    A  - the matrix
233 
234   Output Parameter:
235 .    keptrows - the rows that are not completely zero
236 
237   Notes:
238     keptrows is set to NULL if all rows are nonzero.
239 
240   Level: intermediate
241 
242  @*/
243 PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows)
244 {
245   PetscErrorCode ierr;
246 
247   PetscFunctionBegin;
248   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
249   PetscValidType(mat,1);
250   PetscValidPointer(keptrows,2);
251   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
252   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
253   if (!mat->ops->findnonzerorows) {
254     ierr = MatFindNonzeroRowsOrCols_Basic(mat,PETSC_FALSE,0.0,keptrows);CHKERRQ(ierr);
255   } else {
256     ierr = (*mat->ops->findnonzerorows)(mat,keptrows);CHKERRQ(ierr);
257   }
258   PetscFunctionReturn(0);
259 }
260 
261 /*@
262       MatFindZeroRows - Locate all rows that are completely zero in the matrix
263 
264   Input Parameter:
265 .    A  - the matrix
266 
267   Output Parameter:
268 .    zerorows - the rows that are completely zero
269 
270   Notes:
271     zerorows is set to NULL if no rows are zero.
272 
273   Level: intermediate
274 
275  @*/
276 PetscErrorCode MatFindZeroRows(Mat mat,IS *zerorows)
277 {
278   PetscErrorCode ierr;
279   IS keptrows;
280   PetscInt m, n;
281 
282   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
283   PetscValidType(mat,1);
284 
285   ierr = MatFindNonzeroRows(mat, &keptrows);CHKERRQ(ierr);
286   /* MatFindNonzeroRows sets keptrows to NULL if there are no zero rows.
287      In keeping with this convention, we set zerorows to NULL if there are no zero
288      rows. */
289   if (keptrows == NULL) {
290     *zerorows = NULL;
291   } else {
292     ierr = MatGetOwnershipRange(mat,&m,&n);CHKERRQ(ierr);
293     ierr = ISComplement(keptrows,m,n,zerorows);CHKERRQ(ierr);
294     ierr = ISDestroy(&keptrows);CHKERRQ(ierr);
295   }
296   PetscFunctionReturn(0);
297 }
298 
299 /*@
300    MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling
301 
302    Not Collective
303 
304    Input Parameters:
305 .   A - the matrix
306 
307    Output Parameters:
308 .   a - the diagonal part (which is a SEQUENTIAL matrix)
309 
310    Notes:
311     see the manual page for MatCreateAIJ() for more information on the "diagonal part" of the matrix.
312           Use caution, as the reference count on the returned matrix is not incremented and it is used as
313 	  part of the containing MPI Mat's normal operation.
314 
315    Level: advanced
316 
317 @*/
318 PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a)
319 {
320   PetscErrorCode ierr;
321 
322   PetscFunctionBegin;
323   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
324   PetscValidType(A,1);
325   PetscValidPointer(a,3);
326   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
327   if (!A->ops->getdiagonalblock) {
328     PetscMPIInt size;
329     ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);CHKERRQ(ierr);
330     if (size == 1) {
331       *a = A;
332       PetscFunctionReturn(0);
333     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Not coded for this matrix type");
334   }
335   ierr = (*A->ops->getdiagonalblock)(A,a);CHKERRQ(ierr);
336   PetscFunctionReturn(0);
337 }
338 
339 /*@
340    MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries.
341 
342    Collective on Mat
343 
344    Input Parameters:
345 .  mat - the matrix
346 
347    Output Parameter:
348 .   trace - the sum of the diagonal entries
349 
350    Level: advanced
351 
352 @*/
353 PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace)
354 {
355   PetscErrorCode ierr;
356   Vec            diag;
357 
358   PetscFunctionBegin;
359   ierr = MatCreateVecs(mat,&diag,NULL);CHKERRQ(ierr);
360   ierr = MatGetDiagonal(mat,diag);CHKERRQ(ierr);
361   ierr = VecSum(diag,trace);CHKERRQ(ierr);
362   ierr = VecDestroy(&diag);CHKERRQ(ierr);
363   PetscFunctionReturn(0);
364 }
365 
366 /*@
367    MatRealPart - Zeros out the imaginary part of the matrix
368 
369    Logically Collective on Mat
370 
371    Input Parameters:
372 .  mat - the matrix
373 
374    Level: advanced
375 
376 
377 .seealso: MatImaginaryPart()
378 @*/
379 PetscErrorCode MatRealPart(Mat mat)
380 {
381   PetscErrorCode ierr;
382 
383   PetscFunctionBegin;
384   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
385   PetscValidType(mat,1);
386   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
387   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
388   if (!mat->ops->realpart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
389   MatCheckPreallocated(mat,1);
390   ierr = (*mat->ops->realpart)(mat);CHKERRQ(ierr);
391 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
392   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
393     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
394   }
395 #endif
396   PetscFunctionReturn(0);
397 }
398 
399 /*@C
400    MatGetGhosts - Get the global index of all ghost nodes defined by the sparse matrix
401 
402    Collective on Mat
403 
404    Input Parameter:
405 .  mat - the matrix
406 
407    Output Parameters:
408 +   nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block)
409 -   ghosts - the global indices of the ghost points
410 
411    Notes:
412     the nghosts and ghosts are suitable to pass into VecCreateGhost()
413 
414    Level: advanced
415 
416 @*/
417 PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[])
418 {
419   PetscErrorCode ierr;
420 
421   PetscFunctionBegin;
422   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
423   PetscValidType(mat,1);
424   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
425   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
426   if (!mat->ops->getghosts) {
427     if (nghosts) *nghosts = 0;
428     if (ghosts) *ghosts = 0;
429   } else {
430     ierr = (*mat->ops->getghosts)(mat,nghosts,ghosts);CHKERRQ(ierr);
431   }
432   PetscFunctionReturn(0);
433 }
434 
435 
436 /*@
437    MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part
438 
439    Logically Collective on Mat
440 
441    Input Parameters:
442 .  mat - the matrix
443 
444    Level: advanced
445 
446 
447 .seealso: MatRealPart()
448 @*/
449 PetscErrorCode MatImaginaryPart(Mat mat)
450 {
451   PetscErrorCode ierr;
452 
453   PetscFunctionBegin;
454   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
455   PetscValidType(mat,1);
456   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
457   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
458   if (!mat->ops->imaginarypart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
459   MatCheckPreallocated(mat,1);
460   ierr = (*mat->ops->imaginarypart)(mat);CHKERRQ(ierr);
461 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
462   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
463     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
464   }
465 #endif
466   PetscFunctionReturn(0);
467 }
468 
469 /*@
470    MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices)
471 
472    Not Collective
473 
474    Input Parameter:
475 .  mat - the matrix
476 
477    Output Parameters:
478 +  missing - is any diagonal missing
479 -  dd - first diagonal entry that is missing (optional) on this process
480 
481    Level: advanced
482 
483 
484 .seealso: MatRealPart()
485 @*/
486 PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd)
487 {
488   PetscErrorCode ierr;
489 
490   PetscFunctionBegin;
491   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
492   PetscValidType(mat,1);
493   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
494   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
495   if (!mat->ops->missingdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
496   ierr = (*mat->ops->missingdiagonal)(mat,missing,dd);CHKERRQ(ierr);
497   PetscFunctionReturn(0);
498 }
499 
500 /*@C
501    MatGetRow - Gets a row of a matrix.  You MUST call MatRestoreRow()
502    for each row that you get to ensure that your application does
503    not bleed memory.
504 
505    Not Collective
506 
507    Input Parameters:
508 +  mat - the matrix
509 -  row - the row to get
510 
511    Output Parameters:
512 +  ncols -  if not NULL, the number of nonzeros in the row
513 .  cols - if not NULL, the column numbers
514 -  vals - if not NULL, the values
515 
516    Notes:
517    This routine is provided for people who need to have direct access
518    to the structure of a matrix.  We hope that we provide enough
519    high-level matrix routines that few users will need it.
520 
521    MatGetRow() always returns 0-based column indices, regardless of
522    whether the internal representation is 0-based (default) or 1-based.
523 
524    For better efficiency, set cols and/or vals to NULL if you do
525    not wish to extract these quantities.
526 
527    The user can only examine the values extracted with MatGetRow();
528    the values cannot be altered.  To change the matrix entries, one
529    must use MatSetValues().
530 
531    You can only have one call to MatGetRow() outstanding for a particular
532    matrix at a time, per processor. MatGetRow() can only obtain rows
533    associated with the given processor, it cannot get rows from the
534    other processors; for that we suggest using MatCreateSubMatrices(), then
535    MatGetRow() on the submatrix. The row index passed to MatGetRow()
536    is in the global number of rows.
537 
538    Fortran Notes:
539    The calling sequence from Fortran is
540 .vb
541    MatGetRow(matrix,row,ncols,cols,values,ierr)
542          Mat     matrix (input)
543          integer row    (input)
544          integer ncols  (output)
545          integer cols(maxcols) (output)
546          double precision (or double complex) values(maxcols) output
547 .ve
548    where maxcols >= maximum nonzeros in any row of the matrix.
549 
550 
551    Caution:
552    Do not try to change the contents of the output arrays (cols and vals).
553    In some cases, this may corrupt the matrix.
554 
555    Level: advanced
556 
557    Concepts: matrices^row access
558 
559 .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatCreateSubMatrices(), MatGetDiagonal()
560 @*/
561 PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
562 {
563   PetscErrorCode ierr;
564   PetscInt       incols;
565 
566   PetscFunctionBegin;
567   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
568   PetscValidType(mat,1);
569   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
570   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
571   if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
572   MatCheckPreallocated(mat,1);
573   ierr = PetscLogEventBegin(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr);
574   ierr = (*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals);CHKERRQ(ierr);
575   if (ncols) *ncols = incols;
576   ierr = PetscLogEventEnd(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr);
577   PetscFunctionReturn(0);
578 }
579 
580 /*@
581    MatConjugate - replaces the matrix values with their complex conjugates
582 
583    Logically Collective on Mat
584 
585    Input Parameters:
586 .  mat - the matrix
587 
588    Level: advanced
589 
590 .seealso:  VecConjugate()
591 @*/
592 PetscErrorCode MatConjugate(Mat mat)
593 {
594 #if defined(PETSC_USE_COMPLEX)
595   PetscErrorCode ierr;
596 
597   PetscFunctionBegin;
598   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
599   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
600   if (!mat->ops->conjugate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not provided for this matrix format, send email to petsc-maint@mcs.anl.gov");
601   ierr = (*mat->ops->conjugate)(mat);CHKERRQ(ierr);
602 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
603   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
604     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
605   }
606 #endif
607   PetscFunctionReturn(0);
608 #else
609   return 0;
610 #endif
611 }
612 
613 /*@C
614    MatRestoreRow - Frees any temporary space allocated by MatGetRow().
615 
616    Not Collective
617 
618    Input Parameters:
619 +  mat - the matrix
620 .  row - the row to get
621 .  ncols, cols - the number of nonzeros and their columns
622 -  vals - if nonzero the column values
623 
624    Notes:
625    This routine should be called after you have finished examining the entries.
626 
627    This routine zeros out ncols, cols, and vals. This is to prevent accidental
628    us of the array after it has been restored. If you pass NULL, it will
629    not zero the pointers.  Use of cols or vals after MatRestoreRow is invalid.
630 
631    Fortran Notes:
632    The calling sequence from Fortran is
633 .vb
634    MatRestoreRow(matrix,row,ncols,cols,values,ierr)
635       Mat     matrix (input)
636       integer row    (input)
637       integer ncols  (output)
638       integer cols(maxcols) (output)
639       double precision (or double complex) values(maxcols) output
640 .ve
641    Where maxcols >= maximum nonzeros in any row of the matrix.
642 
643    In Fortran MatRestoreRow() MUST be called after MatGetRow()
644    before another call to MatGetRow() can be made.
645 
646    Level: advanced
647 
648 .seealso:  MatGetRow()
649 @*/
650 PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
651 {
652   PetscErrorCode ierr;
653 
654   PetscFunctionBegin;
655   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
656   if (ncols) PetscValidIntPointer(ncols,3);
657   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
658   if (!mat->ops->restorerow) PetscFunctionReturn(0);
659   ierr = (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);CHKERRQ(ierr);
660   if (ncols) *ncols = 0;
661   if (cols)  *cols = NULL;
662   if (vals)  *vals = NULL;
663   PetscFunctionReturn(0);
664 }
665 
666 /*@
667    MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format.
668    You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag.
669 
670    Not Collective
671 
672    Input Parameters:
673 +  mat - the matrix
674 
675    Notes:
676    The flag is to ensure that users are aware of MatGetRow() only provides the upper trianglular part of the row for the matrices in MATSBAIJ format.
677 
678    Level: advanced
679 
680    Concepts: matrices^row access
681 
682 .seealso: MatRestoreRowUpperTriangular()
683 @*/
684 PetscErrorCode MatGetRowUpperTriangular(Mat mat)
685 {
686   PetscErrorCode ierr;
687 
688   PetscFunctionBegin;
689   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
690   PetscValidType(mat,1);
691   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
692   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
693   MatCheckPreallocated(mat,1);
694   if (!mat->ops->getrowuppertriangular) PetscFunctionReturn(0);
695   ierr = (*mat->ops->getrowuppertriangular)(mat);CHKERRQ(ierr);
696   PetscFunctionReturn(0);
697 }
698 
699 /*@
700    MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format.
701 
702    Not Collective
703 
704    Input Parameters:
705 +  mat - the matrix
706 
707    Notes:
708    This routine should be called after you have finished MatGetRow/MatRestoreRow().
709 
710 
711    Level: advanced
712 
713 .seealso:  MatGetRowUpperTriangular()
714 @*/
715 PetscErrorCode MatRestoreRowUpperTriangular(Mat mat)
716 {
717   PetscErrorCode ierr;
718 
719   PetscFunctionBegin;
720   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
721   PetscValidType(mat,1);
722   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
723   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
724   MatCheckPreallocated(mat,1);
725   if (!mat->ops->restorerowuppertriangular) PetscFunctionReturn(0);
726   ierr = (*mat->ops->restorerowuppertriangular)(mat);CHKERRQ(ierr);
727   PetscFunctionReturn(0);
728 }
729 
730 /*@C
731    MatSetOptionsPrefix - Sets the prefix used for searching for all
732    Mat options in the database.
733 
734    Logically Collective on Mat
735 
736    Input Parameter:
737 +  A - the Mat context
738 -  prefix - the prefix to prepend to all option names
739 
740    Notes:
741    A hyphen (-) must NOT be given at the beginning of the prefix name.
742    The first character of all runtime options is AUTOMATICALLY the hyphen.
743 
744    Level: advanced
745 
746 .seealso: MatSetFromOptions()
747 @*/
748 PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[])
749 {
750   PetscErrorCode ierr;
751 
752   PetscFunctionBegin;
753   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
754   ierr = PetscObjectSetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
755   PetscFunctionReturn(0);
756 }
757 
758 /*@C
759    MatAppendOptionsPrefix - Appends to the prefix used for searching for all
760    Mat options in the database.
761 
762    Logically Collective on Mat
763 
764    Input Parameters:
765 +  A - the Mat context
766 -  prefix - the prefix to prepend to all option names
767 
768    Notes:
769    A hyphen (-) must NOT be given at the beginning of the prefix name.
770    The first character of all runtime options is AUTOMATICALLY the hyphen.
771 
772    Level: advanced
773 
774 .seealso: MatGetOptionsPrefix()
775 @*/
776 PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[])
777 {
778   PetscErrorCode ierr;
779 
780   PetscFunctionBegin;
781   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
782   ierr = PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
783   PetscFunctionReturn(0);
784 }
785 
786 /*@C
787    MatGetOptionsPrefix - Sets the prefix used for searching for all
788    Mat options in the database.
789 
790    Not Collective
791 
792    Input Parameter:
793 .  A - the Mat context
794 
795    Output Parameter:
796 .  prefix - pointer to the prefix string used
797 
798    Notes:
799     On the fortran side, the user should pass in a string 'prefix' of
800    sufficient length to hold the prefix.
801 
802    Level: advanced
803 
804 .seealso: MatAppendOptionsPrefix()
805 @*/
806 PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[])
807 {
808   PetscErrorCode ierr;
809 
810   PetscFunctionBegin;
811   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
812   ierr = PetscObjectGetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
813   PetscFunctionReturn(0);
814 }
815 
816 /*@
817    MatResetPreallocation - Reset mat to use the original nonzero pattern provided by users.
818 
819    Collective on Mat
820 
821    Input Parameters:
822 .  A - the Mat context
823 
824    Notes:
825    The allocated memory will be shrunk after calling MatAssembly with MAT_FINAL_ASSEMBLY. Users can reset the preallocation to access the original memory.
826    Currently support MPIAIJ and SEQAIJ.
827 
828    Level: beginner
829 
830 .seealso: MatSeqAIJSetPreallocation(), MatMPIAIJSetPreallocation(), MatXAIJSetPreallocation()
831 @*/
832 PetscErrorCode MatResetPreallocation(Mat A)
833 {
834   PetscErrorCode ierr;
835 
836   PetscFunctionBegin;
837   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
838   PetscValidType(A,1);
839   ierr = PetscUseMethod(A,"MatResetPreallocation_C",(Mat),(A));CHKERRQ(ierr);
840   PetscFunctionReturn(0);
841 }
842 
843 
844 /*@
845    MatSetUp - Sets up the internal matrix data structures for the later use.
846 
847    Collective on Mat
848 
849    Input Parameters:
850 .  A - the Mat context
851 
852    Notes:
853    If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used.
854 
855    If a suitable preallocation routine is used, this function does not need to be called.
856 
857    See the Performance chapter of the PETSc users manual for how to preallocate matrices
858 
859    Level: beginner
860 
861 .seealso: MatCreate(), MatDestroy()
862 @*/
863 PetscErrorCode MatSetUp(Mat A)
864 {
865   PetscMPIInt    size;
866   PetscErrorCode ierr;
867 
868   PetscFunctionBegin;
869   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
870   if (!((PetscObject)A)->type_name) {
871     ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A), &size);CHKERRQ(ierr);
872     if (size == 1) {
873       ierr = MatSetType(A, MATSEQAIJ);CHKERRQ(ierr);
874     } else {
875       ierr = MatSetType(A, MATMPIAIJ);CHKERRQ(ierr);
876     }
877   }
878   if (!A->preallocated && A->ops->setup) {
879     ierr = PetscInfo(A,"Warning not preallocating matrix storage\n");CHKERRQ(ierr);
880     ierr = (*A->ops->setup)(A);CHKERRQ(ierr);
881   }
882   ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr);
883   ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr);
884   A->preallocated = PETSC_TRUE;
885   PetscFunctionReturn(0);
886 }
887 
888 #if defined(PETSC_HAVE_SAWS)
889 #include <petscviewersaws.h>
890 #endif
891 /*@C
892    MatView - Visualizes a matrix object.
893 
894    Collective on Mat
895 
896    Input Parameters:
897 +  mat - the matrix
898 -  viewer - visualization context
899 
900   Notes:
901   The available visualization contexts include
902 +    PETSC_VIEWER_STDOUT_SELF - for sequential matrices
903 .    PETSC_VIEWER_STDOUT_WORLD - for parallel matrices created on PETSC_COMM_WORLD
904 .    PETSC_VIEWER_STDOUT_(comm) - for matrices created on MPI communicator comm
905 -     PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure
906 
907    The user can open alternative visualization contexts with
908 +    PetscViewerASCIIOpen() - Outputs matrix to a specified file
909 .    PetscViewerBinaryOpen() - Outputs matrix in binary to a
910          specified file; corresponding input uses MatLoad()
911 .    PetscViewerDrawOpen() - Outputs nonzero matrix structure to
912          an X window display
913 -    PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
914          Currently only the sequential dense and AIJ
915          matrix types support the Socket viewer.
916 
917    The user can call PetscViewerPushFormat() to specify the output
918    format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
919    PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen).  Available formats include
920 +    PETSC_VIEWER_DEFAULT - default, prints matrix contents
921 .    PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
922 .    PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
923 .    PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse
924          format common among all matrix types
925 .    PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific
926          format (which is in many cases the same as the default)
927 .    PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
928          size and structure (not the matrix entries)
929 -    PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about
930          the matrix structure
931 
932    Options Database Keys:
933 +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatAssemblyEnd()
934 .  -mat_view ::ascii_info_detail - Prints more detailed info
935 .  -mat_view - Prints matrix in ASCII format
936 .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
937 .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
938 .  -display <name> - Sets display name (default is host)
939 .  -draw_pause <sec> - Sets number of seconds to pause after display
940 .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: ch_matlab for details)
941 .  -viewer_socket_machine <machine> -
942 .  -viewer_socket_port <port> -
943 .  -mat_view binary - save matrix to file in binary format
944 -  -viewer_binary_filename <name> -
945    Level: beginner
946 
947    Notes:
948     The ASCII viewers are only recommended for small matrices on at most a moderate number of processes,
949     the program will seemingly hang and take hours for larger matrices, for larger matrices one should use the binary format.
950 
951     See the manual page for MatLoad() for the exact format of the binary file when the binary
952       viewer is used.
953 
954       See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary
955       viewer is used.
956 
957       One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure,
958       and then use the following mouse functions.
959 + left mouse: zoom in
960 . middle mouse: zoom out
961 - right mouse: continue with the simulation
962 
963    Concepts: matrices^viewing
964    Concepts: matrices^plotting
965    Concepts: matrices^printing
966 
967 .seealso: PetscViewerPushFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(),
968           PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
969 @*/
970 PetscErrorCode MatView(Mat mat,PetscViewer viewer)
971 {
972   PetscErrorCode    ierr;
973   PetscInt          rows,cols,rbs,cbs;
974   PetscBool         iascii,ibinary,isstring;
975   PetscViewerFormat format;
976   PetscMPIInt       size;
977 #if defined(PETSC_HAVE_SAWS)
978   PetscBool         issaws;
979 #endif
980 
981   PetscFunctionBegin;
982   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
983   PetscValidType(mat,1);
984   if (!viewer) {
985     ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);CHKERRQ(ierr);
986   }
987   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
988   PetscCheckSameComm(mat,1,viewer,2);
989   MatCheckPreallocated(mat,1);
990   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
991   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
992   if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(0);
993   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr);
994   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr);
995   if (ibinary) {
996     PetscBool mpiio;
997     ierr = PetscViewerBinaryGetUseMPIIO(viewer,&mpiio);CHKERRQ(ierr);
998     if (mpiio) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"PETSc matrix viewers do not support using MPI-IO, turn off that flag");
999   }
1000 
1001   ierr = PetscLogEventBegin(MAT_View,mat,viewer,0,0);CHKERRQ(ierr);
1002   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1003   if ((!iascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) {
1004     SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detailed");
1005   }
1006 
1007 #if defined(PETSC_HAVE_SAWS)
1008   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr);
1009 #endif
1010   if (iascii) {
1011     if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
1012     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer);CHKERRQ(ierr);
1013     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
1014       MatNullSpace nullsp,transnullsp;
1015 
1016       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1017       ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr);
1018       ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr);
1019       if (rbs != 1 || cbs != 1) {
1020         if (rbs != cbs) {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, rbs=%D, cbs = %D\n",rows,cols,rbs,cbs);CHKERRQ(ierr);}
1021         else            {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,rbs);CHKERRQ(ierr);}
1022       } else {
1023         ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);CHKERRQ(ierr);
1024       }
1025       if (mat->factortype) {
1026         MatSolverType solver;
1027         ierr = MatFactorGetSolverType(mat,&solver);CHKERRQ(ierr);
1028         ierr = PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);CHKERRQ(ierr);
1029       }
1030       if (mat->ops->getinfo) {
1031         MatInfo info;
1032         ierr = MatGetInfo(mat,MAT_GLOBAL_SUM,&info);CHKERRQ(ierr);
1033         ierr = PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated);CHKERRQ(ierr);
1034         ierr = PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls =%D\n",(PetscInt)info.mallocs);CHKERRQ(ierr);
1035       }
1036       ierr = MatGetNullSpace(mat,&nullsp);CHKERRQ(ierr);
1037       ierr = MatGetTransposeNullSpace(mat,&transnullsp);CHKERRQ(ierr);
1038       if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer,"  has attached null space\n");CHKERRQ(ierr);}
1039       if (transnullsp && transnullsp != nullsp) {ierr = PetscViewerASCIIPrintf(viewer,"  has attached transposed null space\n");CHKERRQ(ierr);}
1040       ierr = MatGetNearNullSpace(mat,&nullsp);CHKERRQ(ierr);
1041       if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer,"  has attached near null space\n");CHKERRQ(ierr);}
1042     }
1043 #if defined(PETSC_HAVE_SAWS)
1044   } else if (issaws) {
1045     PetscMPIInt rank;
1046 
1047     ierr = PetscObjectName((PetscObject)mat);CHKERRQ(ierr);
1048     ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
1049     if (!((PetscObject)mat)->amsmem && !rank) {
1050       ierr = PetscObjectViewSAWs((PetscObject)mat,viewer);CHKERRQ(ierr);
1051     }
1052 #endif
1053   } else if (isstring) {
1054     const char *type;
1055     ierr = MatGetType(mat,&type);CHKERRQ(ierr);
1056     ierr = PetscViewerStringSPrintf(viewer," MatType: %-7.7s",type);CHKERRQ(ierr);
1057     if (mat->ops->view) {ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr);}
1058   }
1059   if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && mat->ops->viewnative) {
1060     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1061     ierr = (*mat->ops->viewnative)(mat,viewer);CHKERRQ(ierr);
1062     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1063   } else if (mat->ops->view) {
1064     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1065     ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr);
1066     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1067   }
1068   if (iascii) {
1069     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1070     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
1071       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1072     }
1073   }
1074   ierr = PetscLogEventEnd(MAT_View,mat,viewer,0,0);CHKERRQ(ierr);
1075   PetscFunctionReturn(0);
1076 }
1077 
1078 #if defined(PETSC_USE_DEBUG)
1079 #include <../src/sys/totalview/tv_data_display.h>
1080 PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat)
1081 {
1082   TV_add_row("Local rows", "int", &mat->rmap->n);
1083   TV_add_row("Local columns", "int", &mat->cmap->n);
1084   TV_add_row("Global rows", "int", &mat->rmap->N);
1085   TV_add_row("Global columns", "int", &mat->cmap->N);
1086   TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name);
1087   return TV_format_OK;
1088 }
1089 #endif
1090 
1091 /*@C
1092    MatLoad - Loads a matrix that has been stored in binary/HDF5 format
1093    with MatView().  The matrix format is determined from the options database.
1094    Generates a parallel MPI matrix if the communicator has more than one
1095    processor.  The default matrix type is AIJ.
1096 
1097    Collective on PetscViewer
1098 
1099    Input Parameters:
1100 +  newmat - the newly loaded matrix, this needs to have been created with MatCreate()
1101             or some related function before a call to MatLoad()
1102 -  viewer - binary/HDF5 file viewer
1103 
1104    Options Database Keys:
1105    Used with block matrix formats (MATSEQBAIJ,  ...) to specify
1106    block size
1107 .    -matload_block_size <bs>
1108 
1109    Level: beginner
1110 
1111    Notes:
1112    If the Mat type has not yet been given then MATAIJ is used, call MatSetFromOptions() on the
1113    Mat before calling this routine if you wish to set it from the options database.
1114 
1115    MatLoad() automatically loads into the options database any options
1116    given in the file filename.info where filename is the name of the file
1117    that was passed to the PetscViewerBinaryOpen(). The options in the info
1118    file will be ignored if you use the -viewer_binary_skip_info option.
1119 
1120    If the type or size of newmat is not set before a call to MatLoad, PETSc
1121    sets the default matrix type AIJ and sets the local and global sizes.
1122    If type and/or size is already set, then the same are used.
1123 
1124    In parallel, each processor can load a subset of rows (or the
1125    entire matrix).  This routine is especially useful when a large
1126    matrix is stored on disk and only part of it is desired on each
1127    processor.  For example, a parallel solver may access only some of
1128    the rows from each processor.  The algorithm used here reads
1129    relatively small blocks of data rather than reading the entire
1130    matrix and then subsetting it.
1131 
1132    Viewer's PetscViewerType must be either PETSCVIEWERBINARY or PETSCVIEWERHDF5.
1133    Such viewer can be created using PetscViewerBinaryOpen()/PetscViewerHDF5Open(),
1134    or the sequence like
1135 $    PetscViewer v;
1136 $    PetscViewerCreate(PETSC_COMM_WORLD,&v);
1137 $    PetscViewerSetType(v,PETSCVIEWERBINARY);
1138 $    PetscViewerSetFromOptions(v);
1139 $    PetscViewerFileSetMode(v,FILE_MODE_READ);
1140 $    PetscViewerFileSetName(v,"datafile");
1141    The optional PetscViewerSetFromOptions() call allows to override PetscViewerSetType() using option
1142 $ -viewer_type {binary,hdf5}
1143 
1144    See the example src/ksp/ksp/examples/tutorials/ex27.c with the first approach,
1145    and src/mat/examples/tutorials/ex10.c with the second approach.
1146 
1147    Notes about the PETSc binary format:
1148    In case of PETSCVIEWERBINARY, a native PETSc binary format is used. Each of the blocks
1149    is read onto rank 0 and then shipped to its destination rank, one after another.
1150    Multiple objects, both matrices and vectors, can be stored within the same file.
1151    Their PetscObject name is ignored; they are loaded in the order of their storage.
1152 
1153    Most users should not need to know the details of the binary storage
1154    format, since MatLoad() and MatView() completely hide these details.
1155    But for anyone who's interested, the standard binary matrix storage
1156    format is
1157 
1158 $    int    MAT_FILE_CLASSID
1159 $    int    number of rows
1160 $    int    number of columns
1161 $    int    total number of nonzeros
1162 $    int    *number nonzeros in each row
1163 $    int    *column indices of all nonzeros (starting index is zero)
1164 $    PetscScalar *values of all nonzeros
1165 
1166    PETSc automatically does the byte swapping for
1167 machines that store the bytes reversed, e.g.  DEC alpha, freebsd,
1168 linux, Windows and the paragon; thus if you write your own binary
1169 read/write routines you have to swap the bytes; see PetscBinaryRead()
1170 and PetscBinaryWrite() to see how this may be done.
1171 
1172    Notes about the HDF5 (MATLAB MAT-File Version 7.3) format:
1173    In case of PETSCVIEWERHDF5, a parallel HDF5 reader is used.
1174    Each processor's chunk is loaded independently by its owning rank.
1175    Multiple objects, both matrices and vectors, can be stored within the same file.
1176    They are looked up by their PetscObject name.
1177 
1178    As the MATLAB MAT-File Version 7.3 format is also a HDF5 flavor, we decided to use
1179    by default the same structure and naming of the AIJ arrays and column count
1180    within the HDF5 file. This means that a MAT file saved with -v7.3 flag, e.g.
1181 $    save example.mat A b -v7.3
1182    can be directly read by this routine (see Reference 1 for details).
1183    Note that depending on your MATLAB version, this format might be a default,
1184    otherwise you can set it as default in Preferences.
1185 
1186    Unless -nocompression flag is used to save the file in MATLAB,
1187    PETSc must be configured with ZLIB package.
1188 
1189    See also examples src/mat/examples/tutorials/ex10.c and src/ksp/ksp/examples/tutorials/ex27.c
1190 
1191    Current HDF5 (MAT-File) limitations:
1192    This reader currently supports only real MATSEQAIJ and MATMPIAIJ matrices.
1193 
1194    Corresponding MatView() is not yet implemented.
1195 
1196    The loaded matrix is actually a transpose of the original one in MATLAB,
1197    unless you push PETSC_VIEWER_HDF5_MAT format (see examples above).
1198    With this format, matrix is automatically transposed by PETSc,
1199    unless the matrix is marked as SPD or symmetric
1200    (see MatSetOption(), MAT_SPD, MAT_SYMMETRIC).
1201 
1202    References:
1203 1. MATLAB(R) Documentation, manual page of save(), https://www.mathworks.com/help/matlab/ref/save.html#btox10b-1-version
1204 
1205 .seealso: PetscViewerBinaryOpen(), PetscViewerSetType(), MatView(), VecLoad()
1206 
1207  @*/
1208 PetscErrorCode MatLoad(Mat newmat,PetscViewer viewer)
1209 {
1210   PetscErrorCode ierr;
1211   PetscBool      flg;
1212 
1213   PetscFunctionBegin;
1214   PetscValidHeaderSpecific(newmat,MAT_CLASSID,1);
1215   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1216 
1217   if (!((PetscObject)newmat)->type_name) {
1218     ierr = MatSetType(newmat,MATAIJ);CHKERRQ(ierr);
1219   }
1220 
1221   flg  = PETSC_FALSE;
1222   ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,NULL);CHKERRQ(ierr);
1223   if (flg) {
1224     ierr = MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
1225     ierr = MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);CHKERRQ(ierr);
1226   }
1227   flg  = PETSC_FALSE;
1228   ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_spd",&flg,NULL);CHKERRQ(ierr);
1229   if (flg) {
1230     ierr = MatSetOption(newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr);
1231   }
1232 
1233   if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type");
1234   ierr = PetscLogEventBegin(MAT_Load,viewer,0,0,0);CHKERRQ(ierr);
1235   ierr = (*newmat->ops->load)(newmat,viewer);CHKERRQ(ierr);
1236   ierr = PetscLogEventEnd(MAT_Load,viewer,0,0,0);CHKERRQ(ierr);
1237   PetscFunctionReturn(0);
1238 }
1239 
1240 PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant)
1241 {
1242   PetscErrorCode ierr;
1243   Mat_Redundant  *redund = *redundant;
1244   PetscInt       i;
1245 
1246   PetscFunctionBegin;
1247   if (redund){
1248     if (redund->matseq) { /* via MatCreateSubMatrices()  */
1249       ierr = ISDestroy(&redund->isrow);CHKERRQ(ierr);
1250       ierr = ISDestroy(&redund->iscol);CHKERRQ(ierr);
1251       ierr = MatDestroySubMatrices(1,&redund->matseq);CHKERRQ(ierr);
1252     } else {
1253       ierr = PetscFree2(redund->send_rank,redund->recv_rank);CHKERRQ(ierr);
1254       ierr = PetscFree(redund->sbuf_j);CHKERRQ(ierr);
1255       ierr = PetscFree(redund->sbuf_a);CHKERRQ(ierr);
1256       for (i=0; i<redund->nrecvs; i++) {
1257         ierr = PetscFree(redund->rbuf_j[i]);CHKERRQ(ierr);
1258         ierr = PetscFree(redund->rbuf_a[i]);CHKERRQ(ierr);
1259       }
1260       ierr = PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a);CHKERRQ(ierr);
1261     }
1262 
1263     if (redund->subcomm) {
1264       ierr = PetscCommDestroy(&redund->subcomm);CHKERRQ(ierr);
1265     }
1266     ierr = PetscFree(redund);CHKERRQ(ierr);
1267   }
1268   PetscFunctionReturn(0);
1269 }
1270 
1271 /*@
1272    MatDestroy - Frees space taken by a matrix.
1273 
1274    Collective on Mat
1275 
1276    Input Parameter:
1277 .  A - the matrix
1278 
1279    Level: beginner
1280 
1281 @*/
1282 PetscErrorCode MatDestroy(Mat *A)
1283 {
1284   PetscErrorCode ierr;
1285 
1286   PetscFunctionBegin;
1287   if (!*A) PetscFunctionReturn(0);
1288   PetscValidHeaderSpecific(*A,MAT_CLASSID,1);
1289   if (--((PetscObject)(*A))->refct > 0) {*A = NULL; PetscFunctionReturn(0);}
1290 
1291   /* if memory was published with SAWs then destroy it */
1292   ierr = PetscObjectSAWsViewOff((PetscObject)*A);CHKERRQ(ierr);
1293   if ((*A)->ops->destroy) {
1294     ierr = (*(*A)->ops->destroy)(*A);CHKERRQ(ierr);
1295   }
1296 
1297   ierr = PetscFree((*A)->defaultvectype);CHKERRQ(ierr);
1298   ierr = PetscFree((*A)->bsizes);CHKERRQ(ierr);
1299   ierr = PetscFree((*A)->solvertype);CHKERRQ(ierr);
1300   ierr = MatDestroy_Redundant(&(*A)->redundant);CHKERRQ(ierr);
1301   ierr = MatNullSpaceDestroy(&(*A)->nullsp);CHKERRQ(ierr);
1302   ierr = MatNullSpaceDestroy(&(*A)->transnullsp);CHKERRQ(ierr);
1303   ierr = MatNullSpaceDestroy(&(*A)->nearnullsp);CHKERRQ(ierr);
1304   ierr = MatDestroy(&(*A)->schur);CHKERRQ(ierr);
1305   ierr = PetscLayoutDestroy(&(*A)->rmap);CHKERRQ(ierr);
1306   ierr = PetscLayoutDestroy(&(*A)->cmap);CHKERRQ(ierr);
1307   ierr = PetscHeaderDestroy(A);CHKERRQ(ierr);
1308   PetscFunctionReturn(0);
1309 }
1310 
1311 /*@C
1312    MatSetValues - Inserts or adds a block of values into a matrix.
1313    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1314    MUST be called after all calls to MatSetValues() have been completed.
1315 
1316    Not Collective
1317 
1318    Input Parameters:
1319 +  mat - the matrix
1320 .  v - a logically two-dimensional array of values
1321 .  m, idxm - the number of rows and their global indices
1322 .  n, idxn - the number of columns and their global indices
1323 -  addv - either ADD_VALUES or INSERT_VALUES, where
1324    ADD_VALUES adds values to any existing entries, and
1325    INSERT_VALUES replaces existing entries with new values
1326 
1327    Notes:
1328    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
1329       MatSetUp() before using this routine
1330 
1331    By default the values, v, are row-oriented. See MatSetOption() for other options.
1332 
1333    Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
1334    options cannot be mixed without intervening calls to the assembly
1335    routines.
1336 
1337    MatSetValues() uses 0-based row and column numbers in Fortran
1338    as well as in C.
1339 
1340    Negative indices may be passed in idxm and idxn, these rows and columns are
1341    simply ignored. This allows easily inserting element stiffness matrices
1342    with homogeneous Dirchlet boundary conditions that you don't want represented
1343    in the matrix.
1344 
1345    Efficiency Alert:
1346    The routine MatSetValuesBlocked() may offer much better efficiency
1347    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1348 
1349    Level: beginner
1350 
1351    Developer Notes:
1352     This is labeled with C so does not automatically generate Fortran stubs and interfaces
1353                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
1354 
1355    Concepts: matrices^putting entries in
1356 
1357 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1358           InsertMode, INSERT_VALUES, ADD_VALUES
1359 @*/
1360 PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1361 {
1362   PetscErrorCode ierr;
1363 #if defined(PETSC_USE_DEBUG)
1364   PetscInt       i,j;
1365 #endif
1366 
1367   PetscFunctionBeginHot;
1368   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1369   PetscValidType(mat,1);
1370   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1371   PetscValidIntPointer(idxm,3);
1372   PetscValidIntPointer(idxn,5);
1373   PetscValidScalarPointer(v,6);
1374   MatCheckPreallocated(mat,1);
1375   if (mat->insertmode == NOT_SET_VALUES) {
1376     mat->insertmode = addv;
1377   }
1378 #if defined(PETSC_USE_DEBUG)
1379   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1380   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1381   if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1382 
1383   for (i=0; i<m; i++) {
1384     for (j=0; j<n; j++) {
1385       if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j]))
1386 #if defined(PETSC_USE_COMPLEX)
1387         SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g+ig at matrix entry (%D,%D)",(double)PetscRealPart(v[i*n+j]),(double)PetscImaginaryPart(v[i*n+j]),idxm[i],idxn[j]);
1388 #else
1389         SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%D,%D)",(double)v[i*n+j],idxm[i],idxn[j]);
1390 #endif
1391     }
1392   }
1393 #endif
1394 
1395   if (mat->assembled) {
1396     mat->was_assembled = PETSC_TRUE;
1397     mat->assembled     = PETSC_FALSE;
1398   }
1399   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1400   ierr = (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
1401   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1402 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1403   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1404     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1405   }
1406 #endif
1407   PetscFunctionReturn(0);
1408 }
1409 
1410 
1411 /*@
1412    MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
1413         values into a matrix
1414 
1415    Not Collective
1416 
1417    Input Parameters:
1418 +  mat - the matrix
1419 .  row - the (block) row to set
1420 -  v - a logically two-dimensional array of values
1421 
1422    Notes:
1423    By the values, v, are column-oriented (for the block version) and sorted
1424 
1425    All the nonzeros in the row must be provided
1426 
1427    The matrix must have previously had its column indices set
1428 
1429    The row must belong to this process
1430 
1431    Level: intermediate
1432 
1433    Concepts: matrices^putting entries in
1434 
1435 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1436           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping()
1437 @*/
1438 PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
1439 {
1440   PetscErrorCode ierr;
1441   PetscInt       globalrow;
1442 
1443   PetscFunctionBegin;
1444   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1445   PetscValidType(mat,1);
1446   PetscValidScalarPointer(v,2);
1447   ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);CHKERRQ(ierr);
1448   ierr = MatSetValuesRow(mat,globalrow,v);CHKERRQ(ierr);
1449 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1450   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1451     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1452   }
1453 #endif
1454   PetscFunctionReturn(0);
1455 }
1456 
1457 /*@
1458    MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
1459         values into a matrix
1460 
1461    Not Collective
1462 
1463    Input Parameters:
1464 +  mat - the matrix
1465 .  row - the (block) row to set
1466 -  v - a logically two-dimensional (column major) array of values for  block matrices with blocksize larger than one, otherwise a one dimensional array of values
1467 
1468    Notes:
1469    The values, v, are column-oriented for the block version.
1470 
1471    All the nonzeros in the row must be provided
1472 
1473    THE MATRIX MUST HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually MatSetValues() is used.
1474 
1475    The row must belong to this process
1476 
1477    Level: advanced
1478 
1479    Concepts: matrices^putting entries in
1480 
1481 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1482           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1483 @*/
1484 PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
1485 {
1486   PetscErrorCode ierr;
1487 
1488   PetscFunctionBeginHot;
1489   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1490   PetscValidType(mat,1);
1491   MatCheckPreallocated(mat,1);
1492   PetscValidScalarPointer(v,2);
1493 #if defined(PETSC_USE_DEBUG)
1494   if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
1495   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1496 #endif
1497   mat->insertmode = INSERT_VALUES;
1498 
1499   if (mat->assembled) {
1500     mat->was_assembled = PETSC_TRUE;
1501     mat->assembled     = PETSC_FALSE;
1502   }
1503   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1504   if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1505   ierr = (*mat->ops->setvaluesrow)(mat,row,v);CHKERRQ(ierr);
1506   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1507 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1508   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1509     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1510   }
1511 #endif
1512   PetscFunctionReturn(0);
1513 }
1514 
1515 /*@
1516    MatSetValuesStencil - Inserts or adds a block of values into a matrix.
1517      Using structured grid indexing
1518 
1519    Not Collective
1520 
1521    Input Parameters:
1522 +  mat - the matrix
1523 .  m - number of rows being entered
1524 .  idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
1525 .  n - number of columns being entered
1526 .  idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered
1527 .  v - a logically two-dimensional array of values
1528 -  addv - either ADD_VALUES or INSERT_VALUES, where
1529    ADD_VALUES adds values to any existing entries, and
1530    INSERT_VALUES replaces existing entries with new values
1531 
1532    Notes:
1533    By default the values, v, are row-oriented.  See MatSetOption() for other options.
1534 
1535    Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
1536    options cannot be mixed without intervening calls to the assembly
1537    routines.
1538 
1539    The grid coordinates are across the entire grid, not just the local portion
1540 
1541    MatSetValuesStencil() uses 0-based row and column numbers in Fortran
1542    as well as in C.
1543 
1544    For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1545 
1546    In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1547    or call MatSetLocalToGlobalMapping() and MatSetStencil() first.
1548 
1549    The columns and rows in the stencil passed in MUST be contained within the
1550    ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1551    if you create a DMDA with an overlap of one grid level and on a particular process its first
1552    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1553    first i index you can use in your column and row indices in MatSetStencil() is 5.
1554 
1555    In Fortran idxm and idxn should be declared as
1556 $     MatStencil idxm(4,m),idxn(4,n)
1557    and the values inserted using
1558 $    idxm(MatStencil_i,1) = i
1559 $    idxm(MatStencil_j,1) = j
1560 $    idxm(MatStencil_k,1) = k
1561 $    idxm(MatStencil_c,1) = c
1562    etc
1563 
1564    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
1565    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
1566    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
1567    DM_BOUNDARY_PERIODIC boundary type.
1568 
1569    For indices that don't mean anything for your case (like the k index when working in 2d) or the c index when you have
1570    a single value per point) you can skip filling those indices.
1571 
1572    Inspired by the structured grid interface to the HYPRE package
1573    (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods)
1574 
1575    Efficiency Alert:
1576    The routine MatSetValuesBlockedStencil() may offer much better efficiency
1577    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1578 
1579    Level: beginner
1580 
1581    Concepts: matrices^putting entries in
1582 
1583 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1584           MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil
1585 @*/
1586 PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1587 {
1588   PetscErrorCode ierr;
1589   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1590   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1591   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1592 
1593   PetscFunctionBegin;
1594   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1595   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1596   PetscValidType(mat,1);
1597   PetscValidIntPointer(idxm,3);
1598   PetscValidIntPointer(idxn,5);
1599   PetscValidScalarPointer(v,6);
1600 
1601   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1602     jdxm = buf; jdxn = buf+m;
1603   } else {
1604     ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr);
1605     jdxm = bufm; jdxn = bufn;
1606   }
1607   for (i=0; i<m; i++) {
1608     for (j=0; j<3-sdim; j++) dxm++;
1609     tmp = *dxm++ - starts[0];
1610     for (j=0; j<dim-1; j++) {
1611       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1612       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1613     }
1614     if (mat->stencil.noc) dxm++;
1615     jdxm[i] = tmp;
1616   }
1617   for (i=0; i<n; i++) {
1618     for (j=0; j<3-sdim; j++) dxn++;
1619     tmp = *dxn++ - starts[0];
1620     for (j=0; j<dim-1; j++) {
1621       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1622       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1623     }
1624     if (mat->stencil.noc) dxn++;
1625     jdxn[i] = tmp;
1626   }
1627   ierr = MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr);
1628   ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr);
1629   PetscFunctionReturn(0);
1630 }
1631 
1632 /*@
1633    MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1634      Using structured grid indexing
1635 
1636    Not Collective
1637 
1638    Input Parameters:
1639 +  mat - the matrix
1640 .  m - number of rows being entered
1641 .  idxm - grid coordinates for matrix rows being entered
1642 .  n - number of columns being entered
1643 .  idxn - grid coordinates for matrix columns being entered
1644 .  v - a logically two-dimensional array of values
1645 -  addv - either ADD_VALUES or INSERT_VALUES, where
1646    ADD_VALUES adds values to any existing entries, and
1647    INSERT_VALUES replaces existing entries with new values
1648 
1649    Notes:
1650    By default the values, v, are row-oriented and unsorted.
1651    See MatSetOption() for other options.
1652 
1653    Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
1654    options cannot be mixed without intervening calls to the assembly
1655    routines.
1656 
1657    The grid coordinates are across the entire grid, not just the local portion
1658 
1659    MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran
1660    as well as in C.
1661 
1662    For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1663 
1664    In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1665    or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first.
1666 
1667    The columns and rows in the stencil passed in MUST be contained within the
1668    ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1669    if you create a DMDA with an overlap of one grid level and on a particular process its first
1670    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1671    first i index you can use in your column and row indices in MatSetStencil() is 5.
1672 
1673    In Fortran idxm and idxn should be declared as
1674 $     MatStencil idxm(4,m),idxn(4,n)
1675    and the values inserted using
1676 $    idxm(MatStencil_i,1) = i
1677 $    idxm(MatStencil_j,1) = j
1678 $    idxm(MatStencil_k,1) = k
1679    etc
1680 
1681    Negative indices may be passed in idxm and idxn, these rows and columns are
1682    simply ignored. This allows easily inserting element stiffness matrices
1683    with homogeneous Dirchlet boundary conditions that you don't want represented
1684    in the matrix.
1685 
1686    Inspired by the structured grid interface to the HYPRE package
1687    (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods)
1688 
1689    Level: beginner
1690 
1691    Concepts: matrices^putting entries in
1692 
1693 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1694           MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil,
1695           MatSetBlockSize(), MatSetLocalToGlobalMapping()
1696 @*/
1697 PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1698 {
1699   PetscErrorCode ierr;
1700   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1701   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1702   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1703 
1704   PetscFunctionBegin;
1705   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1706   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1707   PetscValidType(mat,1);
1708   PetscValidIntPointer(idxm,3);
1709   PetscValidIntPointer(idxn,5);
1710   PetscValidScalarPointer(v,6);
1711 
1712   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1713     jdxm = buf; jdxn = buf+m;
1714   } else {
1715     ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr);
1716     jdxm = bufm; jdxn = bufn;
1717   }
1718   for (i=0; i<m; i++) {
1719     for (j=0; j<3-sdim; j++) dxm++;
1720     tmp = *dxm++ - starts[0];
1721     for (j=0; j<sdim-1; j++) {
1722       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1723       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1724     }
1725     dxm++;
1726     jdxm[i] = tmp;
1727   }
1728   for (i=0; i<n; i++) {
1729     for (j=0; j<3-sdim; j++) dxn++;
1730     tmp = *dxn++ - starts[0];
1731     for (j=0; j<sdim-1; j++) {
1732       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1733       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1734     }
1735     dxn++;
1736     jdxn[i] = tmp;
1737   }
1738   ierr = MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr);
1739   ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr);
1740 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1741   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1742     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1743   }
1744 #endif
1745   PetscFunctionReturn(0);
1746 }
1747 
1748 /*@
1749    MatSetStencil - Sets the grid information for setting values into a matrix via
1750         MatSetValuesStencil()
1751 
1752    Not Collective
1753 
1754    Input Parameters:
1755 +  mat - the matrix
1756 .  dim - dimension of the grid 1, 2, or 3
1757 .  dims - number of grid points in x, y, and z direction, including ghost points on your processor
1758 .  starts - starting point of ghost nodes on your processor in x, y, and z direction
1759 -  dof - number of degrees of freedom per node
1760 
1761 
1762    Inspired by the structured grid interface to the HYPRE package
1763    (www.llnl.gov/CASC/hyper)
1764 
1765    For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the
1766    user.
1767 
1768    Level: beginner
1769 
1770    Concepts: matrices^putting entries in
1771 
1772 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1773           MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
1774 @*/
1775 PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1776 {
1777   PetscInt i;
1778 
1779   PetscFunctionBegin;
1780   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1781   PetscValidIntPointer(dims,3);
1782   PetscValidIntPointer(starts,4);
1783 
1784   mat->stencil.dim = dim + (dof > 1);
1785   for (i=0; i<dim; i++) {
1786     mat->stencil.dims[i]   = dims[dim-i-1];      /* copy the values in backwards */
1787     mat->stencil.starts[i] = starts[dim-i-1];
1788   }
1789   mat->stencil.dims[dim]   = dof;
1790   mat->stencil.starts[dim] = 0;
1791   mat->stencil.noc         = (PetscBool)(dof == 1);
1792   PetscFunctionReturn(0);
1793 }
1794 
1795 /*@C
1796    MatSetValuesBlocked - Inserts or adds a block of values into a matrix.
1797 
1798    Not Collective
1799 
1800    Input Parameters:
1801 +  mat - the matrix
1802 .  v - a logically two-dimensional array of values
1803 .  m, idxm - the number of block rows and their global block indices
1804 .  n, idxn - the number of block columns and their global block indices
1805 -  addv - either ADD_VALUES or INSERT_VALUES, where
1806    ADD_VALUES adds values to any existing entries, and
1807    INSERT_VALUES replaces existing entries with new values
1808 
1809    Notes:
1810    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call
1811    MatXXXXSetPreallocation() or MatSetUp() before using this routine.
1812 
1813    The m and n count the NUMBER of blocks in the row direction and column direction,
1814    NOT the total number of rows/columns; for example, if the block size is 2 and
1815    you are passing in values for rows 2,3,4,5  then m would be 2 (not 4).
1816    The values in idxm would be 1 2; that is the first index for each block divided by
1817    the block size.
1818 
1819    Note that you must call MatSetBlockSize() when constructing this matrix (before
1820    preallocating it).
1821 
1822    By default the values, v, are row-oriented, so the layout of
1823    v is the same as for MatSetValues(). See MatSetOption() for other options.
1824 
1825    Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
1826    options cannot be mixed without intervening calls to the assembly
1827    routines.
1828 
1829    MatSetValuesBlocked() uses 0-based row and column numbers in Fortran
1830    as well as in C.
1831 
1832    Negative indices may be passed in idxm and idxn, these rows and columns are
1833    simply ignored. This allows easily inserting element stiffness matrices
1834    with homogeneous Dirchlet boundary conditions that you don't want represented
1835    in the matrix.
1836 
1837    Each time an entry is set within a sparse matrix via MatSetValues(),
1838    internal searching must be done to determine where to place the
1839    data in the matrix storage space.  By instead inserting blocks of
1840    entries via MatSetValuesBlocked(), the overhead of matrix assembly is
1841    reduced.
1842 
1843    Example:
1844 $   Suppose m=n=2 and block size(bs) = 2 The array is
1845 $
1846 $   1  2  | 3  4
1847 $   5  6  | 7  8
1848 $   - - - | - - -
1849 $   9  10 | 11 12
1850 $   13 14 | 15 16
1851 $
1852 $   v[] should be passed in like
1853 $   v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
1854 $
1855 $  If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then
1856 $   v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16]
1857 
1858    Level: intermediate
1859 
1860    Concepts: matrices^putting entries in blocked
1861 
1862 .seealso: MatSetBlockSize(), MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal()
1863 @*/
1864 PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1865 {
1866   PetscErrorCode ierr;
1867 
1868   PetscFunctionBeginHot;
1869   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1870   PetscValidType(mat,1);
1871   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1872   PetscValidIntPointer(idxm,3);
1873   PetscValidIntPointer(idxn,5);
1874   PetscValidScalarPointer(v,6);
1875   MatCheckPreallocated(mat,1);
1876   if (mat->insertmode == NOT_SET_VALUES) {
1877     mat->insertmode = addv;
1878   }
1879 #if defined(PETSC_USE_DEBUG)
1880   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1881   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1882   if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1883 #endif
1884 
1885   if (mat->assembled) {
1886     mat->was_assembled = PETSC_TRUE;
1887     mat->assembled     = PETSC_FALSE;
1888   }
1889   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1890   if (mat->ops->setvaluesblocked) {
1891     ierr = (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
1892   } else {
1893     PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn;
1894     PetscInt i,j,bs,cbs;
1895     ierr = MatGetBlockSizes(mat,&bs,&cbs);CHKERRQ(ierr);
1896     if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1897       iidxm = buf; iidxn = buf + m*bs;
1898     } else {
1899       ierr  = PetscMalloc2(m*bs,&bufr,n*cbs,&bufc);CHKERRQ(ierr);
1900       iidxm = bufr; iidxn = bufc;
1901     }
1902     for (i=0; i<m; i++) {
1903       for (j=0; j<bs; j++) {
1904         iidxm[i*bs+j] = bs*idxm[i] + j;
1905       }
1906     }
1907     for (i=0; i<n; i++) {
1908       for (j=0; j<cbs; j++) {
1909         iidxn[i*cbs+j] = cbs*idxn[i] + j;
1910       }
1911     }
1912     ierr = MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv);CHKERRQ(ierr);
1913     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
1914   }
1915   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1916 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1917   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1918     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1919   }
1920 #endif
1921   PetscFunctionReturn(0);
1922 }
1923 
1924 /*@
1925    MatGetValues - Gets a block of values from a matrix.
1926 
1927    Not Collective; currently only returns a local block
1928 
1929    Input Parameters:
1930 +  mat - the matrix
1931 .  v - a logically two-dimensional array for storing the values
1932 .  m, idxm - the number of rows and their global indices
1933 -  n, idxn - the number of columns and their global indices
1934 
1935    Notes:
1936    The user must allocate space (m*n PetscScalars) for the values, v.
1937    The values, v, are then returned in a row-oriented format,
1938    analogous to that used by default in MatSetValues().
1939 
1940    MatGetValues() uses 0-based row and column numbers in
1941    Fortran as well as in C.
1942 
1943    MatGetValues() requires that the matrix has been assembled
1944    with MatAssemblyBegin()/MatAssemblyEnd().  Thus, calls to
1945    MatSetValues() and MatGetValues() CANNOT be made in succession
1946    without intermediate matrix assembly.
1947 
1948    Negative row or column indices will be ignored and those locations in v[] will be
1949    left unchanged.
1950 
1951    Level: advanced
1952 
1953    Concepts: matrices^accessing values
1954 
1955 .seealso: MatGetRow(), MatCreateSubMatrices(), MatSetValues()
1956 @*/
1957 PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1958 {
1959   PetscErrorCode ierr;
1960 
1961   PetscFunctionBegin;
1962   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1963   PetscValidType(mat,1);
1964   if (!m || !n) PetscFunctionReturn(0);
1965   PetscValidIntPointer(idxm,3);
1966   PetscValidIntPointer(idxn,5);
1967   PetscValidScalarPointer(v,6);
1968   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1969   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1970   if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1971   MatCheckPreallocated(mat,1);
1972 
1973   ierr = PetscLogEventBegin(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
1974   ierr = (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);CHKERRQ(ierr);
1975   ierr = PetscLogEventEnd(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
1976   PetscFunctionReturn(0);
1977 }
1978 
1979 /*@
1980   MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and
1981   the same size. Currently, this can only be called once and creates the given matrix.
1982 
1983   Not Collective
1984 
1985   Input Parameters:
1986 + mat - the matrix
1987 . nb - the number of blocks
1988 . bs - the number of rows (and columns) in each block
1989 . rows - a concatenation of the rows for each block
1990 - v - a concatenation of logically two-dimensional arrays of values
1991 
1992   Notes:
1993   In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix.
1994 
1995   Level: advanced
1996 
1997   Concepts: matrices^putting entries in
1998 
1999 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
2000           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
2001 @*/
2002 PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[])
2003 {
2004   PetscErrorCode ierr;
2005 
2006   PetscFunctionBegin;
2007   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2008   PetscValidType(mat,1);
2009   PetscValidScalarPointer(rows,4);
2010   PetscValidScalarPointer(v,5);
2011 #if defined(PETSC_USE_DEBUG)
2012   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2013 #endif
2014 
2015   ierr = PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr);
2016   if (mat->ops->setvaluesbatch) {
2017     ierr = (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);CHKERRQ(ierr);
2018   } else {
2019     PetscInt b;
2020     for (b = 0; b < nb; ++b) {
2021       ierr = MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);CHKERRQ(ierr);
2022     }
2023   }
2024   ierr = PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr);
2025   PetscFunctionReturn(0);
2026 }
2027 
2028 /*@
2029    MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
2030    the routine MatSetValuesLocal() to allow users to insert matrix entries
2031    using a local (per-processor) numbering.
2032 
2033    Not Collective
2034 
2035    Input Parameters:
2036 +  x - the matrix
2037 .  rmapping - row mapping created with ISLocalToGlobalMappingCreate()   or ISLocalToGlobalMappingCreateIS()
2038 - cmapping - column mapping
2039 
2040    Level: intermediate
2041 
2042    Concepts: matrices^local to global mapping
2043    Concepts: local to global mapping^for matrices
2044 
2045 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
2046 @*/
2047 PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
2048 {
2049   PetscErrorCode ierr;
2050 
2051   PetscFunctionBegin;
2052   PetscValidHeaderSpecific(x,MAT_CLASSID,1);
2053   PetscValidType(x,1);
2054   PetscValidHeaderSpecific(rmapping,IS_LTOGM_CLASSID,2);
2055   PetscValidHeaderSpecific(cmapping,IS_LTOGM_CLASSID,3);
2056 
2057   if (x->ops->setlocaltoglobalmapping) {
2058     ierr = (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);CHKERRQ(ierr);
2059   } else {
2060     ierr = PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);CHKERRQ(ierr);
2061     ierr = PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);CHKERRQ(ierr);
2062   }
2063   PetscFunctionReturn(0);
2064 }
2065 
2066 
2067 /*@
2068    MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping()
2069 
2070    Not Collective
2071 
2072    Input Parameters:
2073 .  A - the matrix
2074 
2075    Output Parameters:
2076 + rmapping - row mapping
2077 - cmapping - column mapping
2078 
2079    Level: advanced
2080 
2081    Concepts: matrices^local to global mapping
2082    Concepts: local to global mapping^for matrices
2083 
2084 .seealso:  MatSetValuesLocal()
2085 @*/
2086 PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
2087 {
2088   PetscFunctionBegin;
2089   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2090   PetscValidType(A,1);
2091   if (rmapping) PetscValidPointer(rmapping,2);
2092   if (cmapping) PetscValidPointer(cmapping,3);
2093   if (rmapping) *rmapping = A->rmap->mapping;
2094   if (cmapping) *cmapping = A->cmap->mapping;
2095   PetscFunctionReturn(0);
2096 }
2097 
2098 /*@
2099    MatGetLayouts - Gets the PetscLayout objects for rows and columns
2100 
2101    Not Collective
2102 
2103    Input Parameters:
2104 .  A - the matrix
2105 
2106    Output Parameters:
2107 + rmap - row layout
2108 - cmap - column layout
2109 
2110    Level: advanced
2111 
2112 .seealso:  MatCreateVecs(), MatGetLocalToGlobalMapping()
2113 @*/
2114 PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap)
2115 {
2116   PetscFunctionBegin;
2117   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2118   PetscValidType(A,1);
2119   if (rmap) PetscValidPointer(rmap,2);
2120   if (cmap) PetscValidPointer(cmap,3);
2121   if (rmap) *rmap = A->rmap;
2122   if (cmap) *cmap = A->cmap;
2123   PetscFunctionReturn(0);
2124 }
2125 
2126 /*@C
2127    MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
2128    using a local ordering of the nodes.
2129 
2130    Not Collective
2131 
2132    Input Parameters:
2133 +  mat - the matrix
2134 .  nrow, irow - number of rows and their local indices
2135 .  ncol, icol - number of columns and their local indices
2136 .  y -  a logically two-dimensional array of values
2137 -  addv - either INSERT_VALUES or ADD_VALUES, where
2138    ADD_VALUES adds values to any existing entries, and
2139    INSERT_VALUES replaces existing entries with new values
2140 
2141    Notes:
2142    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
2143       MatSetUp() before using this routine
2144 
2145    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine
2146 
2147    Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
2148    options cannot be mixed without intervening calls to the assembly
2149    routines.
2150 
2151    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2152    MUST be called after all calls to MatSetValuesLocal() have been completed.
2153 
2154    Level: intermediate
2155 
2156    Concepts: matrices^putting entries in with local numbering
2157 
2158    Developer Notes:
2159     This is labeled with C so does not automatically generate Fortran stubs and interfaces
2160                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
2161 
2162 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
2163            MatSetValueLocal()
2164 @*/
2165 PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2166 {
2167   PetscErrorCode ierr;
2168 
2169   PetscFunctionBeginHot;
2170   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2171   PetscValidType(mat,1);
2172   MatCheckPreallocated(mat,1);
2173   if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */
2174   PetscValidIntPointer(irow,3);
2175   PetscValidIntPointer(icol,5);
2176   PetscValidScalarPointer(y,6);
2177   if (mat->insertmode == NOT_SET_VALUES) {
2178     mat->insertmode = addv;
2179   }
2180 #if defined(PETSC_USE_DEBUG)
2181   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2182   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2183   if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2184 #endif
2185 
2186   if (mat->assembled) {
2187     mat->was_assembled = PETSC_TRUE;
2188     mat->assembled     = PETSC_FALSE;
2189   }
2190   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2191   if (mat->ops->setvalueslocal) {
2192     ierr = (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr);
2193   } else {
2194     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2195     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2196       irowm = buf; icolm = buf+nrow;
2197     } else {
2198       ierr  = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr);
2199       irowm = bufr; icolm = bufc;
2200     }
2201     ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr);
2202     ierr = ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr);
2203     ierr = MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
2204     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
2205   }
2206   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2207 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
2208   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
2209     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
2210   }
2211 #endif
2212   PetscFunctionReturn(0);
2213 }
2214 
2215 /*@C
2216    MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix,
2217    using a local ordering of the nodes a block at a time.
2218 
2219    Not Collective
2220 
2221    Input Parameters:
2222 +  x - the matrix
2223 .  nrow, irow - number of rows and their local indices
2224 .  ncol, icol - number of columns and their local indices
2225 .  y -  a logically two-dimensional array of values
2226 -  addv - either INSERT_VALUES or ADD_VALUES, where
2227    ADD_VALUES adds values to any existing entries, and
2228    INSERT_VALUES replaces existing entries with new values
2229 
2230    Notes:
2231    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
2232       MatSetUp() before using this routine
2233 
2234    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMapping()
2235       before using this routineBefore calling MatSetValuesLocal(), the user must first set the
2236 
2237    Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
2238    options cannot be mixed without intervening calls to the assembly
2239    routines.
2240 
2241    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2242    MUST be called after all calls to MatSetValuesBlockedLocal() have been completed.
2243 
2244    Level: intermediate
2245 
2246    Developer Notes:
2247     This is labeled with C so does not automatically generate Fortran stubs and interfaces
2248                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
2249 
2250    Concepts: matrices^putting blocked values in with local numbering
2251 
2252 .seealso:  MatSetBlockSize(), MatSetLocalToGlobalMapping(), MatAssemblyBegin(), MatAssemblyEnd(),
2253            MatSetValuesLocal(),  MatSetValuesBlocked()
2254 @*/
2255 PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2256 {
2257   PetscErrorCode ierr;
2258 
2259   PetscFunctionBeginHot;
2260   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2261   PetscValidType(mat,1);
2262   MatCheckPreallocated(mat,1);
2263   if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */
2264   PetscValidIntPointer(irow,3);
2265   PetscValidIntPointer(icol,5);
2266   PetscValidScalarPointer(y,6);
2267   if (mat->insertmode == NOT_SET_VALUES) {
2268     mat->insertmode = addv;
2269   }
2270 #if defined(PETSC_USE_DEBUG)
2271   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2272   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2273   if (!mat->ops->setvaluesblockedlocal && !mat->ops->setvaluesblocked && !mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2274 #endif
2275 
2276   if (mat->assembled) {
2277     mat->was_assembled = PETSC_TRUE;
2278     mat->assembled     = PETSC_FALSE;
2279   }
2280 #if defined(PETSC_USE_DEBUG)
2281   /* Condition on the mapping existing, because MatSetValuesBlockedLocal_IS does not require it to be set. */
2282   if (mat->rmap->mapping) {
2283     PetscInt irbs, rbs;
2284     ierr = MatGetBlockSizes(mat, &rbs, NULL);CHKERRQ(ierr);
2285     ierr = ISLocalToGlobalMappingGetBlockSize(mat->rmap->mapping,&irbs);CHKERRQ(ierr);
2286     if (rbs != irbs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different row block sizes! mat %D, row l2g map %D",rbs,irbs);
2287   }
2288   if (mat->cmap->mapping) {
2289     PetscInt icbs, cbs;
2290     ierr = MatGetBlockSizes(mat,NULL,&cbs);CHKERRQ(ierr);
2291     ierr = ISLocalToGlobalMappingGetBlockSize(mat->cmap->mapping,&icbs);CHKERRQ(ierr);
2292     if (cbs != icbs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different col block sizes! mat %D, col l2g map %D",cbs,icbs);
2293   }
2294 #endif
2295   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2296   if (mat->ops->setvaluesblockedlocal) {
2297     ierr = (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr);
2298   } else {
2299     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2300     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2301       irowm = buf; icolm = buf + nrow;
2302     } else {
2303       ierr  = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr);
2304       irowm = bufr; icolm = bufc;
2305     }
2306     ierr = ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr);
2307     ierr = ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr);
2308     ierr = MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
2309     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
2310   }
2311   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2312 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
2313   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
2314     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
2315   }
2316 #endif
2317   PetscFunctionReturn(0);
2318 }
2319 
2320 /*@
2321    MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal
2322 
2323    Collective on Mat and Vec
2324 
2325    Input Parameters:
2326 +  mat - the matrix
2327 -  x   - the vector to be multiplied
2328 
2329    Output Parameters:
2330 .  y - the result
2331 
2332    Notes:
2333    The vectors x and y cannot be the same.  I.e., one cannot
2334    call MatMult(A,y,y).
2335 
2336    Level: developer
2337 
2338    Concepts: matrix-vector product
2339 
2340 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2341 @*/
2342 PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y)
2343 {
2344   PetscErrorCode ierr;
2345 
2346   PetscFunctionBegin;
2347   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2348   PetscValidType(mat,1);
2349   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2350   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2351 
2352   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2353   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2354   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2355   MatCheckPreallocated(mat,1);
2356 
2357   if (!mat->ops->multdiagonalblock) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2358   ierr = (*mat->ops->multdiagonalblock)(mat,x,y);CHKERRQ(ierr);
2359   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2360   PetscFunctionReturn(0);
2361 }
2362 
2363 /* --------------------------------------------------------*/
2364 /*@
2365    MatMult - Computes the matrix-vector product, y = Ax.
2366 
2367    Neighbor-wise Collective on Mat and Vec
2368 
2369    Input Parameters:
2370 +  mat - the matrix
2371 -  x   - the vector to be multiplied
2372 
2373    Output Parameters:
2374 .  y - the result
2375 
2376    Notes:
2377    The vectors x and y cannot be the same.  I.e., one cannot
2378    call MatMult(A,y,y).
2379 
2380    Level: beginner
2381 
2382    Concepts: matrix-vector product
2383 
2384 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2385 @*/
2386 PetscErrorCode MatMult(Mat mat,Vec x,Vec y)
2387 {
2388   PetscErrorCode ierr;
2389 
2390   PetscFunctionBegin;
2391   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2392   PetscValidType(mat,1);
2393   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2394   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2395   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2396   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2397   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2398 #if !defined(PETSC_HAVE_CONSTRAINTS)
2399   if (mat->cmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
2400   if (mat->rmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
2401   if (mat->rmap->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %D %D",mat->rmap->n,y->map->n);
2402 #endif
2403   ierr = VecSetErrorIfLocked(y,3);CHKERRQ(ierr);
2404   if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);}
2405   MatCheckPreallocated(mat,1);
2406 
2407   ierr = VecLockReadPush(x);CHKERRQ(ierr);
2408   if (!mat->ops->mult) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2409   ierr = PetscLogEventBegin(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
2410   ierr = (*mat->ops->mult)(mat,x,y);CHKERRQ(ierr);
2411   ierr = PetscLogEventEnd(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
2412   if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);}
2413   ierr = VecLockReadPop(x);CHKERRQ(ierr);
2414   PetscFunctionReturn(0);
2415 }
2416 
2417 /*@
2418    MatMultTranspose - Computes matrix transpose times a vector y = A^T * x.
2419 
2420    Neighbor-wise Collective on Mat and Vec
2421 
2422    Input Parameters:
2423 +  mat - the matrix
2424 -  x   - the vector to be multiplied
2425 
2426    Output Parameters:
2427 .  y - the result
2428 
2429    Notes:
2430    The vectors x and y cannot be the same.  I.e., one cannot
2431    call MatMultTranspose(A,y,y).
2432 
2433    For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple,
2434    use MatMultHermitianTranspose()
2435 
2436    Level: beginner
2437 
2438    Concepts: matrix vector product^transpose
2439 
2440 .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose()
2441 @*/
2442 PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y)
2443 {
2444   PetscErrorCode ierr;
2445 
2446   PetscFunctionBegin;
2447   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2448   PetscValidType(mat,1);
2449   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2450   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2451 
2452   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2453   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2454   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2455 #if !defined(PETSC_HAVE_CONSTRAINTS)
2456   if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
2457   if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N);
2458 #endif
2459   if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);}
2460   MatCheckPreallocated(mat,1);
2461 
2462   if (!mat->ops->multtranspose) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply transpose defined");
2463   ierr = PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
2464   ierr = VecLockReadPush(x);CHKERRQ(ierr);
2465   ierr = (*mat->ops->multtranspose)(mat,x,y);CHKERRQ(ierr);
2466   ierr = VecLockReadPop(x);CHKERRQ(ierr);
2467   ierr = PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
2468   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2469   if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);}
2470   PetscFunctionReturn(0);
2471 }
2472 
2473 /*@
2474    MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.
2475 
2476    Neighbor-wise Collective on Mat and Vec
2477 
2478    Input Parameters:
2479 +  mat - the matrix
2480 -  x   - the vector to be multilplied
2481 
2482    Output Parameters:
2483 .  y - the result
2484 
2485    Notes:
2486    The vectors x and y cannot be the same.  I.e., one cannot
2487    call MatMultHermitianTranspose(A,y,y).
2488 
2489    Also called the conjugate transpose, complex conjugate transpose, or adjoint.
2490 
2491    For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical.
2492 
2493    Level: beginner
2494 
2495    Concepts: matrix vector product^transpose
2496 
2497 .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose()
2498 @*/
2499 PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y)
2500 {
2501   PetscErrorCode ierr;
2502   Vec            w;
2503 
2504   PetscFunctionBegin;
2505   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2506   PetscValidType(mat,1);
2507   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2508   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2509 
2510   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2511   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2512   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2513 #if !defined(PETSC_HAVE_CONSTRAINTS)
2514   if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
2515   if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N);
2516 #endif
2517   MatCheckPreallocated(mat,1);
2518 
2519   ierr = PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr);
2520   if (mat->ops->multhermitiantranspose) {
2521     ierr = VecLockReadPush(x);CHKERRQ(ierr);
2522     ierr = (*mat->ops->multhermitiantranspose)(mat,x,y);CHKERRQ(ierr);
2523     ierr = VecLockReadPop(x);CHKERRQ(ierr);
2524   } else {
2525     ierr = VecDuplicate(x,&w);CHKERRQ(ierr);
2526     ierr = VecCopy(x,w);CHKERRQ(ierr);
2527     ierr = VecConjugate(w);CHKERRQ(ierr);
2528     ierr = MatMultTranspose(mat,w,y);CHKERRQ(ierr);
2529     ierr = VecDestroy(&w);CHKERRQ(ierr);
2530     ierr = VecConjugate(y);CHKERRQ(ierr);
2531   }
2532   ierr = PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr);
2533   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2534   PetscFunctionReturn(0);
2535 }
2536 
2537 /*@
2538     MatMultAdd -  Computes v3 = v2 + A * v1.
2539 
2540     Neighbor-wise Collective on Mat and Vec
2541 
2542     Input Parameters:
2543 +   mat - the matrix
2544 -   v1, v2 - the vectors
2545 
2546     Output Parameters:
2547 .   v3 - the result
2548 
2549     Notes:
2550     The vectors v1 and v3 cannot be the same.  I.e., one cannot
2551     call MatMultAdd(A,v1,v2,v1).
2552 
2553     Level: beginner
2554 
2555     Concepts: matrix vector product^addition
2556 
2557 .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
2558 @*/
2559 PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2560 {
2561   PetscErrorCode ierr;
2562 
2563   PetscFunctionBegin;
2564   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2565   PetscValidType(mat,1);
2566   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2567   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2568   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2569 
2570   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2571   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2572   if (mat->cmap->N != v1->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->cmap->N,v1->map->N);
2573   /* if (mat->rmap->N != v2->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->rmap->N,v2->map->N);
2574      if (mat->rmap->N != v3->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->rmap->N,v3->map->N); */
2575   if (mat->rmap->n != v3->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: local dim %D %D",mat->rmap->n,v3->map->n);
2576   if (mat->rmap->n != v2->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: local dim %D %D",mat->rmap->n,v2->map->n);
2577   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2578   MatCheckPreallocated(mat,1);
2579 
2580   if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name);
2581   ierr = PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2582   ierr = VecLockReadPush(v1);CHKERRQ(ierr);
2583   ierr = (*mat->ops->multadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2584   ierr = VecLockReadPop(v1);CHKERRQ(ierr);
2585   ierr = PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2586   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2587   PetscFunctionReturn(0);
2588 }
2589 
2590 /*@
2591    MatMultTransposeAdd - Computes v3 = v2 + A' * v1.
2592 
2593    Neighbor-wise Collective on Mat and Vec
2594 
2595    Input Parameters:
2596 +  mat - the matrix
2597 -  v1, v2 - the vectors
2598 
2599    Output Parameters:
2600 .  v3 - the result
2601 
2602    Notes:
2603    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2604    call MatMultTransposeAdd(A,v1,v2,v1).
2605 
2606    Level: beginner
2607 
2608    Concepts: matrix vector product^transpose and addition
2609 
2610 .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
2611 @*/
2612 PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2613 {
2614   PetscErrorCode ierr;
2615 
2616   PetscFunctionBegin;
2617   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2618   PetscValidType(mat,1);
2619   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2620   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2621   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2622 
2623   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2624   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2625   if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2626   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2627   if (mat->rmap->N != v1->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->rmap->N,v1->map->N);
2628   if (mat->cmap->N != v2->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->cmap->N,v2->map->N);
2629   if (mat->cmap->N != v3->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->cmap->N,v3->map->N);
2630   MatCheckPreallocated(mat,1);
2631 
2632   ierr = PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2633   ierr = VecLockReadPush(v1);CHKERRQ(ierr);
2634   ierr = (*mat->ops->multtransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2635   ierr = VecLockReadPop(v1);CHKERRQ(ierr);
2636   ierr = PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2637   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2638   PetscFunctionReturn(0);
2639 }
2640 
2641 /*@
2642    MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1.
2643 
2644    Neighbor-wise Collective on Mat and Vec
2645 
2646    Input Parameters:
2647 +  mat - the matrix
2648 -  v1, v2 - the vectors
2649 
2650    Output Parameters:
2651 .  v3 - the result
2652 
2653    Notes:
2654    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2655    call MatMultHermitianTransposeAdd(A,v1,v2,v1).
2656 
2657    Level: beginner
2658 
2659    Concepts: matrix vector product^transpose and addition
2660 
2661 .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult()
2662 @*/
2663 PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2664 {
2665   PetscErrorCode ierr;
2666 
2667   PetscFunctionBegin;
2668   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2669   PetscValidType(mat,1);
2670   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2671   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2672   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2673 
2674   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2675   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2676   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2677   if (mat->rmap->N != v1->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->rmap->N,v1->map->N);
2678   if (mat->cmap->N != v2->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->cmap->N,v2->map->N);
2679   if (mat->cmap->N != v3->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->cmap->N,v3->map->N);
2680   MatCheckPreallocated(mat,1);
2681 
2682   ierr = PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2683   ierr = VecLockReadPush(v1);CHKERRQ(ierr);
2684   if (mat->ops->multhermitiantransposeadd) {
2685     ierr = (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2686   } else {
2687     Vec w,z;
2688     ierr = VecDuplicate(v1,&w);CHKERRQ(ierr);
2689     ierr = VecCopy(v1,w);CHKERRQ(ierr);
2690     ierr = VecConjugate(w);CHKERRQ(ierr);
2691     ierr = VecDuplicate(v3,&z);CHKERRQ(ierr);
2692     ierr = MatMultTranspose(mat,w,z);CHKERRQ(ierr);
2693     ierr = VecDestroy(&w);CHKERRQ(ierr);
2694     ierr = VecConjugate(z);CHKERRQ(ierr);
2695     if (v2 != v3) {
2696       ierr = VecWAXPY(v3,1.0,v2,z);CHKERRQ(ierr);
2697     } else {
2698       ierr = VecAXPY(v3,1.0,z);CHKERRQ(ierr);
2699     }
2700     ierr = VecDestroy(&z);CHKERRQ(ierr);
2701   }
2702   ierr = VecLockReadPop(v1);CHKERRQ(ierr);
2703   ierr = PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2704   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2705   PetscFunctionReturn(0);
2706 }
2707 
2708 /*@
2709    MatMultConstrained - The inner multiplication routine for a
2710    constrained matrix P^T A P.
2711 
2712    Neighbor-wise Collective on Mat and Vec
2713 
2714    Input Parameters:
2715 +  mat - the matrix
2716 -  x   - the vector to be multilplied
2717 
2718    Output Parameters:
2719 .  y - the result
2720 
2721    Notes:
2722    The vectors x and y cannot be the same.  I.e., one cannot
2723    call MatMult(A,y,y).
2724 
2725    Level: beginner
2726 
2727 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2728 @*/
2729 PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y)
2730 {
2731   PetscErrorCode ierr;
2732 
2733   PetscFunctionBegin;
2734   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2735   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2736   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2737   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2738   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2739   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2740   if (mat->cmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
2741   if (mat->rmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
2742   if (mat->rmap->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %D %D",mat->rmap->n,y->map->n);
2743 
2744   ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2745   ierr = VecLockReadPush(x);CHKERRQ(ierr);
2746   ierr = (*mat->ops->multconstrained)(mat,x,y);CHKERRQ(ierr);
2747   ierr = VecLockReadPop(x);CHKERRQ(ierr);
2748   ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2749   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2750   PetscFunctionReturn(0);
2751 }
2752 
2753 /*@
2754    MatMultTransposeConstrained - The inner multiplication routine for a
2755    constrained matrix P^T A^T P.
2756 
2757    Neighbor-wise Collective on Mat and Vec
2758 
2759    Input Parameters:
2760 +  mat - the matrix
2761 -  x   - the vector to be multilplied
2762 
2763    Output Parameters:
2764 .  y - the result
2765 
2766    Notes:
2767    The vectors x and y cannot be the same.  I.e., one cannot
2768    call MatMult(A,y,y).
2769 
2770    Level: beginner
2771 
2772 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2773 @*/
2774 PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2775 {
2776   PetscErrorCode ierr;
2777 
2778   PetscFunctionBegin;
2779   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2780   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2781   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2782   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2783   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2784   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2785   if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
2786   if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
2787 
2788   ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2789   ierr = (*mat->ops->multtransposeconstrained)(mat,x,y);CHKERRQ(ierr);
2790   ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2791   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2792   PetscFunctionReturn(0);
2793 }
2794 
2795 /*@C
2796    MatGetFactorType - gets the type of factorization it is
2797 
2798    Not Collective
2799 
2800    Input Parameters:
2801 .  mat - the matrix
2802 
2803    Output Parameters:
2804 .  t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT
2805 
2806    Level: intermediate
2807 
2808 .seealso: MatFactorType, MatGetFactor(), MatSetFactorType()
2809 @*/
2810 PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t)
2811 {
2812   PetscFunctionBegin;
2813   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2814   PetscValidType(mat,1);
2815   PetscValidPointer(t,2);
2816   *t = mat->factortype;
2817   PetscFunctionReturn(0);
2818 }
2819 
2820 /*@C
2821    MatSetFactorType - sets the type of factorization it is
2822 
2823    Logically Collective on Mat
2824 
2825    Input Parameters:
2826 +  mat - the matrix
2827 -  t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT
2828 
2829    Level: intermediate
2830 
2831 .seealso: MatFactorType, MatGetFactor(), MatGetFactorType()
2832 @*/
2833 PetscErrorCode MatSetFactorType(Mat mat, MatFactorType t)
2834 {
2835   PetscFunctionBegin;
2836   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2837   PetscValidType(mat,1);
2838   mat->factortype = t;
2839   PetscFunctionReturn(0);
2840 }
2841 
2842 /* ------------------------------------------------------------*/
2843 /*@C
2844    MatGetInfo - Returns information about matrix storage (number of
2845    nonzeros, memory, etc.).
2846 
2847    Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag
2848 
2849    Input Parameters:
2850 .  mat - the matrix
2851 
2852    Output Parameters:
2853 +  flag - flag indicating the type of parameters to be returned
2854    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2855    MAT_GLOBAL_SUM - sum over all processors)
2856 -  info - matrix information context
2857 
2858    Notes:
2859    The MatInfo context contains a variety of matrix data, including
2860    number of nonzeros allocated and used, number of mallocs during
2861    matrix assembly, etc.  Additional information for factored matrices
2862    is provided (such as the fill ratio, number of mallocs during
2863    factorization, etc.).  Much of this info is printed to PETSC_STDOUT
2864    when using the runtime options
2865 $       -info -mat_view ::ascii_info
2866 
2867    Example for C/C++ Users:
2868    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2869    data within the MatInfo context.  For example,
2870 .vb
2871       MatInfo info;
2872       Mat     A;
2873       double  mal, nz_a, nz_u;
2874 
2875       MatGetInfo(A,MAT_LOCAL,&info);
2876       mal  = info.mallocs;
2877       nz_a = info.nz_allocated;
2878 .ve
2879 
2880    Example for Fortran Users:
2881    Fortran users should declare info as a double precision
2882    array of dimension MAT_INFO_SIZE, and then extract the parameters
2883    of interest.  See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h
2884    a complete list of parameter names.
2885 .vb
2886       double  precision info(MAT_INFO_SIZE)
2887       double  precision mal, nz_a
2888       Mat     A
2889       integer ierr
2890 
2891       call MatGetInfo(A,MAT_LOCAL,info,ierr)
2892       mal = info(MAT_INFO_MALLOCS)
2893       nz_a = info(MAT_INFO_NZ_ALLOCATED)
2894 .ve
2895 
2896     Level: intermediate
2897 
2898     Concepts: matrices^getting information on
2899 
2900     Developer Note: fortran interface is not autogenerated as the f90
2901     interface defintion cannot be generated correctly [due to MatInfo]
2902 
2903 .seealso: MatStashGetInfo()
2904 
2905 @*/
2906 PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2907 {
2908   PetscErrorCode ierr;
2909 
2910   PetscFunctionBegin;
2911   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2912   PetscValidType(mat,1);
2913   PetscValidPointer(info,3);
2914   if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2915   MatCheckPreallocated(mat,1);
2916   ierr = (*mat->ops->getinfo)(mat,flag,info);CHKERRQ(ierr);
2917   PetscFunctionReturn(0);
2918 }
2919 
2920 /*
2921    This is used by external packages where it is not easy to get the info from the actual
2922    matrix factorization.
2923 */
2924 PetscErrorCode MatGetInfo_External(Mat A,MatInfoType flag,MatInfo *info)
2925 {
2926   PetscErrorCode ierr;
2927 
2928   PetscFunctionBegin;
2929   ierr = PetscMemzero(info,sizeof(MatInfo));CHKERRQ(ierr);
2930   PetscFunctionReturn(0);
2931 }
2932 
2933 /* ----------------------------------------------------------*/
2934 
2935 /*@C
2936    MatLUFactor - Performs in-place LU factorization of matrix.
2937 
2938    Collective on Mat
2939 
2940    Input Parameters:
2941 +  mat - the matrix
2942 .  row - row permutation
2943 .  col - column permutation
2944 -  info - options for factorization, includes
2945 $          fill - expected fill as ratio of original fill.
2946 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2947 $                   Run with the option -info to determine an optimal value to use
2948 
2949    Notes:
2950    Most users should employ the simplified KSP interface for linear solvers
2951    instead of working directly with matrix algebra routines such as this.
2952    See, e.g., KSPCreate().
2953 
2954    This changes the state of the matrix to a factored matrix; it cannot be used
2955    for example with MatSetValues() unless one first calls MatSetUnfactored().
2956 
2957    Level: developer
2958 
2959    Concepts: matrices^LU factorization
2960 
2961 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2962           MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor()
2963 
2964     Developer Note: fortran interface is not autogenerated as the f90
2965     interface defintion cannot be generated correctly [due to MatFactorInfo]
2966 
2967 @*/
2968 PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2969 {
2970   PetscErrorCode ierr;
2971   MatFactorInfo  tinfo;
2972 
2973   PetscFunctionBegin;
2974   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2975   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
2976   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
2977   if (info) PetscValidPointer(info,4);
2978   PetscValidType(mat,1);
2979   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2980   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2981   if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2982   MatCheckPreallocated(mat,1);
2983   if (!info) {
2984     ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr);
2985     info = &tinfo;
2986   }
2987 
2988   ierr = PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
2989   ierr = (*mat->ops->lufactor)(mat,row,col,info);CHKERRQ(ierr);
2990   ierr = PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
2991   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
2992   PetscFunctionReturn(0);
2993 }
2994 
2995 /*@C
2996    MatILUFactor - Performs in-place ILU factorization of matrix.
2997 
2998    Collective on Mat
2999 
3000    Input Parameters:
3001 +  mat - the matrix
3002 .  row - row permutation
3003 .  col - column permutation
3004 -  info - structure containing
3005 $      levels - number of levels of fill.
3006 $      expected fill - as ratio of original fill.
3007 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
3008                 missing diagonal entries)
3009 
3010    Notes:
3011    Probably really in-place only when level of fill is zero, otherwise allocates
3012    new space to store factored matrix and deletes previous memory.
3013 
3014    Most users should employ the simplified KSP interface for linear solvers
3015    instead of working directly with matrix algebra routines such as this.
3016    See, e.g., KSPCreate().
3017 
3018    Level: developer
3019 
3020    Concepts: matrices^ILU factorization
3021 
3022 .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
3023 
3024     Developer Note: fortran interface is not autogenerated as the f90
3025     interface defintion cannot be generated correctly [due to MatFactorInfo]
3026 
3027 @*/
3028 PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
3029 {
3030   PetscErrorCode ierr;
3031 
3032   PetscFunctionBegin;
3033   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3034   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
3035   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
3036   PetscValidPointer(info,4);
3037   PetscValidType(mat,1);
3038   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
3039   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3040   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3041   if (!mat->ops->ilufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3042   MatCheckPreallocated(mat,1);
3043 
3044   ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
3045   ierr = (*mat->ops->ilufactor)(mat,row,col,info);CHKERRQ(ierr);
3046   ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
3047   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
3048   PetscFunctionReturn(0);
3049 }
3050 
3051 /*@C
3052    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
3053    Call this routine before calling MatLUFactorNumeric().
3054 
3055    Collective on Mat
3056 
3057    Input Parameters:
3058 +  fact - the factor matrix obtained with MatGetFactor()
3059 .  mat - the matrix
3060 .  row, col - row and column permutations
3061 -  info - options for factorization, includes
3062 $          fill - expected fill as ratio of original fill.
3063 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3064 $                   Run with the option -info to determine an optimal value to use
3065 
3066 
3067    Notes:
3068     See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
3069 
3070    Most users should employ the simplified KSP interface for linear solvers
3071    instead of working directly with matrix algebra routines such as this.
3072    See, e.g., KSPCreate().
3073 
3074    Level: developer
3075 
3076    Concepts: matrices^LU symbolic factorization
3077 
3078 .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo, MatFactorInfoInitialize()
3079 
3080     Developer Note: fortran interface is not autogenerated as the f90
3081     interface defintion cannot be generated correctly [due to MatFactorInfo]
3082 
3083 @*/
3084 PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
3085 {
3086   PetscErrorCode ierr;
3087 
3088   PetscFunctionBegin;
3089   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3090   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
3091   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
3092   if (info) PetscValidPointer(info,4);
3093   PetscValidType(mat,1);
3094   PetscValidPointer(fact,5);
3095   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3096   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3097   if (!(fact)->ops->lufactorsymbolic) {
3098     MatSolverType spackage;
3099     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
3100     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage);
3101   }
3102   MatCheckPreallocated(mat,2);
3103 
3104   ierr = PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
3105   ierr = (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
3106   ierr = PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
3107   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3108   PetscFunctionReturn(0);
3109 }
3110 
3111 /*@C
3112    MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
3113    Call this routine after first calling MatLUFactorSymbolic().
3114 
3115    Collective on Mat
3116 
3117    Input Parameters:
3118 +  fact - the factor matrix obtained with MatGetFactor()
3119 .  mat - the matrix
3120 -  info - options for factorization
3121 
3122    Notes:
3123    See MatLUFactor() for in-place factorization.  See
3124    MatCholeskyFactorNumeric() for the symmetric, positive definite case.
3125 
3126    Most users should employ the simplified KSP interface for linear solvers
3127    instead of working directly with matrix algebra routines such as this.
3128    See, e.g., KSPCreate().
3129 
3130    Level: developer
3131 
3132    Concepts: matrices^LU numeric factorization
3133 
3134 .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()
3135 
3136     Developer Note: fortran interface is not autogenerated as the f90
3137     interface defintion cannot be generated correctly [due to MatFactorInfo]
3138 
3139 @*/
3140 PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3141 {
3142   PetscErrorCode ierr;
3143 
3144   PetscFunctionBegin;
3145   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3146   PetscValidType(mat,1);
3147   PetscValidPointer(fact,2);
3148   PetscValidHeaderSpecific(fact,MAT_CLASSID,2);
3149   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3150   if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) SETERRQ4(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dimensions are different %D should = %D %D should = %D",mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N);
3151 
3152   if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name);
3153   MatCheckPreallocated(mat,2);
3154   ierr = PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3155   ierr = (fact->ops->lufactornumeric)(fact,mat,info);CHKERRQ(ierr);
3156   ierr = PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3157   ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr);
3158   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3159   PetscFunctionReturn(0);
3160 }
3161 
3162 /*@C
3163    MatCholeskyFactor - Performs in-place Cholesky factorization of a
3164    symmetric matrix.
3165 
3166    Collective on Mat
3167 
3168    Input Parameters:
3169 +  mat - the matrix
3170 .  perm - row and column permutations
3171 -  f - expected fill as ratio of original fill
3172 
3173    Notes:
3174    See MatLUFactor() for the nonsymmetric case.  See also
3175    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().
3176 
3177    Most users should employ the simplified KSP interface for linear solvers
3178    instead of working directly with matrix algebra routines such as this.
3179    See, e.g., KSPCreate().
3180 
3181    Level: developer
3182 
3183    Concepts: matrices^Cholesky factorization
3184 
3185 .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
3186           MatGetOrdering()
3187 
3188     Developer Note: fortran interface is not autogenerated as the f90
3189     interface defintion cannot be generated correctly [due to MatFactorInfo]
3190 
3191 @*/
3192 PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
3193 {
3194   PetscErrorCode ierr;
3195 
3196   PetscFunctionBegin;
3197   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3198   PetscValidType(mat,1);
3199   if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2);
3200   if (info) PetscValidPointer(info,3);
3201   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3202   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3203   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3204   if (!mat->ops->choleskyfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"In-place factorization for Mat type %s is not supported, try out-of-place factorization. See MatCholeskyFactorSymbolic/Numeric",((PetscObject)mat)->type_name);
3205   MatCheckPreallocated(mat,1);
3206 
3207   ierr = PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
3208   ierr = (*mat->ops->choleskyfactor)(mat,perm,info);CHKERRQ(ierr);
3209   ierr = PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
3210   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
3211   PetscFunctionReturn(0);
3212 }
3213 
3214 /*@C
3215    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
3216    of a symmetric matrix.
3217 
3218    Collective on Mat
3219 
3220    Input Parameters:
3221 +  fact - the factor matrix obtained with MatGetFactor()
3222 .  mat - the matrix
3223 .  perm - row and column permutations
3224 -  info - options for factorization, includes
3225 $          fill - expected fill as ratio of original fill.
3226 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3227 $                   Run with the option -info to determine an optimal value to use
3228 
3229    Notes:
3230    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
3231    MatCholeskyFactor() and MatCholeskyFactorNumeric().
3232 
3233    Most users should employ the simplified KSP interface for linear solvers
3234    instead of working directly with matrix algebra routines such as this.
3235    See, e.g., KSPCreate().
3236 
3237    Level: developer
3238 
3239    Concepts: matrices^Cholesky symbolic factorization
3240 
3241 .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
3242           MatGetOrdering()
3243 
3244     Developer Note: fortran interface is not autogenerated as the f90
3245     interface defintion cannot be generated correctly [due to MatFactorInfo]
3246 
3247 @*/
3248 PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
3249 {
3250   PetscErrorCode ierr;
3251 
3252   PetscFunctionBegin;
3253   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3254   PetscValidType(mat,1);
3255   if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2);
3256   if (info) PetscValidPointer(info,3);
3257   PetscValidPointer(fact,4);
3258   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3259   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3260   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3261   if (!(fact)->ops->choleskyfactorsymbolic) {
3262     MatSolverType spackage;
3263     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
3264     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage);
3265   }
3266   MatCheckPreallocated(mat,2);
3267 
3268   ierr = PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
3269   ierr = (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
3270   ierr = PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
3271   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3272   PetscFunctionReturn(0);
3273 }
3274 
3275 /*@C
3276    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
3277    of a symmetric matrix. Call this routine after first calling
3278    MatCholeskyFactorSymbolic().
3279 
3280    Collective on Mat
3281 
3282    Input Parameters:
3283 +  fact - the factor matrix obtained with MatGetFactor()
3284 .  mat - the initial matrix
3285 .  info - options for factorization
3286 -  fact - the symbolic factor of mat
3287 
3288 
3289    Notes:
3290    Most users should employ the simplified KSP interface for linear solvers
3291    instead of working directly with matrix algebra routines such as this.
3292    See, e.g., KSPCreate().
3293 
3294    Level: developer
3295 
3296    Concepts: matrices^Cholesky numeric factorization
3297 
3298 .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
3299 
3300     Developer Note: fortran interface is not autogenerated as the f90
3301     interface defintion cannot be generated correctly [due to MatFactorInfo]
3302 
3303 @*/
3304 PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3305 {
3306   PetscErrorCode ierr;
3307 
3308   PetscFunctionBegin;
3309   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3310   PetscValidType(mat,1);
3311   PetscValidPointer(fact,2);
3312   PetscValidHeaderSpecific(fact,MAT_CLASSID,2);
3313   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3314   if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name);
3315   if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) SETERRQ4(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dim %D should = %D %D should = %D",mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N);
3316   MatCheckPreallocated(mat,2);
3317 
3318   ierr = PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3319   ierr = (fact->ops->choleskyfactornumeric)(fact,mat,info);CHKERRQ(ierr);
3320   ierr = PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3321   ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr);
3322   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3323   PetscFunctionReturn(0);
3324 }
3325 
3326 /* ----------------------------------------------------------------*/
3327 /*@
3328    MatSolve - Solves A x = b, given a factored matrix.
3329 
3330    Neighbor-wise Collective on Mat and Vec
3331 
3332    Input Parameters:
3333 +  mat - the factored matrix
3334 -  b - the right-hand-side vector
3335 
3336    Output Parameter:
3337 .  x - the result vector
3338 
3339    Notes:
3340    The vectors b and x cannot be the same.  I.e., one cannot
3341    call MatSolve(A,x,x).
3342 
3343    Notes:
3344    Most users should employ the simplified KSP interface for linear solvers
3345    instead of working directly with matrix algebra routines such as this.
3346    See, e.g., KSPCreate().
3347 
3348    Level: developer
3349 
3350    Concepts: matrices^triangular solves
3351 
3352 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
3353 @*/
3354 PetscErrorCode MatSolve(Mat mat,Vec b,Vec x)
3355 {
3356   PetscErrorCode ierr;
3357 
3358   PetscFunctionBegin;
3359   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3360   PetscValidType(mat,1);
3361   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3362   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3363   PetscCheckSameComm(mat,1,b,2);
3364   PetscCheckSameComm(mat,1,x,3);
3365   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3366   if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3367   if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3368   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3369   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3370   if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3371   MatCheckPreallocated(mat,1);
3372 
3373   ierr = PetscLogEventBegin(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
3374   if (mat->factorerrortype) {
3375     ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3376     ierr = VecSetInf(x);CHKERRQ(ierr);
3377   } else {
3378     if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3379     ierr = (*mat->ops->solve)(mat,b,x);CHKERRQ(ierr);
3380   }
3381   ierr = PetscLogEventEnd(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
3382   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3383   PetscFunctionReturn(0);
3384 }
3385 
3386 static PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X, PetscBool trans)
3387 {
3388   PetscErrorCode ierr;
3389   Vec            b,x;
3390   PetscInt       m,N,i;
3391   PetscScalar    *bb,*xx;
3392   PetscBool      flg;
3393 
3394   PetscFunctionBegin;
3395   ierr = PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr);
3396   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
3397   ierr = PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr);
3398   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");
3399 
3400   ierr = MatDenseGetArray(B,&bb);CHKERRQ(ierr);
3401   ierr = MatDenseGetArray(X,&xx);CHKERRQ(ierr);
3402   ierr = MatGetLocalSize(B,&m,NULL);CHKERRQ(ierr);  /* number local rows */
3403   ierr = MatGetSize(B,NULL,&N);CHKERRQ(ierr);       /* total columns in dense matrix */
3404   ierr = MatCreateVecs(A,&x,&b);CHKERRQ(ierr);
3405   for (i=0; i<N; i++) {
3406     ierr = VecPlaceArray(b,bb + i*m);CHKERRQ(ierr);
3407     ierr = VecPlaceArray(x,xx + i*m);CHKERRQ(ierr);
3408     if (trans) {
3409       ierr = MatSolveTranspose(A,b,x);CHKERRQ(ierr);
3410     } else {
3411       ierr = MatSolve(A,b,x);CHKERRQ(ierr);
3412     }
3413     ierr = VecResetArray(x);CHKERRQ(ierr);
3414     ierr = VecResetArray(b);CHKERRQ(ierr);
3415   }
3416   ierr = VecDestroy(&b);CHKERRQ(ierr);
3417   ierr = VecDestroy(&x);CHKERRQ(ierr);
3418   ierr = MatDenseRestoreArray(B,&bb);CHKERRQ(ierr);
3419   ierr = MatDenseRestoreArray(X,&xx);CHKERRQ(ierr);
3420   PetscFunctionReturn(0);
3421 }
3422 
3423 /*@
3424    MatMatSolve - Solves A X = B, given a factored matrix.
3425 
3426    Neighbor-wise Collective on Mat
3427 
3428    Input Parameters:
3429 +  A - the factored matrix
3430 -  B - the right-hand-side matrix  (dense matrix)
3431 
3432    Output Parameter:
3433 .  X - the result matrix (dense matrix)
3434 
3435    Notes:
3436    The matrices b and x cannot be the same.  I.e., one cannot
3437    call MatMatSolve(A,x,x).
3438 
3439    Notes:
3440    Most users should usually employ the simplified KSP interface for linear solvers
3441    instead of working directly with matrix algebra routines such as this.
3442    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3443    at a time.
3444 
3445    When using SuperLU_Dist as a parallel solver PETSc will use the SuperLU_Dist functionality to solve multiple right hand sides simultaneously. For MUMPS
3446    it calls a separate solve for each right hand side since MUMPS does not yet support distributed right hand sides.
3447 
3448    Since the resulting matrix X must always be dense we do not support sparse representation of the matrix B.
3449 
3450    Level: developer
3451 
3452    Concepts: matrices^triangular solves
3453 
3454 .seealso: MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor()
3455 @*/
3456 PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X)
3457 {
3458   PetscErrorCode ierr;
3459 
3460   PetscFunctionBegin;
3461   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3462   PetscValidType(A,1);
3463   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3464   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3465   PetscCheckSameComm(A,1,B,2);
3466   PetscCheckSameComm(A,1,X,3);
3467   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3468   if (A->cmap->N != X->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %D %D",A->cmap->N,X->rmap->N);
3469   if (A->rmap->N != B->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %D %D",A->rmap->N,B->rmap->N);
3470   if (X->cmap->N < B->cmap->N) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as rhs matrix");
3471   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3472   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3473   MatCheckPreallocated(A,1);
3474 
3475   ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3476   if (!A->ops->matsolve) {
3477     ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name);CHKERRQ(ierr);
3478     ierr = MatMatSolve_Basic(A,B,X,PETSC_FALSE);CHKERRQ(ierr);
3479   } else {
3480     ierr = (*A->ops->matsolve)(A,B,X);CHKERRQ(ierr);
3481   }
3482   ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3483   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3484   PetscFunctionReturn(0);
3485 }
3486 
3487 /*@
3488    MatMatSolveTranspose - Solves A^T X = B, given a factored matrix.
3489 
3490    Neighbor-wise Collective on Mat
3491 
3492    Input Parameters:
3493 +  A - the factored matrix
3494 -  B - the right-hand-side matrix  (dense matrix)
3495 
3496    Output Parameter:
3497 .  X - the result matrix (dense matrix)
3498 
3499    Notes:
3500    The matrices B and X cannot be the same.  I.e., one cannot
3501    call MatMatSolveTranspose(A,X,X).
3502 
3503    Notes:
3504    Most users should usually employ the simplified KSP interface for linear solvers
3505    instead of working directly with matrix algebra routines such as this.
3506    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3507    at a time.
3508 
3509    When using SuperLU_Dist or MUMPS as a parallel solver, PETSc will use their functionality to solve multiple right hand sides simultaneously.
3510 
3511    Level: developer
3512 
3513    Concepts: matrices^triangular solves
3514 
3515 .seealso: MatMatSolve(), MatLUFactor(), MatCholeskyFactor()
3516 @*/
3517 PetscErrorCode MatMatSolveTranspose(Mat A,Mat B,Mat X)
3518 {
3519   PetscErrorCode ierr;
3520 
3521   PetscFunctionBegin;
3522   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3523   PetscValidType(A,1);
3524   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3525   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3526   PetscCheckSameComm(A,1,B,2);
3527   PetscCheckSameComm(A,1,X,3);
3528   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3529   if (A->cmap->N != X->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %D %D",A->cmap->N,X->rmap->N);
3530   if (A->rmap->N != B->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %D %D",A->rmap->N,B->rmap->N);
3531   if (A->rmap->n != B->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat A,Mat B: local dim %D %D",A->rmap->n,B->rmap->n);
3532   if (X->cmap->N < B->cmap->N) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as rhs matrix");
3533   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3534   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3535   MatCheckPreallocated(A,1);
3536 
3537   ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3538   if (!A->ops->matsolvetranspose) {
3539     ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolveTranspose\n",((PetscObject)A)->type_name);CHKERRQ(ierr);
3540     ierr = MatMatSolve_Basic(A,B,X,PETSC_TRUE);CHKERRQ(ierr);
3541   } else {
3542     ierr = (*A->ops->matsolvetranspose)(A,B,X);CHKERRQ(ierr);
3543   }
3544   ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3545   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3546   PetscFunctionReturn(0);
3547 }
3548 
3549 /*@
3550    MatMatTransposeSolve - Solves A X = B^T, given a factored matrix.
3551 
3552    Neighbor-wise Collective on Mat
3553 
3554    Input Parameters:
3555 +  A - the factored matrix
3556 -  Bt - the transpose of right-hand-side matrix
3557 
3558    Output Parameter:
3559 .  X - the result matrix (dense matrix)
3560 
3561    Notes:
3562    Most users should usually employ the simplified KSP interface for linear solvers
3563    instead of working directly with matrix algebra routines such as this.
3564    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3565    at a time.
3566 
3567    For MUMPS, it only supports centralized sparse compressed column format on the host processor for right hand side matrix. User must create B^T in sparse compressed row format on the host processor and call MatMatTransposeSolve() to implement MUMPS' MatMatSolve().
3568 
3569    Level: developer
3570 
3571    Concepts: matrices^triangular solves
3572 
3573 .seealso: MatMatSolve(), MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor()
3574 @*/
3575 PetscErrorCode MatMatTransposeSolve(Mat A,Mat Bt,Mat X)
3576 {
3577   PetscErrorCode ierr;
3578 
3579   PetscFunctionBegin;
3580   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3581   PetscValidType(A,1);
3582   PetscValidHeaderSpecific(Bt,MAT_CLASSID,2);
3583   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3584   PetscCheckSameComm(A,1,Bt,2);
3585   PetscCheckSameComm(A,1,X,3);
3586 
3587   if (X == Bt) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3588   if (A->cmap->N != X->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %D %D",A->cmap->N,X->rmap->N);
3589   if (A->rmap->N != Bt->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat Bt: global dim %D %D",A->rmap->N,Bt->cmap->N);
3590   if (X->cmap->N < Bt->rmap->N) SETERRQ(PetscObjectComm((PetscObject)X),PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as row number of the rhs matrix");
3591   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3592   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3593   MatCheckPreallocated(A,1);
3594 
3595   if (!A->ops->mattransposesolve) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
3596   ierr = PetscLogEventBegin(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr);
3597   ierr = (*A->ops->mattransposesolve)(A,Bt,X);CHKERRQ(ierr);
3598   ierr = PetscLogEventEnd(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr);
3599   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3600   PetscFunctionReturn(0);
3601 }
3602 
3603 /*@
3604    MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or
3605                             U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U,
3606 
3607    Neighbor-wise Collective on Mat and Vec
3608 
3609    Input Parameters:
3610 +  mat - the factored matrix
3611 -  b - the right-hand-side vector
3612 
3613    Output Parameter:
3614 .  x - the result vector
3615 
3616    Notes:
3617    MatSolve() should be used for most applications, as it performs
3618    a forward solve followed by a backward solve.
3619 
3620    The vectors b and x cannot be the same,  i.e., one cannot
3621    call MatForwardSolve(A,x,x).
3622 
3623    For matrix in seqsbaij format with block size larger than 1,
3624    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3625    MatForwardSolve() solves U^T*D y = b, and
3626    MatBackwardSolve() solves U x = y.
3627    Thus they do not provide a symmetric preconditioner.
3628 
3629    Most users should employ the simplified KSP interface for linear solvers
3630    instead of working directly with matrix algebra routines such as this.
3631    See, e.g., KSPCreate().
3632 
3633    Level: developer
3634 
3635    Concepts: matrices^forward solves
3636 
3637 .seealso: MatSolve(), MatBackwardSolve()
3638 @*/
3639 PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x)
3640 {
3641   PetscErrorCode ierr;
3642 
3643   PetscFunctionBegin;
3644   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3645   PetscValidType(mat,1);
3646   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3647   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3648   PetscCheckSameComm(mat,1,b,2);
3649   PetscCheckSameComm(mat,1,x,3);
3650   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3651   if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3652   if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3653   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3654   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3655   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3656   MatCheckPreallocated(mat,1);
3657 
3658   if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3659   ierr = PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
3660   ierr = (*mat->ops->forwardsolve)(mat,b,x);CHKERRQ(ierr);
3661   ierr = PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
3662   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3663   PetscFunctionReturn(0);
3664 }
3665 
3666 /*@
3667    MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
3668                              D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U,
3669 
3670    Neighbor-wise Collective on Mat and Vec
3671 
3672    Input Parameters:
3673 +  mat - the factored matrix
3674 -  b - the right-hand-side vector
3675 
3676    Output Parameter:
3677 .  x - the result vector
3678 
3679    Notes:
3680    MatSolve() should be used for most applications, as it performs
3681    a forward solve followed by a backward solve.
3682 
3683    The vectors b and x cannot be the same.  I.e., one cannot
3684    call MatBackwardSolve(A,x,x).
3685 
3686    For matrix in seqsbaij format with block size larger than 1,
3687    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3688    MatForwardSolve() solves U^T*D y = b, and
3689    MatBackwardSolve() solves U x = y.
3690    Thus they do not provide a symmetric preconditioner.
3691 
3692    Most users should employ the simplified KSP interface for linear solvers
3693    instead of working directly with matrix algebra routines such as this.
3694    See, e.g., KSPCreate().
3695 
3696    Level: developer
3697 
3698    Concepts: matrices^backward solves
3699 
3700 .seealso: MatSolve(), MatForwardSolve()
3701 @*/
3702 PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x)
3703 {
3704   PetscErrorCode ierr;
3705 
3706   PetscFunctionBegin;
3707   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3708   PetscValidType(mat,1);
3709   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3710   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3711   PetscCheckSameComm(mat,1,b,2);
3712   PetscCheckSameComm(mat,1,x,3);
3713   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3714   if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3715   if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3716   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3717   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3718   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3719   MatCheckPreallocated(mat,1);
3720 
3721   if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3722   ierr = PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
3723   ierr = (*mat->ops->backwardsolve)(mat,b,x);CHKERRQ(ierr);
3724   ierr = PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
3725   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3726   PetscFunctionReturn(0);
3727 }
3728 
3729 /*@
3730    MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
3731 
3732    Neighbor-wise Collective on Mat and Vec
3733 
3734    Input Parameters:
3735 +  mat - the factored matrix
3736 .  b - the right-hand-side vector
3737 -  y - the vector to be added to
3738 
3739    Output Parameter:
3740 .  x - the result vector
3741 
3742    Notes:
3743    The vectors b and x cannot be the same.  I.e., one cannot
3744    call MatSolveAdd(A,x,y,x).
3745 
3746    Most users should employ the simplified KSP interface for linear solvers
3747    instead of working directly with matrix algebra routines such as this.
3748    See, e.g., KSPCreate().
3749 
3750    Level: developer
3751 
3752    Concepts: matrices^triangular solves
3753 
3754 .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3755 @*/
3756 PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3757 {
3758   PetscScalar    one = 1.0;
3759   Vec            tmp;
3760   PetscErrorCode ierr;
3761 
3762   PetscFunctionBegin;
3763   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3764   PetscValidType(mat,1);
3765   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3766   PetscValidHeaderSpecific(b,VEC_CLASSID,3);
3767   PetscValidHeaderSpecific(x,VEC_CLASSID,4);
3768   PetscCheckSameComm(mat,1,b,2);
3769   PetscCheckSameComm(mat,1,y,2);
3770   PetscCheckSameComm(mat,1,x,3);
3771   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3772   if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3773   if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3774   if (mat->rmap->N != y->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
3775   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3776   if (x->map->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %D %D",x->map->n,y->map->n);
3777   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3778   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3779   MatCheckPreallocated(mat,1);
3780 
3781   ierr = PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
3782   if (mat->ops->solveadd) {
3783     ierr = (*mat->ops->solveadd)(mat,b,y,x);CHKERRQ(ierr);
3784   } else {
3785     /* do the solve then the add manually */
3786     if (x != y) {
3787       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
3788       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
3789     } else {
3790       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
3791       ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr);
3792       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
3793       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
3794       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
3795       ierr = VecDestroy(&tmp);CHKERRQ(ierr);
3796     }
3797   }
3798   ierr = PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
3799   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3800   PetscFunctionReturn(0);
3801 }
3802 
3803 /*@
3804    MatSolveTranspose - Solves A' x = b, given a factored matrix.
3805 
3806    Neighbor-wise Collective on Mat and Vec
3807 
3808    Input Parameters:
3809 +  mat - the factored matrix
3810 -  b - the right-hand-side vector
3811 
3812    Output Parameter:
3813 .  x - the result vector
3814 
3815    Notes:
3816    The vectors b and x cannot be the same.  I.e., one cannot
3817    call MatSolveTranspose(A,x,x).
3818 
3819    Most users should employ the simplified KSP interface for linear solvers
3820    instead of working directly with matrix algebra routines such as this.
3821    See, e.g., KSPCreate().
3822 
3823    Level: developer
3824 
3825    Concepts: matrices^triangular solves
3826 
3827 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
3828 @*/
3829 PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x)
3830 {
3831   PetscErrorCode ierr;
3832 
3833   PetscFunctionBegin;
3834   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3835   PetscValidType(mat,1);
3836   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3837   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3838   PetscCheckSameComm(mat,1,b,2);
3839   PetscCheckSameComm(mat,1,x,3);
3840   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3841   if (mat->rmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
3842   if (mat->cmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->cmap->N,b->map->N);
3843   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3844   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3845   MatCheckPreallocated(mat,1);
3846   ierr = PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
3847   if (mat->factorerrortype) {
3848     ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3849     ierr = VecSetInf(x);CHKERRQ(ierr);
3850   } else {
3851     if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3852     ierr = (*mat->ops->solvetranspose)(mat,b,x);CHKERRQ(ierr);
3853   }
3854   ierr = PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
3855   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3856   PetscFunctionReturn(0);
3857 }
3858 
3859 /*@
3860    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
3861                       factored matrix.
3862 
3863    Neighbor-wise Collective on Mat and Vec
3864 
3865    Input Parameters:
3866 +  mat - the factored matrix
3867 .  b - the right-hand-side vector
3868 -  y - the vector to be added to
3869 
3870    Output Parameter:
3871 .  x - the result vector
3872 
3873    Notes:
3874    The vectors b and x cannot be the same.  I.e., one cannot
3875    call MatSolveTransposeAdd(A,x,y,x).
3876 
3877    Most users should employ the simplified KSP interface for linear solvers
3878    instead of working directly with matrix algebra routines such as this.
3879    See, e.g., KSPCreate().
3880 
3881    Level: developer
3882 
3883    Concepts: matrices^triangular solves
3884 
3885 .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3886 @*/
3887 PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3888 {
3889   PetscScalar    one = 1.0;
3890   PetscErrorCode ierr;
3891   Vec            tmp;
3892 
3893   PetscFunctionBegin;
3894   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3895   PetscValidType(mat,1);
3896   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3897   PetscValidHeaderSpecific(b,VEC_CLASSID,3);
3898   PetscValidHeaderSpecific(x,VEC_CLASSID,4);
3899   PetscCheckSameComm(mat,1,b,2);
3900   PetscCheckSameComm(mat,1,y,3);
3901   PetscCheckSameComm(mat,1,x,4);
3902   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3903   if (mat->rmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
3904   if (mat->cmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->cmap->N,b->map->N);
3905   if (mat->cmap->N != y->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N);
3906   if (x->map->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %D %D",x->map->n,y->map->n);
3907   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3908   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3909   MatCheckPreallocated(mat,1);
3910 
3911   ierr = PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
3912   if (mat->ops->solvetransposeadd) {
3913     if (mat->factorerrortype) {
3914       ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3915       ierr = VecSetInf(x);CHKERRQ(ierr);
3916     } else {
3917       ierr = (*mat->ops->solvetransposeadd)(mat,b,y,x);CHKERRQ(ierr);
3918     }
3919   } else {
3920     /* do the solve then the add manually */
3921     if (x != y) {
3922       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
3923       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
3924     } else {
3925       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
3926       ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr);
3927       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
3928       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
3929       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
3930       ierr = VecDestroy(&tmp);CHKERRQ(ierr);
3931     }
3932   }
3933   ierr = PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
3934   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3935   PetscFunctionReturn(0);
3936 }
3937 /* ----------------------------------------------------------------*/
3938 
3939 /*@
3940    MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps.
3941 
3942    Neighbor-wise Collective on Mat and Vec
3943 
3944    Input Parameters:
3945 +  mat - the matrix
3946 .  b - the right hand side
3947 .  omega - the relaxation factor
3948 .  flag - flag indicating the type of SOR (see below)
3949 .  shift -  diagonal shift
3950 .  its - the number of iterations
3951 -  lits - the number of local iterations
3952 
3953    Output Parameters:
3954 .  x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess)
3955 
3956    SOR Flags:
3957 .     SOR_FORWARD_SWEEP - forward SOR
3958 .     SOR_BACKWARD_SWEEP - backward SOR
3959 .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3960 .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR
3961 .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
3962 .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3963 .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
3964          upper/lower triangular part of matrix to
3965          vector (with omega)
3966 .     SOR_ZERO_INITIAL_GUESS - zero initial guess
3967 
3968    Notes:
3969    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3970    SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3971    on each processor.
3972 
3973    Application programmers will not generally use MatSOR() directly,
3974    but instead will employ the KSP/PC interface.
3975 
3976    Notes:
3977     for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing
3978 
3979    Notes for Advanced Users:
3980    The flags are implemented as bitwise inclusive or operations.
3981    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3982    to specify a zero initial guess for SSOR.
3983 
3984    Most users should employ the simplified KSP interface for linear solvers
3985    instead of working directly with matrix algebra routines such as this.
3986    See, e.g., KSPCreate().
3987 
3988    Vectors x and b CANNOT be the same
3989 
3990    Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes
3991 
3992    Level: developer
3993 
3994    Concepts: matrices^relaxation
3995    Concepts: matrices^SOR
3996    Concepts: matrices^Gauss-Seidel
3997 
3998 @*/
3999 PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
4000 {
4001   PetscErrorCode ierr;
4002 
4003   PetscFunctionBegin;
4004   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4005   PetscValidType(mat,1);
4006   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
4007   PetscValidHeaderSpecific(x,VEC_CLASSID,8);
4008   PetscCheckSameComm(mat,1,b,2);
4009   PetscCheckSameComm(mat,1,x,8);
4010   if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4011   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4012   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4013   if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
4014   if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
4015   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
4016   if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
4017   if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
4018   if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");
4019 
4020   MatCheckPreallocated(mat,1);
4021   ierr = PetscLogEventBegin(MAT_SOR,mat,b,x,0);CHKERRQ(ierr);
4022   ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr);
4023   ierr = PetscLogEventEnd(MAT_SOR,mat,b,x,0);CHKERRQ(ierr);
4024   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
4025   PetscFunctionReturn(0);
4026 }
4027 
4028 /*
4029       Default matrix copy routine.
4030 */
4031 PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
4032 {
4033   PetscErrorCode    ierr;
4034   PetscInt          i,rstart = 0,rend = 0,nz;
4035   const PetscInt    *cwork;
4036   const PetscScalar *vwork;
4037 
4038   PetscFunctionBegin;
4039   if (B->assembled) {
4040     ierr = MatZeroEntries(B);CHKERRQ(ierr);
4041   }
4042   if (str == SAME_NONZERO_PATTERN) {
4043     ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
4044     for (i=rstart; i<rend; i++) {
4045       ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
4046       ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);CHKERRQ(ierr);
4047       ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
4048     }
4049   } else {
4050     ierr = MatAYPX(B,0.0,A,str);CHKERRQ(ierr);
4051   }
4052   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4053   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4054   PetscFunctionReturn(0);
4055 }
4056 
4057 /*@
4058    MatCopy - Copies a matrix to another matrix.
4059 
4060    Collective on Mat
4061 
4062    Input Parameters:
4063 +  A - the matrix
4064 -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
4065 
4066    Output Parameter:
4067 .  B - where the copy is put
4068 
4069    Notes:
4070    If you use SAME_NONZERO_PATTERN then the two matrices had better have the
4071    same nonzero pattern or the routine will crash.
4072 
4073    MatCopy() copies the matrix entries of a matrix to another existing
4074    matrix (after first zeroing the second matrix).  A related routine is
4075    MatConvert(), which first creates a new matrix and then copies the data.
4076 
4077    Level: intermediate
4078 
4079    Concepts: matrices^copying
4080 
4081 .seealso: MatConvert(), MatDuplicate()
4082 
4083 @*/
4084 PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str)
4085 {
4086   PetscErrorCode ierr;
4087   PetscInt       i;
4088 
4089   PetscFunctionBegin;
4090   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4091   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4092   PetscValidType(A,1);
4093   PetscValidType(B,2);
4094   PetscCheckSameComm(A,1,B,2);
4095   MatCheckPreallocated(B,2);
4096   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4097   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4098   if (A->rmap->N != B->rmap->N || A->cmap->N != B->cmap->N) SETERRQ4(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim (%D,%D) (%D,%D)",A->rmap->N,B->rmap->N,A->cmap->N,B->cmap->N);
4099   MatCheckPreallocated(A,1);
4100   if (A == B) PetscFunctionReturn(0);
4101 
4102   ierr = PetscLogEventBegin(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
4103   if (A->ops->copy) {
4104     ierr = (*A->ops->copy)(A,B,str);CHKERRQ(ierr);
4105   } else { /* generic conversion */
4106     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
4107   }
4108 
4109   B->stencil.dim = A->stencil.dim;
4110   B->stencil.noc = A->stencil.noc;
4111   for (i=0; i<=A->stencil.dim; i++) {
4112     B->stencil.dims[i]   = A->stencil.dims[i];
4113     B->stencil.starts[i] = A->stencil.starts[i];
4114   }
4115 
4116   ierr = PetscLogEventEnd(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
4117   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
4118   PetscFunctionReturn(0);
4119 }
4120 
4121 /*@C
4122    MatConvert - Converts a matrix to another matrix, either of the same
4123    or different type.
4124 
4125    Collective on Mat
4126 
4127    Input Parameters:
4128 +  mat - the matrix
4129 .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
4130    same type as the original matrix.
4131 -  reuse - denotes if the destination matrix is to be created or reused.
4132    Use MAT_INPLACE_MATRIX for inplace conversion (that is when you want the input mat to be changed to contain the matrix in the new format), otherwise use
4133    MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX (can only be used after the first call was made with MAT_INITIAL_MATRIX, causes the matrix space in M to be reused).
4134 
4135    Output Parameter:
4136 .  M - pointer to place new matrix
4137 
4138    Notes:
4139    MatConvert() first creates a new matrix and then copies the data from
4140    the first matrix.  A related routine is MatCopy(), which copies the matrix
4141    entries of one matrix to another already existing matrix context.
4142 
4143    Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
4144    the MPI communicator of the generated matrix is always the same as the communicator
4145    of the input matrix.
4146 
4147    Level: intermediate
4148 
4149    Concepts: matrices^converting between storage formats
4150 
4151 .seealso: MatCopy(), MatDuplicate()
4152 @*/
4153 PetscErrorCode MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M)
4154 {
4155   PetscErrorCode ierr;
4156   PetscBool      sametype,issame,flg;
4157   char           convname[256],mtype[256];
4158   Mat            B;
4159 
4160   PetscFunctionBegin;
4161   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4162   PetscValidType(mat,1);
4163   PetscValidPointer(M,3);
4164   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4165   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4166   MatCheckPreallocated(mat,1);
4167 
4168   ierr = PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);CHKERRQ(ierr);
4169   if (flg) {
4170     newtype = mtype;
4171   }
4172   ierr = PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);CHKERRQ(ierr);
4173   ierr = PetscStrcmp(newtype,"same",&issame);CHKERRQ(ierr);
4174   if ((reuse == MAT_INPLACE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix");
4175   if ((reuse == MAT_REUSE_MATRIX) && (mat == *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_REUSE_MATRIX means reuse matrix in final argument, perhaps you mean MAT_INPLACE_MATRIX");
4176 
4177   if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) PetscFunctionReturn(0);
4178 
4179   if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
4180     ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
4181   } else {
4182     PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL;
4183     const char     *prefix[3] = {"seq","mpi",""};
4184     PetscInt       i;
4185     /*
4186        Order of precedence:
4187        0) See if newtype is a superclass of the current matrix.
4188        1) See if a specialized converter is known to the current matrix.
4189        2) See if a specialized converter is known to the desired matrix class.
4190        3) See if a good general converter is registered for the desired class
4191           (as of 6/27/03 only MATMPIADJ falls into this category).
4192        4) See if a good general converter is known for the current matrix.
4193        5) Use a really basic converter.
4194     */
4195 
4196     /* 0) See if newtype is a superclass of the current matrix.
4197           i.e mat is mpiaij and newtype is aij */
4198     for (i=0; i<2; i++) {
4199       ierr = PetscStrncpy(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4200       ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr);
4201       ierr = PetscStrcmp(convname,((PetscObject)mat)->type_name,&flg);CHKERRQ(ierr);
4202       ierr = PetscInfo3(mat,"Check superclass %s %s -> %d\n",convname,((PetscObject)mat)->type_name,flg);CHKERRQ(ierr);
4203       if (flg) {
4204         if (reuse == MAT_INPLACE_MATRIX) {
4205           PetscFunctionReturn(0);
4206         } else if (reuse == MAT_INITIAL_MATRIX && mat->ops->duplicate) {
4207           ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
4208           PetscFunctionReturn(0);
4209         } else if (reuse == MAT_REUSE_MATRIX && mat->ops->copy) {
4210           ierr = MatCopy(mat,*M,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
4211           PetscFunctionReturn(0);
4212         }
4213       }
4214     }
4215     /* 1) See if a specialized converter is known to the current matrix and the desired class */
4216     for (i=0; i<3; i++) {
4217       ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr);
4218       ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr);
4219       ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr);
4220       ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4221       ierr = PetscStrlcat(convname,issame ? ((PetscObject)mat)->type_name : newtype,sizeof(convname));CHKERRQ(ierr);
4222       ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr);
4223       ierr = PetscObjectQueryFunction((PetscObject)mat,convname,&conv);CHKERRQ(ierr);
4224       ierr = PetscInfo3(mat,"Check specialized (1) %s (%s) -> %d\n",convname,((PetscObject)mat)->type_name,!!conv);CHKERRQ(ierr);
4225       if (conv) goto foundconv;
4226     }
4227 
4228     /* 2)  See if a specialized converter is known to the desired matrix class. */
4229     ierr = MatCreate(PetscObjectComm((PetscObject)mat),&B);CHKERRQ(ierr);
4230     ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);CHKERRQ(ierr);
4231     ierr = MatSetType(B,newtype);CHKERRQ(ierr);
4232     for (i=0; i<3; i++) {
4233       ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr);
4234       ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr);
4235       ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr);
4236       ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4237       ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr);
4238       ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr);
4239       ierr = PetscObjectQueryFunction((PetscObject)B,convname,&conv);CHKERRQ(ierr);
4240       ierr = PetscInfo3(mat,"Check specialized (2) %s (%s) -> %d\n",convname,((PetscObject)B)->type_name,!!conv);CHKERRQ(ierr);
4241       if (conv) {
4242         ierr = MatDestroy(&B);CHKERRQ(ierr);
4243         goto foundconv;
4244       }
4245     }
4246 
4247     /* 3) See if a good general converter is registered for the desired class */
4248     conv = B->ops->convertfrom;
4249     ierr = PetscInfo2(mat,"Check convertfrom (%s) -> %d\n",((PetscObject)B)->type_name,!!conv);CHKERRQ(ierr);
4250     ierr = MatDestroy(&B);CHKERRQ(ierr);
4251     if (conv) goto foundconv;
4252 
4253     /* 4) See if a good general converter is known for the current matrix */
4254     if (mat->ops->convert) {
4255       conv = mat->ops->convert;
4256     }
4257     ierr = PetscInfo2(mat,"Check general convert (%s) -> %d\n",((PetscObject)mat)->type_name,!!conv);CHKERRQ(ierr);
4258     if (conv) goto foundconv;
4259 
4260     /* 5) Use a really basic converter. */
4261     ierr = PetscInfo(mat,"Using MatConvert_Basic\n");CHKERRQ(ierr);
4262     conv = MatConvert_Basic;
4263 
4264 foundconv:
4265     ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4266     ierr = (*conv)(mat,newtype,reuse,M);CHKERRQ(ierr);
4267     if (mat->rmap->mapping && mat->cmap->mapping && !(*M)->rmap->mapping && !(*M)->cmap->mapping) {
4268       /* the block sizes must be same if the mappings are copied over */
4269       (*M)->rmap->bs = mat->rmap->bs;
4270       (*M)->cmap->bs = mat->cmap->bs;
4271       ierr = PetscObjectReference((PetscObject)mat->rmap->mapping);CHKERRQ(ierr);
4272       ierr = PetscObjectReference((PetscObject)mat->cmap->mapping);CHKERRQ(ierr);
4273       (*M)->rmap->mapping = mat->rmap->mapping;
4274       (*M)->cmap->mapping = mat->cmap->mapping;
4275     }
4276     (*M)->stencil.dim = mat->stencil.dim;
4277     (*M)->stencil.noc = mat->stencil.noc;
4278     for (i=0; i<=mat->stencil.dim; i++) {
4279       (*M)->stencil.dims[i]   = mat->stencil.dims[i];
4280       (*M)->stencil.starts[i] = mat->stencil.starts[i];
4281     }
4282     ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4283   }
4284   ierr = PetscObjectStateIncrease((PetscObject)*M);CHKERRQ(ierr);
4285 
4286   /* Copy Mat options */
4287   if (mat->symmetric) {ierr = MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);}
4288   if (mat->hermitian) {ierr = MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);}
4289   PetscFunctionReturn(0);
4290 }
4291 
4292 /*@C
4293    MatFactorGetSolverType - Returns name of the package providing the factorization routines
4294 
4295    Not Collective
4296 
4297    Input Parameter:
4298 .  mat - the matrix, must be a factored matrix
4299 
4300    Output Parameter:
4301 .   type - the string name of the package (do not free this string)
4302 
4303    Notes:
4304       In Fortran you pass in a empty string and the package name will be copied into it.
4305     (Make sure the string is long enough)
4306 
4307    Level: intermediate
4308 
4309 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
4310 @*/
4311 PetscErrorCode MatFactorGetSolverType(Mat mat, MatSolverType *type)
4312 {
4313   PetscErrorCode ierr, (*conv)(Mat,MatSolverType*);
4314 
4315   PetscFunctionBegin;
4316   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4317   PetscValidType(mat,1);
4318   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
4319   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverType_C",&conv);CHKERRQ(ierr);
4320   if (!conv) {
4321     *type = MATSOLVERPETSC;
4322   } else {
4323     ierr = (*conv)(mat,type);CHKERRQ(ierr);
4324   }
4325   PetscFunctionReturn(0);
4326 }
4327 
4328 typedef struct _MatSolverTypeForSpecifcType* MatSolverTypeForSpecifcType;
4329 struct _MatSolverTypeForSpecifcType {
4330   MatType                        mtype;
4331   PetscErrorCode                 (*getfactor[4])(Mat,MatFactorType,Mat*);
4332   MatSolverTypeForSpecifcType next;
4333 };
4334 
4335 typedef struct _MatSolverTypeHolder* MatSolverTypeHolder;
4336 struct _MatSolverTypeHolder {
4337   char                           *name;
4338   MatSolverTypeForSpecifcType handlers;
4339   MatSolverTypeHolder         next;
4340 };
4341 
4342 static MatSolverTypeHolder MatSolverTypeHolders = NULL;
4343 
4344 /*@C
4345    MatSolvePackageRegister - Registers a MatSolverType that works for a particular matrix type
4346 
4347    Input Parameters:
4348 +    package - name of the package, for example petsc or superlu
4349 .    mtype - the matrix type that works with this package
4350 .    ftype - the type of factorization supported by the package
4351 -    getfactor - routine that will create the factored matrix ready to be used
4352 
4353     Level: intermediate
4354 
4355 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4356 @*/
4357 PetscErrorCode MatSolverTypeRegister(MatSolverType package,MatType mtype,MatFactorType ftype,PetscErrorCode (*getfactor)(Mat,MatFactorType,Mat*))
4358 {
4359   PetscErrorCode              ierr;
4360   MatSolverTypeHolder         next = MatSolverTypeHolders,prev = NULL;
4361   PetscBool                   flg;
4362   MatSolverTypeForSpecifcType inext,iprev = NULL;
4363 
4364   PetscFunctionBegin;
4365   ierr = MatInitializePackage();CHKERRQ(ierr);
4366   if (!next) {
4367     ierr = PetscNew(&MatSolverTypeHolders);CHKERRQ(ierr);
4368     ierr = PetscStrallocpy(package,&MatSolverTypeHolders->name);CHKERRQ(ierr);
4369     ierr = PetscNew(&MatSolverTypeHolders->handlers);CHKERRQ(ierr);
4370     ierr = PetscStrallocpy(mtype,(char **)&MatSolverTypeHolders->handlers->mtype);CHKERRQ(ierr);
4371     MatSolverTypeHolders->handlers->getfactor[(int)ftype-1] = getfactor;
4372     PetscFunctionReturn(0);
4373   }
4374   while (next) {
4375     ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr);
4376     if (flg) {
4377       if (!next->handlers) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverTypeHolder is missing handlers");
4378       inext = next->handlers;
4379       while (inext) {
4380         ierr = PetscStrcasecmp(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4381         if (flg) {
4382           inext->getfactor[(int)ftype-1] = getfactor;
4383           PetscFunctionReturn(0);
4384         }
4385         iprev = inext;
4386         inext = inext->next;
4387       }
4388       ierr = PetscNew(&iprev->next);CHKERRQ(ierr);
4389       ierr = PetscStrallocpy(mtype,(char **)&iprev->next->mtype);CHKERRQ(ierr);
4390       iprev->next->getfactor[(int)ftype-1] = getfactor;
4391       PetscFunctionReturn(0);
4392     }
4393     prev = next;
4394     next = next->next;
4395   }
4396   ierr = PetscNew(&prev->next);CHKERRQ(ierr);
4397   ierr = PetscStrallocpy(package,&prev->next->name);CHKERRQ(ierr);
4398   ierr = PetscNew(&prev->next->handlers);CHKERRQ(ierr);
4399   ierr = PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);CHKERRQ(ierr);
4400   prev->next->handlers->getfactor[(int)ftype-1] = getfactor;
4401   PetscFunctionReturn(0);
4402 }
4403 
4404 /*@C
4405    MatSolvePackageGet - Get's the function that creates the factor matrix if it exist
4406 
4407    Input Parameters:
4408 +    package - name of the package, for example petsc or superlu
4409 .    ftype - the type of factorization supported by the package
4410 -    mtype - the matrix type that works with this package
4411 
4412    Output Parameters:
4413 +   foundpackage - PETSC_TRUE if the package was registered
4414 .   foundmtype - PETSC_TRUE if the package supports the requested mtype
4415 -   getfactor - routine that will create the factored matrix ready to be used or NULL if not found
4416 
4417     Level: intermediate
4418 
4419 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4420 @*/
4421 PetscErrorCode MatSolverTypeGet(MatSolverType package,MatType mtype,MatFactorType ftype,PetscBool *foundpackage,PetscBool *foundmtype,PetscErrorCode (**getfactor)(Mat,MatFactorType,Mat*))
4422 {
4423   PetscErrorCode                 ierr;
4424   MatSolverTypeHolder         next = MatSolverTypeHolders;
4425   PetscBool                      flg;
4426   MatSolverTypeForSpecifcType inext;
4427 
4428   PetscFunctionBegin;
4429   if (foundpackage) *foundpackage = PETSC_FALSE;
4430   if (foundmtype)   *foundmtype   = PETSC_FALSE;
4431   if (getfactor)    *getfactor    = NULL;
4432 
4433   if (package) {
4434     while (next) {
4435       ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr);
4436       if (flg) {
4437         if (foundpackage) *foundpackage = PETSC_TRUE;
4438         inext = next->handlers;
4439         while (inext) {
4440           ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4441           if (flg) {
4442             if (foundmtype) *foundmtype = PETSC_TRUE;
4443             if (getfactor)  *getfactor  = inext->getfactor[(int)ftype-1];
4444             PetscFunctionReturn(0);
4445           }
4446           inext = inext->next;
4447         }
4448       }
4449       next = next->next;
4450     }
4451   } else {
4452     while (next) {
4453       inext = next->handlers;
4454       while (inext) {
4455         ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4456         if (flg && inext->getfactor[(int)ftype-1]) {
4457           if (foundpackage) *foundpackage = PETSC_TRUE;
4458           if (foundmtype)   *foundmtype   = PETSC_TRUE;
4459           if (getfactor)    *getfactor    = inext->getfactor[(int)ftype-1];
4460           PetscFunctionReturn(0);
4461         }
4462         inext = inext->next;
4463       }
4464       next = next->next;
4465     }
4466   }
4467   PetscFunctionReturn(0);
4468 }
4469 
4470 PetscErrorCode MatSolverTypeDestroy(void)
4471 {
4472   PetscErrorCode              ierr;
4473   MatSolverTypeHolder         next = MatSolverTypeHolders,prev;
4474   MatSolverTypeForSpecifcType inext,iprev;
4475 
4476   PetscFunctionBegin;
4477   while (next) {
4478     ierr = PetscFree(next->name);CHKERRQ(ierr);
4479     inext = next->handlers;
4480     while (inext) {
4481       ierr = PetscFree(inext->mtype);CHKERRQ(ierr);
4482       iprev = inext;
4483       inext = inext->next;
4484       ierr = PetscFree(iprev);CHKERRQ(ierr);
4485     }
4486     prev = next;
4487     next = next->next;
4488     ierr = PetscFree(prev);CHKERRQ(ierr);
4489   }
4490   MatSolverTypeHolders = NULL;
4491   PetscFunctionReturn(0);
4492 }
4493 
4494 /*@C
4495    MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic()
4496 
4497    Collective on Mat
4498 
4499    Input Parameters:
4500 +  mat - the matrix
4501 .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4502 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4503 
4504    Output Parameters:
4505 .  f - the factor matrix used with MatXXFactorSymbolic() calls
4506 
4507    Notes:
4508       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4509      such as pastix, superlu, mumps etc.
4510 
4511       PETSc must have been ./configure to use the external solver, using the option --download-package
4512 
4513    Level: intermediate
4514 
4515 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4516 @*/
4517 PetscErrorCode MatGetFactor(Mat mat, MatSolverType type,MatFactorType ftype,Mat *f)
4518 {
4519   PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
4520   PetscBool      foundpackage,foundmtype;
4521 
4522   PetscFunctionBegin;
4523   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4524   PetscValidType(mat,1);
4525 
4526   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4527   MatCheckPreallocated(mat,1);
4528 
4529   ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,&foundpackage,&foundmtype,&conv);CHKERRQ(ierr);
4530   if (!foundpackage) {
4531     if (type) {
4532       SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver package %s. Perhaps you must ./configure with --download-%s",type,type);
4533     } else {
4534       SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate a solver package. Perhaps you must ./configure with --download-<package>");
4535     }
4536   }
4537 
4538   if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support matrix type %s",type,((PetscObject)mat)->type_name);
4539   if (!conv) SETERRQ3(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support factorization type %s for  matrix type %s",type,MatFactorTypes[ftype],((PetscObject)mat)->type_name);
4540 
4541 #if defined(PETSC_USE_COMPLEX)
4542   if (mat->hermitian && !mat->symmetric && (ftype == MAT_FACTOR_CHOLESKY||ftype == MAT_FACTOR_ICC)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Hermitian CHOLESKY or ICC Factor is not supported");
4543 #endif
4544 
4545   ierr = (*conv)(mat,ftype,f);CHKERRQ(ierr);
4546   PetscFunctionReturn(0);
4547 }
4548 
4549 /*@C
4550    MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type
4551 
4552    Not Collective
4553 
4554    Input Parameters:
4555 +  mat - the matrix
4556 .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4557 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4558 
4559    Output Parameter:
4560 .    flg - PETSC_TRUE if the factorization is available
4561 
4562    Notes:
4563       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4564      such as pastix, superlu, mumps etc.
4565 
4566       PETSc must have been ./configure to use the external solver, using the option --download-package
4567 
4568    Level: intermediate
4569 
4570 .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
4571 @*/
4572 PetscErrorCode MatGetFactorAvailable(Mat mat, MatSolverType type,MatFactorType ftype,PetscBool  *flg)
4573 {
4574   PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*);
4575 
4576   PetscFunctionBegin;
4577   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4578   PetscValidType(mat,1);
4579 
4580   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4581   MatCheckPreallocated(mat,1);
4582 
4583   *flg = PETSC_FALSE;
4584   ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);CHKERRQ(ierr);
4585   if (gconv) {
4586     *flg = PETSC_TRUE;
4587   }
4588   PetscFunctionReturn(0);
4589 }
4590 
4591 #include <petscdmtypes.h>
4592 
4593 /*@
4594    MatDuplicate - Duplicates a matrix including the non-zero structure.
4595 
4596    Collective on Mat
4597 
4598    Input Parameters:
4599 +  mat - the matrix
4600 -  op - One of MAT_DO_NOT_COPY_VALUES, MAT_COPY_VALUES, or MAT_SHARE_NONZERO_PATTERN.
4601         See the manual page for MatDuplicateOption for an explanation of these options.
4602 
4603    Output Parameter:
4604 .  M - pointer to place new matrix
4605 
4606    Level: intermediate
4607 
4608    Concepts: matrices^duplicating
4609 
4610    Notes:
4611     You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN.
4612     When original mat is a product of matrix operation, e.g., an output of MatMatMult() or MatCreateSubMatrix(), only the simple matrix data structure of mat is duplicated and the internal data structures created for the reuse of previous matrix operations are not duplicated. User should not use MatDuplicate() to create new matrix M if M is intended to be reused as the product of matrix operation.
4613 
4614 .seealso: MatCopy(), MatConvert(), MatDuplicateOption
4615 @*/
4616 PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4617 {
4618   PetscErrorCode ierr;
4619   Mat            B;
4620   PetscInt       i;
4621   DM             dm;
4622   void           (*viewf)(void);
4623 
4624   PetscFunctionBegin;
4625   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4626   PetscValidType(mat,1);
4627   PetscValidPointer(M,3);
4628   if (op == MAT_COPY_VALUES && !mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MAT_COPY_VALUES not allowed for unassembled matrix");
4629   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4630   MatCheckPreallocated(mat,1);
4631 
4632   *M = 0;
4633   if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type");
4634   ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4635   ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr);
4636   B    = *M;
4637 
4638   ierr = MatGetOperation(mat,MATOP_VIEW,&viewf);CHKERRQ(ierr);
4639   if (viewf) {
4640     ierr = MatSetOperation(B,MATOP_VIEW,viewf);CHKERRQ(ierr);
4641   }
4642 
4643   B->stencil.dim = mat->stencil.dim;
4644   B->stencil.noc = mat->stencil.noc;
4645   for (i=0; i<=mat->stencil.dim; i++) {
4646     B->stencil.dims[i]   = mat->stencil.dims[i];
4647     B->stencil.starts[i] = mat->stencil.starts[i];
4648   }
4649 
4650   B->nooffproczerorows = mat->nooffproczerorows;
4651   B->nooffprocentries  = mat->nooffprocentries;
4652 
4653   ierr = PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);CHKERRQ(ierr);
4654   if (dm) {
4655     ierr = PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr);
4656   }
4657   ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4658   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
4659   PetscFunctionReturn(0);
4660 }
4661 
4662 /*@
4663    MatGetDiagonal - Gets the diagonal of a matrix.
4664 
4665    Logically Collective on Mat and Vec
4666 
4667    Input Parameters:
4668 +  mat - the matrix
4669 -  v - the vector for storing the diagonal
4670 
4671    Output Parameter:
4672 .  v - the diagonal of the matrix
4673 
4674    Level: intermediate
4675 
4676    Note:
4677    Currently only correct in parallel for square matrices.
4678 
4679    Concepts: matrices^accessing diagonals
4680 
4681 .seealso: MatGetRow(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs()
4682 @*/
4683 PetscErrorCode MatGetDiagonal(Mat mat,Vec v)
4684 {
4685   PetscErrorCode ierr;
4686 
4687   PetscFunctionBegin;
4688   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4689   PetscValidType(mat,1);
4690   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4691   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4692   if (!mat->ops->getdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4693   MatCheckPreallocated(mat,1);
4694 
4695   ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr);
4696   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4697   PetscFunctionReturn(0);
4698 }
4699 
4700 /*@C
4701    MatGetRowMin - Gets the minimum value (of the real part) of each
4702         row of the matrix
4703 
4704    Logically Collective on Mat and Vec
4705 
4706    Input Parameters:
4707 .  mat - the matrix
4708 
4709    Output Parameter:
4710 +  v - the vector for storing the maximums
4711 -  idx - the indices of the column found for each row (optional)
4712 
4713    Level: intermediate
4714 
4715    Notes:
4716     The result of this call are the same as if one converted the matrix to dense format
4717       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4718 
4719     This code is only implemented for a couple of matrix formats.
4720 
4721    Concepts: matrices^getting row maximums
4722 
4723 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(),
4724           MatGetRowMax()
4725 @*/
4726 PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4727 {
4728   PetscErrorCode ierr;
4729 
4730   PetscFunctionBegin;
4731   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4732   PetscValidType(mat,1);
4733   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4734   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4735   if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4736   MatCheckPreallocated(mat,1);
4737 
4738   ierr = (*mat->ops->getrowmin)(mat,v,idx);CHKERRQ(ierr);
4739   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4740   PetscFunctionReturn(0);
4741 }
4742 
4743 /*@C
4744    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4745         row of the matrix
4746 
4747    Logically Collective on Mat and Vec
4748 
4749    Input Parameters:
4750 .  mat - the matrix
4751 
4752    Output Parameter:
4753 +  v - the vector for storing the minimums
4754 -  idx - the indices of the column found for each row (or NULL if not needed)
4755 
4756    Level: intermediate
4757 
4758    Notes:
4759     if a row is completely empty or has only 0.0 values then the idx[] value for that
4760     row is 0 (the first column).
4761 
4762     This code is only implemented for a couple of matrix formats.
4763 
4764    Concepts: matrices^getting row maximums
4765 
4766 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4767 @*/
4768 PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4769 {
4770   PetscErrorCode ierr;
4771 
4772   PetscFunctionBegin;
4773   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4774   PetscValidType(mat,1);
4775   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4776   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4777   if (!mat->ops->getrowminabs) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4778   MatCheckPreallocated(mat,1);
4779   if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);}
4780 
4781   ierr = (*mat->ops->getrowminabs)(mat,v,idx);CHKERRQ(ierr);
4782   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4783   PetscFunctionReturn(0);
4784 }
4785 
4786 /*@C
4787    MatGetRowMax - Gets the maximum value (of the real part) of each
4788         row of the matrix
4789 
4790    Logically Collective on Mat and Vec
4791 
4792    Input Parameters:
4793 .  mat - the matrix
4794 
4795    Output Parameter:
4796 +  v - the vector for storing the maximums
4797 -  idx - the indices of the column found for each row (optional)
4798 
4799    Level: intermediate
4800 
4801    Notes:
4802     The result of this call are the same as if one converted the matrix to dense format
4803       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4804 
4805     This code is only implemented for a couple of matrix formats.
4806 
4807    Concepts: matrices^getting row maximums
4808 
4809 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4810 @*/
4811 PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4812 {
4813   PetscErrorCode ierr;
4814 
4815   PetscFunctionBegin;
4816   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4817   PetscValidType(mat,1);
4818   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4819   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4820   if (!mat->ops->getrowmax) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4821   MatCheckPreallocated(mat,1);
4822 
4823   ierr = (*mat->ops->getrowmax)(mat,v,idx);CHKERRQ(ierr);
4824   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4825   PetscFunctionReturn(0);
4826 }
4827 
4828 /*@C
4829    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4830         row of the matrix
4831 
4832    Logically Collective on Mat and Vec
4833 
4834    Input Parameters:
4835 .  mat - the matrix
4836 
4837    Output Parameter:
4838 +  v - the vector for storing the maximums
4839 -  idx - the indices of the column found for each row (or NULL if not needed)
4840 
4841    Level: intermediate
4842 
4843    Notes:
4844     if a row is completely empty or has only 0.0 values then the idx[] value for that
4845     row is 0 (the first column).
4846 
4847     This code is only implemented for a couple of matrix formats.
4848 
4849    Concepts: matrices^getting row maximums
4850 
4851 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
4852 @*/
4853 PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4854 {
4855   PetscErrorCode ierr;
4856 
4857   PetscFunctionBegin;
4858   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4859   PetscValidType(mat,1);
4860   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4861   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4862   if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4863   MatCheckPreallocated(mat,1);
4864   if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);}
4865 
4866   ierr = (*mat->ops->getrowmaxabs)(mat,v,idx);CHKERRQ(ierr);
4867   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4868   PetscFunctionReturn(0);
4869 }
4870 
4871 /*@
4872    MatGetRowSum - Gets the sum of each row of the matrix
4873 
4874    Logically or Neighborhood Collective on Mat and Vec
4875 
4876    Input Parameters:
4877 .  mat - the matrix
4878 
4879    Output Parameter:
4880 .  v - the vector for storing the sum of rows
4881 
4882    Level: intermediate
4883 
4884    Notes:
4885     This code is slow since it is not currently specialized for different formats
4886 
4887    Concepts: matrices^getting row sums
4888 
4889 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
4890 @*/
4891 PetscErrorCode MatGetRowSum(Mat mat, Vec v)
4892 {
4893   Vec            ones;
4894   PetscErrorCode ierr;
4895 
4896   PetscFunctionBegin;
4897   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4898   PetscValidType(mat,1);
4899   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4900   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4901   MatCheckPreallocated(mat,1);
4902   ierr = MatCreateVecs(mat,&ones,NULL);CHKERRQ(ierr);
4903   ierr = VecSet(ones,1.);CHKERRQ(ierr);
4904   ierr = MatMult(mat,ones,v);CHKERRQ(ierr);
4905   ierr = VecDestroy(&ones);CHKERRQ(ierr);
4906   PetscFunctionReturn(0);
4907 }
4908 
4909 /*@
4910    MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
4911 
4912    Collective on Mat
4913 
4914    Input Parameter:
4915 +  mat - the matrix to transpose
4916 -  reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX
4917 
4918    Output Parameters:
4919 .  B - the transpose
4920 
4921    Notes:
4922      If you use MAT_INPLACE_MATRIX then you must pass in &mat for B
4923 
4924      MAT_REUSE_MATRIX causes the B matrix from a previous call to this function with MAT_INITIAL_MATRIX to be used
4925 
4926      Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed.
4927 
4928    Level: intermediate
4929 
4930    Concepts: matrices^transposing
4931 
4932 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4933 @*/
4934 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4935 {
4936   PetscErrorCode ierr;
4937 
4938   PetscFunctionBegin;
4939   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4940   PetscValidType(mat,1);
4941   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4942   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4943   if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4944   if (reuse == MAT_INPLACE_MATRIX && mat != *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires last matrix to match first");
4945   if (reuse == MAT_REUSE_MATRIX && mat == *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Perhaps you mean MAT_INPLACE_MATRIX");
4946   MatCheckPreallocated(mat,1);
4947 
4948   ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4949   ierr = (*mat->ops->transpose)(mat,reuse,B);CHKERRQ(ierr);
4950   ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4951   if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);}
4952   PetscFunctionReturn(0);
4953 }
4954 
4955 /*@
4956    MatIsTranspose - Test whether a matrix is another one's transpose,
4957         or its own, in which case it tests symmetry.
4958 
4959    Collective on Mat
4960 
4961    Input Parameter:
4962 +  A - the matrix to test
4963 -  B - the matrix to test against, this can equal the first parameter
4964 
4965    Output Parameters:
4966 .  flg - the result
4967 
4968    Notes:
4969    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4970    has a running time of the order of the number of nonzeros; the parallel
4971    test involves parallel copies of the block-offdiagonal parts of the matrix.
4972 
4973    Level: intermediate
4974 
4975    Concepts: matrices^transposing, matrix^symmetry
4976 
4977 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4978 @*/
4979 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4980 {
4981   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4982 
4983   PetscFunctionBegin;
4984   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4985   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4986   PetscValidPointer(flg,3);
4987   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);CHKERRQ(ierr);
4988   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);CHKERRQ(ierr);
4989   *flg = PETSC_FALSE;
4990   if (f && g) {
4991     if (f == g) {
4992       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
4993     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4994   } else {
4995     MatType mattype;
4996     if (!f) {
4997       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
4998     } else {
4999       ierr = MatGetType(B,&mattype);CHKERRQ(ierr);
5000     }
5001     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
5002   }
5003   PetscFunctionReturn(0);
5004 }
5005 
5006 /*@
5007    MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate.
5008 
5009    Collective on Mat
5010 
5011    Input Parameter:
5012 +  mat - the matrix to transpose and complex conjugate
5013 -  reuse - MAT_INITIAL_MATRIX to create a new matrix, MAT_INPLACE_MATRIX to reuse the first argument to store the transpose
5014 
5015    Output Parameters:
5016 .  B - the Hermitian
5017 
5018    Level: intermediate
5019 
5020    Concepts: matrices^transposing, complex conjugatex
5021 
5022 .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
5023 @*/
5024 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
5025 {
5026   PetscErrorCode ierr;
5027 
5028   PetscFunctionBegin;
5029   ierr = MatTranspose(mat,reuse,B);CHKERRQ(ierr);
5030 #if defined(PETSC_USE_COMPLEX)
5031   ierr = MatConjugate(*B);CHKERRQ(ierr);
5032 #endif
5033   PetscFunctionReturn(0);
5034 }
5035 
5036 /*@
5037    MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,
5038 
5039    Collective on Mat
5040 
5041    Input Parameter:
5042 +  A - the matrix to test
5043 -  B - the matrix to test against, this can equal the first parameter
5044 
5045    Output Parameters:
5046 .  flg - the result
5047 
5048    Notes:
5049    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
5050    has a running time of the order of the number of nonzeros; the parallel
5051    test involves parallel copies of the block-offdiagonal parts of the matrix.
5052 
5053    Level: intermediate
5054 
5055    Concepts: matrices^transposing, matrix^symmetry
5056 
5057 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
5058 @*/
5059 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
5060 {
5061   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
5062 
5063   PetscFunctionBegin;
5064   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
5065   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
5066   PetscValidPointer(flg,3);
5067   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);CHKERRQ(ierr);
5068   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);CHKERRQ(ierr);
5069   if (f && g) {
5070     if (f==g) {
5071       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
5072     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
5073   }
5074   PetscFunctionReturn(0);
5075 }
5076 
5077 /*@
5078    MatPermute - Creates a new matrix with rows and columns permuted from the
5079    original.
5080 
5081    Collective on Mat
5082 
5083    Input Parameters:
5084 +  mat - the matrix to permute
5085 .  row - row permutation, each processor supplies only the permutation for its rows
5086 -  col - column permutation, each processor supplies only the permutation for its columns
5087 
5088    Output Parameters:
5089 .  B - the permuted matrix
5090 
5091    Level: advanced
5092 
5093    Note:
5094    The index sets map from row/col of permuted matrix to row/col of original matrix.
5095    The index sets should be on the same communicator as Mat and have the same local sizes.
5096 
5097    Concepts: matrices^permuting
5098 
5099 .seealso: MatGetOrdering(), ISAllGather()
5100 
5101 @*/
5102 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
5103 {
5104   PetscErrorCode ierr;
5105 
5106   PetscFunctionBegin;
5107   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5108   PetscValidType(mat,1);
5109   PetscValidHeaderSpecific(row,IS_CLASSID,2);
5110   PetscValidHeaderSpecific(col,IS_CLASSID,3);
5111   PetscValidPointer(B,4);
5112   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5113   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5114   if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
5115   MatCheckPreallocated(mat,1);
5116 
5117   ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr);
5118   ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);
5119   PetscFunctionReturn(0);
5120 }
5121 
5122 /*@
5123    MatEqual - Compares two matrices.
5124 
5125    Collective on Mat
5126 
5127    Input Parameters:
5128 +  A - the first matrix
5129 -  B - the second matrix
5130 
5131    Output Parameter:
5132 .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
5133 
5134    Level: intermediate
5135 
5136    Concepts: matrices^equality between
5137 @*/
5138 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool  *flg)
5139 {
5140   PetscErrorCode ierr;
5141 
5142   PetscFunctionBegin;
5143   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
5144   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
5145   PetscValidType(A,1);
5146   PetscValidType(B,2);
5147   PetscValidIntPointer(flg,3);
5148   PetscCheckSameComm(A,1,B,2);
5149   MatCheckPreallocated(B,2);
5150   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5151   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5152   if (A->rmap->N != B->rmap->N || A->cmap->N != B->cmap->N) SETERRQ4(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %D %D %D %D",A->rmap->N,B->rmap->N,A->cmap->N,B->cmap->N);
5153   if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
5154   if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
5155   if (A->ops->equal != B->ops->equal) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"A is type: %s\nB is type: %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
5156   MatCheckPreallocated(A,1);
5157 
5158   ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr);
5159   PetscFunctionReturn(0);
5160 }
5161 
5162 /*@
5163    MatDiagonalScale - Scales a matrix on the left and right by diagonal
5164    matrices that are stored as vectors.  Either of the two scaling
5165    matrices can be NULL.
5166 
5167    Collective on Mat
5168 
5169    Input Parameters:
5170 +  mat - the matrix to be scaled
5171 .  l - the left scaling vector (or NULL)
5172 -  r - the right scaling vector (or NULL)
5173 
5174    Notes:
5175    MatDiagonalScale() computes A = LAR, where
5176    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
5177    The L scales the rows of the matrix, the R scales the columns of the matrix.
5178 
5179    Level: intermediate
5180 
5181    Concepts: matrices^diagonal scaling
5182    Concepts: diagonal scaling of matrices
5183 
5184 .seealso: MatScale(), MatShift(), MatDiagonalSet()
5185 @*/
5186 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
5187 {
5188   PetscErrorCode ierr;
5189 
5190   PetscFunctionBegin;
5191   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5192   PetscValidType(mat,1);
5193   if (!mat->ops->diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5194   if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);}
5195   if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);}
5196   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5197   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5198   MatCheckPreallocated(mat,1);
5199 
5200   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5201   ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr);
5202   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5203   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5204 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5205   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5206     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5207   }
5208 #endif
5209   PetscFunctionReturn(0);
5210 }
5211 
5212 /*@
5213     MatScale - Scales all elements of a matrix by a given number.
5214 
5215     Logically Collective on Mat
5216 
5217     Input Parameters:
5218 +   mat - the matrix to be scaled
5219 -   a  - the scaling value
5220 
5221     Output Parameter:
5222 .   mat - the scaled matrix
5223 
5224     Level: intermediate
5225 
5226     Concepts: matrices^scaling all entries
5227 
5228 .seealso: MatDiagonalScale()
5229 @*/
5230 PetscErrorCode MatScale(Mat mat,PetscScalar a)
5231 {
5232   PetscErrorCode ierr;
5233 
5234   PetscFunctionBegin;
5235   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5236   PetscValidType(mat,1);
5237   if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5238   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5239   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5240   PetscValidLogicalCollectiveScalar(mat,a,2);
5241   MatCheckPreallocated(mat,1);
5242 
5243   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5244   if (a != (PetscScalar)1.0) {
5245     ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr);
5246     ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5247 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5248     if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5249       mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5250     }
5251 #endif
5252   }
5253   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5254   PetscFunctionReturn(0);
5255 }
5256 
5257 /*@
5258    MatNorm - Calculates various norms of a matrix.
5259 
5260    Collective on Mat
5261 
5262    Input Parameters:
5263 +  mat - the matrix
5264 -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
5265 
5266    Output Parameters:
5267 .  nrm - the resulting norm
5268 
5269    Level: intermediate
5270 
5271    Concepts: matrices^norm
5272    Concepts: norm^of matrix
5273 @*/
5274 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
5275 {
5276   PetscErrorCode ierr;
5277 
5278   PetscFunctionBegin;
5279   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5280   PetscValidType(mat,1);
5281   PetscValidScalarPointer(nrm,3);
5282 
5283   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5284   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5285   if (!mat->ops->norm) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5286   MatCheckPreallocated(mat,1);
5287 
5288   ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr);
5289   PetscFunctionReturn(0);
5290 }
5291 
5292 /*
5293      This variable is used to prevent counting of MatAssemblyBegin() that
5294    are called from within a MatAssemblyEnd().
5295 */
5296 static PetscInt MatAssemblyEnd_InUse = 0;
5297 /*@
5298    MatAssemblyBegin - Begins assembling the matrix.  This routine should
5299    be called after completing all calls to MatSetValues().
5300 
5301    Collective on Mat
5302 
5303    Input Parameters:
5304 +  mat - the matrix
5305 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5306 
5307    Notes:
5308    MatSetValues() generally caches the values.  The matrix is ready to
5309    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5310    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5311    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5312    using the matrix.
5313 
5314    ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the
5315    same flag of MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY for all processes. Thus you CANNOT locally change from ADD_VALUES to INSERT_VALUES, that is
5316    a global collective operation requring all processes that share the matrix.
5317 
5318    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5319    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5320    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5321 
5322    Level: beginner
5323 
5324    Concepts: matrices^assembling
5325 
5326 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
5327 @*/
5328 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
5329 {
5330   PetscErrorCode ierr;
5331 
5332   PetscFunctionBegin;
5333   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5334   PetscValidType(mat,1);
5335   MatCheckPreallocated(mat,1);
5336   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
5337   if (mat->assembled) {
5338     mat->was_assembled = PETSC_TRUE;
5339     mat->assembled     = PETSC_FALSE;
5340   }
5341   if (!MatAssemblyEnd_InUse) {
5342     ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5343     if (mat->ops->assemblybegin) {ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
5344     ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5345   } else if (mat->ops->assemblybegin) {
5346     ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);
5347   }
5348   PetscFunctionReturn(0);
5349 }
5350 
5351 /*@
5352    MatAssembled - Indicates if a matrix has been assembled and is ready for
5353      use; for example, in matrix-vector product.
5354 
5355    Not Collective
5356 
5357    Input Parameter:
5358 .  mat - the matrix
5359 
5360    Output Parameter:
5361 .  assembled - PETSC_TRUE or PETSC_FALSE
5362 
5363    Level: advanced
5364 
5365    Concepts: matrices^assembled?
5366 
5367 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
5368 @*/
5369 PetscErrorCode MatAssembled(Mat mat,PetscBool  *assembled)
5370 {
5371   PetscFunctionBegin;
5372   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5373   PetscValidPointer(assembled,2);
5374   *assembled = mat->assembled;
5375   PetscFunctionReturn(0);
5376 }
5377 
5378 /*@
5379    MatAssemblyEnd - Completes assembling the matrix.  This routine should
5380    be called after MatAssemblyBegin().
5381 
5382    Collective on Mat
5383 
5384    Input Parameters:
5385 +  mat - the matrix
5386 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5387 
5388    Options Database Keys:
5389 +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
5390 .  -mat_view ::ascii_info_detail - Prints more detailed info
5391 .  -mat_view - Prints matrix in ASCII format
5392 .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
5393 .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
5394 .  -display <name> - Sets display name (default is host)
5395 .  -draw_pause <sec> - Sets number of seconds to pause after display
5396 .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab )
5397 .  -viewer_socket_machine <machine> - Machine to use for socket
5398 .  -viewer_socket_port <port> - Port number to use for socket
5399 -  -mat_view binary:filename[:append] - Save matrix to file in binary format
5400 
5401    Notes:
5402    MatSetValues() generally caches the values.  The matrix is ready to
5403    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5404    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5405    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5406    using the matrix.
5407 
5408    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5409    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5410    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5411 
5412    Level: beginner
5413 
5414 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
5415 @*/
5416 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
5417 {
5418   PetscErrorCode  ierr;
5419   static PetscInt inassm = 0;
5420   PetscBool       flg    = PETSC_FALSE;
5421 
5422   PetscFunctionBegin;
5423   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5424   PetscValidType(mat,1);
5425 
5426   inassm++;
5427   MatAssemblyEnd_InUse++;
5428   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
5429     ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5430     if (mat->ops->assemblyend) {
5431       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5432     }
5433     ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5434   } else if (mat->ops->assemblyend) {
5435     ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5436   }
5437 
5438   /* Flush assembly is not a true assembly */
5439   if (type != MAT_FLUSH_ASSEMBLY) {
5440     mat->assembled = PETSC_TRUE; mat->num_ass++;
5441   }
5442   mat->insertmode = NOT_SET_VALUES;
5443   MatAssemblyEnd_InUse--;
5444   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5445   if (!mat->symmetric_eternal) {
5446     mat->symmetric_set              = PETSC_FALSE;
5447     mat->hermitian_set              = PETSC_FALSE;
5448     mat->structurally_symmetric_set = PETSC_FALSE;
5449   }
5450 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5451   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5452     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5453   }
5454 #endif
5455   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
5456     ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5457 
5458     if (mat->checksymmetryonassembly) {
5459       ierr = MatIsSymmetric(mat,mat->checksymmetrytol,&flg);CHKERRQ(ierr);
5460       if (flg) {
5461         ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5462       } else {
5463         ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5464       }
5465     }
5466     if (mat->nullsp && mat->checknullspaceonassembly) {
5467       ierr = MatNullSpaceTest(mat->nullsp,mat,NULL);CHKERRQ(ierr);
5468     }
5469   }
5470   inassm--;
5471   PetscFunctionReturn(0);
5472 }
5473 
5474 /*@
5475    MatSetOption - Sets a parameter option for a matrix. Some options
5476    may be specific to certain storage formats.  Some options
5477    determine how values will be inserted (or added). Sorted,
5478    row-oriented input will generally assemble the fastest. The default
5479    is row-oriented.
5480 
5481    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5482 
5483    Input Parameters:
5484 +  mat - the matrix
5485 .  option - the option, one of those listed below (and possibly others),
5486 -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5487 
5488   Options Describing Matrix Structure:
5489 +    MAT_SPD - symmetric positive definite
5490 .    MAT_SYMMETRIC - symmetric in terms of both structure and value
5491 .    MAT_HERMITIAN - transpose is the complex conjugation
5492 .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5493 -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5494                             you set to be kept with all future use of the matrix
5495                             including after MatAssemblyBegin/End() which could
5496                             potentially change the symmetry structure, i.e. you
5497                             KNOW the matrix will ALWAYS have the property you set.
5498 
5499 
5500    Options For Use with MatSetValues():
5501    Insert a logically dense subblock, which can be
5502 .    MAT_ROW_ORIENTED - row-oriented (default)
5503 
5504    Note these options reflect the data you pass in with MatSetValues(); it has
5505    nothing to do with how the data is stored internally in the matrix
5506    data structure.
5507 
5508    When (re)assembling a matrix, we can restrict the input for
5509    efficiency/debugging purposes.  These options include:
5510 +    MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow)
5511 .    MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
5512 .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
5513 .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
5514 .    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
5515 .    MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
5516         any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
5517         performance for very large process counts.
5518 -    MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset
5519         of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly
5520         functions, instead sending only neighbor messages.
5521 
5522    Notes:
5523    Except for MAT_UNUSED_NONZERO_LOCATION_ERR and  MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg!
5524 
5525    Some options are relevant only for particular matrix types and
5526    are thus ignored by others.  Other options are not supported by
5527    certain matrix types and will generate an error message if set.
5528 
5529    If using a Fortran 77 module to compute a matrix, one may need to
5530    use the column-oriented option (or convert to the row-oriented
5531    format).
5532 
5533    MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
5534    that would generate a new entry in the nonzero structure is instead
5535    ignored.  Thus, if memory has not alredy been allocated for this particular
5536    data, then the insertion is ignored. For dense matrices, in which
5537    the entire array is allocated, no entries are ever ignored.
5538    Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5539 
5540    MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5541    that would generate a new entry in the nonzero structure instead produces
5542    an error. (Currently supported for AIJ and BAIJ formats only.) If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5543 
5544    MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5545    that would generate a new entry that has not been preallocated will
5546    instead produce an error. (Currently supported for AIJ and BAIJ formats
5547    only.) This is a useful flag when debugging matrix memory preallocation.
5548    If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5549 
5550    MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for
5551    other processors should be dropped, rather than stashed.
5552    This is useful if you know that the "owning" processor is also
5553    always generating the correct matrix entries, so that PETSc need
5554    not transfer duplicate entries generated on another processor.
5555 
5556    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5557    searches during matrix assembly. When this flag is set, the hash table
5558    is created during the first Matrix Assembly. This hash table is
5559    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5560    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5561    should be used with MAT_USE_HASH_TABLE flag. This option is currently
5562    supported by MATMPIBAIJ format only.
5563 
5564    MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries
5565    are kept in the nonzero structure
5566 
5567    MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
5568    a zero location in the matrix
5569 
5570    MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types
5571 
5572    MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the
5573         zero row routines and thus improves performance for very large process counts.
5574 
5575    MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular
5576         part of the matrix (since they should match the upper triangular part).
5577 
5578    Notes:
5579     Can only be called after MatSetSizes() and MatSetType() have been set.
5580 
5581    Level: intermediate
5582 
5583    Concepts: matrices^setting options
5584 
5585 .seealso:  MatOption, Mat
5586 
5587 @*/
5588 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg)
5589 {
5590   PetscErrorCode ierr;
5591 
5592   PetscFunctionBegin;
5593   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5594   PetscValidType(mat,1);
5595   if (op > 0) {
5596     PetscValidLogicalCollectiveEnum(mat,op,2);
5597     PetscValidLogicalCollectiveBool(mat,flg,3);
5598   }
5599 
5600   if (((int) op) <= MAT_OPTION_MIN || ((int) op) >= MAT_OPTION_MAX) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Options %d is out of range",(int)op);
5601   if (!((PetscObject)mat)->type_name) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_TYPENOTSET,"Cannot set options until type and size have been set, see MatSetType() and MatSetSizes()");
5602 
5603   switch (op) {
5604   case MAT_NO_OFF_PROC_ENTRIES:
5605     mat->nooffprocentries = flg;
5606     PetscFunctionReturn(0);
5607     break;
5608   case MAT_SUBSET_OFF_PROC_ENTRIES:
5609     mat->assembly_subset = flg;
5610     if (!mat->assembly_subset) { /* See the same logic in VecAssembly wrt VEC_SUBSET_OFF_PROC_ENTRIES */
5611 #if !defined(PETSC_HAVE_MPIUNI)
5612       ierr = MatStashScatterDestroy_BTS(&mat->stash);CHKERRQ(ierr);
5613 #endif
5614       mat->stash.first_assembly_done = PETSC_FALSE;
5615     }
5616     PetscFunctionReturn(0);
5617   case MAT_NO_OFF_PROC_ZERO_ROWS:
5618     mat->nooffproczerorows = flg;
5619     PetscFunctionReturn(0);
5620     break;
5621   case MAT_SPD:
5622     mat->spd_set = PETSC_TRUE;
5623     mat->spd     = flg;
5624     if (flg) {
5625       mat->symmetric                  = PETSC_TRUE;
5626       mat->structurally_symmetric     = PETSC_TRUE;
5627       mat->symmetric_set              = PETSC_TRUE;
5628       mat->structurally_symmetric_set = PETSC_TRUE;
5629     }
5630     break;
5631   case MAT_SYMMETRIC:
5632     mat->symmetric = flg;
5633     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5634     mat->symmetric_set              = PETSC_TRUE;
5635     mat->structurally_symmetric_set = flg;
5636 #if !defined(PETSC_USE_COMPLEX)
5637     mat->hermitian     = flg;
5638     mat->hermitian_set = PETSC_TRUE;
5639 #endif
5640     break;
5641   case MAT_HERMITIAN:
5642     mat->hermitian = flg;
5643     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5644     mat->hermitian_set              = PETSC_TRUE;
5645     mat->structurally_symmetric_set = flg;
5646 #if !defined(PETSC_USE_COMPLEX)
5647     mat->symmetric     = flg;
5648     mat->symmetric_set = PETSC_TRUE;
5649 #endif
5650     break;
5651   case MAT_STRUCTURALLY_SYMMETRIC:
5652     mat->structurally_symmetric     = flg;
5653     mat->structurally_symmetric_set = PETSC_TRUE;
5654     break;
5655   case MAT_SYMMETRY_ETERNAL:
5656     mat->symmetric_eternal = flg;
5657     break;
5658   case MAT_STRUCTURE_ONLY:
5659     mat->structure_only = flg;
5660     break;
5661   default:
5662     break;
5663   }
5664   if (mat->ops->setoption) {
5665     ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr);
5666   }
5667   PetscFunctionReturn(0);
5668 }
5669 
5670 /*@
5671    MatGetOption - Gets a parameter option that has been set for a matrix.
5672 
5673    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5674 
5675    Input Parameters:
5676 +  mat - the matrix
5677 -  option - the option, this only responds to certain options, check the code for which ones
5678 
5679    Output Parameter:
5680 .  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5681 
5682     Notes:
5683     Can only be called after MatSetSizes() and MatSetType() have been set.
5684 
5685    Level: intermediate
5686 
5687    Concepts: matrices^setting options
5688 
5689 .seealso:  MatOption, MatSetOption()
5690 
5691 @*/
5692 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg)
5693 {
5694   PetscFunctionBegin;
5695   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5696   PetscValidType(mat,1);
5697 
5698   if (((int) op) <= MAT_OPTION_MIN || ((int) op) >= MAT_OPTION_MAX) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Options %d is out of range",(int)op);
5699   if (!((PetscObject)mat)->type_name) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_TYPENOTSET,"Cannot get options until type and size have been set, see MatSetType() and MatSetSizes()");
5700 
5701   switch (op) {
5702   case MAT_NO_OFF_PROC_ENTRIES:
5703     *flg = mat->nooffprocentries;
5704     break;
5705   case MAT_NO_OFF_PROC_ZERO_ROWS:
5706     *flg = mat->nooffproczerorows;
5707     break;
5708   case MAT_SYMMETRIC:
5709     *flg = mat->symmetric;
5710     break;
5711   case MAT_HERMITIAN:
5712     *flg = mat->hermitian;
5713     break;
5714   case MAT_STRUCTURALLY_SYMMETRIC:
5715     *flg = mat->structurally_symmetric;
5716     break;
5717   case MAT_SYMMETRY_ETERNAL:
5718     *flg = mat->symmetric_eternal;
5719     break;
5720   case MAT_SPD:
5721     *flg = mat->spd;
5722     break;
5723   default:
5724     break;
5725   }
5726   PetscFunctionReturn(0);
5727 }
5728 
5729 /*@
5730    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5731    this routine retains the old nonzero structure.
5732 
5733    Logically Collective on Mat
5734 
5735    Input Parameters:
5736 .  mat - the matrix
5737 
5738    Level: intermediate
5739 
5740    Notes:
5741     If the matrix was not preallocated then a default, likely poor preallocation will be set in the matrix, so this should be called after the preallocation phase.
5742    See the Performance chapter of the users manual for information on preallocating matrices.
5743 
5744    Concepts: matrices^zeroing
5745 
5746 .seealso: MatZeroRows()
5747 @*/
5748 PetscErrorCode MatZeroEntries(Mat mat)
5749 {
5750   PetscErrorCode ierr;
5751 
5752   PetscFunctionBegin;
5753   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5754   PetscValidType(mat,1);
5755   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5756   if (mat->insertmode != NOT_SET_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for matrices where you have set values but not yet assembled");
5757   if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5758   MatCheckPreallocated(mat,1);
5759 
5760   ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5761   ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
5762   ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5763   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5764 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5765   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5766     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5767   }
5768 #endif
5769   PetscFunctionReturn(0);
5770 }
5771 
5772 /*@
5773    MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal)
5774    of a set of rows and columns of a matrix.
5775 
5776    Collective on Mat
5777 
5778    Input Parameters:
5779 +  mat - the matrix
5780 .  numRows - the number of rows to remove
5781 .  rows - the global row indices
5782 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5783 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5784 -  b - optional vector of right hand side, that will be adjusted by provided solution
5785 
5786    Notes:
5787    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5788 
5789    The user can set a value in the diagonal entry (or for the AIJ and
5790    row formats can optionally remove the main diagonal entry from the
5791    nonzero structure as well, by passing 0.0 as the final argument).
5792 
5793    For the parallel case, all processes that share the matrix (i.e.,
5794    those in the communicator used for matrix creation) MUST call this
5795    routine, regardless of whether any rows being zeroed are owned by
5796    them.
5797 
5798    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5799    list only rows local to itself).
5800 
5801    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5802 
5803    Level: intermediate
5804 
5805    Concepts: matrices^zeroing rows
5806 
5807 .seealso: MatZeroRowsIS(), MatZeroRows(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5808           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5809 @*/
5810 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5811 {
5812   PetscErrorCode ierr;
5813 
5814   PetscFunctionBegin;
5815   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5816   PetscValidType(mat,1);
5817   if (numRows) PetscValidIntPointer(rows,3);
5818   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5819   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5820   if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5821   MatCheckPreallocated(mat,1);
5822 
5823   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5824   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5825   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5826 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5827   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5828     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5829   }
5830 #endif
5831   PetscFunctionReturn(0);
5832 }
5833 
5834 /*@
5835    MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
5836    of a set of rows and columns of a matrix.
5837 
5838    Collective on Mat
5839 
5840    Input Parameters:
5841 +  mat - the matrix
5842 .  is - the rows to zero
5843 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5844 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5845 -  b - optional vector of right hand side, that will be adjusted by provided solution
5846 
5847    Notes:
5848    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5849 
5850    The user can set a value in the diagonal entry (or for the AIJ and
5851    row formats can optionally remove the main diagonal entry from the
5852    nonzero structure as well, by passing 0.0 as the final argument).
5853 
5854    For the parallel case, all processes that share the matrix (i.e.,
5855    those in the communicator used for matrix creation) MUST call this
5856    routine, regardless of whether any rows being zeroed are owned by
5857    them.
5858 
5859    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5860    list only rows local to itself).
5861 
5862    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5863 
5864    Level: intermediate
5865 
5866    Concepts: matrices^zeroing rows
5867 
5868 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5869           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRows(), MatZeroRowsColumnsStencil()
5870 @*/
5871 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5872 {
5873   PetscErrorCode ierr;
5874   PetscInt       numRows;
5875   const PetscInt *rows;
5876 
5877   PetscFunctionBegin;
5878   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5879   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5880   PetscValidType(mat,1);
5881   PetscValidType(is,2);
5882   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5883   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5884   ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5885   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5886   PetscFunctionReturn(0);
5887 }
5888 
5889 /*@
5890    MatZeroRows - Zeros all entries (except possibly the main diagonal)
5891    of a set of rows of a matrix.
5892 
5893    Collective on Mat
5894 
5895    Input Parameters:
5896 +  mat - the matrix
5897 .  numRows - the number of rows to remove
5898 .  rows - the global row indices
5899 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5900 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5901 -  b - optional vector of right hand side, that will be adjusted by provided solution
5902 
5903    Notes:
5904    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5905    but does not release memory.  For the dense and block diagonal
5906    formats this does not alter the nonzero structure.
5907 
5908    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5909    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5910    merely zeroed.
5911 
5912    The user can set a value in the diagonal entry (or for the AIJ and
5913    row formats can optionally remove the main diagonal entry from the
5914    nonzero structure as well, by passing 0.0 as the final argument).
5915 
5916    For the parallel case, all processes that share the matrix (i.e.,
5917    those in the communicator used for matrix creation) MUST call this
5918    routine, regardless of whether any rows being zeroed are owned by
5919    them.
5920 
5921    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5922    list only rows local to itself).
5923 
5924    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5925    owns that are to be zeroed. This saves a global synchronization in the implementation.
5926 
5927    Level: intermediate
5928 
5929    Concepts: matrices^zeroing rows
5930 
5931 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5932           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5933 @*/
5934 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5935 {
5936   PetscErrorCode ierr;
5937 
5938   PetscFunctionBegin;
5939   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5940   PetscValidType(mat,1);
5941   if (numRows) PetscValidIntPointer(rows,3);
5942   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5943   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5944   if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5945   MatCheckPreallocated(mat,1);
5946 
5947   ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5948   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5949   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5950 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5951   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5952     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5953   }
5954 #endif
5955   PetscFunctionReturn(0);
5956 }
5957 
5958 /*@
5959    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5960    of a set of rows of a matrix.
5961 
5962    Collective on Mat
5963 
5964    Input Parameters:
5965 +  mat - the matrix
5966 .  is - index set of rows to remove
5967 .  diag - value put in all diagonals of eliminated rows
5968 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5969 -  b - optional vector of right hand side, that will be adjusted by provided solution
5970 
5971    Notes:
5972    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5973    but does not release memory.  For the dense and block diagonal
5974    formats this does not alter the nonzero structure.
5975 
5976    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5977    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5978    merely zeroed.
5979 
5980    The user can set a value in the diagonal entry (or for the AIJ and
5981    row formats can optionally remove the main diagonal entry from the
5982    nonzero structure as well, by passing 0.0 as the final argument).
5983 
5984    For the parallel case, all processes that share the matrix (i.e.,
5985    those in the communicator used for matrix creation) MUST call this
5986    routine, regardless of whether any rows being zeroed are owned by
5987    them.
5988 
5989    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5990    list only rows local to itself).
5991 
5992    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5993    owns that are to be zeroed. This saves a global synchronization in the implementation.
5994 
5995    Level: intermediate
5996 
5997    Concepts: matrices^zeroing rows
5998 
5999 .seealso: MatZeroRows(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6000           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6001 @*/
6002 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6003 {
6004   PetscInt       numRows;
6005   const PetscInt *rows;
6006   PetscErrorCode ierr;
6007 
6008   PetscFunctionBegin;
6009   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6010   PetscValidType(mat,1);
6011   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6012   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6013   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6014   ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6015   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6016   PetscFunctionReturn(0);
6017 }
6018 
6019 /*@
6020    MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
6021    of a set of rows of a matrix. These rows must be local to the process.
6022 
6023    Collective on Mat
6024 
6025    Input Parameters:
6026 +  mat - the matrix
6027 .  numRows - the number of rows to remove
6028 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
6029 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
6030 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6031 -  b - optional vector of right hand side, that will be adjusted by provided solution
6032 
6033    Notes:
6034    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
6035    but does not release memory.  For the dense and block diagonal
6036    formats this does not alter the nonzero structure.
6037 
6038    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6039    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6040    merely zeroed.
6041 
6042    The user can set a value in the diagonal entry (or for the AIJ and
6043    row formats can optionally remove the main diagonal entry from the
6044    nonzero structure as well, by passing 0.0 as the final argument).
6045 
6046    For the parallel case, all processes that share the matrix (i.e.,
6047    those in the communicator used for matrix creation) MUST call this
6048    routine, regardless of whether any rows being zeroed are owned by
6049    them.
6050 
6051    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
6052    list only rows local to itself).
6053 
6054    The grid coordinates are across the entire grid, not just the local portion
6055 
6056    In Fortran idxm and idxn should be declared as
6057 $     MatStencil idxm(4,m)
6058    and the values inserted using
6059 $    idxm(MatStencil_i,1) = i
6060 $    idxm(MatStencil_j,1) = j
6061 $    idxm(MatStencil_k,1) = k
6062 $    idxm(MatStencil_c,1) = c
6063    etc
6064 
6065    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
6066    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
6067    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
6068    DM_BOUNDARY_PERIODIC boundary type.
6069 
6070    For indices that don't mean anything for your case (like the k index when working in 2d) or the c index when you have
6071    a single value per point) you can skip filling those indices.
6072 
6073    Level: intermediate
6074 
6075    Concepts: matrices^zeroing rows
6076 
6077 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsl(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6078           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6079 @*/
6080 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
6081 {
6082   PetscInt       dim     = mat->stencil.dim;
6083   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
6084   PetscInt       *dims   = mat->stencil.dims+1;
6085   PetscInt       *starts = mat->stencil.starts;
6086   PetscInt       *dxm    = (PetscInt*) rows;
6087   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
6088   PetscErrorCode ierr;
6089 
6090   PetscFunctionBegin;
6091   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6092   PetscValidType(mat,1);
6093   if (numRows) PetscValidIntPointer(rows,3);
6094 
6095   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
6096   for (i = 0; i < numRows; ++i) {
6097     /* Skip unused dimensions (they are ordered k, j, i, c) */
6098     for (j = 0; j < 3-sdim; ++j) dxm++;
6099     /* Local index in X dir */
6100     tmp = *dxm++ - starts[0];
6101     /* Loop over remaining dimensions */
6102     for (j = 0; j < dim-1; ++j) {
6103       /* If nonlocal, set index to be negative */
6104       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6105       /* Update local index */
6106       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6107     }
6108     /* Skip component slot if necessary */
6109     if (mat->stencil.noc) dxm++;
6110     /* Local row number */
6111     if (tmp >= 0) {
6112       jdxm[numNewRows++] = tmp;
6113     }
6114   }
6115   ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
6116   ierr = PetscFree(jdxm);CHKERRQ(ierr);
6117   PetscFunctionReturn(0);
6118 }
6119 
6120 /*@
6121    MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal)
6122    of a set of rows and columns of a matrix.
6123 
6124    Collective on Mat
6125 
6126    Input Parameters:
6127 +  mat - the matrix
6128 .  numRows - the number of rows/columns to remove
6129 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
6130 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
6131 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6132 -  b - optional vector of right hand side, that will be adjusted by provided solution
6133 
6134    Notes:
6135    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
6136    but does not release memory.  For the dense and block diagonal
6137    formats this does not alter the nonzero structure.
6138 
6139    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6140    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6141    merely zeroed.
6142 
6143    The user can set a value in the diagonal entry (or for the AIJ and
6144    row formats can optionally remove the main diagonal entry from the
6145    nonzero structure as well, by passing 0.0 as the final argument).
6146 
6147    For the parallel case, all processes that share the matrix (i.e.,
6148    those in the communicator used for matrix creation) MUST call this
6149    routine, regardless of whether any rows being zeroed are owned by
6150    them.
6151 
6152    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
6153    list only rows local to itself, but the row/column numbers are given in local numbering).
6154 
6155    The grid coordinates are across the entire grid, not just the local portion
6156 
6157    In Fortran idxm and idxn should be declared as
6158 $     MatStencil idxm(4,m)
6159    and the values inserted using
6160 $    idxm(MatStencil_i,1) = i
6161 $    idxm(MatStencil_j,1) = j
6162 $    idxm(MatStencil_k,1) = k
6163 $    idxm(MatStencil_c,1) = c
6164    etc
6165 
6166    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
6167    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
6168    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
6169    DM_BOUNDARY_PERIODIC boundary type.
6170 
6171    For indices that don't mean anything for your case (like the k index when working in 2d) or the c index when you have
6172    a single value per point) you can skip filling those indices.
6173 
6174    Level: intermediate
6175 
6176    Concepts: matrices^zeroing rows
6177 
6178 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6179           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRows()
6180 @*/
6181 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
6182 {
6183   PetscInt       dim     = mat->stencil.dim;
6184   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
6185   PetscInt       *dims   = mat->stencil.dims+1;
6186   PetscInt       *starts = mat->stencil.starts;
6187   PetscInt       *dxm    = (PetscInt*) rows;
6188   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
6189   PetscErrorCode ierr;
6190 
6191   PetscFunctionBegin;
6192   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6193   PetscValidType(mat,1);
6194   if (numRows) PetscValidIntPointer(rows,3);
6195 
6196   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
6197   for (i = 0; i < numRows; ++i) {
6198     /* Skip unused dimensions (they are ordered k, j, i, c) */
6199     for (j = 0; j < 3-sdim; ++j) dxm++;
6200     /* Local index in X dir */
6201     tmp = *dxm++ - starts[0];
6202     /* Loop over remaining dimensions */
6203     for (j = 0; j < dim-1; ++j) {
6204       /* If nonlocal, set index to be negative */
6205       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6206       /* Update local index */
6207       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6208     }
6209     /* Skip component slot if necessary */
6210     if (mat->stencil.noc) dxm++;
6211     /* Local row number */
6212     if (tmp >= 0) {
6213       jdxm[numNewRows++] = tmp;
6214     }
6215   }
6216   ierr = MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
6217   ierr = PetscFree(jdxm);CHKERRQ(ierr);
6218   PetscFunctionReturn(0);
6219 }
6220 
6221 /*@C
6222    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
6223    of a set of rows of a matrix; using local numbering of rows.
6224 
6225    Collective on Mat
6226 
6227    Input Parameters:
6228 +  mat - the matrix
6229 .  numRows - the number of rows to remove
6230 .  rows - the global row indices
6231 .  diag - value put in all diagonals of eliminated rows
6232 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6233 -  b - optional vector of right hand side, that will be adjusted by provided solution
6234 
6235    Notes:
6236    Before calling MatZeroRowsLocal(), the user must first set the
6237    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6238 
6239    For the AIJ matrix formats this removes the old nonzero structure,
6240    but does not release memory.  For the dense and block diagonal
6241    formats this does not alter the nonzero structure.
6242 
6243    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6244    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6245    merely zeroed.
6246 
6247    The user can set a value in the diagonal entry (or for the AIJ and
6248    row formats can optionally remove the main diagonal entry from the
6249    nonzero structure as well, by passing 0.0 as the final argument).
6250 
6251    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6252    owns that are to be zeroed. This saves a global synchronization in the implementation.
6253 
6254    Level: intermediate
6255 
6256    Concepts: matrices^zeroing
6257 
6258 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRows(), MatSetOption(),
6259           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6260 @*/
6261 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6262 {
6263   PetscErrorCode ierr;
6264 
6265   PetscFunctionBegin;
6266   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6267   PetscValidType(mat,1);
6268   if (numRows) PetscValidIntPointer(rows,3);
6269   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6270   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6271   MatCheckPreallocated(mat,1);
6272 
6273   if (mat->ops->zerorowslocal) {
6274     ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6275   } else {
6276     IS             is, newis;
6277     const PetscInt *newRows;
6278 
6279     if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6280     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6281     ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr);
6282     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6283     ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6284     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6285     ierr = ISDestroy(&newis);CHKERRQ(ierr);
6286     ierr = ISDestroy(&is);CHKERRQ(ierr);
6287   }
6288   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6289 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
6290   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
6291     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
6292   }
6293 #endif
6294   PetscFunctionReturn(0);
6295 }
6296 
6297 /*@
6298    MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
6299    of a set of rows of a matrix; using local numbering of rows.
6300 
6301    Collective on Mat
6302 
6303    Input Parameters:
6304 +  mat - the matrix
6305 .  is - index set of rows to remove
6306 .  diag - value put in all diagonals of eliminated rows
6307 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6308 -  b - optional vector of right hand side, that will be adjusted by provided solution
6309 
6310    Notes:
6311    Before calling MatZeroRowsLocalIS(), the user must first set the
6312    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6313 
6314    For the AIJ matrix formats this removes the old nonzero structure,
6315    but does not release memory.  For the dense and block diagonal
6316    formats this does not alter the nonzero structure.
6317 
6318    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6319    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6320    merely zeroed.
6321 
6322    The user can set a value in the diagonal entry (or for the AIJ and
6323    row formats can optionally remove the main diagonal entry from the
6324    nonzero structure as well, by passing 0.0 as the final argument).
6325 
6326    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6327    owns that are to be zeroed. This saves a global synchronization in the implementation.
6328 
6329    Level: intermediate
6330 
6331    Concepts: matrices^zeroing
6332 
6333 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6334           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6335 @*/
6336 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6337 {
6338   PetscErrorCode ierr;
6339   PetscInt       numRows;
6340   const PetscInt *rows;
6341 
6342   PetscFunctionBegin;
6343   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6344   PetscValidType(mat,1);
6345   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6346   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6347   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6348   MatCheckPreallocated(mat,1);
6349 
6350   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6351   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6352   ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6353   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6354   PetscFunctionReturn(0);
6355 }
6356 
6357 /*@
6358    MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
6359    of a set of rows and columns of a matrix; using local numbering of rows.
6360 
6361    Collective on Mat
6362 
6363    Input Parameters:
6364 +  mat - the matrix
6365 .  numRows - the number of rows to remove
6366 .  rows - the global row indices
6367 .  diag - value put in all diagonals of eliminated rows
6368 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6369 -  b - optional vector of right hand side, that will be adjusted by provided solution
6370 
6371    Notes:
6372    Before calling MatZeroRowsColumnsLocal(), the user must first set the
6373    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6374 
6375    The user can set a value in the diagonal entry (or for the AIJ and
6376    row formats can optionally remove the main diagonal entry from the
6377    nonzero structure as well, by passing 0.0 as the final argument).
6378 
6379    Level: intermediate
6380 
6381    Concepts: matrices^zeroing
6382 
6383 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6384           MatZeroRows(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6385 @*/
6386 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6387 {
6388   PetscErrorCode ierr;
6389   IS             is, newis;
6390   const PetscInt *newRows;
6391 
6392   PetscFunctionBegin;
6393   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6394   PetscValidType(mat,1);
6395   if (numRows) PetscValidIntPointer(rows,3);
6396   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6397   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6398   MatCheckPreallocated(mat,1);
6399 
6400   if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6401   ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6402   ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr);
6403   ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6404   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6405   ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6406   ierr = ISDestroy(&newis);CHKERRQ(ierr);
6407   ierr = ISDestroy(&is);CHKERRQ(ierr);
6408   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6409 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
6410   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
6411     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
6412   }
6413 #endif
6414   PetscFunctionReturn(0);
6415 }
6416 
6417 /*@
6418    MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
6419    of a set of rows and columns of a matrix; using local numbering of rows.
6420 
6421    Collective on Mat
6422 
6423    Input Parameters:
6424 +  mat - the matrix
6425 .  is - index set of rows to remove
6426 .  diag - value put in all diagonals of eliminated rows
6427 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6428 -  b - optional vector of right hand side, that will be adjusted by provided solution
6429 
6430    Notes:
6431    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
6432    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6433 
6434    The user can set a value in the diagonal entry (or for the AIJ and
6435    row formats can optionally remove the main diagonal entry from the
6436    nonzero structure as well, by passing 0.0 as the final argument).
6437 
6438    Level: intermediate
6439 
6440    Concepts: matrices^zeroing
6441 
6442 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6443           MatZeroRowsColumnsLocal(), MatZeroRows(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6444 @*/
6445 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6446 {
6447   PetscErrorCode ierr;
6448   PetscInt       numRows;
6449   const PetscInt *rows;
6450 
6451   PetscFunctionBegin;
6452   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6453   PetscValidType(mat,1);
6454   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6455   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6456   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6457   MatCheckPreallocated(mat,1);
6458 
6459   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6460   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6461   ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6462   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6463   PetscFunctionReturn(0);
6464 }
6465 
6466 /*@C
6467    MatGetSize - Returns the numbers of rows and columns in a matrix.
6468 
6469    Not Collective
6470 
6471    Input Parameter:
6472 .  mat - the matrix
6473 
6474    Output Parameters:
6475 +  m - the number of global rows
6476 -  n - the number of global columns
6477 
6478    Note: both output parameters can be NULL on input.
6479 
6480    Level: beginner
6481 
6482    Concepts: matrices^size
6483 
6484 .seealso: MatGetLocalSize()
6485 @*/
6486 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
6487 {
6488   PetscFunctionBegin;
6489   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6490   if (m) *m = mat->rmap->N;
6491   if (n) *n = mat->cmap->N;
6492   PetscFunctionReturn(0);
6493 }
6494 
6495 /*@C
6496    MatGetLocalSize - Returns the number of rows and columns in a matrix
6497    stored locally.  This information may be implementation dependent, so
6498    use with care.
6499 
6500    Not Collective
6501 
6502    Input Parameters:
6503 .  mat - the matrix
6504 
6505    Output Parameters:
6506 +  m - the number of local rows
6507 -  n - the number of local columns
6508 
6509    Note: both output parameters can be NULL on input.
6510 
6511    Level: beginner
6512 
6513    Concepts: matrices^local size
6514 
6515 .seealso: MatGetSize()
6516 @*/
6517 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
6518 {
6519   PetscFunctionBegin;
6520   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6521   if (m) PetscValidIntPointer(m,2);
6522   if (n) PetscValidIntPointer(n,3);
6523   if (m) *m = mat->rmap->n;
6524   if (n) *n = mat->cmap->n;
6525   PetscFunctionReturn(0);
6526 }
6527 
6528 /*@C
6529    MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6530    this processor. (The columns of the "diagonal block")
6531 
6532    Not Collective, unless matrix has not been allocated, then collective on Mat
6533 
6534    Input Parameters:
6535 .  mat - the matrix
6536 
6537    Output Parameters:
6538 +  m - the global index of the first local column
6539 -  n - one more than the global index of the last local column
6540 
6541    Notes:
6542     both output parameters can be NULL on input.
6543 
6544    Level: developer
6545 
6546    Concepts: matrices^column ownership
6547 
6548 .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
6549 
6550 @*/
6551 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
6552 {
6553   PetscFunctionBegin;
6554   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6555   PetscValidType(mat,1);
6556   if (m) PetscValidIntPointer(m,2);
6557   if (n) PetscValidIntPointer(n,3);
6558   MatCheckPreallocated(mat,1);
6559   if (m) *m = mat->cmap->rstart;
6560   if (n) *n = mat->cmap->rend;
6561   PetscFunctionReturn(0);
6562 }
6563 
6564 /*@C
6565    MatGetOwnershipRange - Returns the range of matrix rows owned by
6566    this processor, assuming that the matrix is laid out with the first
6567    n1 rows on the first processor, the next n2 rows on the second, etc.
6568    For certain parallel layouts this range may not be well defined.
6569 
6570    Not Collective
6571 
6572    Input Parameters:
6573 .  mat - the matrix
6574 
6575    Output Parameters:
6576 +  m - the global index of the first local row
6577 -  n - one more than the global index of the last local row
6578 
6579    Note: Both output parameters can be NULL on input.
6580 $  This function requires that the matrix be preallocated. If you have not preallocated, consider using
6581 $    PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
6582 $  and then MPI_Scan() to calculate prefix sums of the local sizes.
6583 
6584    Level: beginner
6585 
6586    Concepts: matrices^row ownership
6587 
6588 .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()
6589 
6590 @*/
6591 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6592 {
6593   PetscFunctionBegin;
6594   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6595   PetscValidType(mat,1);
6596   if (m) PetscValidIntPointer(m,2);
6597   if (n) PetscValidIntPointer(n,3);
6598   MatCheckPreallocated(mat,1);
6599   if (m) *m = mat->rmap->rstart;
6600   if (n) *n = mat->rmap->rend;
6601   PetscFunctionReturn(0);
6602 }
6603 
6604 /*@C
6605    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6606    each process
6607 
6608    Not Collective, unless matrix has not been allocated, then collective on Mat
6609 
6610    Input Parameters:
6611 .  mat - the matrix
6612 
6613    Output Parameters:
6614 .  ranges - start of each processors portion plus one more than the total length at the end
6615 
6616    Level: beginner
6617 
6618    Concepts: matrices^row ownership
6619 
6620 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
6621 
6622 @*/
6623 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6624 {
6625   PetscErrorCode ierr;
6626 
6627   PetscFunctionBegin;
6628   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6629   PetscValidType(mat,1);
6630   MatCheckPreallocated(mat,1);
6631   ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr);
6632   PetscFunctionReturn(0);
6633 }
6634 
6635 /*@C
6636    MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6637    this processor. (The columns of the "diagonal blocks" for each process)
6638 
6639    Not Collective, unless matrix has not been allocated, then collective on Mat
6640 
6641    Input Parameters:
6642 .  mat - the matrix
6643 
6644    Output Parameters:
6645 .  ranges - start of each processors portion plus one more then the total length at the end
6646 
6647    Level: beginner
6648 
6649    Concepts: matrices^column ownership
6650 
6651 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
6652 
6653 @*/
6654 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6655 {
6656   PetscErrorCode ierr;
6657 
6658   PetscFunctionBegin;
6659   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6660   PetscValidType(mat,1);
6661   MatCheckPreallocated(mat,1);
6662   ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr);
6663   PetscFunctionReturn(0);
6664 }
6665 
6666 /*@C
6667    MatGetOwnershipIS - Get row and column ownership as index sets
6668 
6669    Not Collective
6670 
6671    Input Arguments:
6672 .  A - matrix of type Elemental
6673 
6674    Output Arguments:
6675 +  rows - rows in which this process owns elements
6676 .  cols - columns in which this process owns elements
6677 
6678    Level: intermediate
6679 
6680 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL
6681 @*/
6682 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6683 {
6684   PetscErrorCode ierr,(*f)(Mat,IS*,IS*);
6685 
6686   PetscFunctionBegin;
6687   MatCheckPreallocated(A,1);
6688   ierr = PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);CHKERRQ(ierr);
6689   if (f) {
6690     ierr = (*f)(A,rows,cols);CHKERRQ(ierr);
6691   } else {   /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6692     if (rows) {ierr = ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);CHKERRQ(ierr);}
6693     if (cols) {ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);CHKERRQ(ierr);}
6694   }
6695   PetscFunctionReturn(0);
6696 }
6697 
6698 /*@C
6699    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6700    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6701    to complete the factorization.
6702 
6703    Collective on Mat
6704 
6705    Input Parameters:
6706 +  mat - the matrix
6707 .  row - row permutation
6708 .  column - column permutation
6709 -  info - structure containing
6710 $      levels - number of levels of fill.
6711 $      expected fill - as ratio of original fill.
6712 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6713                 missing diagonal entries)
6714 
6715    Output Parameters:
6716 .  fact - new matrix that has been symbolically factored
6717 
6718    Notes:
6719     See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
6720 
6721    Most users should employ the simplified KSP interface for linear solvers
6722    instead of working directly with matrix algebra routines such as this.
6723    See, e.g., KSPCreate().
6724 
6725    Level: developer
6726 
6727   Concepts: matrices^symbolic LU factorization
6728   Concepts: matrices^factorization
6729   Concepts: LU^symbolic factorization
6730 
6731 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6732           MatGetOrdering(), MatFactorInfo
6733 
6734     Note: this uses the definition of level of fill as in Y. Saad, 2003
6735 
6736     Developer Note: fortran interface is not autogenerated as the f90
6737     interface defintion cannot be generated correctly [due to MatFactorInfo]
6738 
6739    References:
6740      Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003
6741 @*/
6742 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6743 {
6744   PetscErrorCode ierr;
6745 
6746   PetscFunctionBegin;
6747   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6748   PetscValidType(mat,1);
6749   PetscValidHeaderSpecific(row,IS_CLASSID,2);
6750   PetscValidHeaderSpecific(col,IS_CLASSID,3);
6751   PetscValidPointer(info,4);
6752   PetscValidPointer(fact,5);
6753   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6754   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6755   if (!(fact)->ops->ilufactorsymbolic) {
6756     MatSolverType spackage;
6757     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
6758     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6759   }
6760   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6761   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6762   MatCheckPreallocated(mat,2);
6763 
6764   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6765   ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
6766   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6767   PetscFunctionReturn(0);
6768 }
6769 
6770 /*@C
6771    MatICCFactorSymbolic - Performs symbolic incomplete
6772    Cholesky factorization for a symmetric matrix.  Use
6773    MatCholeskyFactorNumeric() to complete the factorization.
6774 
6775    Collective on Mat
6776 
6777    Input Parameters:
6778 +  mat - the matrix
6779 .  perm - row and column permutation
6780 -  info - structure containing
6781 $      levels - number of levels of fill.
6782 $      expected fill - as ratio of original fill.
6783 
6784    Output Parameter:
6785 .  fact - the factored matrix
6786 
6787    Notes:
6788    Most users should employ the KSP interface for linear solvers
6789    instead of working directly with matrix algebra routines such as this.
6790    See, e.g., KSPCreate().
6791 
6792    Level: developer
6793 
6794   Concepts: matrices^symbolic incomplete Cholesky factorization
6795   Concepts: matrices^factorization
6796   Concepts: Cholsky^symbolic factorization
6797 
6798 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
6799 
6800     Note: this uses the definition of level of fill as in Y. Saad, 2003
6801 
6802     Developer Note: fortran interface is not autogenerated as the f90
6803     interface defintion cannot be generated correctly [due to MatFactorInfo]
6804 
6805    References:
6806      Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003
6807 @*/
6808 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6809 {
6810   PetscErrorCode ierr;
6811 
6812   PetscFunctionBegin;
6813   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6814   PetscValidType(mat,1);
6815   PetscValidHeaderSpecific(perm,IS_CLASSID,2);
6816   PetscValidPointer(info,3);
6817   PetscValidPointer(fact,4);
6818   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6819   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6820   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6821   if (!(fact)->ops->iccfactorsymbolic) {
6822     MatSolverType spackage;
6823     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
6824     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6825   }
6826   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6827   MatCheckPreallocated(mat,2);
6828 
6829   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6830   ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
6831   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6832   PetscFunctionReturn(0);
6833 }
6834 
6835 /*@C
6836    MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat
6837    points to an array of valid matrices, they may be reused to store the new
6838    submatrices.
6839 
6840    Collective on Mat
6841 
6842    Input Parameters:
6843 +  mat - the matrix
6844 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6845 .  irow, icol - index sets of rows and columns to extract
6846 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6847 
6848    Output Parameter:
6849 .  submat - the array of submatrices
6850 
6851    Notes:
6852    MatCreateSubMatrices() can extract ONLY sequential submatrices
6853    (from both sequential and parallel matrices). Use MatCreateSubMatrix()
6854    to extract a parallel submatrix.
6855 
6856    Some matrix types place restrictions on the row and column
6857    indices, such as that they be sorted or that they be equal to each other.
6858 
6859    The index sets may not have duplicate entries.
6860 
6861    When extracting submatrices from a parallel matrix, each processor can
6862    form a different submatrix by setting the rows and columns of its
6863    individual index sets according to the local submatrix desired.
6864 
6865    When finished using the submatrices, the user should destroy
6866    them with MatDestroySubMatrices().
6867 
6868    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6869    original matrix has not changed from that last call to MatCreateSubMatrices().
6870 
6871    This routine creates the matrices in submat; you should NOT create them before
6872    calling it. It also allocates the array of matrix pointers submat.
6873 
6874    For BAIJ matrices the index sets must respect the block structure, that is if they
6875    request one row/column in a block, they must request all rows/columns that are in
6876    that block. For example, if the block size is 2 you cannot request just row 0 and
6877    column 0.
6878 
6879    Fortran Note:
6880    The Fortran interface is slightly different from that given below; it
6881    requires one to pass in  as submat a Mat (integer) array of size at least n+1.
6882 
6883    Level: advanced
6884 
6885    Concepts: matrices^accessing submatrices
6886    Concepts: submatrices
6887 
6888 .seealso: MatDestroySubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6889 @*/
6890 PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6891 {
6892   PetscErrorCode ierr;
6893   PetscInt       i;
6894   PetscBool      eq;
6895 
6896   PetscFunctionBegin;
6897   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6898   PetscValidType(mat,1);
6899   if (n) {
6900     PetscValidPointer(irow,3);
6901     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6902     PetscValidPointer(icol,4);
6903     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6904   }
6905   PetscValidPointer(submat,6);
6906   if (n && scall == MAT_REUSE_MATRIX) {
6907     PetscValidPointer(*submat,6);
6908     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6909   }
6910   if (!mat->ops->createsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6911   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6912   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6913   MatCheckPreallocated(mat,1);
6914 
6915   ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6916   ierr = (*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6917   ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6918   for (i=0; i<n; i++) {
6919     (*submat)[i]->factortype = MAT_FACTOR_NONE;  /* in case in place factorization was previously done on submatrix */
6920     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6921       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6922       if (eq) {
6923         if (mat->symmetric) {
6924           ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6925         } else if (mat->hermitian) {
6926           ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6927         } else if (mat->structurally_symmetric) {
6928           ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6929         }
6930       }
6931     }
6932   }
6933   PetscFunctionReturn(0);
6934 }
6935 
6936 /*@C
6937    MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms).
6938 
6939    Collective on Mat
6940 
6941    Input Parameters:
6942 +  mat - the matrix
6943 .  n   - the number of submatrixes to be extracted
6944 .  irow, icol - index sets of rows and columns to extract
6945 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6946 
6947    Output Parameter:
6948 .  submat - the array of submatrices
6949 
6950    Level: advanced
6951 
6952    Concepts: matrices^accessing submatrices
6953    Concepts: submatrices
6954 
6955 .seealso: MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6956 @*/
6957 PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6958 {
6959   PetscErrorCode ierr;
6960   PetscInt       i;
6961   PetscBool      eq;
6962 
6963   PetscFunctionBegin;
6964   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6965   PetscValidType(mat,1);
6966   if (n) {
6967     PetscValidPointer(irow,3);
6968     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6969     PetscValidPointer(icol,4);
6970     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6971   }
6972   PetscValidPointer(submat,6);
6973   if (n && scall == MAT_REUSE_MATRIX) {
6974     PetscValidPointer(*submat,6);
6975     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6976   }
6977   if (!mat->ops->createsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6978   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6979   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6980   MatCheckPreallocated(mat,1);
6981 
6982   ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6983   ierr = (*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6984   ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6985   for (i=0; i<n; i++) {
6986     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6987       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6988       if (eq) {
6989         if (mat->symmetric) {
6990           ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6991         } else if (mat->hermitian) {
6992           ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6993         } else if (mat->structurally_symmetric) {
6994           ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6995         }
6996       }
6997     }
6998   }
6999   PetscFunctionReturn(0);
7000 }
7001 
7002 /*@C
7003    MatDestroyMatrices - Destroys an array of matrices.
7004 
7005    Collective on Mat
7006 
7007    Input Parameters:
7008 +  n - the number of local matrices
7009 -  mat - the matrices (note that this is a pointer to the array of matrices)
7010 
7011    Level: advanced
7012 
7013     Notes:
7014     Frees not only the matrices, but also the array that contains the matrices
7015            In Fortran will not free the array.
7016 
7017 .seealso: MatCreateSubMatrices() MatDestroySubMatrices()
7018 @*/
7019 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
7020 {
7021   PetscErrorCode ierr;
7022   PetscInt       i;
7023 
7024   PetscFunctionBegin;
7025   if (!*mat) PetscFunctionReturn(0);
7026   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
7027   PetscValidPointer(mat,2);
7028 
7029   for (i=0; i<n; i++) {
7030     ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr);
7031   }
7032 
7033   /* memory is allocated even if n = 0 */
7034   ierr = PetscFree(*mat);CHKERRQ(ierr);
7035   PetscFunctionReturn(0);
7036 }
7037 
7038 /*@C
7039    MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices().
7040 
7041    Collective on Mat
7042 
7043    Input Parameters:
7044 +  n - the number of local matrices
7045 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
7046                        sequence of MatCreateSubMatrices())
7047 
7048    Level: advanced
7049 
7050     Notes:
7051     Frees not only the matrices, but also the array that contains the matrices
7052            In Fortran will not free the array.
7053 
7054 .seealso: MatCreateSubMatrices()
7055 @*/
7056 PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[])
7057 {
7058   PetscErrorCode ierr;
7059   Mat            mat0;
7060 
7061   PetscFunctionBegin;
7062   if (!*mat) PetscFunctionReturn(0);
7063   /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */
7064   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
7065   PetscValidPointer(mat,2);
7066 
7067   mat0 = (*mat)[0];
7068   if (mat0 && mat0->ops->destroysubmatrices) {
7069     ierr = (mat0->ops->destroysubmatrices)(n,mat);CHKERRQ(ierr);
7070   } else {
7071     ierr = MatDestroyMatrices(n,mat);CHKERRQ(ierr);
7072   }
7073   PetscFunctionReturn(0);
7074 }
7075 
7076 /*@C
7077    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
7078 
7079    Collective on Mat
7080 
7081    Input Parameters:
7082 .  mat - the matrix
7083 
7084    Output Parameter:
7085 .  matstruct - the sequential matrix with the nonzero structure of mat
7086 
7087   Level: intermediate
7088 
7089 .seealso: MatDestroySeqNonzeroStructure(), MatCreateSubMatrices(), MatDestroyMatrices()
7090 @*/
7091 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
7092 {
7093   PetscErrorCode ierr;
7094 
7095   PetscFunctionBegin;
7096   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7097   PetscValidPointer(matstruct,2);
7098 
7099   PetscValidType(mat,1);
7100   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7101   MatCheckPreallocated(mat,1);
7102 
7103   if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
7104   ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
7105   ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr);
7106   ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
7107   PetscFunctionReturn(0);
7108 }
7109 
7110 /*@C
7111    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
7112 
7113    Collective on Mat
7114 
7115    Input Parameters:
7116 .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
7117                        sequence of MatGetSequentialNonzeroStructure())
7118 
7119    Level: advanced
7120 
7121     Notes:
7122     Frees not only the matrices, but also the array that contains the matrices
7123 
7124 .seealso: MatGetSeqNonzeroStructure()
7125 @*/
7126 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
7127 {
7128   PetscErrorCode ierr;
7129 
7130   PetscFunctionBegin;
7131   PetscValidPointer(mat,1);
7132   ierr = MatDestroy(mat);CHKERRQ(ierr);
7133   PetscFunctionReturn(0);
7134 }
7135 
7136 /*@
7137    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
7138    replaces the index sets by larger ones that represent submatrices with
7139    additional overlap.
7140 
7141    Collective on Mat
7142 
7143    Input Parameters:
7144 +  mat - the matrix
7145 .  n   - the number of index sets
7146 .  is  - the array of index sets (these index sets will changed during the call)
7147 -  ov  - the additional overlap requested
7148 
7149    Options Database:
7150 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
7151 
7152    Level: developer
7153 
7154    Concepts: overlap
7155    Concepts: ASM^computing overlap
7156 
7157 .seealso: MatCreateSubMatrices()
7158 @*/
7159 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
7160 {
7161   PetscErrorCode ierr;
7162 
7163   PetscFunctionBegin;
7164   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7165   PetscValidType(mat,1);
7166   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
7167   if (n) {
7168     PetscValidPointer(is,3);
7169     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
7170   }
7171   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7172   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7173   MatCheckPreallocated(mat,1);
7174 
7175   if (!ov) PetscFunctionReturn(0);
7176   if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7177   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7178   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
7179   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7180   PetscFunctionReturn(0);
7181 }
7182 
7183 
7184 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt);
7185 
7186 /*@
7187    MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across
7188    a sub communicator, replaces the index sets by larger ones that represent submatrices with
7189    additional overlap.
7190 
7191    Collective on Mat
7192 
7193    Input Parameters:
7194 +  mat - the matrix
7195 .  n   - the number of index sets
7196 .  is  - the array of index sets (these index sets will changed during the call)
7197 -  ov  - the additional overlap requested
7198 
7199    Options Database:
7200 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
7201 
7202    Level: developer
7203 
7204    Concepts: overlap
7205    Concepts: ASM^computing overlap
7206 
7207 .seealso: MatCreateSubMatrices()
7208 @*/
7209 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov)
7210 {
7211   PetscInt       i;
7212   PetscErrorCode ierr;
7213 
7214   PetscFunctionBegin;
7215   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7216   PetscValidType(mat,1);
7217   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
7218   if (n) {
7219     PetscValidPointer(is,3);
7220     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
7221   }
7222   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7223   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7224   MatCheckPreallocated(mat,1);
7225   if (!ov) PetscFunctionReturn(0);
7226   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7227   for(i=0; i<n; i++){
7228 	ierr =  MatIncreaseOverlapSplit_Single(mat,&is[i],ov);CHKERRQ(ierr);
7229   }
7230   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7231   PetscFunctionReturn(0);
7232 }
7233 
7234 
7235 
7236 
7237 /*@
7238    MatGetBlockSize - Returns the matrix block size.
7239 
7240    Not Collective
7241 
7242    Input Parameter:
7243 .  mat - the matrix
7244 
7245    Output Parameter:
7246 .  bs - block size
7247 
7248    Notes:
7249     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7250 
7251    If the block size has not been set yet this routine returns 1.
7252 
7253    Level: intermediate
7254 
7255    Concepts: matrices^block size
7256 
7257 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
7258 @*/
7259 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
7260 {
7261   PetscFunctionBegin;
7262   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7263   PetscValidIntPointer(bs,2);
7264   *bs = PetscAbs(mat->rmap->bs);
7265   PetscFunctionReturn(0);
7266 }
7267 
7268 /*@
7269    MatGetBlockSizes - Returns the matrix block row and column sizes.
7270 
7271    Not Collective
7272 
7273    Input Parameter:
7274 .  mat - the matrix
7275 
7276    Output Parameter:
7277 .  rbs - row block size
7278 .  cbs - column block size
7279 
7280    Notes:
7281     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7282     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7283 
7284    If a block size has not been set yet this routine returns 1.
7285 
7286    Level: intermediate
7287 
7288    Concepts: matrices^block size
7289 
7290 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes()
7291 @*/
7292 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
7293 {
7294   PetscFunctionBegin;
7295   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7296   if (rbs) PetscValidIntPointer(rbs,2);
7297   if (cbs) PetscValidIntPointer(cbs,3);
7298   if (rbs) *rbs = PetscAbs(mat->rmap->bs);
7299   if (cbs) *cbs = PetscAbs(mat->cmap->bs);
7300   PetscFunctionReturn(0);
7301 }
7302 
7303 /*@
7304    MatSetBlockSize - Sets the matrix block size.
7305 
7306    Logically Collective on Mat
7307 
7308    Input Parameters:
7309 +  mat - the matrix
7310 -  bs - block size
7311 
7312    Notes:
7313     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7314     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later.
7315 
7316     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size
7317     is compatible with the matrix local sizes.
7318 
7319    Level: intermediate
7320 
7321    Concepts: matrices^block size
7322 
7323 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes()
7324 @*/
7325 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
7326 {
7327   PetscErrorCode ierr;
7328 
7329   PetscFunctionBegin;
7330   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7331   PetscValidLogicalCollectiveInt(mat,bs,2);
7332   ierr = MatSetBlockSizes(mat,bs,bs);CHKERRQ(ierr);
7333   PetscFunctionReturn(0);
7334 }
7335 
7336 /*@
7337    MatSetVariableBlockSizes - Sets a diagonal blocks of the matrix that need not be of the same size
7338 
7339    Logically Collective on Mat
7340 
7341    Input Parameters:
7342 +  mat - the matrix
7343 .  nblocks - the number of blocks on this process
7344 -  bsizes - the block sizes
7345 
7346    Notes:
7347     Currently used by PCVPBJACOBI for SeqAIJ matrices
7348 
7349    Level: intermediate
7350 
7351    Concepts: matrices^block size
7352 
7353 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatGetVariableBlockSizes()
7354 @*/
7355 PetscErrorCode MatSetVariableBlockSizes(Mat mat,PetscInt nblocks,PetscInt *bsizes)
7356 {
7357   PetscErrorCode ierr;
7358   PetscInt       i,ncnt = 0, nlocal;
7359 
7360   PetscFunctionBegin;
7361   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7362   if (nblocks < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number of local blocks must be great than or equal to zero");
7363   ierr = MatGetLocalSize(mat,&nlocal,NULL);CHKERRQ(ierr);
7364   for (i=0; i<nblocks; i++) ncnt += bsizes[i];
7365   if (ncnt != nlocal) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Sum of local block sizes %D does not equal local size of matrix %D",ncnt,nlocal);
7366   ierr = PetscFree(mat->bsizes);CHKERRQ(ierr);
7367   mat->nblocks = nblocks;
7368   ierr = PetscMalloc1(nblocks,&mat->bsizes);CHKERRQ(ierr);
7369   ierr = PetscMemcpy(mat->bsizes,bsizes,nblocks*sizeof(PetscInt));CHKERRQ(ierr);
7370   PetscFunctionReturn(0);
7371 }
7372 
7373 /*@C
7374    MatGetVariableBlockSizes - Gets a diagonal blocks of the matrix that need not be of the same size
7375 
7376    Logically Collective on Mat
7377 
7378    Input Parameters:
7379 .  mat - the matrix
7380 
7381    Output Parameters:
7382 +  nblocks - the number of blocks on this process
7383 -  bsizes - the block sizes
7384 
7385    Notes: Currently not supported from Fortran
7386 
7387    Level: intermediate
7388 
7389    Concepts: matrices^block size
7390 
7391 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatSetVariableBlockSizes()
7392 @*/
7393 PetscErrorCode MatGetVariableBlockSizes(Mat mat,PetscInt *nblocks,const PetscInt **bsizes)
7394 {
7395   PetscFunctionBegin;
7396   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7397   *nblocks = mat->nblocks;
7398   *bsizes  = mat->bsizes;
7399   PetscFunctionReturn(0);
7400 }
7401 
7402 /*@
7403    MatSetBlockSizes - Sets the matrix block row and column sizes.
7404 
7405    Logically Collective on Mat
7406 
7407    Input Parameters:
7408 +  mat - the matrix
7409 -  rbs - row block size
7410 -  cbs - column block size
7411 
7412    Notes:
7413     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7414     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7415     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later
7416 
7417     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes
7418     are compatible with the matrix local sizes.
7419 
7420     The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs().
7421 
7422    Level: intermediate
7423 
7424    Concepts: matrices^block size
7425 
7426 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes()
7427 @*/
7428 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
7429 {
7430   PetscErrorCode ierr;
7431 
7432   PetscFunctionBegin;
7433   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7434   PetscValidLogicalCollectiveInt(mat,rbs,2);
7435   PetscValidLogicalCollectiveInt(mat,cbs,3);
7436   if (mat->ops->setblocksizes) {
7437     ierr = (*mat->ops->setblocksizes)(mat,rbs,cbs);CHKERRQ(ierr);
7438   }
7439   if (mat->rmap->refcnt) {
7440     ISLocalToGlobalMapping l2g = NULL;
7441     PetscLayout            nmap = NULL;
7442 
7443     ierr = PetscLayoutDuplicate(mat->rmap,&nmap);CHKERRQ(ierr);
7444     if (mat->rmap->mapping) {
7445       ierr = ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g);CHKERRQ(ierr);
7446     }
7447     ierr = PetscLayoutDestroy(&mat->rmap);CHKERRQ(ierr);
7448     mat->rmap = nmap;
7449     mat->rmap->mapping = l2g;
7450   }
7451   if (mat->cmap->refcnt) {
7452     ISLocalToGlobalMapping l2g = NULL;
7453     PetscLayout            nmap = NULL;
7454 
7455     ierr = PetscLayoutDuplicate(mat->cmap,&nmap);CHKERRQ(ierr);
7456     if (mat->cmap->mapping) {
7457       ierr = ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g);CHKERRQ(ierr);
7458     }
7459     ierr = PetscLayoutDestroy(&mat->cmap);CHKERRQ(ierr);
7460     mat->cmap = nmap;
7461     mat->cmap->mapping = l2g;
7462   }
7463   ierr = PetscLayoutSetBlockSize(mat->rmap,rbs);CHKERRQ(ierr);
7464   ierr = PetscLayoutSetBlockSize(mat->cmap,cbs);CHKERRQ(ierr);
7465   PetscFunctionReturn(0);
7466 }
7467 
7468 /*@
7469    MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices
7470 
7471    Logically Collective on Mat
7472 
7473    Input Parameters:
7474 +  mat - the matrix
7475 .  fromRow - matrix from which to copy row block size
7476 -  fromCol - matrix from which to copy column block size (can be same as fromRow)
7477 
7478    Level: developer
7479 
7480    Concepts: matrices^block size
7481 
7482 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes()
7483 @*/
7484 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)
7485 {
7486   PetscErrorCode ierr;
7487 
7488   PetscFunctionBegin;
7489   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7490   PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2);
7491   PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3);
7492   if (fromRow->rmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);CHKERRQ(ierr);}
7493   if (fromCol->cmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);CHKERRQ(ierr);}
7494   PetscFunctionReturn(0);
7495 }
7496 
7497 /*@
7498    MatResidual - Default routine to calculate the residual.
7499 
7500    Collective on Mat and Vec
7501 
7502    Input Parameters:
7503 +  mat - the matrix
7504 .  b   - the right-hand-side
7505 -  x   - the approximate solution
7506 
7507    Output Parameter:
7508 .  r - location to store the residual
7509 
7510    Level: developer
7511 
7512 .seealso: PCMGSetResidual()
7513 @*/
7514 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r)
7515 {
7516   PetscErrorCode ierr;
7517 
7518   PetscFunctionBegin;
7519   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7520   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
7521   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
7522   PetscValidHeaderSpecific(r,VEC_CLASSID,4);
7523   PetscValidType(mat,1);
7524   MatCheckPreallocated(mat,1);
7525   ierr  = PetscLogEventBegin(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7526   if (!mat->ops->residual) {
7527     ierr = MatMult(mat,x,r);CHKERRQ(ierr);
7528     ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr);
7529   } else {
7530     ierr  = (*mat->ops->residual)(mat,b,x,r);CHKERRQ(ierr);
7531   }
7532   ierr  = PetscLogEventEnd(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7533   PetscFunctionReturn(0);
7534 }
7535 
7536 /*@C
7537     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
7538 
7539    Collective on Mat
7540 
7541     Input Parameters:
7542 +   mat - the matrix
7543 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
7544 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
7545 -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
7546                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7547                  always used.
7548 
7549     Output Parameters:
7550 +   n - number of rows in the (possibly compressed) matrix
7551 .   ia - the row pointers; that is ia[0] = 0, ia[row] = ia[row-1] + number of elements in that row of the matrix
7552 .   ja - the column indices
7553 -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
7554            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
7555 
7556     Level: developer
7557 
7558     Notes:
7559     You CANNOT change any of the ia[] or ja[] values.
7560 
7561     Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values.
7562 
7563     Fortran Notes:
7564     In Fortran use
7565 $
7566 $      PetscInt ia(1), ja(1)
7567 $      PetscOffset iia, jja
7568 $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
7569 $      ! Access the ith and jth entries via ia(iia + i) and ja(jja + j)
7570 
7571      or
7572 $
7573 $    PetscInt, pointer :: ia(:),ja(:)
7574 $    call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
7575 $    ! Access the ith and jth entries via ia(i) and ja(j)
7576 
7577 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
7578 @*/
7579 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7580 {
7581   PetscErrorCode ierr;
7582 
7583   PetscFunctionBegin;
7584   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7585   PetscValidType(mat,1);
7586   PetscValidIntPointer(n,5);
7587   if (ia) PetscValidIntPointer(ia,6);
7588   if (ja) PetscValidIntPointer(ja,7);
7589   PetscValidIntPointer(done,8);
7590   MatCheckPreallocated(mat,1);
7591   if (!mat->ops->getrowij) *done = PETSC_FALSE;
7592   else {
7593     *done = PETSC_TRUE;
7594     ierr  = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7595     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7596     ierr  = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7597   }
7598   PetscFunctionReturn(0);
7599 }
7600 
7601 /*@C
7602     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
7603 
7604     Collective on Mat
7605 
7606     Input Parameters:
7607 +   mat - the matrix
7608 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7609 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7610                 symmetrized
7611 .   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7612                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7613                  always used.
7614 .   n - number of columns in the (possibly compressed) matrix
7615 .   ia - the column pointers; that is ia[0] = 0, ia[col] = i[col-1] + number of elements in that col of the matrix
7616 -   ja - the row indices
7617 
7618     Output Parameters:
7619 .   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
7620 
7621     Level: developer
7622 
7623 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7624 @*/
7625 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7626 {
7627   PetscErrorCode ierr;
7628 
7629   PetscFunctionBegin;
7630   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7631   PetscValidType(mat,1);
7632   PetscValidIntPointer(n,4);
7633   if (ia) PetscValidIntPointer(ia,5);
7634   if (ja) PetscValidIntPointer(ja,6);
7635   PetscValidIntPointer(done,7);
7636   MatCheckPreallocated(mat,1);
7637   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
7638   else {
7639     *done = PETSC_TRUE;
7640     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7641   }
7642   PetscFunctionReturn(0);
7643 }
7644 
7645 /*@C
7646     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
7647     MatGetRowIJ().
7648 
7649     Collective on Mat
7650 
7651     Input Parameters:
7652 +   mat - the matrix
7653 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7654 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7655                 symmetrized
7656 .   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7657                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7658                  always used.
7659 .   n - size of (possibly compressed) matrix
7660 .   ia - the row pointers
7661 -   ja - the column indices
7662 
7663     Output Parameters:
7664 .   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7665 
7666     Note:
7667     This routine zeros out n, ia, and ja. This is to prevent accidental
7668     us of the array after it has been restored. If you pass NULL, it will
7669     not zero the pointers.  Use of ia or ja after MatRestoreRowIJ() is invalid.
7670 
7671     Level: developer
7672 
7673 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7674 @*/
7675 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7676 {
7677   PetscErrorCode ierr;
7678 
7679   PetscFunctionBegin;
7680   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7681   PetscValidType(mat,1);
7682   if (ia) PetscValidIntPointer(ia,6);
7683   if (ja) PetscValidIntPointer(ja,7);
7684   PetscValidIntPointer(done,8);
7685   MatCheckPreallocated(mat,1);
7686 
7687   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
7688   else {
7689     *done = PETSC_TRUE;
7690     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7691     if (n)  *n = 0;
7692     if (ia) *ia = NULL;
7693     if (ja) *ja = NULL;
7694   }
7695   PetscFunctionReturn(0);
7696 }
7697 
7698 /*@C
7699     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
7700     MatGetColumnIJ().
7701 
7702     Collective on Mat
7703 
7704     Input Parameters:
7705 +   mat - the matrix
7706 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7707 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7708                 symmetrized
7709 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7710                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7711                  always used.
7712 
7713     Output Parameters:
7714 +   n - size of (possibly compressed) matrix
7715 .   ia - the column pointers
7716 .   ja - the row indices
7717 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7718 
7719     Level: developer
7720 
7721 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
7722 @*/
7723 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7724 {
7725   PetscErrorCode ierr;
7726 
7727   PetscFunctionBegin;
7728   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7729   PetscValidType(mat,1);
7730   if (ia) PetscValidIntPointer(ia,5);
7731   if (ja) PetscValidIntPointer(ja,6);
7732   PetscValidIntPointer(done,7);
7733   MatCheckPreallocated(mat,1);
7734 
7735   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
7736   else {
7737     *done = PETSC_TRUE;
7738     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7739     if (n)  *n = 0;
7740     if (ia) *ia = NULL;
7741     if (ja) *ja = NULL;
7742   }
7743   PetscFunctionReturn(0);
7744 }
7745 
7746 /*@C
7747     MatColoringPatch -Used inside matrix coloring routines that
7748     use MatGetRowIJ() and/or MatGetColumnIJ().
7749 
7750     Collective on Mat
7751 
7752     Input Parameters:
7753 +   mat - the matrix
7754 .   ncolors - max color value
7755 .   n   - number of entries in colorarray
7756 -   colorarray - array indicating color for each column
7757 
7758     Output Parameters:
7759 .   iscoloring - coloring generated using colorarray information
7760 
7761     Level: developer
7762 
7763 .seealso: MatGetRowIJ(), MatGetColumnIJ()
7764 
7765 @*/
7766 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7767 {
7768   PetscErrorCode ierr;
7769 
7770   PetscFunctionBegin;
7771   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7772   PetscValidType(mat,1);
7773   PetscValidIntPointer(colorarray,4);
7774   PetscValidPointer(iscoloring,5);
7775   MatCheckPreallocated(mat,1);
7776 
7777   if (!mat->ops->coloringpatch) {
7778     ierr = ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);CHKERRQ(ierr);
7779   } else {
7780     ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
7781   }
7782   PetscFunctionReturn(0);
7783 }
7784 
7785 
7786 /*@
7787    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
7788 
7789    Logically Collective on Mat
7790 
7791    Input Parameter:
7792 .  mat - the factored matrix to be reset
7793 
7794    Notes:
7795    This routine should be used only with factored matrices formed by in-place
7796    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7797    format).  This option can save memory, for example, when solving nonlinear
7798    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7799    ILU(0) preconditioner.
7800 
7801    Note that one can specify in-place ILU(0) factorization by calling
7802 .vb
7803      PCType(pc,PCILU);
7804      PCFactorSeUseInPlace(pc);
7805 .ve
7806    or by using the options -pc_type ilu -pc_factor_in_place
7807 
7808    In-place factorization ILU(0) can also be used as a local
7809    solver for the blocks within the block Jacobi or additive Schwarz
7810    methods (runtime option: -sub_pc_factor_in_place).  See Users-Manual: ch_pc
7811    for details on setting local solver options.
7812 
7813    Most users should employ the simplified KSP interface for linear solvers
7814    instead of working directly with matrix algebra routines such as this.
7815    See, e.g., KSPCreate().
7816 
7817    Level: developer
7818 
7819 .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace()
7820 
7821    Concepts: matrices^unfactored
7822 
7823 @*/
7824 PetscErrorCode MatSetUnfactored(Mat mat)
7825 {
7826   PetscErrorCode ierr;
7827 
7828   PetscFunctionBegin;
7829   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7830   PetscValidType(mat,1);
7831   MatCheckPreallocated(mat,1);
7832   mat->factortype = MAT_FACTOR_NONE;
7833   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
7834   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
7835   PetscFunctionReturn(0);
7836 }
7837 
7838 /*MC
7839     MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.
7840 
7841     Synopsis:
7842     MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7843 
7844     Not collective
7845 
7846     Input Parameter:
7847 .   x - matrix
7848 
7849     Output Parameters:
7850 +   xx_v - the Fortran90 pointer to the array
7851 -   ierr - error code
7852 
7853     Example of Usage:
7854 .vb
7855       PetscScalar, pointer xx_v(:,:)
7856       ....
7857       call MatDenseGetArrayF90(x,xx_v,ierr)
7858       a = xx_v(3)
7859       call MatDenseRestoreArrayF90(x,xx_v,ierr)
7860 .ve
7861 
7862     Level: advanced
7863 
7864 .seealso:  MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90()
7865 
7866     Concepts: matrices^accessing array
7867 
7868 M*/
7869 
7870 /*MC
7871     MatDenseRestoreArrayF90 - Restores a matrix array that has been
7872     accessed with MatDenseGetArrayF90().
7873 
7874     Synopsis:
7875     MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7876 
7877     Not collective
7878 
7879     Input Parameters:
7880 +   x - matrix
7881 -   xx_v - the Fortran90 pointer to the array
7882 
7883     Output Parameter:
7884 .   ierr - error code
7885 
7886     Example of Usage:
7887 .vb
7888        PetscScalar, pointer xx_v(:,:)
7889        ....
7890        call MatDenseGetArrayF90(x,xx_v,ierr)
7891        a = xx_v(3)
7892        call MatDenseRestoreArrayF90(x,xx_v,ierr)
7893 .ve
7894 
7895     Level: advanced
7896 
7897 .seealso:  MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90()
7898 
7899 M*/
7900 
7901 
7902 /*MC
7903     MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.
7904 
7905     Synopsis:
7906     MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7907 
7908     Not collective
7909 
7910     Input Parameter:
7911 .   x - matrix
7912 
7913     Output Parameters:
7914 +   xx_v - the Fortran90 pointer to the array
7915 -   ierr - error code
7916 
7917     Example of Usage:
7918 .vb
7919       PetscScalar, pointer xx_v(:)
7920       ....
7921       call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7922       a = xx_v(3)
7923       call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7924 .ve
7925 
7926     Level: advanced
7927 
7928 .seealso:  MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90()
7929 
7930     Concepts: matrices^accessing array
7931 
7932 M*/
7933 
7934 /*MC
7935     MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7936     accessed with MatSeqAIJGetArrayF90().
7937 
7938     Synopsis:
7939     MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7940 
7941     Not collective
7942 
7943     Input Parameters:
7944 +   x - matrix
7945 -   xx_v - the Fortran90 pointer to the array
7946 
7947     Output Parameter:
7948 .   ierr - error code
7949 
7950     Example of Usage:
7951 .vb
7952        PetscScalar, pointer xx_v(:)
7953        ....
7954        call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7955        a = xx_v(3)
7956        call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7957 .ve
7958 
7959     Level: advanced
7960 
7961 .seealso:  MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90()
7962 
7963 M*/
7964 
7965 
7966 /*@
7967     MatCreateSubMatrix - Gets a single submatrix on the same number of processors
7968                       as the original matrix.
7969 
7970     Collective on Mat
7971 
7972     Input Parameters:
7973 +   mat - the original matrix
7974 .   isrow - parallel IS containing the rows this processor should obtain
7975 .   iscol - parallel IS containing all columns you wish to keep. Each process should list the columns that will be in IT's "diagonal part" in the new matrix.
7976 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7977 
7978     Output Parameter:
7979 .   newmat - the new submatrix, of the same type as the old
7980 
7981     Level: advanced
7982 
7983     Notes:
7984     The submatrix will be able to be multiplied with vectors using the same layout as iscol.
7985 
7986     Some matrix types place restrictions on the row and column indices, such
7987     as that they be sorted or that they be equal to each other.
7988 
7989     The index sets may not have duplicate entries.
7990 
7991       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7992    the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls
7993    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7994    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
7995    you are finished using it.
7996 
7997     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7998     the input matrix.
7999 
8000     If iscol is NULL then all columns are obtained (not supported in Fortran).
8001 
8002    Example usage:
8003    Consider the following 8x8 matrix with 34 non-zero values, that is
8004    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
8005    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
8006    as follows:
8007 
8008 .vb
8009             1  2  0  |  0  3  0  |  0  4
8010     Proc0   0  5  6  |  7  0  0  |  8  0
8011             9  0 10  | 11  0  0  | 12  0
8012     -------------------------------------
8013            13  0 14  | 15 16 17  |  0  0
8014     Proc1   0 18  0  | 19 20 21  |  0  0
8015             0  0  0  | 22 23  0  | 24  0
8016     -------------------------------------
8017     Proc2  25 26 27  |  0  0 28  | 29  0
8018            30  0  0  | 31 32 33  |  0 34
8019 .ve
8020 
8021     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is
8022 
8023 .vb
8024             2  0  |  0  3  0  |  0
8025     Proc0   5  6  |  7  0  0  |  8
8026     -------------------------------
8027     Proc1  18  0  | 19 20 21  |  0
8028     -------------------------------
8029     Proc2  26 27  |  0  0 28  | 29
8030             0  0  | 31 32 33  |  0
8031 .ve
8032 
8033 
8034     Concepts: matrices^submatrices
8035 
8036 .seealso: MatCreateSubMatrices()
8037 @*/
8038 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
8039 {
8040   PetscErrorCode ierr;
8041   PetscMPIInt    size;
8042   Mat            *local;
8043   IS             iscoltmp;
8044 
8045   PetscFunctionBegin;
8046   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8047   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
8048   if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
8049   PetscValidPointer(newmat,5);
8050   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5);
8051   PetscValidType(mat,1);
8052   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8053   if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX");
8054 
8055   MatCheckPreallocated(mat,1);
8056   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
8057 
8058   if (!iscol || isrow == iscol) {
8059     PetscBool   stride;
8060     PetscMPIInt grabentirematrix = 0,grab;
8061     ierr = PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);CHKERRQ(ierr);
8062     if (stride) {
8063       PetscInt first,step,n,rstart,rend;
8064       ierr = ISStrideGetInfo(isrow,&first,&step);CHKERRQ(ierr);
8065       if (step == 1) {
8066         ierr = MatGetOwnershipRange(mat,&rstart,&rend);CHKERRQ(ierr);
8067         if (rstart == first) {
8068           ierr = ISGetLocalSize(isrow,&n);CHKERRQ(ierr);
8069           if (n == rend-rstart) {
8070             grabentirematrix = 1;
8071           }
8072         }
8073       }
8074     }
8075     ierr = MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr);
8076     if (grab) {
8077       ierr = PetscInfo(mat,"Getting entire matrix as submatrix\n");CHKERRQ(ierr);
8078       if (cll == MAT_INITIAL_MATRIX) {
8079         *newmat = mat;
8080         ierr    = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr);
8081       }
8082       PetscFunctionReturn(0);
8083     }
8084   }
8085 
8086   if (!iscol) {
8087     ierr = ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr);
8088   } else {
8089     iscoltmp = iscol;
8090   }
8091 
8092   /* if original matrix is on just one processor then use submatrix generated */
8093   if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
8094     ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
8095     goto setproperties;
8096   } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) {
8097     ierr    = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
8098     *newmat = *local;
8099     ierr    = PetscFree(local);CHKERRQ(ierr);
8100     goto setproperties;
8101   } else if (!mat->ops->createsubmatrix) {
8102     /* Create a new matrix type that implements the operation using the full matrix */
8103     ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8104     switch (cll) {
8105     case MAT_INITIAL_MATRIX:
8106       ierr = MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr);
8107       break;
8108     case MAT_REUSE_MATRIX:
8109       ierr = MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr);
8110       break;
8111     default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
8112     }
8113     ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8114     goto setproperties;
8115   }
8116 
8117   if (!mat->ops->createsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8118   ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8119   ierr = (*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr);
8120   ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8121 
8122   /* Propagate symmetry information for diagonal blocks */
8123 setproperties:
8124   if (isrow == iscoltmp) {
8125     if (mat->symmetric_set && mat->symmetric) {
8126       ierr = MatSetOption(*newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
8127     }
8128     if (mat->structurally_symmetric_set && mat->structurally_symmetric) {
8129       ierr = MatSetOption(*newmat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
8130     }
8131     if (mat->hermitian_set && mat->hermitian) {
8132       ierr = MatSetOption(*newmat,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
8133     }
8134     if (mat->spd_set && mat->spd) {
8135       ierr = MatSetOption(*newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr);
8136     }
8137   }
8138 
8139   if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
8140   if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);}
8141   PetscFunctionReturn(0);
8142 }
8143 
8144 /*@
8145    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
8146    used during the assembly process to store values that belong to
8147    other processors.
8148 
8149    Not Collective
8150 
8151    Input Parameters:
8152 +  mat   - the matrix
8153 .  size  - the initial size of the stash.
8154 -  bsize - the initial size of the block-stash(if used).
8155 
8156    Options Database Keys:
8157 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
8158 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
8159 
8160    Level: intermediate
8161 
8162    Notes:
8163      The block-stash is used for values set with MatSetValuesBlocked() while
8164      the stash is used for values set with MatSetValues()
8165 
8166      Run with the option -info and look for output of the form
8167      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
8168      to determine the appropriate value, MM, to use for size and
8169      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
8170      to determine the value, BMM to use for bsize
8171 
8172    Concepts: stash^setting matrix size
8173    Concepts: matrices^stash
8174 
8175 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
8176 
8177 @*/
8178 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
8179 {
8180   PetscErrorCode ierr;
8181 
8182   PetscFunctionBegin;
8183   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8184   PetscValidType(mat,1);
8185   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
8186   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
8187   PetscFunctionReturn(0);
8188 }
8189 
8190 /*@
8191    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
8192      the matrix
8193 
8194    Neighbor-wise Collective on Mat
8195 
8196    Input Parameters:
8197 +  mat   - the matrix
8198 .  x,y - the vectors
8199 -  w - where the result is stored
8200 
8201    Level: intermediate
8202 
8203    Notes:
8204     w may be the same vector as y.
8205 
8206     This allows one to use either the restriction or interpolation (its transpose)
8207     matrix to do the interpolation
8208 
8209     Concepts: interpolation
8210 
8211 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
8212 
8213 @*/
8214 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
8215 {
8216   PetscErrorCode ierr;
8217   PetscInt       M,N,Ny;
8218 
8219   PetscFunctionBegin;
8220   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8221   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8222   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8223   PetscValidHeaderSpecific(w,VEC_CLASSID,4);
8224   PetscValidType(A,1);
8225   MatCheckPreallocated(A,1);
8226   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8227   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8228   if (M == Ny) {
8229     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
8230   } else {
8231     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
8232   }
8233   PetscFunctionReturn(0);
8234 }
8235 
8236 /*@
8237    MatInterpolate - y = A*x or A'*x depending on the shape of
8238      the matrix
8239 
8240    Neighbor-wise Collective on Mat
8241 
8242    Input Parameters:
8243 +  mat   - the matrix
8244 -  x,y - the vectors
8245 
8246    Level: intermediate
8247 
8248    Notes:
8249     This allows one to use either the restriction or interpolation (its transpose)
8250     matrix to do the interpolation
8251 
8252    Concepts: matrices^interpolation
8253 
8254 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
8255 
8256 @*/
8257 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
8258 {
8259   PetscErrorCode ierr;
8260   PetscInt       M,N,Ny;
8261 
8262   PetscFunctionBegin;
8263   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8264   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8265   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8266   PetscValidType(A,1);
8267   MatCheckPreallocated(A,1);
8268   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8269   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8270   if (M == Ny) {
8271     ierr = MatMult(A,x,y);CHKERRQ(ierr);
8272   } else {
8273     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
8274   }
8275   PetscFunctionReturn(0);
8276 }
8277 
8278 /*@
8279    MatRestrict - y = A*x or A'*x
8280 
8281    Neighbor-wise Collective on Mat
8282 
8283    Input Parameters:
8284 +  mat   - the matrix
8285 -  x,y - the vectors
8286 
8287    Level: intermediate
8288 
8289    Notes:
8290     This allows one to use either the restriction or interpolation (its transpose)
8291     matrix to do the restriction
8292 
8293    Concepts: matrices^restriction
8294 
8295 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
8296 
8297 @*/
8298 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
8299 {
8300   PetscErrorCode ierr;
8301   PetscInt       M,N,Ny;
8302 
8303   PetscFunctionBegin;
8304   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8305   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8306   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8307   PetscValidType(A,1);
8308   MatCheckPreallocated(A,1);
8309 
8310   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8311   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8312   if (M == Ny) {
8313     ierr = MatMult(A,x,y);CHKERRQ(ierr);
8314   } else {
8315     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
8316   }
8317   PetscFunctionReturn(0);
8318 }
8319 
8320 /*@
8321    MatGetNullSpace - retrieves the null space of a matrix.
8322 
8323    Logically Collective on Mat and MatNullSpace
8324 
8325    Input Parameters:
8326 +  mat - the matrix
8327 -  nullsp - the null space object
8328 
8329    Level: developer
8330 
8331    Concepts: null space^attaching to matrix
8332 
8333 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace()
8334 @*/
8335 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
8336 {
8337   PetscFunctionBegin;
8338   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8339   PetscValidPointer(nullsp,2);
8340   *nullsp = (mat->symmetric_set && mat->symmetric && !mat->nullsp) ? mat->transnullsp : mat->nullsp;
8341   PetscFunctionReturn(0);
8342 }
8343 
8344 /*@
8345    MatSetNullSpace - attaches a null space to a matrix.
8346 
8347    Logically Collective on Mat and MatNullSpace
8348 
8349    Input Parameters:
8350 +  mat - the matrix
8351 -  nullsp - the null space object
8352 
8353    Level: advanced
8354 
8355    Notes:
8356       This null space is used by the linear solvers. Overwrites any previous null space that may have been attached
8357 
8358       For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should
8359       call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense.
8360 
8361       You can remove the null space by calling this routine with an nullsp of NULL
8362 
8363 
8364       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8365    the domain of a matrix A (from R^n to R^m (m rows, n columns) R^n = the direct sum of the null space of A, n(A), + the range of A^T, R(A^T).
8366    Similarly R^m = direct sum n(A^T) + R(A).  Hence the linear system A x = b has a solution only if b in R(A) (or correspondingly b is orthogonal to
8367    n(A^T)) and if x is a solution then x + alpha n(A) is a solution for any alpha. The minimum norm solution is orthogonal to n(A). For problems without a solution
8368    the solution that minimizes the norm of the residual (the least squares solution) can be obtained by solving A x = \hat{b} where \hat{b} is b orthogonalized to the n(A^T).
8369 
8370       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8371 
8372     If the matrix is known to be symmetric because it is an SBAIJ matrix or one as called MatSetOption(mat,MAT_SYMMETRIC or MAT_SYMMETRIC_ETERNAL,PETSC_TRUE); this
8373     routine also automatically calls MatSetTransposeNullSpace().
8374 
8375    Concepts: null space^attaching to matrix
8376 
8377 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8378 @*/
8379 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp)
8380 {
8381   PetscErrorCode ierr;
8382 
8383   PetscFunctionBegin;
8384   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8385   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8386   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8387   ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr);
8388   mat->nullsp = nullsp;
8389   if (mat->symmetric_set && mat->symmetric) {
8390     ierr = MatSetTransposeNullSpace(mat,nullsp);CHKERRQ(ierr);
8391   }
8392   PetscFunctionReturn(0);
8393 }
8394 
8395 /*@
8396    MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix.
8397 
8398    Logically Collective on Mat and MatNullSpace
8399 
8400    Input Parameters:
8401 +  mat - the matrix
8402 -  nullsp - the null space object
8403 
8404    Level: developer
8405 
8406    Concepts: null space^attaching to matrix
8407 
8408 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace()
8409 @*/
8410 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp)
8411 {
8412   PetscFunctionBegin;
8413   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8414   PetscValidType(mat,1);
8415   PetscValidPointer(nullsp,2);
8416   *nullsp = (mat->symmetric_set && mat->symmetric && !mat->transnullsp) ? mat->nullsp : mat->transnullsp;
8417   PetscFunctionReturn(0);
8418 }
8419 
8420 /*@
8421    MatSetTransposeNullSpace - attaches a null space to a matrix.
8422 
8423    Logically Collective on Mat and MatNullSpace
8424 
8425    Input Parameters:
8426 +  mat - the matrix
8427 -  nullsp - the null space object
8428 
8429    Level: advanced
8430 
8431    Notes:
8432       For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) this allows the linear system to be solved in a least squares sense.
8433       You must also call MatSetNullSpace()
8434 
8435 
8436       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8437    the domain of a matrix A (from R^n to R^m (m rows, n columns) R^n = the direct sum of the null space of A, n(A), + the range of A^T, R(A^T).
8438    Similarly R^m = direct sum n(A^T) + R(A).  Hence the linear system A x = b has a solution only if b in R(A) (or correspondingly b is orthogonal to
8439    n(A^T)) and if x is a solution then x + alpha n(A) is a solution for any alpha. The minimum norm solution is orthogonal to n(A). For problems without a solution
8440    the solution that minimizes the norm of the residual (the least squares solution) can be obtained by solving A x = \hat{b} where \hat{b} is b orthogonalized to the n(A^T).
8441 
8442       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8443 
8444    Concepts: null space^attaching to matrix
8445 
8446 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8447 @*/
8448 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp)
8449 {
8450   PetscErrorCode ierr;
8451 
8452   PetscFunctionBegin;
8453   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8454   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8455   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8456   ierr = MatNullSpaceDestroy(&mat->transnullsp);CHKERRQ(ierr);
8457   mat->transnullsp = nullsp;
8458   PetscFunctionReturn(0);
8459 }
8460 
8461 /*@
8462    MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions
8463         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.
8464 
8465    Logically Collective on Mat and MatNullSpace
8466 
8467    Input Parameters:
8468 +  mat - the matrix
8469 -  nullsp - the null space object
8470 
8471    Level: advanced
8472 
8473    Notes:
8474       Overwrites any previous near null space that may have been attached
8475 
8476       You can remove the null space by calling this routine with an nullsp of NULL
8477 
8478    Concepts: null space^attaching to matrix
8479 
8480 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace()
8481 @*/
8482 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
8483 {
8484   PetscErrorCode ierr;
8485 
8486   PetscFunctionBegin;
8487   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8488   PetscValidType(mat,1);
8489   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8490   MatCheckPreallocated(mat,1);
8491   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8492   ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr);
8493   mat->nearnullsp = nullsp;
8494   PetscFunctionReturn(0);
8495 }
8496 
8497 /*@
8498    MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()
8499 
8500    Not Collective
8501 
8502    Input Parameters:
8503 .  mat - the matrix
8504 
8505    Output Parameters:
8506 .  nullsp - the null space object, NULL if not set
8507 
8508    Level: developer
8509 
8510    Concepts: null space^attaching to matrix
8511 
8512 .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate()
8513 @*/
8514 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
8515 {
8516   PetscFunctionBegin;
8517   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8518   PetscValidType(mat,1);
8519   PetscValidPointer(nullsp,2);
8520   MatCheckPreallocated(mat,1);
8521   *nullsp = mat->nearnullsp;
8522   PetscFunctionReturn(0);
8523 }
8524 
8525 /*@C
8526    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
8527 
8528    Collective on Mat
8529 
8530    Input Parameters:
8531 +  mat - the matrix
8532 .  row - row/column permutation
8533 .  fill - expected fill factor >= 1.0
8534 -  level - level of fill, for ICC(k)
8535 
8536    Notes:
8537    Probably really in-place only when level of fill is zero, otherwise allocates
8538    new space to store factored matrix and deletes previous memory.
8539 
8540    Most users should employ the simplified KSP interface for linear solvers
8541    instead of working directly with matrix algebra routines such as this.
8542    See, e.g., KSPCreate().
8543 
8544    Level: developer
8545 
8546    Concepts: matrices^incomplete Cholesky factorization
8547    Concepts: Cholesky factorization
8548 
8549 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
8550 
8551     Developer Note: fortran interface is not autogenerated as the f90
8552     interface defintion cannot be generated correctly [due to MatFactorInfo]
8553 
8554 @*/
8555 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
8556 {
8557   PetscErrorCode ierr;
8558 
8559   PetscFunctionBegin;
8560   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8561   PetscValidType(mat,1);
8562   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
8563   PetscValidPointer(info,3);
8564   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
8565   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8566   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8567   if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8568   MatCheckPreallocated(mat,1);
8569   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
8570   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8571   PetscFunctionReturn(0);
8572 }
8573 
8574 /*@
8575    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
8576          ghosted ones.
8577 
8578    Not Collective
8579 
8580    Input Parameters:
8581 +  mat - the matrix
8582 -  diag = the diagonal values, including ghost ones
8583 
8584    Level: developer
8585 
8586    Notes:
8587     Works only for MPIAIJ and MPIBAIJ matrices
8588 
8589 .seealso: MatDiagonalScale()
8590 @*/
8591 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
8592 {
8593   PetscErrorCode ierr;
8594   PetscMPIInt    size;
8595 
8596   PetscFunctionBegin;
8597   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8598   PetscValidHeaderSpecific(diag,VEC_CLASSID,2);
8599   PetscValidType(mat,1);
8600 
8601   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8602   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8603   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
8604   if (size == 1) {
8605     PetscInt n,m;
8606     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
8607     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
8608     if (m == n) {
8609       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
8610     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
8611   } else {
8612     ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr);
8613   }
8614   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8615   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8616   PetscFunctionReturn(0);
8617 }
8618 
8619 /*@
8620    MatGetInertia - Gets the inertia from a factored matrix
8621 
8622    Collective on Mat
8623 
8624    Input Parameter:
8625 .  mat - the matrix
8626 
8627    Output Parameters:
8628 +   nneg - number of negative eigenvalues
8629 .   nzero - number of zero eigenvalues
8630 -   npos - number of positive eigenvalues
8631 
8632    Level: advanced
8633 
8634    Notes:
8635     Matrix must have been factored by MatCholeskyFactor()
8636 
8637 
8638 @*/
8639 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
8640 {
8641   PetscErrorCode ierr;
8642 
8643   PetscFunctionBegin;
8644   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8645   PetscValidType(mat,1);
8646   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8647   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
8648   if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8649   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
8650   PetscFunctionReturn(0);
8651 }
8652 
8653 /* ----------------------------------------------------------------*/
8654 /*@C
8655    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
8656 
8657    Neighbor-wise Collective on Mat and Vecs
8658 
8659    Input Parameters:
8660 +  mat - the factored matrix
8661 -  b - the right-hand-side vectors
8662 
8663    Output Parameter:
8664 .  x - the result vectors
8665 
8666    Notes:
8667    The vectors b and x cannot be the same.  I.e., one cannot
8668    call MatSolves(A,x,x).
8669 
8670    Notes:
8671    Most users should employ the simplified KSP interface for linear solvers
8672    instead of working directly with matrix algebra routines such as this.
8673    See, e.g., KSPCreate().
8674 
8675    Level: developer
8676 
8677    Concepts: matrices^triangular solves
8678 
8679 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
8680 @*/
8681 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
8682 {
8683   PetscErrorCode ierr;
8684 
8685   PetscFunctionBegin;
8686   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8687   PetscValidType(mat,1);
8688   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
8689   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8690   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
8691 
8692   if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8693   MatCheckPreallocated(mat,1);
8694   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8695   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
8696   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8697   PetscFunctionReturn(0);
8698 }
8699 
8700 /*@
8701    MatIsSymmetric - Test whether a matrix is symmetric
8702 
8703    Collective on Mat
8704 
8705    Input Parameter:
8706 +  A - the matrix to test
8707 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
8708 
8709    Output Parameters:
8710 .  flg - the result
8711 
8712    Notes:
8713     For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
8714 
8715    Level: intermediate
8716 
8717    Concepts: matrix^symmetry
8718 
8719 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
8720 @*/
8721 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
8722 {
8723   PetscErrorCode ierr;
8724 
8725   PetscFunctionBegin;
8726   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8727   PetscValidPointer(flg,2);
8728 
8729   if (!A->symmetric_set) {
8730     if (!A->ops->issymmetric) {
8731       MatType mattype;
8732       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8733       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8734     }
8735     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8736     if (!tol) {
8737       A->symmetric_set = PETSC_TRUE;
8738       A->symmetric     = *flg;
8739       if (A->symmetric) {
8740         A->structurally_symmetric_set = PETSC_TRUE;
8741         A->structurally_symmetric     = PETSC_TRUE;
8742       }
8743     }
8744   } else if (A->symmetric) {
8745     *flg = PETSC_TRUE;
8746   } else if (!tol) {
8747     *flg = PETSC_FALSE;
8748   } else {
8749     if (!A->ops->issymmetric) {
8750       MatType mattype;
8751       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8752       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8753     }
8754     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8755   }
8756   PetscFunctionReturn(0);
8757 }
8758 
8759 /*@
8760    MatIsHermitian - Test whether a matrix is Hermitian
8761 
8762    Collective on Mat
8763 
8764    Input Parameter:
8765 +  A - the matrix to test
8766 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
8767 
8768    Output Parameters:
8769 .  flg - the result
8770 
8771    Level: intermediate
8772 
8773    Concepts: matrix^symmetry
8774 
8775 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
8776           MatIsSymmetricKnown(), MatIsSymmetric()
8777 @*/
8778 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
8779 {
8780   PetscErrorCode ierr;
8781 
8782   PetscFunctionBegin;
8783   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8784   PetscValidPointer(flg,2);
8785 
8786   if (!A->hermitian_set) {
8787     if (!A->ops->ishermitian) {
8788       MatType mattype;
8789       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8790       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8791     }
8792     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8793     if (!tol) {
8794       A->hermitian_set = PETSC_TRUE;
8795       A->hermitian     = *flg;
8796       if (A->hermitian) {
8797         A->structurally_symmetric_set = PETSC_TRUE;
8798         A->structurally_symmetric     = PETSC_TRUE;
8799       }
8800     }
8801   } else if (A->hermitian) {
8802     *flg = PETSC_TRUE;
8803   } else if (!tol) {
8804     *flg = PETSC_FALSE;
8805   } else {
8806     if (!A->ops->ishermitian) {
8807       MatType mattype;
8808       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8809       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8810     }
8811     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8812   }
8813   PetscFunctionReturn(0);
8814 }
8815 
8816 /*@
8817    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
8818 
8819    Not Collective
8820 
8821    Input Parameter:
8822 .  A - the matrix to check
8823 
8824    Output Parameters:
8825 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
8826 -  flg - the result
8827 
8828    Level: advanced
8829 
8830    Concepts: matrix^symmetry
8831 
8832    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
8833          if you want it explicitly checked
8834 
8835 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8836 @*/
8837 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8838 {
8839   PetscFunctionBegin;
8840   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8841   PetscValidPointer(set,2);
8842   PetscValidPointer(flg,3);
8843   if (A->symmetric_set) {
8844     *set = PETSC_TRUE;
8845     *flg = A->symmetric;
8846   } else {
8847     *set = PETSC_FALSE;
8848   }
8849   PetscFunctionReturn(0);
8850 }
8851 
8852 /*@
8853    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
8854 
8855    Not Collective
8856 
8857    Input Parameter:
8858 .  A - the matrix to check
8859 
8860    Output Parameters:
8861 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8862 -  flg - the result
8863 
8864    Level: advanced
8865 
8866    Concepts: matrix^symmetry
8867 
8868    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8869          if you want it explicitly checked
8870 
8871 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8872 @*/
8873 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8874 {
8875   PetscFunctionBegin;
8876   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8877   PetscValidPointer(set,2);
8878   PetscValidPointer(flg,3);
8879   if (A->hermitian_set) {
8880     *set = PETSC_TRUE;
8881     *flg = A->hermitian;
8882   } else {
8883     *set = PETSC_FALSE;
8884   }
8885   PetscFunctionReturn(0);
8886 }
8887 
8888 /*@
8889    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
8890 
8891    Collective on Mat
8892 
8893    Input Parameter:
8894 .  A - the matrix to test
8895 
8896    Output Parameters:
8897 .  flg - the result
8898 
8899    Level: intermediate
8900 
8901    Concepts: matrix^symmetry
8902 
8903 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8904 @*/
8905 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
8906 {
8907   PetscErrorCode ierr;
8908 
8909   PetscFunctionBegin;
8910   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8911   PetscValidPointer(flg,2);
8912   if (!A->structurally_symmetric_set) {
8913     if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8914     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
8915 
8916     A->structurally_symmetric_set = PETSC_TRUE;
8917   }
8918   *flg = A->structurally_symmetric;
8919   PetscFunctionReturn(0);
8920 }
8921 
8922 /*@
8923    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8924        to be communicated to other processors during the MatAssemblyBegin/End() process
8925 
8926     Not collective
8927 
8928    Input Parameter:
8929 .   vec - the vector
8930 
8931    Output Parameters:
8932 +   nstash   - the size of the stash
8933 .   reallocs - the number of additional mallocs incurred.
8934 .   bnstash   - the size of the block stash
8935 -   breallocs - the number of additional mallocs incurred.in the block stash
8936 
8937    Level: advanced
8938 
8939 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
8940 
8941 @*/
8942 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8943 {
8944   PetscErrorCode ierr;
8945 
8946   PetscFunctionBegin;
8947   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
8948   ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
8949   PetscFunctionReturn(0);
8950 }
8951 
8952 /*@C
8953    MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same
8954      parallel layout
8955 
8956    Collective on Mat
8957 
8958    Input Parameter:
8959 .  mat - the matrix
8960 
8961    Output Parameter:
8962 +   right - (optional) vector that the matrix can be multiplied against
8963 -   left - (optional) vector that the matrix vector product can be stored in
8964 
8965    Notes:
8966     The blocksize of the returned vectors is determined by the row and column block sizes set with MatSetBlockSizes() or the single blocksize (same for both) set by MatSetBlockSize().
8967 
8968   Notes:
8969     These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed
8970 
8971   Level: advanced
8972 
8973 .seealso: MatCreate(), VecDestroy()
8974 @*/
8975 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left)
8976 {
8977   PetscErrorCode ierr;
8978 
8979   PetscFunctionBegin;
8980   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8981   PetscValidType(mat,1);
8982   if (mat->ops->getvecs) {
8983     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
8984   } else {
8985     PetscInt rbs,cbs;
8986     ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr);
8987     if (right) {
8988       if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup");
8989       ierr = VecCreate(PetscObjectComm((PetscObject)mat),right);CHKERRQ(ierr);
8990       ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8991       ierr = VecSetBlockSize(*right,cbs);CHKERRQ(ierr);
8992       ierr = VecSetType(*right,mat->defaultvectype);CHKERRQ(ierr);
8993       ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr);
8994     }
8995     if (left) {
8996       if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup");
8997       ierr = VecCreate(PetscObjectComm((PetscObject)mat),left);CHKERRQ(ierr);
8998       ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8999       ierr = VecSetBlockSize(*left,rbs);CHKERRQ(ierr);
9000       ierr = VecSetType(*left,mat->defaultvectype);CHKERRQ(ierr);
9001       ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr);
9002     }
9003   }
9004   PetscFunctionReturn(0);
9005 }
9006 
9007 /*@C
9008    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
9009      with default values.
9010 
9011    Not Collective
9012 
9013    Input Parameters:
9014 .    info - the MatFactorInfo data structure
9015 
9016 
9017    Notes:
9018     The solvers are generally used through the KSP and PC objects, for example
9019           PCLU, PCILU, PCCHOLESKY, PCICC
9020 
9021    Level: developer
9022 
9023 .seealso: MatFactorInfo
9024 
9025     Developer Note: fortran interface is not autogenerated as the f90
9026     interface defintion cannot be generated correctly [due to MatFactorInfo]
9027 
9028 @*/
9029 
9030 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
9031 {
9032   PetscErrorCode ierr;
9033 
9034   PetscFunctionBegin;
9035   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
9036   PetscFunctionReturn(0);
9037 }
9038 
9039 /*@
9040    MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed
9041 
9042    Collective on Mat
9043 
9044    Input Parameters:
9045 +  mat - the factored matrix
9046 -  is - the index set defining the Schur indices (0-based)
9047 
9048    Notes:
9049     Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system.
9050 
9051    You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call.
9052 
9053    Level: developer
9054 
9055    Concepts:
9056 
9057 .seealso: MatGetFactor(), MatFactorGetSchurComplement(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSolveSchurComplement(),
9058           MatFactorSolveSchurComplementTranspose(), MatFactorSolveSchurComplement()
9059 
9060 @*/
9061 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is)
9062 {
9063   PetscErrorCode ierr,(*f)(Mat,IS);
9064 
9065   PetscFunctionBegin;
9066   PetscValidType(mat,1);
9067   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9068   PetscValidType(is,2);
9069   PetscValidHeaderSpecific(is,IS_CLASSID,2);
9070   PetscCheckSameComm(mat,1,is,2);
9071   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
9072   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);CHKERRQ(ierr);
9073   if (!f) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"The selected MatSolverType does not support Schur complement computation. You should use MATSOLVERMUMPS or MATSOLVERMKL_PARDISO");
9074   if (mat->schur) {
9075     ierr = MatDestroy(&mat->schur);CHKERRQ(ierr);
9076   }
9077   ierr = (*f)(mat,is);CHKERRQ(ierr);
9078   if (!mat->schur) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created");
9079   ierr = MatFactorSetUpInPlaceSchur_Private(mat);CHKERRQ(ierr);
9080   PetscFunctionReturn(0);
9081 }
9082 
9083 /*@
9084   MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step
9085 
9086    Logically Collective on Mat
9087 
9088    Input Parameters:
9089 +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
9090 .  S - location where to return the Schur complement, can be NULL
9091 -  status - the status of the Schur complement matrix, can be NULL
9092 
9093    Notes:
9094    You must call MatFactorSetSchurIS() before calling this routine.
9095 
9096    The routine provides a copy of the Schur matrix stored within the solver data structures.
9097    The caller must destroy the object when it is no longer needed.
9098    If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse.
9099 
9100    Use MatFactorGetSchurComplement() to get access to the Schur complement matrix inside the factored matrix instead of making a copy of it (which this function does)
9101 
9102    Developer Notes:
9103     The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc
9104    matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix.
9105 
9106    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
9107 
9108    Level: advanced
9109 
9110    References:
9111 
9112 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorSchurStatus
9113 @*/
9114 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
9115 {
9116   PetscErrorCode ierr;
9117 
9118   PetscFunctionBegin;
9119   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9120   if (S) PetscValidPointer(S,2);
9121   if (status) PetscValidPointer(status,3);
9122   if (S) {
9123     PetscErrorCode (*f)(Mat,Mat*);
9124 
9125     ierr = PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f);CHKERRQ(ierr);
9126     if (f) {
9127       ierr = (*f)(F,S);CHKERRQ(ierr);
9128     } else {
9129       ierr = MatDuplicate(F->schur,MAT_COPY_VALUES,S);CHKERRQ(ierr);
9130     }
9131   }
9132   if (status) *status = F->schur_status;
9133   PetscFunctionReturn(0);
9134 }
9135 
9136 /*@
9137   MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix
9138 
9139    Logically Collective on Mat
9140 
9141    Input Parameters:
9142 +  F - the factored matrix obtained by calling MatGetFactor()
9143 .  *S - location where to return the Schur complement, can be NULL
9144 -  status - the status of the Schur complement matrix, can be NULL
9145 
9146    Notes:
9147    You must call MatFactorSetSchurIS() before calling this routine.
9148 
9149    Schur complement mode is currently implemented for sequential matrices.
9150    The routine returns a the Schur Complement stored within the data strutures of the solver.
9151    If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement.
9152    The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed.
9153 
9154    Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix
9155 
9156    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
9157 
9158    Level: advanced
9159 
9160    References:
9161 
9162 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
9163 @*/
9164 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
9165 {
9166   PetscFunctionBegin;
9167   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9168   if (S) PetscValidPointer(S,2);
9169   if (status) PetscValidPointer(status,3);
9170   if (S) *S = F->schur;
9171   if (status) *status = F->schur_status;
9172   PetscFunctionReturn(0);
9173 }
9174 
9175 /*@
9176   MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement
9177 
9178    Logically Collective on Mat
9179 
9180    Input Parameters:
9181 +  F - the factored matrix obtained by calling MatGetFactor()
9182 .  *S - location where the Schur complement is stored
9183 -  status - the status of the Schur complement matrix (see MatFactorSchurStatus)
9184 
9185    Notes:
9186 
9187    Level: advanced
9188 
9189    References:
9190 
9191 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
9192 @*/
9193 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status)
9194 {
9195   PetscErrorCode ierr;
9196 
9197   PetscFunctionBegin;
9198   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9199   if (S) {
9200     PetscValidHeaderSpecific(*S,MAT_CLASSID,2);
9201     *S = NULL;
9202   }
9203   F->schur_status = status;
9204   ierr = MatFactorUpdateSchurStatus_Private(F);CHKERRQ(ierr);
9205   PetscFunctionReturn(0);
9206 }
9207 
9208 /*@
9209   MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step
9210 
9211    Logically Collective on Mat
9212 
9213    Input Parameters:
9214 +  F - the factored matrix obtained by calling MatGetFactor()
9215 .  rhs - location where the right hand side of the Schur complement system is stored
9216 -  sol - location where the solution of the Schur complement system has to be returned
9217 
9218    Notes:
9219    The sizes of the vectors should match the size of the Schur complement
9220 
9221    Must be called after MatFactorSetSchurIS()
9222 
9223    Level: advanced
9224 
9225    References:
9226 
9227 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplement()
9228 @*/
9229 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol)
9230 {
9231   PetscErrorCode ierr;
9232 
9233   PetscFunctionBegin;
9234   PetscValidType(F,1);
9235   PetscValidType(rhs,2);
9236   PetscValidType(sol,3);
9237   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9238   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
9239   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
9240   PetscCheckSameComm(F,1,rhs,2);
9241   PetscCheckSameComm(F,1,sol,3);
9242   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9243   switch (F->schur_status) {
9244   case MAT_FACTOR_SCHUR_FACTORED:
9245     ierr = MatSolveTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
9246     break;
9247   case MAT_FACTOR_SCHUR_INVERTED:
9248     ierr = MatMultTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
9249     break;
9250   default:
9251     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9252     break;
9253   }
9254   PetscFunctionReturn(0);
9255 }
9256 
9257 /*@
9258   MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step
9259 
9260    Logically Collective on Mat
9261 
9262    Input Parameters:
9263 +  F - the factored matrix obtained by calling MatGetFactor()
9264 .  rhs - location where the right hand side of the Schur complement system is stored
9265 -  sol - location where the solution of the Schur complement system has to be returned
9266 
9267    Notes:
9268    The sizes of the vectors should match the size of the Schur complement
9269 
9270    Must be called after MatFactorSetSchurIS()
9271 
9272    Level: advanced
9273 
9274    References:
9275 
9276 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplementTranspose()
9277 @*/
9278 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol)
9279 {
9280   PetscErrorCode ierr;
9281 
9282   PetscFunctionBegin;
9283   PetscValidType(F,1);
9284   PetscValidType(rhs,2);
9285   PetscValidType(sol,3);
9286   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9287   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
9288   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
9289   PetscCheckSameComm(F,1,rhs,2);
9290   PetscCheckSameComm(F,1,sol,3);
9291   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9292   switch (F->schur_status) {
9293   case MAT_FACTOR_SCHUR_FACTORED:
9294     ierr = MatSolve(F->schur,rhs,sol);CHKERRQ(ierr);
9295     break;
9296   case MAT_FACTOR_SCHUR_INVERTED:
9297     ierr = MatMult(F->schur,rhs,sol);CHKERRQ(ierr);
9298     break;
9299   default:
9300     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9301     break;
9302   }
9303   PetscFunctionReturn(0);
9304 }
9305 
9306 /*@
9307   MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step
9308 
9309    Logically Collective on Mat
9310 
9311    Input Parameters:
9312 +  F - the factored matrix obtained by calling MatGetFactor()
9313 
9314    Notes:
9315     Must be called after MatFactorSetSchurIS().
9316 
9317    Call MatFactorGetSchurComplement() or  MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it.
9318 
9319    Level: advanced
9320 
9321    References:
9322 
9323 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorCreateSchurComplement()
9324 @*/
9325 PetscErrorCode MatFactorInvertSchurComplement(Mat F)
9326 {
9327   PetscErrorCode ierr;
9328 
9329   PetscFunctionBegin;
9330   PetscValidType(F,1);
9331   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9332   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0);
9333   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9334   ierr = MatFactorInvertSchurComplement_Private(F);CHKERRQ(ierr);
9335   F->schur_status = MAT_FACTOR_SCHUR_INVERTED;
9336   PetscFunctionReturn(0);
9337 }
9338 
9339 /*@
9340   MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step
9341 
9342    Logically Collective on Mat
9343 
9344    Input Parameters:
9345 +  F - the factored matrix obtained by calling MatGetFactor()
9346 
9347    Notes:
9348     Must be called after MatFactorSetSchurIS().
9349 
9350    Level: advanced
9351 
9352    References:
9353 
9354 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorInvertSchurComplement()
9355 @*/
9356 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F)
9357 {
9358   PetscErrorCode ierr;
9359 
9360   PetscFunctionBegin;
9361   PetscValidType(F,1);
9362   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9363   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0);
9364   ierr = MatFactorFactorizeSchurComplement_Private(F);CHKERRQ(ierr);
9365   F->schur_status = MAT_FACTOR_SCHUR_FACTORED;
9366   PetscFunctionReturn(0);
9367 }
9368 
9369 /*@
9370    MatPtAP - Creates the matrix product C = P^T * A * P
9371 
9372    Neighbor-wise Collective on Mat
9373 
9374    Input Parameters:
9375 +  A - the matrix
9376 .  P - the projection matrix
9377 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9378 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate
9379           if the result is a dense matrix this is irrelevent
9380 
9381    Output Parameters:
9382 .  C - the product matrix
9383 
9384    Notes:
9385    C will be created and must be destroyed by the user with MatDestroy().
9386 
9387    This routine is currently only implemented for pairs of sequential dense matrices, AIJ matrices and classes
9388    which inherit from AIJ.
9389 
9390    Level: intermediate
9391 
9392 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
9393 @*/
9394 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
9395 {
9396   PetscErrorCode ierr;
9397   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9398   PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
9399   PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9400   PetscBool      sametype;
9401 
9402   PetscFunctionBegin;
9403   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9404   PetscValidType(A,1);
9405   MatCheckPreallocated(A,1);
9406   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9407   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9408   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9409   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9410   PetscValidType(P,2);
9411   MatCheckPreallocated(P,2);
9412   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9413   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9414 
9415   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);
9416   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);
9417   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9418   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9419 
9420   if (scall == MAT_REUSE_MATRIX) {
9421     PetscValidPointer(*C,5);
9422     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9423 
9424     if (!(*C)->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You cannot use MAT_REUSE_MATRIX");
9425     ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9426     ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9427     ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr);
9428     ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9429     ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9430     PetscFunctionReturn(0);
9431   }
9432 
9433   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9434   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9435 
9436   fA = A->ops->ptap;
9437   fP = P->ops->ptap;
9438   ierr = PetscStrcmp(((PetscObject)A)->type_name,((PetscObject)P)->type_name,&sametype);CHKERRQ(ierr);
9439   if (fP == fA && sametype) {
9440     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name);
9441     ptap = fA;
9442   } else {
9443     /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
9444     char ptapname[256];
9445     ierr = PetscStrncpy(ptapname,"MatPtAP_",sizeof(ptapname));CHKERRQ(ierr);
9446     ierr = PetscStrlcat(ptapname,((PetscObject)A)->type_name,sizeof(ptapname));CHKERRQ(ierr);
9447     ierr = PetscStrlcat(ptapname,"_",sizeof(ptapname));CHKERRQ(ierr);
9448     ierr = PetscStrlcat(ptapname,((PetscObject)P)->type_name,sizeof(ptapname));CHKERRQ(ierr);
9449     ierr = PetscStrlcat(ptapname,"_C",sizeof(ptapname));CHKERRQ(ierr); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
9450     ierr = PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);CHKERRQ(ierr);
9451     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);
9452   }
9453 
9454   ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9455   ierr = (*ptap)(A,P,scall,fill,C);CHKERRQ(ierr);
9456   ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9457   if (A->symmetric_set && A->symmetric) {
9458     ierr = MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
9459   }
9460   PetscFunctionReturn(0);
9461 }
9462 
9463 /*@
9464    MatPtAPNumeric - Computes the matrix product C = P^T * A * P
9465 
9466    Neighbor-wise Collective on Mat
9467 
9468    Input Parameters:
9469 +  A - the matrix
9470 -  P - the projection matrix
9471 
9472    Output Parameters:
9473 .  C - the product matrix
9474 
9475    Notes:
9476    C must have been created by calling MatPtAPSymbolic and must be destroyed by
9477    the user using MatDeatroy().
9478 
9479    This routine is currently only implemented for pairs of AIJ matrices and classes
9480    which inherit from AIJ.  C will be of type MATAIJ.
9481 
9482    Level: intermediate
9483 
9484 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
9485 @*/
9486 PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C)
9487 {
9488   PetscErrorCode ierr;
9489 
9490   PetscFunctionBegin;
9491   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9492   PetscValidType(A,1);
9493   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9494   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9495   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9496   PetscValidType(P,2);
9497   MatCheckPreallocated(P,2);
9498   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9499   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9500   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9501   PetscValidType(C,3);
9502   MatCheckPreallocated(C,3);
9503   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9504   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);
9505   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);
9506   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);
9507   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);
9508   MatCheckPreallocated(A,1);
9509 
9510   if (!C->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You should call MatPtAPSymbolic first");
9511   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9512   ierr = (*C->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr);
9513   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9514   PetscFunctionReturn(0);
9515 }
9516 
9517 /*@
9518    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P
9519 
9520    Neighbor-wise Collective on Mat
9521 
9522    Input Parameters:
9523 +  A - the matrix
9524 -  P - the projection matrix
9525 
9526    Output Parameters:
9527 .  C - the (i,j) structure of the product matrix
9528 
9529    Notes:
9530    C will be created and must be destroyed by the user with MatDestroy().
9531 
9532    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9533    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9534    this (i,j) structure by calling MatPtAPNumeric().
9535 
9536    Level: intermediate
9537 
9538 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
9539 @*/
9540 PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
9541 {
9542   PetscErrorCode ierr;
9543 
9544   PetscFunctionBegin;
9545   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9546   PetscValidType(A,1);
9547   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9548   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9549   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9550   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9551   PetscValidType(P,2);
9552   MatCheckPreallocated(P,2);
9553   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9554   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9555   PetscValidPointer(C,3);
9556 
9557   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);
9558   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);
9559   MatCheckPreallocated(A,1);
9560 
9561   if (!A->ops->ptapsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatType %s",((PetscObject)A)->type_name);
9562   ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
9563   ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr);
9564   ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
9565 
9566   /* ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); NO! this is not always true -ma */
9567   PetscFunctionReturn(0);
9568 }
9569 
9570 /*@
9571    MatRARt - Creates the matrix product C = R * A * R^T
9572 
9573    Neighbor-wise Collective on Mat
9574 
9575    Input Parameters:
9576 +  A - the matrix
9577 .  R - the projection matrix
9578 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9579 -  fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate
9580           if the result is a dense matrix this is irrelevent
9581 
9582    Output Parameters:
9583 .  C - the product matrix
9584 
9585    Notes:
9586    C will be created and must be destroyed by the user with MatDestroy().
9587 
9588    This routine is currently only implemented for pairs of AIJ matrices and classes
9589    which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes,
9590    parallel MatRARt is implemented via explicit transpose of R, which could be very expensive.
9591    We recommend using MatPtAP().
9592 
9593    Level: intermediate
9594 
9595 .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
9596 @*/
9597 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
9598 {
9599   PetscErrorCode ierr;
9600 
9601   PetscFunctionBegin;
9602   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9603   PetscValidType(A,1);
9604   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9605   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9606   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9607   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9608   PetscValidType(R,2);
9609   MatCheckPreallocated(R,2);
9610   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9611   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9612   PetscValidPointer(C,3);
9613   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);
9614 
9615   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9616   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9617   MatCheckPreallocated(A,1);
9618 
9619   if (!A->ops->rart) {
9620     Mat Rt;
9621     ierr = MatTranspose(R,MAT_INITIAL_MATRIX,&Rt);CHKERRQ(ierr);
9622     ierr = MatMatMatMult(R,A,Rt,scall,fill,C);CHKERRQ(ierr);
9623     ierr = MatDestroy(&Rt);CHKERRQ(ierr);
9624     PetscFunctionReturn(0);
9625   }
9626   ierr = PetscLogEventBegin(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
9627   ierr = (*A->ops->rart)(A,R,scall,fill,C);CHKERRQ(ierr);
9628   ierr = PetscLogEventEnd(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
9629   PetscFunctionReturn(0);
9630 }
9631 
9632 /*@
9633    MatRARtNumeric - Computes the matrix product C = R * A * R^T
9634 
9635    Neighbor-wise Collective on Mat
9636 
9637    Input Parameters:
9638 +  A - the matrix
9639 -  R - the projection matrix
9640 
9641    Output Parameters:
9642 .  C - the product matrix
9643 
9644    Notes:
9645    C must have been created by calling MatRARtSymbolic and must be destroyed by
9646    the user using MatDestroy().
9647 
9648    This routine is currently only implemented for pairs of AIJ matrices and classes
9649    which inherit from AIJ.  C will be of type MATAIJ.
9650 
9651    Level: intermediate
9652 
9653 .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
9654 @*/
9655 PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C)
9656 {
9657   PetscErrorCode ierr;
9658 
9659   PetscFunctionBegin;
9660   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9661   PetscValidType(A,1);
9662   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9663   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9664   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9665   PetscValidType(R,2);
9666   MatCheckPreallocated(R,2);
9667   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9668   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9669   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9670   PetscValidType(C,3);
9671   MatCheckPreallocated(C,3);
9672   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9673   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);
9674   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);
9675   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);
9676   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);
9677   MatCheckPreallocated(A,1);
9678 
9679   ierr = PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
9680   ierr = (*A->ops->rartnumeric)(A,R,C);CHKERRQ(ierr);
9681   ierr = PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
9682   PetscFunctionReturn(0);
9683 }
9684 
9685 /*@
9686    MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T
9687 
9688    Neighbor-wise Collective on Mat
9689 
9690    Input Parameters:
9691 +  A - the matrix
9692 -  R - the projection matrix
9693 
9694    Output Parameters:
9695 .  C - the (i,j) structure of the product matrix
9696 
9697    Notes:
9698    C will be created and must be destroyed by the user with MatDestroy().
9699 
9700    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9701    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9702    this (i,j) structure by calling MatRARtNumeric().
9703 
9704    Level: intermediate
9705 
9706 .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
9707 @*/
9708 PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
9709 {
9710   PetscErrorCode ierr;
9711 
9712   PetscFunctionBegin;
9713   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9714   PetscValidType(A,1);
9715   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9716   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9717   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9718   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9719   PetscValidType(R,2);
9720   MatCheckPreallocated(R,2);
9721   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9722   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9723   PetscValidPointer(C,3);
9724 
9725   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);
9726   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);
9727   MatCheckPreallocated(A,1);
9728   ierr = PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
9729   ierr = (*A->ops->rartsymbolic)(A,R,fill,C);CHKERRQ(ierr);
9730   ierr = PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
9731 
9732   ierr = MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));CHKERRQ(ierr);
9733   PetscFunctionReturn(0);
9734 }
9735 
9736 /*@
9737    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
9738 
9739    Neighbor-wise Collective on Mat
9740 
9741    Input Parameters:
9742 +  A - the left matrix
9743 .  B - the right matrix
9744 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9745 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
9746           if the result is a dense matrix this is irrelevent
9747 
9748    Output Parameters:
9749 .  C - the product matrix
9750 
9751    Notes:
9752    Unless scall is MAT_REUSE_MATRIX C will be created.
9753 
9754    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
9755    call to this function with either MAT_INITIAL_MATRIX or MatMatMultSymbolic()
9756 
9757    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9758    actually needed.
9759 
9760    If you have many matrices with the same non-zero structure to multiply, you
9761    should either
9762 $   1) use MAT_REUSE_MATRIX in all calls but the first or
9763 $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
9764    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
9765    with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse.
9766 
9767    Level: intermediate
9768 
9769 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(),  MatMatTransposeMult(), MatPtAP()
9770 @*/
9771 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9772 {
9773   PetscErrorCode ierr;
9774   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9775   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9776   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9777 
9778   PetscFunctionBegin;
9779   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9780   PetscValidType(A,1);
9781   MatCheckPreallocated(A,1);
9782   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9783   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9784   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9785   PetscValidType(B,2);
9786   MatCheckPreallocated(B,2);
9787   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9788   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9789   PetscValidPointer(C,3);
9790   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9791   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);
9792   if (scall == MAT_REUSE_MATRIX) {
9793     PetscValidPointer(*C,5);
9794     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9795     ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9796     ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9797     ierr = (*(*C)->ops->matmultnumeric)(A,B,*C);CHKERRQ(ierr);
9798     ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9799     ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9800     PetscFunctionReturn(0);
9801   }
9802   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9803   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9804 
9805   fA = A->ops->matmult;
9806   fB = B->ops->matmult;
9807   if (fB == fA) {
9808     if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
9809     mult = fB;
9810   } else {
9811     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9812     char multname[256];
9813     ierr = PetscStrncpy(multname,"MatMatMult_",sizeof(multname));CHKERRQ(ierr);
9814     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
9815     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
9816     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
9817     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9818     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
9819     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);
9820   }
9821   ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9822   ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr);
9823   ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9824   PetscFunctionReturn(0);
9825 }
9826 
9827 /*@
9828    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
9829    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().
9830 
9831    Neighbor-wise Collective on Mat
9832 
9833    Input Parameters:
9834 +  A - the left matrix
9835 .  B - the right matrix
9836 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
9837       if C is a dense matrix this is irrelevent
9838 
9839    Output Parameters:
9840 .  C - the product matrix
9841 
9842    Notes:
9843    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9844    actually needed.
9845 
9846    This routine is currently implemented for
9847     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
9848     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9849     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9850 
9851    Level: intermediate
9852 
9853    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, https://arxiv.org/abs/1006.4173
9854      We should incorporate them into PETSc.
9855 
9856 .seealso: MatMatMult(), MatMatMultNumeric()
9857 @*/
9858 PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
9859 {
9860   PetscErrorCode ierr;
9861   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*);
9862   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*);
9863   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL;
9864 
9865   PetscFunctionBegin;
9866   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9867   PetscValidType(A,1);
9868   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9869   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9870 
9871   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9872   PetscValidType(B,2);
9873   MatCheckPreallocated(B,2);
9874   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9875   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9876   PetscValidPointer(C,3);
9877 
9878   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);
9879   if (fill == PETSC_DEFAULT) fill = 2.0;
9880   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9881   MatCheckPreallocated(A,1);
9882 
9883   Asymbolic = A->ops->matmultsymbolic;
9884   Bsymbolic = B->ops->matmultsymbolic;
9885   if (Asymbolic == Bsymbolic) {
9886     if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
9887     symbolic = Bsymbolic;
9888   } else { /* dispatch based on the type of A and B */
9889     char symbolicname[256];
9890     ierr = PetscStrncpy(symbolicname,"MatMatMultSymbolic_",sizeof(symbolicname));CHKERRQ(ierr);
9891     ierr = PetscStrlcat(symbolicname,((PetscObject)A)->type_name,sizeof(symbolicname));CHKERRQ(ierr);
9892     ierr = PetscStrlcat(symbolicname,"_",sizeof(symbolicname));CHKERRQ(ierr);
9893     ierr = PetscStrlcat(symbolicname,((PetscObject)B)->type_name,sizeof(symbolicname));CHKERRQ(ierr);
9894     ierr = PetscStrlcat(symbolicname,"_C",sizeof(symbolicname));CHKERRQ(ierr);
9895     ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);CHKERRQ(ierr);
9896     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);
9897   }
9898   ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9899   ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr);
9900   ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9901   PetscFunctionReturn(0);
9902 }
9903 
9904 /*@
9905    MatMatMultNumeric - Performs the numeric matrix-matrix product.
9906    Call this routine after first calling MatMatMultSymbolic().
9907 
9908    Neighbor-wise Collective on Mat
9909 
9910    Input Parameters:
9911 +  A - the left matrix
9912 -  B - the right matrix
9913 
9914    Output Parameters:
9915 .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
9916 
9917    Notes:
9918    C must have been created with MatMatMultSymbolic().
9919 
9920    This routine is currently implemented for
9921     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
9922     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9923     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9924 
9925    Level: intermediate
9926 
9927 .seealso: MatMatMult(), MatMatMultSymbolic()
9928 @*/
9929 PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C)
9930 {
9931   PetscErrorCode ierr;
9932 
9933   PetscFunctionBegin;
9934   ierr = MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);CHKERRQ(ierr);
9935   PetscFunctionReturn(0);
9936 }
9937 
9938 /*@
9939    MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.
9940 
9941    Neighbor-wise Collective on Mat
9942 
9943    Input Parameters:
9944 +  A - the left matrix
9945 .  B - the right matrix
9946 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9947 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9948 
9949    Output Parameters:
9950 .  C - the product matrix
9951 
9952    Notes:
9953    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9954 
9955    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9956 
9957   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9958    actually needed.
9959 
9960    This routine is currently only implemented for pairs of SeqAIJ matrices, for the SeqDense class,
9961    and for pairs of MPIDense matrices.
9962 
9963    Options Database Keys:
9964 +  -matmattransmult_mpidense_mpidense_via {allgatherv,cyclic} - Choose between algorthims for MPIDense matrices: the
9965                                                                 first redundantly copies the transposed B matrix on each process and requiers O(log P) communication complexity;
9966                                                                 the second never stores more than one portion of the B matrix at a time by requires O(P) communication complexity.
9967 
9968    Level: intermediate
9969 
9970 .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
9971 @*/
9972 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9973 {
9974   PetscErrorCode ierr;
9975   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9976   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9977 
9978   PetscFunctionBegin;
9979   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9980   PetscValidType(A,1);
9981   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9982   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9983   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9984   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9985   PetscValidType(B,2);
9986   MatCheckPreallocated(B,2);
9987   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9988   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9989   PetscValidPointer(C,3);
9990   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);
9991   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9992   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9993   MatCheckPreallocated(A,1);
9994 
9995   fA = A->ops->mattransposemult;
9996   if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
9997   fB = B->ops->mattransposemult;
9998   if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
9999   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);
10000 
10001   ierr = PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
10002   if (scall == MAT_INITIAL_MATRIX) {
10003     ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
10004     ierr = (*A->ops->mattransposemultsymbolic)(A,B,fill,C);CHKERRQ(ierr);
10005     ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
10006   }
10007   ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
10008   ierr = (*A->ops->mattransposemultnumeric)(A,B,*C);CHKERRQ(ierr);
10009   ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
10010   ierr = PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
10011   PetscFunctionReturn(0);
10012 }
10013 
10014 /*@
10015    MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.
10016 
10017    Neighbor-wise Collective on Mat
10018 
10019    Input Parameters:
10020 +  A - the left matrix
10021 .  B - the right matrix
10022 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10023 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
10024 
10025    Output Parameters:
10026 .  C - the product matrix
10027 
10028    Notes:
10029    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
10030 
10031    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
10032 
10033   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
10034    actually needed.
10035 
10036    This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
10037    which inherit from SeqAIJ.  C will be of same type as the input matrices.
10038 
10039    Level: intermediate
10040 
10041 .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
10042 @*/
10043 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
10044 {
10045   PetscErrorCode ierr;
10046   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
10047   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
10048   PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL;
10049 
10050   PetscFunctionBegin;
10051   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
10052   PetscValidType(A,1);
10053   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10054   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10055   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10056   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
10057   PetscValidType(B,2);
10058   MatCheckPreallocated(B,2);
10059   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10060   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10061   PetscValidPointer(C,3);
10062   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);
10063   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
10064   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
10065   MatCheckPreallocated(A,1);
10066 
10067   fA = A->ops->transposematmult;
10068   fB = B->ops->transposematmult;
10069   if (fB==fA) {
10070     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
10071     transposematmult = fA;
10072   } else {
10073     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
10074     char multname[256];
10075     ierr = PetscStrncpy(multname,"MatTransposeMatMult_",sizeof(multname));CHKERRQ(ierr);
10076     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
10077     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
10078     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
10079     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
10080     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);CHKERRQ(ierr);
10081     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);
10082   }
10083   ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
10084   ierr = (*transposematmult)(A,B,scall,fill,C);CHKERRQ(ierr);
10085   ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
10086   PetscFunctionReturn(0);
10087 }
10088 
10089 /*@
10090    MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.
10091 
10092    Neighbor-wise Collective on Mat
10093 
10094    Input Parameters:
10095 +  A - the left matrix
10096 .  B - the middle matrix
10097 .  C - the right matrix
10098 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10099 -  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
10100           if the result is a dense matrix this is irrelevent
10101 
10102    Output Parameters:
10103 .  D - the product matrix
10104 
10105    Notes:
10106    Unless scall is MAT_REUSE_MATRIX D will be created.
10107 
10108    MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call
10109 
10110    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
10111    actually needed.
10112 
10113    If you have many matrices with the same non-zero structure to multiply, you
10114    should use MAT_REUSE_MATRIX in all calls but the first or
10115 
10116    Level: intermediate
10117 
10118 .seealso: MatMatMult, MatPtAP()
10119 @*/
10120 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
10121 {
10122   PetscErrorCode ierr;
10123   PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
10124   PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
10125   PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
10126   PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
10127 
10128   PetscFunctionBegin;
10129   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
10130   PetscValidType(A,1);
10131   MatCheckPreallocated(A,1);
10132   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10133   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10134   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10135   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
10136   PetscValidType(B,2);
10137   MatCheckPreallocated(B,2);
10138   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10139   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10140   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
10141   PetscValidPointer(C,3);
10142   MatCheckPreallocated(C,3);
10143   if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10144   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10145   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);
10146   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);
10147   if (scall == MAT_REUSE_MATRIX) {
10148     PetscValidPointer(*D,6);
10149     PetscValidHeaderSpecific(*D,MAT_CLASSID,6);
10150     ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10151     ierr = (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
10152     ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10153     PetscFunctionReturn(0);
10154   }
10155   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
10156   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
10157 
10158   fA = A->ops->matmatmult;
10159   fB = B->ops->matmatmult;
10160   fC = C->ops->matmatmult;
10161   if (fA == fB && fA == fC) {
10162     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name);
10163     mult = fA;
10164   } else {
10165     /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */
10166     char multname[256];
10167     ierr = PetscStrncpy(multname,"MatMatMatMult_",sizeof(multname));CHKERRQ(ierr);
10168     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
10169     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
10170     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
10171     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
10172     ierr = PetscStrlcat(multname,((PetscObject)C)->type_name,sizeof(multname));CHKERRQ(ierr);
10173     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr);
10174     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
10175     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);
10176   }
10177   ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10178   ierr = (*mult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
10179   ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10180   PetscFunctionReturn(0);
10181 }
10182 
10183 /*@
10184    MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
10185 
10186    Collective on Mat
10187 
10188    Input Parameters:
10189 +  mat - the matrix
10190 .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
10191 .  subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used)
10192 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10193 
10194    Output Parameter:
10195 .  matredundant - redundant matrix
10196 
10197    Notes:
10198    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
10199    original matrix has not changed from that last call to MatCreateRedundantMatrix().
10200 
10201    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
10202    calling it.
10203 
10204    Level: advanced
10205 
10206    Concepts: subcommunicator
10207    Concepts: duplicate matrix
10208 
10209 .seealso: MatDestroy()
10210 @*/
10211 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant)
10212 {
10213   PetscErrorCode ierr;
10214   MPI_Comm       comm;
10215   PetscMPIInt    size;
10216   PetscInt       mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs;
10217   Mat_Redundant  *redund=NULL;
10218   PetscSubcomm   psubcomm=NULL;
10219   MPI_Comm       subcomm_in=subcomm;
10220   Mat            *matseq;
10221   IS             isrow,iscol;
10222   PetscBool      newsubcomm=PETSC_FALSE;
10223 
10224   PetscFunctionBegin;
10225   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10226   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
10227     PetscValidPointer(*matredundant,5);
10228     PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5);
10229   }
10230 
10231   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
10232   if (size == 1 || nsubcomm == 1) {
10233     if (reuse == MAT_INITIAL_MATRIX) {
10234       ierr = MatDuplicate(mat,MAT_COPY_VALUES,matredundant);CHKERRQ(ierr);
10235     } else {
10236       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");
10237       ierr = MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
10238     }
10239     PetscFunctionReturn(0);
10240   }
10241 
10242   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10243   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10244   MatCheckPreallocated(mat,1);
10245 
10246   ierr = PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
10247   if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */
10248     /* create psubcomm, then get subcomm */
10249     ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
10250     ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
10251     if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size);
10252 
10253     ierr = PetscSubcommCreate(comm,&psubcomm);CHKERRQ(ierr);
10254     ierr = PetscSubcommSetNumber(psubcomm,nsubcomm);CHKERRQ(ierr);
10255     ierr = PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);CHKERRQ(ierr);
10256     ierr = PetscSubcommSetFromOptions(psubcomm);CHKERRQ(ierr);
10257     ierr = PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);CHKERRQ(ierr);
10258     newsubcomm = PETSC_TRUE;
10259     ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr);
10260   }
10261 
10262   /* get isrow, iscol and a local sequential matrix matseq[0] */
10263   if (reuse == MAT_INITIAL_MATRIX) {
10264     mloc_sub = PETSC_DECIDE;
10265     nloc_sub = PETSC_DECIDE;
10266     if (bs < 1) {
10267       ierr = PetscSplitOwnership(subcomm,&mloc_sub,&M);CHKERRQ(ierr);
10268       ierr = PetscSplitOwnership(subcomm,&nloc_sub,&N);CHKERRQ(ierr);
10269     } else {
10270       ierr = PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);CHKERRQ(ierr);
10271       ierr = PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N);CHKERRQ(ierr);
10272     }
10273     ierr = MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);CHKERRQ(ierr);
10274     rstart = rend - mloc_sub;
10275     ierr = ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);CHKERRQ(ierr);
10276     ierr = ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);CHKERRQ(ierr);
10277   } else { /* reuse == MAT_REUSE_MATRIX */
10278     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");
10279     /* retrieve subcomm */
10280     ierr = PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);CHKERRQ(ierr);
10281     redund = (*matredundant)->redundant;
10282     isrow  = redund->isrow;
10283     iscol  = redund->iscol;
10284     matseq = redund->matseq;
10285   }
10286   ierr = MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);CHKERRQ(ierr);
10287 
10288   /* get matredundant over subcomm */
10289   if (reuse == MAT_INITIAL_MATRIX) {
10290     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant);CHKERRQ(ierr);
10291 
10292     /* create a supporting struct and attach it to C for reuse */
10293     ierr = PetscNewLog(*matredundant,&redund);CHKERRQ(ierr);
10294     (*matredundant)->redundant = redund;
10295     redund->isrow              = isrow;
10296     redund->iscol              = iscol;
10297     redund->matseq             = matseq;
10298     if (newsubcomm) {
10299       redund->subcomm          = subcomm;
10300     } else {
10301       redund->subcomm          = MPI_COMM_NULL;
10302     }
10303   } else {
10304     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);CHKERRQ(ierr);
10305   }
10306   ierr = PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
10307   PetscFunctionReturn(0);
10308 }
10309 
10310 /*@C
10311    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
10312    a given 'mat' object. Each submatrix can span multiple procs.
10313 
10314    Collective on Mat
10315 
10316    Input Parameters:
10317 +  mat - the matrix
10318 .  subcomm - the subcommunicator obtained by com_split(comm)
10319 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10320 
10321    Output Parameter:
10322 .  subMat - 'parallel submatrices each spans a given subcomm
10323 
10324   Notes:
10325   The submatrix partition across processors is dictated by 'subComm' a
10326   communicator obtained by com_split(comm). The comm_split
10327   is not restriced to be grouped with consecutive original ranks.
10328 
10329   Due the comm_split() usage, the parallel layout of the submatrices
10330   map directly to the layout of the original matrix [wrt the local
10331   row,col partitioning]. So the original 'DiagonalMat' naturally maps
10332   into the 'DiagonalMat' of the subMat, hence it is used directly from
10333   the subMat. However the offDiagMat looses some columns - and this is
10334   reconstructed with MatSetValues()
10335 
10336   Level: advanced
10337 
10338   Concepts: subcommunicator
10339   Concepts: submatrices
10340 
10341 .seealso: MatCreateSubMatrices()
10342 @*/
10343 PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
10344 {
10345   PetscErrorCode ierr;
10346   PetscMPIInt    commsize,subCommSize;
10347 
10348   PetscFunctionBegin;
10349   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRQ(ierr);
10350   ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr);
10351   if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
10352 
10353   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");
10354   ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10355   ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr);
10356   ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10357   PetscFunctionReturn(0);
10358 }
10359 
10360 /*@
10361    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
10362 
10363    Not Collective
10364 
10365    Input Arguments:
10366    mat - matrix to extract local submatrix from
10367    isrow - local row indices for submatrix
10368    iscol - local column indices for submatrix
10369 
10370    Output Arguments:
10371    submat - the submatrix
10372 
10373    Level: intermediate
10374 
10375    Notes:
10376    The submat should be returned with MatRestoreLocalSubMatrix().
10377 
10378    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
10379    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
10380 
10381    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
10382    MatSetValuesBlockedLocal() will also be implemented.
10383 
10384    The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that
10385    matrices obtained with DMCreateMatrix() generally already have the local to global mapping provided.
10386 
10387 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping()
10388 @*/
10389 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10390 {
10391   PetscErrorCode ierr;
10392 
10393   PetscFunctionBegin;
10394   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10395   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10396   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10397   PetscCheckSameComm(isrow,2,iscol,3);
10398   PetscValidPointer(submat,4);
10399   if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call");
10400 
10401   if (mat->ops->getlocalsubmatrix) {
10402     ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10403   } else {
10404     ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr);
10405   }
10406   PetscFunctionReturn(0);
10407 }
10408 
10409 /*@
10410    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
10411 
10412    Not Collective
10413 
10414    Input Arguments:
10415    mat - matrix to extract local submatrix from
10416    isrow - local row indices for submatrix
10417    iscol - local column indices for submatrix
10418    submat - the submatrix
10419 
10420    Level: intermediate
10421 
10422 .seealso: MatGetLocalSubMatrix()
10423 @*/
10424 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10425 {
10426   PetscErrorCode ierr;
10427 
10428   PetscFunctionBegin;
10429   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10430   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10431   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10432   PetscCheckSameComm(isrow,2,iscol,3);
10433   PetscValidPointer(submat,4);
10434   if (*submat) {
10435     PetscValidHeaderSpecific(*submat,MAT_CLASSID,4);
10436   }
10437 
10438   if (mat->ops->restorelocalsubmatrix) {
10439     ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10440   } else {
10441     ierr = MatDestroy(submat);CHKERRQ(ierr);
10442   }
10443   *submat = NULL;
10444   PetscFunctionReturn(0);
10445 }
10446 
10447 /* --------------------------------------------------------*/
10448 /*@
10449    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix
10450 
10451    Collective on Mat
10452 
10453    Input Parameter:
10454 .  mat - the matrix
10455 
10456    Output Parameter:
10457 .  is - if any rows have zero diagonals this contains the list of them
10458 
10459    Level: developer
10460 
10461    Concepts: matrix-vector product
10462 
10463 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10464 @*/
10465 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is)
10466 {
10467   PetscErrorCode ierr;
10468 
10469   PetscFunctionBegin;
10470   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10471   PetscValidType(mat,1);
10472   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10473   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10474 
10475   if (!mat->ops->findzerodiagonals) {
10476     Vec                diag;
10477     const PetscScalar *a;
10478     PetscInt          *rows;
10479     PetscInt           rStart, rEnd, r, nrow = 0;
10480 
10481     ierr = MatCreateVecs(mat, &diag, NULL);CHKERRQ(ierr);
10482     ierr = MatGetDiagonal(mat, diag);CHKERRQ(ierr);
10483     ierr = MatGetOwnershipRange(mat, &rStart, &rEnd);CHKERRQ(ierr);
10484     ierr = VecGetArrayRead(diag, &a);CHKERRQ(ierr);
10485     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow;
10486     ierr = PetscMalloc1(nrow, &rows);CHKERRQ(ierr);
10487     nrow = 0;
10488     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart;
10489     ierr = VecRestoreArrayRead(diag, &a);CHKERRQ(ierr);
10490     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10491     ierr = ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);CHKERRQ(ierr);
10492   } else {
10493     ierr = (*mat->ops->findzerodiagonals)(mat, is);CHKERRQ(ierr);
10494   }
10495   PetscFunctionReturn(0);
10496 }
10497 
10498 /*@
10499    MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size)
10500 
10501    Collective on Mat
10502 
10503    Input Parameter:
10504 .  mat - the matrix
10505 
10506    Output Parameter:
10507 .  is - contains the list of rows with off block diagonal entries
10508 
10509    Level: developer
10510 
10511    Concepts: matrix-vector product
10512 
10513 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10514 @*/
10515 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is)
10516 {
10517   PetscErrorCode ierr;
10518 
10519   PetscFunctionBegin;
10520   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10521   PetscValidType(mat,1);
10522   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10523   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10524 
10525   if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined");
10526   ierr = (*mat->ops->findoffblockdiagonalentries)(mat,is);CHKERRQ(ierr);
10527   PetscFunctionReturn(0);
10528 }
10529 
10530 /*@C
10531   MatInvertBlockDiagonal - Inverts the block diagonal entries.
10532 
10533   Collective on Mat
10534 
10535   Input Parameters:
10536 . mat - the matrix
10537 
10538   Output Parameters:
10539 . values - the block inverses in column major order (FORTRAN-like)
10540 
10541    Note:
10542    This routine is not available from Fortran.
10543 
10544   Level: advanced
10545 
10546 .seealso: MatInvertBockDiagonalMat
10547 @*/
10548 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
10549 {
10550   PetscErrorCode ierr;
10551 
10552   PetscFunctionBegin;
10553   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10554   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10555   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10556   if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
10557   ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr);
10558   PetscFunctionReturn(0);
10559 }
10560 
10561 /*@C
10562   MatInvertVariableBlockDiagonal - Inverts the block diagonal entries.
10563 
10564   Collective on Mat
10565 
10566   Input Parameters:
10567 + mat - the matrix
10568 . nblocks - the number of blocks
10569 - bsizes - the size of each block
10570 
10571   Output Parameters:
10572 . values - the block inverses in column major order (FORTRAN-like)
10573 
10574    Note:
10575    This routine is not available from Fortran.
10576 
10577   Level: advanced
10578 
10579 .seealso: MatInvertBockDiagonal()
10580 @*/
10581 PetscErrorCode MatInvertVariableBlockDiagonal(Mat mat,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *values)
10582 {
10583   PetscErrorCode ierr;
10584 
10585   PetscFunctionBegin;
10586   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10587   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10588   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10589   if (!mat->ops->invertvariableblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
10590   ierr = (*mat->ops->invertvariableblockdiagonal)(mat,nblocks,bsizes,values);CHKERRQ(ierr);
10591   PetscFunctionReturn(0);
10592 }
10593 
10594 /*@
10595   MatInvertBlockDiagonalMat - set matrix C to be the inverted block diagonal of matrix A
10596 
10597   Collective on Mat
10598 
10599   Input Parameters:
10600 . A - the matrix
10601 
10602   Output Parameters:
10603 . C - matrix with inverted block diagonal of A.  This matrix should be created and may have its type set.
10604 
10605   Notes: the blocksize of the matrix is used to determine the blocks on the diagonal of C
10606 
10607   Level: advanced
10608 
10609 .seealso: MatInvertBockDiagonal()
10610 @*/
10611 PetscErrorCode MatInvertBlockDiagonalMat(Mat A,Mat C)
10612 {
10613   PetscErrorCode     ierr;
10614   const PetscScalar *vals;
10615   PetscInt          *dnnz;
10616   PetscInt           M,N,m,n,rstart,rend,bs,i,j;
10617 
10618   PetscFunctionBegin;
10619   ierr = MatInvertBlockDiagonal(A,&vals);CHKERRQ(ierr);
10620   ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr);
10621   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
10622   ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr);
10623   ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr);
10624   ierr = MatSetBlockSize(C,bs);CHKERRQ(ierr);
10625   ierr = PetscMalloc1(m/bs,&dnnz);CHKERRQ(ierr);
10626   for (j = 0; j < m/bs; j++) dnnz[j] = 1;
10627   ierr = MatXAIJSetPreallocation(C,bs,dnnz,NULL,NULL,NULL);CHKERRQ(ierr);
10628   ierr = PetscFree(dnnz);CHKERRQ(ierr);
10629   ierr = MatGetOwnershipRange(C,&rstart,&rend);CHKERRQ(ierr);
10630   ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr);
10631   for (i = rstart/bs; i < rend/bs; i++) {
10632     ierr = MatSetValuesBlocked(C,1,&i,1,&i,&vals[(i-rstart/bs)*bs*bs],INSERT_VALUES);CHKERRQ(ierr);
10633   }
10634   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10635   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10636   ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr);
10637   PetscFunctionReturn(0);
10638 }
10639 
10640 /*@C
10641     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
10642     via MatTransposeColoringCreate().
10643 
10644     Collective on MatTransposeColoring
10645 
10646     Input Parameter:
10647 .   c - coloring context
10648 
10649     Level: intermediate
10650 
10651 .seealso: MatTransposeColoringCreate()
10652 @*/
10653 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c)
10654 {
10655   PetscErrorCode       ierr;
10656   MatTransposeColoring matcolor=*c;
10657 
10658   PetscFunctionBegin;
10659   if (!matcolor) PetscFunctionReturn(0);
10660   if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; PetscFunctionReturn(0);}
10661 
10662   ierr = PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);CHKERRQ(ierr);
10663   ierr = PetscFree(matcolor->rows);CHKERRQ(ierr);
10664   ierr = PetscFree(matcolor->den2sp);CHKERRQ(ierr);
10665   ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr);
10666   ierr = PetscFree(matcolor->columns);CHKERRQ(ierr);
10667   if (matcolor->brows>0) {
10668     ierr = PetscFree(matcolor->lstart);CHKERRQ(ierr);
10669   }
10670   ierr = PetscHeaderDestroy(c);CHKERRQ(ierr);
10671   PetscFunctionReturn(0);
10672 }
10673 
10674 /*@C
10675     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
10676     a MatTransposeColoring context has been created, computes a dense B^T by Apply
10677     MatTransposeColoring to sparse B.
10678 
10679     Collective on MatTransposeColoring
10680 
10681     Input Parameters:
10682 +   B - sparse matrix B
10683 .   Btdense - symbolic dense matrix B^T
10684 -   coloring - coloring context created with MatTransposeColoringCreate()
10685 
10686     Output Parameter:
10687 .   Btdense - dense matrix B^T
10688 
10689     Level: advanced
10690 
10691      Notes:
10692     These are used internally for some implementations of MatRARt()
10693 
10694 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplyDenToSp()
10695 
10696 @*/
10697 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
10698 {
10699   PetscErrorCode ierr;
10700 
10701   PetscFunctionBegin;
10702   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
10703   PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2);
10704   PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3);
10705 
10706   if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
10707   ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr);
10708   PetscFunctionReturn(0);
10709 }
10710 
10711 /*@C
10712     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
10713     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
10714     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
10715     Csp from Cden.
10716 
10717     Collective on MatTransposeColoring
10718 
10719     Input Parameters:
10720 +   coloring - coloring context created with MatTransposeColoringCreate()
10721 -   Cden - matrix product of a sparse matrix and a dense matrix Btdense
10722 
10723     Output Parameter:
10724 .   Csp - sparse matrix
10725 
10726     Level: advanced
10727 
10728      Notes:
10729     These are used internally for some implementations of MatRARt()
10730 
10731 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()
10732 
10733 @*/
10734 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
10735 {
10736   PetscErrorCode ierr;
10737 
10738   PetscFunctionBegin;
10739   PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1);
10740   PetscValidHeaderSpecific(Cden,MAT_CLASSID,2);
10741   PetscValidHeaderSpecific(Csp,MAT_CLASSID,3);
10742 
10743   if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
10744   ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr);
10745   PetscFunctionReturn(0);
10746 }
10747 
10748 /*@C
10749    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.
10750 
10751    Collective on Mat
10752 
10753    Input Parameters:
10754 +  mat - the matrix product C
10755 -  iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring()
10756 
10757     Output Parameter:
10758 .   color - the new coloring context
10759 
10760     Level: intermediate
10761 
10762 .seealso: MatTransposeColoringDestroy(),  MatTransColoringApplySpToDen(),
10763            MatTransColoringApplyDenToSp()
10764 @*/
10765 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
10766 {
10767   MatTransposeColoring c;
10768   MPI_Comm             comm;
10769   PetscErrorCode       ierr;
10770 
10771   PetscFunctionBegin;
10772   ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10773   ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
10774   ierr = PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);CHKERRQ(ierr);
10775 
10776   c->ctype = iscoloring->ctype;
10777   if (mat->ops->transposecoloringcreate) {
10778     ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr);
10779   } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type");
10780 
10781   *color = c;
10782   ierr   = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10783   PetscFunctionReturn(0);
10784 }
10785 
10786 /*@
10787       MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the
10788         matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the
10789         same, otherwise it will be larger
10790 
10791      Not Collective
10792 
10793   Input Parameter:
10794 .    A  - the matrix
10795 
10796   Output Parameter:
10797 .    state - the current state
10798 
10799   Notes:
10800     You can only compare states from two different calls to the SAME matrix, you cannot compare calls between
10801          different matrices
10802 
10803   Level: intermediate
10804 
10805 @*/
10806 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state)
10807 {
10808   PetscFunctionBegin;
10809   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10810   *state = mat->nonzerostate;
10811   PetscFunctionReturn(0);
10812 }
10813 
10814 /*@
10815       MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential
10816                  matrices from each processor
10817 
10818     Collective on MPI_Comm
10819 
10820    Input Parameters:
10821 +    comm - the communicators the parallel matrix will live on
10822 .    seqmat - the input sequential matrices
10823 .    n - number of local columns (or PETSC_DECIDE)
10824 -    reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10825 
10826    Output Parameter:
10827 .    mpimat - the parallel matrix generated
10828 
10829     Level: advanced
10830 
10831    Notes:
10832     The number of columns of the matrix in EACH processor MUST be the same.
10833 
10834 @*/
10835 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat)
10836 {
10837   PetscErrorCode ierr;
10838 
10839   PetscFunctionBegin;
10840   if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name);
10841   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");
10842 
10843   ierr = PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10844   ierr = (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);CHKERRQ(ierr);
10845   ierr = PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10846   PetscFunctionReturn(0);
10847 }
10848 
10849 /*@
10850      MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent
10851                  ranks' ownership ranges.
10852 
10853     Collective on A
10854 
10855    Input Parameters:
10856 +    A   - the matrix to create subdomains from
10857 -    N   - requested number of subdomains
10858 
10859 
10860    Output Parameters:
10861 +    n   - number of subdomains resulting on this rank
10862 -    iss - IS list with indices of subdomains on this rank
10863 
10864     Level: advanced
10865 
10866     Notes:
10867     number of subdomains must be smaller than the communicator size
10868 @*/
10869 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[])
10870 {
10871   MPI_Comm        comm,subcomm;
10872   PetscMPIInt     size,rank,color;
10873   PetscInt        rstart,rend,k;
10874   PetscErrorCode  ierr;
10875 
10876   PetscFunctionBegin;
10877   ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr);
10878   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
10879   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
10880   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);
10881   *n = 1;
10882   k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */
10883   color = rank/k;
10884   ierr = MPI_Comm_split(comm,color,rank,&subcomm);CHKERRQ(ierr);
10885   ierr = PetscMalloc1(1,iss);CHKERRQ(ierr);
10886   ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
10887   ierr = ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);CHKERRQ(ierr);
10888   ierr = MPI_Comm_free(&subcomm);CHKERRQ(ierr);
10889   PetscFunctionReturn(0);
10890 }
10891 
10892 /*@
10893    MatGalerkin - Constructs the coarse grid problem via Galerkin projection.
10894 
10895    If the interpolation and restriction operators are the same, uses MatPtAP.
10896    If they are not the same, use MatMatMatMult.
10897 
10898    Once the coarse grid problem is constructed, correct for interpolation operators
10899    that are not of full rank, which can legitimately happen in the case of non-nested
10900    geometric multigrid.
10901 
10902    Input Parameters:
10903 +  restrct - restriction operator
10904 .  dA - fine grid matrix
10905 .  interpolate - interpolation operator
10906 .  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10907 -  fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate
10908 
10909    Output Parameters:
10910 .  A - the Galerkin coarse matrix
10911 
10912    Options Database Key:
10913 .  -pc_mg_galerkin <both,pmat,mat,none>
10914 
10915    Level: developer
10916 
10917 .seealso: MatPtAP(), MatMatMatMult()
10918 @*/
10919 PetscErrorCode  MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A)
10920 {
10921   PetscErrorCode ierr;
10922   IS             zerorows;
10923   Vec            diag;
10924 
10925   PetscFunctionBegin;
10926   if (reuse == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10927   /* Construct the coarse grid matrix */
10928   if (interpolate == restrct) {
10929     ierr = MatPtAP(dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10930   } else {
10931     ierr = MatMatMatMult(restrct,dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10932   }
10933 
10934   /* If the interpolation matrix is not of full rank, A will have zero rows.
10935      This can legitimately happen in the case of non-nested geometric multigrid.
10936      In that event, we set the rows of the matrix to the rows of the identity,
10937      ignoring the equations (as the RHS will also be zero). */
10938 
10939   ierr = MatFindZeroRows(*A, &zerorows);CHKERRQ(ierr);
10940 
10941   if (zerorows != NULL) { /* if there are any zero rows */
10942     ierr = MatCreateVecs(*A, &diag, NULL);CHKERRQ(ierr);
10943     ierr = MatGetDiagonal(*A, diag);CHKERRQ(ierr);
10944     ierr = VecISSet(diag, zerorows, 1.0);CHKERRQ(ierr);
10945     ierr = MatDiagonalSet(*A, diag, INSERT_VALUES);CHKERRQ(ierr);
10946     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10947     ierr = ISDestroy(&zerorows);CHKERRQ(ierr);
10948   }
10949   PetscFunctionReturn(0);
10950 }
10951 
10952 /*@C
10953     MatSetOperation - Allows user to set a matrix operation for any matrix type
10954 
10955    Logically Collective on Mat
10956 
10957     Input Parameters:
10958 +   mat - the matrix
10959 .   op - the name of the operation
10960 -   f - the function that provides the operation
10961 
10962    Level: developer
10963 
10964     Usage:
10965 $      extern PetscErrorCode usermult(Mat,Vec,Vec);
10966 $      ierr = MatCreateXXX(comm,...&A);
10967 $      ierr = MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult);
10968 
10969     Notes:
10970     See the file include/petscmat.h for a complete list of matrix
10971     operations, which all have the form MATOP_<OPERATION>, where
10972     <OPERATION> is the name (in all capital letters) of the
10973     user interface routine (e.g., MatMult() -> MATOP_MULT).
10974 
10975     All user-provided functions (except for MATOP_DESTROY) should have the same calling
10976     sequence as the usual matrix interface routines, since they
10977     are intended to be accessed via the usual matrix interface
10978     routines, e.g.,
10979 $       MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec)
10980 
10981     In particular each function MUST return an error code of 0 on success and
10982     nonzero on failure.
10983 
10984     This routine is distinct from MatShellSetOperation() in that it can be called on any matrix type.
10985 
10986 .seealso: MatGetOperation(), MatCreateShell(), MatShellSetContext(), MatShellSetOperation()
10987 @*/
10988 PetscErrorCode MatSetOperation(Mat mat,MatOperation op,void (*f)(void))
10989 {
10990   PetscFunctionBegin;
10991   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10992   if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) {
10993     mat->ops->viewnative = mat->ops->view;
10994   }
10995   (((void(**)(void))mat->ops)[op]) = f;
10996   PetscFunctionReturn(0);
10997 }
10998 
10999 /*@C
11000     MatGetOperation - Gets a matrix operation for any matrix type.
11001 
11002     Not Collective
11003 
11004     Input Parameters:
11005 +   mat - the matrix
11006 -   op - the name of the operation
11007 
11008     Output Parameter:
11009 .   f - the function that provides the operation
11010 
11011     Level: developer
11012 
11013     Usage:
11014 $      PetscErrorCode (*usermult)(Mat,Vec,Vec);
11015 $      ierr = MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult);
11016 
11017     Notes:
11018     See the file include/petscmat.h for a complete list of matrix
11019     operations, which all have the form MATOP_<OPERATION>, where
11020     <OPERATION> is the name (in all capital letters) of the
11021     user interface routine (e.g., MatMult() -> MATOP_MULT).
11022 
11023     This routine is distinct from MatShellGetOperation() in that it can be called on any matrix type.
11024 
11025 .seealso: MatSetOperation(), MatCreateShell(), MatShellGetContext(), MatShellGetOperation()
11026 @*/
11027 PetscErrorCode MatGetOperation(Mat mat,MatOperation op,void(**f)(void))
11028 {
11029   PetscFunctionBegin;
11030   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
11031   *f = (((void (**)(void))mat->ops)[op]);
11032   PetscFunctionReturn(0);
11033 }
11034 
11035 /*@
11036     MatHasOperation - Determines whether the given matrix supports the particular
11037     operation.
11038 
11039    Not Collective
11040 
11041    Input Parameters:
11042 +  mat - the matrix
11043 -  op - the operation, for example, MATOP_GET_DIAGONAL
11044 
11045    Output Parameter:
11046 .  has - either PETSC_TRUE or PETSC_FALSE
11047 
11048    Level: advanced
11049 
11050    Notes:
11051    See the file include/petscmat.h for a complete list of matrix
11052    operations, which all have the form MATOP_<OPERATION>, where
11053    <OPERATION> is the name (in all capital letters) of the
11054    user-level routine.  E.g., MatNorm() -> MATOP_NORM.
11055 
11056 .seealso: MatCreateShell()
11057 @*/
11058 PetscErrorCode MatHasOperation(Mat mat,MatOperation op,PetscBool *has)
11059 {
11060   PetscErrorCode ierr;
11061 
11062   PetscFunctionBegin;
11063   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
11064   PetscValidType(mat,1);
11065   PetscValidPointer(has,3);
11066   if (mat->ops->hasoperation) {
11067     ierr = (*mat->ops->hasoperation)(mat,op,has);CHKERRQ(ierr);
11068   } else {
11069     if (((void**)mat->ops)[op]) *has =  PETSC_TRUE;
11070     else {
11071       *has = PETSC_FALSE;
11072       if (op == MATOP_CREATE_SUBMATRIX) {
11073         PetscMPIInt size;
11074 
11075         ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
11076         if (size == 1) {
11077           ierr = MatHasOperation(mat,MATOP_CREATE_SUBMATRICES,has);CHKERRQ(ierr);
11078         }
11079       }
11080     }
11081   }
11082   PetscFunctionReturn(0);
11083 }
11084 
11085 /*@
11086     MatHasCongruentLayouts - Determines whether the rows and columns layouts
11087     of the matrix are congruent
11088 
11089    Collective on mat
11090 
11091    Input Parameters:
11092 .  mat - the matrix
11093 
11094    Output Parameter:
11095 .  cong - either PETSC_TRUE or PETSC_FALSE
11096 
11097    Level: beginner
11098 
11099    Notes:
11100 
11101 .seealso: MatCreate(), MatSetSizes()
11102 @*/
11103 PetscErrorCode MatHasCongruentLayouts(Mat mat,PetscBool *cong)
11104 {
11105   PetscErrorCode ierr;
11106 
11107   PetscFunctionBegin;
11108   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
11109   PetscValidType(mat,1);
11110   PetscValidPointer(cong,2);
11111   if (!mat->rmap || !mat->cmap) {
11112     *cong = mat->rmap == mat->cmap ? PETSC_TRUE : PETSC_FALSE;
11113     PetscFunctionReturn(0);
11114   }
11115   if (mat->congruentlayouts == PETSC_DECIDE) { /* first time we compare rows and cols layouts */
11116     ierr = PetscLayoutCompare(mat->rmap,mat->cmap,cong);CHKERRQ(ierr);
11117     if (*cong) mat->congruentlayouts = 1;
11118     else       mat->congruentlayouts = 0;
11119   } else *cong = mat->congruentlayouts ? PETSC_TRUE : PETSC_FALSE;
11120   PetscFunctionReturn(0);
11121 }
11122 
11123 /*@
11124     MatFreeIntermediateDataStructures - Free intermediate data structures created for reuse,
11125     e.g., matrx product of MatPtAP.
11126 
11127    Collective on mat
11128 
11129    Input Parameters:
11130 .  mat - the matrix
11131 
11132    Output Parameter:
11133 .  mat - the matrix with intermediate data structures released
11134 
11135    Level: advanced
11136 
11137    Notes:
11138 
11139 .seealso: MatPtAP(), MatMatMult()
11140 @*/
11141 PetscErrorCode MatFreeIntermediateDataStructures(Mat mat)
11142 {
11143   PetscErrorCode ierr;
11144 
11145   PetscFunctionBegin;
11146   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
11147   PetscValidType(mat,1);
11148   if (mat->ops->freeintermediatedatastructures) {
11149     ierr = (*mat->ops->freeintermediatedatastructures)(mat);CHKERRQ(ierr);
11150   }
11151   PetscFunctionReturn(0);
11152 }
11153