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