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