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