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