Actual source code: matrix.c
petsc-3.5.0 2014-06-30
2: /*
3: This is where the abstract matrix operations are defined
4: */
6: #include <petsc-private/matimpl.h> /*I "petscmat.h" I*/
7: #include <petsc-private/vecimpl.h>
9: /* Logging support */
10: PetscClassId MAT_CLASSID;
11: PetscClassId MAT_COLORING_CLASSID;
12: PetscClassId MAT_FDCOLORING_CLASSID;
13: PetscClassId MAT_TRANSPOSECOLORING_CLASSID;
15: PetscLogEvent MAT_Mult, MAT_Mults, MAT_MultConstrained, MAT_MultAdd, MAT_MultTranspose;
16: PetscLogEvent MAT_MultTransposeConstrained, MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve;
17: PetscLogEvent MAT_SolveTransposeAdd, MAT_SOR, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic;
18: PetscLogEvent MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor;
19: PetscLogEvent MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin;
20: PetscLogEvent MAT_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetRowIJ, MAT_GetSubMatrices, MAT_GetOrdering, MAT_GetRedundantMatrix, MAT_GetSeqNonzeroStructure;
21: PetscLogEvent MAT_IncreaseOverlap, MAT_Partitioning, MAT_Coarsen, MAT_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate;
22: PetscLogEvent MAT_FDColoringSetUp, MAT_FDColoringApply,MAT_Transpose,MAT_FDColoringFunction;
23: PetscLogEvent MAT_TransposeColoringCreate;
24: PetscLogEvent MAT_MatMult, MAT_MatMultSymbolic, MAT_MatMultNumeric;
25: PetscLogEvent MAT_PtAP, MAT_PtAPSymbolic, MAT_PtAPNumeric,MAT_RARt, MAT_RARtSymbolic, MAT_RARtNumeric;
26: PetscLogEvent MAT_MatTransposeMult, MAT_MatTransposeMultSymbolic, MAT_MatTransposeMultNumeric;
27: PetscLogEvent MAT_TransposeMatMult, MAT_TransposeMatMultSymbolic, MAT_TransposeMatMultNumeric;
28: PetscLogEvent MAT_MatMatMult, MAT_MatMatMultSymbolic, MAT_MatMatMultNumeric;
29: PetscLogEvent MAT_MultHermitianTranspose,MAT_MultHermitianTransposeAdd;
30: PetscLogEvent MAT_Getsymtranspose, MAT_Getsymtransreduced, MAT_Transpose_SeqAIJ, MAT_GetBrowsOfAcols;
31: PetscLogEvent MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym;
32: PetscLogEvent MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure;
33: PetscLogEvent MAT_GetMultiProcBlock;
34: PetscLogEvent MAT_CUSPCopyToGPU, MAT_CUSPARSECopyToGPU, MAT_SetValuesBatch, MAT_SetValuesBatchI, MAT_SetValuesBatchII, MAT_SetValuesBatchIII, MAT_SetValuesBatchIV;
35: PetscLogEvent MAT_ViennaCLCopyToGPU;
36: PetscLogEvent MAT_Merge,MAT_Residual;
37: PetscLogEvent Mat_Coloring_Apply,Mat_Coloring_Comm,Mat_Coloring_Local,Mat_Coloring_ISCreate,Mat_Coloring_SetUp,Mat_Coloring_Weights;
39: const char *const MatFactorTypes[] = {"NONE","LU","CHOLESKY","ILU","ICC","ILUDT","MatFactorType","MAT_FACTOR_",0};
43: /*@
44: MatSetRandom - Sets all components of a matrix to random numbers. For sparse matrices that have been preallocated it randomly selects appropriate locations
46: Logically Collective on Vec
48: Input Parameters:
49: + x - the vector
50: - rctx - the random number context, formed by PetscRandomCreate(), or NULL and
51: it will create one internally.
53: Output Parameter:
54: . x - the vector
56: Example of Usage:
57: .vb
58: PetscRandomCreate(PETSC_COMM_WORLD,&rctx);
59: VecSetRandom(x,rctx);
60: PetscRandomDestroy(rctx);
61: .ve
63: Level: intermediate
65: Concepts: vector^setting to random
66: Concepts: random^vector
68: .seealso: MatZeroEntries(), MatSetValues(), PetscRandomCreate(), PetscRandomDestroy()
69: @*/
70: PetscErrorCode MatSetRandom(Mat x,PetscRandom rctx)
71: {
73: PetscRandom randObj = NULL;
80: if (!rctx) {
81: MPI_Comm comm;
82: PetscObjectGetComm((PetscObject)x,&comm);
83: PetscRandomCreate(comm,&randObj);
84: PetscRandomSetFromOptions(randObj);
85: rctx = randObj;
86: }
88: PetscLogEventBegin(VEC_SetRandom,x,rctx,0,0);
89: (*x->ops->setrandom)(x,rctx);
90: PetscLogEventEnd(VEC_SetRandom,x,rctx,0,0);
92: x->assembled = PETSC_TRUE;
93: PetscRandomDestroy(&randObj);
94: return(0);
95: }
100: /*@
101: MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix
103: Input Parameter:
104: . A - the matrix
106: Output Parameter:
107: . keptrows - the rows that are not completely zero
109: Level: intermediate
111: @*/
112: PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows)
113: {
118: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
119: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
120: if (!mat->ops->findnonzerorows) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not coded for this matrix type");
121: (*mat->ops->findnonzerorows)(mat,keptrows);
122: return(0);
123: }
127: /*@
128: MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling
130: Not Collective
132: Input Parameters:
133: . A - the matrix
135: Output Parameters:
136: . a - the diagonal part (which is a SEQUENTIAL matrix)
138: Notes: see the manual page for MatCreateAIJ() for more information on the "diagonal part" of the matrix.
140: Level: advanced
142: @*/
143: PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a)
144: {
145: PetscErrorCode ierr,(*f)(Mat,Mat*);
146: PetscMPIInt size;
152: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
153: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
154: MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);
155: PetscObjectQueryFunction((PetscObject)A,"MatGetDiagonalBlock_C",&f);
156: if (f) {
157: (*f)(A,a);
158: return(0);
159: } else if (size == 1) {
160: *a = A;
161: } else {
162: MatType mattype;
163: MatGetType(A,&mattype);
164: SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix type %s does not support getting diagonal block",mattype);
165: }
166: return(0);
167: }
171: /*@
172: MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries.
174: Collective on Mat
176: Input Parameters:
177: . mat - the matrix
179: Output Parameter:
180: . trace - the sum of the diagonal entries
182: Level: advanced
184: @*/
185: PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace)
186: {
188: Vec diag;
191: MatGetVecs(mat,&diag,NULL);
192: MatGetDiagonal(mat,diag);
193: VecSum(diag,trace);
194: VecDestroy(&diag);
195: return(0);
196: }
200: /*@
201: MatRealPart - Zeros out the imaginary part of the matrix
203: Logically Collective on Mat
205: Input Parameters:
206: . mat - the matrix
208: Level: advanced
211: .seealso: MatImaginaryPart()
212: @*/
213: PetscErrorCode MatRealPart(Mat mat)
214: {
220: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
221: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
222: if (!mat->ops->realpart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
223: MatCheckPreallocated(mat,1);
224: (*mat->ops->realpart)(mat);
225: #if defined(PETSC_HAVE_CUSP)
226: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
227: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
228: }
229: #endif
230: #if defined(PETSC_HAVE_VIENNACL)
231: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
232: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
233: }
234: #endif
235: return(0);
236: }
240: /*@C
241: MatGetGhosts - Get the global index of all ghost nodes defined by the sparse matrix
243: Collective on Mat
245: Input Parameter:
246: . mat - the matrix
248: Output Parameters:
249: + nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block)
250: - ghosts - the global indices of the ghost points
252: Notes: the nghosts and ghosts are suitable to pass into VecCreateGhost()
254: Level: advanced
256: @*/
257: PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[])
258: {
264: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
265: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
266: if (!mat->ops->getghosts) {
267: if (nghosts) *nghosts = 0;
268: if (ghosts) *ghosts = 0;
269: } else {
270: (*mat->ops->getghosts)(mat,nghosts,ghosts);
271: }
272: return(0);
273: }
278: /*@
279: MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part
281: Logically Collective on Mat
283: Input Parameters:
284: . mat - the matrix
286: Level: advanced
289: .seealso: MatRealPart()
290: @*/
291: PetscErrorCode MatImaginaryPart(Mat mat)
292: {
298: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
299: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
300: if (!mat->ops->imaginarypart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
301: MatCheckPreallocated(mat,1);
302: (*mat->ops->imaginarypart)(mat);
303: #if defined(PETSC_HAVE_CUSP)
304: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
305: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
306: }
307: #endif
308: #if defined(PETSC_HAVE_VIENNACL)
309: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
310: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
311: }
312: #endif
313: return(0);
314: }
318: /*@
319: MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices)
321: Collective on Mat
323: Input Parameter:
324: . mat - the matrix
326: Output Parameters:
327: + missing - is any diagonal missing
328: - dd - first diagonal entry that is missing (optional)
330: Level: advanced
333: .seealso: MatRealPart()
334: @*/
335: PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd)
336: {
342: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
343: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
344: if (!mat->ops->missingdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
345: (*mat->ops->missingdiagonal)(mat,missing,dd);
346: return(0);
347: }
351: /*@C
352: MatGetRow - Gets a row of a matrix. You MUST call MatRestoreRow()
353: for each row that you get to ensure that your application does
354: not bleed memory.
356: Not Collective
358: Input Parameters:
359: + mat - the matrix
360: - row - the row to get
362: Output Parameters:
363: + ncols - if not NULL, the number of nonzeros in the row
364: . cols - if not NULL, the column numbers
365: - vals - if not NULL, the values
367: Notes:
368: This routine is provided for people who need to have direct access
369: to the structure of a matrix. We hope that we provide enough
370: high-level matrix routines that few users will need it.
372: MatGetRow() always returns 0-based column indices, regardless of
373: whether the internal representation is 0-based (default) or 1-based.
375: For better efficiency, set cols and/or vals to NULL if you do
376: not wish to extract these quantities.
378: The user can only examine the values extracted with MatGetRow();
379: the values cannot be altered. To change the matrix entries, one
380: must use MatSetValues().
382: You can only have one call to MatGetRow() outstanding for a particular
383: matrix at a time, per processor. MatGetRow() can only obtain rows
384: associated with the given processor, it cannot get rows from the
385: other processors; for that we suggest using MatGetSubMatrices(), then
386: MatGetRow() on the submatrix. The row indix passed to MatGetRows()
387: is in the global number of rows.
389: Fortran Notes:
390: The calling sequence from Fortran is
391: .vb
392: MatGetRow(matrix,row,ncols,cols,values,ierr)
393: Mat matrix (input)
394: integer row (input)
395: integer ncols (output)
396: integer cols(maxcols) (output)
397: double precision (or double complex) values(maxcols) output
398: .ve
399: where maxcols >= maximum nonzeros in any row of the matrix.
402: Caution:
403: Do not try to change the contents of the output arrays (cols and vals).
404: In some cases, this may corrupt the matrix.
406: Level: advanced
408: Concepts: matrices^row access
410: .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatGetSubMatrices(), MatGetDiagonal()
411: @*/
412: PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
413: {
415: PetscInt incols;
420: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
421: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
422: if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
423: MatCheckPreallocated(mat,1);
424: PetscLogEventBegin(MAT_GetRow,mat,0,0,0);
425: (*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals);
426: if (ncols) *ncols = incols;
427: PetscLogEventEnd(MAT_GetRow,mat,0,0,0);
428: return(0);
429: }
433: /*@
434: MatConjugate - replaces the matrix values with their complex conjugates
436: Logically Collective on Mat
438: Input Parameters:
439: . mat - the matrix
441: Level: advanced
443: .seealso: VecConjugate()
444: @*/
445: PetscErrorCode MatConjugate(Mat mat)
446: {
447: #if defined(PETSC_USE_COMPLEX)
452: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
453: if (!mat->ops->conjugate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not provided for this matrix format, send email to petsc-maint@mcs.anl.gov");
454: (*mat->ops->conjugate)(mat);
455: #if defined(PETSC_HAVE_CUSP)
456: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
457: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
458: }
459: #endif
460: #if defined(PETSC_HAVE_VIENNACL)
461: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
462: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
463: }
464: #endif
465: return(0);
466: #else
467: return 0;
468: #endif
469: }
473: /*@C
474: MatRestoreRow - Frees any temporary space allocated by MatGetRow().
476: Not Collective
478: Input Parameters:
479: + mat - the matrix
480: . row - the row to get
481: . ncols, cols - the number of nonzeros and their columns
482: - vals - if nonzero the column values
484: Notes:
485: This routine should be called after you have finished examining the entries.
487: This routine zeros out ncols, cols, and vals. This is to prevent accidental
488: us of the array after it has been restored. If you pass NULL, it will
489: not zero the pointers. Use of cols or vals after MatRestoreRow is invalid.
491: Fortran Notes:
492: The calling sequence from Fortran is
493: .vb
494: MatRestoreRow(matrix,row,ncols,cols,values,ierr)
495: Mat matrix (input)
496: integer row (input)
497: integer ncols (output)
498: integer cols(maxcols) (output)
499: double precision (or double complex) values(maxcols) output
500: .ve
501: Where maxcols >= maximum nonzeros in any row of the matrix.
503: In Fortran MatRestoreRow() MUST be called after MatGetRow()
504: before another call to MatGetRow() can be made.
506: Level: advanced
508: .seealso: MatGetRow()
509: @*/
510: PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
511: {
517: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
518: if (!mat->ops->restorerow) return(0);
519: (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);
520: if (ncols) *ncols = 0;
521: if (cols) *cols = NULL;
522: if (vals) *vals = NULL;
523: return(0);
524: }
528: /*@
529: MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format.
530: You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag.
532: Not Collective
534: Input Parameters:
535: + mat - the matrix
537: Notes:
538: 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.
540: Level: advanced
542: Concepts: matrices^row access
544: .seealso: MatRestoreRowRowUpperTriangular()
545: @*/
546: PetscErrorCode MatGetRowUpperTriangular(Mat mat)
547: {
553: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
554: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
555: if (!mat->ops->getrowuppertriangular) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
556: MatCheckPreallocated(mat,1);
557: (*mat->ops->getrowuppertriangular)(mat);
558: return(0);
559: }
563: /*@
564: MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format.
566: Not Collective
568: Input Parameters:
569: + mat - the matrix
571: Notes:
572: This routine should be called after you have finished MatGetRow/MatRestoreRow().
575: Level: advanced
577: .seealso: MatGetRowUpperTriangular()
578: @*/
579: PetscErrorCode MatRestoreRowUpperTriangular(Mat mat)
580: {
585: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
586: if (!mat->ops->restorerowuppertriangular) return(0);
587: (*mat->ops->restorerowuppertriangular)(mat);
588: return(0);
589: }
593: /*@C
594: MatSetOptionsPrefix - Sets the prefix used for searching for all
595: Mat options in the database.
597: Logically Collective on Mat
599: Input Parameter:
600: + A - the Mat context
601: - prefix - the prefix to prepend to all option names
603: Notes:
604: A hyphen (-) must NOT be given at the beginning of the prefix name.
605: The first character of all runtime options is AUTOMATICALLY the hyphen.
607: Level: advanced
609: .keywords: Mat, set, options, prefix, database
611: .seealso: MatSetFromOptions()
612: @*/
613: PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[])
614: {
619: PetscObjectSetOptionsPrefix((PetscObject)A,prefix);
620: return(0);
621: }
625: /*@C
626: MatAppendOptionsPrefix - Appends to the prefix used for searching for all
627: Mat options in the database.
629: Logically Collective on Mat
631: Input Parameters:
632: + A - the Mat context
633: - prefix - the prefix to prepend to all option names
635: Notes:
636: A hyphen (-) must NOT be given at the beginning of the prefix name.
637: The first character of all runtime options is AUTOMATICALLY the hyphen.
639: Level: advanced
641: .keywords: Mat, append, options, prefix, database
643: .seealso: MatGetOptionsPrefix()
644: @*/
645: PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[])
646: {
651: PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);
652: return(0);
653: }
657: /*@C
658: MatGetOptionsPrefix - Sets the prefix used for searching for all
659: Mat options in the database.
661: Not Collective
663: Input Parameter:
664: . A - the Mat context
666: Output Parameter:
667: . prefix - pointer to the prefix string used
669: Notes: On the fortran side, the user should pass in a string 'prefix' of
670: sufficient length to hold the prefix.
672: Level: advanced
674: .keywords: Mat, get, options, prefix, database
676: .seealso: MatAppendOptionsPrefix()
677: @*/
678: PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[])
679: {
684: PetscObjectGetOptionsPrefix((PetscObject)A,prefix);
685: return(0);
686: }
690: /*@
691: MatSetUp - Sets up the internal matrix data structures for the later use.
693: Collective on Mat
695: Input Parameters:
696: . A - the Mat context
698: Notes:
699: If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used.
701: If a suitable preallocation routine is used, this function does not need to be called.
703: See the Performance chapter of the PETSc users manual for how to preallocate matrices
705: Level: beginner
707: .keywords: Mat, setup
709: .seealso: MatCreate(), MatDestroy()
710: @*/
711: PetscErrorCode MatSetUp(Mat A)
712: {
713: PetscMPIInt size;
718: if (!((PetscObject)A)->type_name) {
719: MPI_Comm_size(PetscObjectComm((PetscObject)A), &size);
720: if (size == 1) {
721: MatSetType(A, MATSEQAIJ);
722: } else {
723: MatSetType(A, MATMPIAIJ);
724: }
725: }
726: if (!A->preallocated && A->ops->setup) {
727: PetscInfo(A,"Warning not preallocating matrix storage\n");
728: (*A->ops->setup)(A);
729: }
730: A->preallocated = PETSC_TRUE;
731: return(0);
732: }
734: #if defined(PETSC_HAVE_SAWS)
735: #include <petscviewersaws.h>
736: #endif
739: /*@C
740: MatView - Visualizes a matrix object.
742: Collective on Mat
744: Input Parameters:
745: + mat - the matrix
746: - viewer - visualization context
748: Notes:
749: The available visualization contexts include
750: + PETSC_VIEWER_STDOUT_SELF - standard output (default)
751: . PETSC_VIEWER_STDOUT_WORLD - synchronized standard
752: output where only the first processor opens
753: the file. All other processors send their
754: data to the first processor to print.
755: - PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure
757: The user can open alternative visualization contexts with
758: + PetscViewerASCIIOpen() - Outputs matrix to a specified file
759: . PetscViewerBinaryOpen() - Outputs matrix in binary to a
760: specified file; corresponding input uses MatLoad()
761: . PetscViewerDrawOpen() - Outputs nonzero matrix structure to
762: an X window display
763: - PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
764: Currently only the sequential dense and AIJ
765: matrix types support the Socket viewer.
767: The user can call PetscViewerSetFormat() to specify the output
768: format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
769: PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen). Available formats include
770: + PETSC_VIEWER_DEFAULT - default, prints matrix contents
771: . PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
772: . PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
773: . PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse
774: format common among all matrix types
775: . PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific
776: format (which is in many cases the same as the default)
777: . PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
778: size and structure (not the matrix entries)
779: . PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about
780: the matrix structure
782: Options Database Keys:
783: + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
784: . -mat_view ::ascii_info_detail - Prints more detailed info
785: . -mat_view - Prints matrix in ASCII format
786: . -mat_view ::ascii_matlab - Prints matrix in Matlab format
787: . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
788: . -display <name> - Sets display name (default is host)
789: . -draw_pause <sec> - Sets number of seconds to pause after display
790: . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: Chapter 10 Using MATLAB with PETSc for details)
791: . -viewer_socket_machine <machine>
792: . -viewer_socket_port <port>
793: . -mat_view binary - save matrix to file in binary format
794: - -viewer_binary_filename <name>
795: Level: beginner
797: Notes: see the manual page for MatLoad() for the exact format of the binary file when the binary
798: viewer is used.
800: See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary
801: viewer is used.
803: One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure.
804: And then use the following mouse functions:
805: left mouse: zoom in
806: middle mouse: zoom out
807: right mouse: continue with the simulation
809: Concepts: matrices^viewing
810: Concepts: matrices^plotting
811: Concepts: matrices^printing
813: .seealso: PetscViewerSetFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(),
814: PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
815: @*/
816: PetscErrorCode MatView(Mat mat,PetscViewer viewer)
817: {
818: PetscErrorCode ierr;
819: PetscInt rows,cols,bs;
820: PetscBool iascii;
821: PetscViewerFormat format;
822: #if defined(PETSC_HAVE_SAWS)
823: PetscBool isams;
824: #endif
829: if (!viewer) {
830: PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);
831: }
834: MatCheckPreallocated(mat,1);
836: PetscLogEventBegin(MAT_View,mat,viewer,0,0);
837: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
838: PetscViewerGetFormat(viewer,&format);
839: if ((!iascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) {
840: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detailed");
841: }
843: #if defined(PETSC_HAVE_SAWS)
844: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&isams);
845: #endif
846: if (iascii) {
847: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
848: PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer);
849: if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
850: PetscViewerASCIIPushTab(viewer);
851: MatGetSize(mat,&rows,&cols);
852: MatGetBlockSize(mat,&bs);
853: if (bs != 1) {
854: PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,bs);
855: } else {
856: PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);
857: }
858: if (mat->factortype) {
859: const MatSolverPackage solver;
860: MatFactorGetSolverPackage(mat,&solver);
861: PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);
862: }
863: if (mat->ops->getinfo) {
864: MatInfo info;
865: MatGetInfo(mat,MAT_GLOBAL_SUM,&info);
866: PetscViewerASCIIPrintf(viewer,"total: nonzeros=%g, allocated nonzeros=%g\n",info.nz_used,info.nz_allocated);
867: PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls =%D\n",(PetscInt)info.mallocs);
868: }
869: if (mat->nullsp) {PetscViewerASCIIPrintf(viewer," has attached null space\n");}
870: if (mat->nearnullsp) {PetscViewerASCIIPrintf(viewer," has attached near null space\n");}
871: }
872: #if defined(PETSC_HAVE_SAWS)
873: } else if (isams) {
874: PetscMPIInt rank;
876: PetscObjectName((PetscObject)mat);
877: MPI_Comm_rank(PETSC_COMM_WORLD,&rank);
878: if (!((PetscObject)mat)->amsmem && !rank) {
879: PetscObjectViewSAWs((PetscObject)mat,viewer);
880: }
881: #endif
882: }
883: if (mat->ops->view) {
884: PetscViewerASCIIPushTab(viewer);
885: (*mat->ops->view)(mat,viewer);
886: PetscViewerASCIIPopTab(viewer);
887: }
888: if (iascii) {
889: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
890: PetscViewerGetFormat(viewer,&format);
891: if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
892: PetscViewerASCIIPopTab(viewer);
893: }
894: }
895: PetscLogEventEnd(MAT_View,mat,viewer,0,0);
896: return(0);
897: }
899: #if defined(PETSC_USE_DEBUG)
900: #include <../src/sys/totalview/tv_data_display.h>
901: PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat)
902: {
903: TV_add_row("Local rows", "int", &mat->rmap->n);
904: TV_add_row("Local columns", "int", &mat->cmap->n);
905: TV_add_row("Global rows", "int", &mat->rmap->N);
906: TV_add_row("Global columns", "int", &mat->cmap->N);
907: TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name);
908: return TV_format_OK;
909: }
910: #endif
914: /*@C
915: MatLoad - Loads a matrix that has been stored in binary format
916: with MatView(). The matrix format is determined from the options database.
917: Generates a parallel MPI matrix if the communicator has more than one
918: processor. The default matrix type is AIJ.
920: Collective on PetscViewer
922: Input Parameters:
923: + newmat - the newly loaded matrix, this needs to have been created with MatCreate()
924: or some related function before a call to MatLoad()
925: - viewer - binary file viewer, created with PetscViewerBinaryOpen()
927: Options Database Keys:
928: Used with block matrix formats (MATSEQBAIJ, ...) to specify
929: block size
930: . -matload_block_size <bs>
932: Level: beginner
934: Notes:
935: If the Mat type has not yet been given then MATAIJ is used, call MatSetFromOptions() on the
936: Mat before calling this routine if you wish to set it from the options database.
938: MatLoad() automatically loads into the options database any options
939: given in the file filename.info where filename is the name of the file
940: that was passed to the PetscViewerBinaryOpen(). The options in the info
941: file will be ignored if you use the -viewer_binary_skip_info option.
943: If the type or size of newmat is not set before a call to MatLoad, PETSc
944: sets the default matrix type AIJ and sets the local and global sizes.
945: If type and/or size is already set, then the same are used.
947: In parallel, each processor can load a subset of rows (or the
948: entire matrix). This routine is especially useful when a large
949: matrix is stored on disk and only part of it is desired on each
950: processor. For example, a parallel solver may access only some of
951: the rows from each processor. The algorithm used here reads
952: relatively small blocks of data rather than reading the entire
953: matrix and then subsetting it.
955: Notes for advanced users:
956: Most users should not need to know the details of the binary storage
957: format, since MatLoad() and MatView() completely hide these details.
958: But for anyone who's interested, the standard binary matrix storage
959: format is
961: $ int MAT_FILE_CLASSID
962: $ int number of rows
963: $ int number of columns
964: $ int total number of nonzeros
965: $ int *number nonzeros in each row
966: $ int *column indices of all nonzeros (starting index is zero)
967: $ PetscScalar *values of all nonzeros
969: PETSc automatically does the byte swapping for
970: machines that store the bytes reversed, e.g. DEC alpha, freebsd,
971: linux, Windows and the paragon; thus if you write your own binary
972: read/write routines you have to swap the bytes; see PetscBinaryRead()
973: and PetscBinaryWrite() to see how this may be done.
975: .keywords: matrix, load, binary, input
977: .seealso: PetscViewerBinaryOpen(), MatView(), VecLoad()
979: @*/
980: PetscErrorCode MatLoad(Mat newmat,PetscViewer viewer)
981: {
983: PetscBool isbinary,flg;
988: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);
989: if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()");
991: if (!((PetscObject)newmat)->type_name) {
992: MatSetType(newmat,MATAIJ);
993: }
995: if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type");
996: PetscLogEventBegin(MAT_Load,viewer,0,0,0);
997: (*newmat->ops->load)(newmat,viewer);
998: PetscLogEventEnd(MAT_Load,viewer,0,0,0);
1000: flg = PETSC_FALSE;
1001: PetscOptionsGetBool(((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,NULL);
1002: if (flg) {
1003: MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);
1004: MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);
1005: }
1006: flg = PETSC_FALSE;
1007: PetscOptionsGetBool(((PetscObject)newmat)->prefix,"-matload_spd",&flg,NULL);
1008: if (flg) {
1009: MatSetOption(newmat,MAT_SPD,PETSC_TRUE);
1010: }
1011: return(0);
1012: }
1016: /*@
1017: MatDestroy - Frees space taken by a matrix.
1019: Collective on Mat
1021: Input Parameter:
1022: . A - the matrix
1024: Level: beginner
1026: @*/
1027: PetscErrorCode MatDestroy(Mat *A)
1028: {
1032: if (!*A) return(0);
1034: if (--((PetscObject)(*A))->refct > 0) {*A = NULL; return(0);}
1036: /* if memory was published with SAWs then destroy it */
1037: PetscObjectSAWsViewOff((PetscObject)*A);
1038: if ((*A)->ops->destroy) {
1039: (*(*A)->ops->destroy)(*A);
1040: }
1041: MatNullSpaceDestroy(&(*A)->nullsp);
1042: MatNullSpaceDestroy(&(*A)->nearnullsp);
1043: PetscLayoutDestroy(&(*A)->rmap);
1044: PetscLayoutDestroy(&(*A)->cmap);
1045: PetscHeaderDestroy(A);
1046: return(0);
1047: }
1051: /*@
1052: MatSetValues - Inserts or adds a block of values into a matrix.
1053: These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1054: MUST be called after all calls to MatSetValues() have been completed.
1056: Not Collective
1058: Input Parameters:
1059: + mat - the matrix
1060: . v - a logically two-dimensional array of values
1061: . m, idxm - the number of rows and their global indices
1062: . n, idxn - the number of columns and their global indices
1063: - addv - either ADD_VALUES or INSERT_VALUES, where
1064: ADD_VALUES adds values to any existing entries, and
1065: INSERT_VALUES replaces existing entries with new values
1067: Notes:
1068: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
1069: MatSetUp() before using this routine
1071: By default the values, v, are row-oriented. See MatSetOption() for other options.
1073: Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
1074: options cannot be mixed without intervening calls to the assembly
1075: routines.
1077: MatSetValues() uses 0-based row and column numbers in Fortran
1078: as well as in C.
1080: Negative indices may be passed in idxm and idxn, these rows and columns are
1081: simply ignored. This allows easily inserting element stiffness matrices
1082: with homogeneous Dirchlet boundary conditions that you don't want represented
1083: in the matrix.
1085: Efficiency Alert:
1086: The routine MatSetValuesBlocked() may offer much better efficiency
1087: for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1089: Level: beginner
1091: Concepts: matrices^putting entries in
1093: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1094: InsertMode, INSERT_VALUES, ADD_VALUES
1095: @*/
1096: PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1097: {
1099: #if defined(PETSC_USE_DEBUG)
1100: PetscInt i,j;
1101: #endif
1106: if (!m || !n) return(0); /* no values to insert */
1110: MatCheckPreallocated(mat,1);
1111: if (mat->insertmode == NOT_SET_VALUES) {
1112: mat->insertmode = addv;
1113: }
1114: #if defined(PETSC_USE_DEBUG)
1115: else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1116: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1117: if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1119: for (i=0; i<m; i++) {
1120: for (j=0; j<n; j++) {
1121: if (PetscIsInfOrNanScalar(v[i*n+j]))
1122: #if defined(PETSC_USE_COMPLEX)
1123: SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g+ig at matrix entry (%D,%D)",(double)PetscRealPart(v[i*n+j]),(double)PetscImaginaryPart(v[i*n+j]),idxm[i],idxn[j]);
1124: #else
1125: SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%D,%D)",(double)v[i*n+j],idxm[i],idxn[j]);
1126: #endif
1127: }
1128: }
1129: #endif
1131: if (mat->assembled) {
1132: mat->was_assembled = PETSC_TRUE;
1133: mat->assembled = PETSC_FALSE;
1134: }
1135: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1136: (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);
1137: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1138: #if defined(PETSC_HAVE_CUSP)
1139: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1140: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1141: }
1142: #endif
1143: #if defined(PETSC_HAVE_VIENNACL)
1144: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1145: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1146: }
1147: #endif
1148: return(0);
1149: }
1154: /*@
1155: MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
1156: values into a matrix
1158: Not Collective
1160: Input Parameters:
1161: + mat - the matrix
1162: . row - the (block) row to set
1163: - v - a logically two-dimensional array of values
1165: Notes:
1166: By the values, v, are column-oriented (for the block version) and sorted
1168: All the nonzeros in the row must be provided
1170: The matrix must have previously had its column indices set
1172: The row must belong to this process
1174: Level: intermediate
1176: Concepts: matrices^putting entries in
1178: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1179: InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping()
1180: @*/
1181: PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
1182: {
1184: PetscInt globalrow;
1190: ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);
1191: MatSetValuesRow(mat,globalrow,v);
1192: #if defined(PETSC_HAVE_CUSP)
1193: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1194: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1195: }
1196: #endif
1197: #if defined(PETSC_HAVE_VIENNACL)
1198: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1199: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1200: }
1201: #endif
1202: return(0);
1203: }
1207: /*@
1208: MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
1209: values into a matrix
1211: Not Collective
1213: Input Parameters:
1214: + mat - the matrix
1215: . row - the (block) row to set
1216: - v - a logically two-dimensional array of values
1218: Notes:
1219: The values, v, are column-oriented for the block version.
1221: All the nonzeros in the row must be provided
1223: THE MATRIX MUSAT HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually MatSetValues() is used.
1225: The row must belong to this process
1227: Level: advanced
1229: Concepts: matrices^putting entries in
1231: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1232: InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1233: @*/
1234: PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
1235: {
1241: MatCheckPreallocated(mat,1);
1243: #if defined(PETSC_USE_DEBUG)
1244: if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
1245: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1246: #endif
1247: mat->insertmode = INSERT_VALUES;
1249: if (mat->assembled) {
1250: mat->was_assembled = PETSC_TRUE;
1251: mat->assembled = PETSC_FALSE;
1252: }
1253: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1254: if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1255: (*mat->ops->setvaluesrow)(mat,row,v);
1256: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1257: #if defined(PETSC_HAVE_CUSP)
1258: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1259: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1260: }
1261: #endif
1262: #if defined(PETSC_HAVE_VIENNACL)
1263: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1264: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1265: }
1266: #endif
1267: return(0);
1268: }
1272: /*@
1273: MatSetValuesStencil - Inserts or adds a block of values into a matrix.
1274: Using structured grid indexing
1276: Not Collective
1278: Input Parameters:
1279: + mat - the matrix
1280: . m - number of rows being entered
1281: . idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
1282: . n - number of columns being entered
1283: . idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered
1284: . v - a logically two-dimensional array of values
1285: - addv - either ADD_VALUES or INSERT_VALUES, where
1286: ADD_VALUES adds values to any existing entries, and
1287: INSERT_VALUES replaces existing entries with new values
1289: Notes:
1290: By default the values, v, are row-oriented. See MatSetOption() for other options.
1292: Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
1293: options cannot be mixed without intervening calls to the assembly
1294: routines.
1296: The grid coordinates are across the entire grid, not just the local portion
1298: MatSetValuesStencil() uses 0-based row and column numbers in Fortran
1299: as well as in C.
1301: For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1303: In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1304: or call MatSetLocalToGlobalMapping() and MatSetStencil() first.
1306: The columns and rows in the stencil passed in MUST be contained within the
1307: ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1308: if you create a DMDA with an overlap of one grid level and on a particular process its first
1309: local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1310: first i index you can use in your column and row indices in MatSetStencil() is 5.
1312: In Fortran idxm and idxn should be declared as
1313: $ MatStencil idxm(4,m),idxn(4,n)
1314: and the values inserted using
1315: $ idxm(MatStencil_i,1) = i
1316: $ idxm(MatStencil_j,1) = j
1317: $ idxm(MatStencil_k,1) = k
1318: $ idxm(MatStencil_c,1) = c
1319: etc
1321: For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
1322: obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
1323: etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
1324: DM_BOUNDARY_PERIODIC boundary type.
1326: 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
1327: a single value per point) you can skip filling those indices.
1329: Inspired by the structured grid interface to the HYPRE package
1330: (http://www.llnl.gov/CASC/hypre)
1332: Efficiency Alert:
1333: The routine MatSetValuesBlockedStencil() may offer much better efficiency
1334: for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1336: Level: beginner
1338: Concepts: matrices^putting entries in
1340: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1341: MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil
1342: @*/
1343: PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1344: {
1346: PetscInt buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1347: PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1348: PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1351: if (!m || !n) return(0); /* no values to insert */
1358: if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1359: jdxm = buf; jdxn = buf+m;
1360: } else {
1361: PetscMalloc2(m,&bufm,n,&bufn);
1362: jdxm = bufm; jdxn = bufn;
1363: }
1364: for (i=0; i<m; i++) {
1365: for (j=0; j<3-sdim; j++) dxm++;
1366: tmp = *dxm++ - starts[0];
1367: for (j=0; j<dim-1; j++) {
1368: if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1369: else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1370: }
1371: if (mat->stencil.noc) dxm++;
1372: jdxm[i] = tmp;
1373: }
1374: for (i=0; i<n; i++) {
1375: for (j=0; j<3-sdim; j++) dxn++;
1376: tmp = *dxn++ - starts[0];
1377: for (j=0; j<dim-1; j++) {
1378: if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1379: else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1380: }
1381: if (mat->stencil.noc) dxn++;
1382: jdxn[i] = tmp;
1383: }
1384: MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);
1385: PetscFree2(bufm,bufn);
1386: return(0);
1387: }
1391: /*@
1392: MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1393: Using structured grid indexing
1395: Not Collective
1397: Input Parameters:
1398: + mat - the matrix
1399: . m - number of rows being entered
1400: . idxm - grid coordinates for matrix rows being entered
1401: . n - number of columns being entered
1402: . idxn - grid coordinates for matrix columns being entered
1403: . v - a logically two-dimensional array of values
1404: - addv - either ADD_VALUES or INSERT_VALUES, where
1405: ADD_VALUES adds values to any existing entries, and
1406: INSERT_VALUES replaces existing entries with new values
1408: Notes:
1409: By default the values, v, are row-oriented and unsorted.
1410: See MatSetOption() for other options.
1412: Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
1413: options cannot be mixed without intervening calls to the assembly
1414: routines.
1416: The grid coordinates are across the entire grid, not just the local portion
1418: MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran
1419: as well as in C.
1421: For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1423: In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1424: or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first.
1426: The columns and rows in the stencil passed in MUST be contained within the
1427: ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1428: if you create a DMDA with an overlap of one grid level and on a particular process its first
1429: local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1430: first i index you can use in your column and row indices in MatSetStencil() is 5.
1432: In Fortran idxm and idxn should be declared as
1433: $ MatStencil idxm(4,m),idxn(4,n)
1434: and the values inserted using
1435: $ idxm(MatStencil_i,1) = i
1436: $ idxm(MatStencil_j,1) = j
1437: $ idxm(MatStencil_k,1) = k
1438: etc
1440: Negative indices may be passed in idxm and idxn, these rows and columns are
1441: simply ignored. This allows easily inserting element stiffness matrices
1442: with homogeneous Dirchlet boundary conditions that you don't want represented
1443: in the matrix.
1445: Inspired by the structured grid interface to the HYPRE package
1446: (http://www.llnl.gov/CASC/hypre)
1448: Level: beginner
1450: Concepts: matrices^putting entries in
1452: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1453: MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil,
1454: MatSetBlockSize(), MatSetLocalToGlobalMapping()
1455: @*/
1456: PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1457: {
1459: PetscInt buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1460: PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1461: PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1464: if (!m || !n) return(0); /* no values to insert */
1471: if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1472: jdxm = buf; jdxn = buf+m;
1473: } else {
1474: PetscMalloc2(m,&bufm,n,&bufn);
1475: jdxm = bufm; jdxn = bufn;
1476: }
1477: for (i=0; i<m; i++) {
1478: for (j=0; j<3-sdim; j++) dxm++;
1479: tmp = *dxm++ - starts[0];
1480: for (j=0; j<sdim-1; j++) {
1481: if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1482: else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1483: }
1484: dxm++;
1485: jdxm[i] = tmp;
1486: }
1487: for (i=0; i<n; i++) {
1488: for (j=0; j<3-sdim; j++) dxn++;
1489: tmp = *dxn++ - starts[0];
1490: for (j=0; j<sdim-1; j++) {
1491: if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1492: else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1493: }
1494: dxn++;
1495: jdxn[i] = tmp;
1496: }
1497: MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);
1498: PetscFree2(bufm,bufn);
1499: #if defined(PETSC_HAVE_CUSP)
1500: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1501: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1502: }
1503: #endif
1504: #if defined(PETSC_HAVE_VIENNACL)
1505: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1506: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1507: }
1508: #endif
1509: return(0);
1510: }
1514: /*@
1515: MatSetStencil - Sets the grid information for setting values into a matrix via
1516: MatSetValuesStencil()
1518: Not Collective
1520: Input Parameters:
1521: + mat - the matrix
1522: . dim - dimension of the grid 1, 2, or 3
1523: . dims - number of grid points in x, y, and z direction, including ghost points on your processor
1524: . starts - starting point of ghost nodes on your processor in x, y, and z direction
1525: - dof - number of degrees of freedom per node
1528: Inspired by the structured grid interface to the HYPRE package
1529: (www.llnl.gov/CASC/hyper)
1531: For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the
1532: user.
1534: Level: beginner
1536: Concepts: matrices^putting entries in
1538: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1539: MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
1540: @*/
1541: PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1542: {
1543: PetscInt i;
1550: mat->stencil.dim = dim + (dof > 1);
1551: for (i=0; i<dim; i++) {
1552: mat->stencil.dims[i] = dims[dim-i-1]; /* copy the values in backwards */
1553: mat->stencil.starts[i] = starts[dim-i-1];
1554: }
1555: mat->stencil.dims[dim] = dof;
1556: mat->stencil.starts[dim] = 0;
1557: mat->stencil.noc = (PetscBool)(dof == 1);
1558: return(0);
1559: }
1563: /*@
1564: MatSetValuesBlocked - Inserts or adds a block of values into a matrix.
1566: Not Collective
1568: Input Parameters:
1569: + mat - the matrix
1570: . v - a logically two-dimensional array of values
1571: . m, idxm - the number of block rows and their global block indices
1572: . n, idxn - the number of block columns and their global block indices
1573: - addv - either ADD_VALUES or INSERT_VALUES, where
1574: ADD_VALUES adds values to any existing entries, and
1575: INSERT_VALUES replaces existing entries with new values
1577: Notes:
1578: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call
1579: MatXXXXSetPreallocation() or MatSetUp() before using this routine.
1581: The m and n count the NUMBER of blocks in the row direction and column direction,
1582: NOT the total number of rows/columns; for example, if the block size is 2 and
1583: you are passing in values for rows 2,3,4,5 then m would be 2 (not 4).
1584: The values in idxm would be 1 2; that is the first index for each block divided by
1585: the block size.
1587: Note that you must call MatSetBlockSize() when constructing this matrix (after
1588: preallocating it).
1590: By default the values, v, are row-oriented, so the layout of
1591: v is the same as for MatSetValues(). See MatSetOption() for other options.
1593: Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
1594: options cannot be mixed without intervening calls to the assembly
1595: routines.
1597: MatSetValuesBlocked() uses 0-based row and column numbers in Fortran
1598: as well as in C.
1600: Negative indices may be passed in idxm and idxn, these rows and columns are
1601: simply ignored. This allows easily inserting element stiffness matrices
1602: with homogeneous Dirchlet boundary conditions that you don't want represented
1603: in the matrix.
1605: Each time an entry is set within a sparse matrix via MatSetValues(),
1606: internal searching must be done to determine where to place the the
1607: data in the matrix storage space. By instead inserting blocks of
1608: entries via MatSetValuesBlocked(), the overhead of matrix assembly is
1609: reduced.
1611: Example:
1612: $ Suppose m=n=2 and block size(bs) = 2 The array is
1613: $
1614: $ 1 2 | 3 4
1615: $ 5 6 | 7 8
1616: $ - - - | - - -
1617: $ 9 10 | 11 12
1618: $ 13 14 | 15 16
1619: $
1620: $ v[] should be passed in like
1621: $ v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
1622: $
1623: $ If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then
1624: $ v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16]
1626: Level: intermediate
1628: Concepts: matrices^putting entries in blocked
1630: .seealso: MatSetBlockSize(), MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal()
1631: @*/
1632: PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1633: {
1639: if (!m || !n) return(0); /* no values to insert */
1643: MatCheckPreallocated(mat,1);
1644: if (mat->insertmode == NOT_SET_VALUES) {
1645: mat->insertmode = addv;
1646: }
1647: #if defined(PETSC_USE_DEBUG)
1648: else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1649: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1650: if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1651: #endif
1653: if (mat->assembled) {
1654: mat->was_assembled = PETSC_TRUE;
1655: mat->assembled = PETSC_FALSE;
1656: }
1657: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1658: if (mat->ops->setvaluesblocked) {
1659: (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);
1660: } else {
1661: PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn;
1662: PetscInt i,j,bs,cbs;
1663: MatGetBlockSizes(mat,&bs,&cbs);
1664: if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1665: iidxm = buf; iidxn = buf + m*bs;
1666: } else {
1667: PetscMalloc2(m*bs,&bufr,n*cbs,&bufc);
1668: iidxm = bufr; iidxn = bufc;
1669: }
1670: for (i=0; i<m; i++) {
1671: for (j=0; j<bs; j++) {
1672: iidxm[i*bs+j] = bs*idxm[i] + j;
1673: }
1674: }
1675: for (i=0; i<n; i++) {
1676: for (j=0; j<cbs; j++) {
1677: iidxn[i*cbs+j] = cbs*idxn[i] + j;
1678: }
1679: }
1680: MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv);
1681: PetscFree2(bufr,bufc);
1682: }
1683: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1684: #if defined(PETSC_HAVE_CUSP)
1685: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1686: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1687: }
1688: #endif
1689: #if defined(PETSC_HAVE_VIENNACL)
1690: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1691: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1692: }
1693: #endif
1694: return(0);
1695: }
1699: /*@
1700: MatGetValues - Gets a block of values from a matrix.
1702: Not Collective; currently only returns a local block
1704: Input Parameters:
1705: + mat - the matrix
1706: . v - a logically two-dimensional array for storing the values
1707: . m, idxm - the number of rows and their global indices
1708: - n, idxn - the number of columns and their global indices
1710: Notes:
1711: The user must allocate space (m*n PetscScalars) for the values, v.
1712: The values, v, are then returned in a row-oriented format,
1713: analogous to that used by default in MatSetValues().
1715: MatGetValues() uses 0-based row and column numbers in
1716: Fortran as well as in C.
1718: MatGetValues() requires that the matrix has been assembled
1719: with MatAssemblyBegin()/MatAssemblyEnd(). Thus, calls to
1720: MatSetValues() and MatGetValues() CANNOT be made in succession
1721: without intermediate matrix assembly.
1723: Negative row or column indices will be ignored and those locations in v[] will be
1724: left unchanged.
1726: Level: advanced
1728: Concepts: matrices^accessing values
1730: .seealso: MatGetRow(), MatGetSubMatrices(), MatSetValues()
1731: @*/
1732: PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1733: {
1739: if (!m || !n) return(0);
1743: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1744: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1745: if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1746: MatCheckPreallocated(mat,1);
1748: PetscLogEventBegin(MAT_GetValues,mat,0,0,0);
1749: (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);
1750: PetscLogEventEnd(MAT_GetValues,mat,0,0,0);
1751: return(0);
1752: }
1756: /*@
1757: MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and
1758: the same size. Currently, this can only be called once and creates the given matrix.
1760: Not Collective
1762: Input Parameters:
1763: + mat - the matrix
1764: . nb - the number of blocks
1765: . bs - the number of rows (and columns) in each block
1766: . rows - a concatenation of the rows for each block
1767: - v - a concatenation of logically two-dimensional arrays of values
1769: Notes:
1770: In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix.
1772: Level: advanced
1774: Concepts: matrices^putting entries in
1776: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1777: InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1778: @*/
1779: PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[])
1780: {
1788: #if defined(PETSC_USE_DEBUG)
1789: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1790: #endif
1792: PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);
1793: if (mat->ops->setvaluesbatch) {
1794: (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);
1795: } else {
1796: PetscInt b;
1797: for (b = 0; b < nb; ++b) {
1798: MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);
1799: }
1800: }
1801: PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);
1802: return(0);
1803: }
1807: /*@
1808: MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
1809: the routine MatSetValuesLocal() to allow users to insert matrix entries
1810: using a local (per-processor) numbering.
1812: Not Collective
1814: Input Parameters:
1815: + x - the matrix
1816: . rmapping - row mapping created with ISLocalToGlobalMappingCreate() or ISLocalToGlobalMappingCreateIS()
1817: - cmapping - column mapping
1819: Level: intermediate
1821: Concepts: matrices^local to global mapping
1822: Concepts: local to global mapping^for matrices
1824: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
1825: @*/
1826: PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
1827: {
1836: if (x->ops->setlocaltoglobalmapping) {
1837: (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);
1838: } else {
1839: PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);
1840: PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);
1841: }
1842: return(0);
1843: }
1848: /*@
1849: MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping()
1851: Not Collective
1853: Input Parameters:
1854: . A - the matrix
1856: Output Parameters:
1857: + rmapping - row mapping
1858: - cmapping - column mapping
1860: Level: advanced
1862: Concepts: matrices^local to global mapping
1863: Concepts: local to global mapping^for matrices
1865: .seealso: MatSetValuesLocal()
1866: @*/
1867: PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
1868: {
1874: if (rmapping) *rmapping = A->rmap->mapping;
1875: if (cmapping) *cmapping = A->cmap->mapping;
1876: return(0);
1877: }
1881: /*@
1882: MatGetLayouts - Gets the PetscLayout objects for rows and columns
1884: Not Collective
1886: Input Parameters:
1887: . A - the matrix
1889: Output Parameters:
1890: + rmap - row layout
1891: - cmap - column layout
1893: Level: advanced
1895: .seealso: MatGetVecs(), MatGetLocalToGlobalMapping()
1896: @*/
1897: PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap)
1898: {
1904: if (rmap) *rmap = A->rmap;
1905: if (cmap) *cmap = A->cmap;
1906: return(0);
1907: }
1911: /*@
1912: MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
1913: using a local ordering of the nodes.
1915: Not Collective
1917: Input Parameters:
1918: + x - the matrix
1919: . nrow, irow - number of rows and their local indices
1920: . ncol, icol - number of columns and their local indices
1921: . y - a logically two-dimensional array of values
1922: - addv - either INSERT_VALUES or ADD_VALUES, where
1923: ADD_VALUES adds values to any existing entries, and
1924: INSERT_VALUES replaces existing entries with new values
1926: Notes:
1927: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
1928: MatSetUp() before using this routine
1930: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine
1932: Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
1933: options cannot be mixed without intervening calls to the assembly
1934: routines.
1936: These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1937: MUST be called after all calls to MatSetValuesLocal() have been completed.
1939: Level: intermediate
1941: Concepts: matrices^putting entries in with local numbering
1943: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
1944: MatSetValueLocal()
1945: @*/
1946: PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
1947: {
1953: MatCheckPreallocated(mat,1);
1954: if (!nrow || !ncol) return(0); /* no values to insert */
1958: if (mat->insertmode == NOT_SET_VALUES) {
1959: mat->insertmode = addv;
1960: }
1961: #if defined(PETSC_USE_DEBUG)
1962: else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1963: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1964: if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1965: #endif
1967: if (mat->assembled) {
1968: mat->was_assembled = PETSC_TRUE;
1969: mat->assembled = PETSC_FALSE;
1970: }
1971: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1972: if (mat->ops->setvalueslocal) {
1973: (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);
1974: } else {
1975: PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
1976: if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1977: irowm = buf; icolm = buf+nrow;
1978: } else {
1979: PetscMalloc2(nrow,&bufr,ncol,&bufc);
1980: irowm = bufr; icolm = bufc;
1981: }
1982: ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);
1983: ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);
1984: MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);
1985: PetscFree2(bufr,bufc);
1986: }
1987: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1988: #if defined(PETSC_HAVE_CUSP)
1989: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1990: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1991: }
1992: #endif
1993: #if defined(PETSC_HAVE_VIENNACL)
1994: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1995: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1996: }
1997: #endif
1998: return(0);
1999: }
2003: /*@
2004: MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix,
2005: using a local ordering of the nodes a block at a time.
2007: Not Collective
2009: Input Parameters:
2010: + x - the matrix
2011: . nrow, irow - number of rows and their local indices
2012: . ncol, icol - number of columns and their local indices
2013: . y - a logically two-dimensional array of values
2014: - addv - either INSERT_VALUES or ADD_VALUES, where
2015: ADD_VALUES adds values to any existing entries, and
2016: INSERT_VALUES replaces existing entries with new values
2018: Notes:
2019: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
2020: MatSetUp() before using this routine
2022: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMapping()
2023: before using this routineBefore calling MatSetValuesLocal(), the user must first set the
2025: Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
2026: options cannot be mixed without intervening calls to the assembly
2027: routines.
2029: These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2030: MUST be called after all calls to MatSetValuesBlockedLocal() have been completed.
2032: Level: intermediate
2034: Concepts: matrices^putting blocked values in with local numbering
2036: .seealso: MatSetBlockSize(), MatSetLocalToGlobalMapping(), MatAssemblyBegin(), MatAssemblyEnd(),
2037: MatSetValuesLocal(), MatSetValuesBlocked()
2038: @*/
2039: PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2040: {
2046: MatCheckPreallocated(mat,1);
2047: if (!nrow || !ncol) return(0); /* no values to insert */
2051: if (mat->insertmode == NOT_SET_VALUES) {
2052: mat->insertmode = addv;
2053: }
2054: #if defined(PETSC_USE_DEBUG)
2055: else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2056: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2057: if (!mat->ops->setvaluesblockedlocal && !mat->ops->setvaluesblocked && !mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2058: #endif
2060: if (mat->assembled) {
2061: mat->was_assembled = PETSC_TRUE;
2062: mat->assembled = PETSC_FALSE;
2063: }
2064: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
2065: if (mat->ops->setvaluesblockedlocal) {
2066: (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);
2067: } else {
2068: PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2069: if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2070: irowm = buf; icolm = buf + nrow;
2071: } else {
2072: PetscMalloc2(nrow,&bufr,ncol,&bufc);
2073: irowm = bufr; icolm = bufc;
2074: }
2075: ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,irowm);
2076: ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,icolm);
2077: MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);
2078: PetscFree2(bufr,bufc);
2079: }
2080: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
2081: #if defined(PETSC_HAVE_CUSP)
2082: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
2083: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
2084: }
2085: #endif
2086: #if defined(PETSC_HAVE_VIENNACL)
2087: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
2088: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
2089: }
2090: #endif
2091: return(0);
2092: }
2096: /*@
2097: MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal
2099: Collective on Mat and Vec
2101: Input Parameters:
2102: + mat - the matrix
2103: - x - the vector to be multiplied
2105: Output Parameters:
2106: . y - the result
2108: Notes:
2109: The vectors x and y cannot be the same. I.e., one cannot
2110: call MatMult(A,y,y).
2112: Level: developer
2114: Concepts: matrix-vector product
2116: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2117: @*/
2118: PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y)
2119: {
2128: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2129: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2130: if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2131: MatCheckPreallocated(mat,1);
2133: if (!mat->ops->multdiagonalblock) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2134: (*mat->ops->multdiagonalblock)(mat,x,y);
2135: PetscObjectStateIncrease((PetscObject)y);
2136: return(0);
2137: }
2139: /* --------------------------------------------------------*/
2142: /*@
2143: MatMult - Computes the matrix-vector product, y = Ax.
2145: Neighbor-wise Collective on Mat and Vec
2147: Input Parameters:
2148: + mat - the matrix
2149: - x - the vector to be multiplied
2151: Output Parameters:
2152: . y - the result
2154: Notes:
2155: The vectors x and y cannot be the same. I.e., one cannot
2156: call MatMult(A,y,y).
2158: Level: beginner
2160: Concepts: matrix-vector product
2162: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2163: @*/
2164: PetscErrorCode MatMult(Mat mat,Vec x,Vec y)
2165: {
2173: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2174: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2175: if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2176: #if !defined(PETSC_HAVE_CONSTRAINTS)
2177: 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);
2178: 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);
2179: 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);
2180: #endif
2181: VecValidValues(x,2,PETSC_TRUE);
2182: MatCheckPreallocated(mat,1);
2184: if (!mat->ops->mult) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2185: PetscLogEventBegin(MAT_Mult,mat,x,y,0);
2186: (*mat->ops->mult)(mat,x,y);
2187: PetscLogEventEnd(MAT_Mult,mat,x,y,0);
2188: VecValidValues(y,3,PETSC_FALSE);
2189: return(0);
2190: }
2194: /*@
2195: MatMultTranspose - Computes matrix transpose times a vector.
2197: Neighbor-wise Collective on Mat and Vec
2199: Input Parameters:
2200: + mat - the matrix
2201: - x - the vector to be multilplied
2203: Output Parameters:
2204: . y - the result
2206: Notes:
2207: The vectors x and y cannot be the same. I.e., one cannot
2208: call MatMultTranspose(A,y,y).
2210: For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple,
2211: use MatMultHermitianTranspose()
2213: Level: beginner
2215: Concepts: matrix vector product^transpose
2217: .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose()
2218: @*/
2219: PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y)
2220: {
2229: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2230: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2231: if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2232: #if !defined(PETSC_HAVE_CONSTRAINTS)
2233: 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);
2234: 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);
2235: #endif
2236: VecValidValues(x,2,PETSC_TRUE);
2237: MatCheckPreallocated(mat,1);
2239: if (!mat->ops->multtranspose) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply tranpose defined");
2240: PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);
2241: (*mat->ops->multtranspose)(mat,x,y);
2242: PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);
2243: PetscObjectStateIncrease((PetscObject)y);
2244: VecValidValues(y,3,PETSC_FALSE);
2245: return(0);
2246: }
2250: /*@
2251: MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.
2253: Neighbor-wise Collective on Mat and Vec
2255: Input Parameters:
2256: + mat - the matrix
2257: - x - the vector to be multilplied
2259: Output Parameters:
2260: . y - the result
2262: Notes:
2263: The vectors x and y cannot be the same. I.e., one cannot
2264: call MatMultHermitianTranspose(A,y,y).
2266: Also called the conjugate transpose, complex conjugate transpose, or adjoint.
2268: For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical.
2270: Level: beginner
2272: Concepts: matrix vector product^transpose
2274: .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose()
2275: @*/
2276: PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y)
2277: {
2279: Vec w;
2287: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2288: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2289: if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2290: #if !defined(PETSC_HAVE_CONSTRAINTS)
2291: 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);
2292: 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);
2293: #endif
2294: MatCheckPreallocated(mat,1);
2296: PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);
2297: if (mat->ops->multhermitiantranspose) {
2298: (*mat->ops->multhermitiantranspose)(mat,x,y);
2299: } else {
2300: VecDuplicate(x,&w);
2301: VecCopy(x,w);
2302: VecConjugate(w);
2303: MatMultTranspose(mat,w,y);
2304: VecDestroy(&w);
2305: VecConjugate(y);
2306: }
2307: PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);
2308: PetscObjectStateIncrease((PetscObject)y);
2309: return(0);
2310: }
2314: /*@
2315: MatMultAdd - Computes v3 = v2 + A * v1.
2317: Neighbor-wise Collective on Mat and Vec
2319: Input Parameters:
2320: + mat - the matrix
2321: - v1, v2 - the vectors
2323: Output Parameters:
2324: . v3 - the result
2326: Notes:
2327: The vectors v1 and v3 cannot be the same. I.e., one cannot
2328: call MatMultAdd(A,v1,v2,v1).
2330: Level: beginner
2332: Concepts: matrix vector product^addition
2334: .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
2335: @*/
2336: PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2337: {
2347: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2348: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2349: if (mat->cmap->N != v1->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->cmap->N,v1->map->N);
2350: /* 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);
2351: 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); */
2352: 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);
2353: 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);
2354: if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2355: MatCheckPreallocated(mat,1);
2357: if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name);
2358: PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);
2359: (*mat->ops->multadd)(mat,v1,v2,v3);
2360: PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);
2361: PetscObjectStateIncrease((PetscObject)v3);
2362: return(0);
2363: }
2367: /*@
2368: MatMultTransposeAdd - Computes v3 = v2 + A' * v1.
2370: Neighbor-wise Collective on Mat and Vec
2372: Input Parameters:
2373: + mat - the matrix
2374: - v1, v2 - the vectors
2376: Output Parameters:
2377: . v3 - the result
2379: Notes:
2380: The vectors v1 and v3 cannot be the same. I.e., one cannot
2381: call MatMultTransposeAdd(A,v1,v2,v1).
2383: Level: beginner
2385: Concepts: matrix vector product^transpose and addition
2387: .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
2388: @*/
2389: PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2390: {
2400: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2401: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2402: if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2403: if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2404: if (mat->rmap->N != v1->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->rmap->N,v1->map->N);
2405: if (mat->cmap->N != v2->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->cmap->N,v2->map->N);
2406: if (mat->cmap->N != v3->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->cmap->N,v3->map->N);
2407: MatCheckPreallocated(mat,1);
2409: PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);
2410: (*mat->ops->multtransposeadd)(mat,v1,v2,v3);
2411: PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);
2412: PetscObjectStateIncrease((PetscObject)v3);
2413: return(0);
2414: }
2418: /*@
2419: MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1.
2421: Neighbor-wise Collective on Mat and Vec
2423: Input Parameters:
2424: + mat - the matrix
2425: - v1, v2 - the vectors
2427: Output Parameters:
2428: . v3 - the result
2430: Notes:
2431: The vectors v1 and v3 cannot be the same. I.e., one cannot
2432: call MatMultHermitianTransposeAdd(A,v1,v2,v1).
2434: Level: beginner
2436: Concepts: matrix vector product^transpose and addition
2438: .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult()
2439: @*/
2440: PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2441: {
2451: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2452: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2453: if (!mat->ops->multhermitiantransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2454: if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2455: if (mat->rmap->N != v1->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->rmap->N,v1->map->N);
2456: if (mat->cmap->N != v2->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->cmap->N,v2->map->N);
2457: if (mat->cmap->N != v3->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->cmap->N,v3->map->N);
2458: MatCheckPreallocated(mat,1);
2460: PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2461: (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);
2462: PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2463: PetscObjectStateIncrease((PetscObject)v3);
2464: return(0);
2465: }
2469: /*@
2470: MatMultConstrained - The inner multiplication routine for a
2471: constrained matrix P^T A P.
2473: Neighbor-wise Collective on Mat and Vec
2475: Input Parameters:
2476: + mat - the matrix
2477: - x - the vector to be multilplied
2479: Output Parameters:
2480: . y - the result
2482: Notes:
2483: The vectors x and y cannot be the same. I.e., one cannot
2484: call MatMult(A,y,y).
2486: Level: beginner
2488: .keywords: matrix, multiply, matrix-vector product, constraint
2489: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2490: @*/
2491: PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y)
2492: {
2499: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2500: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2501: if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2502: 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);
2503: 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);
2504: 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);
2506: PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2507: (*mat->ops->multconstrained)(mat,x,y);
2508: PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2509: PetscObjectStateIncrease((PetscObject)y);
2510: return(0);
2511: }
2515: /*@
2516: MatMultTransposeConstrained - The inner multiplication routine for a
2517: constrained matrix P^T A^T P.
2519: Neighbor-wise Collective on Mat and Vec
2521: Input Parameters:
2522: + mat - the matrix
2523: - x - the vector to be multilplied
2525: Output Parameters:
2526: . y - the result
2528: Notes:
2529: The vectors x and y cannot be the same. I.e., one cannot
2530: call MatMult(A,y,y).
2532: Level: beginner
2534: .keywords: matrix, multiply, matrix-vector product, constraint
2535: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2536: @*/
2537: PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2538: {
2545: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2546: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2547: if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2548: 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);
2549: 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);
2551: PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2552: (*mat->ops->multtransposeconstrained)(mat,x,y);
2553: PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2554: PetscObjectStateIncrease((PetscObject)y);
2555: return(0);
2556: }
2560: /*@C
2561: MatGetFactorType - gets the type of factorization it is
2563: Note Collective
2564: as the flag
2566: Input Parameters:
2567: . mat - the matrix
2569: Output Parameters:
2570: . t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT
2572: Level: intermediate
2574: .seealso: MatFactorType, MatGetFactor()
2575: @*/
2576: PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t)
2577: {
2581: *t = mat->factortype;
2582: return(0);
2583: }
2585: /* ------------------------------------------------------------*/
2588: /*@C
2589: MatGetInfo - Returns information about matrix storage (number of
2590: nonzeros, memory, etc.).
2592: Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag
2594: Input Parameters:
2595: . mat - the matrix
2597: Output Parameters:
2598: + flag - flag indicating the type of parameters to be returned
2599: (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2600: MAT_GLOBAL_SUM - sum over all processors)
2601: - info - matrix information context
2603: Notes:
2604: The MatInfo context contains a variety of matrix data, including
2605: number of nonzeros allocated and used, number of mallocs during
2606: matrix assembly, etc. Additional information for factored matrices
2607: is provided (such as the fill ratio, number of mallocs during
2608: factorization, etc.). Much of this info is printed to PETSC_STDOUT
2609: when using the runtime options
2610: $ -info -mat_view ::ascii_info
2612: Example for C/C++ Users:
2613: See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2614: data within the MatInfo context. For example,
2615: .vb
2616: MatInfo info;
2617: Mat A;
2618: double mal, nz_a, nz_u;
2620: MatGetInfo(A,MAT_LOCAL,&info);
2621: mal = info.mallocs;
2622: nz_a = info.nz_allocated;
2623: .ve
2625: Example for Fortran Users:
2626: Fortran users should declare info as a double precision
2627: array of dimension MAT_INFO_SIZE, and then extract the parameters
2628: of interest. See the file ${PETSC_DIR}/include/finclude/petscmat.h
2629: a complete list of parameter names.
2630: .vb
2631: double precision info(MAT_INFO_SIZE)
2632: double precision mal, nz_a
2633: Mat A
2634: integer ierr
2636: call MatGetInfo(A,MAT_LOCAL,info,ierr)
2637: mal = info(MAT_INFO_MALLOCS)
2638: nz_a = info(MAT_INFO_NZ_ALLOCATED)
2639: .ve
2641: Level: intermediate
2643: Concepts: matrices^getting information on
2645: Developer Note: fortran interface is not autogenerated as the f90
2646: interface defintion cannot be generated correctly [due to MatInfo]
2648: .seealso: MatStashGetInfo()
2650: @*/
2651: PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2652: {
2659: if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2660: MatCheckPreallocated(mat,1);
2661: (*mat->ops->getinfo)(mat,flag,info);
2662: return(0);
2663: }
2665: /* ----------------------------------------------------------*/
2669: /*@C
2670: MatLUFactor - Performs in-place LU factorization of matrix.
2672: Collective on Mat
2674: Input Parameters:
2675: + mat - the matrix
2676: . row - row permutation
2677: . col - column permutation
2678: - info - options for factorization, includes
2679: $ fill - expected fill as ratio of original fill.
2680: $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2681: $ Run with the option -info to determine an optimal value to use
2683: Notes:
2684: Most users should employ the simplified KSP interface for linear solvers
2685: instead of working directly with matrix algebra routines such as this.
2686: See, e.g., KSPCreate().
2688: This changes the state of the matrix to a factored matrix; it cannot be used
2689: for example with MatSetValues() unless one first calls MatSetUnfactored().
2691: Level: developer
2693: Concepts: matrices^LU factorization
2695: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2696: MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor()
2698: Developer Note: fortran interface is not autogenerated as the f90
2699: interface defintion cannot be generated correctly [due to MatFactorInfo]
2701: @*/
2702: PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2703: {
2705: MatFactorInfo tinfo;
2713: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2714: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2715: if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2716: MatCheckPreallocated(mat,1);
2717: if (!info) {
2718: MatFactorInfoInitialize(&tinfo);
2719: info = &tinfo;
2720: }
2722: PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);
2723: (*mat->ops->lufactor)(mat,row,col,info);
2724: PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);
2725: PetscObjectStateIncrease((PetscObject)mat);
2726: return(0);
2727: }
2731: /*@C
2732: MatILUFactor - Performs in-place ILU factorization of matrix.
2734: Collective on Mat
2736: Input Parameters:
2737: + mat - the matrix
2738: . row - row permutation
2739: . col - column permutation
2740: - info - structure containing
2741: $ levels - number of levels of fill.
2742: $ expected fill - as ratio of original fill.
2743: $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2744: missing diagonal entries)
2746: Notes:
2747: Probably really in-place only when level of fill is zero, otherwise allocates
2748: new space to store factored matrix and deletes previous memory.
2750: Most users should employ the simplified KSP interface for linear solvers
2751: instead of working directly with matrix algebra routines such as this.
2752: See, e.g., KSPCreate().
2754: Level: developer
2756: Concepts: matrices^ILU factorization
2758: .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
2760: Developer Note: fortran interface is not autogenerated as the f90
2761: interface defintion cannot be generated correctly [due to MatFactorInfo]
2763: @*/
2764: PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2765: {
2774: if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
2775: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2776: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2777: if (!mat->ops->ilufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2778: MatCheckPreallocated(mat,1);
2780: PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);
2781: (*mat->ops->ilufactor)(mat,row,col,info);
2782: PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);
2783: PetscObjectStateIncrease((PetscObject)mat);
2784: return(0);
2785: }
2789: /*@C
2790: MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
2791: Call this routine before calling MatLUFactorNumeric().
2793: Collective on Mat
2795: Input Parameters:
2796: + fact - the factor matrix obtained with MatGetFactor()
2797: . mat - the matrix
2798: . row, col - row and column permutations
2799: - info - options for factorization, includes
2800: $ fill - expected fill as ratio of original fill.
2801: $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2802: $ Run with the option -info to determine an optimal value to use
2805: Notes: See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
2807: Most users should employ the simplified KSP interface for linear solvers
2808: instead of working directly with matrix algebra routines such as this.
2809: See, e.g., KSPCreate().
2811: Level: developer
2813: Concepts: matrices^LU symbolic factorization
2815: .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
2817: Developer Note: fortran interface is not autogenerated as the f90
2818: interface defintion cannot be generated correctly [due to MatFactorInfo]
2820: @*/
2821: PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
2822: {
2832: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2833: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2834: if (!(fact)->ops->lufactorsymbolic) {
2835: const MatSolverPackage spackage;
2836: MatFactorGetSolverPackage(fact,&spackage);
2837: SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage);
2838: }
2839: MatCheckPreallocated(mat,2);
2841: PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);
2842: (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);
2843: PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);
2844: PetscObjectStateIncrease((PetscObject)fact);
2845: return(0);
2846: }
2850: /*@C
2851: MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
2852: Call this routine after first calling MatLUFactorSymbolic().
2854: Collective on Mat
2856: Input Parameters:
2857: + fact - the factor matrix obtained with MatGetFactor()
2858: . mat - the matrix
2859: - info - options for factorization
2861: Notes:
2862: See MatLUFactor() for in-place factorization. See
2863: MatCholeskyFactorNumeric() for the symmetric, positive definite case.
2865: Most users should employ the simplified KSP interface for linear solvers
2866: instead of working directly with matrix algebra routines such as this.
2867: See, e.g., KSPCreate().
2869: Level: developer
2871: Concepts: matrices^LU numeric factorization
2873: .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()
2875: Developer Note: fortran interface is not autogenerated as the f90
2876: interface defintion cannot be generated correctly [due to MatFactorInfo]
2878: @*/
2879: PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
2880: {
2888: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2889: if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) SETERRQ4(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dimensions are different %D should = %D %D should = %D",mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N);
2891: if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name);
2892: MatCheckPreallocated(mat,2);
2893: PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);
2894: (fact->ops->lufactornumeric)(fact,mat,info);
2895: PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);
2896: MatViewFromOptions(fact,NULL,"-mat_factor_view");
2897: PetscObjectStateIncrease((PetscObject)fact);
2898: return(0);
2899: }
2903: /*@C
2904: MatCholeskyFactor - Performs in-place Cholesky factorization of a
2905: symmetric matrix.
2907: Collective on Mat
2909: Input Parameters:
2910: + mat - the matrix
2911: . perm - row and column permutations
2912: - f - expected fill as ratio of original fill
2914: Notes:
2915: See MatLUFactor() for the nonsymmetric case. See also
2916: MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().
2918: Most users should employ the simplified KSP interface for linear solvers
2919: instead of working directly with matrix algebra routines such as this.
2920: See, e.g., KSPCreate().
2922: Level: developer
2924: Concepts: matrices^Cholesky factorization
2926: .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
2927: MatGetOrdering()
2929: Developer Note: fortran interface is not autogenerated as the f90
2930: interface defintion cannot be generated correctly [due to MatFactorInfo]
2932: @*/
2933: PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
2934: {
2942: if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
2943: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2944: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2945: if (!mat->ops->choleskyfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2946: MatCheckPreallocated(mat,1);
2948: PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);
2949: (*mat->ops->choleskyfactor)(mat,perm,info);
2950: PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);
2951: PetscObjectStateIncrease((PetscObject)mat);
2952: return(0);
2953: }
2957: /*@C
2958: MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
2959: of a symmetric matrix.
2961: Collective on Mat
2963: Input Parameters:
2964: + fact - the factor matrix obtained with MatGetFactor()
2965: . mat - the matrix
2966: . perm - row and column permutations
2967: - info - options for factorization, includes
2968: $ fill - expected fill as ratio of original fill.
2969: $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2970: $ Run with the option -info to determine an optimal value to use
2972: Notes:
2973: See MatLUFactorSymbolic() for the nonsymmetric case. See also
2974: MatCholeskyFactor() and MatCholeskyFactorNumeric().
2976: Most users should employ the simplified KSP interface for linear solvers
2977: instead of working directly with matrix algebra routines such as this.
2978: See, e.g., KSPCreate().
2980: Level: developer
2982: Concepts: matrices^Cholesky symbolic factorization
2984: .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
2985: MatGetOrdering()
2987: Developer Note: fortran interface is not autogenerated as the f90
2988: interface defintion cannot be generated correctly [due to MatFactorInfo]
2990: @*/
2991: PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
2992: {
3001: if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3002: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3003: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3004: if (!(fact)->ops->choleskyfactorsymbolic) {
3005: const MatSolverPackage spackage;
3006: MatFactorGetSolverPackage(fact,&spackage);
3007: SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage);
3008: }
3009: MatCheckPreallocated(mat,2);
3011: PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
3012: (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);
3013: PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
3014: PetscObjectStateIncrease((PetscObject)fact);
3015: return(0);
3016: }
3020: /*@C
3021: MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
3022: of a symmetric matrix. Call this routine after first calling
3023: MatCholeskyFactorSymbolic().
3025: Collective on Mat
3027: Input Parameters:
3028: + fact - the factor matrix obtained with MatGetFactor()
3029: . mat - the initial matrix
3030: . info - options for factorization
3031: - fact - the symbolic factor of mat
3034: Notes:
3035: Most users should employ the simplified KSP interface for linear solvers
3036: instead of working directly with matrix algebra routines such as this.
3037: See, e.g., KSPCreate().
3039: Level: developer
3041: Concepts: matrices^Cholesky numeric factorization
3043: .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
3045: Developer Note: fortran interface is not autogenerated as the f90
3046: interface defintion cannot be generated correctly [due to MatFactorInfo]
3048: @*/
3049: PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3050: {
3058: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3059: if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name);
3060: if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) SETERRQ4(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dim %D should = %D %D should = %D",mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N);
3061: MatCheckPreallocated(mat,2);
3063: PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);
3064: (fact->ops->choleskyfactornumeric)(fact,mat,info);
3065: PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);
3066: MatViewFromOptions(fact,NULL,"-mat_factor_view");
3067: PetscObjectStateIncrease((PetscObject)fact);
3068: return(0);
3069: }
3071: /* ----------------------------------------------------------------*/
3074: /*@
3075: MatSolve - Solves A x = b, given a factored matrix.
3077: Neighbor-wise Collective on Mat and Vec
3079: Input Parameters:
3080: + mat - the factored matrix
3081: - b - the right-hand-side vector
3083: Output Parameter:
3084: . x - the result vector
3086: Notes:
3087: The vectors b and x cannot be the same. I.e., one cannot
3088: call MatSolve(A,x,x).
3090: Notes:
3091: Most users should employ the simplified KSP interface for linear solvers
3092: instead of working directly with matrix algebra routines such as this.
3093: See, e.g., KSPCreate().
3095: Level: developer
3097: Concepts: matrices^triangular solves
3099: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
3100: @*/
3101: PetscErrorCode MatSolve(Mat mat,Vec b,Vec x)
3102: {
3112: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3113: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3114: if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3115: if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3116: 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);
3117: if (!mat->rmap->N && !mat->cmap->N) return(0);
3118: if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3119: MatCheckPreallocated(mat,1);
3121: PetscLogEventBegin(MAT_Solve,mat,b,x,0);
3122: (*mat->ops->solve)(mat,b,x);
3123: PetscLogEventEnd(MAT_Solve,mat,b,x,0);
3124: PetscObjectStateIncrease((PetscObject)x);
3125: return(0);
3126: }
3130: PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X)
3131: {
3133: Vec b,x;
3134: PetscInt m,N,i;
3135: PetscScalar *bb,*xx;
3136: PetscBool flg;
3139: PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);
3140: if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
3141: PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);
3142: if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");
3144: MatDenseGetArray(B,&bb);
3145: MatDenseGetArray(X,&xx);
3146: MatGetLocalSize(B,&m,NULL); /* number local rows */
3147: MatGetSize(B,NULL,&N); /* total columns in dense matrix */
3148: MatGetVecs(A,&x,&b);
3149: for (i=0; i<N; i++) {
3150: VecPlaceArray(b,bb + i*m);
3151: VecPlaceArray(x,xx + i*m);
3152: MatSolve(A,b,x);
3153: VecResetArray(x);
3154: VecResetArray(b);
3155: }
3156: VecDestroy(&b);
3157: VecDestroy(&x);
3158: MatDenseRestoreArray(B,&bb);
3159: MatDenseRestoreArray(X,&xx);
3160: return(0);
3161: }
3165: /*@
3166: MatMatSolve - Solves A X = B, given a factored matrix.
3168: Neighbor-wise Collective on Mat
3170: Input Parameters:
3171: + mat - the factored matrix
3172: - B - the right-hand-side matrix (dense matrix)
3174: Output Parameter:
3175: . X - the result matrix (dense matrix)
3177: Notes:
3178: The matrices b and x cannot be the same. I.e., one cannot
3179: call MatMatSolve(A,x,x).
3181: Notes:
3182: Most users should usually employ the simplified KSP interface for linear solvers
3183: instead of working directly with matrix algebra routines such as this.
3184: See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3185: at a time.
3187: When using SuperLU_Dist as a parallel solver PETSc will use the SuperLU_Dist functionality to solve multiple right hand sides simultaneously. For MUMPS
3188: it calls a separate solve for each right hand side since MUMPS does not yet support distributed right hand sides.
3190: Since the resulting matrix X must always be dense we do not support sparse representation of the matrix B.
3192: Level: developer
3194: Concepts: matrices^triangular solves
3196: .seealso: MatMatSolveAdd(), MatMatSolveTranspose(), MatMatSolveTransposeAdd(), MatLUFactor(), MatCholeskyFactor()
3197: @*/
3198: PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X)
3199: {
3209: if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3210: if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3211: if (A->cmap->N != X->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %D %D",A->cmap->N,X->rmap->N);
3212: if (A->rmap->N != B->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %D %D",A->rmap->N,B->rmap->N);
3213: 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);
3214: if (!A->rmap->N && !A->cmap->N) return(0);
3215: MatCheckPreallocated(A,1);
3217: PetscLogEventBegin(MAT_MatSolve,A,B,X,0);
3218: if (!A->ops->matsolve) {
3219: PetscInfo1(A,"Mat type %s using basic MatMatSolve",((PetscObject)A)->type_name);
3220: MatMatSolve_Basic(A,B,X);
3221: } else {
3222: (*A->ops->matsolve)(A,B,X);
3223: }
3224: PetscLogEventEnd(MAT_MatSolve,A,B,X,0);
3225: PetscObjectStateIncrease((PetscObject)X);
3226: return(0);
3227: }
3232: /*@
3233: MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or
3234: U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U,
3236: Neighbor-wise Collective on Mat and Vec
3238: Input Parameters:
3239: + mat - the factored matrix
3240: - b - the right-hand-side vector
3242: Output Parameter:
3243: . x - the result vector
3245: Notes:
3246: MatSolve() should be used for most applications, as it performs
3247: a forward solve followed by a backward solve.
3249: The vectors b and x cannot be the same, i.e., one cannot
3250: call MatForwardSolve(A,x,x).
3252: For matrix in seqsbaij format with block size larger than 1,
3253: the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3254: MatForwardSolve() solves U^T*D y = b, and
3255: MatBackwardSolve() solves U x = y.
3256: Thus they do not provide a symmetric preconditioner.
3258: Most users should employ the simplified KSP interface for linear solvers
3259: instead of working directly with matrix algebra routines such as this.
3260: See, e.g., KSPCreate().
3262: Level: developer
3264: Concepts: matrices^forward solves
3266: .seealso: MatSolve(), MatBackwardSolve()
3267: @*/
3268: PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x)
3269: {
3279: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3280: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3281: if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3282: if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3283: if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3284: 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);
3285: MatCheckPreallocated(mat,1);
3286: PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);
3287: (*mat->ops->forwardsolve)(mat,b,x);
3288: PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);
3289: PetscObjectStateIncrease((PetscObject)x);
3290: return(0);
3291: }
3295: /*@
3296: MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
3297: D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U,
3299: Neighbor-wise Collective on Mat and Vec
3301: Input Parameters:
3302: + mat - the factored matrix
3303: - b - the right-hand-side vector
3305: Output Parameter:
3306: . x - the result vector
3308: Notes:
3309: MatSolve() should be used for most applications, as it performs
3310: a forward solve followed by a backward solve.
3312: The vectors b and x cannot be the same. I.e., one cannot
3313: call MatBackwardSolve(A,x,x).
3315: For matrix in seqsbaij format with block size larger than 1,
3316: the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3317: MatForwardSolve() solves U^T*D y = b, and
3318: MatBackwardSolve() solves U x = y.
3319: Thus they do not provide a symmetric preconditioner.
3321: Most users should employ the simplified KSP interface for linear solvers
3322: instead of working directly with matrix algebra routines such as this.
3323: See, e.g., KSPCreate().
3325: Level: developer
3327: Concepts: matrices^backward solves
3329: .seealso: MatSolve(), MatForwardSolve()
3330: @*/
3331: PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x)
3332: {
3342: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3343: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3344: if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3345: if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3346: if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3347: 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);
3348: MatCheckPreallocated(mat,1);
3350: PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);
3351: (*mat->ops->backwardsolve)(mat,b,x);
3352: PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);
3353: PetscObjectStateIncrease((PetscObject)x);
3354: return(0);
3355: }
3359: /*@
3360: MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
3362: Neighbor-wise Collective on Mat and Vec
3364: Input Parameters:
3365: + mat - the factored matrix
3366: . b - the right-hand-side vector
3367: - y - the vector to be added to
3369: Output Parameter:
3370: . x - the result vector
3372: Notes:
3373: The vectors b and x cannot be the same. I.e., one cannot
3374: call MatSolveAdd(A,x,y,x).
3376: Most users should employ the simplified KSP interface for linear solvers
3377: instead of working directly with matrix algebra routines such as this.
3378: See, e.g., KSPCreate().
3380: Level: developer
3382: Concepts: matrices^triangular solves
3384: .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3385: @*/
3386: PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3387: {
3388: PetscScalar one = 1.0;
3389: Vec tmp;
3401: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3402: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3403: if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3404: if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3405: if (mat->rmap->N != y->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
3406: 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);
3407: 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);
3408: MatCheckPreallocated(mat,1);
3410: PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);
3411: if (mat->ops->solveadd) {
3412: (*mat->ops->solveadd)(mat,b,y,x);
3413: } else {
3414: /* do the solve then the add manually */
3415: if (x != y) {
3416: MatSolve(mat,b,x);
3417: VecAXPY(x,one,y);
3418: } else {
3419: VecDuplicate(x,&tmp);
3420: PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);
3421: VecCopy(x,tmp);
3422: MatSolve(mat,b,x);
3423: VecAXPY(x,one,tmp);
3424: VecDestroy(&tmp);
3425: }
3426: }
3427: PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);
3428: PetscObjectStateIncrease((PetscObject)x);
3429: return(0);
3430: }
3434: /*@
3435: MatSolveTranspose - Solves A' x = b, given a factored matrix.
3437: Neighbor-wise Collective on Mat and Vec
3439: Input Parameters:
3440: + mat - the factored matrix
3441: - b - the right-hand-side vector
3443: Output Parameter:
3444: . x - the result vector
3446: Notes:
3447: The vectors b and x cannot be the same. I.e., one cannot
3448: call MatSolveTranspose(A,x,x).
3450: Most users should employ the simplified KSP interface for linear solvers
3451: instead of working directly with matrix algebra routines such as this.
3452: See, e.g., KSPCreate().
3454: Level: developer
3456: Concepts: matrices^triangular solves
3458: .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
3459: @*/
3460: PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x)
3461: {
3471: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3472: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3473: if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3474: if (mat->rmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
3475: if (mat->cmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->cmap->N,b->map->N);
3476: MatCheckPreallocated(mat,1);
3477: PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);
3478: (*mat->ops->solvetranspose)(mat,b,x);
3479: PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);
3480: PetscObjectStateIncrease((PetscObject)x);
3481: return(0);
3482: }
3486: /*@
3487: MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
3488: factored matrix.
3490: Neighbor-wise Collective on Mat and Vec
3492: Input Parameters:
3493: + mat - the factored matrix
3494: . b - the right-hand-side vector
3495: - y - the vector to be added to
3497: Output Parameter:
3498: . x - the result vector
3500: Notes:
3501: The vectors b and x cannot be the same. I.e., one cannot
3502: call MatSolveTransposeAdd(A,x,y,x).
3504: Most users should employ the simplified KSP interface for linear solvers
3505: instead of working directly with matrix algebra routines such as this.
3506: See, e.g., KSPCreate().
3508: Level: developer
3510: Concepts: matrices^triangular solves
3512: .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3513: @*/
3514: PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3515: {
3516: PetscScalar one = 1.0;
3518: Vec tmp;
3529: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3530: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3531: if (mat->rmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
3532: if (mat->cmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->cmap->N,b->map->N);
3533: if (mat->cmap->N != y->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N);
3534: 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);
3535: MatCheckPreallocated(mat,1);
3537: PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);
3538: if (mat->ops->solvetransposeadd) {
3539: (*mat->ops->solvetransposeadd)(mat,b,y,x);
3540: } else {
3541: /* do the solve then the add manually */
3542: if (x != y) {
3543: MatSolveTranspose(mat,b,x);
3544: VecAXPY(x,one,y);
3545: } else {
3546: VecDuplicate(x,&tmp);
3547: PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);
3548: VecCopy(x,tmp);
3549: MatSolveTranspose(mat,b,x);
3550: VecAXPY(x,one,tmp);
3551: VecDestroy(&tmp);
3552: }
3553: }
3554: PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);
3555: PetscObjectStateIncrease((PetscObject)x);
3556: return(0);
3557: }
3558: /* ----------------------------------------------------------------*/
3562: /*@
3563: MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps.
3565: Neighbor-wise Collective on Mat and Vec
3567: Input Parameters:
3568: + mat - the matrix
3569: . b - the right hand side
3570: . omega - the relaxation factor
3571: . flag - flag indicating the type of SOR (see below)
3572: . shift - diagonal shift
3573: . its - the number of iterations
3574: - lits - the number of local iterations
3576: Output Parameters:
3577: . x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess)
3579: SOR Flags:
3580: . SOR_FORWARD_SWEEP - forward SOR
3581: . SOR_BACKWARD_SWEEP - backward SOR
3582: . SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3583: . SOR_LOCAL_FORWARD_SWEEP - local forward SOR
3584: . SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
3585: . SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3586: . SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
3587: upper/lower triangular part of matrix to
3588: vector (with omega)
3589: . SOR_ZERO_INITIAL_GUESS - zero initial guess
3591: Notes:
3592: SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3593: SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3594: on each processor.
3596: Application programmers will not generally use MatSOR() directly,
3597: but instead will employ the KSP/PC interface.
3599: Notes: for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing
3601: Notes for Advanced Users:
3602: The flags are implemented as bitwise inclusive or operations.
3603: For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3604: to specify a zero initial guess for SSOR.
3606: Most users should employ the simplified KSP interface for linear solvers
3607: instead of working directly with matrix algebra routines such as this.
3608: See, e.g., KSPCreate().
3610: Vectors x and b CANNOT be the same
3612: Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes
3614: Level: developer
3616: Concepts: matrices^relaxation
3617: Concepts: matrices^SOR
3618: Concepts: matrices^Gauss-Seidel
3620: @*/
3621: PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3622: {
3632: if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3633: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3634: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3635: if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3636: if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3637: 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);
3638: if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
3639: if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
3640: if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");
3642: MatCheckPreallocated(mat,1);
3643: PetscLogEventBegin(MAT_SOR,mat,b,x,0);
3644: ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);
3645: PetscLogEventEnd(MAT_SOR,mat,b,x,0);
3646: PetscObjectStateIncrease((PetscObject)x);
3647: return(0);
3648: }
3652: /*
3653: Default matrix copy routine.
3654: */
3655: PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
3656: {
3657: PetscErrorCode ierr;
3658: PetscInt i,rstart = 0,rend = 0,nz;
3659: const PetscInt *cwork;
3660: const PetscScalar *vwork;
3663: if (B->assembled) {
3664: MatZeroEntries(B);
3665: }
3666: MatGetOwnershipRange(A,&rstart,&rend);
3667: for (i=rstart; i<rend; i++) {
3668: MatGetRow(A,i,&nz,&cwork,&vwork);
3669: MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);
3670: MatRestoreRow(A,i,&nz,&cwork,&vwork);
3671: }
3672: MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
3673: MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);
3674: PetscObjectStateIncrease((PetscObject)B);
3675: return(0);
3676: }
3680: /*@
3681: MatCopy - Copys a matrix to another matrix.
3683: Collective on Mat
3685: Input Parameters:
3686: + A - the matrix
3687: - str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
3689: Output Parameter:
3690: . B - where the copy is put
3692: Notes:
3693: If you use SAME_NONZERO_PATTERN then the two matrices had better have the
3694: same nonzero pattern or the routine will crash.
3696: MatCopy() copies the matrix entries of a matrix to another existing
3697: matrix (after first zeroing the second matrix). A related routine is
3698: MatConvert(), which first creates a new matrix and then copies the data.
3700: Level: intermediate
3702: Concepts: matrices^copying
3704: .seealso: MatConvert(), MatDuplicate()
3706: @*/
3707: PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str)
3708: {
3710: PetscInt i;
3718: MatCheckPreallocated(B,2);
3719: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3720: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3721: if (A->rmap->N != B->rmap->N || A->cmap->N != B->cmap->N) SETERRQ4(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim (%D,%D) (%D,%D)",A->rmap->N,B->rmap->N,A->cmap->N,B->cmap->N);
3722: MatCheckPreallocated(A,1);
3724: PetscLogEventBegin(MAT_Copy,A,B,0,0);
3725: if (A->ops->copy) {
3726: (*A->ops->copy)(A,B,str);
3727: } else { /* generic conversion */
3728: MatCopy_Basic(A,B,str);
3729: }
3731: B->stencil.dim = A->stencil.dim;
3732: B->stencil.noc = A->stencil.noc;
3733: for (i=0; i<=A->stencil.dim; i++) {
3734: B->stencil.dims[i] = A->stencil.dims[i];
3735: B->stencil.starts[i] = A->stencil.starts[i];
3736: }
3738: PetscLogEventEnd(MAT_Copy,A,B,0,0);
3739: PetscObjectStateIncrease((PetscObject)B);
3740: return(0);
3741: }
3745: /*@C
3746: MatConvert - Converts a matrix to another matrix, either of the same
3747: or different type.
3749: Collective on Mat
3751: Input Parameters:
3752: + mat - the matrix
3753: . newtype - new matrix type. Use MATSAME to create a new matrix of the
3754: same type as the original matrix.
3755: - reuse - denotes if the destination matrix is to be created or reused. Currently
3756: MAT_REUSE_MATRIX is only supported for inplace conversion, otherwise use
3757: MAT_INITIAL_MATRIX.
3759: Output Parameter:
3760: . M - pointer to place new matrix
3762: Notes:
3763: MatConvert() first creates a new matrix and then copies the data from
3764: the first matrix. A related routine is MatCopy(), which copies the matrix
3765: entries of one matrix to another already existing matrix context.
3767: Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
3768: the MPI communicator of the generated matrix is always the same as the communicator
3769: of the input matrix.
3771: Level: intermediate
3773: Concepts: matrices^converting between storage formats
3775: .seealso: MatCopy(), MatDuplicate()
3776: @*/
3777: PetscErrorCode MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M)
3778: {
3780: PetscBool sametype,issame,flg;
3781: char convname[256],mtype[256];
3782: Mat B;
3788: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3789: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3790: MatCheckPreallocated(mat,1);
3791: MatSetOption(mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);
3793: PetscOptionsGetString(((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);
3794: if (flg) {
3795: newtype = mtype;
3796: }
3797: PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);
3798: PetscStrcmp(newtype,"same",&issame);
3799: if ((reuse == MAT_REUSE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_REUSE_MATRIX only supported for in-place conversion currently");
3801: if ((reuse == MAT_REUSE_MATRIX) && (issame || sametype)) return(0);
3803: if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
3804: (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);
3805: } else {
3806: PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL;
3807: const char *prefix[3] = {"seq","mpi",""};
3808: PetscInt i;
3809: /*
3810: Order of precedence:
3811: 1) See if a specialized converter is known to the current matrix.
3812: 2) See if a specialized converter is known to the desired matrix class.
3813: 3) See if a good general converter is registered for the desired class
3814: (as of 6/27/03 only MATMPIADJ falls into this category).
3815: 4) See if a good general converter is known for the current matrix.
3816: 5) Use a really basic converter.
3817: */
3819: /* 1) See if a specialized converter is known to the current matrix and the desired class */
3820: for (i=0; i<3; i++) {
3821: PetscStrcpy(convname,"MatConvert_");
3822: PetscStrcat(convname,((PetscObject)mat)->type_name);
3823: PetscStrcat(convname,"_");
3824: PetscStrcat(convname,prefix[i]);
3825: PetscStrcat(convname,issame ? ((PetscObject)mat)->type_name : newtype);
3826: PetscStrcat(convname,"_C");
3827: PetscObjectQueryFunction((PetscObject)mat,convname,&conv);
3828: if (conv) goto foundconv;
3829: }
3831: /* 2) See if a specialized converter is known to the desired matrix class. */
3832: MatCreate(PetscObjectComm((PetscObject)mat),&B);
3833: MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);
3834: MatSetType(B,newtype);
3835: for (i=0; i<3; i++) {
3836: PetscStrcpy(convname,"MatConvert_");
3837: PetscStrcat(convname,((PetscObject)mat)->type_name);
3838: PetscStrcat(convname,"_");
3839: PetscStrcat(convname,prefix[i]);
3840: PetscStrcat(convname,newtype);
3841: PetscStrcat(convname,"_C");
3842: PetscObjectQueryFunction((PetscObject)B,convname,&conv);
3843: if (conv) {
3844: MatDestroy(&B);
3845: goto foundconv;
3846: }
3847: }
3849: /* 3) See if a good general converter is registered for the desired class */
3850: conv = B->ops->convertfrom;
3851: MatDestroy(&B);
3852: if (conv) goto foundconv;
3854: /* 4) See if a good general converter is known for the current matrix */
3855: if (mat->ops->convert) {
3856: conv = mat->ops->convert;
3857: }
3858: if (conv) goto foundconv;
3860: /* 5) Use a really basic converter. */
3861: conv = MatConvert_Basic;
3863: foundconv:
3864: PetscLogEventBegin(MAT_Convert,mat,0,0,0);
3865: (*conv)(mat,newtype,reuse,M);
3866: PetscLogEventEnd(MAT_Convert,mat,0,0,0);
3867: }
3868: PetscObjectStateIncrease((PetscObject)*M);
3870: /* Copy Mat options */
3871: if (mat->symmetric) {MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);}
3872: if (mat->hermitian) {MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);}
3873: return(0);
3874: }
3878: /*@C
3879: MatFactorGetSolverPackage - Returns name of the package providing the factorization routines
3881: Not Collective
3883: Input Parameter:
3884: . mat - the matrix, must be a factored matrix
3886: Output Parameter:
3887: . type - the string name of the package (do not free this string)
3889: Notes:
3890: In Fortran you pass in a empty string and the package name will be copied into it.
3891: (Make sure the string is long enough)
3893: Level: intermediate
3895: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
3896: @*/
3897: PetscErrorCode MatFactorGetSolverPackage(Mat mat, const MatSolverPackage *type)
3898: {
3899: PetscErrorCode ierr, (*conv)(Mat,const MatSolverPackage*);
3904: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
3905: PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverPackage_C",&conv);
3906: if (!conv) {
3907: *type = MATSOLVERPETSC;
3908: } else {
3909: (*conv)(mat,type);
3910: }
3911: return(0);
3912: }
3916: /*@C
3917: MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic()
3919: Collective on Mat
3921: Input Parameters:
3922: + mat - the matrix
3923: . type - name of solver type, for example, superlu, petsc (to use PETSc's default)
3924: - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
3926: Output Parameters:
3927: . f - the factor matrix used with MatXXFactorSymbolic() calls
3929: Notes:
3930: Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
3931: such as pastix, superlu, mumps etc.
3933: PETSc must have been ./configure to use the external solver, using the option --download-package
3935: Level: intermediate
3937: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
3938: @*/
3939: PetscErrorCode MatGetFactor(Mat mat, const MatSolverPackage type,MatFactorType ftype,Mat *f)
3940: {
3941: PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
3942: char convname[256];
3948: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3949: MatCheckPreallocated(mat,1);
3951: PetscStrcpy(convname,"MatGetFactor_");
3952: PetscStrcat(convname,type);
3953: PetscStrcat(convname,"_C");
3954: PetscObjectQueryFunction((PetscObject)mat,convname,&conv);
3955: if (!conv) {
3956: PetscBool flag;
3957: MPI_Comm comm;
3959: PetscObjectGetComm((PetscObject)mat,&comm);
3960: PetscStrcasecmp(MATSOLVERPETSC,type,&flag);
3961: if (flag) SETERRQ2(comm,PETSC_ERR_SUP,"Matrix format %s does not have a built-in PETSc %s",((PetscObject)mat)->type_name,MatFactorTypes[ftype]);
3962: else SETERRQ4(comm,PETSC_ERR_SUP,"Matrix format %s does not have a solver package %s for %s. Perhaps you must ./configure with --download-%s",((PetscObject)mat)->type_name,type,MatFactorTypes[ftype],type);
3963: }
3964: (*conv)(mat,ftype,f);
3965: return(0);
3966: }
3970: /*@C
3971: MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type
3973: Not Collective
3975: Input Parameters:
3976: + mat - the matrix
3977: . type - name of solver type, for example, superlu, petsc (to use PETSc's default)
3978: - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
3980: Output Parameter:
3981: . flg - PETSC_TRUE if the factorization is available
3983: Notes:
3984: Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
3985: such as pastix, superlu, mumps etc.
3987: PETSc must have been ./configure to use the external solver, using the option --download-package
3989: Level: intermediate
3991: .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
3992: @*/
3993: PetscErrorCode MatGetFactorAvailable(Mat mat, const MatSolverPackage type,MatFactorType ftype,PetscBool *flg)
3994: {
3995: PetscErrorCode ierr, (*conv)(Mat,MatFactorType,PetscBool*);
3996: char convname[256];
4002: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4003: MatCheckPreallocated(mat,1);
4005: PetscStrcpy(convname,"MatGetFactorAvailable_");
4006: PetscStrcat(convname,type);
4007: PetscStrcat(convname,"_C");
4008: PetscObjectQueryFunction((PetscObject)mat,convname,&conv);
4009: if (!conv) {
4010: *flg = PETSC_FALSE;
4011: } else {
4012: (*conv)(mat,ftype,flg);
4013: }
4014: return(0);
4015: }
4020: /*@
4021: MatDuplicate - Duplicates a matrix including the non-zero structure.
4023: Collective on Mat
4025: Input Parameters:
4026: + mat - the matrix
4027: - op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy the numerical values in the matrix
4028: MAT_SHARE_NONZERO_PATTERN to share the nonzero patterns with the previous matrix and not copy them.
4030: Output Parameter:
4031: . M - pointer to place new matrix
4033: Level: intermediate
4035: Concepts: matrices^duplicating
4037: Notes: You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN.
4039: .seealso: MatCopy(), MatConvert()
4040: @*/
4041: PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4042: {
4044: Mat B;
4045: PetscInt i;
4051: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4052: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4053: MatCheckPreallocated(mat,1);
4055: *M = 0;
4056: if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type");
4057: PetscLogEventBegin(MAT_Convert,mat,0,0,0);
4058: (*mat->ops->duplicate)(mat,op,M);
4059: B = *M;
4061: B->stencil.dim = mat->stencil.dim;
4062: B->stencil.noc = mat->stencil.noc;
4063: for (i=0; i<=mat->stencil.dim; i++) {
4064: B->stencil.dims[i] = mat->stencil.dims[i];
4065: B->stencil.starts[i] = mat->stencil.starts[i];
4066: }
4068: B->nooffproczerorows = mat->nooffproczerorows;
4069: B->nooffprocentries = mat->nooffprocentries;
4071: PetscLogEventEnd(MAT_Convert,mat,0,0,0);
4072: PetscObjectStateIncrease((PetscObject)B);
4073: return(0);
4074: }
4078: /*@
4079: MatGetDiagonal - Gets the diagonal of a matrix.
4081: Logically Collective on Mat and Vec
4083: Input Parameters:
4084: + mat - the matrix
4085: - v - the vector for storing the diagonal
4087: Output Parameter:
4088: . v - the diagonal of the matrix
4090: Level: intermediate
4092: Note:
4093: Currently only correct in parallel for square matrices.
4095: Concepts: matrices^accessing diagonals
4097: .seealso: MatGetRow(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs()
4098: @*/
4099: PetscErrorCode MatGetDiagonal(Mat mat,Vec v)
4100: {
4107: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4108: if (!mat->ops->getdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4109: MatCheckPreallocated(mat,1);
4111: (*mat->ops->getdiagonal)(mat,v);
4112: PetscObjectStateIncrease((PetscObject)v);
4113: return(0);
4114: }
4118: /*@
4119: MatGetRowMin - Gets the minimum value (of the real part) of each
4120: row of the matrix
4122: Logically Collective on Mat and Vec
4124: Input Parameters:
4125: . mat - the matrix
4127: Output Parameter:
4128: + v - the vector for storing the maximums
4129: - idx - the indices of the column found for each row (optional)
4131: Level: intermediate
4133: Notes: The result of this call are the same as if one converted the matrix to dense format
4134: and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4136: This code is only implemented for a couple of matrix formats.
4138: Concepts: matrices^getting row maximums
4140: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(),
4141: MatGetRowMax()
4142: @*/
4143: PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4144: {
4151: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4152: if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4153: MatCheckPreallocated(mat,1);
4155: (*mat->ops->getrowmin)(mat,v,idx);
4156: PetscObjectStateIncrease((PetscObject)v);
4157: return(0);
4158: }
4162: /*@
4163: MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4164: row of the matrix
4166: Logically Collective on Mat and Vec
4168: Input Parameters:
4169: . mat - the matrix
4171: Output Parameter:
4172: + v - the vector for storing the minimums
4173: - idx - the indices of the column found for each row (or NULL if not needed)
4175: Level: intermediate
4177: Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
4178: row is 0 (the first column).
4180: This code is only implemented for a couple of matrix formats.
4182: Concepts: matrices^getting row maximums
4184: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4185: @*/
4186: PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4187: {
4194: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4195: if (!mat->ops->getrowminabs) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4196: MatCheckPreallocated(mat,1);
4197: if (idx) {PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));}
4199: (*mat->ops->getrowminabs)(mat,v,idx);
4200: PetscObjectStateIncrease((PetscObject)v);
4201: return(0);
4202: }
4206: /*@
4207: MatGetRowMax - Gets the maximum value (of the real part) of each
4208: row of the matrix
4210: Logically Collective on Mat and Vec
4212: Input Parameters:
4213: . mat - the matrix
4215: Output Parameter:
4216: + v - the vector for storing the maximums
4217: - idx - the indices of the column found for each row (optional)
4219: Level: intermediate
4221: Notes: The result of this call are the same as if one converted the matrix to dense format
4222: and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4224: This code is only implemented for a couple of matrix formats.
4226: Concepts: matrices^getting row maximums
4228: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4229: @*/
4230: PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4231: {
4238: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4239: if (!mat->ops->getrowmax) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4240: MatCheckPreallocated(mat,1);
4242: (*mat->ops->getrowmax)(mat,v,idx);
4243: PetscObjectStateIncrease((PetscObject)v);
4244: return(0);
4245: }
4249: /*@
4250: MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4251: row of the matrix
4253: Logically Collective on Mat and Vec
4255: Input Parameters:
4256: . mat - the matrix
4258: Output Parameter:
4259: + v - the vector for storing the maximums
4260: - idx - the indices of the column found for each row (or NULL if not needed)
4262: Level: intermediate
4264: Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
4265: row is 0 (the first column).
4267: This code is only implemented for a couple of matrix formats.
4269: Concepts: matrices^getting row maximums
4271: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4272: @*/
4273: PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4274: {
4281: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4282: if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4283: MatCheckPreallocated(mat,1);
4284: if (idx) {PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));}
4286: (*mat->ops->getrowmaxabs)(mat,v,idx);
4287: PetscObjectStateIncrease((PetscObject)v);
4288: return(0);
4289: }
4293: /*@
4294: MatGetRowSum - Gets the sum of each row of the matrix
4296: Logically Collective on Mat and Vec
4298: Input Parameters:
4299: . mat - the matrix
4301: Output Parameter:
4302: . v - the vector for storing the sum of rows
4304: Level: intermediate
4306: Notes: This code is slow since it is not currently specialized for different formats
4308: Concepts: matrices^getting row sums
4310: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4311: @*/
4312: PetscErrorCode MatGetRowSum(Mat mat, Vec v)
4313: {
4314: PetscInt start = 0, end = 0, row;
4315: PetscScalar *array;
4322: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4323: MatCheckPreallocated(mat,1);
4324: MatGetOwnershipRange(mat, &start, &end);
4325: VecGetArray(v, &array);
4326: for (row = start; row < end; ++row) {
4327: PetscInt ncols, col;
4328: const PetscInt *cols;
4329: const PetscScalar *vals;
4331: array[row - start] = 0.0;
4333: MatGetRow(mat, row, &ncols, &cols, &vals);
4334: for (col = 0; col < ncols; col++) {
4335: array[row - start] += vals[col];
4336: }
4337: MatRestoreRow(mat, row, &ncols, &cols, &vals);
4338: }
4339: VecRestoreArray(v, &array);
4340: PetscObjectStateIncrease((PetscObject) v);
4341: return(0);
4342: }
4346: /*@
4347: MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
4349: Collective on Mat
4351: Input Parameter:
4352: + mat - the matrix to transpose
4353: - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
4355: Output Parameters:
4356: . B - the transpose
4358: Notes:
4359: If you pass in &mat for B the transpose will be done in place, for example MatTranspose(mat,MAT_REUSE_MATRIX,&mat);
4361: Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed.
4363: Level: intermediate
4365: Concepts: matrices^transposing
4367: .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4368: @*/
4369: PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4370: {
4376: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4377: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4378: if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4379: MatCheckPreallocated(mat,1);
4381: PetscLogEventBegin(MAT_Transpose,mat,0,0,0);
4382: (*mat->ops->transpose)(mat,reuse,B);
4383: PetscLogEventEnd(MAT_Transpose,mat,0,0,0);
4384: if (B) {PetscObjectStateIncrease((PetscObject)*B);}
4385: return(0);
4386: }
4390: /*@
4391: MatIsTranspose - Test whether a matrix is another one's transpose,
4392: or its own, in which case it tests symmetry.
4394: Collective on Mat
4396: Input Parameter:
4397: + A - the matrix to test
4398: - B - the matrix to test against, this can equal the first parameter
4400: Output Parameters:
4401: . flg - the result
4403: Notes:
4404: Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4405: has a running time of the order of the number of nonzeros; the parallel
4406: test involves parallel copies of the block-offdiagonal parts of the matrix.
4408: Level: intermediate
4410: Concepts: matrices^transposing, matrix^symmetry
4412: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4413: @*/
4414: PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg)
4415: {
4416: PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4422: PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);
4423: PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);
4424: *flg = PETSC_FALSE;
4425: if (f && g) {
4426: if (f == g) {
4427: (*f)(A,B,tol,flg);
4428: } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4429: } else {
4430: MatType mattype;
4431: if (!f) {
4432: MatGetType(A,&mattype);
4433: } else {
4434: MatGetType(B,&mattype);
4435: }
4436: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
4437: }
4438: return(0);
4439: }
4443: /*@
4444: MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate.
4446: Collective on Mat
4448: Input Parameter:
4449: + mat - the matrix to transpose and complex conjugate
4450: - reuse - store the transpose matrix in the provided B
4452: Output Parameters:
4453: . B - the Hermitian
4455: Notes:
4456: If you pass in &mat for B the Hermitian will be done in place
4458: Level: intermediate
4460: Concepts: matrices^transposing, complex conjugatex
4462: .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4463: @*/
4464: PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
4465: {
4469: MatTranspose(mat,reuse,B);
4470: #if defined(PETSC_USE_COMPLEX)
4471: MatConjugate(*B);
4472: #endif
4473: return(0);
4474: }
4478: /*@
4479: MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,
4481: Collective on Mat
4483: Input Parameter:
4484: + A - the matrix to test
4485: - B - the matrix to test against, this can equal the first parameter
4487: Output Parameters:
4488: . flg - the result
4490: Notes:
4491: Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4492: has a running time of the order of the number of nonzeros; the parallel
4493: test involves parallel copies of the block-offdiagonal parts of the matrix.
4495: Level: intermediate
4497: Concepts: matrices^transposing, matrix^symmetry
4499: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
4500: @*/
4501: PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg)
4502: {
4503: PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4509: PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);
4510: PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);
4511: if (f && g) {
4512: if (f==g) {
4513: (*f)(A,B,tol,flg);
4514: } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
4515: }
4516: return(0);
4517: }
4521: /*@
4522: MatPermute - Creates a new matrix with rows and columns permuted from the
4523: original.
4525: Collective on Mat
4527: Input Parameters:
4528: + mat - the matrix to permute
4529: . row - row permutation, each processor supplies only the permutation for its rows
4530: - col - column permutation, each processor supplies only the permutation for its columns
4532: Output Parameters:
4533: . B - the permuted matrix
4535: Level: advanced
4537: Note:
4538: The index sets map from row/col of permuted matrix to row/col of original matrix.
4539: The index sets should be on the same communicator as Mat and have the same local sizes.
4541: Concepts: matrices^permuting
4543: .seealso: MatGetOrdering(), ISAllGather()
4545: @*/
4546: PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
4547: {
4556: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4557: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4558: if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
4559: MatCheckPreallocated(mat,1);
4561: (*mat->ops->permute)(mat,row,col,B);
4562: PetscObjectStateIncrease((PetscObject)*B);
4563: return(0);
4564: }
4568: /*@
4569: MatEqual - Compares two matrices.
4571: Collective on Mat
4573: Input Parameters:
4574: + A - the first matrix
4575: - B - the second matrix
4577: Output Parameter:
4578: . flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
4580: Level: intermediate
4582: Concepts: matrices^equality between
4583: @*/
4584: PetscErrorCode MatEqual(Mat A,Mat B,PetscBool *flg)
4585: {
4595: MatCheckPreallocated(B,2);
4596: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4597: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4598: if (A->rmap->N != B->rmap->N || A->cmap->N != B->cmap->N) SETERRQ4(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %D %D %D %D",A->rmap->N,B->rmap->N,A->cmap->N,B->cmap->N);
4599: if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4600: if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4601: if (A->ops->equal != B->ops->equal) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"A is type: %s\nB is type: %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
4602: MatCheckPreallocated(A,1);
4604: (*A->ops->equal)(A,B,flg);
4605: return(0);
4606: }
4610: /*@
4611: MatDiagonalScale - Scales a matrix on the left and right by diagonal
4612: matrices that are stored as vectors. Either of the two scaling
4613: matrices can be NULL.
4615: Collective on Mat
4617: Input Parameters:
4618: + mat - the matrix to be scaled
4619: . l - the left scaling vector (or NULL)
4620: - r - the right scaling vector (or NULL)
4622: Notes:
4623: MatDiagonalScale() computes A = LAR, where
4624: L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
4625: The L scales the rows of the matrix, the R scales the columns of the matrix.
4627: Level: intermediate
4629: Concepts: matrices^diagonal scaling
4630: Concepts: diagonal scaling of matrices
4632: .seealso: MatScale()
4633: @*/
4634: PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
4635: {
4641: if (!mat->ops->diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4644: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4645: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4646: MatCheckPreallocated(mat,1);
4648: PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4649: (*mat->ops->diagonalscale)(mat,l,r);
4650: PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4651: PetscObjectStateIncrease((PetscObject)mat);
4652: #if defined(PETSC_HAVE_CUSP)
4653: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4654: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4655: }
4656: #endif
4657: #if defined(PETSC_HAVE_VIENNACL)
4658: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
4659: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
4660: }
4661: #endif
4662: return(0);
4663: }
4667: /*@
4668: MatScale - Scales all elements of a matrix by a given number.
4670: Logically Collective on Mat
4672: Input Parameters:
4673: + mat - the matrix to be scaled
4674: - a - the scaling value
4676: Output Parameter:
4677: . mat - the scaled matrix
4679: Level: intermediate
4681: Concepts: matrices^scaling all entries
4683: .seealso: MatDiagonalScale()
4684: @*/
4685: PetscErrorCode MatScale(Mat mat,PetscScalar a)
4686: {
4692: if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4693: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4694: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4696: MatCheckPreallocated(mat,1);
4698: PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4699: if (a != (PetscScalar)1.0) {
4700: (*mat->ops->scale)(mat,a);
4701: PetscObjectStateIncrease((PetscObject)mat);
4702: }
4703: PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4704: #if defined(PETSC_HAVE_CUSP)
4705: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4706: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4707: }
4708: #endif
4709: #if defined(PETSC_HAVE_VIENNACL)
4710: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
4711: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
4712: }
4713: #endif
4714: return(0);
4715: }
4719: /*@
4720: MatNorm - Calculates various norms of a matrix.
4722: Collective on Mat
4724: Input Parameters:
4725: + mat - the matrix
4726: - type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
4728: Output Parameters:
4729: . nrm - the resulting norm
4731: Level: intermediate
4733: Concepts: matrices^norm
4734: Concepts: norm^of matrix
4735: @*/
4736: PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
4737: {
4745: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4746: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4747: if (!mat->ops->norm) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4748: MatCheckPreallocated(mat,1);
4750: (*mat->ops->norm)(mat,type,nrm);
4751: return(0);
4752: }
4754: /*
4755: This variable is used to prevent counting of MatAssemblyBegin() that
4756: are called from within a MatAssemblyEnd().
4757: */
4758: static PetscInt MatAssemblyEnd_InUse = 0;
4761: /*@
4762: MatAssemblyBegin - Begins assembling the matrix. This routine should
4763: be called after completing all calls to MatSetValues().
4765: Collective on Mat
4767: Input Parameters:
4768: + mat - the matrix
4769: - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
4771: Notes:
4772: MatSetValues() generally caches the values. The matrix is ready to
4773: use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4774: Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4775: in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4776: using the matrix.
4778: ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the
4779: same flag of MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY for all processes. Thus you CANNOT locally change from ADD_VALUES to INSERT_VALUES, that is
4780: a global collective operation requring all processes that share the matrix.
4782: Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
4783: out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
4784: before MAT_FINAL_ASSEMBLY so the space is not compressed out.
4786: Level: beginner
4788: Concepts: matrices^assembling
4790: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
4791: @*/
4792: PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
4793: {
4799: MatCheckPreallocated(mat,1);
4800: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
4801: if (mat->assembled) {
4802: mat->was_assembled = PETSC_TRUE;
4803: mat->assembled = PETSC_FALSE;
4804: }
4805: if (!MatAssemblyEnd_InUse) {
4806: PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);
4807: if (mat->ops->assemblybegin) {(*mat->ops->assemblybegin)(mat,type);}
4808: PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);
4809: } else if (mat->ops->assemblybegin) {
4810: (*mat->ops->assemblybegin)(mat,type);
4811: }
4812: return(0);
4813: }
4817: /*@
4818: MatAssembled - Indicates if a matrix has been assembled and is ready for
4819: use; for example, in matrix-vector product.
4821: Not Collective
4823: Input Parameter:
4824: . mat - the matrix
4826: Output Parameter:
4827: . assembled - PETSC_TRUE or PETSC_FALSE
4829: Level: advanced
4831: Concepts: matrices^assembled?
4833: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
4834: @*/
4835: PetscErrorCode MatAssembled(Mat mat,PetscBool *assembled)
4836: {
4841: *assembled = mat->assembled;
4842: return(0);
4843: }
4847: /*@
4848: MatAssemblyEnd - Completes assembling the matrix. This routine should
4849: be called after MatAssemblyBegin().
4851: Collective on Mat
4853: Input Parameters:
4854: + mat - the matrix
4855: - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
4857: Options Database Keys:
4858: + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
4859: . -mat_view ::ascii_info_detail - Prints more detailed info
4860: . -mat_view - Prints matrix in ASCII format
4861: . -mat_view ::ascii_matlab - Prints matrix in Matlab format
4862: . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
4863: . -display <name> - Sets display name (default is host)
4864: . -draw_pause <sec> - Sets number of seconds to pause after display
4865: . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: Chapter 10 Using MATLAB with PETSc )
4866: . -viewer_socket_machine <machine>
4867: . -viewer_socket_port <port>
4868: . -mat_view binary - save matrix to file in binary format
4869: - -viewer_binary_filename <name>
4871: Notes:
4872: MatSetValues() generally caches the values. The matrix is ready to
4873: use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4874: Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4875: in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4876: using the matrix.
4878: Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
4879: out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
4880: before MAT_FINAL_ASSEMBLY so the space is not compressed out.
4882: Level: beginner
4884: .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
4885: @*/
4886: PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
4887: {
4888: PetscErrorCode ierr;
4889: static PetscInt inassm = 0;
4890: PetscBool flg = PETSC_FALSE;
4896: inassm++;
4897: MatAssemblyEnd_InUse++;
4898: if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
4899: PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);
4900: if (mat->ops->assemblyend) {
4901: (*mat->ops->assemblyend)(mat,type);
4902: }
4903: PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);
4904: } else if (mat->ops->assemblyend) {
4905: (*mat->ops->assemblyend)(mat,type);
4906: }
4908: /* Flush assembly is not a true assembly */
4909: if (type != MAT_FLUSH_ASSEMBLY) {
4910: mat->assembled = PETSC_TRUE; mat->num_ass++;
4911: }
4912: mat->insertmode = NOT_SET_VALUES;
4913: MatAssemblyEnd_InUse--;
4914: PetscObjectStateIncrease((PetscObject)mat);
4915: if (!mat->symmetric_eternal) {
4916: mat->symmetric_set = PETSC_FALSE;
4917: mat->hermitian_set = PETSC_FALSE;
4918: mat->structurally_symmetric_set = PETSC_FALSE;
4919: }
4920: #if defined(PETSC_HAVE_CUSP)
4921: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4922: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4923: }
4924: #endif
4925: #if defined(PETSC_HAVE_VIENNACL)
4926: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
4927: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
4928: }
4929: #endif
4930: if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
4931: MatViewFromOptions(mat,NULL,"-mat_view");
4933: if (mat->checksymmetryonassembly) {
4934: MatIsSymmetric(mat,mat->checksymmetrytol,&flg);
4935: if (flg) {
4936: PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);
4937: } else {
4938: PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);
4939: }
4940: }
4941: if (mat->nullsp && mat->checknullspaceonassembly) {
4942: MatNullSpaceTest(mat->nullsp,mat,NULL);
4943: }
4944: }
4945: inassm--;
4946: return(0);
4947: }
4951: /*@
4952: MatSetOption - Sets a parameter option for a matrix. Some options
4953: may be specific to certain storage formats. Some options
4954: determine how values will be inserted (or added). Sorted,
4955: row-oriented input will generally assemble the fastest. The default
4956: is row-oriented.
4958: Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
4960: Input Parameters:
4961: + mat - the matrix
4962: . option - the option, one of those listed below (and possibly others),
4963: - flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
4965: Options Describing Matrix Structure:
4966: + MAT_SPD - symmetric positive definite
4967: - MAT_SYMMETRIC - symmetric in terms of both structure and value
4968: . MAT_HERMITIAN - transpose is the complex conjugation
4969: . MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
4970: - MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
4971: you set to be kept with all future use of the matrix
4972: including after MatAssemblyBegin/End() which could
4973: potentially change the symmetry structure, i.e. you
4974: KNOW the matrix will ALWAYS have the property you set.
4977: Options For Use with MatSetValues():
4978: Insert a logically dense subblock, which can be
4979: . MAT_ROW_ORIENTED - row-oriented (default)
4981: Note these options reflect the data you pass in with MatSetValues(); it has
4982: nothing to do with how the data is stored internally in the matrix
4983: data structure.
4985: When (re)assembling a matrix, we can restrict the input for
4986: efficiency/debugging purposes. These options include:
4987: + MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow)
4988: . MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
4989: . MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
4990: . MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
4991: . MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
4992: + MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
4993: any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
4994: performance for very large process counts.
4996: Notes:
4997: Some options are relevant only for particular matrix types and
4998: are thus ignored by others. Other options are not supported by
4999: certain matrix types and will generate an error message if set.
5001: If using a Fortran 77 module to compute a matrix, one may need to
5002: use the column-oriented option (or convert to the row-oriented
5003: format).
5005: MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
5006: that would generate a new entry in the nonzero structure is instead
5007: ignored. Thus, if memory has not alredy been allocated for this particular
5008: data, then the insertion is ignored. For dense matrices, in which
5009: the entire array is allocated, no entries are ever ignored.
5010: Set after the first MatAssemblyEnd()
5012: MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5013: that would generate a new entry in the nonzero structure instead produces
5014: an error. (Currently supported for AIJ and BAIJ formats only.)
5016: MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5017: that would generate a new entry that has not been preallocated will
5018: instead produce an error. (Currently supported for AIJ and BAIJ formats
5019: only.) This is a useful flag when debugging matrix memory preallocation.
5021: MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for
5022: other processors should be dropped, rather than stashed.
5023: This is useful if you know that the "owning" processor is also
5024: always generating the correct matrix entries, so that PETSc need
5025: not transfer duplicate entries generated on another processor.
5027: MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5028: searches during matrix assembly. When this flag is set, the hash table
5029: is created during the first Matrix Assembly. This hash table is
5030: used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5031: to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5032: should be used with MAT_USE_HASH_TABLE flag. This option is currently
5033: supported by MATMPIBAIJ format only.
5035: MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries
5036: are kept in the nonzero structure
5038: MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
5039: a zero location in the matrix
5041: MAT_USE_INODES - indicates using inode version of the code - works with AIJ and
5042: ROWBS matrix types
5044: MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the
5045: zero row routines and thus improves performance for very large process counts.
5047: MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular
5048: part of the matrix (since they should match the upper triangular part).
5050: Notes: Can only be called after MatSetSizes() and MatSetType() have been set.
5052: Level: intermediate
5054: Concepts: matrices^setting options
5056: .seealso: MatOption, Mat
5058: @*/
5059: PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg)
5060: {
5066: if (op > 0) {
5069: }
5071: if (((int) op) <= MAT_OPTION_MIN || ((int) op) >= MAT_OPTION_MAX) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Options %d is out of range",(int)op);
5072: if (!((PetscObject)mat)->type_name) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_TYPENOTSET,"Cannot set options until type and size have been set, see MatSetType() and MatSetSizes()");
5074: switch (op) {
5075: case MAT_NO_OFF_PROC_ENTRIES:
5076: mat->nooffprocentries = flg;
5077: return(0);
5078: break;
5079: case MAT_NO_OFF_PROC_ZERO_ROWS:
5080: mat->nooffproczerorows = flg;
5081: return(0);
5082: break;
5083: case MAT_SPD:
5084: mat->spd_set = PETSC_TRUE;
5085: mat->spd = flg;
5086: if (flg) {
5087: mat->symmetric = PETSC_TRUE;
5088: mat->structurally_symmetric = PETSC_TRUE;
5089: mat->symmetric_set = PETSC_TRUE;
5090: mat->structurally_symmetric_set = PETSC_TRUE;
5091: }
5092: break;
5093: case MAT_SYMMETRIC:
5094: mat->symmetric = flg;
5095: if (flg) mat->structurally_symmetric = PETSC_TRUE;
5096: mat->symmetric_set = PETSC_TRUE;
5097: mat->structurally_symmetric_set = flg;
5098: break;
5099: case MAT_HERMITIAN:
5100: mat->hermitian = flg;
5101: if (flg) mat->structurally_symmetric = PETSC_TRUE;
5102: mat->hermitian_set = PETSC_TRUE;
5103: mat->structurally_symmetric_set = flg;
5104: break;
5105: case MAT_STRUCTURALLY_SYMMETRIC:
5106: mat->structurally_symmetric = flg;
5107: mat->structurally_symmetric_set = PETSC_TRUE;
5108: break;
5109: case MAT_SYMMETRY_ETERNAL:
5110: mat->symmetric_eternal = flg;
5111: break;
5112: default:
5113: break;
5114: }
5115: if (mat->ops->setoption) {
5116: (*mat->ops->setoption)(mat,op,flg);
5117: }
5118: return(0);
5119: }
5123: /*@
5124: MatZeroEntries - Zeros all entries of a matrix. For sparse matrices
5125: this routine retains the old nonzero structure.
5127: Logically Collective on Mat
5129: Input Parameters:
5130: . mat - the matrix
5132: Level: intermediate
5134: Notes: If the matrix was not preallocated then a default, likely poor preallocation will be set in the matrix, so this should be called after the preallocation phase.
5135: See the Performance chapter of the users manual for information on preallocating matrices.
5137: Concepts: matrices^zeroing
5139: .seealso: MatZeroRows()
5140: @*/
5141: PetscErrorCode MatZeroEntries(Mat mat)
5142: {
5148: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5149: 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");
5150: if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5151: MatCheckPreallocated(mat,1);
5153: PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);
5154: (*mat->ops->zeroentries)(mat);
5155: PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);
5156: PetscObjectStateIncrease((PetscObject)mat);
5157: #if defined(PETSC_HAVE_CUSP)
5158: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5159: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5160: }
5161: #endif
5162: #if defined(PETSC_HAVE_VIENNACL)
5163: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5164: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5165: }
5166: #endif
5167: return(0);
5168: }
5172: /*@C
5173: MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal)
5174: of a set of rows and columns of a matrix.
5176: Collective on Mat
5178: Input Parameters:
5179: + mat - the matrix
5180: . numRows - the number of rows to remove
5181: . rows - the global row indices
5182: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5183: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5184: - b - optional vector of right hand side, that will be adjusted by provided solution
5186: Notes:
5187: This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5189: The user can set a value in the diagonal entry (or for the AIJ and
5190: row formats can optionally remove the main diagonal entry from the
5191: nonzero structure as well, by passing 0.0 as the final argument).
5193: For the parallel case, all processes that share the matrix (i.e.,
5194: those in the communicator used for matrix creation) MUST call this
5195: routine, regardless of whether any rows being zeroed are owned by
5196: them.
5198: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5199: list only rows local to itself).
5201: The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5203: Level: intermediate
5205: Concepts: matrices^zeroing rows
5207: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumnsIS()
5208: @*/
5209: PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5210: {
5217: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5218: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5219: if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5220: MatCheckPreallocated(mat,1);
5222: (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);
5223: MatViewFromOptions(mat,NULL,"-mat_view");
5224: PetscObjectStateIncrease((PetscObject)mat);
5225: #if defined(PETSC_HAVE_CUSP)
5226: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5227: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5228: }
5229: #endif
5230: #if defined(PETSC_HAVE_VIENNACL)
5231: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5232: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5233: }
5234: #endif
5235: return(0);
5236: }
5240: /*@C
5241: MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
5242: of a set of rows and columns of a matrix.
5244: Collective on Mat
5246: Input Parameters:
5247: + mat - the matrix
5248: . is - the rows to zero
5249: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5250: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5251: - b - optional vector of right hand side, that will be adjusted by provided solution
5253: Notes:
5254: This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5256: The user can set a value in the diagonal entry (or for the AIJ and
5257: row formats can optionally remove the main diagonal entry from the
5258: nonzero structure as well, by passing 0.0 as the final argument).
5260: For the parallel case, all processes that share the matrix (i.e.,
5261: those in the communicator used for matrix creation) MUST call this
5262: routine, regardless of whether any rows being zeroed are owned by
5263: them.
5265: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5266: list only rows local to itself).
5268: The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5270: Level: intermediate
5272: Concepts: matrices^zeroing rows
5274: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumns()
5275: @*/
5276: PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5277: {
5279: PetscInt numRows;
5280: const PetscInt *rows;
5287: ISGetLocalSize(is,&numRows);
5288: ISGetIndices(is,&rows);
5289: MatZeroRowsColumns(mat,numRows,rows,diag,x,b);
5290: ISRestoreIndices(is,&rows);
5291: return(0);
5292: }
5296: /*@C
5297: MatZeroRows - Zeros all entries (except possibly the main diagonal)
5298: of a set of rows of a matrix.
5300: Collective on Mat
5302: Input Parameters:
5303: + mat - the matrix
5304: . numRows - the number of rows to remove
5305: . rows - the global row indices
5306: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5307: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5308: - b - optional vector of right hand side, that will be adjusted by provided solution
5310: Notes:
5311: For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5312: but does not release memory. For the dense and block diagonal
5313: formats this does not alter the nonzero structure.
5315: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5316: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5317: merely zeroed.
5319: The user can set a value in the diagonal entry (or for the AIJ and
5320: row formats can optionally remove the main diagonal entry from the
5321: nonzero structure as well, by passing 0.0 as the final argument).
5323: For the parallel case, all processes that share the matrix (i.e.,
5324: those in the communicator used for matrix creation) MUST call this
5325: routine, regardless of whether any rows being zeroed are owned by
5326: them.
5328: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5329: list only rows local to itself).
5331: You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5332: owns that are to be zeroed. This saves a global synchronization in the implementation.
5334: Level: intermediate
5336: Concepts: matrices^zeroing rows
5338: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5339: @*/
5340: PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5341: {
5348: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5349: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5350: if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5351: MatCheckPreallocated(mat,1);
5353: (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);
5354: MatViewFromOptions(mat,NULL,"-mat_view");
5355: PetscObjectStateIncrease((PetscObject)mat);
5356: #if defined(PETSC_HAVE_CUSP)
5357: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5358: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5359: }
5360: #endif
5361: #if defined(PETSC_HAVE_VIENNACL)
5362: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5363: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5364: }
5365: #endif
5366: return(0);
5367: }
5371: /*@C
5372: MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5373: of a set of rows of a matrix.
5375: Collective on Mat
5377: Input Parameters:
5378: + mat - the matrix
5379: . is - index set of rows to remove
5380: . diag - value put in all diagonals of eliminated rows
5381: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5382: - b - optional vector of right hand side, that will be adjusted by provided solution
5384: Notes:
5385: For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5386: but does not release memory. For the dense and block diagonal
5387: formats this does not alter the nonzero structure.
5389: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5390: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5391: merely zeroed.
5393: The user can set a value in the diagonal entry (or for the AIJ and
5394: row formats can optionally remove the main diagonal entry from the
5395: nonzero structure as well, by passing 0.0 as the final argument).
5397: For the parallel case, all processes that share the matrix (i.e.,
5398: those in the communicator used for matrix creation) MUST call this
5399: routine, regardless of whether any rows being zeroed are owned by
5400: them.
5402: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5403: list only rows local to itself).
5405: You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5406: owns that are to be zeroed. This saves a global synchronization in the implementation.
5408: Level: intermediate
5410: Concepts: matrices^zeroing rows
5412: .seealso: MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5413: @*/
5414: PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5415: {
5416: PetscInt numRows;
5417: const PetscInt *rows;
5424: ISGetLocalSize(is,&numRows);
5425: ISGetIndices(is,&rows);
5426: MatZeroRows(mat,numRows,rows,diag,x,b);
5427: ISRestoreIndices(is,&rows);
5428: return(0);
5429: }
5433: /*@C
5434: MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
5435: of a set of rows of a matrix. These rows must be local to the process.
5437: Collective on Mat
5439: Input Parameters:
5440: + mat - the matrix
5441: . numRows - the number of rows to remove
5442: . rows - the grid coordinates (and component number when dof > 1) for matrix rows
5443: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5444: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5445: - b - optional vector of right hand side, that will be adjusted by provided solution
5447: Notes:
5448: For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5449: but does not release memory. For the dense and block diagonal
5450: formats this does not alter the nonzero structure.
5452: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5453: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5454: merely zeroed.
5456: The user can set a value in the diagonal entry (or for the AIJ and
5457: row formats can optionally remove the main diagonal entry from the
5458: nonzero structure as well, by passing 0.0 as the final argument).
5460: For the parallel case, all processes that share the matrix (i.e.,
5461: those in the communicator used for matrix creation) MUST call this
5462: routine, regardless of whether any rows being zeroed are owned by
5463: them.
5465: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5466: list only rows local to itself).
5468: The grid coordinates are across the entire grid, not just the local portion
5470: In Fortran idxm and idxn should be declared as
5471: $ MatStencil idxm(4,m)
5472: and the values inserted using
5473: $ idxm(MatStencil_i,1) = i
5474: $ idxm(MatStencil_j,1) = j
5475: $ idxm(MatStencil_k,1) = k
5476: $ idxm(MatStencil_c,1) = c
5477: etc
5479: For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5480: obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5481: etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5482: DM_BOUNDARY_PERIODIC boundary type.
5484: 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
5485: a single value per point) you can skip filling those indices.
5487: Level: intermediate
5489: Concepts: matrices^zeroing rows
5491: .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5492: @*/
5493: PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5494: {
5495: PetscInt dim = mat->stencil.dim;
5496: PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc);
5497: PetscInt *dims = mat->stencil.dims+1;
5498: PetscInt *starts = mat->stencil.starts;
5499: PetscInt *dxm = (PetscInt*) rows;
5500: PetscInt *jdxm, i, j, tmp, numNewRows = 0;
5508: PetscMalloc1(numRows, &jdxm);
5509: for (i = 0; i < numRows; ++i) {
5510: /* Skip unused dimensions (they are ordered k, j, i, c) */
5511: for (j = 0; j < 3-sdim; ++j) dxm++;
5512: /* Local index in X dir */
5513: tmp = *dxm++ - starts[0];
5514: /* Loop over remaining dimensions */
5515: for (j = 0; j < dim-1; ++j) {
5516: /* If nonlocal, set index to be negative */
5517: if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5518: /* Update local index */
5519: else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5520: }
5521: /* Skip component slot if necessary */
5522: if (mat->stencil.noc) dxm++;
5523: /* Local row number */
5524: if (tmp >= 0) {
5525: jdxm[numNewRows++] = tmp;
5526: }
5527: }
5528: MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);
5529: PetscFree(jdxm);
5530: return(0);
5531: }
5535: /*@C
5536: MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal)
5537: of a set of rows and columns of a matrix.
5539: Collective on Mat
5541: Input Parameters:
5542: + mat - the matrix
5543: . numRows - the number of rows/columns to remove
5544: . rows - the grid coordinates (and component number when dof > 1) for matrix rows
5545: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5546: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5547: - b - optional vector of right hand side, that will be adjusted by provided solution
5549: Notes:
5550: For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5551: but does not release memory. For the dense and block diagonal
5552: formats this does not alter the nonzero structure.
5554: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5555: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5556: merely zeroed.
5558: The user can set a value in the diagonal entry (or for the AIJ and
5559: row formats can optionally remove the main diagonal entry from the
5560: nonzero structure as well, by passing 0.0 as the final argument).
5562: For the parallel case, all processes that share the matrix (i.e.,
5563: those in the communicator used for matrix creation) MUST call this
5564: routine, regardless of whether any rows being zeroed are owned by
5565: them.
5567: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5568: list only rows local to itself, but the row/column numbers are given in local numbering).
5570: The grid coordinates are across the entire grid, not just the local portion
5572: In Fortran idxm and idxn should be declared as
5573: $ MatStencil idxm(4,m)
5574: and the values inserted using
5575: $ idxm(MatStencil_i,1) = i
5576: $ idxm(MatStencil_j,1) = j
5577: $ idxm(MatStencil_k,1) = k
5578: $ idxm(MatStencil_c,1) = c
5579: etc
5581: For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5582: obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5583: etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5584: DM_BOUNDARY_PERIODIC boundary type.
5586: 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
5587: a single value per point) you can skip filling those indices.
5589: Level: intermediate
5591: Concepts: matrices^zeroing rows
5593: .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5594: @*/
5595: PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5596: {
5597: PetscInt dim = mat->stencil.dim;
5598: PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc);
5599: PetscInt *dims = mat->stencil.dims+1;
5600: PetscInt *starts = mat->stencil.starts;
5601: PetscInt *dxm = (PetscInt*) rows;
5602: PetscInt *jdxm, i, j, tmp, numNewRows = 0;
5610: PetscMalloc1(numRows, &jdxm);
5611: for (i = 0; i < numRows; ++i) {
5612: /* Skip unused dimensions (they are ordered k, j, i, c) */
5613: for (j = 0; j < 3-sdim; ++j) dxm++;
5614: /* Local index in X dir */
5615: tmp = *dxm++ - starts[0];
5616: /* Loop over remaining dimensions */
5617: for (j = 0; j < dim-1; ++j) {
5618: /* If nonlocal, set index to be negative */
5619: if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5620: /* Update local index */
5621: else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5622: }
5623: /* Skip component slot if necessary */
5624: if (mat->stencil.noc) dxm++;
5625: /* Local row number */
5626: if (tmp >= 0) {
5627: jdxm[numNewRows++] = tmp;
5628: }
5629: }
5630: MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);
5631: PetscFree(jdxm);
5632: return(0);
5633: }
5637: /*@C
5638: MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
5639: of a set of rows of a matrix; using local numbering of rows.
5641: Collective on Mat
5643: Input Parameters:
5644: + mat - the matrix
5645: . numRows - the number of rows to remove
5646: . rows - the global row indices
5647: . diag - value put in all diagonals of eliminated rows
5648: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5649: - b - optional vector of right hand side, that will be adjusted by provided solution
5651: Notes:
5652: Before calling MatZeroRowsLocal(), the user must first set the
5653: local-to-global mapping by calling MatSetLocalToGlobalMapping().
5655: For the AIJ matrix formats this removes the old nonzero structure,
5656: but does not release memory. For the dense and block diagonal
5657: formats this does not alter the nonzero structure.
5659: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5660: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5661: merely zeroed.
5663: The user can set a value in the diagonal entry (or for the AIJ and
5664: row formats can optionally remove the main diagonal entry from the
5665: nonzero structure as well, by passing 0.0 as the final argument).
5667: You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5668: owns that are to be zeroed. This saves a global synchronization in the implementation.
5670: Level: intermediate
5672: Concepts: matrices^zeroing
5674: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5675: @*/
5676: PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5677: {
5684: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5685: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5686: MatCheckPreallocated(mat,1);
5688: if (mat->ops->zerorowslocal) {
5689: (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);
5690: } else {
5691: IS is, newis;
5692: const PetscInt *newRows;
5694: if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5695: ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
5696: ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);
5697: ISGetIndices(newis,&newRows);
5698: (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);
5699: ISRestoreIndices(newis,&newRows);
5700: ISDestroy(&newis);
5701: ISDestroy(&is);
5702: }
5703: PetscObjectStateIncrease((PetscObject)mat);
5704: #if defined(PETSC_HAVE_CUSP)
5705: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5706: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5707: }
5708: #endif
5709: #if defined(PETSC_HAVE_VIENNACL)
5710: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5711: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5712: }
5713: #endif
5714: return(0);
5715: }
5719: /*@C
5720: MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
5721: of a set of rows of a matrix; using local numbering of rows.
5723: Collective on Mat
5725: Input Parameters:
5726: + mat - the matrix
5727: . is - index set of rows to remove
5728: . diag - value put in all diagonals of eliminated rows
5729: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5730: - b - optional vector of right hand side, that will be adjusted by provided solution
5732: Notes:
5733: Before calling MatZeroRowsLocalIS(), the user must first set the
5734: local-to-global mapping by calling MatSetLocalToGlobalMapping().
5736: For the AIJ matrix formats this removes the old nonzero structure,
5737: but does not release memory. For the dense and block diagonal
5738: formats this does not alter the nonzero structure.
5740: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5741: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5742: merely zeroed.
5744: The user can set a value in the diagonal entry (or for the AIJ and
5745: row formats can optionally remove the main diagonal entry from the
5746: nonzero structure as well, by passing 0.0 as the final argument).
5748: You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5749: owns that are to be zeroed. This saves a global synchronization in the implementation.
5751: Level: intermediate
5753: Concepts: matrices^zeroing
5755: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5756: @*/
5757: PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5758: {
5760: PetscInt numRows;
5761: const PetscInt *rows;
5767: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5768: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5769: MatCheckPreallocated(mat,1);
5771: ISGetLocalSize(is,&numRows);
5772: ISGetIndices(is,&rows);
5773: MatZeroRowsLocal(mat,numRows,rows,diag,x,b);
5774: ISRestoreIndices(is,&rows);
5775: return(0);
5776: }
5780: /*@C
5781: MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
5782: of a set of rows and columns of a matrix; using local numbering of rows.
5784: Collective on Mat
5786: Input Parameters:
5787: + mat - the matrix
5788: . numRows - the number of rows to remove
5789: . rows - the global row indices
5790: . diag - value put in all diagonals of eliminated rows
5791: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5792: - b - optional vector of right hand side, that will be adjusted by provided solution
5794: Notes:
5795: Before calling MatZeroRowsColumnsLocal(), the user must first set the
5796: local-to-global mapping by calling MatSetLocalToGlobalMapping().
5798: The user can set a value in the diagonal entry (or for the AIJ and
5799: row formats can optionally remove the main diagonal entry from the
5800: nonzero structure as well, by passing 0.0 as the final argument).
5802: Level: intermediate
5804: Concepts: matrices^zeroing
5806: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5807: @*/
5808: PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5809: {
5811: IS is, newis;
5812: const PetscInt *newRows;
5818: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5819: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5820: MatCheckPreallocated(mat,1);
5822: if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5823: ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
5824: ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);
5825: ISGetIndices(newis,&newRows);
5826: (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);
5827: ISRestoreIndices(newis,&newRows);
5828: ISDestroy(&newis);
5829: ISDestroy(&is);
5830: PetscObjectStateIncrease((PetscObject)mat);
5831: #if defined(PETSC_HAVE_CUSP)
5832: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5833: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5834: }
5835: #endif
5836: #if defined(PETSC_HAVE_VIENNACL)
5837: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5838: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5839: }
5840: #endif
5841: return(0);
5842: }
5846: /*@C
5847: MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
5848: of a set of rows and columns of a matrix; using local numbering of rows.
5850: Collective on Mat
5852: Input Parameters:
5853: + mat - the matrix
5854: . is - index set of rows to remove
5855: . diag - value put in all diagonals of eliminated rows
5856: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5857: - b - optional vector of right hand side, that will be adjusted by provided solution
5859: Notes:
5860: Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
5861: local-to-global mapping by calling MatSetLocalToGlobalMapping().
5863: The user can set a value in the diagonal entry (or for the AIJ and
5864: row formats can optionally remove the main diagonal entry from the
5865: nonzero structure as well, by passing 0.0 as the final argument).
5867: Level: intermediate
5869: Concepts: matrices^zeroing
5871: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5872: @*/
5873: PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5874: {
5876: PetscInt numRows;
5877: const PetscInt *rows;
5883: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5884: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5885: MatCheckPreallocated(mat,1);
5887: ISGetLocalSize(is,&numRows);
5888: ISGetIndices(is,&rows);
5889: MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);
5890: ISRestoreIndices(is,&rows);
5891: return(0);
5892: }
5896: /*@
5897: MatGetSize - Returns the numbers of rows and columns in a matrix.
5899: Not Collective
5901: Input Parameter:
5902: . mat - the matrix
5904: Output Parameters:
5905: + m - the number of global rows
5906: - n - the number of global columns
5908: Note: both output parameters can be NULL on input.
5910: Level: beginner
5912: Concepts: matrices^size
5914: .seealso: MatGetLocalSize()
5915: @*/
5916: PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
5917: {
5920: if (m) *m = mat->rmap->N;
5921: if (n) *n = mat->cmap->N;
5922: return(0);
5923: }
5927: /*@
5928: MatGetLocalSize - Returns the number of rows and columns in a matrix
5929: stored locally. This information may be implementation dependent, so
5930: use with care.
5932: Not Collective
5934: Input Parameters:
5935: . mat - the matrix
5937: Output Parameters:
5938: + m - the number of local rows
5939: - n - the number of local columns
5941: Note: both output parameters can be NULL on input.
5943: Level: beginner
5945: Concepts: matrices^local size
5947: .seealso: MatGetSize()
5948: @*/
5949: PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
5950: {
5955: if (m) *m = mat->rmap->n;
5956: if (n) *n = mat->cmap->n;
5957: return(0);
5958: }
5962: /*@
5963: MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
5964: this processor. (The columns of the "diagonal block")
5966: Not Collective, unless matrix has not been allocated, then collective on Mat
5968: Input Parameters:
5969: . mat - the matrix
5971: Output Parameters:
5972: + m - the global index of the first local column
5973: - n - one more than the global index of the last local column
5975: Notes: both output parameters can be NULL on input.
5977: Level: developer
5979: Concepts: matrices^column ownership
5981: .seealso: MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
5983: @*/
5984: PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
5985: {
5991: MatCheckPreallocated(mat,1);
5992: if (m) *m = mat->cmap->rstart;
5993: if (n) *n = mat->cmap->rend;
5994: return(0);
5995: }
5999: /*@
6000: MatGetOwnershipRange - Returns the range of matrix rows owned by
6001: this processor, assuming that the matrix is laid out with the first
6002: n1 rows on the first processor, the next n2 rows on the second, etc.
6003: For certain parallel layouts this range may not be well defined.
6005: Not Collective
6007: Input Parameters:
6008: . mat - the matrix
6010: Output Parameters:
6011: + m - the global index of the first local row
6012: - n - one more than the global index of the last local row
6014: Note: Both output parameters can be NULL on input.
6015: $ This function requires that the matrix be preallocated. If you have not preallocated, consider using
6016: $ PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
6017: $ and then MPI_Scan() to calculate prefix sums of the local sizes.
6019: Level: beginner
6021: Concepts: matrices^row ownership
6023: .seealso: MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()
6025: @*/
6026: PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6027: {
6033: MatCheckPreallocated(mat,1);
6034: if (m) *m = mat->rmap->rstart;
6035: if (n) *n = mat->rmap->rend;
6036: return(0);
6037: }
6041: /*@C
6042: MatGetOwnershipRanges - Returns the range of matrix rows owned by
6043: each process
6045: Not Collective, unless matrix has not been allocated, then collective on Mat
6047: Input Parameters:
6048: . mat - the matrix
6050: Output Parameters:
6051: . ranges - start of each processors portion plus one more then the total length at the end
6053: Level: beginner
6055: Concepts: matrices^row ownership
6057: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
6059: @*/
6060: PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6061: {
6067: MatCheckPreallocated(mat,1);
6068: PetscLayoutGetRanges(mat->rmap,ranges);
6069: return(0);
6070: }
6074: /*@C
6075: MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6076: this processor. (The columns of the "diagonal blocks" for each process)
6078: Not Collective, unless matrix has not been allocated, then collective on Mat
6080: Input Parameters:
6081: . mat - the matrix
6083: Output Parameters:
6084: . ranges - start of each processors portion plus one more then the total length at the end
6086: Level: beginner
6088: Concepts: matrices^column ownership
6090: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
6092: @*/
6093: PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6094: {
6100: MatCheckPreallocated(mat,1);
6101: PetscLayoutGetRanges(mat->cmap,ranges);
6102: return(0);
6103: }
6107: /*@C
6108: MatGetOwnershipIS - Get row and column ownership as index sets
6110: Not Collective
6112: Input Arguments:
6113: . A - matrix of type Elemental
6115: Output Arguments:
6116: + rows - rows in which this process owns elements
6117: . cols - columns in which this process owns elements
6119: Level: intermediate
6121: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL, MatSetValues()
6122: @*/
6123: PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6124: {
6125: PetscErrorCode ierr,(*f)(Mat,IS*,IS*);
6128: MatCheckPreallocated(A,1);
6129: PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);
6130: if (f) {
6131: (*f)(A,rows,cols);
6132: } else { /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6133: if (rows) {ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);}
6134: if (cols) {ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);}
6135: }
6136: return(0);
6137: }
6141: /*@C
6142: MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6143: Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6144: to complete the factorization.
6146: Collective on Mat
6148: Input Parameters:
6149: + mat - the matrix
6150: . row - row permutation
6151: . column - column permutation
6152: - info - structure containing
6153: $ levels - number of levels of fill.
6154: $ expected fill - as ratio of original fill.
6155: $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6156: missing diagonal entries)
6158: Output Parameters:
6159: . fact - new matrix that has been symbolically factored
6161: Notes: See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
6163: Most users should employ the simplified KSP interface for linear solvers
6164: instead of working directly with matrix algebra routines such as this.
6165: See, e.g., KSPCreate().
6167: Level: developer
6169: Concepts: matrices^symbolic LU factorization
6170: Concepts: matrices^factorization
6171: Concepts: LU^symbolic factorization
6173: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6174: MatGetOrdering(), MatFactorInfo
6176: Developer Note: fortran interface is not autogenerated as the f90
6177: interface defintion cannot be generated correctly [due to MatFactorInfo]
6179: @*/
6180: PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6181: {
6191: if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6192: if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6193: if (!(fact)->ops->ilufactorsymbolic) {
6194: const MatSolverPackage spackage;
6195: MatFactorGetSolverPackage(fact,&spackage);
6196: SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6197: }
6198: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6199: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6200: MatCheckPreallocated(mat,2);
6202: PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);
6203: (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);
6204: PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);
6205: return(0);
6206: }
6210: /*@C
6211: MatICCFactorSymbolic - Performs symbolic incomplete
6212: Cholesky factorization for a symmetric matrix. Use
6213: MatCholeskyFactorNumeric() to complete the factorization.
6215: Collective on Mat
6217: Input Parameters:
6218: + mat - the matrix
6219: . perm - row and column permutation
6220: - info - structure containing
6221: $ levels - number of levels of fill.
6222: $ expected fill - as ratio of original fill.
6224: Output Parameter:
6225: . fact - the factored matrix
6227: Notes:
6228: Most users should employ the KSP interface for linear solvers
6229: instead of working directly with matrix algebra routines such as this.
6230: See, e.g., KSPCreate().
6232: Level: developer
6234: Concepts: matrices^symbolic incomplete Cholesky factorization
6235: Concepts: matrices^factorization
6236: Concepts: Cholsky^symbolic factorization
6238: .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
6240: Developer Note: fortran interface is not autogenerated as the f90
6241: interface defintion cannot be generated correctly [due to MatFactorInfo]
6243: @*/
6244: PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6245: {
6254: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6255: if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6256: if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6257: if (!(fact)->ops->iccfactorsymbolic) {
6258: const MatSolverPackage spackage;
6259: MatFactorGetSolverPackage(fact,&spackage);
6260: SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6261: }
6262: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6263: MatCheckPreallocated(mat,2);
6265: PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);
6266: (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);
6267: PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);
6268: return(0);
6269: }
6273: /*@C
6274: MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
6275: points to an array of valid matrices, they may be reused to store the new
6276: submatrices.
6278: Collective on Mat
6280: Input Parameters:
6281: + mat - the matrix
6282: . n - the number of submatrixes to be extracted (on this processor, may be zero)
6283: . irow, icol - index sets of rows and columns to extract (must be sorted)
6284: - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6286: Output Parameter:
6287: . submat - the array of submatrices
6289: Notes:
6290: MatGetSubMatrices() can extract ONLY sequential submatrices
6291: (from both sequential and parallel matrices). Use MatGetSubMatrix()
6292: to extract a parallel submatrix.
6294: Currently both row and column indices must be sorted to guarantee
6295: correctness with all matrix types.
6297: When extracting submatrices from a parallel matrix, each processor can
6298: form a different submatrix by setting the rows and columns of its
6299: individual index sets according to the local submatrix desired.
6301: When finished using the submatrices, the user should destroy
6302: them with MatDestroyMatrices().
6304: MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6305: original matrix has not changed from that last call to MatGetSubMatrices().
6307: This routine creates the matrices in submat; you should NOT create them before
6308: calling it. It also allocates the array of matrix pointers submat.
6310: For BAIJ matrices the index sets must respect the block structure, that is if they
6311: request one row/column in a block, they must request all rows/columns that are in
6312: that block. For example, if the block size is 2 you cannot request just row 0 and
6313: column 0.
6315: Fortran Note:
6316: The Fortran interface is slightly different from that given below; it
6317: requires one to pass in as submat a Mat (integer) array of size at least m.
6319: Level: advanced
6321: Concepts: matrices^accessing submatrices
6322: Concepts: submatrices
6324: .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6325: @*/
6326: PetscErrorCode MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6327: {
6329: PetscInt i;
6330: PetscBool eq;
6335: if (n) {
6340: }
6342: if (n && scall == MAT_REUSE_MATRIX) {
6345: }
6346: if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6347: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6348: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6349: MatCheckPreallocated(mat,1);
6351: PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6352: (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);
6353: PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6354: for (i=0; i<n; i++) {
6355: (*submat)[i]->factortype = MAT_FACTOR_NONE; /* in case in place factorization was previously done on submatrix */
6356: if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6357: ISEqual(irow[i],icol[i],&eq);
6358: if (eq) {
6359: if (mat->symmetric) {
6360: MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6361: } else if (mat->hermitian) {
6362: MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6363: } else if (mat->structurally_symmetric) {
6364: MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6365: }
6366: }
6367: }
6368: }
6369: return(0);
6370: }
6374: PetscErrorCode MatGetSubMatricesParallel(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6375: {
6377: PetscInt i;
6378: PetscBool eq;
6383: if (n) {
6388: }
6390: if (n && scall == MAT_REUSE_MATRIX) {
6393: }
6394: if (!mat->ops->getsubmatricesparallel) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6395: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6396: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6397: MatCheckPreallocated(mat,1);
6399: PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6400: (*mat->ops->getsubmatricesparallel)(mat,n,irow,icol,scall,submat);
6401: PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6402: for (i=0; i<n; i++) {
6403: if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6404: ISEqual(irow[i],icol[i],&eq);
6405: if (eq) {
6406: if (mat->symmetric) {
6407: MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6408: } else if (mat->hermitian) {
6409: MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6410: } else if (mat->structurally_symmetric) {
6411: MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6412: }
6413: }
6414: }
6415: }
6416: return(0);
6417: }
6421: /*@C
6422: MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().
6424: Collective on Mat
6426: Input Parameters:
6427: + n - the number of local matrices
6428: - mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6429: sequence of MatGetSubMatrices())
6431: Level: advanced
6433: Notes: Frees not only the matrices, but also the array that contains the matrices
6434: In Fortran will not free the array.
6436: .seealso: MatGetSubMatrices()
6437: @*/
6438: PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
6439: {
6441: PetscInt i;
6444: if (!*mat) return(0);
6445: if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6447: for (i=0; i<n; i++) {
6448: MatDestroy(&(*mat)[i]);
6449: }
6450: /* memory is allocated even if n = 0 */
6451: PetscFree(*mat);
6452: *mat = NULL;
6453: return(0);
6454: }
6458: /*@C
6459: MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
6461: Collective on Mat
6463: Input Parameters:
6464: . mat - the matrix
6466: Output Parameter:
6467: . matstruct - the sequential matrix with the nonzero structure of mat
6469: Level: intermediate
6471: .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
6472: @*/
6473: PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6474: {
6482: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6483: MatCheckPreallocated(mat,1);
6485: if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6486: PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6487: (*mat->ops->getseqnonzerostructure)(mat,matstruct);
6488: PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6489: return(0);
6490: }
6494: /*@C
6495: MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
6497: Collective on Mat
6499: Input Parameters:
6500: . mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
6501: sequence of MatGetSequentialNonzeroStructure())
6503: Level: advanced
6505: Notes: Frees not only the matrices, but also the array that contains the matrices
6507: .seealso: MatGetSeqNonzeroStructure()
6508: @*/
6509: PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
6510: {
6515: MatDestroy(mat);
6516: return(0);
6517: }
6521: /*@
6522: MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6523: replaces the index sets by larger ones that represent submatrices with
6524: additional overlap.
6526: Collective on Mat
6528: Input Parameters:
6529: + mat - the matrix
6530: . n - the number of index sets
6531: . is - the array of index sets (these index sets will changed during the call)
6532: - ov - the additional overlap requested
6534: Level: developer
6536: Concepts: overlap
6537: Concepts: ASM^computing overlap
6539: .seealso: MatGetSubMatrices()
6540: @*/
6541: PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6542: {
6548: if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6549: if (n) {
6552: }
6553: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6554: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6555: MatCheckPreallocated(mat,1);
6557: if (!ov) return(0);
6558: if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6559: PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
6560: (*mat->ops->increaseoverlap)(mat,n,is,ov);
6561: PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
6562: return(0);
6563: }
6567: /*@
6568: MatGetBlockSize - Returns the matrix block size; useful especially for the
6569: block row and block diagonal formats.
6571: Not Collective
6573: Input Parameter:
6574: . mat - the matrix
6576: Output Parameter:
6577: . bs - block size
6579: Notes:
6580: Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ.
6582: If the block size has not been set yet this routine returns -1.
6584: Level: intermediate
6586: Concepts: matrices^block size
6588: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
6589: @*/
6590: PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
6591: {
6595: *bs = PetscAbs(mat->rmap->bs);
6596: return(0);
6597: }
6601: /*@
6602: MatGetBlockSizes - Returns the matrix block row and column sizes;
6603: useful especially for the block row and block diagonal formats.
6605: Not Collective
6607: Input Parameter:
6608: . mat - the matrix
6610: Output Parameter:
6611: . rbs - row block size
6612: . cbs - coumn block size
6614: Notes:
6615: Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ.
6617: If a block size has not been set yet this routine returns -1.
6619: Level: intermediate
6621: Concepts: matrices^block size
6623: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
6624: @*/
6625: PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
6626: {
6631: if (rbs) *rbs = PetscAbs(mat->rmap->bs);
6632: if (cbs) *cbs = PetscAbs(mat->cmap->bs);
6633: return(0);
6634: }
6638: /*@
6639: MatSetBlockSize - Sets the matrix block size.
6641: Logically Collective on Mat
6643: Input Parameters:
6644: + mat - the matrix
6645: - bs - block size
6647: Notes:
6648: This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later
6650: Level: intermediate
6652: Concepts: matrices^block size
6654: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
6655: @*/
6656: PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
6657: {
6663: PetscLayoutSetBlockSize(mat->rmap,bs);
6664: PetscLayoutSetBlockSize(mat->cmap,bs);
6665: return(0);
6666: }
6670: /*@
6671: MatSetBlockSizes - Sets the matrix block row and column sizes.
6673: Logically Collective on Mat
6675: Input Parameters:
6676: + mat - the matrix
6677: - rbs - row block size
6678: - cbs - column block size
6680: Notes:
6681: This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later
6683: Level: intermediate
6685: Concepts: matrices^block size
6687: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
6688: @*/
6689: PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
6690: {
6697: PetscLayoutSetBlockSize(mat->rmap,rbs);
6698: PetscLayoutSetBlockSize(mat->cmap,cbs);
6699: return(0);
6700: }
6704: /*@
6705: MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices
6707: Logically Collective on Mat
6709: Input Parameters:
6710: + mat - the matrix
6711: . fromRow - matrix from which to copy row block size
6712: - fromCol - matrix from which to copy column block size (can be same as fromRow)
6714: Level: developer
6716: Concepts: matrices^block size
6718: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes()
6719: @*/
6720: PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)
6721: {
6728: if (fromRow->rmap->bs > 0) {PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);}
6729: if (fromCol->cmap->bs > 0) {PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);}
6730: return(0);
6731: }
6735: /*@
6736: MatResidual - Default routine to calculate the residual.
6738: Collective on Mat and Vec
6740: Input Parameters:
6741: + mat - the matrix
6742: . b - the right-hand-side
6743: - x - the approximate solution
6745: Output Parameter:
6746: . r - location to store the residual
6748: Level: developer
6750: .keywords: MG, default, multigrid, residual
6752: .seealso: PCMGSetResidual()
6753: @*/
6754: PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r)
6755: {
6764: MatCheckPreallocated(mat,1);
6765: PetscLogEventBegin(MAT_Residual,mat,0,0,0);
6766: if (!mat->ops->residual) {
6767: MatMult(mat,x,r);
6768: VecAYPX(r,-1.0,b);
6769: } else {
6770: (*mat->ops->residual)(mat,b,x,r);
6771: }
6772: PetscLogEventEnd(MAT_Residual,mat,0,0,0);
6773: return(0);
6774: }
6778: /*@C
6779: MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
6781: Collective on Mat
6783: Input Parameters:
6784: + mat - the matrix
6785: . shift - 0 or 1 indicating we want the indices starting at 0 or 1
6786: . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be symmetrized
6787: - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6788: inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6789: always used.
6791: Output Parameters:
6792: + n - number of rows in the (possibly compressed) matrix
6793: . ia - the row pointers [of length n+1]
6794: . ja - the column indices
6795: - done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
6796: are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
6798: Level: developer
6800: Notes: You CANNOT change any of the ia[] or ja[] values.
6802: Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values
6804: Fortran Node
6806: In Fortran use
6807: $ PetscInt ia(1), ja(1)
6808: $ PetscOffset iia, jja
6809: $ call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
6810: $
6811: $ or
6812: $
6813: $ PetscScalar, pointer :: xx_v(:)
6814: $ call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
6817: Acess the ith and jth entries via ia(iia + i) and ja(jja + j)
6819: .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
6820: @*/
6821: PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done)
6822: {
6832: MatCheckPreallocated(mat,1);
6833: if (!mat->ops->getrowij) *done = PETSC_FALSE;
6834: else {
6835: *done = PETSC_TRUE;
6836: PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);
6837: (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6838: PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);
6839: }
6840: return(0);
6841: }
6845: /*@C
6846: MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
6848: Collective on Mat
6850: Input Parameters:
6851: + mat - the matrix
6852: . shift - 1 or zero indicating we want the indices starting at 0 or 1
6853: . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6854: symmetrized
6855: . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6856: inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6857: always used.
6858: . n - number of columns in the (possibly compressed) matrix
6859: . ia - the column pointers
6860: - ja - the row indices
6862: Output Parameters:
6863: . done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
6865: Note:
6866: This routine zeros out n, ia, and ja. This is to prevent accidental
6867: us of the array after it has been restored. If you pass NULL, it will
6868: not zero the pointers. Use of ia or ja after MatRestoreColumnIJ() is invalid.
6870: Level: developer
6872: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6873: @*/
6874: PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done)
6875: {
6885: MatCheckPreallocated(mat,1);
6886: if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
6887: else {
6888: *done = PETSC_TRUE;
6889: (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6890: }
6891: return(0);
6892: }
6896: /*@C
6897: MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
6898: MatGetRowIJ().
6900: Collective on Mat
6902: Input Parameters:
6903: + mat - the matrix
6904: . shift - 1 or zero indicating we want the indices starting at 0 or 1
6905: . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6906: symmetrized
6907: . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6908: inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6909: always used.
6910: . n - size of (possibly compressed) matrix
6911: . ia - the row pointers
6912: - ja - the column indices
6914: Output Parameters:
6915: . done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
6917: Note:
6918: This routine zeros out n, ia, and ja. This is to prevent accidental
6919: us of the array after it has been restored. If you pass NULL, it will
6920: not zero the pointers. Use of ia or ja after MatRestoreRowIJ() is invalid.
6922: Level: developer
6924: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6925: @*/
6926: PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done)
6927: {
6936: MatCheckPreallocated(mat,1);
6938: if (!mat->ops->restorerowij) *done = PETSC_FALSE;
6939: else {
6940: *done = PETSC_TRUE;
6941: (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6942: if (n) *n = 0;
6943: if (ia) *ia = NULL;
6944: if (ja) *ja = NULL;
6945: }
6946: return(0);
6947: }
6951: /*@C
6952: MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
6953: MatGetColumnIJ().
6955: Collective on Mat
6957: Input Parameters:
6958: + mat - the matrix
6959: . shift - 1 or zero indicating we want the indices starting at 0 or 1
6960: - symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6961: symmetrized
6962: - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6963: inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6964: always used.
6966: Output Parameters:
6967: + n - size of (possibly compressed) matrix
6968: . ia - the column pointers
6969: . ja - the row indices
6970: - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
6972: Level: developer
6974: .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
6975: @*/
6976: PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done)
6977: {
6986: MatCheckPreallocated(mat,1);
6988: if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
6989: else {
6990: *done = PETSC_TRUE;
6991: (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6992: if (n) *n = 0;
6993: if (ia) *ia = NULL;
6994: if (ja) *ja = NULL;
6995: }
6996: return(0);
6997: }
7001: /*@C
7002: MatColoringPatch -Used inside matrix coloring routines that
7003: use MatGetRowIJ() and/or MatGetColumnIJ().
7005: Collective on Mat
7007: Input Parameters:
7008: + mat - the matrix
7009: . ncolors - max color value
7010: . n - number of entries in colorarray
7011: - colorarray - array indicating color for each column
7013: Output Parameters:
7014: . iscoloring - coloring generated using colorarray information
7016: Level: developer
7018: .seealso: MatGetRowIJ(), MatGetColumnIJ()
7020: @*/
7021: PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7022: {
7030: MatCheckPreallocated(mat,1);
7032: if (!mat->ops->coloringpatch) {
7033: ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,iscoloring);
7034: } else {
7035: (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);
7036: }
7037: return(0);
7038: }
7043: /*@
7044: MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
7046: Logically Collective on Mat
7048: Input Parameter:
7049: . mat - the factored matrix to be reset
7051: Notes:
7052: This routine should be used only with factored matrices formed by in-place
7053: factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7054: format). This option can save memory, for example, when solving nonlinear
7055: systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7056: ILU(0) preconditioner.
7058: Note that one can specify in-place ILU(0) factorization by calling
7059: .vb
7060: PCType(pc,PCILU);
7061: PCFactorSeUseInPlace(pc);
7062: .ve
7063: or by using the options -pc_type ilu -pc_factor_in_place
7065: In-place factorization ILU(0) can also be used as a local
7066: solver for the blocks within the block Jacobi or additive Schwarz
7067: methods (runtime option: -sub_pc_factor_in_place). See Users-Manual: ch_pc
7068: for details on setting local solver options.
7070: Most users should employ the simplified KSP interface for linear solvers
7071: instead of working directly with matrix algebra routines such as this.
7072: See, e.g., KSPCreate().
7074: Level: developer
7076: .seealso: PCFactorSetUseInPlace()
7078: Concepts: matrices^unfactored
7080: @*/
7081: PetscErrorCode MatSetUnfactored(Mat mat)
7082: {
7088: MatCheckPreallocated(mat,1);
7089: mat->factortype = MAT_FACTOR_NONE;
7090: if (!mat->ops->setunfactored) return(0);
7091: (*mat->ops->setunfactored)(mat);
7092: return(0);
7093: }
7095: /*MC
7096: MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.
7098: Synopsis:
7099: MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7101: Not collective
7103: Input Parameter:
7104: . x - matrix
7106: Output Parameters:
7107: + xx_v - the Fortran90 pointer to the array
7108: - ierr - error code
7110: Example of Usage:
7111: .vb
7112: PetscScalar, pointer xx_v(:,:)
7113: ....
7114: call MatDenseGetArrayF90(x,xx_v,ierr)
7115: a = xx_v(3)
7116: call MatDenseRestoreArrayF90(x,xx_v,ierr)
7117: .ve
7119: Level: advanced
7121: .seealso: MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90()
7123: Concepts: matrices^accessing array
7125: M*/
7127: /*MC
7128: MatDenseRestoreArrayF90 - Restores a matrix array that has been
7129: accessed with MatDenseGetArrayF90().
7131: Synopsis:
7132: MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7134: Not collective
7136: Input Parameters:
7137: + x - matrix
7138: - xx_v - the Fortran90 pointer to the array
7140: Output Parameter:
7141: . ierr - error code
7143: Example of Usage:
7144: .vb
7145: PetscScalar, pointer xx_v(:)
7146: ....
7147: call MatDenseGetArrayF90(x,xx_v,ierr)
7148: a = xx_v(3)
7149: call MatDenseRestoreArrayF90(x,xx_v,ierr)
7150: .ve
7152: Level: advanced
7154: .seealso: MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90()
7156: M*/
7159: /*MC
7160: MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.
7162: Synopsis:
7163: MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7165: Not collective
7167: Input Parameter:
7168: . x - matrix
7170: Output Parameters:
7171: + xx_v - the Fortran90 pointer to the array
7172: - ierr - error code
7174: Example of Usage:
7175: .vb
7176: PetscScalar, pointer xx_v(:,:)
7177: ....
7178: call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7179: a = xx_v(3)
7180: call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7181: .ve
7183: Level: advanced
7185: .seealso: MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90()
7187: Concepts: matrices^accessing array
7189: M*/
7191: /*MC
7192: MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7193: accessed with MatSeqAIJGetArrayF90().
7195: Synopsis:
7196: MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7198: Not collective
7200: Input Parameters:
7201: + x - matrix
7202: - xx_v - the Fortran90 pointer to the array
7204: Output Parameter:
7205: . ierr - error code
7207: Example of Usage:
7208: .vb
7209: PetscScalar, pointer xx_v(:)
7210: ....
7211: call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7212: a = xx_v(3)
7213: call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7214: .ve
7216: Level: advanced
7218: .seealso: MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90()
7220: M*/
7225: /*@
7226: MatGetSubMatrix - Gets a single submatrix on the same number of processors
7227: as the original matrix.
7229: Collective on Mat
7231: Input Parameters:
7232: + mat - the original matrix
7233: . isrow - parallel IS containing the rows this processor should obtain
7234: . 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.
7235: - cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7237: Output Parameter:
7238: . newmat - the new submatrix, of the same type as the old
7240: Level: advanced
7242: Notes:
7243: The submatrix will be able to be multiplied with vectors using the same layout as iscol.
7245: The rows in isrow will be sorted into the same order as the original matrix on each process.
7247: The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7248: the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
7249: to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7250: will reuse the matrix generated the first time. You should call MatDestroy() on newmat when
7251: you are finished using it.
7253: The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7254: the input matrix.
7256: If iscol is NULL then all columns are obtained (not supported in Fortran).
7258: Example usage:
7259: Consider the following 8x8 matrix with 34 non-zero values, that is
7260: assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7261: proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7262: as follows:
7264: .vb
7265: 1 2 0 | 0 3 0 | 0 4
7266: Proc0 0 5 6 | 7 0 0 | 8 0
7267: 9 0 10 | 11 0 0 | 12 0
7268: -------------------------------------
7269: 13 0 14 | 15 16 17 | 0 0
7270: Proc1 0 18 0 | 19 20 21 | 0 0
7271: 0 0 0 | 22 23 0 | 24 0
7272: -------------------------------------
7273: Proc2 25 26 27 | 0 0 28 | 29 0
7274: 30 0 0 | 31 32 33 | 0 34
7275: .ve
7277: Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6]. The resulting submatrix is
7279: .vb
7280: 2 0 | 0 3 0 | 0
7281: Proc0 5 6 | 7 0 0 | 8
7282: -------------------------------
7283: Proc1 18 0 | 19 20 21 | 0
7284: -------------------------------
7285: Proc2 26 27 | 0 0 28 | 29
7286: 0 0 | 31 32 33 | 0
7287: .ve
7290: Concepts: matrices^submatrices
7292: .seealso: MatGetSubMatrices()
7293: @*/
7294: PetscErrorCode MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7295: {
7297: PetscMPIInt size;
7298: Mat *local;
7299: IS iscoltmp;
7308: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7309: MatCheckPreallocated(mat,1);
7310: MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
7312: if (!iscol) {
7313: ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);
7314: } else {
7315: iscoltmp = iscol;
7316: }
7318: /* if original matrix is on just one processor then use submatrix generated */
7319: if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7320: MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);
7321: if (!iscol) {ISDestroy(&iscoltmp);}
7322: return(0);
7323: } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) {
7324: MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);
7325: *newmat = *local;
7326: PetscFree(local);
7327: if (!iscol) {ISDestroy(&iscoltmp);}
7328: return(0);
7329: } else if (!mat->ops->getsubmatrix) {
7330: /* Create a new matrix type that implements the operation using the full matrix */
7331: switch (cll) {
7332: case MAT_INITIAL_MATRIX:
7333: MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);
7334: break;
7335: case MAT_REUSE_MATRIX:
7336: MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);
7337: break;
7338: default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7339: }
7340: if (!iscol) {ISDestroy(&iscoltmp);}
7341: return(0);
7342: }
7344: if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7345: (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);
7346: if (!iscol) {ISDestroy(&iscoltmp);}
7347: if (*newmat && cll == MAT_INITIAL_MATRIX) {PetscObjectStateIncrease((PetscObject)*newmat);}
7348: return(0);
7349: }
7353: /*@
7354: MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7355: used during the assembly process to store values that belong to
7356: other processors.
7358: Not Collective
7360: Input Parameters:
7361: + mat - the matrix
7362: . size - the initial size of the stash.
7363: - bsize - the initial size of the block-stash(if used).
7365: Options Database Keys:
7366: + -matstash_initial_size <size> or <size0,size1,...sizep-1>
7367: - -matstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1>
7369: Level: intermediate
7371: Notes:
7372: The block-stash is used for values set with MatSetValuesBlocked() while
7373: the stash is used for values set with MatSetValues()
7375: Run with the option -info and look for output of the form
7376: MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7377: to determine the appropriate value, MM, to use for size and
7378: MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7379: to determine the value, BMM to use for bsize
7381: Concepts: stash^setting matrix size
7382: Concepts: matrices^stash
7384: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
7386: @*/
7387: PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7388: {
7394: MatStashSetInitialSize_Private(&mat->stash,size);
7395: MatStashSetInitialSize_Private(&mat->bstash,bsize);
7396: return(0);
7397: }
7401: /*@
7402: MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
7403: the matrix
7405: Neighbor-wise Collective on Mat
7407: Input Parameters:
7408: + mat - the matrix
7409: . x,y - the vectors
7410: - w - where the result is stored
7412: Level: intermediate
7414: Notes:
7415: w may be the same vector as y.
7417: This allows one to use either the restriction or interpolation (its transpose)
7418: matrix to do the interpolation
7420: Concepts: interpolation
7422: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7424: @*/
7425: PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7426: {
7428: PetscInt M,N,Ny;
7436: MatCheckPreallocated(A,1);
7437: MatGetSize(A,&M,&N);
7438: VecGetSize(y,&Ny);
7439: if (M == Ny) {
7440: MatMultAdd(A,x,y,w);
7441: } else {
7442: MatMultTransposeAdd(A,x,y,w);
7443: }
7444: return(0);
7445: }
7449: /*@
7450: MatInterpolate - y = A*x or A'*x depending on the shape of
7451: the matrix
7453: Neighbor-wise Collective on Mat
7455: Input Parameters:
7456: + mat - the matrix
7457: - x,y - the vectors
7459: Level: intermediate
7461: Notes:
7462: This allows one to use either the restriction or interpolation (its transpose)
7463: matrix to do the interpolation
7465: Concepts: matrices^interpolation
7467: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7469: @*/
7470: PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
7471: {
7473: PetscInt M,N,Ny;
7480: MatCheckPreallocated(A,1);
7481: MatGetSize(A,&M,&N);
7482: VecGetSize(y,&Ny);
7483: if (M == Ny) {
7484: MatMult(A,x,y);
7485: } else {
7486: MatMultTranspose(A,x,y);
7487: }
7488: return(0);
7489: }
7493: /*@
7494: MatRestrict - y = A*x or A'*x
7496: Neighbor-wise Collective on Mat
7498: Input Parameters:
7499: + mat - the matrix
7500: - x,y - the vectors
7502: Level: intermediate
7504: Notes:
7505: This allows one to use either the restriction or interpolation (its transpose)
7506: matrix to do the restriction
7508: Concepts: matrices^restriction
7510: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
7512: @*/
7513: PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
7514: {
7516: PetscInt M,N,Ny;
7523: MatCheckPreallocated(A,1);
7525: MatGetSize(A,&M,&N);
7526: VecGetSize(y,&Ny);
7527: if (M == Ny) {
7528: MatMult(A,x,y);
7529: } else {
7530: MatMultTranspose(A,x,y);
7531: }
7532: return(0);
7533: }
7537: /*@
7538: MatGetNullSpace - retrieves the null space to a matrix.
7540: Logically Collective on Mat and MatNullSpace
7542: Input Parameters:
7543: + mat - the matrix
7544: - nullsp - the null space object
7546: Level: developer
7548: Notes:
7549: This null space is used by solvers. Overwrites any previous null space that may have been attached
7551: Concepts: null space^attaching to matrix
7553: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace()
7554: @*/
7555: PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
7556: {
7561: *nullsp = mat->nullsp;
7562: return(0);
7563: }
7567: /*@
7568: MatSetNullSpace - attaches a null space to a matrix.
7569: This null space will be removed from the resulting vector whenever
7570: MatMult() is called
7572: Logically Collective on Mat and MatNullSpace
7574: Input Parameters:
7575: + mat - the matrix
7576: - nullsp - the null space object
7578: Level: advanced
7580: Notes:
7581: This null space is used by solvers. Overwrites any previous null space that may have been attached
7583: Concepts: null space^attaching to matrix
7585: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace()
7586: @*/
7587: PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp)
7588: {
7595: MatCheckPreallocated(mat,1);
7596: PetscObjectReference((PetscObject)nullsp);
7597: MatNullSpaceDestroy(&mat->nullsp);
7599: mat->nullsp = nullsp;
7600: return(0);
7601: }
7605: /*@
7606: MatSetNearNullSpace - attaches a null space to a matrix.
7607: This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.
7609: Logically Collective on Mat and MatNullSpace
7611: Input Parameters:
7612: + mat - the matrix
7613: - nullsp - the null space object
7615: Level: advanced
7617: Notes:
7618: Overwrites any previous near null space that may have been attached
7620: Concepts: null space^attaching to matrix
7622: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace()
7623: @*/
7624: PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
7625: {
7632: MatCheckPreallocated(mat,1);
7633: PetscObjectReference((PetscObject)nullsp);
7634: MatNullSpaceDestroy(&mat->nearnullsp);
7636: mat->nearnullsp = nullsp;
7637: return(0);
7638: }
7642: /*@
7643: MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()
7645: Not Collective
7647: Input Parameters:
7648: . mat - the matrix
7650: Output Parameters:
7651: . nullsp - the null space object, NULL if not set
7653: Level: developer
7655: Concepts: null space^attaching to matrix
7657: .seealso: MatSetNearNullSpace(), MatGetNullSpace()
7658: @*/
7659: PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
7660: {
7665: MatCheckPreallocated(mat,1);
7666: *nullsp = mat->nearnullsp;
7667: return(0);
7668: }
7672: /*@C
7673: MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
7675: Collective on Mat
7677: Input Parameters:
7678: + mat - the matrix
7679: . row - row/column permutation
7680: . fill - expected fill factor >= 1.0
7681: - level - level of fill, for ICC(k)
7683: Notes:
7684: Probably really in-place only when level of fill is zero, otherwise allocates
7685: new space to store factored matrix and deletes previous memory.
7687: Most users should employ the simplified KSP interface for linear solvers
7688: instead of working directly with matrix algebra routines such as this.
7689: See, e.g., KSPCreate().
7691: Level: developer
7693: Concepts: matrices^incomplete Cholesky factorization
7694: Concepts: Cholesky factorization
7696: .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
7698: Developer Note: fortran interface is not autogenerated as the f90
7699: interface defintion cannot be generated correctly [due to MatFactorInfo]
7701: @*/
7702: PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
7703: {
7711: if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
7712: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7713: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7714: if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7715: MatCheckPreallocated(mat,1);
7716: (*mat->ops->iccfactor)(mat,row,info);
7717: PetscObjectStateIncrease((PetscObject)mat);
7718: return(0);
7719: }
7723: /*@
7724: MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.
7726: Not Collective
7728: Input Parameters:
7729: + mat - the matrix
7730: . nl - leading dimension of v
7731: - v - the values compute with ADIFOR
7733: Level: developer
7735: Notes:
7736: Must call MatSetColoring() before using this routine. Also this matrix must already
7737: have its nonzero pattern determined.
7739: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7740: MatSetValues(), MatSetColoring()
7741: @*/
7742: PetscErrorCode MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
7743: {
7751: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7752: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
7753: if (!mat->ops->setvaluesadifor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7754: (*mat->ops->setvaluesadifor)(mat,nl,v);
7755: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
7756: PetscObjectStateIncrease((PetscObject)mat);
7757: return(0);
7758: }
7762: /*@
7763: MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
7764: ghosted ones.
7766: Not Collective
7768: Input Parameters:
7769: + mat - the matrix
7770: - diag = the diagonal values, including ghost ones
7772: Level: developer
7774: Notes: Works only for MPIAIJ and MPIBAIJ matrices
7776: .seealso: MatDiagonalScale()
7777: @*/
7778: PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
7779: {
7781: PetscMPIInt size;
7788: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7789: PetscLogEventBegin(MAT_Scale,mat,0,0,0);
7790: MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
7791: if (size == 1) {
7792: PetscInt n,m;
7793: VecGetSize(diag,&n);
7794: MatGetSize(mat,0,&m);
7795: if (m == n) {
7796: MatDiagonalScale(mat,0,diag);
7797: } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
7798: } else {
7799: PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));
7800: }
7801: PetscLogEventEnd(MAT_Scale,mat,0,0,0);
7802: PetscObjectStateIncrease((PetscObject)mat);
7803: return(0);
7804: }
7808: /*@
7809: MatGetInertia - Gets the inertia from a factored matrix
7811: Collective on Mat
7813: Input Parameter:
7814: . mat - the matrix
7816: Output Parameters:
7817: + nneg - number of negative eigenvalues
7818: . nzero - number of zero eigenvalues
7819: - npos - number of positive eigenvalues
7821: Level: advanced
7823: Notes: Matrix must have been factored by MatCholeskyFactor()
7826: @*/
7827: PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
7828: {
7834: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7835: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
7836: if (!mat->ops->getinertia) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7837: (*mat->ops->getinertia)(mat,nneg,nzero,npos);
7838: return(0);
7839: }
7841: /* ----------------------------------------------------------------*/
7844: /*@C
7845: MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
7847: Neighbor-wise Collective on Mat and Vecs
7849: Input Parameters:
7850: + mat - the factored matrix
7851: - b - the right-hand-side vectors
7853: Output Parameter:
7854: . x - the result vectors
7856: Notes:
7857: The vectors b and x cannot be the same. I.e., one cannot
7858: call MatSolves(A,x,x).
7860: Notes:
7861: Most users should employ the simplified KSP interface for linear solvers
7862: instead of working directly with matrix algebra routines such as this.
7863: See, e.g., KSPCreate().
7865: Level: developer
7867: Concepts: matrices^triangular solves
7869: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
7870: @*/
7871: PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
7872: {
7878: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
7879: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7880: if (!mat->rmap->N && !mat->cmap->N) return(0);
7882: if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7883: MatCheckPreallocated(mat,1);
7884: PetscLogEventBegin(MAT_Solves,mat,0,0,0);
7885: (*mat->ops->solves)(mat,b,x);
7886: PetscLogEventEnd(MAT_Solves,mat,0,0,0);
7887: return(0);
7888: }
7892: /*@
7893: MatIsSymmetric - Test whether a matrix is symmetric
7895: Collective on Mat
7897: Input Parameter:
7898: + A - the matrix to test
7899: - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
7901: Output Parameters:
7902: . flg - the result
7904: Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
7906: Level: intermediate
7908: Concepts: matrix^symmetry
7910: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
7911: @*/
7912: PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool *flg)
7913: {
7920: if (!A->symmetric_set) {
7921: if (!A->ops->issymmetric) {
7922: MatType mattype;
7923: MatGetType(A,&mattype);
7924: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7925: }
7926: (*A->ops->issymmetric)(A,tol,flg);
7927: if (!tol) {
7928: A->symmetric_set = PETSC_TRUE;
7929: A->symmetric = *flg;
7930: if (A->symmetric) {
7931: A->structurally_symmetric_set = PETSC_TRUE;
7932: A->structurally_symmetric = PETSC_TRUE;
7933: }
7934: }
7935: } else if (A->symmetric) {
7936: *flg = PETSC_TRUE;
7937: } else if (!tol) {
7938: *flg = PETSC_FALSE;
7939: } else {
7940: if (!A->ops->issymmetric) {
7941: MatType mattype;
7942: MatGetType(A,&mattype);
7943: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7944: }
7945: (*A->ops->issymmetric)(A,tol,flg);
7946: }
7947: return(0);
7948: }
7952: /*@
7953: MatIsHermitian - Test whether a matrix is Hermitian
7955: Collective on Mat
7957: Input Parameter:
7958: + A - the matrix to test
7959: - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
7961: Output Parameters:
7962: . flg - the result
7964: Level: intermediate
7966: Concepts: matrix^symmetry
7968: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
7969: MatIsSymmetricKnown(), MatIsSymmetric()
7970: @*/
7971: PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool *flg)
7972: {
7979: if (!A->hermitian_set) {
7980: if (!A->ops->ishermitian) {
7981: MatType mattype;
7982: MatGetType(A,&mattype);
7983: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7984: }
7985: (*A->ops->ishermitian)(A,tol,flg);
7986: if (!tol) {
7987: A->hermitian_set = PETSC_TRUE;
7988: A->hermitian = *flg;
7989: if (A->hermitian) {
7990: A->structurally_symmetric_set = PETSC_TRUE;
7991: A->structurally_symmetric = PETSC_TRUE;
7992: }
7993: }
7994: } else if (A->hermitian) {
7995: *flg = PETSC_TRUE;
7996: } else if (!tol) {
7997: *flg = PETSC_FALSE;
7998: } else {
7999: if (!A->ops->ishermitian) {
8000: MatType mattype;
8001: MatGetType(A,&mattype);
8002: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8003: }
8004: (*A->ops->ishermitian)(A,tol,flg);
8005: }
8006: return(0);
8007: }
8011: /*@
8012: MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
8014: Not Collective
8016: Input Parameter:
8017: . A - the matrix to check
8019: Output Parameters:
8020: + set - if the symmetric flag is set (this tells you if the next flag is valid)
8021: - flg - the result
8023: Level: advanced
8025: Concepts: matrix^symmetry
8027: Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
8028: if you want it explicitly checked
8030: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8031: @*/
8032: PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool *set,PetscBool *flg)
8033: {
8038: if (A->symmetric_set) {
8039: *set = PETSC_TRUE;
8040: *flg = A->symmetric;
8041: } else {
8042: *set = PETSC_FALSE;
8043: }
8044: return(0);
8045: }
8049: /*@
8050: MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
8052: Not Collective
8054: Input Parameter:
8055: . A - the matrix to check
8057: Output Parameters:
8058: + set - if the hermitian flag is set (this tells you if the next flag is valid)
8059: - flg - the result
8061: Level: advanced
8063: Concepts: matrix^symmetry
8065: Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8066: if you want it explicitly checked
8068: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8069: @*/
8070: PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg)
8071: {
8076: if (A->hermitian_set) {
8077: *set = PETSC_TRUE;
8078: *flg = A->hermitian;
8079: } else {
8080: *set = PETSC_FALSE;
8081: }
8082: return(0);
8083: }
8087: /*@
8088: MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
8090: Collective on Mat
8092: Input Parameter:
8093: . A - the matrix to test
8095: Output Parameters:
8096: . flg - the result
8098: Level: intermediate
8100: Concepts: matrix^symmetry
8102: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8103: @*/
8104: PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg)
8105: {
8111: if (!A->structurally_symmetric_set) {
8112: if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8113: (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);
8115: A->structurally_symmetric_set = PETSC_TRUE;
8116: }
8117: *flg = A->structurally_symmetric;
8118: return(0);
8119: }
8123: extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
8124: /*@
8125: MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8126: to be communicated to other processors during the MatAssemblyBegin/End() process
8128: Not collective
8130: Input Parameter:
8131: . vec - the vector
8133: Output Parameters:
8134: + nstash - the size of the stash
8135: . reallocs - the number of additional mallocs incurred.
8136: . bnstash - the size of the block stash
8137: - breallocs - the number of additional mallocs incurred.in the block stash
8139: Level: advanced
8141: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
8143: @*/
8144: PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8145: {
8149: MatStashGetInfo_Private(&mat->stash,nstash,reallocs);
8150: MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);
8151: return(0);
8152: }
8156: /*@C
8157: MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same
8158: parallel layout
8160: Collective on Mat
8162: Input Parameter:
8163: . mat - the matrix
8165: Output Parameter:
8166: + right - (optional) vector that the matrix can be multiplied against
8167: - left - (optional) vector that the matrix vector product can be stored in
8169: Level: advanced
8171: .seealso: MatCreate()
8172: @*/
8173: PetscErrorCode MatGetVecs(Mat mat,Vec *right,Vec *left)
8174: {
8180: MatCheckPreallocated(mat,1);
8181: if (mat->ops->getvecs) {
8182: (*mat->ops->getvecs)(mat,right,left);
8183: } else {
8184: PetscMPIInt size;
8185: PetscInt rbs,cbs;
8186: MPI_Comm_size(PetscObjectComm((PetscObject)mat), &size);
8187: MatGetBlockSizes(mat,&rbs,&cbs);
8188: if (right) {
8189: VecCreate(PetscObjectComm((PetscObject)mat),right);
8190: VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);
8191: VecSetBlockSize(*right,cbs);
8192: VecSetType(*right,VECSTANDARD);
8193: PetscLayoutReference(mat->cmap,&(*right)->map);
8194: }
8195: if (left) {
8196: VecCreate(PetscObjectComm((PetscObject)mat),left);
8197: VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);
8198: VecSetBlockSize(*left,rbs);
8199: VecSetType(*left,VECSTANDARD);
8200: PetscLayoutReference(mat->rmap,&(*left)->map);
8201: }
8202: }
8203: return(0);
8204: }
8208: /*@C
8209: MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8210: with default values.
8212: Not Collective
8214: Input Parameters:
8215: . info - the MatFactorInfo data structure
8218: Notes: The solvers are generally used through the KSP and PC objects, for example
8219: PCLU, PCILU, PCCHOLESKY, PCICC
8221: Level: developer
8223: .seealso: MatFactorInfo
8225: Developer Note: fortran interface is not autogenerated as the f90
8226: interface defintion cannot be generated correctly [due to MatFactorInfo]
8228: @*/
8230: PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
8231: {
8235: PetscMemzero(info,sizeof(MatFactorInfo));
8236: return(0);
8237: }
8241: /*@
8242: MatPtAP - Creates the matrix product C = P^T * A * P
8244: Neighbor-wise Collective on Mat
8246: Input Parameters:
8247: + A - the matrix
8248: . P - the projection matrix
8249: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8250: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P))
8252: Output Parameters:
8253: . C - the product matrix
8255: Notes:
8256: C will be created and must be destroyed by the user with MatDestroy().
8258: This routine is currently only implemented for pairs of AIJ matrices and classes
8259: which inherit from AIJ.
8261: Level: intermediate
8263: .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
8264: @*/
8265: PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
8266: {
8268: PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8269: PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
8270: PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
8271: PetscBool viatranspose=PETSC_FALSE,viamatmatmatmult=PETSC_FALSE;
8274: PetscOptionsGetBool(((PetscObject)A)->prefix,"-matptap_viatranspose",&viatranspose,NULL);
8275: PetscOptionsGetBool(((PetscObject)A)->prefix,"-matptap_viamatmatmatmult",&viamatmatmatmult,NULL);
8279: MatCheckPreallocated(A,1);
8280: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8281: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8284: MatCheckPreallocated(P,2);
8285: if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8286: if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8288: if (P->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
8289: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
8291: if (scall == MAT_REUSE_MATRIX) {
8294: if (viatranspose || viamatmatmatmult) {
8295: Mat Pt;
8296: MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);
8297: if (viamatmatmatmult) {
8298: MatMatMatMult(Pt,A,P,scall,fill,C);
8299: } else {
8300: Mat AP;
8301: MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);
8302: MatMatMult(Pt,AP,scall,fill,C);
8303: MatDestroy(&AP);
8304: }
8305: MatDestroy(&Pt);
8306: } else {
8307: PetscLogEventBegin(MAT_PtAP,A,P,0,0);
8308: PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
8309: (*(*C)->ops->ptapnumeric)(A,P,*C);
8310: PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
8311: PetscLogEventEnd(MAT_PtAP,A,P,0,0);
8312: }
8313: return(0);
8314: }
8316: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8317: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
8319: fA = A->ops->ptap;
8320: fP = P->ops->ptap;
8321: if (fP == fA) {
8322: if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name);
8323: ptap = fA;
8324: } else {
8325: /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
8326: char ptapname[256];
8327: PetscStrcpy(ptapname,"MatPtAP_");
8328: PetscStrcat(ptapname,((PetscObject)A)->type_name);
8329: PetscStrcat(ptapname,"_");
8330: PetscStrcat(ptapname,((PetscObject)P)->type_name);
8331: PetscStrcat(ptapname,"_C"); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
8332: PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);
8333: if (!ptap) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatPtAP requires A, %s, to be compatible with P, %s",((PetscObject)A)->type_name,((PetscObject)P)->type_name);
8334: }
8336: if (viatranspose || viamatmatmatmult) {
8337: Mat Pt;
8338: MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);
8339: if (viamatmatmatmult) {
8340: MatMatMatMult(Pt,A,P,scall,fill,C);
8341: PetscInfo(*C,"MatPtAP via MatMatMatMult\n");
8342: } else {
8343: Mat AP;
8344: MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);
8345: MatMatMult(Pt,AP,scall,fill,C);
8346: MatDestroy(&AP);
8347: PetscInfo(*C,"MatPtAP via MatTranspose and MatMatMult\n");
8348: }
8349: MatDestroy(&Pt);
8350: } else {
8351: PetscLogEventBegin(MAT_PtAP,A,P,0,0);
8352: (*ptap)(A,P,scall,fill,C);
8353: PetscLogEventEnd(MAT_PtAP,A,P,0,0);
8354: }
8355: return(0);
8356: }
8360: /*@
8361: MatPtAPNumeric - Computes the matrix product C = P^T * A * P
8363: Neighbor-wise Collective on Mat
8365: Input Parameters:
8366: + A - the matrix
8367: - P - the projection matrix
8369: Output Parameters:
8370: . C - the product matrix
8372: Notes:
8373: C must have been created by calling MatPtAPSymbolic and must be destroyed by
8374: the user using MatDeatroy().
8376: This routine is currently only implemented for pairs of AIJ matrices and classes
8377: which inherit from AIJ. C will be of type MATAIJ.
8379: Level: intermediate
8381: .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
8382: @*/
8383: PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C)
8384: {
8390: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8391: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8394: MatCheckPreallocated(P,2);
8395: if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8396: if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8399: MatCheckPreallocated(C,3);
8400: if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8401: if (P->cmap->N!=C->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->rmap->N);
8402: if (P->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
8403: if (A->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
8404: if (P->cmap->N!=C->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->cmap->N);
8405: MatCheckPreallocated(A,1);
8407: PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
8408: (*C->ops->ptapnumeric)(A,P,C);
8409: PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
8410: return(0);
8411: }
8415: /*@
8416: MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P
8418: Neighbor-wise Collective on Mat
8420: Input Parameters:
8421: + A - the matrix
8422: - P - the projection matrix
8424: Output Parameters:
8425: . C - the (i,j) structure of the product matrix
8427: Notes:
8428: C will be created and must be destroyed by the user with MatDestroy().
8430: This routine is currently only implemented for pairs of SeqAIJ matrices and classes
8431: which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using
8432: this (i,j) structure by calling MatPtAPNumeric().
8434: Level: intermediate
8436: .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
8437: @*/
8438: PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
8439: {
8445: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8446: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8447: if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
8450: MatCheckPreallocated(P,2);
8451: if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8452: if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8455: if (P->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
8456: if (A->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
8457: MatCheckPreallocated(A,1);
8458: PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);
8459: (*A->ops->ptapsymbolic)(A,P,fill,C);
8460: PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);
8462: /* MatSetBlockSize(*C,A->rmap->bs); NO! this is not always true -ma */
8463: return(0);
8464: }
8468: /*@
8469: MatRARt - Creates the matrix product C = R * A * R^T
8471: Neighbor-wise Collective on Mat
8473: Input Parameters:
8474: + A - the matrix
8475: . R - the projection matrix
8476: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8477: - fill - expected fill as ratio of nnz(C)/nnz(A)
8479: Output Parameters:
8480: . C - the product matrix
8482: Notes:
8483: C will be created and must be destroyed by the user with MatDestroy().
8485: This routine is currently only implemented for pairs of AIJ matrices and classes
8486: which inherit from AIJ.
8488: Level: intermediate
8490: .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
8491: @*/
8492: PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
8493: {
8499: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8500: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8503: MatCheckPreallocated(R,2);
8504: if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8505: if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8507: if (R->cmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)R),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N);
8508: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
8509: MatCheckPreallocated(A,1);
8511: if (!A->ops->rart) {
8512: MatType mattype;
8513: MatGetType(A,&mattype);
8514: SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix of type <%s> does not support RARt",mattype);
8515: }
8516: PetscLogEventBegin(MAT_RARt,A,R,0,0);
8517: (*A->ops->rart)(A,R,scall,fill,C);
8518: PetscLogEventEnd(MAT_RARt,A,R,0,0);
8519: return(0);
8520: }
8524: /*@
8525: MatRARtNumeric - Computes the matrix product C = R * A * R^T
8527: Neighbor-wise Collective on Mat
8529: Input Parameters:
8530: + A - the matrix
8531: - R - the projection matrix
8533: Output Parameters:
8534: . C - the product matrix
8536: Notes:
8537: C must have been created by calling MatRARtSymbolic and must be destroyed by
8538: the user using MatDeatroy().
8540: This routine is currently only implemented for pairs of AIJ matrices and classes
8541: which inherit from AIJ. C will be of type MATAIJ.
8543: Level: intermediate
8545: .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
8546: @*/
8547: PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C)
8548: {
8554: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8555: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8558: MatCheckPreallocated(R,2);
8559: if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8560: if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8563: MatCheckPreallocated(C,3);
8564: if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8565: if (R->rmap->N!=C->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->rmap->N,C->rmap->N);
8566: if (R->cmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N);
8567: if (A->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
8568: if (R->rmap->N!=C->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->rmap->N,C->cmap->N);
8569: MatCheckPreallocated(A,1);
8571: PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);
8572: (*A->ops->rartnumeric)(A,R,C);
8573: PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);
8574: return(0);
8575: }
8579: /*@
8580: MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T
8582: Neighbor-wise Collective on Mat
8584: Input Parameters:
8585: + A - the matrix
8586: - R - the projection matrix
8588: Output Parameters:
8589: . C - the (i,j) structure of the product matrix
8591: Notes:
8592: C will be created and must be destroyed by the user with MatDestroy().
8594: This routine is currently only implemented for pairs of SeqAIJ matrices and classes
8595: which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using
8596: this (i,j) structure by calling MatRARtNumeric().
8598: Level: intermediate
8600: .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
8601: @*/
8602: PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
8603: {
8609: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8610: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8611: if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
8614: MatCheckPreallocated(R,2);
8615: if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8616: if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8619: if (R->cmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N);
8620: if (A->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
8621: MatCheckPreallocated(A,1);
8622: PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);
8623: (*A->ops->rartsymbolic)(A,R,fill,C);
8624: PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);
8626: MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));
8627: return(0);
8628: }
8632: /*@
8633: MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
8635: Neighbor-wise Collective on Mat
8637: Input Parameters:
8638: + A - the left matrix
8639: . B - the right matrix
8640: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8641: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
8642: if the result is a dense matrix this is irrelevent
8644: Output Parameters:
8645: . C - the product matrix
8647: Notes:
8648: Unless scall is MAT_REUSE_MATRIX C will be created.
8650: MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8652: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8653: actually needed.
8655: If you have many matrices with the same non-zero structure to multiply, you
8656: should either
8657: $ 1) use MAT_REUSE_MATRIX in all calls but the first or
8658: $ 2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
8660: Level: intermediate
8662: .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(), MatMatTransposeMult(), MatPtAP()
8663: @*/
8664: PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8665: {
8667: PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8668: PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8669: PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
8674: MatCheckPreallocated(A,1);
8675: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8676: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8679: MatCheckPreallocated(B,2);
8680: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8681: if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8683: if (B->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
8684: if (scall == MAT_REUSE_MATRIX) {
8687: PetscLogEventBegin(MAT_MatMult,A,B,0,0);
8688: PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);
8689: (*(*C)->ops->matmultnumeric)(A,B,*C);
8690: PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);
8691: PetscLogEventEnd(MAT_MatMult,A,B,0,0);
8692: return(0);
8693: }
8694: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8695: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
8697: fA = A->ops->matmult;
8698: fB = B->ops->matmult;
8699: if (fB == fA) {
8700: if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
8701: mult = fB;
8702: } else {
8703: /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
8704: char multname[256];
8705: PetscStrcpy(multname,"MatMatMult_");
8706: PetscStrcat(multname,((PetscObject)A)->type_name);
8707: PetscStrcat(multname,"_");
8708: PetscStrcat(multname,((PetscObject)B)->type_name);
8709: PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
8710: PetscObjectQueryFunction((PetscObject)B,multname,&mult);
8711: if (!mult) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
8712: }
8713: PetscLogEventBegin(MAT_MatMult,A,B,0,0);
8714: (*mult)(A,B,scall,fill,C);
8715: PetscLogEventEnd(MAT_MatMult,A,B,0,0);
8716: return(0);
8717: }
8721: /*@
8722: MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
8723: of the matrix-matrix product C=A*B. Call this routine before calling MatMatMultNumeric().
8725: Neighbor-wise Collective on Mat
8727: Input Parameters:
8728: + A - the left matrix
8729: . B - the right matrix
8730: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
8731: if C is a dense matrix this is irrelevent
8733: Output Parameters:
8734: . C - the product matrix
8736: Notes:
8737: Unless scall is MAT_REUSE_MATRIX C will be created.
8739: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8740: actually needed.
8742: This routine is currently implemented for
8743: - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
8744: - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8745: - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
8747: Level: intermediate
8749: Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
8750: We should incorporate them into PETSc.
8752: .seealso: MatMatMult(), MatMatMultNumeric()
8753: @*/
8754: PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
8755: {
8757: PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*);
8758: PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*);
8759: PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL;
8764: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8765: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8769: MatCheckPreallocated(B,2);
8770: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8771: if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8774: if (B->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
8775: if (fill == PETSC_DEFAULT) fill = 2.0;
8776: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
8777: MatCheckPreallocated(A,1);
8779: Asymbolic = A->ops->matmultsymbolic;
8780: Bsymbolic = B->ops->matmultsymbolic;
8781: if (Asymbolic == Bsymbolic) {
8782: if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
8783: symbolic = Bsymbolic;
8784: } else { /* dispatch based on the type of A and B */
8785: char symbolicname[256];
8786: PetscStrcpy(symbolicname,"MatMatMultSymbolic_");
8787: PetscStrcat(symbolicname,((PetscObject)A)->type_name);
8788: PetscStrcat(symbolicname,"_");
8789: PetscStrcat(symbolicname,((PetscObject)B)->type_name);
8790: PetscStrcat(symbolicname,"_C");
8791: PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);
8792: if (!symbolic) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatMultSymbolic requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
8793: }
8794: PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);
8795: (*symbolic)(A,B,fill,C);
8796: PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);
8797: return(0);
8798: }
8802: /*@
8803: MatMatMultNumeric - Performs the numeric matrix-matrix product.
8804: Call this routine after first calling MatMatMultSymbolic().
8806: Neighbor-wise Collective on Mat
8808: Input Parameters:
8809: + A - the left matrix
8810: - B - the right matrix
8812: Output Parameters:
8813: . C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
8815: Notes:
8816: C must have been created with MatMatMultSymbolic().
8818: This routine is currently implemented for
8819: - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
8820: - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8821: - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
8823: Level: intermediate
8825: .seealso: MatMatMult(), MatMatMultSymbolic()
8826: @*/
8827: PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C)
8828: {
8832: MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);
8833: return(0);
8834: }
8838: /*@
8839: MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.
8841: Neighbor-wise Collective on Mat
8843: Input Parameters:
8844: + A - the left matrix
8845: . B - the right matrix
8846: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8847: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
8849: Output Parameters:
8850: . C - the product matrix
8852: Notes:
8853: C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
8855: MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8857: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8858: actually needed.
8860: This routine is currently only implemented for pairs of SeqAIJ matrices. C will be of type MATSEQAIJ.
8862: Level: intermediate
8864: .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
8865: @*/
8866: PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8867: {
8869: PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8870: PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8875: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8876: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8879: MatCheckPreallocated(B,2);
8880: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8881: if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8883: if (B->cmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, AN %D != BN %D",A->cmap->N,B->cmap->N);
8884: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8885: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
8886: MatCheckPreallocated(A,1);
8888: fA = A->ops->mattransposemult;
8889: if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
8890: fB = B->ops->mattransposemult;
8891: if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
8892: if (fB!=fA) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatTransposeMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
8894: PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);
8895: if (scall == MAT_INITIAL_MATRIX) {
8896: PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);
8897: (*A->ops->mattransposemultsymbolic)(A,B,fill,C);
8898: PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);
8899: }
8900: PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);
8901: (*A->ops->mattransposemultnumeric)(A,B,*C);
8902: PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);
8903: PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);
8904: return(0);
8905: }
8909: /*@
8910: MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.
8912: Neighbor-wise Collective on Mat
8914: Input Parameters:
8915: + A - the left matrix
8916: . B - the right matrix
8917: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8918: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
8920: Output Parameters:
8921: . C - the product matrix
8923: Notes:
8924: C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
8926: MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8928: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8929: actually needed.
8931: This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
8932: which inherit from SeqAIJ. C will be of same type as the input matrices.
8934: Level: intermediate
8936: .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
8937: @*/
8938: PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8939: {
8941: PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8942: PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8943: PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL;
8948: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8949: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8952: MatCheckPreallocated(B,2);
8953: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8954: if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8956: if (B->rmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->rmap->N);
8957: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8958: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
8959: MatCheckPreallocated(A,1);
8961: fA = A->ops->transposematmult;
8962: fB = B->ops->transposematmult;
8963: if (fB==fA) {
8964: if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
8965: transposematmult = fA;
8966: } else {
8967: /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
8968: char multname[256];
8969: PetscStrcpy(multname,"MatTransposeMatMult_");
8970: PetscStrcat(multname,((PetscObject)A)->type_name);
8971: PetscStrcat(multname,"_");
8972: PetscStrcat(multname,((PetscObject)B)->type_name);
8973: PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
8974: PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);
8975: if (!transposematmult) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatTransposeMatMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
8976: }
8977: PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);
8978: (*transposematmult)(A,B,scall,fill,C);
8979: PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);
8980: return(0);
8981: }
8985: /*@
8986: MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.
8988: Neighbor-wise Collective on Mat
8990: Input Parameters:
8991: + A - the left matrix
8992: . B - the middle matrix
8993: . C - the right matrix
8994: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8995: - fill - expected fill as ratio of nnz(D)/(nnz(A) + nnz(B)+nnz(C)), use PETSC_DEFAULT if you do not have a good estimate
8996: if the result is a dense matrix this is irrelevent
8998: Output Parameters:
8999: . D - the product matrix
9001: Notes:
9002: Unless scall is MAT_REUSE_MATRIX D will be created.
9004: MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call
9006: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9007: actually needed.
9009: If you have many matrices with the same non-zero structure to multiply, you
9010: should either
9011: $ 1) use MAT_REUSE_MATRIX in all calls but the first or
9012: $ 2) call MatMatMatMultSymbolic() once and then MatMatMatMultNumeric() for each product needed
9014: Level: intermediate
9016: .seealso: MatMatMult, MatPtAP()
9017: @*/
9018: PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
9019: {
9021: PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9022: PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9023: PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9024: PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9029: MatCheckPreallocated(A,1);
9030: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9031: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9034: MatCheckPreallocated(B,2);
9035: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9036: if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9039: MatCheckPreallocated(C,3);
9040: if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9041: if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9042: if (B->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
9043: if (C->rmap->N!=B->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",C->rmap->N,B->cmap->N);
9044: if (scall == MAT_REUSE_MATRIX) {
9047: PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);
9048: (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);
9049: PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);
9050: return(0);
9051: }
9052: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9053: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9055: fA = A->ops->matmatmult;
9056: fB = B->ops->matmatmult;
9057: fC = C->ops->matmatmult;
9058: if (fA == fB && fA == fC) {
9059: if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9060: mult = fA;
9061: } else {
9062: /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */
9063: char multname[256];
9064: PetscStrcpy(multname,"MatMatMatMult_");
9065: PetscStrcat(multname,((PetscObject)A)->type_name);
9066: PetscStrcat(multname,"_");
9067: PetscStrcat(multname,((PetscObject)B)->type_name);
9068: PetscStrcat(multname,"_");
9069: PetscStrcat(multname,((PetscObject)C)->type_name);
9070: PetscStrcat(multname,"_C");
9071: PetscObjectQueryFunction((PetscObject)B,multname,&mult);
9072: if (!mult) SETERRQ3(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatMatMult requires A, %s, to be compatible with B, %s, C, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name,((PetscObject)C)->type_name);
9073: }
9074: PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);
9075: (*mult)(A,B,C,scall,fill,D);
9076: PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);
9077: return(0);
9078: }
9082: /*@C
9083: MatGetRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
9085: Collective on Mat
9087: Input Parameters:
9088: + mat - the matrix
9089: . nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
9090: . subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used)
9091: - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9093: Output Parameter:
9094: . matredundant - redundant matrix
9096: Notes:
9097: MAT_REUSE_MATRIX can only be used when the nonzero structure of the
9098: original matrix has not changed from that last call to MatGetRedundantMatrix().
9100: This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
9101: calling it.
9103: Only MPIAIJ matrix is supported.
9105: Level: advanced
9107: Concepts: subcommunicator
9108: Concepts: duplicate matrix
9110: .seealso: MatDestroy()
9111: @*/
9112: PetscErrorCode MatGetRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant)
9113: {
9118: if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
9121: }
9122: if (!mat->ops->getredundantmatrix) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
9123: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9124: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9125: MatCheckPreallocated(mat,1);
9127: PetscLogEventBegin(MAT_GetRedundantMatrix,mat,0,0,0);
9128: (*mat->ops->getredundantmatrix)(mat,nsubcomm,subcomm,reuse,matredundant);
9129: PetscLogEventEnd(MAT_GetRedundantMatrix,mat,0,0,0);
9130: return(0);
9131: }
9135: /*@C
9136: MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
9137: a given 'mat' object. Each submatrix can span multiple procs.
9139: Collective on Mat
9141: Input Parameters:
9142: + mat - the matrix
9143: . subcomm - the subcommunicator obtained by com_split(comm)
9144: - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9146: Output Parameter:
9147: . subMat - 'parallel submatrices each spans a given subcomm
9149: Notes:
9150: The submatrix partition across processors is dictated by 'subComm' a
9151: communicator obtained by com_split(comm). The comm_split
9152: is not restriced to be grouped with consecutive original ranks.
9154: Due the comm_split() usage, the parallel layout of the submatrices
9155: map directly to the layout of the original matrix [wrt the local
9156: row,col partitioning]. So the original 'DiagonalMat' naturally maps
9157: into the 'DiagonalMat' of the subMat, hence it is used directly from
9158: the subMat. However the offDiagMat looses some columns - and this is
9159: reconstructed with MatSetValues()
9161: Level: advanced
9163: Concepts: subcommunicator
9164: Concepts: submatrices
9166: .seealso: MatGetSubMatrices()
9167: @*/
9168: PetscErrorCode MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
9169: {
9171: PetscMPIInt commsize,subCommSize;
9174: MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);
9175: MPI_Comm_size(subComm,&subCommSize);
9176: if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
9178: PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);
9179: (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);
9180: PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);
9181: return(0);
9182: }
9186: /*@
9187: MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
9189: Not Collective
9191: Input Arguments:
9192: mat - matrix to extract local submatrix from
9193: isrow - local row indices for submatrix
9194: iscol - local column indices for submatrix
9196: Output Arguments:
9197: submat - the submatrix
9199: Level: intermediate
9201: Notes:
9202: The submat should be returned with MatRestoreLocalSubMatrix().
9204: Depending on the format of mat, the returned submat may not implement MatMult(). Its communicator may be
9205: the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
9207: The submat always implements MatSetValuesLocal(). If isrow and iscol have the same block size, then
9208: MatSetValuesBlockedLocal() will also be implemented.
9210: .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef()
9211: @*/
9212: PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9213: {
9223: if (mat->ops->getlocalsubmatrix) {
9224: (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);
9225: } else {
9226: MatCreateLocalRef(mat,isrow,iscol,submat);
9227: }
9228: return(0);
9229: }
9233: /*@
9234: MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
9236: Not Collective
9238: Input Arguments:
9239: mat - matrix to extract local submatrix from
9240: isrow - local row indices for submatrix
9241: iscol - local column indices for submatrix
9242: submat - the submatrix
9244: Level: intermediate
9246: .seealso: MatGetLocalSubMatrix()
9247: @*/
9248: PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9249: {
9258: if (*submat) {
9260: }
9262: if (mat->ops->restorelocalsubmatrix) {
9263: (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);
9264: } else {
9265: MatDestroy(submat);
9266: }
9267: *submat = NULL;
9268: return(0);
9269: }
9271: /* --------------------------------------------------------*/
9274: /*@
9275: MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no entry in the matrix
9277: Collective on Mat
9279: Input Parameter:
9280: . mat - the matrix
9282: Output Parameter:
9283: . is - if any rows have zero diagonals this contains the list of them
9285: Level: developer
9287: Concepts: matrix-vector product
9289: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
9290: @*/
9291: PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is)
9292: {
9298: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9299: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9301: if (!mat->ops->findzerodiagonals) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find zero diagonals defined");
9302: (*mat->ops->findzerodiagonals)(mat,is);
9303: return(0);
9304: }
9308: /*@
9309: MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size)
9311: Collective on Mat
9313: Input Parameter:
9314: . mat - the matrix
9316: Output Parameter:
9317: . is - contains the list of rows with off block diagonal entries
9319: Level: developer
9321: Concepts: matrix-vector product
9323: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
9324: @*/
9325: PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is)
9326: {
9332: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9333: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9335: if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined");
9336: (*mat->ops->findoffblockdiagonalentries)(mat,is);
9337: return(0);
9338: }
9342: /*@C
9343: MatInvertBlockDiagonal - Inverts the block diagonal entries.
9345: Collective on Mat
9347: Input Parameters:
9348: . mat - the matrix
9350: Output Parameters:
9351: . values - the block inverses in column major order (FORTRAN-like)
9353: Note:
9354: This routine is not available from Fortran.
9356: Level: advanced
9357: @*/
9358: PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
9359: {
9364: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9365: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9366: if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
9367: (*mat->ops->invertblockdiagonal)(mat,values);
9368: return(0);
9369: }
9373: /*@C
9374: MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
9375: via MatTransposeColoringCreate().
9377: Collective on MatTransposeColoring
9379: Input Parameter:
9380: . c - coloring context
9382: Level: intermediate
9384: .seealso: MatTransposeColoringCreate()
9385: @*/
9386: PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c)
9387: {
9388: PetscErrorCode ierr;
9389: MatTransposeColoring matcolor=*c;
9392: if (!matcolor) return(0);
9393: if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; return(0);}
9395: PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);
9396: PetscFree(matcolor->rows);
9397: PetscFree(matcolor->den2sp);
9398: PetscFree(matcolor->colorforcol);
9399: PetscFree(matcolor->columns);
9400: if (matcolor->brows>0) {
9401: PetscFree(matcolor->lstart);
9402: }
9403: PetscHeaderDestroy(c);
9404: return(0);
9405: }
9409: /*@C
9410: MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
9411: a MatTransposeColoring context has been created, computes a dense B^T by Apply
9412: MatTransposeColoring to sparse B.
9414: Collective on MatTransposeColoring
9416: Input Parameters:
9417: + B - sparse matrix B
9418: . Btdense - symbolic dense matrix B^T
9419: - coloring - coloring context created with MatTransposeColoringCreate()
9421: Output Parameter:
9422: . Btdense - dense matrix B^T
9424: Options Database Keys:
9425: + -mat_transpose_coloring_view - Activates basic viewing or coloring
9426: . -mat_transpose_coloring_view_draw - Activates drawing of coloring
9427: - -mat_transpose_coloring_view_info - Activates viewing of coloring info
9429: Level: intermediate
9431: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy()
9433: .keywords: coloring
9434: @*/
9435: PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
9436: {
9444: if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
9445: (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);
9446: return(0);
9447: }
9451: /*@C
9452: MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
9453: a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
9454: in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
9455: Csp from Cden.
9457: Collective on MatTransposeColoring
9459: Input Parameters:
9460: + coloring - coloring context created with MatTransposeColoringCreate()
9461: - Cden - matrix product of a sparse matrix and a dense matrix Btdense
9463: Output Parameter:
9464: . Csp - sparse matrix
9466: Options Database Keys:
9467: + -mat_multtranspose_coloring_view - Activates basic viewing or coloring
9468: . -mat_multtranspose_coloring_view_draw - Activates drawing of coloring
9469: - -mat_multtranspose_coloring_view_info - Activates viewing of coloring info
9471: Level: intermediate
9473: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()
9475: .keywords: coloring
9476: @*/
9477: PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
9478: {
9486: if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
9487: (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);
9488: return(0);
9489: }
9493: /*@C
9494: MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.
9496: Collective on Mat
9498: Input Parameters:
9499: + mat - the matrix product C
9500: - iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring()
9502: Output Parameter:
9503: . color - the new coloring context
9505: Level: intermediate
9507: .seealso: MatTransposeColoringDestroy(), MatTransposeColoringSetFromOptions(), MatTransColoringApplySpToDen(),
9508: MatTransColoringApplyDenToSp(), MatTransposeColoringView(),
9509: @*/
9510: PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
9511: {
9512: MatTransposeColoring c;
9513: MPI_Comm comm;
9514: PetscErrorCode ierr;
9517: PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);
9518: PetscObjectGetComm((PetscObject)mat,&comm);
9519: PetscHeaderCreate(c,_p_MatTransposeColoring,int,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,0);
9521: c->ctype = iscoloring->ctype;
9522: if (mat->ops->transposecoloringcreate) {
9523: (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);
9524: } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type");
9526: *color = c;
9527: PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);
9528: return(0);
9529: }
9533: /*@
9534: MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the
9535: matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the
9536: same, otherwise it will be larger
9538: Not Collective
9540: Input Parameter:
9541: . A - the matrix
9543: Output Parameter:
9544: . state - the current state
9546: Notes: You can only compare states from two different calls to the SAME matrix, you cannot compare calls between
9547: different matrices
9549: Level: intermediate
9551: @*/
9552: PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state)
9553: {
9555: *state = mat->nonzerostate;
9556: return(0);
9557: }