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