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