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