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