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