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