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