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