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