xref: /petsc/src/mat/interface/matrix.c (revision 7717923bc701bab8a4f3ac99c5385655439376ed)
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     if (mat->rmap->mapping && mat->cmap->mapping && !(*M)->rmap->mapping && !(*M)->cmap->mapping) {
4066       ierr = MatSetLocalToGlobalMapping(*M,mat->rmap->mapping,mat->cmap->mapping);CHKERRQ(ierr);
4067     }
4068     (*M)->stencil.dim = mat->stencil.dim;
4069     (*M)->stencil.noc = mat->stencil.noc;
4070     for (i=0; i<=mat->stencil.dim; i++) {
4071       (*M)->stencil.dims[i]   = mat->stencil.dims[i];
4072       (*M)->stencil.starts[i] = mat->stencil.starts[i];
4073     }
4074     ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4075   }
4076   ierr = PetscObjectStateIncrease((PetscObject)*M);CHKERRQ(ierr);
4077 
4078   /* Copy Mat options */
4079   if (mat->symmetric) {ierr = MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);}
4080   if (mat->hermitian) {ierr = MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);}
4081   PetscFunctionReturn(0);
4082 }
4083 
4084 /*@C
4085    MatFactorGetSolverPackage - Returns name of the package providing the factorization routines
4086 
4087    Not Collective
4088 
4089    Input Parameter:
4090 .  mat - the matrix, must be a factored matrix
4091 
4092    Output Parameter:
4093 .   type - the string name of the package (do not free this string)
4094 
4095    Notes:
4096       In Fortran you pass in a empty string and the package name will be copied into it.
4097     (Make sure the string is long enough)
4098 
4099    Level: intermediate
4100 
4101 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
4102 @*/
4103 PetscErrorCode MatFactorGetSolverPackage(Mat mat, const MatSolverPackage *type)
4104 {
4105   PetscErrorCode ierr, (*conv)(Mat,const MatSolverPackage*);
4106 
4107   PetscFunctionBegin;
4108   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4109   PetscValidType(mat,1);
4110   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
4111   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverPackage_C",&conv);CHKERRQ(ierr);
4112   if (!conv) {
4113     *type = MATSOLVERPETSC;
4114   } else {
4115     ierr = (*conv)(mat,type);CHKERRQ(ierr);
4116   }
4117   PetscFunctionReturn(0);
4118 }
4119 
4120 typedef struct _MatSolverPackageForSpecifcType* MatSolverPackageForSpecifcType;
4121 struct _MatSolverPackageForSpecifcType {
4122   MatType                        mtype;
4123   PetscErrorCode                 (*getfactor[4])(Mat,MatFactorType,Mat*);
4124   MatSolverPackageForSpecifcType next;
4125 };
4126 
4127 typedef struct _MatSolverPackageHolder* MatSolverPackageHolder;
4128 struct _MatSolverPackageHolder {
4129   char                           *name;
4130   MatSolverPackageForSpecifcType handlers;
4131   MatSolverPackageHolder         next;
4132 };
4133 
4134 static MatSolverPackageHolder MatSolverPackageHolders = NULL;
4135 
4136 /*@C
4137    MatSolvePackageRegister - Registers a MatSolverPackage that works for a particular matrix type
4138 
4139    Input Parameters:
4140 +    package - name of the package, for example petsc or superlu
4141 .    mtype - the matrix type that works with this package
4142 .    ftype - the type of factorization supported by the package
4143 -    getfactor - routine that will create the factored matrix ready to be used
4144 
4145     Level: intermediate
4146 
4147 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4148 @*/
4149 PetscErrorCode MatSolverPackageRegister(const MatSolverPackage package,const MatType mtype,MatFactorType ftype,PetscErrorCode (*getfactor)(Mat,MatFactorType,Mat*))
4150 {
4151   PetscErrorCode                 ierr;
4152   MatSolverPackageHolder         next = MatSolverPackageHolders,prev;
4153   PetscBool                      flg;
4154   MatSolverPackageForSpecifcType inext,iprev = NULL;
4155 
4156   PetscFunctionBegin;
4157   if (!next) {
4158     ierr = PetscNew(&MatSolverPackageHolders);CHKERRQ(ierr);
4159     ierr = PetscStrallocpy(package,&MatSolverPackageHolders->name);CHKERRQ(ierr);
4160     ierr = PetscNew(&MatSolverPackageHolders->handlers);CHKERRQ(ierr);
4161     ierr = PetscStrallocpy(mtype,(char **)&MatSolverPackageHolders->handlers->mtype);CHKERRQ(ierr);
4162     MatSolverPackageHolders->handlers->getfactor[(int)ftype-1] = getfactor;
4163     PetscFunctionReturn(0);
4164   }
4165   while (next) {
4166     ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr);
4167     if (flg) {
4168       if (!next->handlers) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverPackageHolder is missing handlers");
4169       inext = next->handlers;
4170       while (inext) {
4171         ierr = PetscStrcasecmp(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4172         if (flg) {
4173           inext->getfactor[(int)ftype-1] = getfactor;
4174           PetscFunctionReturn(0);
4175         }
4176         iprev = inext;
4177         inext = inext->next;
4178       }
4179       ierr = PetscNew(&iprev->next);CHKERRQ(ierr);
4180       ierr = PetscStrallocpy(mtype,(char **)&iprev->next->mtype);CHKERRQ(ierr);
4181       iprev->next->getfactor[(int)ftype-1] = getfactor;
4182       PetscFunctionReturn(0);
4183     }
4184     prev = next;
4185     next = next->next;
4186   }
4187   ierr = PetscNew(&prev->next);CHKERRQ(ierr);
4188   ierr = PetscStrallocpy(package,&prev->next->name);CHKERRQ(ierr);
4189   ierr = PetscNew(&prev->next->handlers);CHKERRQ(ierr);
4190   ierr = PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);CHKERRQ(ierr);
4191   prev->next->handlers->getfactor[(int)ftype-1] = getfactor;
4192   PetscFunctionReturn(0);
4193 }
4194 
4195 /*@C
4196    MatSolvePackageGet - Get's the function that creates the factor matrix if it exist
4197 
4198    Input Parameters:
4199 +    package - name of the package, for example petsc or superlu
4200 .    ftype - the type of factorization supported by the package
4201 -    mtype - the matrix type that works with this package
4202 
4203    Output Parameters:
4204 +   foundpackage - PETSC_TRUE if the package was registered
4205 .   foundmtype - PETSC_TRUE if the package supports the requested mtype
4206 -   getfactor - routine that will create the factored matrix ready to be used or NULL if not found
4207 
4208     Level: intermediate
4209 
4210 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4211 @*/
4212 PetscErrorCode MatSolverPackageGet(const MatSolverPackage package,const MatType mtype,MatFactorType ftype,PetscBool *foundpackage,PetscBool *foundmtype,PetscErrorCode (**getfactor)(Mat,MatFactorType,Mat*))
4213 {
4214   PetscErrorCode                 ierr;
4215   MatSolverPackageHolder         next = MatSolverPackageHolders;
4216   PetscBool                      flg;
4217   MatSolverPackageForSpecifcType inext;
4218 
4219   PetscFunctionBegin;
4220   if (foundpackage) *foundpackage = PETSC_FALSE;
4221   if (foundmtype)   *foundmtype   = PETSC_FALSE;
4222   if (getfactor)    *getfactor    = NULL;
4223 
4224   if (package) {
4225     while (next) {
4226       ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr);
4227       if (flg) {
4228         if (foundpackage) *foundpackage = PETSC_TRUE;
4229         inext = next->handlers;
4230         while (inext) {
4231           ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4232           if (flg) {
4233             if (foundmtype) *foundmtype = PETSC_TRUE;
4234             if (getfactor)  *getfactor  = inext->getfactor[(int)ftype-1];
4235             PetscFunctionReturn(0);
4236           }
4237           inext = inext->next;
4238         }
4239       }
4240       next = next->next;
4241     }
4242   } else {
4243     while (next) {
4244       inext = next->handlers;
4245       while (inext) {
4246         ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4247         if (flg && inext->getfactor[(int)ftype-1]) {
4248           if (foundpackage) *foundpackage = PETSC_TRUE;
4249           if (foundmtype)   *foundmtype   = PETSC_TRUE;
4250           if (getfactor)    *getfactor    = inext->getfactor[(int)ftype-1];
4251           PetscFunctionReturn(0);
4252         }
4253         inext = inext->next;
4254       }
4255       next = next->next;
4256     }
4257   }
4258   PetscFunctionReturn(0);
4259 }
4260 
4261 PetscErrorCode MatSolverPackageDestroy(void)
4262 {
4263   PetscErrorCode                 ierr;
4264   MatSolverPackageHolder         next = MatSolverPackageHolders,prev;
4265   MatSolverPackageForSpecifcType inext,iprev;
4266 
4267   PetscFunctionBegin;
4268   while (next) {
4269     ierr = PetscFree(next->name);CHKERRQ(ierr);
4270     inext = next->handlers;
4271     while (inext) {
4272       ierr = PetscFree(inext->mtype);CHKERRQ(ierr);
4273       iprev = inext;
4274       inext = inext->next;
4275       ierr = PetscFree(iprev);CHKERRQ(ierr);
4276     }
4277     prev = next;
4278     next = next->next;
4279     ierr = PetscFree(prev);CHKERRQ(ierr);
4280   }
4281   MatSolverPackageHolders = NULL;
4282   PetscFunctionReturn(0);
4283 }
4284 
4285 /*@C
4286    MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic()
4287 
4288    Collective on Mat
4289 
4290    Input Parameters:
4291 +  mat - the matrix
4292 .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4293 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4294 
4295    Output Parameters:
4296 .  f - the factor matrix used with MatXXFactorSymbolic() calls
4297 
4298    Notes:
4299       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4300      such as pastix, superlu, mumps etc.
4301 
4302       PETSc must have been ./configure to use the external solver, using the option --download-package
4303 
4304    Level: intermediate
4305 
4306 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4307 @*/
4308 PetscErrorCode MatGetFactor(Mat mat, const MatSolverPackage type,MatFactorType ftype,Mat *f)
4309 {
4310   PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
4311   PetscBool      foundpackage,foundmtype;
4312 
4313   PetscFunctionBegin;
4314   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4315   PetscValidType(mat,1);
4316 
4317   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4318   MatCheckPreallocated(mat,1);
4319 
4320   ierr = MatSolverPackageGet(type,((PetscObject)mat)->type_name,ftype,&foundpackage,&foundmtype,&conv);CHKERRQ(ierr);
4321   if (!foundpackage) {
4322     if (type) {
4323       SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver package %s. Perhaps you must ./configure with --download-%s",type,type);
4324     } else {
4325       SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate a solver package. Perhaps you must ./configure with --download-<package>");
4326     }
4327   }
4328 
4329   if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverPackage %s does not support matrix type %s",type,((PetscObject)mat)->type_name);
4330   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);
4331 
4332 #if defined(PETSC_USE_COMPLEX)
4333   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");
4334 #endif
4335 
4336   ierr = (*conv)(mat,ftype,f);CHKERRQ(ierr);
4337   PetscFunctionReturn(0);
4338 }
4339 
4340 /*@C
4341    MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type
4342 
4343    Not Collective
4344 
4345    Input Parameters:
4346 +  mat - the matrix
4347 .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4348 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4349 
4350    Output Parameter:
4351 .    flg - PETSC_TRUE if the factorization is available
4352 
4353    Notes:
4354       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4355      such as pastix, superlu, mumps etc.
4356 
4357       PETSc must have been ./configure to use the external solver, using the option --download-package
4358 
4359    Level: intermediate
4360 
4361 .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
4362 @*/
4363 PetscErrorCode MatGetFactorAvailable(Mat mat, const MatSolverPackage type,MatFactorType ftype,PetscBool  *flg)
4364 {
4365   PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*);
4366 
4367   PetscFunctionBegin;
4368   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4369   PetscValidType(mat,1);
4370 
4371   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4372   MatCheckPreallocated(mat,1);
4373 
4374   *flg = PETSC_FALSE;
4375   ierr = MatSolverPackageGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);CHKERRQ(ierr);
4376   if (gconv) {
4377     *flg = PETSC_TRUE;
4378   }
4379   PetscFunctionReturn(0);
4380 }
4381 
4382 #include <petscdmtypes.h>
4383 
4384 /*@
4385    MatDuplicate - Duplicates a matrix including the non-zero structure.
4386 
4387    Collective on Mat
4388 
4389    Input Parameters:
4390 +  mat - the matrix
4391 -  op - One of MAT_DO_NOT_COPY_VALUES, MAT_COPY_VALUES, or MAT_SHARE_NONZERO_PATTERN.
4392         See the manual page for MatDuplicateOption for an explanation of these options.
4393 
4394    Output Parameter:
4395 .  M - pointer to place new matrix
4396 
4397    Level: intermediate
4398 
4399    Concepts: matrices^duplicating
4400 
4401    Notes: You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN.
4402 
4403 .seealso: MatCopy(), MatConvert(), MatDuplicateOption
4404 @*/
4405 PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4406 {
4407   PetscErrorCode ierr;
4408   Mat            B;
4409   PetscInt       i;
4410   DM             dm;
4411 
4412   PetscFunctionBegin;
4413   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4414   PetscValidType(mat,1);
4415   PetscValidPointer(M,3);
4416   if (op == MAT_COPY_VALUES && !mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MAT_COPY_VALUES not allowed for unassembled matrix");
4417   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4418   MatCheckPreallocated(mat,1);
4419 
4420   *M = 0;
4421   if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type");
4422   ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4423   ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr);
4424   B    = *M;
4425 
4426   B->stencil.dim = mat->stencil.dim;
4427   B->stencil.noc = mat->stencil.noc;
4428   for (i=0; i<=mat->stencil.dim; i++) {
4429     B->stencil.dims[i]   = mat->stencil.dims[i];
4430     B->stencil.starts[i] = mat->stencil.starts[i];
4431   }
4432 
4433   B->nooffproczerorows = mat->nooffproczerorows;
4434   B->nooffprocentries  = mat->nooffprocentries;
4435 
4436   ierr = PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);CHKERRQ(ierr);
4437   if (dm) {
4438     ierr = PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr);
4439   }
4440   ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4441   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
4442   PetscFunctionReturn(0);
4443 }
4444 
4445 /*@
4446    MatGetDiagonal - Gets the diagonal of a matrix.
4447 
4448    Logically Collective on Mat and Vec
4449 
4450    Input Parameters:
4451 +  mat - the matrix
4452 -  v - the vector for storing the diagonal
4453 
4454    Output Parameter:
4455 .  v - the diagonal of the matrix
4456 
4457    Level: intermediate
4458 
4459    Note:
4460    Currently only correct in parallel for square matrices.
4461 
4462    Concepts: matrices^accessing diagonals
4463 
4464 .seealso: MatGetRow(), MatCreateSubMatrices(), MatCreateSubmatrix(), MatGetRowMaxAbs()
4465 @*/
4466 PetscErrorCode MatGetDiagonal(Mat mat,Vec v)
4467 {
4468   PetscErrorCode ierr;
4469 
4470   PetscFunctionBegin;
4471   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4472   PetscValidType(mat,1);
4473   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4474   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4475   if (!mat->ops->getdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4476   MatCheckPreallocated(mat,1);
4477 
4478   ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr);
4479   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4480   PetscFunctionReturn(0);
4481 }
4482 
4483 /*@C
4484    MatGetRowMin - Gets the minimum value (of the real part) of each
4485         row of the matrix
4486 
4487    Logically Collective on Mat and Vec
4488 
4489    Input Parameters:
4490 .  mat - the matrix
4491 
4492    Output Parameter:
4493 +  v - the vector for storing the maximums
4494 -  idx - the indices of the column found for each row (optional)
4495 
4496    Level: intermediate
4497 
4498    Notes: The result of this call are the same as if one converted the matrix to dense format
4499       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4500 
4501     This code is only implemented for a couple of matrix formats.
4502 
4503    Concepts: matrices^getting row maximums
4504 
4505 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubmatrix(), MatGetRowMaxAbs(),
4506           MatGetRowMax()
4507 @*/
4508 PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4509 {
4510   PetscErrorCode ierr;
4511 
4512   PetscFunctionBegin;
4513   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4514   PetscValidType(mat,1);
4515   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4516   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4517   if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4518   MatCheckPreallocated(mat,1);
4519 
4520   ierr = (*mat->ops->getrowmin)(mat,v,idx);CHKERRQ(ierr);
4521   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4522   PetscFunctionReturn(0);
4523 }
4524 
4525 /*@C
4526    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4527         row of the matrix
4528 
4529    Logically Collective on Mat and Vec
4530 
4531    Input Parameters:
4532 .  mat - the matrix
4533 
4534    Output Parameter:
4535 +  v - the vector for storing the minimums
4536 -  idx - the indices of the column found for each row (or NULL if not needed)
4537 
4538    Level: intermediate
4539 
4540    Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
4541     row is 0 (the first column).
4542 
4543     This code is only implemented for a couple of matrix formats.
4544 
4545    Concepts: matrices^getting row maximums
4546 
4547 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubmatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4548 @*/
4549 PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4550 {
4551   PetscErrorCode ierr;
4552 
4553   PetscFunctionBegin;
4554   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4555   PetscValidType(mat,1);
4556   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4557   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4558   if (!mat->ops->getrowminabs) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4559   MatCheckPreallocated(mat,1);
4560   if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);}
4561 
4562   ierr = (*mat->ops->getrowminabs)(mat,v,idx);CHKERRQ(ierr);
4563   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4564   PetscFunctionReturn(0);
4565 }
4566 
4567 /*@C
4568    MatGetRowMax - Gets the maximum value (of the real part) of each
4569         row of the matrix
4570 
4571    Logically Collective on Mat and Vec
4572 
4573    Input Parameters:
4574 .  mat - the matrix
4575 
4576    Output Parameter:
4577 +  v - the vector for storing the maximums
4578 -  idx - the indices of the column found for each row (optional)
4579 
4580    Level: intermediate
4581 
4582    Notes: The result of this call are the same as if one converted the matrix to dense format
4583       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4584 
4585     This code is only implemented for a couple of matrix formats.
4586 
4587    Concepts: matrices^getting row maximums
4588 
4589 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubmatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4590 @*/
4591 PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4592 {
4593   PetscErrorCode ierr;
4594 
4595   PetscFunctionBegin;
4596   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4597   PetscValidType(mat,1);
4598   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4599   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4600   if (!mat->ops->getrowmax) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4601   MatCheckPreallocated(mat,1);
4602 
4603   ierr = (*mat->ops->getrowmax)(mat,v,idx);CHKERRQ(ierr);
4604   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4605   PetscFunctionReturn(0);
4606 }
4607 
4608 /*@C
4609    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4610         row of the matrix
4611 
4612    Logically Collective on Mat and Vec
4613 
4614    Input Parameters:
4615 .  mat - the matrix
4616 
4617    Output Parameter:
4618 +  v - the vector for storing the maximums
4619 -  idx - the indices of the column found for each row (or NULL if not needed)
4620 
4621    Level: intermediate
4622 
4623    Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
4624     row is 0 (the first column).
4625 
4626     This code is only implemented for a couple of matrix formats.
4627 
4628    Concepts: matrices^getting row maximums
4629 
4630 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubmatrix(), MatGetRowMax(), MatGetRowMin()
4631 @*/
4632 PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4633 {
4634   PetscErrorCode ierr;
4635 
4636   PetscFunctionBegin;
4637   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4638   PetscValidType(mat,1);
4639   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4640   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4641   if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4642   MatCheckPreallocated(mat,1);
4643   if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);}
4644 
4645   ierr = (*mat->ops->getrowmaxabs)(mat,v,idx);CHKERRQ(ierr);
4646   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4647   PetscFunctionReturn(0);
4648 }
4649 
4650 /*@
4651    MatGetRowSum - Gets the sum of each row of the matrix
4652 
4653    Logically or Neighborhood Collective on Mat and Vec
4654 
4655    Input Parameters:
4656 .  mat - the matrix
4657 
4658    Output Parameter:
4659 .  v - the vector for storing the sum of rows
4660 
4661    Level: intermediate
4662 
4663    Notes: This code is slow since it is not currently specialized for different formats
4664 
4665    Concepts: matrices^getting row sums
4666 
4667 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubmatrix(), MatGetRowMax(), MatGetRowMin()
4668 @*/
4669 PetscErrorCode MatGetRowSum(Mat mat, Vec v)
4670 {
4671   Vec            ones;
4672   PetscErrorCode ierr;
4673 
4674   PetscFunctionBegin;
4675   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4676   PetscValidType(mat,1);
4677   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4678   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4679   MatCheckPreallocated(mat,1);
4680   ierr = MatCreateVecs(mat,NULL,&ones);CHKERRQ(ierr);
4681   ierr = VecSet(ones,1.);CHKERRQ(ierr);
4682   ierr = MatMult(mat,ones,v);CHKERRQ(ierr);
4683   ierr = VecDestroy(&ones);CHKERRQ(ierr);
4684   PetscFunctionReturn(0);
4685 }
4686 
4687 /*@
4688    MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
4689 
4690    Collective on Mat
4691 
4692    Input Parameter:
4693 +  mat - the matrix to transpose
4694 -  reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX
4695 
4696    Output Parameters:
4697 .  B - the transpose
4698 
4699    Notes:
4700      If you use MAT_INPLACE_MATRIX then you must pass in &mat for B
4701 
4702      MAT_REUSE_MATRIX causes the B matrix from a previous call to this function with MAT_INITIAL_MATRIX to be used
4703 
4704      Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed.
4705 
4706    Level: intermediate
4707 
4708    Concepts: matrices^transposing
4709 
4710 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4711 @*/
4712 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4713 {
4714   PetscErrorCode ierr;
4715 
4716   PetscFunctionBegin;
4717   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4718   PetscValidType(mat,1);
4719   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4720   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4721   if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4722   if (reuse == MAT_INPLACE_MATRIX && mat != *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires last matrix to match first");
4723   if (reuse == MAT_REUSE_MATRIX && mat == *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Perhaps you mean MAT_INPLACE_MATRIX");
4724   MatCheckPreallocated(mat,1);
4725 
4726   ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4727   ierr = (*mat->ops->transpose)(mat,reuse,B);CHKERRQ(ierr);
4728   ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4729   if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);}
4730   PetscFunctionReturn(0);
4731 }
4732 
4733 /*@
4734    MatIsTranspose - Test whether a matrix is another one's transpose,
4735         or its own, in which case it tests symmetry.
4736 
4737    Collective on Mat
4738 
4739    Input Parameter:
4740 +  A - the matrix to test
4741 -  B - the matrix to test against, this can equal the first parameter
4742 
4743    Output Parameters:
4744 .  flg - the result
4745 
4746    Notes:
4747    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4748    has a running time of the order of the number of nonzeros; the parallel
4749    test involves parallel copies of the block-offdiagonal parts of the matrix.
4750 
4751    Level: intermediate
4752 
4753    Concepts: matrices^transposing, matrix^symmetry
4754 
4755 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4756 @*/
4757 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4758 {
4759   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4760 
4761   PetscFunctionBegin;
4762   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4763   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4764   PetscValidPointer(flg,3);
4765   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);CHKERRQ(ierr);
4766   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);CHKERRQ(ierr);
4767   *flg = PETSC_FALSE;
4768   if (f && g) {
4769     if (f == g) {
4770       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
4771     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4772   } else {
4773     MatType mattype;
4774     if (!f) {
4775       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
4776     } else {
4777       ierr = MatGetType(B,&mattype);CHKERRQ(ierr);
4778     }
4779     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
4780   }
4781   PetscFunctionReturn(0);
4782 }
4783 
4784 /*@
4785    MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate.
4786 
4787    Collective on Mat
4788 
4789    Input Parameter:
4790 +  mat - the matrix to transpose and complex conjugate
4791 -  reuse - MAT_INITIAL_MATRIX to create a new matrix, MAT_INPLACE_MATRIX to reuse the first argument to store the transpose
4792 
4793    Output Parameters:
4794 .  B - the Hermitian
4795 
4796    Level: intermediate
4797 
4798    Concepts: matrices^transposing, complex conjugatex
4799 
4800 .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4801 @*/
4802 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
4803 {
4804   PetscErrorCode ierr;
4805 
4806   PetscFunctionBegin;
4807   ierr = MatTranspose(mat,reuse,B);CHKERRQ(ierr);
4808 #if defined(PETSC_USE_COMPLEX)
4809   ierr = MatConjugate(*B);CHKERRQ(ierr);
4810 #endif
4811   PetscFunctionReturn(0);
4812 }
4813 
4814 /*@
4815    MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,
4816 
4817    Collective on Mat
4818 
4819    Input Parameter:
4820 +  A - the matrix to test
4821 -  B - the matrix to test against, this can equal the first parameter
4822 
4823    Output Parameters:
4824 .  flg - the result
4825 
4826    Notes:
4827    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4828    has a running time of the order of the number of nonzeros; the parallel
4829    test involves parallel copies of the block-offdiagonal parts of the matrix.
4830 
4831    Level: intermediate
4832 
4833    Concepts: matrices^transposing, matrix^symmetry
4834 
4835 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
4836 @*/
4837 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4838 {
4839   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4840 
4841   PetscFunctionBegin;
4842   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4843   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4844   PetscValidPointer(flg,3);
4845   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);CHKERRQ(ierr);
4846   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);CHKERRQ(ierr);
4847   if (f && g) {
4848     if (f==g) {
4849       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
4850     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
4851   }
4852   PetscFunctionReturn(0);
4853 }
4854 
4855 /*@
4856    MatPermute - Creates a new matrix with rows and columns permuted from the
4857    original.
4858 
4859    Collective on Mat
4860 
4861    Input Parameters:
4862 +  mat - the matrix to permute
4863 .  row - row permutation, each processor supplies only the permutation for its rows
4864 -  col - column permutation, each processor supplies only the permutation for its columns
4865 
4866    Output Parameters:
4867 .  B - the permuted matrix
4868 
4869    Level: advanced
4870 
4871    Note:
4872    The index sets map from row/col of permuted matrix to row/col of original matrix.
4873    The index sets should be on the same communicator as Mat and have the same local sizes.
4874 
4875    Concepts: matrices^permuting
4876 
4877 .seealso: MatGetOrdering(), ISAllGather()
4878 
4879 @*/
4880 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
4881 {
4882   PetscErrorCode ierr;
4883 
4884   PetscFunctionBegin;
4885   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4886   PetscValidType(mat,1);
4887   PetscValidHeaderSpecific(row,IS_CLASSID,2);
4888   PetscValidHeaderSpecific(col,IS_CLASSID,3);
4889   PetscValidPointer(B,4);
4890   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4891   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4892   if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
4893   MatCheckPreallocated(mat,1);
4894 
4895   ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr);
4896   ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);
4897   PetscFunctionReturn(0);
4898 }
4899 
4900 /*@
4901    MatEqual - Compares two matrices.
4902 
4903    Collective on Mat
4904 
4905    Input Parameters:
4906 +  A - the first matrix
4907 -  B - the second matrix
4908 
4909    Output Parameter:
4910 .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
4911 
4912    Level: intermediate
4913 
4914    Concepts: matrices^equality between
4915 @*/
4916 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool  *flg)
4917 {
4918   PetscErrorCode ierr;
4919 
4920   PetscFunctionBegin;
4921   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4922   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4923   PetscValidType(A,1);
4924   PetscValidType(B,2);
4925   PetscValidIntPointer(flg,3);
4926   PetscCheckSameComm(A,1,B,2);
4927   MatCheckPreallocated(B,2);
4928   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4929   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4930   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);
4931   if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4932   if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4933   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);
4934   MatCheckPreallocated(A,1);
4935 
4936   ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr);
4937   PetscFunctionReturn(0);
4938 }
4939 
4940 /*@C
4941    MatDiagonalScale - Scales a matrix on the left and right by diagonal
4942    matrices that are stored as vectors.  Either of the two scaling
4943    matrices can be NULL.
4944 
4945    Collective on Mat
4946 
4947    Input Parameters:
4948 +  mat - the matrix to be scaled
4949 .  l - the left scaling vector (or NULL)
4950 -  r - the right scaling vector (or NULL)
4951 
4952    Notes:
4953    MatDiagonalScale() computes A = LAR, where
4954    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
4955    The L scales the rows of the matrix, the R scales the columns of the matrix.
4956 
4957    Level: intermediate
4958 
4959    Concepts: matrices^diagonal scaling
4960    Concepts: diagonal scaling of matrices
4961 
4962 .seealso: MatScale()
4963 @*/
4964 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
4965 {
4966   PetscErrorCode ierr;
4967 
4968   PetscFunctionBegin;
4969   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4970   PetscValidType(mat,1);
4971   if (!mat->ops->diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4972   if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);}
4973   if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);}
4974   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4975   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4976   MatCheckPreallocated(mat,1);
4977 
4978   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4979   ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr);
4980   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4981   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4982 #if defined(PETSC_HAVE_CUSP)
4983   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4984     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4985   }
4986 #elif defined(PETSC_HAVE_VIENNACL)
4987   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
4988     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
4989   }
4990 #elif defined(PETSC_HAVE_VECCUDA)
4991   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
4992     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
4993   }
4994 #endif
4995   PetscFunctionReturn(0);
4996 }
4997 
4998 /*@
4999     MatScale - Scales all elements of a matrix by a given number.
5000 
5001     Logically Collective on Mat
5002 
5003     Input Parameters:
5004 +   mat - the matrix to be scaled
5005 -   a  - the scaling value
5006 
5007     Output Parameter:
5008 .   mat - the scaled matrix
5009 
5010     Level: intermediate
5011 
5012     Concepts: matrices^scaling all entries
5013 
5014 .seealso: MatDiagonalScale()
5015 @*/
5016 PetscErrorCode MatScale(Mat mat,PetscScalar a)
5017 {
5018   PetscErrorCode ierr;
5019 
5020   PetscFunctionBegin;
5021   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5022   PetscValidType(mat,1);
5023   if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5024   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5025   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5026   PetscValidLogicalCollectiveScalar(mat,a,2);
5027   MatCheckPreallocated(mat,1);
5028 
5029   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5030   if (a != (PetscScalar)1.0) {
5031     ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr);
5032     ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5033 #if defined(PETSC_HAVE_CUSP)
5034     if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5035       mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5036     }
5037 #elif defined(PETSC_HAVE_VIENNACL)
5038     if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5039       mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5040     }
5041 #elif defined(PETSC_HAVE_VECCUDA)
5042     if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5043       mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5044     }
5045 #endif
5046   }
5047   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5048   PetscFunctionReturn(0);
5049 }
5050 
5051 /*@
5052    MatNorm - Calculates various norms of a matrix.
5053 
5054    Collective on Mat
5055 
5056    Input Parameters:
5057 +  mat - the matrix
5058 -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
5059 
5060    Output Parameters:
5061 .  nrm - the resulting norm
5062 
5063    Level: intermediate
5064 
5065    Concepts: matrices^norm
5066    Concepts: norm^of matrix
5067 @*/
5068 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
5069 {
5070   PetscErrorCode ierr;
5071 
5072   PetscFunctionBegin;
5073   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5074   PetscValidType(mat,1);
5075   PetscValidScalarPointer(nrm,3);
5076 
5077   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5078   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5079   if (!mat->ops->norm) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5080   MatCheckPreallocated(mat,1);
5081 
5082   ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr);
5083   PetscFunctionReturn(0);
5084 }
5085 
5086 /*
5087      This variable is used to prevent counting of MatAssemblyBegin() that
5088    are called from within a MatAssemblyEnd().
5089 */
5090 static PetscInt MatAssemblyEnd_InUse = 0;
5091 /*@
5092    MatAssemblyBegin - Begins assembling the matrix.  This routine should
5093    be called after completing all calls to MatSetValues().
5094 
5095    Collective on Mat
5096 
5097    Input Parameters:
5098 +  mat - the matrix
5099 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5100 
5101    Notes:
5102    MatSetValues() generally caches the values.  The matrix is ready to
5103    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5104    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5105    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5106    using the matrix.
5107 
5108    ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the
5109    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
5110    a global collective operation requring all processes that share the matrix.
5111 
5112    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5113    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5114    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5115 
5116    Level: beginner
5117 
5118    Concepts: matrices^assembling
5119 
5120 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
5121 @*/
5122 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
5123 {
5124   PetscErrorCode ierr;
5125 
5126   PetscFunctionBegin;
5127   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5128   PetscValidType(mat,1);
5129   MatCheckPreallocated(mat,1);
5130   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
5131   if (mat->assembled) {
5132     mat->was_assembled = PETSC_TRUE;
5133     mat->assembled     = PETSC_FALSE;
5134   }
5135   if (!MatAssemblyEnd_InUse) {
5136     ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5137     if (mat->ops->assemblybegin) {ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
5138     ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5139   } else if (mat->ops->assemblybegin) {
5140     ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);
5141   }
5142   PetscFunctionReturn(0);
5143 }
5144 
5145 /*@
5146    MatAssembled - Indicates if a matrix has been assembled and is ready for
5147      use; for example, in matrix-vector product.
5148 
5149    Not Collective
5150 
5151    Input Parameter:
5152 .  mat - the matrix
5153 
5154    Output Parameter:
5155 .  assembled - PETSC_TRUE or PETSC_FALSE
5156 
5157    Level: advanced
5158 
5159    Concepts: matrices^assembled?
5160 
5161 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
5162 @*/
5163 PetscErrorCode MatAssembled(Mat mat,PetscBool  *assembled)
5164 {
5165   PetscFunctionBegin;
5166   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5167   PetscValidType(mat,1);
5168   PetscValidPointer(assembled,2);
5169   *assembled = mat->assembled;
5170   PetscFunctionReturn(0);
5171 }
5172 
5173 /*@
5174    MatAssemblyEnd - Completes assembling the matrix.  This routine should
5175    be called after MatAssemblyBegin().
5176 
5177    Collective on Mat
5178 
5179    Input Parameters:
5180 +  mat - the matrix
5181 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5182 
5183    Options Database Keys:
5184 +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
5185 .  -mat_view ::ascii_info_detail - Prints more detailed info
5186 .  -mat_view - Prints matrix in ASCII format
5187 .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
5188 .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
5189 .  -display <name> - Sets display name (default is host)
5190 .  -draw_pause <sec> - Sets number of seconds to pause after display
5191 .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab )
5192 .  -viewer_socket_machine <machine> - Machine to use for socket
5193 .  -viewer_socket_port <port> - Port number to use for socket
5194 -  -mat_view binary:filename[:append] - Save matrix to file in binary format
5195 
5196    Notes:
5197    MatSetValues() generally caches the values.  The matrix is ready to
5198    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5199    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5200    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5201    using the matrix.
5202 
5203    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5204    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5205    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5206 
5207    Level: beginner
5208 
5209 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
5210 @*/
5211 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
5212 {
5213   PetscErrorCode  ierr;
5214   static PetscInt inassm = 0;
5215   PetscBool       flg    = PETSC_FALSE;
5216 
5217   PetscFunctionBegin;
5218   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5219   PetscValidType(mat,1);
5220 
5221   inassm++;
5222   MatAssemblyEnd_InUse++;
5223   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
5224     ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5225     if (mat->ops->assemblyend) {
5226       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5227     }
5228     ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5229   } else if (mat->ops->assemblyend) {
5230     ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5231   }
5232 
5233   /* Flush assembly is not a true assembly */
5234   if (type != MAT_FLUSH_ASSEMBLY) {
5235     mat->assembled = PETSC_TRUE; mat->num_ass++;
5236   }
5237   mat->insertmode = NOT_SET_VALUES;
5238   MatAssemblyEnd_InUse--;
5239   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5240   if (!mat->symmetric_eternal) {
5241     mat->symmetric_set              = PETSC_FALSE;
5242     mat->hermitian_set              = PETSC_FALSE;
5243     mat->structurally_symmetric_set = PETSC_FALSE;
5244   }
5245 #if defined(PETSC_HAVE_CUSP)
5246   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5247     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5248   }
5249 #elif defined(PETSC_HAVE_VIENNACL)
5250   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5251     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5252   }
5253 #elif defined(PETSC_HAVE_VECCUDA)
5254   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5255     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5256   }
5257 #endif
5258   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
5259     ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5260 
5261     if (mat->checksymmetryonassembly) {
5262       ierr = MatIsSymmetric(mat,mat->checksymmetrytol,&flg);CHKERRQ(ierr);
5263       if (flg) {
5264         ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5265       } else {
5266         ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5267       }
5268     }
5269     if (mat->nullsp && mat->checknullspaceonassembly) {
5270       ierr = MatNullSpaceTest(mat->nullsp,mat,NULL);CHKERRQ(ierr);
5271     }
5272   }
5273   inassm--;
5274   PetscFunctionReturn(0);
5275 }
5276 
5277 /*@
5278    MatSetOption - Sets a parameter option for a matrix. Some options
5279    may be specific to certain storage formats.  Some options
5280    determine how values will be inserted (or added). Sorted,
5281    row-oriented input will generally assemble the fastest. The default
5282    is row-oriented.
5283 
5284    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5285 
5286    Input Parameters:
5287 +  mat - the matrix
5288 .  option - the option, one of those listed below (and possibly others),
5289 -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5290 
5291   Options Describing Matrix Structure:
5292 +    MAT_SPD - symmetric positive definite
5293 .    MAT_SYMMETRIC - symmetric in terms of both structure and value
5294 .    MAT_HERMITIAN - transpose is the complex conjugation
5295 .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5296 -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5297                             you set to be kept with all future use of the matrix
5298                             including after MatAssemblyBegin/End() which could
5299                             potentially change the symmetry structure, i.e. you
5300                             KNOW the matrix will ALWAYS have the property you set.
5301 
5302 
5303    Options For Use with MatSetValues():
5304    Insert a logically dense subblock, which can be
5305 .    MAT_ROW_ORIENTED - row-oriented (default)
5306 
5307    Note these options reflect the data you pass in with MatSetValues(); it has
5308    nothing to do with how the data is stored internally in the matrix
5309    data structure.
5310 
5311    When (re)assembling a matrix, we can restrict the input for
5312    efficiency/debugging purposes.  These options include:
5313 +    MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow)
5314 .    MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
5315 .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
5316 .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
5317 .    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
5318 .    MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
5319         any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
5320         performance for very large process counts.
5321 -    MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset
5322         of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly
5323         functions, instead sending only neighbor messages.
5324 
5325    Notes:
5326    Except for MAT_UNUSED_NONZERO_LOCATION_ERR and  MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg!
5327 
5328    Some options are relevant only for particular matrix types and
5329    are thus ignored by others.  Other options are not supported by
5330    certain matrix types and will generate an error message if set.
5331 
5332    If using a Fortran 77 module to compute a matrix, one may need to
5333    use the column-oriented option (or convert to the row-oriented
5334    format).
5335 
5336    MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
5337    that would generate a new entry in the nonzero structure is instead
5338    ignored.  Thus, if memory has not alredy been allocated for this particular
5339    data, then the insertion is ignored. For dense matrices, in which
5340    the entire array is allocated, no entries are ever ignored.
5341    Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5342 
5343    MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5344    that would generate a new entry in the nonzero structure instead produces
5345    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
5346 
5347    MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5348    that would generate a new entry that has not been preallocated will
5349    instead produce an error. (Currently supported for AIJ and BAIJ formats
5350    only.) This is a useful flag when debugging matrix memory preallocation.
5351    If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5352 
5353    MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for
5354    other processors should be dropped, rather than stashed.
5355    This is useful if you know that the "owning" processor is also
5356    always generating the correct matrix entries, so that PETSc need
5357    not transfer duplicate entries generated on another processor.
5358 
5359    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5360    searches during matrix assembly. When this flag is set, the hash table
5361    is created during the first Matrix Assembly. This hash table is
5362    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5363    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5364    should be used with MAT_USE_HASH_TABLE flag. This option is currently
5365    supported by MATMPIBAIJ format only.
5366 
5367    MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries
5368    are kept in the nonzero structure
5369 
5370    MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
5371    a zero location in the matrix
5372 
5373    MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types
5374 
5375    MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the
5376         zero row routines and thus improves performance for very large process counts.
5377 
5378    MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular
5379         part of the matrix (since they should match the upper triangular part).
5380 
5381    Notes: Can only be called after MatSetSizes() and MatSetType() have been set.
5382 
5383    Level: intermediate
5384 
5385    Concepts: matrices^setting options
5386 
5387 .seealso:  MatOption, Mat
5388 
5389 @*/
5390 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg)
5391 {
5392   PetscErrorCode ierr;
5393 
5394   PetscFunctionBegin;
5395   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5396   PetscValidType(mat,1);
5397   if (op > 0) {
5398     PetscValidLogicalCollectiveEnum(mat,op,2);
5399     PetscValidLogicalCollectiveBool(mat,flg,3);
5400   }
5401 
5402   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);
5403   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()");
5404 
5405   switch (op) {
5406   case MAT_NO_OFF_PROC_ENTRIES:
5407     mat->nooffprocentries = flg;
5408     PetscFunctionReturn(0);
5409     break;
5410   case MAT_SUBSET_OFF_PROC_ENTRIES:
5411     mat->subsetoffprocentries = flg;
5412     PetscFunctionReturn(0);
5413   case MAT_NO_OFF_PROC_ZERO_ROWS:
5414     mat->nooffproczerorows = flg;
5415     PetscFunctionReturn(0);
5416     break;
5417   case MAT_SPD:
5418     mat->spd_set = PETSC_TRUE;
5419     mat->spd     = flg;
5420     if (flg) {
5421       mat->symmetric                  = PETSC_TRUE;
5422       mat->structurally_symmetric     = PETSC_TRUE;
5423       mat->symmetric_set              = PETSC_TRUE;
5424       mat->structurally_symmetric_set = PETSC_TRUE;
5425     }
5426     break;
5427   case MAT_SYMMETRIC:
5428     mat->symmetric = flg;
5429     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5430     mat->symmetric_set              = PETSC_TRUE;
5431     mat->structurally_symmetric_set = flg;
5432 #if !defined(PETSC_USE_COMPLEX)
5433     mat->hermitian     = flg;
5434     mat->hermitian_set = PETSC_TRUE;
5435 #endif
5436     break;
5437   case MAT_HERMITIAN:
5438     mat->hermitian = flg;
5439     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5440     mat->hermitian_set              = PETSC_TRUE;
5441     mat->structurally_symmetric_set = flg;
5442 #if !defined(PETSC_USE_COMPLEX)
5443     mat->symmetric     = flg;
5444     mat->symmetric_set = PETSC_TRUE;
5445 #endif
5446     break;
5447   case MAT_STRUCTURALLY_SYMMETRIC:
5448     mat->structurally_symmetric     = flg;
5449     mat->structurally_symmetric_set = PETSC_TRUE;
5450     break;
5451   case MAT_SYMMETRY_ETERNAL:
5452     mat->symmetric_eternal = flg;
5453     break;
5454   case MAT_STRUCTURE_ONLY:
5455     mat->structure_only = flg;
5456     break;
5457   default:
5458     break;
5459   }
5460   if (mat->ops->setoption) {
5461     ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr);
5462   }
5463   PetscFunctionReturn(0);
5464 }
5465 
5466 /*@
5467    MatGetOption - Gets a parameter option that has been set for a matrix.
5468 
5469    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5470 
5471    Input Parameters:
5472 +  mat - the matrix
5473 -  option - the option, this only responds to certain options, check the code for which ones
5474 
5475    Output Parameter:
5476 .  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5477 
5478     Notes: Can only be called after MatSetSizes() and MatSetType() have been set.
5479 
5480    Level: intermediate
5481 
5482    Concepts: matrices^setting options
5483 
5484 .seealso:  MatOption, MatSetOption()
5485 
5486 @*/
5487 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg)
5488 {
5489   PetscFunctionBegin;
5490   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5491   PetscValidType(mat,1);
5492 
5493   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);
5494   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()");
5495 
5496   switch (op) {
5497   case MAT_NO_OFF_PROC_ENTRIES:
5498     *flg = mat->nooffprocentries;
5499     break;
5500   case MAT_NO_OFF_PROC_ZERO_ROWS:
5501     *flg = mat->nooffproczerorows;
5502     break;
5503   case MAT_SYMMETRIC:
5504     *flg = mat->symmetric;
5505     break;
5506   case MAT_HERMITIAN:
5507     *flg = mat->hermitian;
5508     break;
5509   case MAT_STRUCTURALLY_SYMMETRIC:
5510     *flg = mat->structurally_symmetric;
5511     break;
5512   case MAT_SYMMETRY_ETERNAL:
5513     *flg = mat->symmetric_eternal;
5514     break;
5515   case MAT_SPD:
5516     *flg = mat->spd;
5517     break;
5518   default:
5519     break;
5520   }
5521   PetscFunctionReturn(0);
5522 }
5523 
5524 /*@
5525    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5526    this routine retains the old nonzero structure.
5527 
5528    Logically Collective on Mat
5529 
5530    Input Parameters:
5531 .  mat - the matrix
5532 
5533    Level: intermediate
5534 
5535    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.
5536    See the Performance chapter of the users manual for information on preallocating matrices.
5537 
5538    Concepts: matrices^zeroing
5539 
5540 .seealso: MatZeroRows()
5541 @*/
5542 PetscErrorCode MatZeroEntries(Mat mat)
5543 {
5544   PetscErrorCode ierr;
5545 
5546   PetscFunctionBegin;
5547   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5548   PetscValidType(mat,1);
5549   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5550   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");
5551   if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5552   MatCheckPreallocated(mat,1);
5553 
5554   ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5555   ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
5556   ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5557   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5558 #if defined(PETSC_HAVE_CUSP)
5559   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5560     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5561   }
5562 #elif defined(PETSC_HAVE_VIENNACL)
5563   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5564     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5565   }
5566 #elif defined(PETSC_HAVE_VECCUDA)
5567   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5568     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5569   }
5570 #endif
5571   PetscFunctionReturn(0);
5572 }
5573 
5574 /*@C
5575    MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal)
5576    of a set of rows and columns of a matrix.
5577 
5578    Collective on Mat
5579 
5580    Input Parameters:
5581 +  mat - the matrix
5582 .  numRows - the number of rows to remove
5583 .  rows - the global row indices
5584 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5585 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5586 -  b - optional vector of right hand side, that will be adjusted by provided solution
5587 
5588    Notes:
5589    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5590 
5591    The user can set a value in the diagonal entry (or for the AIJ and
5592    row formats can optionally remove the main diagonal entry from the
5593    nonzero structure as well, by passing 0.0 as the final argument).
5594 
5595    For the parallel case, all processes that share the matrix (i.e.,
5596    those in the communicator used for matrix creation) MUST call this
5597    routine, regardless of whether any rows being zeroed are owned by
5598    them.
5599 
5600    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5601    list only rows local to itself).
5602 
5603    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5604 
5605    Level: intermediate
5606 
5607    Concepts: matrices^zeroing rows
5608 
5609 .seealso: MatZeroRowsIS(), MatZeroRows(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5610           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5611 @*/
5612 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5613 {
5614   PetscErrorCode ierr;
5615 
5616   PetscFunctionBegin;
5617   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5618   PetscValidType(mat,1);
5619   if (numRows) PetscValidIntPointer(rows,3);
5620   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5621   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5622   if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5623   MatCheckPreallocated(mat,1);
5624 
5625   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5626   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5627   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5628 #if defined(PETSC_HAVE_CUSP)
5629   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5630     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5631   }
5632 #elif defined(PETSC_HAVE_VIENNACL)
5633   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5634     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5635   }
5636 #elif defined(PETSC_HAVE_VECCUDA)
5637   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5638     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5639   }
5640 #endif
5641   PetscFunctionReturn(0);
5642 }
5643 
5644 /*@C
5645    MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
5646    of a set of rows and columns of a matrix.
5647 
5648    Collective on Mat
5649 
5650    Input Parameters:
5651 +  mat - the matrix
5652 .  is - the rows to zero
5653 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5654 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5655 -  b - optional vector of right hand side, that will be adjusted by provided solution
5656 
5657    Notes:
5658    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5659 
5660    The user can set a value in the diagonal entry (or for the AIJ and
5661    row formats can optionally remove the main diagonal entry from the
5662    nonzero structure as well, by passing 0.0 as the final argument).
5663 
5664    For the parallel case, all processes that share the matrix (i.e.,
5665    those in the communicator used for matrix creation) MUST call this
5666    routine, regardless of whether any rows being zeroed are owned by
5667    them.
5668 
5669    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5670    list only rows local to itself).
5671 
5672    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5673 
5674    Level: intermediate
5675 
5676    Concepts: matrices^zeroing rows
5677 
5678 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5679           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRows(), MatZeroRowsColumnsStencil()
5680 @*/
5681 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5682 {
5683   PetscErrorCode ierr;
5684   PetscInt       numRows;
5685   const PetscInt *rows;
5686 
5687   PetscFunctionBegin;
5688   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5689   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5690   PetscValidType(mat,1);
5691   PetscValidType(is,2);
5692   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5693   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5694   ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5695   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5696   PetscFunctionReturn(0);
5697 }
5698 
5699 /*@C
5700    MatZeroRows - Zeros all entries (except possibly the main diagonal)
5701    of a set of rows of a matrix.
5702 
5703    Collective on Mat
5704 
5705    Input Parameters:
5706 +  mat - the matrix
5707 .  numRows - the number of rows to remove
5708 .  rows - the global row indices
5709 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5710 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5711 -  b - optional vector of right hand side, that will be adjusted by provided solution
5712 
5713    Notes:
5714    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5715    but does not release memory.  For the dense and block diagonal
5716    formats this does not alter the nonzero structure.
5717 
5718    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5719    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5720    merely zeroed.
5721 
5722    The user can set a value in the diagonal entry (or for the AIJ and
5723    row formats can optionally remove the main diagonal entry from the
5724    nonzero structure as well, by passing 0.0 as the final argument).
5725 
5726    For the parallel case, all processes that share the matrix (i.e.,
5727    those in the communicator used for matrix creation) MUST call this
5728    routine, regardless of whether any rows being zeroed are owned by
5729    them.
5730 
5731    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5732    list only rows local to itself).
5733 
5734    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5735    owns that are to be zeroed. This saves a global synchronization in the implementation.
5736 
5737    Level: intermediate
5738 
5739    Concepts: matrices^zeroing rows
5740 
5741 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5742           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5743 @*/
5744 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5745 {
5746   PetscErrorCode ierr;
5747 
5748   PetscFunctionBegin;
5749   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5750   PetscValidType(mat,1);
5751   if (numRows) PetscValidIntPointer(rows,3);
5752   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5753   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5754   if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5755   MatCheckPreallocated(mat,1);
5756 
5757   ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5758   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5759   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5760 #if defined(PETSC_HAVE_CUSP)
5761   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5762     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5763   }
5764 #elif defined(PETSC_HAVE_VIENNACL)
5765   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5766     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5767   }
5768 #elif defined(PETSC_HAVE_VECCUDA)
5769   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5770     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5771   }
5772 #endif
5773   PetscFunctionReturn(0);
5774 }
5775 
5776 /*@C
5777    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5778    of a set of rows of a matrix.
5779 
5780    Collective on Mat
5781 
5782    Input Parameters:
5783 +  mat - the matrix
5784 .  is - index set of rows to remove
5785 .  diag - value put in all diagonals of eliminated rows
5786 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5787 -  b - optional vector of right hand side, that will be adjusted by provided solution
5788 
5789    Notes:
5790    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5791    but does not release memory.  For the dense and block diagonal
5792    formats this does not alter the nonzero structure.
5793 
5794    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5795    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5796    merely zeroed.
5797 
5798    The user can set a value in the diagonal entry (or for the AIJ and
5799    row formats can optionally remove the main diagonal entry from the
5800    nonzero structure as well, by passing 0.0 as the final argument).
5801 
5802    For the parallel case, all processes that share the matrix (i.e.,
5803    those in the communicator used for matrix creation) MUST call this
5804    routine, regardless of whether any rows being zeroed are owned by
5805    them.
5806 
5807    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5808    list only rows local to itself).
5809 
5810    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5811    owns that are to be zeroed. This saves a global synchronization in the implementation.
5812 
5813    Level: intermediate
5814 
5815    Concepts: matrices^zeroing rows
5816 
5817 .seealso: MatZeroRows(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5818           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5819 @*/
5820 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5821 {
5822   PetscInt       numRows;
5823   const PetscInt *rows;
5824   PetscErrorCode ierr;
5825 
5826   PetscFunctionBegin;
5827   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5828   PetscValidType(mat,1);
5829   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5830   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5831   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5832   ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5833   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5834   PetscFunctionReturn(0);
5835 }
5836 
5837 /*@C
5838    MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
5839    of a set of rows of a matrix. These rows must be local to the process.
5840 
5841    Collective on Mat
5842 
5843    Input Parameters:
5844 +  mat - the matrix
5845 .  numRows - the number of rows to remove
5846 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
5847 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5848 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5849 -  b - optional vector of right hand side, that will be adjusted by provided solution
5850 
5851    Notes:
5852    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5853    but does not release memory.  For the dense and block diagonal
5854    formats this does not alter the nonzero structure.
5855 
5856    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5857    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5858    merely zeroed.
5859 
5860    The user can set a value in the diagonal entry (or for the AIJ and
5861    row formats can optionally remove the main diagonal entry from the
5862    nonzero structure as well, by passing 0.0 as the final argument).
5863 
5864    For the parallel case, all processes that share the matrix (i.e.,
5865    those in the communicator used for matrix creation) MUST call this
5866    routine, regardless of whether any rows being zeroed are owned by
5867    them.
5868 
5869    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5870    list only rows local to itself).
5871 
5872    The grid coordinates are across the entire grid, not just the local portion
5873 
5874    In Fortran idxm and idxn should be declared as
5875 $     MatStencil idxm(4,m)
5876    and the values inserted using
5877 $    idxm(MatStencil_i,1) = i
5878 $    idxm(MatStencil_j,1) = j
5879 $    idxm(MatStencil_k,1) = k
5880 $    idxm(MatStencil_c,1) = c
5881    etc
5882 
5883    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5884    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5885    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5886    DM_BOUNDARY_PERIODIC boundary type.
5887 
5888    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
5889    a single value per point) you can skip filling those indices.
5890 
5891    Level: intermediate
5892 
5893    Concepts: matrices^zeroing rows
5894 
5895 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsl(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5896           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5897 @*/
5898 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5899 {
5900   PetscInt       dim     = mat->stencil.dim;
5901   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
5902   PetscInt       *dims   = mat->stencil.dims+1;
5903   PetscInt       *starts = mat->stencil.starts;
5904   PetscInt       *dxm    = (PetscInt*) rows;
5905   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
5906   PetscErrorCode ierr;
5907 
5908   PetscFunctionBegin;
5909   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5910   PetscValidType(mat,1);
5911   if (numRows) PetscValidIntPointer(rows,3);
5912 
5913   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
5914   for (i = 0; i < numRows; ++i) {
5915     /* Skip unused dimensions (they are ordered k, j, i, c) */
5916     for (j = 0; j < 3-sdim; ++j) dxm++;
5917     /* Local index in X dir */
5918     tmp = *dxm++ - starts[0];
5919     /* Loop over remaining dimensions */
5920     for (j = 0; j < dim-1; ++j) {
5921       /* If nonlocal, set index to be negative */
5922       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5923       /* Update local index */
5924       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5925     }
5926     /* Skip component slot if necessary */
5927     if (mat->stencil.noc) dxm++;
5928     /* Local row number */
5929     if (tmp >= 0) {
5930       jdxm[numNewRows++] = tmp;
5931     }
5932   }
5933   ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
5934   ierr = PetscFree(jdxm);CHKERRQ(ierr);
5935   PetscFunctionReturn(0);
5936 }
5937 
5938 /*@C
5939    MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal)
5940    of a set of rows and columns of a matrix.
5941 
5942    Collective on Mat
5943 
5944    Input Parameters:
5945 +  mat - the matrix
5946 .  numRows - the number of rows/columns to remove
5947 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
5948 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5949 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5950 -  b - optional vector of right hand side, that will be adjusted by provided solution
5951 
5952    Notes:
5953    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5954    but does not release memory.  For the dense and block diagonal
5955    formats this does not alter the nonzero structure.
5956 
5957    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5958    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5959    merely zeroed.
5960 
5961    The user can set a value in the diagonal entry (or for the AIJ and
5962    row formats can optionally remove the main diagonal entry from the
5963    nonzero structure as well, by passing 0.0 as the final argument).
5964 
5965    For the parallel case, all processes that share the matrix (i.e.,
5966    those in the communicator used for matrix creation) MUST call this
5967    routine, regardless of whether any rows being zeroed are owned by
5968    them.
5969 
5970    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5971    list only rows local to itself, but the row/column numbers are given in local numbering).
5972 
5973    The grid coordinates are across the entire grid, not just the local portion
5974 
5975    In Fortran idxm and idxn should be declared as
5976 $     MatStencil idxm(4,m)
5977    and the values inserted using
5978 $    idxm(MatStencil_i,1) = i
5979 $    idxm(MatStencil_j,1) = j
5980 $    idxm(MatStencil_k,1) = k
5981 $    idxm(MatStencil_c,1) = c
5982    etc
5983 
5984    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5985    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5986    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5987    DM_BOUNDARY_PERIODIC boundary type.
5988 
5989    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
5990    a single value per point) you can skip filling those indices.
5991 
5992    Level: intermediate
5993 
5994    Concepts: matrices^zeroing rows
5995 
5996 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5997           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRows()
5998 @*/
5999 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
6000 {
6001   PetscInt       dim     = mat->stencil.dim;
6002   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
6003   PetscInt       *dims   = mat->stencil.dims+1;
6004   PetscInt       *starts = mat->stencil.starts;
6005   PetscInt       *dxm    = (PetscInt*) rows;
6006   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
6007   PetscErrorCode ierr;
6008 
6009   PetscFunctionBegin;
6010   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6011   PetscValidType(mat,1);
6012   if (numRows) PetscValidIntPointer(rows,3);
6013 
6014   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
6015   for (i = 0; i < numRows; ++i) {
6016     /* Skip unused dimensions (they are ordered k, j, i, c) */
6017     for (j = 0; j < 3-sdim; ++j) dxm++;
6018     /* Local index in X dir */
6019     tmp = *dxm++ - starts[0];
6020     /* Loop over remaining dimensions */
6021     for (j = 0; j < dim-1; ++j) {
6022       /* If nonlocal, set index to be negative */
6023       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6024       /* Update local index */
6025       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6026     }
6027     /* Skip component slot if necessary */
6028     if (mat->stencil.noc) dxm++;
6029     /* Local row number */
6030     if (tmp >= 0) {
6031       jdxm[numNewRows++] = tmp;
6032     }
6033   }
6034   ierr = MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
6035   ierr = PetscFree(jdxm);CHKERRQ(ierr);
6036   PetscFunctionReturn(0);
6037 }
6038 
6039 /*@C
6040    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
6041    of a set of rows of a matrix; using local numbering of rows.
6042 
6043    Collective on Mat
6044 
6045    Input Parameters:
6046 +  mat - the matrix
6047 .  numRows - the number of rows to remove
6048 .  rows - the global row indices
6049 .  diag - value put in all diagonals of eliminated rows
6050 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6051 -  b - optional vector of right hand side, that will be adjusted by provided solution
6052 
6053    Notes:
6054    Before calling MatZeroRowsLocal(), the user must first set the
6055    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6056 
6057    For the AIJ matrix formats this removes the old nonzero structure,
6058    but does not release memory.  For the dense and block diagonal
6059    formats this does not alter the nonzero structure.
6060 
6061    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6062    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6063    merely zeroed.
6064 
6065    The user can set a value in the diagonal entry (or for the AIJ and
6066    row formats can optionally remove the main diagonal entry from the
6067    nonzero structure as well, by passing 0.0 as the final argument).
6068 
6069    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6070    owns that are to be zeroed. This saves a global synchronization in the implementation.
6071 
6072    Level: intermediate
6073 
6074    Concepts: matrices^zeroing
6075 
6076 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRows(), MatSetOption(),
6077           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6078 @*/
6079 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6080 {
6081   PetscErrorCode ierr;
6082 
6083   PetscFunctionBegin;
6084   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6085   PetscValidType(mat,1);
6086   if (numRows) PetscValidIntPointer(rows,3);
6087   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6088   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6089   MatCheckPreallocated(mat,1);
6090 
6091   if (mat->ops->zerorowslocal) {
6092     ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6093   } else {
6094     IS             is, newis;
6095     const PetscInt *newRows;
6096 
6097     if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6098     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6099     ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr);
6100     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6101     ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6102     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6103     ierr = ISDestroy(&newis);CHKERRQ(ierr);
6104     ierr = ISDestroy(&is);CHKERRQ(ierr);
6105   }
6106   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6107 #if defined(PETSC_HAVE_CUSP)
6108   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
6109     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
6110   }
6111 #elif defined(PETSC_HAVE_VIENNACL)
6112   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
6113     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
6114   }
6115 #elif defined(PETSC_HAVE_VECCUDA)
6116   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
6117     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
6118   }
6119 #endif
6120   PetscFunctionReturn(0);
6121 }
6122 
6123 /*@C
6124    MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
6125    of a set of rows of a matrix; using local numbering of rows.
6126 
6127    Collective on Mat
6128 
6129    Input Parameters:
6130 +  mat - the matrix
6131 .  is - index set of rows to remove
6132 .  diag - value put in all diagonals of eliminated rows
6133 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6134 -  b - optional vector of right hand side, that will be adjusted by provided solution
6135 
6136    Notes:
6137    Before calling MatZeroRowsLocalIS(), the user must first set the
6138    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6139 
6140    For the AIJ matrix formats this removes the old nonzero structure,
6141    but does not release memory.  For the dense and block diagonal
6142    formats this does not alter the nonzero structure.
6143 
6144    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6145    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6146    merely zeroed.
6147 
6148    The user can set a value in the diagonal entry (or for the AIJ and
6149    row formats can optionally remove the main diagonal entry from the
6150    nonzero structure as well, by passing 0.0 as the final argument).
6151 
6152    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6153    owns that are to be zeroed. This saves a global synchronization in the implementation.
6154 
6155    Level: intermediate
6156 
6157    Concepts: matrices^zeroing
6158 
6159 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6160           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6161 @*/
6162 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6163 {
6164   PetscErrorCode ierr;
6165   PetscInt       numRows;
6166   const PetscInt *rows;
6167 
6168   PetscFunctionBegin;
6169   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6170   PetscValidType(mat,1);
6171   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6172   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6173   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6174   MatCheckPreallocated(mat,1);
6175 
6176   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6177   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6178   ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6179   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6180   PetscFunctionReturn(0);
6181 }
6182 
6183 /*@C
6184    MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
6185    of a set of rows and columns of a matrix; using local numbering of rows.
6186 
6187    Collective on Mat
6188 
6189    Input Parameters:
6190 +  mat - the matrix
6191 .  numRows - the number of rows to remove
6192 .  rows - the global row indices
6193 .  diag - value put in all diagonals of eliminated rows
6194 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6195 -  b - optional vector of right hand side, that will be adjusted by provided solution
6196 
6197    Notes:
6198    Before calling MatZeroRowsColumnsLocal(), the user must first set the
6199    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6200 
6201    The user can set a value in the diagonal entry (or for the AIJ and
6202    row formats can optionally remove the main diagonal entry from the
6203    nonzero structure as well, by passing 0.0 as the final argument).
6204 
6205    Level: intermediate
6206 
6207    Concepts: matrices^zeroing
6208 
6209 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6210           MatZeroRows(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6211 @*/
6212 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6213 {
6214   PetscErrorCode ierr;
6215   IS             is, newis;
6216   const PetscInt *newRows;
6217 
6218   PetscFunctionBegin;
6219   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6220   PetscValidType(mat,1);
6221   if (numRows) PetscValidIntPointer(rows,3);
6222   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6223   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6224   MatCheckPreallocated(mat,1);
6225 
6226   if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6227   ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6228   ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr);
6229   ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6230   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6231   ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6232   ierr = ISDestroy(&newis);CHKERRQ(ierr);
6233   ierr = ISDestroy(&is);CHKERRQ(ierr);
6234   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6235 #if defined(PETSC_HAVE_CUSP)
6236   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
6237     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
6238   }
6239 #elif defined(PETSC_HAVE_VIENNACL)
6240   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
6241     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
6242   }
6243 #elif defined(PETSC_HAVE_VECCUDA)
6244   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
6245     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
6246   }
6247 #endif
6248   PetscFunctionReturn(0);
6249 }
6250 
6251 /*@C
6252    MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
6253    of a set of rows and columns of a matrix; using local numbering of rows.
6254 
6255    Collective on Mat
6256 
6257    Input Parameters:
6258 +  mat - the matrix
6259 .  is - index set of rows to remove
6260 .  diag - value put in all diagonals of eliminated rows
6261 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6262 -  b - optional vector of right hand side, that will be adjusted by provided solution
6263 
6264    Notes:
6265    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
6266    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6267 
6268    The user can set a value in the diagonal entry (or for the AIJ and
6269    row formats can optionally remove the main diagonal entry from the
6270    nonzero structure as well, by passing 0.0 as the final argument).
6271 
6272    Level: intermediate
6273 
6274    Concepts: matrices^zeroing
6275 
6276 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6277           MatZeroRowsColumnsLocal(), MatZeroRows(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6278 @*/
6279 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6280 {
6281   PetscErrorCode ierr;
6282   PetscInt       numRows;
6283   const PetscInt *rows;
6284 
6285   PetscFunctionBegin;
6286   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6287   PetscValidType(mat,1);
6288   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6289   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6290   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6291   MatCheckPreallocated(mat,1);
6292 
6293   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6294   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6295   ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6296   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6297   PetscFunctionReturn(0);
6298 }
6299 
6300 /*@C
6301    MatGetSize - Returns the numbers of rows and columns in a matrix.
6302 
6303    Not Collective
6304 
6305    Input Parameter:
6306 .  mat - the matrix
6307 
6308    Output Parameters:
6309 +  m - the number of global rows
6310 -  n - the number of global columns
6311 
6312    Note: both output parameters can be NULL on input.
6313 
6314    Level: beginner
6315 
6316    Concepts: matrices^size
6317 
6318 .seealso: MatGetLocalSize()
6319 @*/
6320 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
6321 {
6322   PetscFunctionBegin;
6323   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6324   if (m) *m = mat->rmap->N;
6325   if (n) *n = mat->cmap->N;
6326   PetscFunctionReturn(0);
6327 }
6328 
6329 /*@C
6330    MatGetLocalSize - Returns the number of rows and columns in a matrix
6331    stored locally.  This information may be implementation dependent, so
6332    use with care.
6333 
6334    Not Collective
6335 
6336    Input Parameters:
6337 .  mat - the matrix
6338 
6339    Output Parameters:
6340 +  m - the number of local rows
6341 -  n - the number of local columns
6342 
6343    Note: both output parameters can be NULL on input.
6344 
6345    Level: beginner
6346 
6347    Concepts: matrices^local size
6348 
6349 .seealso: MatGetSize()
6350 @*/
6351 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
6352 {
6353   PetscFunctionBegin;
6354   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6355   if (m) PetscValidIntPointer(m,2);
6356   if (n) PetscValidIntPointer(n,3);
6357   if (m) *m = mat->rmap->n;
6358   if (n) *n = mat->cmap->n;
6359   PetscFunctionReturn(0);
6360 }
6361 
6362 /*@
6363    MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6364    this processor. (The columns of the "diagonal block")
6365 
6366    Not Collective, unless matrix has not been allocated, then collective on Mat
6367 
6368    Input Parameters:
6369 .  mat - the matrix
6370 
6371    Output Parameters:
6372 +  m - the global index of the first local column
6373 -  n - one more than the global index of the last local column
6374 
6375    Notes: both output parameters can be NULL on input.
6376 
6377    Level: developer
6378 
6379    Concepts: matrices^column ownership
6380 
6381 .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
6382 
6383 @*/
6384 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
6385 {
6386   PetscFunctionBegin;
6387   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6388   PetscValidType(mat,1);
6389   if (m) PetscValidIntPointer(m,2);
6390   if (n) PetscValidIntPointer(n,3);
6391   MatCheckPreallocated(mat,1);
6392   if (m) *m = mat->cmap->rstart;
6393   if (n) *n = mat->cmap->rend;
6394   PetscFunctionReturn(0);
6395 }
6396 
6397 /*@
6398    MatGetOwnershipRange - Returns the range of matrix rows owned by
6399    this processor, assuming that the matrix is laid out with the first
6400    n1 rows on the first processor, the next n2 rows on the second, etc.
6401    For certain parallel layouts this range may not be well defined.
6402 
6403    Not Collective
6404 
6405    Input Parameters:
6406 .  mat - the matrix
6407 
6408    Output Parameters:
6409 +  m - the global index of the first local row
6410 -  n - one more than the global index of the last local row
6411 
6412    Note: Both output parameters can be NULL on input.
6413 $  This function requires that the matrix be preallocated. If you have not preallocated, consider using
6414 $    PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
6415 $  and then MPI_Scan() to calculate prefix sums of the local sizes.
6416 
6417    Level: beginner
6418 
6419    Concepts: matrices^row ownership
6420 
6421 .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()
6422 
6423 @*/
6424 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6425 {
6426   PetscFunctionBegin;
6427   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6428   PetscValidType(mat,1);
6429   if (m) PetscValidIntPointer(m,2);
6430   if (n) PetscValidIntPointer(n,3);
6431   MatCheckPreallocated(mat,1);
6432   if (m) *m = mat->rmap->rstart;
6433   if (n) *n = mat->rmap->rend;
6434   PetscFunctionReturn(0);
6435 }
6436 
6437 /*@C
6438    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6439    each process
6440 
6441    Not Collective, unless matrix has not been allocated, then collective on Mat
6442 
6443    Input Parameters:
6444 .  mat - the matrix
6445 
6446    Output Parameters:
6447 .  ranges - start of each processors portion plus one more than the total length at the end
6448 
6449    Level: beginner
6450 
6451    Concepts: matrices^row ownership
6452 
6453 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
6454 
6455 @*/
6456 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6457 {
6458   PetscErrorCode ierr;
6459 
6460   PetscFunctionBegin;
6461   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6462   PetscValidType(mat,1);
6463   MatCheckPreallocated(mat,1);
6464   ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr);
6465   PetscFunctionReturn(0);
6466 }
6467 
6468 /*@C
6469    MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6470    this processor. (The columns of the "diagonal blocks" for each process)
6471 
6472    Not Collective, unless matrix has not been allocated, then collective on Mat
6473 
6474    Input Parameters:
6475 .  mat - the matrix
6476 
6477    Output Parameters:
6478 .  ranges - start of each processors portion plus one more then the total length at the end
6479 
6480    Level: beginner
6481 
6482    Concepts: matrices^column ownership
6483 
6484 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
6485 
6486 @*/
6487 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6488 {
6489   PetscErrorCode ierr;
6490 
6491   PetscFunctionBegin;
6492   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6493   PetscValidType(mat,1);
6494   MatCheckPreallocated(mat,1);
6495   ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr);
6496   PetscFunctionReturn(0);
6497 }
6498 
6499 /*@C
6500    MatGetOwnershipIS - Get row and column ownership as index sets
6501 
6502    Not Collective
6503 
6504    Input Arguments:
6505 .  A - matrix of type Elemental
6506 
6507    Output Arguments:
6508 +  rows - rows in which this process owns elements
6509 .  cols - columns in which this process owns elements
6510 
6511    Level: intermediate
6512 
6513 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL, MatSetValues()
6514 @*/
6515 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6516 {
6517   PetscErrorCode ierr,(*f)(Mat,IS*,IS*);
6518 
6519   PetscFunctionBegin;
6520   MatCheckPreallocated(A,1);
6521   ierr = PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);CHKERRQ(ierr);
6522   if (f) {
6523     ierr = (*f)(A,rows,cols);CHKERRQ(ierr);
6524   } else {   /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6525     if (rows) {ierr = ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);CHKERRQ(ierr);}
6526     if (cols) {ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);CHKERRQ(ierr);}
6527   }
6528   PetscFunctionReturn(0);
6529 }
6530 
6531 /*@C
6532    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6533    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6534    to complete the factorization.
6535 
6536    Collective on Mat
6537 
6538    Input Parameters:
6539 +  mat - the matrix
6540 .  row - row permutation
6541 .  column - column permutation
6542 -  info - structure containing
6543 $      levels - number of levels of fill.
6544 $      expected fill - as ratio of original fill.
6545 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6546                 missing diagonal entries)
6547 
6548    Output Parameters:
6549 .  fact - new matrix that has been symbolically factored
6550 
6551    Notes: See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
6552 
6553    Most users should employ the simplified KSP interface for linear solvers
6554    instead of working directly with matrix algebra routines such as this.
6555    See, e.g., KSPCreate().
6556 
6557    Level: developer
6558 
6559   Concepts: matrices^symbolic LU factorization
6560   Concepts: matrices^factorization
6561   Concepts: LU^symbolic factorization
6562 
6563 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6564           MatGetOrdering(), MatFactorInfo
6565 
6566     Developer Note: fortran interface is not autogenerated as the f90
6567     interface defintion cannot be generated correctly [due to MatFactorInfo]
6568 
6569 @*/
6570 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6571 {
6572   PetscErrorCode ierr;
6573 
6574   PetscFunctionBegin;
6575   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6576   PetscValidType(mat,1);
6577   PetscValidHeaderSpecific(row,IS_CLASSID,2);
6578   PetscValidHeaderSpecific(col,IS_CLASSID,3);
6579   PetscValidPointer(info,4);
6580   PetscValidPointer(fact,5);
6581   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6582   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6583   if (!(fact)->ops->ilufactorsymbolic) {
6584     const MatSolverPackage spackage;
6585     ierr = MatFactorGetSolverPackage(fact,&spackage);CHKERRQ(ierr);
6586     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6587   }
6588   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6589   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6590   MatCheckPreallocated(mat,2);
6591 
6592   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6593   ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
6594   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6595   PetscFunctionReturn(0);
6596 }
6597 
6598 /*@C
6599    MatICCFactorSymbolic - Performs symbolic incomplete
6600    Cholesky factorization for a symmetric matrix.  Use
6601    MatCholeskyFactorNumeric() to complete the factorization.
6602 
6603    Collective on Mat
6604 
6605    Input Parameters:
6606 +  mat - the matrix
6607 .  perm - row and column permutation
6608 -  info - structure containing
6609 $      levels - number of levels of fill.
6610 $      expected fill - as ratio of original fill.
6611 
6612    Output Parameter:
6613 .  fact - the factored matrix
6614 
6615    Notes:
6616    Most users should employ the KSP interface for linear solvers
6617    instead of working directly with matrix algebra routines such as this.
6618    See, e.g., KSPCreate().
6619 
6620    Level: developer
6621 
6622   Concepts: matrices^symbolic incomplete Cholesky factorization
6623   Concepts: matrices^factorization
6624   Concepts: Cholsky^symbolic factorization
6625 
6626 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
6627 
6628     Developer Note: fortran interface is not autogenerated as the f90
6629     interface defintion cannot be generated correctly [due to MatFactorInfo]
6630 
6631 @*/
6632 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6633 {
6634   PetscErrorCode ierr;
6635 
6636   PetscFunctionBegin;
6637   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6638   PetscValidType(mat,1);
6639   PetscValidHeaderSpecific(perm,IS_CLASSID,2);
6640   PetscValidPointer(info,3);
6641   PetscValidPointer(fact,4);
6642   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6643   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6644   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6645   if (!(fact)->ops->iccfactorsymbolic) {
6646     const MatSolverPackage spackage;
6647     ierr = MatFactorGetSolverPackage(fact,&spackage);CHKERRQ(ierr);
6648     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6649   }
6650   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6651   MatCheckPreallocated(mat,2);
6652 
6653   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6654   ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
6655   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6656   PetscFunctionReturn(0);
6657 }
6658 
6659 /*@C
6660    MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat
6661    points to an array of valid matrices, they may be reused to store the new
6662    submatrices.
6663 
6664    Collective on Mat
6665 
6666    Input Parameters:
6667 +  mat - the matrix
6668 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6669 .  irow, icol - index sets of rows and columns to extract
6670 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6671 
6672    Output Parameter:
6673 .  submat - the array of submatrices
6674 
6675    Notes:
6676    MatCreateSubMatrices() can extract ONLY sequential submatrices
6677    (from both sequential and parallel matrices). Use MatCreateSubMatrix()
6678    to extract a parallel submatrix.
6679 
6680    Some matrix types place restrictions on the row and column
6681    indices, such as that they be sorted or that they be equal to each other.
6682 
6683    The index sets may not have duplicate entries.
6684 
6685    When extracting submatrices from a parallel matrix, each processor can
6686    form a different submatrix by setting the rows and columns of its
6687    individual index sets according to the local submatrix desired.
6688 
6689    When finished using the submatrices, the user should destroy
6690    them with MatDestroyMatrices().
6691 
6692    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6693    original matrix has not changed from that last call to MatCreateSubMatrices().
6694 
6695    This routine creates the matrices in submat; you should NOT create them before
6696    calling it. It also allocates the array of matrix pointers submat.
6697 
6698    For BAIJ matrices the index sets must respect the block structure, that is if they
6699    request one row/column in a block, they must request all rows/columns that are in
6700    that block. For example, if the block size is 2 you cannot request just row 0 and
6701    column 0.
6702 
6703    Fortran Note:
6704    The Fortran interface is slightly different from that given below; it
6705    requires one to pass in  as submat a Mat (integer) array of size at least m.
6706 
6707    Level: advanced
6708 
6709    Concepts: matrices^accessing submatrices
6710    Concepts: submatrices
6711 
6712 .seealso: MatDestroySubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6713 @*/
6714 PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6715 {
6716   PetscErrorCode ierr;
6717   PetscInt       i;
6718   PetscBool      eq;
6719 
6720   PetscFunctionBegin;
6721   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6722   PetscValidType(mat,1);
6723   if (n) {
6724     PetscValidPointer(irow,3);
6725     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6726     PetscValidPointer(icol,4);
6727     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6728   }
6729   PetscValidPointer(submat,6);
6730   if (n && scall == MAT_REUSE_MATRIX) {
6731     PetscValidPointer(*submat,6);
6732     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6733   }
6734   if (!mat->ops->createsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6735   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6736   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6737   MatCheckPreallocated(mat,1);
6738 
6739   ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6740   ierr = (*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6741   ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6742   for (i=0; i<n; i++) {
6743     (*submat)[i]->factortype = MAT_FACTOR_NONE;  /* in case in place factorization was previously done on submatrix */
6744     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6745       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6746       if (eq) {
6747         if (mat->symmetric) {
6748           ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6749         } else if (mat->hermitian) {
6750           ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6751         } else if (mat->structurally_symmetric) {
6752           ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6753         }
6754       }
6755     }
6756   }
6757   PetscFunctionReturn(0);
6758 }
6759 
6760 /*@C
6761    MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms).
6762 
6763    Collective on Mat
6764 
6765    Input Parameters:
6766 +  mat - the matrix
6767 .  n   - the number of submatrixes to be extracted
6768 .  irow, icol - index sets of rows and columns to extract
6769 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6770 
6771    Output Parameter:
6772 .  submat - the array of submatrices
6773 
6774    Level: advanced
6775 
6776    Concepts: matrices^accessing submatrices
6777    Concepts: submatrices
6778 
6779 .seealso: MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6780 @*/
6781 PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6782 {
6783   PetscErrorCode ierr;
6784   PetscInt       i;
6785   PetscBool      eq;
6786 
6787   PetscFunctionBegin;
6788   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6789   PetscValidType(mat,1);
6790   if (n) {
6791     PetscValidPointer(irow,3);
6792     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6793     PetscValidPointer(icol,4);
6794     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6795   }
6796   PetscValidPointer(submat,6);
6797   if (n && scall == MAT_REUSE_MATRIX) {
6798     PetscValidPointer(*submat,6);
6799     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6800   }
6801   if (!mat->ops->createsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6802   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6803   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6804   MatCheckPreallocated(mat,1);
6805 
6806   ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6807   ierr = (*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6808   ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6809   for (i=0; i<n; i++) {
6810     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6811       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6812       if (eq) {
6813         if (mat->symmetric) {
6814           ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6815         } else if (mat->hermitian) {
6816           ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6817         } else if (mat->structurally_symmetric) {
6818           ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6819         }
6820       }
6821     }
6822   }
6823   PetscFunctionReturn(0);
6824 }
6825 
6826 /*@C
6827    MatDestroyMatrices - Destroys an array of matrices.
6828 
6829    Collective on Mat
6830 
6831    Input Parameters:
6832 +  n - the number of local matrices
6833 -  mat - the matrices (note that this is a pointer to the array of matrices)
6834 
6835    Level: advanced
6836 
6837     Notes: Frees not only the matrices, but also the array that contains the matrices
6838            In Fortran will not free the array.
6839 
6840 .seealso: MatCreateSubMatrices() MatDestroySubMatrices()
6841 @*/
6842 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
6843 {
6844   PetscErrorCode ierr;
6845   PetscInt       i;
6846 
6847   PetscFunctionBegin;
6848   if (!*mat) PetscFunctionReturn(0);
6849   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6850   PetscValidPointer(mat,2);
6851 
6852   for (i=0; i<n; i++) {
6853     ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr);
6854   }
6855 
6856   /* memory is allocated even if n = 0 */
6857   ierr = PetscFree(*mat);CHKERRQ(ierr);
6858   PetscFunctionReturn(0);
6859 }
6860 
6861 /*@C
6862    MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices().
6863 
6864    Collective on Mat
6865 
6866    Input Parameters:
6867 +  n - the number of local matrices
6868 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6869                        sequence of MatCreateSubMatrices())
6870 
6871    Level: advanced
6872 
6873     Notes: Frees not only the matrices, but also the array that contains the matrices
6874            In Fortran will not free the array.
6875 
6876 .seealso: MatCreateSubMatrices()
6877 @*/
6878 PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[])
6879 {
6880   PetscErrorCode ierr;
6881   Mat            mat0;
6882 
6883   PetscFunctionBegin;
6884   if (!*mat) PetscFunctionReturn(0);
6885   /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */
6886   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6887   PetscValidPointer(mat,2);
6888 
6889   mat0 = (*mat)[0];
6890   if (mat0 && mat0->ops->destroysubmatrices) {
6891     ierr = (mat0->ops->destroysubmatrices)(n,mat);CHKERRQ(ierr);
6892   } else {
6893     ierr = MatDestroyMatrices(n,mat);CHKERRQ(ierr);
6894   }
6895   PetscFunctionReturn(0);
6896 }
6897 
6898 /*@C
6899    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
6900 
6901    Collective on Mat
6902 
6903    Input Parameters:
6904 .  mat - the matrix
6905 
6906    Output Parameter:
6907 .  matstruct - the sequential matrix with the nonzero structure of mat
6908 
6909   Level: intermediate
6910 
6911 .seealso: MatDestroySeqNonzeroStructure(), MatCreateSubMatrices(), MatDestroyMatrices()
6912 @*/
6913 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6914 {
6915   PetscErrorCode ierr;
6916 
6917   PetscFunctionBegin;
6918   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6919   PetscValidPointer(matstruct,2);
6920 
6921   PetscValidType(mat,1);
6922   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6923   MatCheckPreallocated(mat,1);
6924 
6925   if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6926   ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
6927   ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr);
6928   ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
6929   PetscFunctionReturn(0);
6930 }
6931 
6932 /*@C
6933    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
6934 
6935    Collective on Mat
6936 
6937    Input Parameters:
6938 .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
6939                        sequence of MatGetSequentialNonzeroStructure())
6940 
6941    Level: advanced
6942 
6943     Notes: Frees not only the matrices, but also the array that contains the matrices
6944 
6945 .seealso: MatGetSeqNonzeroStructure()
6946 @*/
6947 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
6948 {
6949   PetscErrorCode ierr;
6950 
6951   PetscFunctionBegin;
6952   PetscValidPointer(mat,1);
6953   ierr = MatDestroy(mat);CHKERRQ(ierr);
6954   PetscFunctionReturn(0);
6955 }
6956 
6957 /*@
6958    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6959    replaces the index sets by larger ones that represent submatrices with
6960    additional overlap.
6961 
6962    Collective on Mat
6963 
6964    Input Parameters:
6965 +  mat - the matrix
6966 .  n   - the number of index sets
6967 .  is  - the array of index sets (these index sets will changed during the call)
6968 -  ov  - the additional overlap requested
6969 
6970    Options Database:
6971 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
6972 
6973    Level: developer
6974 
6975    Concepts: overlap
6976    Concepts: ASM^computing overlap
6977 
6978 .seealso: MatCreateSubMatrices()
6979 @*/
6980 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6981 {
6982   PetscErrorCode ierr;
6983 
6984   PetscFunctionBegin;
6985   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6986   PetscValidType(mat,1);
6987   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6988   if (n) {
6989     PetscValidPointer(is,3);
6990     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
6991   }
6992   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6993   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6994   MatCheckPreallocated(mat,1);
6995 
6996   if (!ov) PetscFunctionReturn(0);
6997   if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6998   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
6999   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
7000   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7001   PetscFunctionReturn(0);
7002 }
7003 
7004 
7005 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt);
7006 
7007 /*@
7008    MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across
7009    a sub communicator, replaces the index sets by larger ones that represent submatrices with
7010    additional overlap.
7011 
7012    Collective on Mat
7013 
7014    Input Parameters:
7015 +  mat - the matrix
7016 .  n   - the number of index sets
7017 .  is  - the array of index sets (these index sets will changed during the call)
7018 -  ov  - the additional overlap requested
7019 
7020    Options Database:
7021 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
7022 
7023    Level: developer
7024 
7025    Concepts: overlap
7026    Concepts: ASM^computing overlap
7027 
7028 .seealso: MatCreateSubMatrices()
7029 @*/
7030 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov)
7031 {
7032   PetscInt       i;
7033   PetscErrorCode ierr;
7034 
7035   PetscFunctionBegin;
7036   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7037   PetscValidType(mat,1);
7038   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
7039   if (n) {
7040     PetscValidPointer(is,3);
7041     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
7042   }
7043   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7044   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7045   MatCheckPreallocated(mat,1);
7046   if (!ov) PetscFunctionReturn(0);
7047   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7048   for(i=0; i<n; i++){
7049 	ierr =  MatIncreaseOverlapSplit_Single(mat,&is[i],ov);CHKERRQ(ierr);
7050   }
7051   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7052   PetscFunctionReturn(0);
7053 }
7054 
7055 
7056 
7057 
7058 /*@
7059    MatGetBlockSize - Returns the matrix block size.
7060 
7061    Not Collective
7062 
7063    Input Parameter:
7064 .  mat - the matrix
7065 
7066    Output Parameter:
7067 .  bs - block size
7068 
7069    Notes:
7070     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7071 
7072    If the block size has not been set yet this routine returns 1.
7073 
7074    Level: intermediate
7075 
7076    Concepts: matrices^block size
7077 
7078 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
7079 @*/
7080 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
7081 {
7082   PetscFunctionBegin;
7083   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7084   PetscValidIntPointer(bs,2);
7085   *bs = PetscAbs(mat->rmap->bs);
7086   PetscFunctionReturn(0);
7087 }
7088 
7089 /*@
7090    MatGetBlockSizes - Returns the matrix block row and column sizes.
7091 
7092    Not Collective
7093 
7094    Input Parameter:
7095 .  mat - the matrix
7096 
7097    Output Parameter:
7098 .  rbs - row block size
7099 .  cbs - column block size
7100 
7101    Notes:
7102     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7103     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7104 
7105    If a block size has not been set yet this routine returns 1.
7106 
7107    Level: intermediate
7108 
7109    Concepts: matrices^block size
7110 
7111 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes()
7112 @*/
7113 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
7114 {
7115   PetscFunctionBegin;
7116   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7117   if (rbs) PetscValidIntPointer(rbs,2);
7118   if (cbs) PetscValidIntPointer(cbs,3);
7119   if (rbs) *rbs = PetscAbs(mat->rmap->bs);
7120   if (cbs) *cbs = PetscAbs(mat->cmap->bs);
7121   PetscFunctionReturn(0);
7122 }
7123 
7124 /*@
7125    MatSetBlockSize - Sets the matrix block size.
7126 
7127    Logically Collective on Mat
7128 
7129    Input Parameters:
7130 +  mat - the matrix
7131 -  bs - block size
7132 
7133    Notes:
7134     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7135     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later.
7136 
7137     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size
7138     is compatible with the matrix local sizes.
7139 
7140    Level: intermediate
7141 
7142    Concepts: matrices^block size
7143 
7144 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes()
7145 @*/
7146 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
7147 {
7148   PetscErrorCode ierr;
7149 
7150   PetscFunctionBegin;
7151   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7152   PetscValidLogicalCollectiveInt(mat,bs,2);
7153   ierr = MatSetBlockSizes(mat,bs,bs);CHKERRQ(ierr);
7154   PetscFunctionReturn(0);
7155 }
7156 
7157 /*@
7158    MatSetBlockSizes - Sets the matrix block row and column sizes.
7159 
7160    Logically Collective on Mat
7161 
7162    Input Parameters:
7163 +  mat - the matrix
7164 -  rbs - row block size
7165 -  cbs - column block size
7166 
7167    Notes:
7168     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7169     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7170     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later
7171 
7172     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes
7173     are compatible with the matrix local sizes.
7174 
7175     The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs().
7176 
7177    Level: intermediate
7178 
7179    Concepts: matrices^block size
7180 
7181 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes()
7182 @*/
7183 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
7184 {
7185   PetscErrorCode ierr;
7186 
7187   PetscFunctionBegin;
7188   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7189   PetscValidLogicalCollectiveInt(mat,rbs,2);
7190   PetscValidLogicalCollectiveInt(mat,cbs,3);
7191   if (mat->ops->setblocksizes) {
7192     ierr = (*mat->ops->setblocksizes)(mat,rbs,cbs);CHKERRQ(ierr);
7193   }
7194   if (mat->rmap->refcnt) {
7195     ISLocalToGlobalMapping l2g = NULL;
7196     PetscLayout            nmap = NULL;
7197 
7198     ierr = PetscLayoutDuplicate(mat->rmap,&nmap);CHKERRQ(ierr);
7199     if (mat->rmap->mapping) {
7200       ierr = ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g);CHKERRQ(ierr);
7201     }
7202     ierr = PetscLayoutDestroy(&mat->rmap);CHKERRQ(ierr);
7203     mat->rmap = nmap;
7204     mat->rmap->mapping = l2g;
7205   }
7206   if (mat->cmap->refcnt) {
7207     ISLocalToGlobalMapping l2g = NULL;
7208     PetscLayout            nmap = NULL;
7209 
7210     ierr = PetscLayoutDuplicate(mat->cmap,&nmap);CHKERRQ(ierr);
7211     if (mat->cmap->mapping) {
7212       ierr = ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g);CHKERRQ(ierr);
7213     }
7214     ierr = PetscLayoutDestroy(&mat->cmap);CHKERRQ(ierr);
7215     mat->cmap = nmap;
7216     mat->cmap->mapping = l2g;
7217   }
7218   ierr = PetscLayoutSetBlockSize(mat->rmap,rbs);CHKERRQ(ierr);
7219   ierr = PetscLayoutSetBlockSize(mat->cmap,cbs);CHKERRQ(ierr);
7220   PetscFunctionReturn(0);
7221 }
7222 
7223 /*@
7224    MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices
7225 
7226    Logically Collective on Mat
7227 
7228    Input Parameters:
7229 +  mat - the matrix
7230 .  fromRow - matrix from which to copy row block size
7231 -  fromCol - matrix from which to copy column block size (can be same as fromRow)
7232 
7233    Level: developer
7234 
7235    Concepts: matrices^block size
7236 
7237 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes()
7238 @*/
7239 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)
7240 {
7241   PetscErrorCode ierr;
7242 
7243   PetscFunctionBegin;
7244   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7245   PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2);
7246   PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3);
7247   if (fromRow->rmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);CHKERRQ(ierr);}
7248   if (fromCol->cmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);CHKERRQ(ierr);}
7249   PetscFunctionReturn(0);
7250 }
7251 
7252 /*@
7253    MatResidual - Default routine to calculate the residual.
7254 
7255    Collective on Mat and Vec
7256 
7257    Input Parameters:
7258 +  mat - the matrix
7259 .  b   - the right-hand-side
7260 -  x   - the approximate solution
7261 
7262    Output Parameter:
7263 .  r - location to store the residual
7264 
7265    Level: developer
7266 
7267 .keywords: MG, default, multigrid, residual
7268 
7269 .seealso: PCMGSetResidual()
7270 @*/
7271 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r)
7272 {
7273   PetscErrorCode ierr;
7274 
7275   PetscFunctionBegin;
7276   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7277   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
7278   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
7279   PetscValidHeaderSpecific(r,VEC_CLASSID,4);
7280   PetscValidType(mat,1);
7281   MatCheckPreallocated(mat,1);
7282   ierr  = PetscLogEventBegin(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7283   if (!mat->ops->residual) {
7284     ierr = MatMult(mat,x,r);CHKERRQ(ierr);
7285     ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr);
7286   } else {
7287     ierr  = (*mat->ops->residual)(mat,b,x,r);CHKERRQ(ierr);
7288   }
7289   ierr  = PetscLogEventEnd(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7290   PetscFunctionReturn(0);
7291 }
7292 
7293 /*@C
7294     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
7295 
7296    Collective on Mat
7297 
7298     Input Parameters:
7299 +   mat - the matrix
7300 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
7301 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
7302 -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
7303                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7304                  always used.
7305 
7306     Output Parameters:
7307 +   n - number of rows in the (possibly compressed) matrix
7308 .   ia - the row pointers [of length n+1]
7309 .   ja - the column indices
7310 -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
7311            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
7312 
7313     Level: developer
7314 
7315     Notes: You CANNOT change any of the ia[] or ja[] values.
7316 
7317            Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values
7318 
7319     Fortran Node
7320 
7321            In Fortran use
7322 $           PetscInt ia(1), ja(1)
7323 $           PetscOffset iia, jja
7324 $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
7325 $      Acess the ith and jth entries via ia(iia + i) and ja(jja + j)
7326 $
7327 $          or
7328 $
7329 $           PetscInt, pointer :: ia(:),ja(:)
7330 $    call  MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
7331 $      Acess the ith and jth entries via ia(i) and ja(j)
7332 
7333 
7334 
7335 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
7336 @*/
7337 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7338 {
7339   PetscErrorCode ierr;
7340 
7341   PetscFunctionBegin;
7342   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7343   PetscValidType(mat,1);
7344   PetscValidIntPointer(n,5);
7345   if (ia) PetscValidIntPointer(ia,6);
7346   if (ja) PetscValidIntPointer(ja,7);
7347   PetscValidIntPointer(done,8);
7348   MatCheckPreallocated(mat,1);
7349   if (!mat->ops->getrowij) *done = PETSC_FALSE;
7350   else {
7351     *done = PETSC_TRUE;
7352     ierr  = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7353     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7354     ierr  = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7355   }
7356   PetscFunctionReturn(0);
7357 }
7358 
7359 /*@C
7360     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
7361 
7362     Collective on Mat
7363 
7364     Input Parameters:
7365 +   mat - the matrix
7366 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7367 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7368                 symmetrized
7369 .   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7370                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7371                  always used.
7372 .   n - number of columns in the (possibly compressed) matrix
7373 .   ia - the column pointers
7374 -   ja - the row indices
7375 
7376     Output Parameters:
7377 .   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
7378 
7379     Note:
7380     This routine zeros out n, ia, and ja. This is to prevent accidental
7381     us of the array after it has been restored. If you pass NULL, it will
7382     not zero the pointers.  Use of ia or ja after MatRestoreColumnIJ() is invalid.
7383 
7384     Level: developer
7385 
7386 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7387 @*/
7388 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7389 {
7390   PetscErrorCode ierr;
7391 
7392   PetscFunctionBegin;
7393   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7394   PetscValidType(mat,1);
7395   PetscValidIntPointer(n,4);
7396   if (ia) PetscValidIntPointer(ia,5);
7397   if (ja) PetscValidIntPointer(ja,6);
7398   PetscValidIntPointer(done,7);
7399   MatCheckPreallocated(mat,1);
7400   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
7401   else {
7402     *done = PETSC_TRUE;
7403     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7404   }
7405   PetscFunctionReturn(0);
7406 }
7407 
7408 /*@C
7409     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
7410     MatGetRowIJ().
7411 
7412     Collective on Mat
7413 
7414     Input Parameters:
7415 +   mat - the matrix
7416 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7417 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7418                 symmetrized
7419 .   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7420                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7421                  always used.
7422 .   n - size of (possibly compressed) matrix
7423 .   ia - the row pointers
7424 -   ja - the column indices
7425 
7426     Output Parameters:
7427 .   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7428 
7429     Note:
7430     This routine zeros out n, ia, and ja. This is to prevent accidental
7431     us of the array after it has been restored. If you pass NULL, it will
7432     not zero the pointers.  Use of ia or ja after MatRestoreRowIJ() is invalid.
7433 
7434     Level: developer
7435 
7436 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7437 @*/
7438 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7439 {
7440   PetscErrorCode ierr;
7441 
7442   PetscFunctionBegin;
7443   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7444   PetscValidType(mat,1);
7445   if (ia) PetscValidIntPointer(ia,6);
7446   if (ja) PetscValidIntPointer(ja,7);
7447   PetscValidIntPointer(done,8);
7448   MatCheckPreallocated(mat,1);
7449 
7450   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
7451   else {
7452     *done = PETSC_TRUE;
7453     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7454     if (n)  *n = 0;
7455     if (ia) *ia = NULL;
7456     if (ja) *ja = NULL;
7457   }
7458   PetscFunctionReturn(0);
7459 }
7460 
7461 /*@C
7462     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
7463     MatGetColumnIJ().
7464 
7465     Collective on Mat
7466 
7467     Input Parameters:
7468 +   mat - the matrix
7469 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7470 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7471                 symmetrized
7472 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7473                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7474                  always used.
7475 
7476     Output Parameters:
7477 +   n - size of (possibly compressed) matrix
7478 .   ia - the column pointers
7479 .   ja - the row indices
7480 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7481 
7482     Level: developer
7483 
7484 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
7485 @*/
7486 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7487 {
7488   PetscErrorCode ierr;
7489 
7490   PetscFunctionBegin;
7491   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7492   PetscValidType(mat,1);
7493   if (ia) PetscValidIntPointer(ia,5);
7494   if (ja) PetscValidIntPointer(ja,6);
7495   PetscValidIntPointer(done,7);
7496   MatCheckPreallocated(mat,1);
7497 
7498   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
7499   else {
7500     *done = PETSC_TRUE;
7501     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7502     if (n)  *n = 0;
7503     if (ia) *ia = NULL;
7504     if (ja) *ja = NULL;
7505   }
7506   PetscFunctionReturn(0);
7507 }
7508 
7509 /*@C
7510     MatColoringPatch -Used inside matrix coloring routines that
7511     use MatGetRowIJ() and/or MatGetColumnIJ().
7512 
7513     Collective on Mat
7514 
7515     Input Parameters:
7516 +   mat - the matrix
7517 .   ncolors - max color value
7518 .   n   - number of entries in colorarray
7519 -   colorarray - array indicating color for each column
7520 
7521     Output Parameters:
7522 .   iscoloring - coloring generated using colorarray information
7523 
7524     Level: developer
7525 
7526 .seealso: MatGetRowIJ(), MatGetColumnIJ()
7527 
7528 @*/
7529 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7530 {
7531   PetscErrorCode ierr;
7532 
7533   PetscFunctionBegin;
7534   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7535   PetscValidType(mat,1);
7536   PetscValidIntPointer(colorarray,4);
7537   PetscValidPointer(iscoloring,5);
7538   MatCheckPreallocated(mat,1);
7539 
7540   if (!mat->ops->coloringpatch) {
7541     ierr = ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);CHKERRQ(ierr);
7542   } else {
7543     ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
7544   }
7545   PetscFunctionReturn(0);
7546 }
7547 
7548 
7549 /*@
7550    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
7551 
7552    Logically Collective on Mat
7553 
7554    Input Parameter:
7555 .  mat - the factored matrix to be reset
7556 
7557    Notes:
7558    This routine should be used only with factored matrices formed by in-place
7559    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7560    format).  This option can save memory, for example, when solving nonlinear
7561    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7562    ILU(0) preconditioner.
7563 
7564    Note that one can specify in-place ILU(0) factorization by calling
7565 .vb
7566      PCType(pc,PCILU);
7567      PCFactorSeUseInPlace(pc);
7568 .ve
7569    or by using the options -pc_type ilu -pc_factor_in_place
7570 
7571    In-place factorization ILU(0) can also be used as a local
7572    solver for the blocks within the block Jacobi or additive Schwarz
7573    methods (runtime option: -sub_pc_factor_in_place).  See Users-Manual: ch_pc
7574    for details on setting local solver options.
7575 
7576    Most users should employ the simplified KSP interface for linear solvers
7577    instead of working directly with matrix algebra routines such as this.
7578    See, e.g., KSPCreate().
7579 
7580    Level: developer
7581 
7582 .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace()
7583 
7584    Concepts: matrices^unfactored
7585 
7586 @*/
7587 PetscErrorCode MatSetUnfactored(Mat mat)
7588 {
7589   PetscErrorCode ierr;
7590 
7591   PetscFunctionBegin;
7592   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7593   PetscValidType(mat,1);
7594   MatCheckPreallocated(mat,1);
7595   mat->factortype = MAT_FACTOR_NONE;
7596   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
7597   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
7598   PetscFunctionReturn(0);
7599 }
7600 
7601 /*MC
7602     MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.
7603 
7604     Synopsis:
7605     MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7606 
7607     Not collective
7608 
7609     Input Parameter:
7610 .   x - matrix
7611 
7612     Output Parameters:
7613 +   xx_v - the Fortran90 pointer to the array
7614 -   ierr - error code
7615 
7616     Example of Usage:
7617 .vb
7618       PetscScalar, pointer xx_v(:,:)
7619       ....
7620       call MatDenseGetArrayF90(x,xx_v,ierr)
7621       a = xx_v(3)
7622       call MatDenseRestoreArrayF90(x,xx_v,ierr)
7623 .ve
7624 
7625     Level: advanced
7626 
7627 .seealso:  MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90()
7628 
7629     Concepts: matrices^accessing array
7630 
7631 M*/
7632 
7633 /*MC
7634     MatDenseRestoreArrayF90 - Restores a matrix array that has been
7635     accessed with MatDenseGetArrayF90().
7636 
7637     Synopsis:
7638     MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7639 
7640     Not collective
7641 
7642     Input Parameters:
7643 +   x - matrix
7644 -   xx_v - the Fortran90 pointer to the array
7645 
7646     Output Parameter:
7647 .   ierr - error code
7648 
7649     Example of Usage:
7650 .vb
7651        PetscScalar, pointer xx_v(:,:)
7652        ....
7653        call MatDenseGetArrayF90(x,xx_v,ierr)
7654        a = xx_v(3)
7655        call MatDenseRestoreArrayF90(x,xx_v,ierr)
7656 .ve
7657 
7658     Level: advanced
7659 
7660 .seealso:  MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90()
7661 
7662 M*/
7663 
7664 
7665 /*MC
7666     MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.
7667 
7668     Synopsis:
7669     MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7670 
7671     Not collective
7672 
7673     Input Parameter:
7674 .   x - matrix
7675 
7676     Output Parameters:
7677 +   xx_v - the Fortran90 pointer to the array
7678 -   ierr - error code
7679 
7680     Example of Usage:
7681 .vb
7682       PetscScalar, pointer xx_v(:)
7683       ....
7684       call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7685       a = xx_v(3)
7686       call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7687 .ve
7688 
7689     Level: advanced
7690 
7691 .seealso:  MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90()
7692 
7693     Concepts: matrices^accessing array
7694 
7695 M*/
7696 
7697 /*MC
7698     MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7699     accessed with MatSeqAIJGetArrayF90().
7700 
7701     Synopsis:
7702     MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7703 
7704     Not collective
7705 
7706     Input Parameters:
7707 +   x - matrix
7708 -   xx_v - the Fortran90 pointer to the array
7709 
7710     Output Parameter:
7711 .   ierr - error code
7712 
7713     Example of Usage:
7714 .vb
7715        PetscScalar, pointer xx_v(:)
7716        ....
7717        call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7718        a = xx_v(3)
7719        call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7720 .ve
7721 
7722     Level: advanced
7723 
7724 .seealso:  MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90()
7725 
7726 M*/
7727 
7728 
7729 /*@
7730     MatCreateSubMatrix - Gets a single submatrix on the same number of processors
7731                       as the original matrix.
7732 
7733     Collective on Mat
7734 
7735     Input Parameters:
7736 +   mat - the original matrix
7737 .   isrow - parallel IS containing the rows this processor should obtain
7738 .   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.
7739 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7740 
7741     Output Parameter:
7742 .   newmat - the new submatrix, of the same type as the old
7743 
7744     Level: advanced
7745 
7746     Notes:
7747     The submatrix will be able to be multiplied with vectors using the same layout as iscol.
7748 
7749     Some matrix types place restrictions on the row and column indices, such
7750     as that they be sorted or that they be equal to each other.
7751 
7752     The index sets may not have duplicate entries.
7753 
7754       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7755    the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls
7756    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7757    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
7758    you are finished using it.
7759 
7760     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7761     the input matrix.
7762 
7763     If iscol is NULL then all columns are obtained (not supported in Fortran).
7764 
7765    Example usage:
7766    Consider the following 8x8 matrix with 34 non-zero values, that is
7767    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7768    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7769    as follows:
7770 
7771 .vb
7772             1  2  0  |  0  3  0  |  0  4
7773     Proc0   0  5  6  |  7  0  0  |  8  0
7774             9  0 10  | 11  0  0  | 12  0
7775     -------------------------------------
7776            13  0 14  | 15 16 17  |  0  0
7777     Proc1   0 18  0  | 19 20 21  |  0  0
7778             0  0  0  | 22 23  0  | 24  0
7779     -------------------------------------
7780     Proc2  25 26 27  |  0  0 28  | 29  0
7781            30  0  0  | 31 32 33  |  0 34
7782 .ve
7783 
7784     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is
7785 
7786 .vb
7787             2  0  |  0  3  0  |  0
7788     Proc0   5  6  |  7  0  0  |  8
7789     -------------------------------
7790     Proc1  18  0  | 19 20 21  |  0
7791     -------------------------------
7792     Proc2  26 27  |  0  0 28  | 29
7793             0  0  | 31 32 33  |  0
7794 .ve
7795 
7796 
7797     Concepts: matrices^submatrices
7798 
7799 .seealso: MatCreateSubMatrices()
7800 @*/
7801 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7802 {
7803   PetscErrorCode ierr;
7804   PetscMPIInt    size;
7805   Mat            *local;
7806   IS             iscoltmp;
7807 
7808   PetscFunctionBegin;
7809   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7810   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
7811   if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
7812   PetscValidPointer(newmat,5);
7813   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5);
7814   PetscValidType(mat,1);
7815   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7816   if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX");
7817 
7818   MatCheckPreallocated(mat,1);
7819   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
7820 
7821   if (!iscol || isrow == iscol) {
7822     PetscBool   stride;
7823     PetscMPIInt grabentirematrix = 0,grab;
7824     ierr = PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);CHKERRQ(ierr);
7825     if (stride) {
7826       PetscInt first,step,n,rstart,rend;
7827       ierr = ISStrideGetInfo(isrow,&first,&step);CHKERRQ(ierr);
7828       if (step == 1) {
7829         ierr = MatGetOwnershipRange(mat,&rstart,&rend);CHKERRQ(ierr);
7830         if (rstart == first) {
7831           ierr = ISGetLocalSize(isrow,&n);CHKERRQ(ierr);
7832           if (n == rend-rstart) {
7833             grabentirematrix = 1;
7834           }
7835         }
7836       }
7837     }
7838     ierr = MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr);
7839     if (grab) {
7840       ierr = PetscInfo(mat,"Getting entire matrix as submatrix\n");CHKERRQ(ierr);
7841       if (cll == MAT_INITIAL_MATRIX) {
7842         *newmat = mat;
7843         ierr    = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr);
7844       }
7845       PetscFunctionReturn(0);
7846     }
7847   }
7848 
7849   if (!iscol) {
7850     ierr = ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr);
7851   } else {
7852     iscoltmp = iscol;
7853   }
7854 
7855   /* if original matrix is on just one processor then use submatrix generated */
7856   if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7857     ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
7858     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7859     PetscFunctionReturn(0);
7860   } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) {
7861     ierr    = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
7862     *newmat = *local;
7863     ierr    = PetscFree(local);CHKERRQ(ierr);
7864     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7865     PetscFunctionReturn(0);
7866   } else if (!mat->ops->createsubmatrix) {
7867     /* Create a new matrix type that implements the operation using the full matrix */
7868     ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
7869     switch (cll) {
7870     case MAT_INITIAL_MATRIX:
7871       ierr = MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr);
7872       break;
7873     case MAT_REUSE_MATRIX:
7874       ierr = MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr);
7875       break;
7876     default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7877     }
7878     ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
7879     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7880     PetscFunctionReturn(0);
7881   }
7882 
7883   if (!mat->ops->createsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7884   ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
7885   ierr = (*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr);
7886   ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
7887   if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7888   if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);}
7889   PetscFunctionReturn(0);
7890 }
7891 
7892 /*@
7893    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7894    used during the assembly process to store values that belong to
7895    other processors.
7896 
7897    Not Collective
7898 
7899    Input Parameters:
7900 +  mat   - the matrix
7901 .  size  - the initial size of the stash.
7902 -  bsize - the initial size of the block-stash(if used).
7903 
7904    Options Database Keys:
7905 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
7906 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
7907 
7908    Level: intermediate
7909 
7910    Notes:
7911      The block-stash is used for values set with MatSetValuesBlocked() while
7912      the stash is used for values set with MatSetValues()
7913 
7914      Run with the option -info and look for output of the form
7915      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7916      to determine the appropriate value, MM, to use for size and
7917      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7918      to determine the value, BMM to use for bsize
7919 
7920    Concepts: stash^setting matrix size
7921    Concepts: matrices^stash
7922 
7923 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
7924 
7925 @*/
7926 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7927 {
7928   PetscErrorCode ierr;
7929 
7930   PetscFunctionBegin;
7931   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7932   PetscValidType(mat,1);
7933   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
7934   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
7935   PetscFunctionReturn(0);
7936 }
7937 
7938 /*@
7939    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
7940      the matrix
7941 
7942    Neighbor-wise Collective on Mat
7943 
7944    Input Parameters:
7945 +  mat   - the matrix
7946 .  x,y - the vectors
7947 -  w - where the result is stored
7948 
7949    Level: intermediate
7950 
7951    Notes:
7952     w may be the same vector as y.
7953 
7954     This allows one to use either the restriction or interpolation (its transpose)
7955     matrix to do the interpolation
7956 
7957     Concepts: interpolation
7958 
7959 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7960 
7961 @*/
7962 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7963 {
7964   PetscErrorCode ierr;
7965   PetscInt       M,N,Ny;
7966 
7967   PetscFunctionBegin;
7968   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7969   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7970   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7971   PetscValidHeaderSpecific(w,VEC_CLASSID,4);
7972   PetscValidType(A,1);
7973   MatCheckPreallocated(A,1);
7974   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
7975   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
7976   if (M == Ny) {
7977     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
7978   } else {
7979     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
7980   }
7981   PetscFunctionReturn(0);
7982 }
7983 
7984 /*@
7985    MatInterpolate - y = A*x or A'*x depending on the shape of
7986      the matrix
7987 
7988    Neighbor-wise Collective on Mat
7989 
7990    Input Parameters:
7991 +  mat   - the matrix
7992 -  x,y - the vectors
7993 
7994    Level: intermediate
7995 
7996    Notes:
7997     This allows one to use either the restriction or interpolation (its transpose)
7998     matrix to do the interpolation
7999 
8000    Concepts: matrices^interpolation
8001 
8002 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
8003 
8004 @*/
8005 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
8006 {
8007   PetscErrorCode ierr;
8008   PetscInt       M,N,Ny;
8009 
8010   PetscFunctionBegin;
8011   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8012   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8013   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8014   PetscValidType(A,1);
8015   MatCheckPreallocated(A,1);
8016   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8017   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8018   if (M == Ny) {
8019     ierr = MatMult(A,x,y);CHKERRQ(ierr);
8020   } else {
8021     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
8022   }
8023   PetscFunctionReturn(0);
8024 }
8025 
8026 /*@
8027    MatRestrict - y = A*x or A'*x
8028 
8029    Neighbor-wise Collective on Mat
8030 
8031    Input Parameters:
8032 +  mat   - the matrix
8033 -  x,y - the vectors
8034 
8035    Level: intermediate
8036 
8037    Notes:
8038     This allows one to use either the restriction or interpolation (its transpose)
8039     matrix to do the restriction
8040 
8041    Concepts: matrices^restriction
8042 
8043 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
8044 
8045 @*/
8046 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
8047 {
8048   PetscErrorCode ierr;
8049   PetscInt       M,N,Ny;
8050 
8051   PetscFunctionBegin;
8052   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8053   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8054   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8055   PetscValidType(A,1);
8056   MatCheckPreallocated(A,1);
8057 
8058   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8059   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8060   if (M == Ny) {
8061     ierr = MatMult(A,x,y);CHKERRQ(ierr);
8062   } else {
8063     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
8064   }
8065   PetscFunctionReturn(0);
8066 }
8067 
8068 /*@
8069    MatGetNullSpace - retrieves the null space to a matrix.
8070 
8071    Logically Collective on Mat and MatNullSpace
8072 
8073    Input Parameters:
8074 +  mat - the matrix
8075 -  nullsp - the null space object
8076 
8077    Level: developer
8078 
8079    Concepts: null space^attaching to matrix
8080 
8081 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace()
8082 @*/
8083 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
8084 {
8085   PetscFunctionBegin;
8086   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8087   PetscValidType(mat,1);
8088   PetscValidPointer(nullsp,2);
8089   *nullsp = mat->nullsp;
8090   PetscFunctionReturn(0);
8091 }
8092 
8093 /*@
8094    MatSetNullSpace - attaches a null space to a matrix.
8095 
8096    Logically Collective on Mat and MatNullSpace
8097 
8098    Input Parameters:
8099 +  mat - the matrix
8100 -  nullsp - the null space object
8101 
8102    Level: advanced
8103 
8104    Notes:
8105       This null space is used by the linear solvers. Overwrites any previous null space that may have been attached
8106 
8107       For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should
8108       call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense.
8109 
8110       You can remove the null space by calling this routine with an nullsp of NULL
8111 
8112 
8113       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8114    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).
8115    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
8116    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
8117    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).
8118 
8119       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8120 
8121     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
8122     routine also automatically calls MatSetTransposeNullSpace().
8123 
8124    Concepts: null space^attaching to matrix
8125 
8126 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8127 @*/
8128 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp)
8129 {
8130   PetscErrorCode ierr;
8131 
8132   PetscFunctionBegin;
8133   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8134   PetscValidType(mat,1);
8135   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8136   MatCheckPreallocated(mat,1);
8137   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8138   ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr);
8139   mat->nullsp = nullsp;
8140   if (mat->symmetric_set && mat->symmetric) {
8141     ierr = MatSetTransposeNullSpace(mat,nullsp);CHKERRQ(ierr);
8142   }
8143   PetscFunctionReturn(0);
8144 }
8145 
8146 /*@
8147    MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix.
8148 
8149    Logically Collective on Mat and MatNullSpace
8150 
8151    Input Parameters:
8152 +  mat - the matrix
8153 -  nullsp - the null space object
8154 
8155    Level: developer
8156 
8157    Concepts: null space^attaching to matrix
8158 
8159 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace()
8160 @*/
8161 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp)
8162 {
8163   PetscFunctionBegin;
8164   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8165   PetscValidType(mat,1);
8166   PetscValidPointer(nullsp,2);
8167   *nullsp = mat->transnullsp;
8168   PetscFunctionReturn(0);
8169 }
8170 
8171 /*@
8172    MatSetTransposeNullSpace - attaches a null space to a matrix.
8173 
8174    Logically Collective on Mat and MatNullSpace
8175 
8176    Input Parameters:
8177 +  mat - the matrix
8178 -  nullsp - the null space object
8179 
8180    Level: advanced
8181 
8182    Notes:
8183       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.
8184       You must also call MatSetNullSpace()
8185 
8186 
8187       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8188    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).
8189    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
8190    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
8191    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).
8192 
8193       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8194 
8195    Concepts: null space^attaching to matrix
8196 
8197 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8198 @*/
8199 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp)
8200 {
8201   PetscErrorCode ierr;
8202 
8203   PetscFunctionBegin;
8204   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8205   PetscValidType(mat,1);
8206   PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8207   MatCheckPreallocated(mat,1);
8208   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
8209   ierr = MatNullSpaceDestroy(&mat->transnullsp);CHKERRQ(ierr);
8210   mat->transnullsp = nullsp;
8211   PetscFunctionReturn(0);
8212 }
8213 
8214 /*@
8215    MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions
8216         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.
8217 
8218    Logically Collective on Mat and MatNullSpace
8219 
8220    Input Parameters:
8221 +  mat - the matrix
8222 -  nullsp - the null space object
8223 
8224    Level: advanced
8225 
8226    Notes:
8227       Overwrites any previous near null space that may have been attached
8228 
8229       You can remove the null space by calling this routine with an nullsp of NULL
8230 
8231    Concepts: null space^attaching to matrix
8232 
8233 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace()
8234 @*/
8235 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
8236 {
8237   PetscErrorCode ierr;
8238 
8239   PetscFunctionBegin;
8240   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8241   PetscValidType(mat,1);
8242   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8243   MatCheckPreallocated(mat,1);
8244   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8245   ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr);
8246   mat->nearnullsp = nullsp;
8247   PetscFunctionReturn(0);
8248 }
8249 
8250 /*@
8251    MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()
8252 
8253    Not Collective
8254 
8255    Input Parameters:
8256 .  mat - the matrix
8257 
8258    Output Parameters:
8259 .  nullsp - the null space object, NULL if not set
8260 
8261    Level: developer
8262 
8263    Concepts: null space^attaching to matrix
8264 
8265 .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate()
8266 @*/
8267 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
8268 {
8269   PetscFunctionBegin;
8270   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8271   PetscValidType(mat,1);
8272   PetscValidPointer(nullsp,2);
8273   MatCheckPreallocated(mat,1);
8274   *nullsp = mat->nearnullsp;
8275   PetscFunctionReturn(0);
8276 }
8277 
8278 /*@C
8279    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
8280 
8281    Collective on Mat
8282 
8283    Input Parameters:
8284 +  mat - the matrix
8285 .  row - row/column permutation
8286 .  fill - expected fill factor >= 1.0
8287 -  level - level of fill, for ICC(k)
8288 
8289    Notes:
8290    Probably really in-place only when level of fill is zero, otherwise allocates
8291    new space to store factored matrix and deletes previous memory.
8292 
8293    Most users should employ the simplified KSP interface for linear solvers
8294    instead of working directly with matrix algebra routines such as this.
8295    See, e.g., KSPCreate().
8296 
8297    Level: developer
8298 
8299    Concepts: matrices^incomplete Cholesky factorization
8300    Concepts: Cholesky factorization
8301 
8302 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
8303 
8304     Developer Note: fortran interface is not autogenerated as the f90
8305     interface defintion cannot be generated correctly [due to MatFactorInfo]
8306 
8307 @*/
8308 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
8309 {
8310   PetscErrorCode ierr;
8311 
8312   PetscFunctionBegin;
8313   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8314   PetscValidType(mat,1);
8315   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
8316   PetscValidPointer(info,3);
8317   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
8318   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8319   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8320   if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8321   MatCheckPreallocated(mat,1);
8322   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
8323   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8324   PetscFunctionReturn(0);
8325 }
8326 
8327 /*@
8328    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
8329          ghosted ones.
8330 
8331    Not Collective
8332 
8333    Input Parameters:
8334 +  mat - the matrix
8335 -  diag = the diagonal values, including ghost ones
8336 
8337    Level: developer
8338 
8339    Notes: Works only for MPIAIJ and MPIBAIJ matrices
8340 
8341 .seealso: MatDiagonalScale()
8342 @*/
8343 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
8344 {
8345   PetscErrorCode ierr;
8346   PetscMPIInt    size;
8347 
8348   PetscFunctionBegin;
8349   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8350   PetscValidHeaderSpecific(diag,VEC_CLASSID,2);
8351   PetscValidType(mat,1);
8352 
8353   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8354   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8355   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
8356   if (size == 1) {
8357     PetscInt n,m;
8358     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
8359     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
8360     if (m == n) {
8361       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
8362     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
8363   } else {
8364     ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr);
8365   }
8366   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8367   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8368   PetscFunctionReturn(0);
8369 }
8370 
8371 /*@
8372    MatGetInertia - Gets the inertia from a factored matrix
8373 
8374    Collective on Mat
8375 
8376    Input Parameter:
8377 .  mat - the matrix
8378 
8379    Output Parameters:
8380 +   nneg - number of negative eigenvalues
8381 .   nzero - number of zero eigenvalues
8382 -   npos - number of positive eigenvalues
8383 
8384    Level: advanced
8385 
8386    Notes: Matrix must have been factored by MatCholeskyFactor()
8387 
8388 
8389 @*/
8390 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
8391 {
8392   PetscErrorCode ierr;
8393 
8394   PetscFunctionBegin;
8395   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8396   PetscValidType(mat,1);
8397   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8398   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
8399   if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8400   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
8401   PetscFunctionReturn(0);
8402 }
8403 
8404 /* ----------------------------------------------------------------*/
8405 /*@C
8406    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
8407 
8408    Neighbor-wise Collective on Mat and Vecs
8409 
8410    Input Parameters:
8411 +  mat - the factored matrix
8412 -  b - the right-hand-side vectors
8413 
8414    Output Parameter:
8415 .  x - the result vectors
8416 
8417    Notes:
8418    The vectors b and x cannot be the same.  I.e., one cannot
8419    call MatSolves(A,x,x).
8420 
8421    Notes:
8422    Most users should employ the simplified KSP interface for linear solvers
8423    instead of working directly with matrix algebra routines such as this.
8424    See, e.g., KSPCreate().
8425 
8426    Level: developer
8427 
8428    Concepts: matrices^triangular solves
8429 
8430 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
8431 @*/
8432 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
8433 {
8434   PetscErrorCode ierr;
8435 
8436   PetscFunctionBegin;
8437   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8438   PetscValidType(mat,1);
8439   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
8440   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8441   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
8442 
8443   if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8444   MatCheckPreallocated(mat,1);
8445   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8446   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
8447   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8448   PetscFunctionReturn(0);
8449 }
8450 
8451 /*@
8452    MatIsSymmetric - Test whether a matrix is symmetric
8453 
8454    Collective on Mat
8455 
8456    Input Parameter:
8457 +  A - the matrix to test
8458 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
8459 
8460    Output Parameters:
8461 .  flg - the result
8462 
8463    Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
8464 
8465    Level: intermediate
8466 
8467    Concepts: matrix^symmetry
8468 
8469 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
8470 @*/
8471 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
8472 {
8473   PetscErrorCode ierr;
8474 
8475   PetscFunctionBegin;
8476   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8477   PetscValidPointer(flg,2);
8478 
8479   if (!A->symmetric_set) {
8480     if (!A->ops->issymmetric) {
8481       MatType mattype;
8482       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8483       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8484     }
8485     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8486     if (!tol) {
8487       A->symmetric_set = PETSC_TRUE;
8488       A->symmetric     = *flg;
8489       if (A->symmetric) {
8490         A->structurally_symmetric_set = PETSC_TRUE;
8491         A->structurally_symmetric     = PETSC_TRUE;
8492       }
8493     }
8494   } else if (A->symmetric) {
8495     *flg = PETSC_TRUE;
8496   } else if (!tol) {
8497     *flg = PETSC_FALSE;
8498   } else {
8499     if (!A->ops->issymmetric) {
8500       MatType mattype;
8501       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8502       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8503     }
8504     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8505   }
8506   PetscFunctionReturn(0);
8507 }
8508 
8509 /*@
8510    MatIsHermitian - Test whether a matrix is Hermitian
8511 
8512    Collective on Mat
8513 
8514    Input Parameter:
8515 +  A - the matrix to test
8516 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
8517 
8518    Output Parameters:
8519 .  flg - the result
8520 
8521    Level: intermediate
8522 
8523    Concepts: matrix^symmetry
8524 
8525 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
8526           MatIsSymmetricKnown(), MatIsSymmetric()
8527 @*/
8528 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
8529 {
8530   PetscErrorCode ierr;
8531 
8532   PetscFunctionBegin;
8533   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8534   PetscValidPointer(flg,2);
8535 
8536   if (!A->hermitian_set) {
8537     if (!A->ops->ishermitian) {
8538       MatType mattype;
8539       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8540       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8541     }
8542     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8543     if (!tol) {
8544       A->hermitian_set = PETSC_TRUE;
8545       A->hermitian     = *flg;
8546       if (A->hermitian) {
8547         A->structurally_symmetric_set = PETSC_TRUE;
8548         A->structurally_symmetric     = PETSC_TRUE;
8549       }
8550     }
8551   } else if (A->hermitian) {
8552     *flg = PETSC_TRUE;
8553   } else if (!tol) {
8554     *flg = PETSC_FALSE;
8555   } else {
8556     if (!A->ops->ishermitian) {
8557       MatType mattype;
8558       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8559       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8560     }
8561     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8562   }
8563   PetscFunctionReturn(0);
8564 }
8565 
8566 /*@
8567    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
8568 
8569    Not Collective
8570 
8571    Input Parameter:
8572 .  A - the matrix to check
8573 
8574    Output Parameters:
8575 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
8576 -  flg - the result
8577 
8578    Level: advanced
8579 
8580    Concepts: matrix^symmetry
8581 
8582    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
8583          if you want it explicitly checked
8584 
8585 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8586 @*/
8587 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8588 {
8589   PetscFunctionBegin;
8590   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8591   PetscValidPointer(set,2);
8592   PetscValidPointer(flg,3);
8593   if (A->symmetric_set) {
8594     *set = PETSC_TRUE;
8595     *flg = A->symmetric;
8596   } else {
8597     *set = PETSC_FALSE;
8598   }
8599   PetscFunctionReturn(0);
8600 }
8601 
8602 /*@
8603    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
8604 
8605    Not Collective
8606 
8607    Input Parameter:
8608 .  A - the matrix to check
8609 
8610    Output Parameters:
8611 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8612 -  flg - the result
8613 
8614    Level: advanced
8615 
8616    Concepts: matrix^symmetry
8617 
8618    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8619          if you want it explicitly checked
8620 
8621 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8622 @*/
8623 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8624 {
8625   PetscFunctionBegin;
8626   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8627   PetscValidPointer(set,2);
8628   PetscValidPointer(flg,3);
8629   if (A->hermitian_set) {
8630     *set = PETSC_TRUE;
8631     *flg = A->hermitian;
8632   } else {
8633     *set = PETSC_FALSE;
8634   }
8635   PetscFunctionReturn(0);
8636 }
8637 
8638 /*@
8639    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
8640 
8641    Collective on Mat
8642 
8643    Input Parameter:
8644 .  A - the matrix to test
8645 
8646    Output Parameters:
8647 .  flg - the result
8648 
8649    Level: intermediate
8650 
8651    Concepts: matrix^symmetry
8652 
8653 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8654 @*/
8655 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
8656 {
8657   PetscErrorCode ierr;
8658 
8659   PetscFunctionBegin;
8660   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8661   PetscValidPointer(flg,2);
8662   if (!A->structurally_symmetric_set) {
8663     if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8664     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
8665 
8666     A->structurally_symmetric_set = PETSC_TRUE;
8667   }
8668   *flg = A->structurally_symmetric;
8669   PetscFunctionReturn(0);
8670 }
8671 
8672 /*@
8673    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8674        to be communicated to other processors during the MatAssemblyBegin/End() process
8675 
8676     Not collective
8677 
8678    Input Parameter:
8679 .   vec - the vector
8680 
8681    Output Parameters:
8682 +   nstash   - the size of the stash
8683 .   reallocs - the number of additional mallocs incurred.
8684 .   bnstash   - the size of the block stash
8685 -   breallocs - the number of additional mallocs incurred.in the block stash
8686 
8687    Level: advanced
8688 
8689 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
8690 
8691 @*/
8692 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8693 {
8694   PetscErrorCode ierr;
8695 
8696   PetscFunctionBegin;
8697   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
8698   ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
8699   PetscFunctionReturn(0);
8700 }
8701 
8702 /*@C
8703    MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same
8704      parallel layout
8705 
8706    Collective on Mat
8707 
8708    Input Parameter:
8709 .  mat - the matrix
8710 
8711    Output Parameter:
8712 +   right - (optional) vector that the matrix can be multiplied against
8713 -   left - (optional) vector that the matrix vector product can be stored in
8714 
8715    Notes:
8716     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().
8717 
8718   Notes: These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed
8719 
8720   Level: advanced
8721 
8722 .seealso: MatCreate(), VecDestroy()
8723 @*/
8724 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left)
8725 {
8726   PetscErrorCode ierr;
8727 
8728   PetscFunctionBegin;
8729   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8730   PetscValidType(mat,1);
8731   if (mat->ops->getvecs) {
8732     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
8733   } else {
8734     PetscInt rbs,cbs;
8735     ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr);
8736     if (right) {
8737       if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup");
8738       ierr = VecCreate(PetscObjectComm((PetscObject)mat),right);CHKERRQ(ierr);
8739       ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8740       ierr = VecSetBlockSize(*right,cbs);CHKERRQ(ierr);
8741       ierr = VecSetType(*right,VECSTANDARD);CHKERRQ(ierr);
8742       ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr);
8743     }
8744     if (left) {
8745       if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup");
8746       ierr = VecCreate(PetscObjectComm((PetscObject)mat),left);CHKERRQ(ierr);
8747       ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8748       ierr = VecSetBlockSize(*left,rbs);CHKERRQ(ierr);
8749       ierr = VecSetType(*left,VECSTANDARD);CHKERRQ(ierr);
8750       ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr);
8751     }
8752   }
8753   PetscFunctionReturn(0);
8754 }
8755 
8756 /*@C
8757    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8758      with default values.
8759 
8760    Not Collective
8761 
8762    Input Parameters:
8763 .    info - the MatFactorInfo data structure
8764 
8765 
8766    Notes: The solvers are generally used through the KSP and PC objects, for example
8767           PCLU, PCILU, PCCHOLESKY, PCICC
8768 
8769    Level: developer
8770 
8771 .seealso: MatFactorInfo
8772 
8773     Developer Note: fortran interface is not autogenerated as the f90
8774     interface defintion cannot be generated correctly [due to MatFactorInfo]
8775 
8776 @*/
8777 
8778 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
8779 {
8780   PetscErrorCode ierr;
8781 
8782   PetscFunctionBegin;
8783   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
8784   PetscFunctionReturn(0);
8785 }
8786 
8787 /*@
8788    MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed
8789 
8790    Collective on Mat
8791 
8792    Input Parameters:
8793 +  mat - the factored matrix
8794 -  is - the index set defining the Schur indices (0-based)
8795 
8796    Notes:  Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system.
8797 
8798    You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call.
8799 
8800    Level: developer
8801 
8802    Concepts:
8803 
8804 .seealso: MatGetFactor(), MatFactorGetSchurComplement(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSolveSchurComplement(),
8805           MatFactorSolveSchurComplementTranspose(), MatFactorSolveSchurComplement()
8806 
8807 @*/
8808 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is)
8809 {
8810   PetscErrorCode ierr,(*f)(Mat,IS);
8811 
8812   PetscFunctionBegin;
8813   PetscValidType(mat,1);
8814   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8815   PetscValidType(is,2);
8816   PetscValidHeaderSpecific(is,IS_CLASSID,2);
8817   PetscCheckSameComm(mat,1,is,2);
8818   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
8819   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);CHKERRQ(ierr);
8820   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");
8821   if (mat->schur) {
8822     ierr = MatDestroy(&mat->schur);CHKERRQ(ierr);
8823   }
8824   ierr = (*f)(mat,is);CHKERRQ(ierr);
8825   if (!mat->schur) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created");
8826   ierr = MatFactorSetUpInPlaceSchur_Private(mat);CHKERRQ(ierr);
8827   PetscFunctionReturn(0);
8828 }
8829 
8830 /*@
8831   MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step
8832 
8833    Logically Collective on Mat
8834 
8835    Input Parameters:
8836 +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
8837 .  S - location where to return the Schur complement, can be NULL
8838 -  status - the status of the Schur complement matrix, can be NULL
8839 
8840    Notes:
8841    You must call MatFactorSetSchurIS() before calling this routine.
8842 
8843    The routine provides a copy of the Schur matrix stored within the solver data structures.
8844    The caller must destroy the object when it is no longer needed.
8845    If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse.
8846 
8847    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)
8848 
8849    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
8850    matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix.
8851 
8852    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
8853 
8854    Level: advanced
8855 
8856    References:
8857 
8858 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorSchurStatus
8859 @*/
8860 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
8861 {
8862   PetscErrorCode ierr;
8863 
8864   PetscFunctionBegin;
8865   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8866   if (S) PetscValidPointer(S,2);
8867   if (status) PetscValidPointer(status,3);
8868   if (S) {
8869     PetscErrorCode (*f)(Mat,Mat*);
8870 
8871     ierr = PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f);CHKERRQ(ierr);
8872     if (f) {
8873       ierr = (*f)(F,S);CHKERRQ(ierr);
8874     } else {
8875       ierr = MatDuplicate(F->schur,MAT_COPY_VALUES,S);CHKERRQ(ierr);
8876     }
8877   }
8878   if (status) *status = F->schur_status;
8879   PetscFunctionReturn(0);
8880 }
8881 
8882 /*@
8883   MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix
8884 
8885    Logically Collective on Mat
8886 
8887    Input Parameters:
8888 +  F - the factored matrix obtained by calling MatGetFactor()
8889 .  *S - location where to return the Schur complement, can be NULL
8890 -  status - the status of the Schur complement matrix, can be NULL
8891 
8892    Notes:
8893    You must call MatFactorSetSchurIS() before calling this routine.
8894 
8895    Schur complement mode is currently implemented for sequential matrices.
8896    The routine returns a the Schur Complement stored within the data strutures of the solver.
8897    If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement.
8898    The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed.
8899 
8900    Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix
8901 
8902    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
8903 
8904    Level: advanced
8905 
8906    References:
8907 
8908 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
8909 @*/
8910 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
8911 {
8912   PetscFunctionBegin;
8913   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8914   if (S) PetscValidPointer(S,2);
8915   if (status) PetscValidPointer(status,3);
8916   if (S) *S = F->schur;
8917   if (status) *status = F->schur_status;
8918   PetscFunctionReturn(0);
8919 }
8920 
8921 /*@
8922   MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement
8923 
8924    Logically Collective on Mat
8925 
8926    Input Parameters:
8927 +  F - the factored matrix obtained by calling MatGetFactor()
8928 .  *S - location where the Schur complement is stored
8929 -  status - the status of the Schur complement matrix (see MatFactorSchurStatus)
8930 
8931    Notes:
8932 
8933    Level: advanced
8934 
8935    References:
8936 
8937 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
8938 @*/
8939 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status)
8940 {
8941   PetscErrorCode ierr;
8942 
8943   PetscFunctionBegin;
8944   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8945   if (S) {
8946     PetscValidHeaderSpecific(*S,MAT_CLASSID,2);
8947     *S = NULL;
8948   }
8949   F->schur_status = status;
8950   ierr = MatFactorUpdateSchurStatus_Private(F);CHKERRQ(ierr);
8951   PetscFunctionReturn(0);
8952 }
8953 
8954 /*@
8955   MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step
8956 
8957    Logically Collective on Mat
8958 
8959    Input Parameters:
8960 +  F - the factored matrix obtained by calling MatGetFactor()
8961 .  rhs - location where the right hand side of the Schur complement system is stored
8962 -  sol - location where the solution of the Schur complement system has to be returned
8963 
8964    Notes:
8965    The sizes of the vectors should match the size of the Schur complement
8966 
8967    Must be called after MatFactorSetSchurIS()
8968 
8969    Level: advanced
8970 
8971    References:
8972 
8973 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplement()
8974 @*/
8975 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol)
8976 {
8977   PetscErrorCode ierr;
8978 
8979   PetscFunctionBegin;
8980   PetscValidType(F,1);
8981   PetscValidType(rhs,2);
8982   PetscValidType(sol,3);
8983   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8984   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
8985   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
8986   PetscCheckSameComm(F,1,rhs,2);
8987   PetscCheckSameComm(F,1,sol,3);
8988   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
8989   switch (F->schur_status) {
8990   case MAT_FACTOR_SCHUR_FACTORED:
8991     ierr = MatSolveTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
8992     break;
8993   case MAT_FACTOR_SCHUR_INVERTED:
8994     ierr = MatMultTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
8995     break;
8996   default:
8997     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
8998     break;
8999   }
9000   PetscFunctionReturn(0);
9001 }
9002 
9003 /*@
9004   MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step
9005 
9006    Logically Collective on Mat
9007 
9008    Input Parameters:
9009 +  F - the factored matrix obtained by calling MatGetFactor()
9010 .  rhs - location where the right hand side of the Schur complement system is stored
9011 -  sol - location where the solution of the Schur complement system has to be returned
9012 
9013    Notes:
9014    The sizes of the vectors should match the size of the Schur complement
9015 
9016    Must be called after MatFactorSetSchurIS()
9017 
9018    Level: advanced
9019 
9020    References:
9021 
9022 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplementTranspose()
9023 @*/
9024 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol)
9025 {
9026   PetscErrorCode ierr;
9027 
9028   PetscFunctionBegin;
9029   PetscValidType(F,1);
9030   PetscValidType(rhs,2);
9031   PetscValidType(sol,3);
9032   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9033   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
9034   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
9035   PetscCheckSameComm(F,1,rhs,2);
9036   PetscCheckSameComm(F,1,sol,3);
9037   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9038   switch (F->schur_status) {
9039   case MAT_FACTOR_SCHUR_FACTORED:
9040     ierr = MatSolve(F->schur,rhs,sol);CHKERRQ(ierr);
9041     break;
9042   case MAT_FACTOR_SCHUR_INVERTED:
9043     ierr = MatMult(F->schur,rhs,sol);CHKERRQ(ierr);
9044     break;
9045   default:
9046     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9047     break;
9048   }
9049   PetscFunctionReturn(0);
9050 }
9051 
9052 /*@
9053   MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step
9054 
9055    Logically Collective on Mat
9056 
9057    Input Parameters:
9058 +  F - the factored matrix obtained by calling MatGetFactor()
9059 
9060    Notes: Must be called after MatFactorSetSchurIS().
9061 
9062    Call MatFactorGetSchurComplement() or  MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it.
9063 
9064    Level: advanced
9065 
9066    References:
9067 
9068 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorCreateSchurComplement()
9069 @*/
9070 PetscErrorCode MatFactorInvertSchurComplement(Mat F)
9071 {
9072   PetscErrorCode ierr;
9073 
9074   PetscFunctionBegin;
9075   PetscValidType(F,1);
9076   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9077   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0);
9078   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9079   ierr = MatFactorInvertSchurComplement_Private(F);CHKERRQ(ierr);
9080   F->schur_status = MAT_FACTOR_SCHUR_INVERTED;
9081   PetscFunctionReturn(0);
9082 }
9083 
9084 /*@
9085   MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step
9086 
9087    Logically Collective on Mat
9088 
9089    Input Parameters:
9090 +  F - the factored matrix obtained by calling MatGetFactor()
9091 
9092    Notes: Must be called after MatFactorSetSchurIS().
9093 
9094    Level: advanced
9095 
9096    References:
9097 
9098 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorInvertSchurComplement()
9099 @*/
9100 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F)
9101 {
9102   PetscErrorCode ierr;
9103 
9104   PetscFunctionBegin;
9105   PetscValidType(F,1);
9106   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9107   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0);
9108   ierr = MatFactorFactorizeSchurComplement_Private(F);CHKERRQ(ierr);
9109   F->schur_status = MAT_FACTOR_SCHUR_FACTORED;
9110   PetscFunctionReturn(0);
9111 }
9112 
9113 /*@
9114    MatPtAP - Creates the matrix product C = P^T * A * P
9115 
9116    Neighbor-wise Collective on Mat
9117 
9118    Input Parameters:
9119 +  A - the matrix
9120 .  P - the projection matrix
9121 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9122 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate
9123           if the result is a dense matrix this is irrelevent
9124 
9125    Output Parameters:
9126 .  C - the product matrix
9127 
9128    Notes:
9129    C will be created and must be destroyed by the user with MatDestroy().
9130 
9131    This routine is currently only implemented for pairs of sequential dense matrices, AIJ matrices and classes
9132    which inherit from AIJ.
9133 
9134    Level: intermediate
9135 
9136 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
9137 @*/
9138 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
9139 {
9140   PetscErrorCode ierr;
9141   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9142   PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
9143   PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9144 
9145   PetscFunctionBegin;
9146   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9147   PetscValidType(A,1);
9148   MatCheckPreallocated(A,1);
9149   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9150   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9151   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9152   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9153   PetscValidType(P,2);
9154   MatCheckPreallocated(P,2);
9155   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9156   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9157 
9158   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);
9159   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);
9160   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9161   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9162 
9163   if (scall == MAT_REUSE_MATRIX) {
9164     PetscValidPointer(*C,5);
9165     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9166 
9167     ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9168     ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9169     ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr);
9170     ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9171     ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9172     PetscFunctionReturn(0);
9173   }
9174 
9175   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9176   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9177 
9178   fA = A->ops->ptap;
9179   fP = P->ops->ptap;
9180   if (fP == fA) {
9181     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name);
9182     ptap = fA;
9183   } else {
9184     /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
9185     char ptapname[256];
9186     ierr = PetscStrcpy(ptapname,"MatPtAP_");CHKERRQ(ierr);
9187     ierr = PetscStrcat(ptapname,((PetscObject)A)->type_name);CHKERRQ(ierr);
9188     ierr = PetscStrcat(ptapname,"_");CHKERRQ(ierr);
9189     ierr = PetscStrcat(ptapname,((PetscObject)P)->type_name);CHKERRQ(ierr);
9190     ierr = PetscStrcat(ptapname,"_C");CHKERRQ(ierr); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
9191     ierr = PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);CHKERRQ(ierr);
9192     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);
9193   }
9194 
9195   ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9196   ierr = (*ptap)(A,P,scall,fill,C);CHKERRQ(ierr);
9197   ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9198   PetscFunctionReturn(0);
9199 }
9200 
9201 /*@
9202    MatPtAPNumeric - Computes the matrix product C = P^T * A * P
9203 
9204    Neighbor-wise Collective on Mat
9205 
9206    Input Parameters:
9207 +  A - the matrix
9208 -  P - the projection matrix
9209 
9210    Output Parameters:
9211 .  C - the product matrix
9212 
9213    Notes:
9214    C must have been created by calling MatPtAPSymbolic and must be destroyed by
9215    the user using MatDeatroy().
9216 
9217    This routine is currently only implemented for pairs of AIJ matrices and classes
9218    which inherit from AIJ.  C will be of type MATAIJ.
9219 
9220    Level: intermediate
9221 
9222 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
9223 @*/
9224 PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C)
9225 {
9226   PetscErrorCode ierr;
9227 
9228   PetscFunctionBegin;
9229   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9230   PetscValidType(A,1);
9231   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9232   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9233   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9234   PetscValidType(P,2);
9235   MatCheckPreallocated(P,2);
9236   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9237   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9238   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9239   PetscValidType(C,3);
9240   MatCheckPreallocated(C,3);
9241   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9242   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);
9243   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);
9244   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);
9245   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);
9246   MatCheckPreallocated(A,1);
9247 
9248   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9249   ierr = (*C->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr);
9250   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9251   PetscFunctionReturn(0);
9252 }
9253 
9254 /*@
9255    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P
9256 
9257    Neighbor-wise Collective on Mat
9258 
9259    Input Parameters:
9260 +  A - the matrix
9261 -  P - the projection matrix
9262 
9263    Output Parameters:
9264 .  C - the (i,j) structure of the product matrix
9265 
9266    Notes:
9267    C will be created and must be destroyed by the user with MatDestroy().
9268 
9269    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9270    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9271    this (i,j) structure by calling MatPtAPNumeric().
9272 
9273    Level: intermediate
9274 
9275 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
9276 @*/
9277 PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
9278 {
9279   PetscErrorCode ierr;
9280 
9281   PetscFunctionBegin;
9282   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9283   PetscValidType(A,1);
9284   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9285   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9286   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9287   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9288   PetscValidType(P,2);
9289   MatCheckPreallocated(P,2);
9290   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9291   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9292   PetscValidPointer(C,3);
9293 
9294   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);
9295   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);
9296   MatCheckPreallocated(A,1);
9297   ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
9298   ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr);
9299   ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
9300 
9301   /* ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); NO! this is not always true -ma */
9302   PetscFunctionReturn(0);
9303 }
9304 
9305 /*@
9306    MatRARt - Creates the matrix product C = R * A * R^T
9307 
9308    Neighbor-wise Collective on Mat
9309 
9310    Input Parameters:
9311 +  A - the matrix
9312 .  R - the projection matrix
9313 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9314 -  fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate
9315           if the result is a dense matrix this is irrelevent
9316 
9317    Output Parameters:
9318 .  C - the product matrix
9319 
9320    Notes:
9321    C will be created and must be destroyed by the user with MatDestroy().
9322 
9323    This routine is currently only implemented for pairs of AIJ matrices and classes
9324    which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes,
9325    parallel MatRARt is implemented via explicit transpose of R, which could be very expensive.
9326    We recommend using MatPtAP().
9327 
9328    Level: intermediate
9329 
9330 .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
9331 @*/
9332 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
9333 {
9334   PetscErrorCode ierr;
9335 
9336   PetscFunctionBegin;
9337   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9338   PetscValidType(A,1);
9339   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9340   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9341   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9342   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9343   PetscValidType(R,2);
9344   MatCheckPreallocated(R,2);
9345   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9346   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9347   PetscValidPointer(C,3);
9348   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);
9349 
9350   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9351   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9352   MatCheckPreallocated(A,1);
9353 
9354   if (!A->ops->rart) {
9355     Mat Rt;
9356     ierr = MatTranspose(R,MAT_INITIAL_MATRIX,&Rt);CHKERRQ(ierr);
9357     ierr = MatMatMatMult(R,A,Rt,scall,fill,C);CHKERRQ(ierr);
9358     ierr = MatDestroy(&Rt);CHKERRQ(ierr);
9359   }
9360   ierr = PetscLogEventBegin(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
9361   ierr = (*A->ops->rart)(A,R,scall,fill,C);CHKERRQ(ierr);
9362   ierr = PetscLogEventEnd(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
9363   PetscFunctionReturn(0);
9364 }
9365 
9366 /*@
9367    MatRARtNumeric - Computes the matrix product C = R * A * R^T
9368 
9369    Neighbor-wise Collective on Mat
9370 
9371    Input Parameters:
9372 +  A - the matrix
9373 -  R - the projection matrix
9374 
9375    Output Parameters:
9376 .  C - the product matrix
9377 
9378    Notes:
9379    C must have been created by calling MatRARtSymbolic and must be destroyed by
9380    the user using MatDestroy().
9381 
9382    This routine is currently only implemented for pairs of AIJ matrices and classes
9383    which inherit from AIJ.  C will be of type MATAIJ.
9384 
9385    Level: intermediate
9386 
9387 .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
9388 @*/
9389 PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C)
9390 {
9391   PetscErrorCode ierr;
9392 
9393   PetscFunctionBegin;
9394   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9395   PetscValidType(A,1);
9396   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9397   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9398   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9399   PetscValidType(R,2);
9400   MatCheckPreallocated(R,2);
9401   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9402   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9403   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9404   PetscValidType(C,3);
9405   MatCheckPreallocated(C,3);
9406   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9407   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);
9408   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);
9409   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);
9410   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);
9411   MatCheckPreallocated(A,1);
9412 
9413   ierr = PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
9414   ierr = (*A->ops->rartnumeric)(A,R,C);CHKERRQ(ierr);
9415   ierr = PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
9416   PetscFunctionReturn(0);
9417 }
9418 
9419 /*@
9420    MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T
9421 
9422    Neighbor-wise Collective on Mat
9423 
9424    Input Parameters:
9425 +  A - the matrix
9426 -  R - the projection matrix
9427 
9428    Output Parameters:
9429 .  C - the (i,j) structure of the product matrix
9430 
9431    Notes:
9432    C will be created and must be destroyed by the user with MatDestroy().
9433 
9434    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9435    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9436    this (i,j) structure by calling MatRARtNumeric().
9437 
9438    Level: intermediate
9439 
9440 .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
9441 @*/
9442 PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
9443 {
9444   PetscErrorCode ierr;
9445 
9446   PetscFunctionBegin;
9447   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9448   PetscValidType(A,1);
9449   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9450   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9451   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9452   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9453   PetscValidType(R,2);
9454   MatCheckPreallocated(R,2);
9455   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9456   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9457   PetscValidPointer(C,3);
9458 
9459   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);
9460   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);
9461   MatCheckPreallocated(A,1);
9462   ierr = PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
9463   ierr = (*A->ops->rartsymbolic)(A,R,fill,C);CHKERRQ(ierr);
9464   ierr = PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
9465 
9466   ierr = MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));CHKERRQ(ierr);
9467   PetscFunctionReturn(0);
9468 }
9469 
9470 /*@
9471    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
9472 
9473    Neighbor-wise Collective on Mat
9474 
9475    Input Parameters:
9476 +  A - the left matrix
9477 .  B - the right matrix
9478 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9479 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
9480           if the result is a dense matrix this is irrelevent
9481 
9482    Output Parameters:
9483 .  C - the product matrix
9484 
9485    Notes:
9486    Unless scall is MAT_REUSE_MATRIX C will be created.
9487 
9488    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
9489    call to this function with either MAT_INITIAL_MATRIX or MatMatMultSymbolic()
9490 
9491    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9492    actually needed.
9493 
9494    If you have many matrices with the same non-zero structure to multiply, you
9495    should either
9496 $   1) use MAT_REUSE_MATRIX in all calls but the first or
9497 $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
9498    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
9499    with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse.
9500 
9501    Level: intermediate
9502 
9503 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(),  MatMatTransposeMult(), MatPtAP()
9504 @*/
9505 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9506 {
9507   PetscErrorCode ierr;
9508   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9509   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9510   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9511 
9512   PetscFunctionBegin;
9513   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9514   PetscValidType(A,1);
9515   MatCheckPreallocated(A,1);
9516   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9517   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9518   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9519   PetscValidType(B,2);
9520   MatCheckPreallocated(B,2);
9521   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9522   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9523   PetscValidPointer(C,3);
9524   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9525   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);
9526   if (scall == MAT_REUSE_MATRIX) {
9527     PetscValidPointer(*C,5);
9528     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9529     ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9530     ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9531     ierr = (*(*C)->ops->matmultnumeric)(A,B,*C);CHKERRQ(ierr);
9532     ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9533     ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9534     PetscFunctionReturn(0);
9535   }
9536   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9537   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9538 
9539   fA = A->ops->matmult;
9540   fB = B->ops->matmult;
9541   if (fB == fA) {
9542     if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
9543     mult = fB;
9544   } else {
9545     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9546     char multname[256];
9547     ierr = PetscStrcpy(multname,"MatMatMult_");CHKERRQ(ierr);
9548     ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr);
9549     ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);
9550     ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr);
9551     ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9552     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
9553     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);
9554   }
9555   ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9556   ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr);
9557   ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9558   PetscFunctionReturn(0);
9559 }
9560 
9561 /*@
9562    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
9563    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().
9564 
9565    Neighbor-wise Collective on Mat
9566 
9567    Input Parameters:
9568 +  A - the left matrix
9569 .  B - the right matrix
9570 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
9571       if C is a dense matrix this is irrelevent
9572 
9573    Output Parameters:
9574 .  C - the product matrix
9575 
9576    Notes:
9577    Unless scall is MAT_REUSE_MATRIX C will be created.
9578 
9579    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9580    actually needed.
9581 
9582    This routine is currently implemented for
9583     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
9584     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9585     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9586 
9587    Level: intermediate
9588 
9589    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
9590      We should incorporate them into PETSc.
9591 
9592 .seealso: MatMatMult(), MatMatMultNumeric()
9593 @*/
9594 PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
9595 {
9596   PetscErrorCode ierr;
9597   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*);
9598   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*);
9599   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL;
9600 
9601   PetscFunctionBegin;
9602   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9603   PetscValidType(A,1);
9604   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9605   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9606 
9607   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9608   PetscValidType(B,2);
9609   MatCheckPreallocated(B,2);
9610   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9611   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9612   PetscValidPointer(C,3);
9613 
9614   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);
9615   if (fill == PETSC_DEFAULT) fill = 2.0;
9616   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9617   MatCheckPreallocated(A,1);
9618 
9619   Asymbolic = A->ops->matmultsymbolic;
9620   Bsymbolic = B->ops->matmultsymbolic;
9621   if (Asymbolic == Bsymbolic) {
9622     if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
9623     symbolic = Bsymbolic;
9624   } else { /* dispatch based on the type of A and B */
9625     char symbolicname[256];
9626     ierr = PetscStrcpy(symbolicname,"MatMatMultSymbolic_");CHKERRQ(ierr);
9627     ierr = PetscStrcat(symbolicname,((PetscObject)A)->type_name);CHKERRQ(ierr);
9628     ierr = PetscStrcat(symbolicname,"_");CHKERRQ(ierr);
9629     ierr = PetscStrcat(symbolicname,((PetscObject)B)->type_name);CHKERRQ(ierr);
9630     ierr = PetscStrcat(symbolicname,"_C");CHKERRQ(ierr);
9631     ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);CHKERRQ(ierr);
9632     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);
9633   }
9634   ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9635   ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr);
9636   ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9637   PetscFunctionReturn(0);
9638 }
9639 
9640 /*@
9641    MatMatMultNumeric - Performs the numeric matrix-matrix product.
9642    Call this routine after first calling MatMatMultSymbolic().
9643 
9644    Neighbor-wise Collective on Mat
9645 
9646    Input Parameters:
9647 +  A - the left matrix
9648 -  B - the right matrix
9649 
9650    Output Parameters:
9651 .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
9652 
9653    Notes:
9654    C must have been created with MatMatMultSymbolic().
9655 
9656    This routine is currently implemented for
9657     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
9658     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9659     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9660 
9661    Level: intermediate
9662 
9663 .seealso: MatMatMult(), MatMatMultSymbolic()
9664 @*/
9665 PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C)
9666 {
9667   PetscErrorCode ierr;
9668 
9669   PetscFunctionBegin;
9670   ierr = MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);CHKERRQ(ierr);
9671   PetscFunctionReturn(0);
9672 }
9673 
9674 /*@
9675    MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.
9676 
9677    Neighbor-wise Collective on Mat
9678 
9679    Input Parameters:
9680 +  A - the left matrix
9681 .  B - the right matrix
9682 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9683 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9684 
9685    Output Parameters:
9686 .  C - the product matrix
9687 
9688    Notes:
9689    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9690 
9691    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9692 
9693   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9694    actually needed.
9695 
9696    This routine is currently only implemented for pairs of SeqAIJ matrices and for the SeqDense class.
9697 
9698    Level: intermediate
9699 
9700 .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
9701 @*/
9702 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9703 {
9704   PetscErrorCode ierr;
9705   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9706   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9707 
9708   PetscFunctionBegin;
9709   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9710   PetscValidType(A,1);
9711   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9712   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9713   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9714   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9715   PetscValidType(B,2);
9716   MatCheckPreallocated(B,2);
9717   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9718   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9719   PetscValidPointer(C,3);
9720   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);
9721   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9722   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9723   MatCheckPreallocated(A,1);
9724 
9725   fA = A->ops->mattransposemult;
9726   if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
9727   fB = B->ops->mattransposemult;
9728   if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
9729   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);
9730 
9731   ierr = PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
9732   if (scall == MAT_INITIAL_MATRIX) {
9733     ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9734     ierr = (*A->ops->mattransposemultsymbolic)(A,B,fill,C);CHKERRQ(ierr);
9735     ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9736   }
9737   ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
9738   ierr = (*A->ops->mattransposemultnumeric)(A,B,*C);CHKERRQ(ierr);
9739   ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
9740   ierr = PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
9741   PetscFunctionReturn(0);
9742 }
9743 
9744 /*@
9745    MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.
9746 
9747    Neighbor-wise Collective on Mat
9748 
9749    Input Parameters:
9750 +  A - the left matrix
9751 .  B - the right matrix
9752 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9753 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9754 
9755    Output Parameters:
9756 .  C - the product matrix
9757 
9758    Notes:
9759    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9760 
9761    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9762 
9763   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9764    actually needed.
9765 
9766    This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
9767    which inherit from SeqAIJ.  C will be of same type as the input matrices.
9768 
9769    Level: intermediate
9770 
9771 .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
9772 @*/
9773 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9774 {
9775   PetscErrorCode ierr;
9776   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9777   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9778   PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL;
9779 
9780   PetscFunctionBegin;
9781   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9782   PetscValidType(A,1);
9783   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9784   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9785   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9786   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9787   PetscValidType(B,2);
9788   MatCheckPreallocated(B,2);
9789   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9790   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9791   PetscValidPointer(C,3);
9792   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);
9793   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9794   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9795   MatCheckPreallocated(A,1);
9796 
9797   fA = A->ops->transposematmult;
9798   fB = B->ops->transposematmult;
9799   if (fB==fA) {
9800     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9801     transposematmult = fA;
9802   } else {
9803     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9804     char multname[256];
9805     ierr = PetscStrcpy(multname,"MatTransposeMatMult_");CHKERRQ(ierr);
9806     ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr);
9807     ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);
9808     ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr);
9809     ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9810     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);CHKERRQ(ierr);
9811     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);
9812   }
9813   ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
9814   ierr = (*transposematmult)(A,B,scall,fill,C);CHKERRQ(ierr);
9815   ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
9816   PetscFunctionReturn(0);
9817 }
9818 
9819 /*@
9820    MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.
9821 
9822    Neighbor-wise Collective on Mat
9823 
9824    Input Parameters:
9825 +  A - the left matrix
9826 .  B - the middle matrix
9827 .  C - the right matrix
9828 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9829 -  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
9830           if the result is a dense matrix this is irrelevent
9831 
9832    Output Parameters:
9833 .  D - the product matrix
9834 
9835    Notes:
9836    Unless scall is MAT_REUSE_MATRIX D will be created.
9837 
9838    MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call
9839 
9840    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9841    actually needed.
9842 
9843    If you have many matrices with the same non-zero structure to multiply, you
9844    should use MAT_REUSE_MATRIX in all calls but the first or
9845 
9846    Level: intermediate
9847 
9848 .seealso: MatMatMult, MatPtAP()
9849 @*/
9850 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
9851 {
9852   PetscErrorCode ierr;
9853   PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9854   PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9855   PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9856   PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9857 
9858   PetscFunctionBegin;
9859   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9860   PetscValidType(A,1);
9861   MatCheckPreallocated(A,1);
9862   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9863   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9864   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9865   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9866   PetscValidType(B,2);
9867   MatCheckPreallocated(B,2);
9868   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9869   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9870   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9871   PetscValidPointer(C,3);
9872   MatCheckPreallocated(C,3);
9873   if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9874   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9875   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);
9876   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);
9877   if (scall == MAT_REUSE_MATRIX) {
9878     PetscValidPointer(*D,6);
9879     PetscValidHeaderSpecific(*D,MAT_CLASSID,6);
9880     ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9881     ierr = (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
9882     ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9883     PetscFunctionReturn(0);
9884   }
9885   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9886   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9887 
9888   fA = A->ops->matmatmult;
9889   fB = B->ops->matmatmult;
9890   fC = C->ops->matmatmult;
9891   if (fA == fB && fA == fC) {
9892     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9893     mult = fA;
9894   } else {
9895     /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */
9896     char multname[256];
9897     ierr = PetscStrcpy(multname,"MatMatMatMult_");CHKERRQ(ierr);
9898     ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr);
9899     ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);
9900     ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr);
9901     ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);
9902     ierr = PetscStrcat(multname,((PetscObject)C)->type_name);CHKERRQ(ierr);
9903     ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr);
9904     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
9905     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);
9906   }
9907   ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9908   ierr = (*mult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
9909   ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9910   PetscFunctionReturn(0);
9911 }
9912 
9913 /*@
9914    MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
9915 
9916    Collective on Mat
9917 
9918    Input Parameters:
9919 +  mat - the matrix
9920 .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
9921 .  subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used)
9922 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9923 
9924    Output Parameter:
9925 .  matredundant - redundant matrix
9926 
9927    Notes:
9928    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
9929    original matrix has not changed from that last call to MatCreateRedundantMatrix().
9930 
9931    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
9932    calling it.
9933 
9934    Level: advanced
9935 
9936    Concepts: subcommunicator
9937    Concepts: duplicate matrix
9938 
9939 .seealso: MatDestroy()
9940 @*/
9941 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant)
9942 {
9943   PetscErrorCode ierr;
9944   MPI_Comm       comm;
9945   PetscMPIInt    size;
9946   PetscInt       mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs;
9947   Mat_Redundant  *redund=NULL;
9948   PetscSubcomm   psubcomm=NULL;
9949   MPI_Comm       subcomm_in=subcomm;
9950   Mat            *matseq;
9951   IS             isrow,iscol;
9952   PetscBool      newsubcomm=PETSC_FALSE;
9953 
9954   PetscFunctionBegin;
9955   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9956   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
9957     PetscValidPointer(*matredundant,5);
9958     PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5);
9959   }
9960 
9961   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
9962   if (size == 1 || nsubcomm == 1) {
9963     if (reuse == MAT_INITIAL_MATRIX) {
9964       ierr = MatDuplicate(mat,MAT_COPY_VALUES,matredundant);CHKERRQ(ierr);
9965     } else {
9966       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");
9967       ierr = MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
9968     }
9969     PetscFunctionReturn(0);
9970   }
9971 
9972   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9973   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9974   MatCheckPreallocated(mat,1);
9975 
9976   ierr = PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
9977   if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */
9978     /* create psubcomm, then get subcomm */
9979     ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
9980     ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
9981     if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size);
9982 
9983     ierr = PetscSubcommCreate(comm,&psubcomm);CHKERRQ(ierr);
9984     ierr = PetscSubcommSetNumber(psubcomm,nsubcomm);CHKERRQ(ierr);
9985     ierr = PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);CHKERRQ(ierr);
9986     ierr = PetscSubcommSetFromOptions(psubcomm);CHKERRQ(ierr);
9987     ierr = PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);CHKERRQ(ierr);
9988     newsubcomm = PETSC_TRUE;
9989     ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr);
9990   }
9991 
9992   /* get isrow, iscol and a local sequential matrix matseq[0] */
9993   if (reuse == MAT_INITIAL_MATRIX) {
9994     mloc_sub = PETSC_DECIDE;
9995     nloc_sub = PETSC_DECIDE;
9996     if (bs < 1) {
9997       ierr = PetscSplitOwnership(subcomm,&mloc_sub,&M);CHKERRQ(ierr);
9998       ierr = PetscSplitOwnership(subcomm,&nloc_sub,&N);CHKERRQ(ierr);
9999     } else {
10000       ierr = PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);CHKERRQ(ierr);
10001       ierr = PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N);CHKERRQ(ierr);
10002     }
10003     ierr = MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);CHKERRQ(ierr);
10004     rstart = rend - mloc_sub;
10005     ierr = ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);CHKERRQ(ierr);
10006     ierr = ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);CHKERRQ(ierr);
10007   } else { /* reuse == MAT_REUSE_MATRIX */
10008     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");
10009     /* retrieve subcomm */
10010     ierr = PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);CHKERRQ(ierr);
10011     redund = (*matredundant)->redundant;
10012     isrow  = redund->isrow;
10013     iscol  = redund->iscol;
10014     matseq = redund->matseq;
10015   }
10016   ierr = MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);CHKERRQ(ierr);
10017 
10018   /* get matredundant over subcomm */
10019   if (reuse == MAT_INITIAL_MATRIX) {
10020     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant);CHKERRQ(ierr);
10021 
10022     /* create a supporting struct and attach it to C for reuse */
10023     ierr = PetscNewLog(*matredundant,&redund);CHKERRQ(ierr);
10024     (*matredundant)->redundant = redund;
10025     redund->isrow              = isrow;
10026     redund->iscol              = iscol;
10027     redund->matseq             = matseq;
10028     if (newsubcomm) {
10029       redund->subcomm          = subcomm;
10030     } else {
10031       redund->subcomm          = MPI_COMM_NULL;
10032     }
10033   } else {
10034     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);CHKERRQ(ierr);
10035   }
10036   ierr = PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
10037   PetscFunctionReturn(0);
10038 }
10039 
10040 /*@C
10041    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
10042    a given 'mat' object. Each submatrix can span multiple procs.
10043 
10044    Collective on Mat
10045 
10046    Input Parameters:
10047 +  mat - the matrix
10048 .  subcomm - the subcommunicator obtained by com_split(comm)
10049 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10050 
10051    Output Parameter:
10052 .  subMat - 'parallel submatrices each spans a given subcomm
10053 
10054   Notes:
10055   The submatrix partition across processors is dictated by 'subComm' a
10056   communicator obtained by com_split(comm). The comm_split
10057   is not restriced to be grouped with consecutive original ranks.
10058 
10059   Due the comm_split() usage, the parallel layout of the submatrices
10060   map directly to the layout of the original matrix [wrt the local
10061   row,col partitioning]. So the original 'DiagonalMat' naturally maps
10062   into the 'DiagonalMat' of the subMat, hence it is used directly from
10063   the subMat. However the offDiagMat looses some columns - and this is
10064   reconstructed with MatSetValues()
10065 
10066   Level: advanced
10067 
10068   Concepts: subcommunicator
10069   Concepts: submatrices
10070 
10071 .seealso: MatCreateSubMatrices()
10072 @*/
10073 PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
10074 {
10075   PetscErrorCode ierr;
10076   PetscMPIInt    commsize,subCommSize;
10077 
10078   PetscFunctionBegin;
10079   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRQ(ierr);
10080   ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr);
10081   if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
10082 
10083   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");
10084   ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10085   ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr);
10086   ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10087   PetscFunctionReturn(0);
10088 }
10089 
10090 /*@
10091    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
10092 
10093    Not Collective
10094 
10095    Input Arguments:
10096    mat - matrix to extract local submatrix from
10097    isrow - local row indices for submatrix
10098    iscol - local column indices for submatrix
10099 
10100    Output Arguments:
10101    submat - the submatrix
10102 
10103    Level: intermediate
10104 
10105    Notes:
10106    The submat should be returned with MatRestoreLocalSubMatrix().
10107 
10108    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
10109    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
10110 
10111    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
10112    MatSetValuesBlockedLocal() will also be implemented.
10113 
10114    The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that
10115    matrices obtained with DMCreateMat() generally already have the local to global mapping provided.
10116 
10117 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping()
10118 @*/
10119 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10120 {
10121   PetscErrorCode ierr;
10122 
10123   PetscFunctionBegin;
10124   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10125   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10126   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10127   PetscCheckSameComm(isrow,2,iscol,3);
10128   PetscValidPointer(submat,4);
10129   if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call");
10130 
10131   if (mat->ops->getlocalsubmatrix) {
10132     ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10133   } else {
10134     ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr);
10135   }
10136   PetscFunctionReturn(0);
10137 }
10138 
10139 /*@
10140    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
10141 
10142    Not Collective
10143 
10144    Input Arguments:
10145    mat - matrix to extract local submatrix from
10146    isrow - local row indices for submatrix
10147    iscol - local column indices for submatrix
10148    submat - the submatrix
10149 
10150    Level: intermediate
10151 
10152 .seealso: MatGetLocalSubMatrix()
10153 @*/
10154 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10155 {
10156   PetscErrorCode ierr;
10157 
10158   PetscFunctionBegin;
10159   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10160   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10161   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10162   PetscCheckSameComm(isrow,2,iscol,3);
10163   PetscValidPointer(submat,4);
10164   if (*submat) {
10165     PetscValidHeaderSpecific(*submat,MAT_CLASSID,4);
10166   }
10167 
10168   if (mat->ops->restorelocalsubmatrix) {
10169     ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10170   } else {
10171     ierr = MatDestroy(submat);CHKERRQ(ierr);
10172   }
10173   *submat = NULL;
10174   PetscFunctionReturn(0);
10175 }
10176 
10177 /* --------------------------------------------------------*/
10178 /*@
10179    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix
10180 
10181    Collective on Mat
10182 
10183    Input Parameter:
10184 .  mat - the matrix
10185 
10186    Output Parameter:
10187 .  is - if any rows have zero diagonals this contains the list of them
10188 
10189    Level: developer
10190 
10191    Concepts: matrix-vector product
10192 
10193 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10194 @*/
10195 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is)
10196 {
10197   PetscErrorCode ierr;
10198 
10199   PetscFunctionBegin;
10200   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10201   PetscValidType(mat,1);
10202   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10203   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10204 
10205   if (!mat->ops->findzerodiagonals) {
10206     Vec                diag;
10207     const PetscScalar *a;
10208     PetscInt          *rows;
10209     PetscInt           rStart, rEnd, r, nrow = 0;
10210 
10211     ierr = MatCreateVecs(mat, &diag, NULL);CHKERRQ(ierr);
10212     ierr = MatGetDiagonal(mat, diag);CHKERRQ(ierr);
10213     ierr = MatGetOwnershipRange(mat, &rStart, &rEnd);CHKERRQ(ierr);
10214     ierr = VecGetArrayRead(diag, &a);CHKERRQ(ierr);
10215     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow;
10216     ierr = PetscMalloc1(nrow, &rows);CHKERRQ(ierr);
10217     nrow = 0;
10218     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart;
10219     ierr = VecRestoreArrayRead(diag, &a);CHKERRQ(ierr);
10220     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10221     ierr = ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);CHKERRQ(ierr);
10222   } else {
10223     ierr = (*mat->ops->findzerodiagonals)(mat, is);CHKERRQ(ierr);
10224   }
10225   PetscFunctionReturn(0);
10226 }
10227 
10228 /*@
10229    MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size)
10230 
10231    Collective on Mat
10232 
10233    Input Parameter:
10234 .  mat - the matrix
10235 
10236    Output Parameter:
10237 .  is - contains the list of rows with off block diagonal entries
10238 
10239    Level: developer
10240 
10241    Concepts: matrix-vector product
10242 
10243 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10244 @*/
10245 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is)
10246 {
10247   PetscErrorCode ierr;
10248 
10249   PetscFunctionBegin;
10250   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10251   PetscValidType(mat,1);
10252   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10253   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10254 
10255   if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined");
10256   ierr = (*mat->ops->findoffblockdiagonalentries)(mat,is);CHKERRQ(ierr);
10257   PetscFunctionReturn(0);
10258 }
10259 
10260 /*@C
10261   MatInvertBlockDiagonal - Inverts the block diagonal entries.
10262 
10263   Collective on Mat
10264 
10265   Input Parameters:
10266 . mat - the matrix
10267 
10268   Output Parameters:
10269 . values - the block inverses in column major order (FORTRAN-like)
10270 
10271    Note:
10272    This routine is not available from Fortran.
10273 
10274   Level: advanced
10275 @*/
10276 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
10277 {
10278   PetscErrorCode ierr;
10279 
10280   PetscFunctionBegin;
10281   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10282   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10283   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10284   if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
10285   ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr);
10286   PetscFunctionReturn(0);
10287 }
10288 
10289 /*@C
10290     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
10291     via MatTransposeColoringCreate().
10292 
10293     Collective on MatTransposeColoring
10294 
10295     Input Parameter:
10296 .   c - coloring context
10297 
10298     Level: intermediate
10299 
10300 .seealso: MatTransposeColoringCreate()
10301 @*/
10302 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c)
10303 {
10304   PetscErrorCode       ierr;
10305   MatTransposeColoring matcolor=*c;
10306 
10307   PetscFunctionBegin;
10308   if (!matcolor) PetscFunctionReturn(0);
10309   if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; PetscFunctionReturn(0);}
10310 
10311   ierr = PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);CHKERRQ(ierr);
10312   ierr = PetscFree(matcolor->rows);CHKERRQ(ierr);
10313   ierr = PetscFree(matcolor->den2sp);CHKERRQ(ierr);
10314   ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr);
10315   ierr = PetscFree(matcolor->columns);CHKERRQ(ierr);
10316   if (matcolor->brows>0) {
10317     ierr = PetscFree(matcolor->lstart);CHKERRQ(ierr);
10318   }
10319   ierr = PetscHeaderDestroy(c);CHKERRQ(ierr);
10320   PetscFunctionReturn(0);
10321 }
10322 
10323 /*@C
10324     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
10325     a MatTransposeColoring context has been created, computes a dense B^T by Apply
10326     MatTransposeColoring to sparse B.
10327 
10328     Collective on MatTransposeColoring
10329 
10330     Input Parameters:
10331 +   B - sparse matrix B
10332 .   Btdense - symbolic dense matrix B^T
10333 -   coloring - coloring context created with MatTransposeColoringCreate()
10334 
10335     Output Parameter:
10336 .   Btdense - dense matrix B^T
10337 
10338     Level: advanced
10339 
10340      Notes: These are used internally for some implementations of MatRARt()
10341 
10342 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplyDenToSp()
10343 
10344 .keywords: coloring
10345 @*/
10346 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
10347 {
10348   PetscErrorCode ierr;
10349 
10350   PetscFunctionBegin;
10351   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
10352   PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2);
10353   PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3);
10354 
10355   if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
10356   ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr);
10357   PetscFunctionReturn(0);
10358 }
10359 
10360 /*@C
10361     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
10362     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
10363     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
10364     Csp from Cden.
10365 
10366     Collective on MatTransposeColoring
10367 
10368     Input Parameters:
10369 +   coloring - coloring context created with MatTransposeColoringCreate()
10370 -   Cden - matrix product of a sparse matrix and a dense matrix Btdense
10371 
10372     Output Parameter:
10373 .   Csp - sparse matrix
10374 
10375     Level: advanced
10376 
10377      Notes: These are used internally for some implementations of MatRARt()
10378 
10379 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()
10380 
10381 .keywords: coloring
10382 @*/
10383 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
10384 {
10385   PetscErrorCode ierr;
10386 
10387   PetscFunctionBegin;
10388   PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1);
10389   PetscValidHeaderSpecific(Cden,MAT_CLASSID,2);
10390   PetscValidHeaderSpecific(Csp,MAT_CLASSID,3);
10391 
10392   if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
10393   ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr);
10394   PetscFunctionReturn(0);
10395 }
10396 
10397 /*@C
10398    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.
10399 
10400    Collective on Mat
10401 
10402    Input Parameters:
10403 +  mat - the matrix product C
10404 -  iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring()
10405 
10406     Output Parameter:
10407 .   color - the new coloring context
10408 
10409     Level: intermediate
10410 
10411 .seealso: MatTransposeColoringDestroy(),  MatTransColoringApplySpToDen(),
10412            MatTransColoringApplyDenToSp()
10413 @*/
10414 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
10415 {
10416   MatTransposeColoring c;
10417   MPI_Comm             comm;
10418   PetscErrorCode       ierr;
10419 
10420   PetscFunctionBegin;
10421   ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10422   ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
10423   ierr = PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);CHKERRQ(ierr);
10424 
10425   c->ctype = iscoloring->ctype;
10426   if (mat->ops->transposecoloringcreate) {
10427     ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr);
10428   } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type");
10429 
10430   *color = c;
10431   ierr   = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10432   PetscFunctionReturn(0);
10433 }
10434 
10435 /*@
10436       MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the
10437         matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the
10438         same, otherwise it will be larger
10439 
10440      Not Collective
10441 
10442   Input Parameter:
10443 .    A  - the matrix
10444 
10445   Output Parameter:
10446 .    state - the current state
10447 
10448   Notes: You can only compare states from two different calls to the SAME matrix, you cannot compare calls between
10449          different matrices
10450 
10451   Level: intermediate
10452 
10453 @*/
10454 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state)
10455 {
10456   PetscFunctionBegin;
10457   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10458   *state = mat->nonzerostate;
10459   PetscFunctionReturn(0);
10460 }
10461 
10462 /*@
10463       MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential
10464                  matrices from each processor
10465 
10466     Collective on MPI_Comm
10467 
10468    Input Parameters:
10469 +    comm - the communicators the parallel matrix will live on
10470 .    seqmat - the input sequential matrices
10471 .    n - number of local columns (or PETSC_DECIDE)
10472 -    reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10473 
10474    Output Parameter:
10475 .    mpimat - the parallel matrix generated
10476 
10477     Level: advanced
10478 
10479    Notes: The number of columns of the matrix in EACH processor MUST be the same.
10480 
10481 @*/
10482 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat)
10483 {
10484   PetscErrorCode ierr;
10485 
10486   PetscFunctionBegin;
10487   if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name);
10488   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");
10489 
10490   ierr = PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10491   ierr = (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);CHKERRQ(ierr);
10492   ierr = PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10493   PetscFunctionReturn(0);
10494 }
10495 
10496 /*@
10497      MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent
10498                  ranks' ownership ranges.
10499 
10500     Collective on A
10501 
10502    Input Parameters:
10503 +    A   - the matrix to create subdomains from
10504 -    N   - requested number of subdomains
10505 
10506 
10507    Output Parameters:
10508 +    n   - number of subdomains resulting on this rank
10509 -    iss - IS list with indices of subdomains on this rank
10510 
10511     Level: advanced
10512 
10513     Notes: number of subdomains must be smaller than the communicator size
10514 @*/
10515 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[])
10516 {
10517   MPI_Comm        comm,subcomm;
10518   PetscMPIInt     size,rank,color;
10519   PetscInt        rstart,rend,k;
10520   PetscErrorCode  ierr;
10521 
10522   PetscFunctionBegin;
10523   ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr);
10524   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
10525   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
10526   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);
10527   *n = 1;
10528   k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */
10529   color = rank/k;
10530   ierr = MPI_Comm_split(comm,color,rank,&subcomm);CHKERRQ(ierr);
10531   ierr = PetscMalloc1(1,iss);CHKERRQ(ierr);
10532   ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
10533   ierr = ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);CHKERRQ(ierr);
10534   ierr = MPI_Comm_free(&subcomm);CHKERRQ(ierr);
10535   PetscFunctionReturn(0);
10536 }
10537 
10538 /*@
10539    MatGalerkin - Constructs the coarse grid problem via Galerkin projection.
10540 
10541    If the interpolation and restriction operators are the same, uses MatPtAP.
10542    If they are not the same, use MatMatMatMult.
10543 
10544    Once the coarse grid problem is constructed, correct for interpolation operators
10545    that are not of full rank, which can legitimately happen in the case of non-nested
10546    geometric multigrid.
10547 
10548    Input Parameters:
10549 +  restrct - restriction operator
10550 .  dA - fine grid matrix
10551 .  interpolate - interpolation operator
10552 .  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10553 -  fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate
10554 
10555    Output Parameters:
10556 .  A - the Galerkin coarse matrix
10557 
10558    Options Database Key:
10559 .  -pc_mg_galerkin <both,pmat,mat,none>
10560 
10561    Level: developer
10562 
10563 .keywords: MG, multigrid, Galerkin
10564 
10565 .seealso: MatPtAP(), MatMatMatMult()
10566 @*/
10567 PetscErrorCode  MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A)
10568 {
10569   PetscErrorCode ierr;
10570   IS             zerorows;
10571   Vec            diag;
10572 
10573   PetscFunctionBegin;
10574   if (reuse == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10575   /* Construct the coarse grid matrix */
10576   if (interpolate == restrct) {
10577     ierr = MatPtAP(dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10578   } else {
10579     ierr = MatMatMatMult(restrct,dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10580   }
10581 
10582   /* If the interpolation matrix is not of full rank, A will have zero rows.
10583      This can legitimately happen in the case of non-nested geometric multigrid.
10584      In that event, we set the rows of the matrix to the rows of the identity,
10585      ignoring the equations (as the RHS will also be zero). */
10586 
10587   ierr = MatFindZeroRows(*A, &zerorows);CHKERRQ(ierr);
10588 
10589   if (zerorows != NULL) { /* if there are any zero rows */
10590     ierr = MatCreateVecs(*A, &diag, NULL);CHKERRQ(ierr);
10591     ierr = MatGetDiagonal(*A, diag);CHKERRQ(ierr);
10592     ierr = VecISSet(diag, zerorows, 1.0);CHKERRQ(ierr);
10593     ierr = MatDiagonalSet(*A, diag, INSERT_VALUES);CHKERRQ(ierr);
10594     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10595     ierr = ISDestroy(&zerorows);CHKERRQ(ierr);
10596   }
10597   PetscFunctionReturn(0);
10598 }
10599