Actual source code: matrix.c
2: /*
3: This is where the abstract matrix operations are defined
4: */
6: #include <private/matimpl.h> /*I "petscmat.h" I*/
7: #include <private/vecimpl.h>
9: /* Logging support */
10: PetscClassId MAT_CLASSID;
11: PetscClassId MAT_FDCOLORING_CLASSID;
13: PetscLogEvent MAT_Mult, MAT_Mults, MAT_MultConstrained, MAT_MultAdd, MAT_MultTranspose;
14: PetscLogEvent MAT_MultTransposeConstrained, MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve;
15: PetscLogEvent MAT_SolveTransposeAdd, MAT_SOR, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic;
16: PetscLogEvent MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor;
17: PetscLogEvent MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin;
18: PetscLogEvent MAT_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetRowIJ, MAT_GetSubMatrices, MAT_GetColoring, MAT_GetOrdering, MAT_GetRedundantMatrix, MAT_GetSeqNonzeroStructure;
19: PetscLogEvent MAT_IncreaseOverlap, MAT_Partitioning, MAT_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate;
20: PetscLogEvent MAT_FDColoringApply,MAT_Transpose,MAT_FDColoringFunction;
21: PetscLogEvent MAT_MatMult, MAT_MatMultSymbolic, MAT_MatMultNumeric;
22: PetscLogEvent MAT_PtAP, MAT_PtAPSymbolic, MAT_PtAPNumeric;
23: PetscLogEvent MAT_MatMultTranspose, MAT_MatMultTransposeSymbolic, MAT_MatMultTransposeNumeric;
24: PetscLogEvent MAT_MultHermitianTranspose,MAT_MultHermitianTransposeAdd;
25: PetscLogEvent MAT_Getsymtranspose, MAT_Getsymtransreduced, MAT_Transpose_SeqAIJ, MAT_GetBrowsOfAcols;
26: PetscLogEvent MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym;
27: PetscLogEvent MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure;
28: PetscLogEvent MAT_GetMultiProcBlock;
29: PetscLogEvent MAT_CUSPCopyToGPU, MAT_SetValuesBatch, MAT_SetValuesBatchI, MAT_SetValuesBatchII, MAT_SetValuesBatchIII, MAT_SetValuesBatchIV;
31: /* nasty global values for MatSetValue() */
32: PetscInt MatSetValue_Row = 0;
33: PetscInt MatSetValue_Column = 0;
34: PetscScalar MatSetValue_Value = 0.0;
36: const char *const MatFactorTypes[] = {"NONE","LU","CHOLESKY","ILU","ICC","ILUDT","MatFactorType","MAT_FACTOR_",0};
40: /*@C
41: MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix
43: Input Parameter:
44: . A - the matrix
46: Output Parameter:
47: . keptrows - the rows that are not completely zero
49: Level: intermediate
51: @*/
52: PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows)
53: {
54: PetscErrorCode ierr;
58: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
59: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
60: if (!mat->ops->findnonzerorows) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Not coded for this matrix type");
61: (*mat->ops->findnonzerorows)(mat,keptrows);
62: return(0);
63: }
67: /*@
68: MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling
70: Not Collective
72: Input Parameters:
73: . A - the matrix
75: Output Parameters:
76: . a - the diagonal part (which is a SEQUENTIAL matrix)
78: Notes: see the manual page for MatCreateMPIAIJ() for more information on the "diagonal part" of the matrix.
80: Level: advanced
82: @*/
83: PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a)
84: {
85: PetscErrorCode ierr,(*f)(Mat,Mat*);
86: PetscMPIInt size;
92: if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
93: if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
94: MPI_Comm_size(((PetscObject)A)->comm,&size);
95: PetscObjectQueryFunction((PetscObject)A,"MatGetDiagonalBlock_C",(void (**)(void))&f);
96: if (f) {
97: (*f)(A,a);
98: return(0);
99: } else if (size == 1) {
100: *a = A;
101: } else {
102: const MatType mattype;
103: MatGetType(A,&mattype);
104: SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix type %s does not support getting diagonal block",mattype);
105: }
106: return(0);
107: }
111: /*@
112: MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries.
114: Collective on Mat
116: Input Parameters:
117: . mat - the matrix
119: Output Parameter:
120: . trace - the sum of the diagonal entries
122: Level: advanced
124: @*/
125: PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace)
126: {
128: Vec diag;
131: MatGetVecs(mat,&diag,PETSC_NULL);
132: MatGetDiagonal(mat,diag);
133: VecSum(diag,trace);
134: VecDestroy(&diag);
135: return(0);
136: }
140: /*@
141: MatRealPart - Zeros out the imaginary part of the matrix
143: Logically Collective on Mat
145: Input Parameters:
146: . mat - the matrix
148: Level: advanced
151: .seealso: MatImaginaryPart()
152: @*/
153: PetscErrorCode MatRealPart(Mat mat)
154: {
160: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
161: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
162: if (!mat->ops->realpart) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
163: MatPreallocated(mat);
164: (*mat->ops->realpart)(mat);
165: #if defined(PETSC_HAVE_CUSP)
166: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
167: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
168: }
169: #endif
170: return(0);
171: }
175: /*@C
176: MatGetGhosts - Get the global index of all ghost nodes defined by the sparse matrix
178: Collective on Mat
180: Input Parameter:
181: . mat - the matrix
183: Output Parameters:
184: + nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block)
185: - ghosts - the global indices of the ghost points
187: Notes: the nghosts and ghosts are suitable to pass into VecCreateGhost()
189: Level: advanced
191: @*/
192: PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[])
193: {
199: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
200: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
201: if (!mat->ops->getghosts) {
202: if (nghosts) *nghosts = 0;
203: if (ghosts) *ghosts = 0;
204: } else {
205: (*mat->ops->getghosts)(mat,nghosts,ghosts);
206: }
207: return(0);
208: }
213: /*@
214: MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part
216: Logically Collective on Mat
218: Input Parameters:
219: . mat - the matrix
221: Level: advanced
224: .seealso: MatRealPart()
225: @*/
226: PetscErrorCode MatImaginaryPart(Mat mat)
227: {
233: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
234: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
235: if (!mat->ops->imaginarypart) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
236: MatPreallocated(mat);
237: (*mat->ops->imaginarypart)(mat);
238: #if defined(PETSC_HAVE_CUSP)
239: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
240: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
241: }
242: #endif
243: return(0);
244: }
248: /*@
249: MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices)
251: Collective on Mat
253: Input Parameter:
254: . mat - the matrix
256: Output Parameters:
257: + missing - is any diagonal missing
258: - dd - first diagonal entry that is missing (optional)
260: Level: advanced
263: .seealso: MatRealPart()
264: @*/
265: PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd)
266: {
272: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
273: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
274: if (!mat->ops->missingdiagonal) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
275: (*mat->ops->missingdiagonal)(mat,missing,dd);
276: return(0);
277: }
281: /*@C
282: MatGetRow - Gets a row of a matrix. You MUST call MatRestoreRow()
283: for each row that you get to ensure that your application does
284: not bleed memory.
286: Not Collective
288: Input Parameters:
289: + mat - the matrix
290: - row - the row to get
292: Output Parameters:
293: + ncols - if not NULL, the number of nonzeros in the row
294: . cols - if not NULL, the column numbers
295: - vals - if not NULL, the values
297: Notes:
298: This routine is provided for people who need to have direct access
299: to the structure of a matrix. We hope that we provide enough
300: high-level matrix routines that few users will need it.
302: MatGetRow() always returns 0-based column indices, regardless of
303: whether the internal representation is 0-based (default) or 1-based.
305: For better efficiency, set cols and/or vals to PETSC_NULL if you do
306: not wish to extract these quantities.
308: The user can only examine the values extracted with MatGetRow();
309: the values cannot be altered. To change the matrix entries, one
310: must use MatSetValues().
312: You can only have one call to MatGetRow() outstanding for a particular
313: matrix at a time, per processor. MatGetRow() can only obtain rows
314: associated with the given processor, it cannot get rows from the
315: other processors; for that we suggest using MatGetSubMatrices(), then
316: MatGetRow() on the submatrix. The row indix passed to MatGetRows()
317: is in the global number of rows.
319: Fortran Notes:
320: The calling sequence from Fortran is
321: .vb
322: MatGetRow(matrix,row,ncols,cols,values,ierr)
323: Mat matrix (input)
324: integer row (input)
325: integer ncols (output)
326: integer cols(maxcols) (output)
327: double precision (or double complex) values(maxcols) output
328: .ve
329: where maxcols >= maximum nonzeros in any row of the matrix.
332: Caution:
333: Do not try to change the contents of the output arrays (cols and vals).
334: In some cases, this may corrupt the matrix.
336: Level: advanced
338: Concepts: matrices^row access
340: .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatGetSubMatrices(), MatGetDiagonal()
341: @*/
342: PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
343: {
345: PetscInt incols;
350: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
351: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
352: if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
353: MatPreallocated(mat);
354: PetscLogEventBegin(MAT_GetRow,mat,0,0,0);
355: (*mat->ops->getrow)(mat,row,&incols,(PetscInt **)cols,(PetscScalar **)vals);
356: if (ncols) *ncols = incols;
357: PetscLogEventEnd(MAT_GetRow,mat,0,0,0);
358: return(0);
359: }
363: /*@
364: MatConjugate - replaces the matrix values with their complex conjugates
366: Logically Collective on Mat
368: Input Parameters:
369: . mat - the matrix
371: Level: advanced
373: .seealso: VecConjugate()
374: @*/
375: PetscErrorCode MatConjugate(Mat mat)
376: {
381: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
382: if (!mat->ops->conjugate) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Not provided for this matrix format, send email to petsc-maint@mcs.anl.gov");
383: (*mat->ops->conjugate)(mat);
384: #if defined(PETSC_HAVE_CUSP)
385: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
386: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
387: }
388: #endif
389: return(0);
390: }
394: /*@C
395: MatRestoreRow - Frees any temporary space allocated by MatGetRow().
397: Not Collective
399: Input Parameters:
400: + mat - the matrix
401: . row - the row to get
402: . ncols, cols - the number of nonzeros and their columns
403: - vals - if nonzero the column values
405: Notes:
406: This routine should be called after you have finished examining the entries.
408: Fortran Notes:
409: The calling sequence from Fortran is
410: .vb
411: MatRestoreRow(matrix,row,ncols,cols,values,ierr)
412: Mat matrix (input)
413: integer row (input)
414: integer ncols (output)
415: integer cols(maxcols) (output)
416: double precision (or double complex) values(maxcols) output
417: .ve
418: Where maxcols >= maximum nonzeros in any row of the matrix.
420: In Fortran MatRestoreRow() MUST be called after MatGetRow()
421: before another call to MatGetRow() can be made.
423: Level: advanced
425: .seealso: MatGetRow()
426: @*/
427: PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
428: {
434: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
435: if (!mat->ops->restorerow) return(0);
436: (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);
437: return(0);
438: }
442: /*@
443: MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format.
444: You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag.
446: Not Collective
448: Input Parameters:
449: + mat - the matrix
451: Notes:
452: 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.
454: Level: advanced
456: Concepts: matrices^row access
458: .seealso: MatRestoreRowRowUpperTriangular()
459: @*/
460: PetscErrorCode MatGetRowUpperTriangular(Mat mat)
461: {
467: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
468: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
469: if (!mat->ops->getrowuppertriangular) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
470: MatPreallocated(mat);
471: (*mat->ops->getrowuppertriangular)(mat);
472: return(0);
473: }
477: /*@
478: MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format.
480: Not Collective
482: Input Parameters:
483: + mat - the matrix
485: Notes:
486: This routine should be called after you have finished MatGetRow/MatRestoreRow().
489: Level: advanced
491: .seealso: MatGetRowUpperTriangular()
492: @*/
493: PetscErrorCode MatRestoreRowUpperTriangular(Mat mat)
494: {
499: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
500: if (!mat->ops->restorerowuppertriangular) return(0);
501: (*mat->ops->restorerowuppertriangular)(mat);
502: return(0);
503: }
507: /*@C
508: MatSetOptionsPrefix - Sets the prefix used for searching for all
509: Mat options in the database.
511: Logically Collective on Mat
513: Input Parameter:
514: + A - the Mat context
515: - prefix - the prefix to prepend to all option names
517: Notes:
518: A hyphen (-) must NOT be given at the beginning of the prefix name.
519: The first character of all runtime options is AUTOMATICALLY the hyphen.
521: Level: advanced
523: .keywords: Mat, set, options, prefix, database
525: .seealso: MatSetFromOptions()
526: @*/
527: PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[])
528: {
533: PetscObjectSetOptionsPrefix((PetscObject)A,prefix);
534: return(0);
535: }
539: /*@C
540: MatAppendOptionsPrefix - Appends to the prefix used for searching for all
541: Mat options in the database.
543: Logically Collective on Mat
545: Input Parameters:
546: + A - the Mat context
547: - prefix - the prefix to prepend to all option names
549: Notes:
550: A hyphen (-) must NOT be given at the beginning of the prefix name.
551: The first character of all runtime options is AUTOMATICALLY the hyphen.
553: Level: advanced
555: .keywords: Mat, append, options, prefix, database
557: .seealso: MatGetOptionsPrefix()
558: @*/
559: PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[])
560: {
562:
565: PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);
566: return(0);
567: }
571: /*@C
572: MatGetOptionsPrefix - Sets the prefix used for searching for all
573: Mat options in the database.
575: Not Collective
577: Input Parameter:
578: . A - the Mat context
580: Output Parameter:
581: . prefix - pointer to the prefix string used
583: Notes: On the fortran side, the user should pass in a string 'prefix' of
584: sufficient length to hold the prefix.
586: Level: advanced
588: .keywords: Mat, get, options, prefix, database
590: .seealso: MatAppendOptionsPrefix()
591: @*/
592: PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[])
593: {
598: PetscObjectGetOptionsPrefix((PetscObject)A,prefix);
599: return(0);
600: }
604: /*@
605: MatSetUp - Sets up the internal matrix data structures for the later use.
607: Collective on Mat
609: Input Parameters:
610: . A - the Mat context
612: Notes:
613: For basic use of the Mat classes the user need not explicitly call
614: MatSetUp(), since these actions will happen automatically.
616: Level: advanced
618: .keywords: Mat, setup
620: .seealso: MatCreate(), MatDestroy()
621: @*/
622: PetscErrorCode MatSetUp(Mat A)
623: {
624: PetscMPIInt size;
629: if (!((PetscObject)A)->type_name) {
630: MPI_Comm_size(((PetscObject)A)->comm, &size);
631: if (size == 1) {
632: MatSetType(A, MATSEQAIJ);
633: } else {
634: MatSetType(A, MATMPIAIJ);
635: }
636: }
637: MatSetUpPreallocation(A);
638: return(0);
639: }
644: /*@C
645: MatView - Visualizes a matrix object.
647: Collective on Mat
649: Input Parameters:
650: + mat - the matrix
651: - viewer - visualization context
653: Notes:
654: The available visualization contexts include
655: + PETSC_VIEWER_STDOUT_SELF - standard output (default)
656: . PETSC_VIEWER_STDOUT_WORLD - synchronized standard
657: output where only the first processor opens
658: the file. All other processors send their
659: data to the first processor to print.
660: - PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure
662: The user can open alternative visualization contexts with
663: + PetscViewerASCIIOpen() - Outputs matrix to a specified file
664: . PetscViewerBinaryOpen() - Outputs matrix in binary to a
665: specified file; corresponding input uses MatLoad()
666: . PetscViewerDrawOpen() - Outputs nonzero matrix structure to
667: an X window display
668: - PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
669: Currently only the sequential dense and AIJ
670: matrix types support the Socket viewer.
672: The user can call PetscViewerSetFormat() to specify the output
673: format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
674: PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen). Available formats include
675: + PETSC_VIEWER_DEFAULT - default, prints matrix contents
676: . PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
677: . PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
678: . PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse
679: format common among all matrix types
680: . PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific
681: format (which is in many cases the same as the default)
682: . PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
683: size and structure (not the matrix entries)
684: . PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about
685: the matrix structure
687: Options Database Keys:
688: + -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly()
689: . -mat_view_info_detailed - Prints more detailed info
690: . -mat_view - Prints matrix in ASCII format
691: . -mat_view_matlab - Prints matrix in Matlab format
692: . -mat_view_draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
693: . -display <name> - Sets display name (default is host)
694: . -draw_pause <sec> - Sets number of seconds to pause after display
695: . -mat_view_socket - Sends matrix to socket, can be accessed from Matlab (see the <a href="../../docs/manual.pdf">users manual</a> for details).
696: . -viewer_socket_machine <machine>
697: . -viewer_socket_port <port>
698: . -mat_view_binary - save matrix to file in binary format
699: - -viewer_binary_filename <name>
700: Level: beginner
702: Notes: see the manual page for MatLoad() for the exact format of the binary file when the binary
703: viewer is used.
705: See bin/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary
706: viewer is used.
708: Concepts: matrices^viewing
709: Concepts: matrices^plotting
710: Concepts: matrices^printing
712: .seealso: PetscViewerSetFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(),
713: PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
714: @*/
715: PetscErrorCode MatView(Mat mat,PetscViewer viewer)
716: {
717: PetscErrorCode ierr;
718: PetscInt rows,cols;
719: PetscBool iascii;
720: PetscViewerFormat format;
725: if (!viewer) {
726: PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
727: }
730: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
731: MatPreallocated(mat);
733: PetscLogEventBegin(MAT_View,mat,viewer,0,0);
734: PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
735: if (iascii) {
736: PetscViewerGetFormat(viewer,&format);
737: if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
738: PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer,"Matrix Object");
739: PetscViewerASCIIPushTab(viewer);
740: MatGetSize(mat,&rows,&cols);
741: PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);
742: if (mat->factortype) {
743: const MatSolverPackage solver;
744: MatFactorGetSolverPackage(mat,&solver);
745: PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);
746: }
747: if (mat->ops->getinfo) {
748: MatInfo info;
749: MatGetInfo(mat,MAT_GLOBAL_SUM,&info);
750: PetscViewerASCIIPrintf(viewer,"total: nonzeros=%D, allocated nonzeros=%D\n",(PetscInt)info.nz_used,(PetscInt)info.nz_allocated);
751: PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls =%D\n",(PetscInt)info.mallocs);
752: }
753: }
754: }
755: if (mat->ops->view) {
756: PetscViewerASCIIPushTab(viewer);
757: (*mat->ops->view)(mat,viewer);
758: PetscViewerASCIIPopTab(viewer);
759: } else if (!iascii) {
760: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Viewer type %s not supported",((PetscObject)viewer)->type_name);
761: }
762: if (iascii) {
763: PetscViewerGetFormat(viewer,&format);
764: if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
765: PetscViewerASCIIPopTab(viewer);
766: }
767: }
768: PetscLogEventEnd(MAT_View,mat,viewer,0,0);
769: return(0);
770: }
772: #if defined(PETSC_USE_DEBUG)
773: #include <../src/sys/totalview/tv_data_display.h>
774: PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat)
775: {
776: TV_add_row("Local rows", "int", &mat->rmap->n);
777: TV_add_row("Local columns", "int", &mat->cmap->n);
778: TV_add_row("Global rows", "int", &mat->rmap->N);
779: TV_add_row("Global columns", "int", &mat->cmap->N);
780: TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name);
781: return TV_format_OK;
782: }
783: #endif
787: /*@C
788: MatLoad - Loads a matrix that has been stored in binary format
789: with MatView(). The matrix format is determined from the options database.
790: Generates a parallel MPI matrix if the communicator has more than one
791: processor. The default matrix type is AIJ.
793: Collective on PetscViewer
795: Input Parameters:
796: + newmat - the newly loaded matrix, this needs to have been created with MatCreate()
797: or some related function before a call to MatLoad()
798: - viewer - binary file viewer, created with PetscViewerBinaryOpen()
800: Options Database Keys:
801: Used with block matrix formats (MATSEQBAIJ, ...) to specify
802: block size
803: . -matload_block_size <bs>
805: Level: beginner
807: Notes:
808: If the Mat type has not yet been given then MATAIJ is used, call MatSetFromOptions() on the
809: Mat before calling this routine if you wish to set it from the options database.
811: MatLoad() automatically loads into the options database any options
812: given in the file filename.info where filename is the name of the file
813: that was passed to the PetscViewerBinaryOpen(). The options in the info
814: file will be ignored if you use the -viewer_binary_skip_info option.
816: If the type or size of newmat is not set before a call to MatLoad, PETSc
817: sets the default matrix type AIJ and sets the local and global sizes.
818: If type and/or size is already set, then the same are used.
820: In parallel, each processor can load a subset of rows (or the
821: entire matrix). This routine is especially useful when a large
822: matrix is stored on disk and only part of it is desired on each
823: processor. For example, a parallel solver may access only some of
824: the rows from each processor. The algorithm used here reads
825: relatively small blocks of data rather than reading the entire
826: matrix and then subsetting it.
828: Notes for advanced users:
829: Most users should not need to know the details of the binary storage
830: format, since MatLoad() and MatView() completely hide these details.
831: But for anyone who's interested, the standard binary matrix storage
832: format is
834: $ int MAT_FILE_CLASSID
835: $ int number of rows
836: $ int number of columns
837: $ int total number of nonzeros
838: $ int *number nonzeros in each row
839: $ int *column indices of all nonzeros (starting index is zero)
840: $ PetscScalar *values of all nonzeros
842: PETSc automatically does the byte swapping for
843: machines that store the bytes reversed, e.g. DEC alpha, freebsd,
844: linux, Windows and the paragon; thus if you write your own binary
845: read/write routines you have to swap the bytes; see PetscBinaryRead()
846: and PetscBinaryWrite() to see how this may be done.
848: .keywords: matrix, load, binary, input
850: .seealso: PetscViewerBinaryOpen(), MatView(), VecLoad()
852: @*/
853: PetscErrorCode MatLoad(Mat newmat,PetscViewer viewer)
854: {
856: PetscBool isbinary,flg;
861: PetscTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);
862: if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()");
864: if (!((PetscObject)newmat)->type_name) {
865: MatSetType(newmat,MATAIJ);
866: }
868: if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type");
869: PetscLogEventBegin(MAT_Load,viewer,0,0,0);
870: (*newmat->ops->load)(newmat,viewer);
871: PetscLogEventEnd(MAT_Load,viewer,0,0,0);
873: flg = PETSC_FALSE;
874: PetscOptionsGetBool(((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,PETSC_NULL);
875: if (flg) {
876: MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);
877: MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);
878: }
879: flg = PETSC_FALSE;
880: PetscOptionsGetBool(((PetscObject)newmat)->prefix,"-matload_spd",&flg,PETSC_NULL);
881: if (flg) {
882: MatSetOption(newmat,MAT_SPD,PETSC_TRUE);
883: }
884: return(0);
885: }
889: /*@
890: MatScaleSystem - Scale a vector solution and right hand side to
891: match the scaling of a scaled matrix.
892:
893: Collective on Mat
895: Input Parameter:
896: + mat - the matrix
897: . b - right hand side vector (or PETSC_NULL)
898: - x - solution vector (or PETSC_NULL)
901: Notes:
902: For AIJ, and BAIJ matrix formats, the matrices are not
903: internally scaled, so this does nothing.
905: The KSP methods automatically call this routine when required
906: (via PCPreSolve()) so it is rarely used directly.
908: Level: Developer
910: Concepts: matrices^scaling
912: .seealso: MatUseScaledForm(), MatUnScaleSystem()
913: @*/
914: PetscErrorCode MatScaleSystem(Mat mat,Vec b,Vec x)
915: {
921: MatPreallocated(mat);
925: if (mat->ops->scalesystem) {
926: (*mat->ops->scalesystem)(mat,b,x);
927: }
928: return(0);
929: }
933: /*@
934: MatUnScaleSystem - Unscales a vector solution and right hand side to
935: match the original scaling of a scaled matrix.
936:
937: Collective on Mat
939: Input Parameter:
940: + mat - the matrix
941: . b - right hand side vector (or PETSC_NULL)
942: - x - solution vector (or PETSC_NULL)
945: Notes:
946: For AIJ and BAIJ matrix formats, the matrices are not
947: internally scaled, so this does nothing.
949: The KSP methods automatically call this routine when required
950: (via PCPreSolve()) so it is rarely used directly.
952: Level: Developer
954: .seealso: MatUseScaledForm(), MatScaleSystem()
955: @*/
956: PetscErrorCode MatUnScaleSystem(Mat mat,Vec b,Vec x)
957: {
963: MatPreallocated(mat);
966: if (mat->ops->unscalesystem) {
967: (*mat->ops->unscalesystem)(mat,b,x);
968: }
969: return(0);
970: }
974: /*@
975: MatUseScaledForm - For matrix storage formats that scale the
976: matrix indicates matrix operations (MatMult() etc) are
977: applied using the scaled matrix.
978:
979: Logically Collective on Mat
981: Input Parameter:
982: + mat - the matrix
983: - scaled - PETSC_TRUE for applying the scaled, PETSC_FALSE for
984: applying the original matrix
986: Notes:
987: For scaled matrix formats, applying the original, unscaled matrix
988: will be slightly more expensive
990: Level: Developer
992: .seealso: MatScaleSystem(), MatUnScaleSystem()
993: @*/
994: PetscErrorCode MatUseScaledForm(Mat mat,PetscBool scaled)
995: {
1002: MatPreallocated(mat);
1003: if (mat->ops->usescaledform) {
1004: (*mat->ops->usescaledform)(mat,scaled);
1005: }
1006: return(0);
1007: }
1011: /*@
1012: MatDestroy - Frees space taken by a matrix.
1014: Collective on Mat
1016: Input Parameter:
1017: . A - the matrix
1019: Level: beginner
1021: @*/
1022: PetscErrorCode MatDestroy(Mat *A)
1023: {
1027: if (!*A) return(0);
1029: if (--((PetscObject)(*A))->refct > 0) {*A = PETSC_NULL; return(0);}
1031: /* if memory was published with AMS then destroy it */
1032: PetscObjectDepublish(*A);
1034: if ((*A)->ops->destroy) {
1035: (*(*A)->ops->destroy)(*A);
1036: }
1038: MatNullSpaceDestroy(&(*A)->nullsp);
1039: PetscLayoutDestroy(&(*A)->rmap);
1040: PetscLayoutDestroy(&(*A)->cmap);
1041: PetscHeaderDestroy(A);
1042: return(0);
1043: }
1047: /*@
1048: MatSetValues - Inserts or adds a block of values into a matrix.
1049: These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1050: MUST be called after all calls to MatSetValues() have been completed.
1052: Not Collective
1054: Input Parameters:
1055: + mat - the matrix
1056: . v - a logically two-dimensional array of values
1057: . m, idxm - the number of rows and their global indices
1058: . n, idxn - the number of columns and their global indices
1059: - addv - either ADD_VALUES or INSERT_VALUES, where
1060: ADD_VALUES adds values to any existing entries, and
1061: INSERT_VALUES replaces existing entries with new values
1063: Notes:
1064: By default the values, v, are row-oriented. See MatSetOption() for other options.
1066: Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
1067: options cannot be mixed without intervening calls to the assembly
1068: routines.
1070: MatSetValues() uses 0-based row and column numbers in Fortran
1071: as well as in C.
1073: Negative indices may be passed in idxm and idxn, these rows and columns are
1074: simply ignored. This allows easily inserting element stiffness matrices
1075: with homogeneous Dirchlet boundary conditions that you don't want represented
1076: in the matrix.
1078: Efficiency Alert:
1079: The routine MatSetValuesBlocked() may offer much better efficiency
1080: for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1082: Level: beginner
1084: Concepts: matrices^putting entries in
1086: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1087: InsertMode, INSERT_VALUES, ADD_VALUES
1088: @*/
1089: PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1090: {
1096: if (!m || !n) return(0); /* no values to insert */
1100: MatPreallocated(mat);
1101: if (mat->insertmode == NOT_SET_VALUES) {
1102: mat->insertmode = addv;
1103: }
1104: #if defined(PETSC_USE_DEBUG)
1105: else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1106: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1107: if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1108: #endif
1110: if (mat->assembled) {
1111: mat->was_assembled = PETSC_TRUE;
1112: mat->assembled = PETSC_FALSE;
1113: }
1114: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1115: (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);
1116: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1117: #if defined(PETSC_HAVE_CUSP)
1118: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1119: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1120: }
1121: #endif
1122: return(0);
1123: }
1128: /*@
1129: MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
1130: values into a matrix
1132: Not Collective
1134: Input Parameters:
1135: + mat - the matrix
1136: . row - the (block) row to set
1137: - v - a logically two-dimensional array of values
1139: Notes:
1140: By the values, v, are column-oriented (for the block version) and sorted
1142: All the nonzeros in the row must be provided
1144: The matrix must have previously had its column indices set
1146: The row must belong to this process
1148: Level: intermediate
1150: Concepts: matrices^putting entries in
1152: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1153: InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping()
1154: @*/
1155: PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
1156: {
1163: MatSetValuesRow(mat, mat->rmap->mapping->indices[row],v);
1164: #if defined(PETSC_HAVE_CUSP)
1165: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1166: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1167: }
1168: #endif
1169: return(0);
1170: }
1174: /*@
1175: MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
1176: values into a matrix
1178: Not Collective
1180: Input Parameters:
1181: + mat - the matrix
1182: . row - the (block) row to set
1183: - v - a logically two-dimensional array of values
1185: Notes:
1186: The values, v, are column-oriented for the block version.
1188: All the nonzeros in the row must be provided
1190: THE MATRIX MUSAT HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually MatSetValues() is used.
1192: The row must belong to this process
1194: Level: advanced
1196: Concepts: matrices^putting entries in
1198: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1199: InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1200: @*/
1201: PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
1202: {
1209: #if defined(PETSC_USE_DEBUG)
1210: if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
1211: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1212: #endif
1213: mat->insertmode = INSERT_VALUES;
1215: if (mat->assembled) {
1216: mat->was_assembled = PETSC_TRUE;
1217: mat->assembled = PETSC_FALSE;
1218: }
1219: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1220: if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1221: (*mat->ops->setvaluesrow)(mat,row,v);
1222: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1223: #if defined(PETSC_HAVE_CUSP)
1224: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1225: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1226: }
1227: #endif
1228: return(0);
1229: }
1233: /*@
1234: MatSetValuesStencil - Inserts or adds a block of values into a matrix.
1235: Using structured grid indexing
1237: Not Collective
1239: Input Parameters:
1240: + mat - the matrix
1241: . m - number of rows being entered
1242: . idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
1243: . n - number of columns being entered
1244: . idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered
1245: . v - a logically two-dimensional array of values
1246: - addv - either ADD_VALUES or INSERT_VALUES, where
1247: ADD_VALUES adds values to any existing entries, and
1248: INSERT_VALUES replaces existing entries with new values
1250: Notes:
1251: By default the values, v, are row-oriented. See MatSetOption() for other options.
1253: Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
1254: options cannot be mixed without intervening calls to the assembly
1255: routines.
1257: The grid coordinates are across the entire grid, not just the local portion
1259: MatSetValuesStencil() uses 0-based row and column numbers in Fortran
1260: as well as in C.
1262: For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1264: In order to use this routine you must either obtain the matrix with DMGetMatrix()
1265: or call MatSetLocalToGlobalMapping() and MatSetStencil() first.
1267: The columns and rows in the stencil passed in MUST be contained within the
1268: ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1269: if you create a DMDA with an overlap of one grid level and on a particular process its first
1270: local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1271: first i index you can use in your column and row indices in MatSetStencil() is 5.
1273: In Fortran idxm and idxn should be declared as
1274: $ MatStencil idxm(4,m),idxn(4,n)
1275: and the values inserted using
1276: $ idxm(MatStencil_i,1) = i
1277: $ idxm(MatStencil_j,1) = j
1278: $ idxm(MatStencil_k,1) = k
1279: $ idxm(MatStencil_c,1) = c
1280: etc
1281:
1282: For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
1283: obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
1284: etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
1285: DMDA_BOUNDARY_PERIODIC boundary type.
1287: 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
1288: a single value per point) you can skip filling those indices.
1290: Inspired by the structured grid interface to the HYPRE package
1291: (http://www.llnl.gov/CASC/hypre)
1293: Efficiency Alert:
1294: The routine MatSetValuesBlockedStencil() may offer much better efficiency
1295: for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1297: Level: beginner
1299: Concepts: matrices^putting entries in
1301: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1302: MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMGetMatrix(), DMDAVecGetArray(), MatStencil
1303: @*/
1304: PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1305: {
1307: PetscInt buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1308: PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1309: PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1312: if (!m || !n) return(0); /* no values to insert */
1319: if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1320: jdxm = buf; jdxn = buf+m;
1321: } else {
1322: PetscMalloc2(m,PetscInt,&bufm,n,PetscInt,&bufn);
1323: jdxm = bufm; jdxn = bufn;
1324: }
1325: for (i=0; i<m; i++) {
1326: for (j=0; j<3-sdim; j++) dxm++;
1327: tmp = *dxm++ - starts[0];
1328: for (j=0; j<dim-1; j++) {
1329: if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1330: else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1331: }
1332: if (mat->stencil.noc) dxm++;
1333: jdxm[i] = tmp;
1334: }
1335: for (i=0; i<n; i++) {
1336: for (j=0; j<3-sdim; j++) dxn++;
1337: tmp = *dxn++ - starts[0];
1338: for (j=0; j<dim-1; j++) {
1339: if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1340: else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1341: }
1342: if (mat->stencil.noc) dxn++;
1343: jdxn[i] = tmp;
1344: }
1345: MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);
1346: PetscFree2(bufm,bufn);
1347: return(0);
1348: }
1352: /*@C
1353: MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1354: Using structured grid indexing
1356: Not Collective
1358: Input Parameters:
1359: + mat - the matrix
1360: . m - number of rows being entered
1361: . idxm - grid coordinates for matrix rows being entered
1362: . n - number of columns being entered
1363: . idxn - grid coordinates for matrix columns being entered
1364: . v - a logically two-dimensional array of values
1365: - addv - either ADD_VALUES or INSERT_VALUES, where
1366: ADD_VALUES adds values to any existing entries, and
1367: INSERT_VALUES replaces existing entries with new values
1369: Notes:
1370: By default the values, v, are row-oriented and unsorted.
1371: See MatSetOption() for other options.
1373: Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
1374: options cannot be mixed without intervening calls to the assembly
1375: routines.
1377: The grid coordinates are across the entire grid, not just the local portion
1379: MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran
1380: as well as in C.
1382: For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1384: In order to use this routine you must either obtain the matrix with DMGetMatrix()
1385: or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first.
1387: The columns and rows in the stencil passed in MUST be contained within the
1388: ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1389: if you create a DMDA with an overlap of one grid level and on a particular process its first
1390: local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1391: first i index you can use in your column and row indices in MatSetStencil() is 5.
1393: In Fortran idxm and idxn should be declared as
1394: $ MatStencil idxm(4,m),idxn(4,n)
1395: and the values inserted using
1396: $ idxm(MatStencil_i,1) = i
1397: $ idxm(MatStencil_j,1) = j
1398: $ idxm(MatStencil_k,1) = k
1399: etc
1401: Negative indices may be passed in idxm and idxn, these rows and columns are
1402: simply ignored. This allows easily inserting element stiffness matrices
1403: with homogeneous Dirchlet boundary conditions that you don't want represented
1404: in the matrix.
1406: Inspired by the structured grid interface to the HYPRE package
1407: (http://www.llnl.gov/CASC/hypre)
1409: Level: beginner
1411: Concepts: matrices^putting entries in
1413: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1414: MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMGetMatrix(), DMDAVecGetArray(), MatStencil,
1415: MatSetBlockSize(), MatSetLocalToGlobalMapping()
1416: @*/
1417: PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1418: {
1420: PetscInt buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1421: PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1422: PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1425: if (!m || !n) return(0); /* no values to insert */
1432: if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1433: jdxm = buf; jdxn = buf+m;
1434: } else {
1435: PetscMalloc2(m,PetscInt,&bufm,n,PetscInt,&bufn);
1436: jdxm = bufm; jdxn = bufn;
1437: }
1438: for (i=0; i<m; i++) {
1439: for (j=0; j<3-sdim; j++) dxm++;
1440: tmp = *dxm++ - starts[0];
1441: for (j=0; j<sdim-1; j++) {
1442: if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1443: else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1444: }
1445: dxm++;
1446: jdxm[i] = tmp;
1447: }
1448: for (i=0; i<n; i++) {
1449: for (j=0; j<3-sdim; j++) dxn++;
1450: tmp = *dxn++ - starts[0];
1451: for (j=0; j<sdim-1; j++) {
1452: if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1453: else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1454: }
1455: dxn++;
1456: jdxn[i] = tmp;
1457: }
1458: MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);
1459: PetscFree2(bufm,bufn);
1460: #if defined(PETSC_HAVE_CUSP)
1461: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1462: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1463: }
1464: #endif
1465: return(0);
1466: }
1470: /*@
1471: MatSetStencil - Sets the grid information for setting values into a matrix via
1472: MatSetValuesStencil()
1474: Not Collective
1476: Input Parameters:
1477: + mat - the matrix
1478: . dim - dimension of the grid 1, 2, or 3
1479: . dims - number of grid points in x, y, and z direction, including ghost points on your processor
1480: . starts - starting point of ghost nodes on your processor in x, y, and z direction
1481: - dof - number of degrees of freedom per node
1484: Inspired by the structured grid interface to the HYPRE package
1485: (www.llnl.gov/CASC/hyper)
1487: For matrices generated with DMGetMatrix() this routine is automatically called and so not needed by the
1488: user.
1489:
1490: Level: beginner
1492: Concepts: matrices^putting entries in
1494: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1495: MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
1496: @*/
1497: PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1498: {
1499: PetscInt i;
1506: mat->stencil.dim = dim + (dof > 1);
1507: for (i=0; i<dim; i++) {
1508: mat->stencil.dims[i] = dims[dim-i-1]; /* copy the values in backwards */
1509: mat->stencil.starts[i] = starts[dim-i-1];
1510: }
1511: mat->stencil.dims[dim] = dof;
1512: mat->stencil.starts[dim] = 0;
1513: mat->stencil.noc = (PetscBool)(dof == 1);
1514: return(0);
1515: }
1519: /*@
1520: MatSetValuesBlocked - Inserts or adds a block of values into a matrix.
1522: Not Collective
1524: Input Parameters:
1525: + mat - the matrix
1526: . v - a logically two-dimensional array of values
1527: . m, idxm - the number of block rows and their global block indices
1528: . n, idxn - the number of block columns and their global block indices
1529: - addv - either ADD_VALUES or INSERT_VALUES, where
1530: ADD_VALUES adds values to any existing entries, and
1531: INSERT_VALUES replaces existing entries with new values
1533: Notes:
1534: The m and n count the NUMBER of blocks in the row direction and column direction,
1535: NOT the total number of rows/columns; for example, if the block size is 2 and
1536: you are passing in values for rows 2,3,4,5 then m would be 2 (not 4).
1537: The values in idxm would be 1 2; that is the first index for each block divided by
1538: the block size.
1540: Note that you must call MatSetBlockSize() when constructing this matrix (after
1541: preallocating it).
1543: By default the values, v, are row-oriented, so the layout of
1544: v is the same as for MatSetValues(). See MatSetOption() for other options.
1546: Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
1547: options cannot be mixed without intervening calls to the assembly
1548: routines.
1550: MatSetValuesBlocked() uses 0-based row and column numbers in Fortran
1551: as well as in C.
1553: Negative indices may be passed in idxm and idxn, these rows and columns are
1554: simply ignored. This allows easily inserting element stiffness matrices
1555: with homogeneous Dirchlet boundary conditions that you don't want represented
1556: in the matrix.
1558: Each time an entry is set within a sparse matrix via MatSetValues(),
1559: internal searching must be done to determine where to place the the
1560: data in the matrix storage space. By instead inserting blocks of
1561: entries via MatSetValuesBlocked(), the overhead of matrix assembly is
1562: reduced.
1564: Example:
1565: $ Suppose m=n=2 and block size(bs) = 2 The array is
1566: $
1567: $ 1 2 | 3 4
1568: $ 5 6 | 7 8
1569: $ - - - | - - -
1570: $ 9 10 | 11 12
1571: $ 13 14 | 15 16
1572: $
1573: $ v[] should be passed in like
1574: $ v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
1575: $
1576: $ If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then
1577: $ v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16]
1579: Level: intermediate
1581: Concepts: matrices^putting entries in blocked
1583: .seealso: MatSetBlockSize(), MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal()
1584: @*/
1585: PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1586: {
1592: if (!m || !n) return(0); /* no values to insert */
1596: MatPreallocated(mat);
1597: if (mat->insertmode == NOT_SET_VALUES) {
1598: mat->insertmode = addv;
1599: }
1600: #if defined(PETSC_USE_DEBUG)
1601: else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1602: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1603: if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1604: #endif
1606: if (mat->assembled) {
1607: mat->was_assembled = PETSC_TRUE;
1608: mat->assembled = PETSC_FALSE;
1609: }
1610: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1611: if (mat->ops->setvaluesblocked) {
1612: (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);
1613: } else {
1614: PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn;
1615: PetscInt i,j,bs=mat->rmap->bs;
1616: if ((m+n)*bs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1617: iidxm = buf; iidxn = buf + m*bs;
1618: } else {
1619: PetscMalloc2(m*bs,PetscInt,&bufr,n*bs,PetscInt,&bufc);
1620: iidxm = bufr; iidxn = bufc;
1621: }
1622: for (i=0; i<m; i++)
1623: for (j=0; j<bs; j++)
1624: iidxm[i*bs+j] = bs*idxm[i] + j;
1625: for (i=0; i<n; i++)
1626: for (j=0; j<bs; j++)
1627: iidxn[i*bs+j] = bs*idxn[i] + j;
1628: MatSetValues(mat,m*bs,iidxm,n*bs,iidxn,v,addv);
1629: PetscFree2(bufr,bufc);
1630: }
1631: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1632: #if defined(PETSC_HAVE_CUSP)
1633: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1634: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1635: }
1636: #endif
1637: return(0);
1638: }
1642: /*@
1643: MatGetValues - Gets a block of values from a matrix.
1645: Not Collective; currently only returns a local block
1647: Input Parameters:
1648: + mat - the matrix
1649: . v - a logically two-dimensional array for storing the values
1650: . m, idxm - the number of rows and their global indices
1651: - n, idxn - the number of columns and their global indices
1653: Notes:
1654: The user must allocate space (m*n PetscScalars) for the values, v.
1655: The values, v, are then returned in a row-oriented format,
1656: analogous to that used by default in MatSetValues().
1658: MatGetValues() uses 0-based row and column numbers in
1659: Fortran as well as in C.
1661: MatGetValues() requires that the matrix has been assembled
1662: with MatAssemblyBegin()/MatAssemblyEnd(). Thus, calls to
1663: MatSetValues() and MatGetValues() CANNOT be made in succession
1664: without intermediate matrix assembly.
1666: Negative row or column indices will be ignored and those locations in v[] will be
1667: left unchanged.
1669: Level: advanced
1671: Concepts: matrices^accessing values
1673: .seealso: MatGetRow(), MatGetSubMatrices(), MatSetValues()
1674: @*/
1675: PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1676: {
1682: if (!m || !n) return(0);
1686: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1687: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1688: if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1689: MatPreallocated(mat);
1691: PetscLogEventBegin(MAT_GetValues,mat,0,0,0);
1692: (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);
1693: PetscLogEventEnd(MAT_GetValues,mat,0,0,0);
1694: return(0);
1695: }
1699: /*@
1700: MatSetValuesBatch - Inserts many blocks of values into a matrix at once. The blocks must all be square and the same size.
1702: Not Collective
1704: Input Parameters:
1705: + mat - the matrix
1706: . nb - the number of blocks
1707: . bs - the number of rows (and columns) in each block
1708: . rows - a concatenation of the rows for each block
1709: - v - a concatenation of logically two-dimensional arrays of values
1711: Notes:
1712: In the future, we may extend this routine to handle rectangular blocks, and additive mode.
1714: Level: advanced
1716: Concepts: matrices^putting entries in
1718: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1719: InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1720: @*/
1721: PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[])
1722: {
1730: #if defined(PETSC_USE_DEBUG)
1731: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1732: #endif
1734: if (mat->ops->setvaluesbatch) {
1735: PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);
1736: (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);
1737: PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);
1738: } else {
1739: PetscInt b;
1740: for(b = 0; b < nb; ++b) {
1741: MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);
1742: }
1743: }
1744: return(0);
1745: }
1749: /*@
1750: MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
1751: the routine MatSetValuesLocal() to allow users to insert matrix entries
1752: using a local (per-processor) numbering.
1754: Not Collective
1756: Input Parameters:
1757: + x - the matrix
1758: . rmapping - row mapping created with ISLocalToGlobalMappingCreate()
1759: or ISLocalToGlobalMappingCreateIS()
1760: - cmapping - column mapping
1762: Level: intermediate
1764: Concepts: matrices^local to global mapping
1765: Concepts: local to global mapping^for matrices
1767: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
1768: @*/
1769: PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
1770: {
1777: MatPreallocated(x);
1779: if (x->ops->setlocaltoglobalmapping) {
1780: (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);
1781: } else {
1782: PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);
1783: PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);
1784: }
1785: return(0);
1786: }
1790: /*@
1791: MatSetLocalToGlobalMappingBlock - Sets a local-to-global numbering for use
1792: by the routine MatSetValuesBlockedLocal() to allow users to insert matrix
1793: entries using a local (per-processor) numbering.
1795: Not Collective
1797: Input Parameters:
1798: + x - the matrix
1799: . rmapping - row mapping created with ISLocalToGlobalMappingCreate() or
1800: ISLocalToGlobalMappingCreateIS()
1801: - cmapping - column mapping
1803: Level: intermediate
1805: Concepts: matrices^local to global mapping blocked
1806: Concepts: local to global mapping^for matrices, blocked
1808: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal(),
1809: MatSetValuesBlocked(), MatSetValuesLocal()
1810: @*/
1811: PetscErrorCode MatSetLocalToGlobalMappingBlock(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
1812: {
1819: MatPreallocated(x);
1821: PetscLayoutSetISLocalToGlobalMappingBlock(x->rmap,rmapping);
1822: PetscLayoutSetISLocalToGlobalMappingBlock(x->cmap,cmapping);
1823: return(0);
1824: }
1828: /*@
1829: MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping()
1831: Not Collective
1833: Input Parameters:
1834: . A - the matrix
1836: Output Parameters:
1837: + rmapping - row mapping
1838: - cmapping - column mapping
1840: Level: advanced
1842: Concepts: matrices^local to global mapping
1843: Concepts: local to global mapping^for matrices
1845: .seealso: MatSetValuesLocal(), MatGetLocalToGlobalMappingBlock()
1846: @*/
1847: PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
1848: {
1854: if (rmapping) *rmapping = A->rmap->mapping;
1855: if (cmapping) *cmapping = A->cmap->mapping;
1856: return(0);
1857: }
1861: /*@
1862: MatGetLocalToGlobalMappingBlock - Gets the local-to-global numbering set by MatSetLocalToGlobalMappingBlock()
1864: Not Collective
1866: Input Parameters:
1867: . A - the matrix
1869: Output Parameters:
1870: + rmapping - row mapping
1871: - cmapping - column mapping
1873: Level: advanced
1875: Concepts: matrices^local to global mapping blocked
1876: Concepts: local to global mapping^for matrices, blocked
1878: .seealso: MatSetValuesBlockedLocal(), MatGetLocalToGlobalMapping()
1879: @*/
1880: PetscErrorCode MatGetLocalToGlobalMappingBlock(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
1881: {
1887: if (rmapping) *rmapping = A->rmap->bmapping;
1888: if (cmapping) *cmapping = A->cmap->bmapping;
1889: return(0);
1890: }
1894: /*@
1895: MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
1896: using a local ordering of the nodes.
1898: Not Collective
1900: Input Parameters:
1901: + x - the matrix
1902: . nrow, irow - number of rows and their local indices
1903: . ncol, icol - number of columns and their local indices
1904: . y - a logically two-dimensional array of values
1905: - addv - either INSERT_VALUES or ADD_VALUES, where
1906: ADD_VALUES adds values to any existing entries, and
1907: INSERT_VALUES replaces existing entries with new values
1909: Notes:
1910: Before calling MatSetValuesLocal(), the user must first set the
1911: local-to-global mapping by calling MatSetLocalToGlobalMapping().
1913: Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
1914: options cannot be mixed without intervening calls to the assembly
1915: routines.
1917: These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1918: MUST be called after all calls to MatSetValuesLocal() have been completed.
1920: Level: intermediate
1922: Concepts: matrices^putting entries in with local numbering
1924: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
1925: MatSetValueLocal()
1926: @*/
1927: PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
1928: {
1934: if (!nrow || !ncol) return(0); /* no values to insert */
1938: MatPreallocated(mat);
1939: if (mat->insertmode == NOT_SET_VALUES) {
1940: mat->insertmode = addv;
1941: }
1942: #if defined(PETSC_USE_DEBUG)
1943: else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1944: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1945: if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1946: #endif
1948: if (mat->assembled) {
1949: mat->was_assembled = PETSC_TRUE;
1950: mat->assembled = PETSC_FALSE;
1951: }
1952: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1953: if (mat->ops->setvalueslocal) {
1954: (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);
1955: } else {
1956: PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
1957: if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1958: irowm = buf; icolm = buf+nrow;
1959: } else {
1960: PetscMalloc2(nrow,PetscInt,&bufr,ncol,PetscInt,&bufc);
1961: irowm = bufr; icolm = bufc;
1962: }
1963: ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);
1964: ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);
1965: MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);
1966: PetscFree2(bufr,bufc);
1967: }
1968: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1969: #if defined(PETSC_HAVE_CUSP)
1970: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1971: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1972: }
1973: #endif
1974: return(0);
1975: }
1979: /*@
1980: MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix,
1981: using a local ordering of the nodes a block at a time.
1983: Not Collective
1985: Input Parameters:
1986: + x - the matrix
1987: . nrow, irow - number of rows and their local indices
1988: . ncol, icol - number of columns and their local indices
1989: . y - a logically two-dimensional array of values
1990: - addv - either INSERT_VALUES or ADD_VALUES, where
1991: ADD_VALUES adds values to any existing entries, and
1992: INSERT_VALUES replaces existing entries with new values
1994: Notes:
1995: Before calling MatSetValuesBlockedLocal(), the user must first set the
1996: block size using MatSetBlockSize(), and the local-to-global mapping by
1997: calling MatSetLocalToGlobalMappingBlock(), where the mapping MUST be
1998: set for matrix blocks, not for matrix elements.
2000: Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
2001: options cannot be mixed without intervening calls to the assembly
2002: routines.
2004: These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2005: MUST be called after all calls to MatSetValuesBlockedLocal() have been completed.
2007: Level: intermediate
2009: Concepts: matrices^putting blocked values in with local numbering
2011: .seealso: MatSetBlockSize(), MatSetLocalToGlobalMappingBlock(), MatAssemblyBegin(), MatAssemblyEnd(),
2012: MatSetValuesLocal(), MatSetLocalToGlobalMappingBlock(), MatSetValuesBlocked()
2013: @*/
2014: PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2015: {
2021: if (!nrow || !ncol) return(0); /* no values to insert */
2025: MatPreallocated(mat);
2026: if (mat->insertmode == NOT_SET_VALUES) {
2027: mat->insertmode = addv;
2028: }
2029: #if defined(PETSC_USE_DEBUG)
2030: else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2031: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2032: 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);
2033: #endif
2035: if (mat->assembled) {
2036: mat->was_assembled = PETSC_TRUE;
2037: mat->assembled = PETSC_FALSE;
2038: }
2039: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
2040: if (mat->ops->setvaluesblockedlocal) {
2041: (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);
2042: } else {
2043: PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2044: if (mat->rmap->bmapping && mat->cmap->bmapping) {
2045: if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2046: irowm = buf; icolm = buf + nrow;
2047: } else {
2048: PetscMalloc2(nrow,PetscInt,&bufr,ncol,PetscInt,&bufc);
2049: irowm = bufr; icolm = bufc;
2050: }
2051: ISLocalToGlobalMappingApply(mat->rmap->bmapping,nrow,irow,irowm);
2052: ISLocalToGlobalMappingApply(mat->cmap->bmapping,ncol,icol,icolm);
2053: MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);
2054: PetscFree2(bufr,bufc);
2055: } else {
2056: PetscInt i,j,bs=mat->rmap->bs;
2057: if ((nrow+ncol)*bs <=(PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2058: irowm = buf; icolm = buf + nrow;
2059: } else {
2060: PetscMalloc2(nrow*bs,PetscInt,&bufr,ncol*bs,PetscInt,&bufc);
2061: irowm = bufr; icolm = bufc;
2062: }
2063: for (i=0; i<nrow; i++)
2064: for (j=0; j<bs; j++)
2065: irowm[i*bs+j] = irow[i]*bs+j;
2066: for (i=0; i<ncol; i++)
2067: for (j=0; j<bs; j++)
2068: icolm[i*bs+j] = icol[i]*bs+j;
2069: MatSetValuesLocal(mat,nrow*bs,irowm,ncol*bs,icolm,y,addv);
2070: PetscFree2(bufr,bufc);
2071: }
2072: }
2073: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
2074: #if defined(PETSC_HAVE_CUSP)
2075: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
2076: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
2077: }
2078: #endif
2079: return(0);
2080: }
2084: /*@
2085: MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal
2087: Collective on Mat and Vec
2089: Input Parameters:
2090: + mat - the matrix
2091: - x - the vector to be multiplied
2093: Output Parameters:
2094: . y - the result
2096: Notes:
2097: The vectors x and y cannot be the same. I.e., one cannot
2098: call MatMult(A,y,y).
2100: Level: developer
2102: Concepts: matrix-vector product
2104: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2105: @*/
2106: PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y)
2107: {
2116: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2117: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2118: if (x == y) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2119: MatPreallocated(mat);
2121: if (!mat->ops->multdiagonalblock) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2122: (*mat->ops->multdiagonalblock)(mat,x,y);
2123: PetscObjectStateIncrease((PetscObject)y);
2124: return(0);
2125: }
2127: /* --------------------------------------------------------*/
2130: /*@
2131: MatMult - Computes the matrix-vector product, y = Ax.
2133: Neighbor-wise Collective on Mat and Vec
2135: Input Parameters:
2136: + mat - the matrix
2137: - x - the vector to be multiplied
2139: Output Parameters:
2140: . y - the result
2142: Notes:
2143: The vectors x and y cannot be the same. I.e., one cannot
2144: call MatMult(A,y,y).
2146: Level: beginner
2148: Concepts: matrix-vector product
2150: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2151: @*/
2152: PetscErrorCode MatMult(Mat mat,Vec x,Vec y)
2153: {
2161: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2162: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2163: if (x == y) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2164: #ifndef PETSC_HAVE_CONSTRAINTS
2165: 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);
2166: 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);
2167: 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);
2168: #endif
2169: MatPreallocated(mat);
2171: if (mat->nullsp) {
2172: MatNullSpaceRemove(mat->nullsp,x,&x);
2173: }
2175: if (!mat->ops->mult) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2176: PetscLogEventBegin(MAT_Mult,mat,x,y,0);
2177: (*mat->ops->mult)(mat,x,y);
2178: PetscLogEventEnd(MAT_Mult,mat,x,y,0);
2180: if (mat->nullsp) {
2181: MatNullSpaceRemove(mat->nullsp,y,PETSC_NULL);
2182: }
2183: PetscObjectStateIncrease((PetscObject)y);
2184: return(0);
2185: }
2189: /*@
2190: MatMultTranspose - Computes matrix transpose times a vector.
2192: Neighbor-wise Collective on Mat and Vec
2194: Input Parameters:
2195: + mat - the matrix
2196: - x - the vector to be multilplied
2198: Output Parameters:
2199: . y - the result
2201: Notes:
2202: The vectors x and y cannot be the same. I.e., one cannot
2203: call MatMultTranspose(A,y,y).
2205: For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple,
2206: use MatMultHermitianTranspose()
2208: Level: beginner
2210: Concepts: matrix vector product^transpose
2212: .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose()
2213: @*/
2214: PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y)
2215: {
2224: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2225: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2226: if (x == y) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2227: #ifndef PETSC_HAVE_CONSTRAINTS
2228: 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);
2229: 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);
2230: #endif
2231: MatPreallocated(mat);
2233: if (!mat->ops->multtranspose) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"This matrix type does not have a multiply tranpose defined");
2234: PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);
2235: (*mat->ops->multtranspose)(mat,x,y);
2236: PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);
2237: PetscObjectStateIncrease((PetscObject)y);
2238: return(0);
2239: }
2243: /*@
2244: MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.
2246: Neighbor-wise Collective on Mat and Vec
2248: Input Parameters:
2249: + mat - the matrix
2250: - x - the vector to be multilplied
2252: Output Parameters:
2253: . y - the result
2255: Notes:
2256: The vectors x and y cannot be the same. I.e., one cannot
2257: call MatMultHermitianTranspose(A,y,y).
2259: Also called the conjugate transpose, complex conjugate transpose, or adjoint.
2261: For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical.
2263: Level: beginner
2265: Concepts: matrix vector product^transpose
2267: .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose()
2268: @*/
2269: PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y)
2270: {
2279: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2280: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2281: if (x == y) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2282: #ifndef PETSC_HAVE_CONSTRAINTS
2283: 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);
2284: 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);
2285: #endif
2286: MatPreallocated(mat);
2288: if (!mat->ops->multhermitiantranspose) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2289: PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);
2290: (*mat->ops->multhermitiantranspose)(mat,x,y);
2291: PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);
2292: PetscObjectStateIncrease((PetscObject)y);
2293: return(0);
2294: }
2298: /*@
2299: MatMultAdd - Computes v3 = v2 + A * v1.
2301: Neighbor-wise Collective on Mat and Vec
2303: Input Parameters:
2304: + mat - the matrix
2305: - v1, v2 - the vectors
2307: Output Parameters:
2308: . v3 - the result
2310: Notes:
2311: The vectors v1 and v3 cannot be the same. I.e., one cannot
2312: call MatMultAdd(A,v1,v2,v1).
2314: Level: beginner
2316: Concepts: matrix vector product^addition
2318: .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
2319: @*/
2320: PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2321: {
2331: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2332: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2333: if (mat->cmap->N != v1->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->cmap->N,v1->map->N);
2334: /* 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);
2335: 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); */
2336: 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);
2337: 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);
2338: if (v1 == v3) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2339: MatPreallocated(mat);
2341: if (!mat->ops->multadd) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name);
2342: PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);
2343: (*mat->ops->multadd)(mat,v1,v2,v3);
2344: PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);
2345: PetscObjectStateIncrease((PetscObject)v3);
2346: return(0);
2347: }
2351: /*@
2352: MatMultTransposeAdd - Computes v3 = v2 + A' * v1.
2354: Neighbor-wise Collective on Mat and Vec
2356: Input Parameters:
2357: + mat - the matrix
2358: - v1, v2 - the vectors
2360: Output Parameters:
2361: . v3 - the result
2363: Notes:
2364: The vectors v1 and v3 cannot be the same. I.e., one cannot
2365: call MatMultTransposeAdd(A,v1,v2,v1).
2367: Level: beginner
2369: Concepts: matrix vector product^transpose and addition
2371: .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
2372: @*/
2373: PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2374: {
2384: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2385: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2386: if (!mat->ops->multtransposeadd) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2387: if (v1 == v3) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2388: if (mat->rmap->N != v1->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->rmap->N,v1->map->N);
2389: if (mat->cmap->N != v2->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->cmap->N,v2->map->N);
2390: if (mat->cmap->N != v3->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->cmap->N,v3->map->N);
2391: MatPreallocated(mat);
2393: PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);
2394: (*mat->ops->multtransposeadd)(mat,v1,v2,v3);
2395: PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);
2396: PetscObjectStateIncrease((PetscObject)v3);
2397: return(0);
2398: }
2402: /*@
2403: MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1.
2405: Neighbor-wise Collective on Mat and Vec
2407: Input Parameters:
2408: + mat - the matrix
2409: - v1, v2 - the vectors
2411: Output Parameters:
2412: . v3 - the result
2414: Notes:
2415: The vectors v1 and v3 cannot be the same. I.e., one cannot
2416: call MatMultHermitianTransposeAdd(A,v1,v2,v1).
2418: Level: beginner
2420: Concepts: matrix vector product^transpose and addition
2422: .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult()
2423: @*/
2424: PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2425: {
2435: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2436: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2437: if (!mat->ops->multhermitiantransposeadd) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2438: if (v1 == v3) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2439: if (mat->rmap->N != v1->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->rmap->N,v1->map->N);
2440: if (mat->cmap->N != v2->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->cmap->N,v2->map->N);
2441: if (mat->cmap->N != v3->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->cmap->N,v3->map->N);
2442: MatPreallocated(mat);
2444: PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2445: (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);
2446: PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2447: PetscObjectStateIncrease((PetscObject)v3);
2448: return(0);
2449: }
2453: /*@
2454: MatMultConstrained - The inner multiplication routine for a
2455: constrained matrix P^T A P.
2457: Neighbor-wise Collective on Mat and Vec
2459: Input Parameters:
2460: + mat - the matrix
2461: - x - the vector to be multilplied
2463: Output Parameters:
2464: . y - the result
2466: Notes:
2467: The vectors x and y cannot be the same. I.e., one cannot
2468: call MatMult(A,y,y).
2470: Level: beginner
2472: .keywords: matrix, multiply, matrix-vector product, constraint
2473: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2474: @*/
2475: PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y)
2476: {
2483: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2484: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2485: if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2486: 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);
2487: 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);
2488: 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);
2490: PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2491: (*mat->ops->multconstrained)(mat,x,y);
2492: PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2493: PetscObjectStateIncrease((PetscObject)y);
2495: return(0);
2496: }
2500: /*@
2501: MatMultTransposeConstrained - The inner multiplication routine for a
2502: constrained matrix P^T A^T P.
2504: Neighbor-wise Collective on Mat and Vec
2506: Input Parameters:
2507: + mat - the matrix
2508: - x - the vector to be multilplied
2510: Output Parameters:
2511: . y - the result
2513: Notes:
2514: The vectors x and y cannot be the same. I.e., one cannot
2515: call MatMult(A,y,y).
2517: Level: beginner
2519: .keywords: matrix, multiply, matrix-vector product, constraint
2520: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2521: @*/
2522: PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2523: {
2530: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2531: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2532: if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2533: 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);
2534: 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);
2536: PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2537: (*mat->ops->multtransposeconstrained)(mat,x,y);
2538: PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2539: PetscObjectStateIncrease((PetscObject)y);
2541: return(0);
2542: }
2546: /*@C
2547: MatGetFactorType - gets the type of factorization it is
2549: Note Collective
2550: as the flag
2552: Input Parameters:
2553: . mat - the matrix
2555: Output Parameters:
2556: . t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT
2558: Level: intermediate
2560: .seealso: MatFactorType, MatGetFactor()
2561: @*/
2562: PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t)
2563: {
2567: *t = mat->factortype;
2568: return(0);
2569: }
2571: /* ------------------------------------------------------------*/
2574: /*@C
2575: MatGetInfo - Returns information about matrix storage (number of
2576: nonzeros, memory, etc.).
2578: Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag
2580: Input Parameters:
2581: . mat - the matrix
2583: Output Parameters:
2584: + flag - flag indicating the type of parameters to be returned
2585: (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2586: MAT_GLOBAL_SUM - sum over all processors)
2587: - info - matrix information context
2589: Notes:
2590: The MatInfo context contains a variety of matrix data, including
2591: number of nonzeros allocated and used, number of mallocs during
2592: matrix assembly, etc. Additional information for factored matrices
2593: is provided (such as the fill ratio, number of mallocs during
2594: factorization, etc.). Much of this info is printed to PETSC_STDOUT
2595: when using the runtime options
2596: $ -info -mat_view_info
2598: Example for C/C++ Users:
2599: See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2600: data within the MatInfo context. For example,
2601: .vb
2602: MatInfo info;
2603: Mat A;
2604: double mal, nz_a, nz_u;
2606: MatGetInfo(A,MAT_LOCAL,&info);
2607: mal = info.mallocs;
2608: nz_a = info.nz_allocated;
2609: .ve
2611: Example for Fortran Users:
2612: Fortran users should declare info as a double precision
2613: array of dimension MAT_INFO_SIZE, and then extract the parameters
2614: of interest. See the file ${PETSC_DIR}/include/finclude/petscmat.h
2615: a complete list of parameter names.
2616: .vb
2617: double precision info(MAT_INFO_SIZE)
2618: double precision mal, nz_a
2619: Mat A
2620: integer ierr
2622: call MatGetInfo(A,MAT_LOCAL,info,ierr)
2623: mal = info(MAT_INFO_MALLOCS)
2624: nz_a = info(MAT_INFO_NZ_ALLOCATED)
2625: .ve
2627: Level: intermediate
2629: Concepts: matrices^getting information on
2630:
2631: Developer Note: fortran interface is not autogenerated as the f90
2632: interface defintion cannot be generated correctly [due to MatInfo]
2633:
2634: @*/
2635: PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2636: {
2643: if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2644: MatPreallocated(mat);
2645: (*mat->ops->getinfo)(mat,flag,info);
2646: return(0);
2647: }
2649: /* ----------------------------------------------------------*/
2653: /*@C
2654: MatLUFactor - Performs in-place LU factorization of matrix.
2656: Collective on Mat
2658: Input Parameters:
2659: + mat - the matrix
2660: . row - row permutation
2661: . col - column permutation
2662: - info - options for factorization, includes
2663: $ fill - expected fill as ratio of original fill.
2664: $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2665: $ Run with the option -info to determine an optimal value to use
2667: Notes:
2668: Most users should employ the simplified KSP interface for linear solvers
2669: instead of working directly with matrix algebra routines such as this.
2670: See, e.g., KSPCreate().
2672: This changes the state of the matrix to a factored matrix; it cannot be used
2673: for example with MatSetValues() unless one first calls MatSetUnfactored().
2675: Level: developer
2677: Concepts: matrices^LU factorization
2679: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2680: MatGetOrdering(), MatSetUnfactored(), MatFactorInfo
2682: Developer Note: fortran interface is not autogenerated as the f90
2683: interface defintion cannot be generated correctly [due to MatFactorInfo]
2685: @*/
2686: PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2687: {
2696: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2697: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2698: if (!mat->ops->lufactor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2699: MatPreallocated(mat);
2701: PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);
2702: (*mat->ops->lufactor)(mat,row,col,info);
2703: PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);
2704: PetscObjectStateIncrease((PetscObject)mat);
2705: return(0);
2706: }
2710: /*@C
2711: MatILUFactor - Performs in-place ILU factorization of matrix.
2713: Collective on Mat
2715: Input Parameters:
2716: + mat - the matrix
2717: . row - row permutation
2718: . col - column permutation
2719: - info - structure containing
2720: $ levels - number of levels of fill.
2721: $ expected fill - as ratio of original fill.
2722: $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2723: missing diagonal entries)
2725: Notes:
2726: Probably really in-place only when level of fill is zero, otherwise allocates
2727: new space to store factored matrix and deletes previous memory.
2729: Most users should employ the simplified KSP interface for linear solvers
2730: instead of working directly with matrix algebra routines such as this.
2731: See, e.g., KSPCreate().
2733: Level: developer
2735: Concepts: matrices^ILU factorization
2737: .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
2739: Developer Note: fortran interface is not autogenerated as the f90
2740: interface defintion cannot be generated correctly [due to MatFactorInfo]
2742: @*/
2743: PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2744: {
2753: if (mat->rmap->N != mat->cmap->N) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONG,"matrix must be square");
2754: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2755: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2756: if (!mat->ops->ilufactor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2757: MatPreallocated(mat);
2759: PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);
2760: (*mat->ops->ilufactor)(mat,row,col,info);
2761: PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);
2762: PetscObjectStateIncrease((PetscObject)mat);
2763: return(0);
2764: }
2768: /*@C
2769: MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
2770: Call this routine before calling MatLUFactorNumeric().
2772: Collective on Mat
2774: Input Parameters:
2775: + fact - the factor matrix obtained with MatGetFactor()
2776: . mat - the matrix
2777: . row, col - row and column permutations
2778: - info - options for factorization, includes
2779: $ fill - expected fill as ratio of original fill.
2780: $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2781: $ Run with the option -info to determine an optimal value to use
2784: Notes:
2785: See the <a href="../../docs/manual.pdf">users manual</a> for additional information about
2786: choosing the fill factor for better efficiency.
2788: Most users should employ the simplified KSP interface for linear solvers
2789: instead of working directly with matrix algebra routines such as this.
2790: See, e.g., KSPCreate().
2792: Level: developer
2794: Concepts: matrices^LU symbolic factorization
2796: .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
2798: Developer Note: fortran interface is not autogenerated as the f90
2799: interface defintion cannot be generated correctly [due to MatFactorInfo]
2801: @*/
2802: PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
2803: {
2813: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2814: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2815: if (!(fact)->ops->lufactorsymbolic) {
2816: const MatSolverPackage spackage;
2817: MatFactorGetSolverPackage(fact,&spackage);
2818: SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage);
2819: }
2820: MatPreallocated(mat);
2822: PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);
2823: (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);
2824: PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);
2825: PetscObjectStateIncrease((PetscObject)fact);
2826: return(0);
2827: }
2831: /*@C
2832: MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
2833: Call this routine after first calling MatLUFactorSymbolic().
2835: Collective on Mat
2837: Input Parameters:
2838: + fact - the factor matrix obtained with MatGetFactor()
2839: . mat - the matrix
2840: - info - options for factorization
2842: Notes:
2843: See MatLUFactor() for in-place factorization. See
2844: MatCholeskyFactorNumeric() for the symmetric, positive definite case.
2846: Most users should employ the simplified KSP interface for linear solvers
2847: instead of working directly with matrix algebra routines such as this.
2848: See, e.g., KSPCreate().
2850: Level: developer
2852: Concepts: matrices^LU numeric factorization
2854: .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()
2856: Developer Note: fortran interface is not autogenerated as the f90
2857: interface defintion cannot be generated correctly [due to MatFactorInfo]
2859: @*/
2860: PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
2861: {
2869: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2870: if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) {
2871: SETERRQ4(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dimensions are different %D should = %D %D should = %D",mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N);
2872: }
2873: if (!(fact)->ops->lufactornumeric) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name);
2874: MatPreallocated(mat);
2875: PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);
2876: (fact->ops->lufactornumeric)(fact,mat,info);
2877: PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);
2879: MatView_Private(fact);
2880: PetscObjectStateIncrease((PetscObject)fact);
2881: return(0);
2882: }
2886: /*@C
2887: MatCholeskyFactor - Performs in-place Cholesky factorization of a
2888: symmetric matrix.
2890: Collective on Mat
2892: Input Parameters:
2893: + mat - the matrix
2894: . perm - row and column permutations
2895: - f - expected fill as ratio of original fill
2897: Notes:
2898: See MatLUFactor() for the nonsymmetric case. See also
2899: MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().
2901: Most users should employ the simplified KSP interface for linear solvers
2902: instead of working directly with matrix algebra routines such as this.
2903: See, e.g., KSPCreate().
2905: Level: developer
2907: Concepts: matrices^Cholesky factorization
2909: .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
2910: MatGetOrdering()
2912: Developer Note: fortran interface is not autogenerated as the f90
2913: interface defintion cannot be generated correctly [due to MatFactorInfo]
2915: @*/
2916: PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
2917: {
2925: if (mat->rmap->N != mat->cmap->N) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONG,"Matrix must be square");
2926: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2927: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2928: if (!mat->ops->choleskyfactor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2929: MatPreallocated(mat);
2931: PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);
2932: (*mat->ops->choleskyfactor)(mat,perm,info);
2933: PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);
2934: PetscObjectStateIncrease((PetscObject)mat);
2935: return(0);
2936: }
2940: /*@C
2941: MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
2942: of a symmetric matrix.
2944: Collective on Mat
2946: Input Parameters:
2947: + fact - the factor matrix obtained with MatGetFactor()
2948: . mat - the matrix
2949: . perm - row and column permutations
2950: - info - options for factorization, includes
2951: $ fill - expected fill as ratio of original fill.
2952: $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2953: $ Run with the option -info to determine an optimal value to use
2955: Notes:
2956: See MatLUFactorSymbolic() for the nonsymmetric case. See also
2957: MatCholeskyFactor() and MatCholeskyFactorNumeric().
2959: Most users should employ the simplified KSP interface for linear solvers
2960: instead of working directly with matrix algebra routines such as this.
2961: See, e.g., KSPCreate().
2963: Level: developer
2965: Concepts: matrices^Cholesky symbolic factorization
2967: .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
2968: MatGetOrdering()
2970: Developer Note: fortran interface is not autogenerated as the f90
2971: interface defintion cannot be generated correctly [due to MatFactorInfo]
2973: @*/
2974: PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
2975: {
2984: if (mat->rmap->N != mat->cmap->N) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONG,"Matrix must be square");
2985: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2986: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2987: if (!(fact)->ops->choleskyfactorsymbolic) {
2988: const MatSolverPackage spackage;
2989: MatFactorGetSolverPackage(fact,&spackage);
2990: SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage);
2991: }
2992: MatPreallocated(mat);
2994: PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
2995: (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);
2996: PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
2997: PetscObjectStateIncrease((PetscObject)fact);
2998: return(0);
2999: }
3003: /*@C
3004: MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
3005: of a symmetric matrix. Call this routine after first calling
3006: MatCholeskyFactorSymbolic().
3008: Collective on Mat
3010: Input Parameters:
3011: + fact - the factor matrix obtained with MatGetFactor()
3012: . mat - the initial matrix
3013: . info - options for factorization
3014: - fact - the symbolic factor of mat
3017: Notes:
3018: Most users should employ the simplified KSP interface for linear solvers
3019: instead of working directly with matrix algebra routines such as this.
3020: See, e.g., KSPCreate().
3022: Level: developer
3024: Concepts: matrices^Cholesky numeric factorization
3026: .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
3028: Developer Note: fortran interface is not autogenerated as the f90
3029: interface defintion cannot be generated correctly [due to MatFactorInfo]
3031: @*/
3032: PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3033: {
3041: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3042: if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name);
3043: if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) {
3044: SETERRQ4(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dim %D should = %D %D should = %D",mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N);
3045: }
3046: MatPreallocated(mat);
3048: PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);
3049: (fact->ops->choleskyfactornumeric)(fact,mat,info);
3050: PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);
3052: MatView_Private(fact);
3053: PetscObjectStateIncrease((PetscObject)fact);
3054: return(0);
3055: }
3057: /* ----------------------------------------------------------------*/
3060: /*@
3061: MatSolve - Solves A x = b, given a factored matrix.
3063: Neighbor-wise Collective on Mat and Vec
3065: Input Parameters:
3066: + mat - the factored matrix
3067: - b - the right-hand-side vector
3069: Output Parameter:
3070: . x - the result vector
3072: Notes:
3073: The vectors b and x cannot be the same. I.e., one cannot
3074: call MatSolve(A,x,x).
3076: Notes:
3077: Most users should employ the simplified KSP interface for linear solvers
3078: instead of working directly with matrix algebra routines such as this.
3079: See, e.g., KSPCreate().
3081: Level: developer
3083: Concepts: matrices^triangular solves
3085: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
3086: @*/
3087: PetscErrorCode MatSolve(Mat mat,Vec b,Vec x)
3088: {
3098: if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3099: if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3100: if (mat->cmap->N != x->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3101: if (mat->rmap->N != b->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3102: if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3103: if (!mat->rmap->N && !mat->cmap->N) return(0);
3104: if (!mat->ops->solve) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3105: MatPreallocated(mat);
3107: PetscLogEventBegin(MAT_Solve,mat,b,x,0);
3108: (*mat->ops->solve)(mat,b,x);
3109: PetscLogEventEnd(MAT_Solve,mat,b,x,0);
3110: PetscObjectStateIncrease((PetscObject)x);
3111: return(0);
3112: }
3116: PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X)
3117: {
3119: Vec b,x;
3120: PetscInt m,N,i;
3121: PetscScalar *bb,*xx;
3122: PetscBool flg;
3125: PetscTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,PETSC_NULL);
3126: if (!flg) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
3127: PetscTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,PETSC_NULL);
3128: if (!flg) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");
3130: MatGetArray(B,&bb);
3131: MatGetArray(X,&xx);
3132: MatGetLocalSize(B,&m,PETSC_NULL); /* number local rows */
3133: MatGetSize(B,PETSC_NULL,&N); /* total columns in dense matrix */
3134: MatGetVecs(A,&x,&b);
3135: for (i=0; i<N; i++) {
3136: VecPlaceArray(b,bb + i*m);
3137: VecPlaceArray(x,xx + i*m);
3138: MatSolve(A,b,x);
3139: VecResetArray(x);
3140: VecResetArray(b);
3141: }
3142: VecDestroy(&b);
3143: VecDestroy(&x);
3144: MatRestoreArray(B,&bb);
3145: MatRestoreArray(X,&xx);
3146: return(0);
3147: }
3151: /*@
3152: MatMatSolve - Solves A X = B, given a factored matrix.
3154: Neighbor-wise Collective on Mat
3156: Input Parameters:
3157: + mat - the factored matrix
3158: - B - the right-hand-side matrix (dense matrix)
3160: Output Parameter:
3161: . X - the result matrix (dense matrix)
3163: Notes:
3164: The matrices b and x cannot be the same. I.e., one cannot
3165: call MatMatSolve(A,x,x).
3167: Notes:
3168: Most users should usually employ the simplified KSP interface for linear solvers
3169: instead of working directly with matrix algebra routines such as this.
3170: See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3171: at a time.
3173: Level: developer
3175: Concepts: matrices^triangular solves
3177: .seealso: MatMatSolveAdd(), MatMatSolveTranspose(), MatMatSolveTransposeAdd(), MatLUFactor(), MatCholeskyFactor()
3178: @*/
3179: PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X)
3180: {
3190: if (X == B) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3191: if (!A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3192: if (A->cmap->N != X->rmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %D %D",A->cmap->N,X->rmap->N);
3193: if (A->rmap->N != B->rmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %D %D",A->rmap->N,B->rmap->N);
3194: 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);
3195: if (!A->rmap->N && !A->cmap->N) return(0);
3196: MatPreallocated(A);
3198: PetscLogEventBegin(MAT_MatSolve,A,B,X,0);
3199: if (!A->ops->matsolve) {
3200: PetscInfo1(A,"Mat type %s using basic MatMatSolve",((PetscObject)A)->type_name);
3201: MatMatSolve_Basic(A,B,X);
3202: } else {
3203: (*A->ops->matsolve)(A,B,X);
3204: }
3205: PetscLogEventEnd(MAT_MatSolve,A,B,X,0);
3206: PetscObjectStateIncrease((PetscObject)X);
3207: return(0);
3208: }
3213: /*@
3214: MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or
3215: U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U,
3217: Neighbor-wise Collective on Mat and Vec
3219: Input Parameters:
3220: + mat - the factored matrix
3221: - b - the right-hand-side vector
3223: Output Parameter:
3224: . x - the result vector
3226: Notes:
3227: MatSolve() should be used for most applications, as it performs
3228: a forward solve followed by a backward solve.
3230: The vectors b and x cannot be the same, i.e., one cannot
3231: call MatForwardSolve(A,x,x).
3233: For matrix in seqsbaij format with block size larger than 1,
3234: the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3235: MatForwardSolve() solves U^T*D y = b, and
3236: MatBackwardSolve() solves U x = y.
3237: Thus they do not provide a symmetric preconditioner.
3239: Most users should employ the simplified KSP interface for linear solvers
3240: instead of working directly with matrix algebra routines such as this.
3241: See, e.g., KSPCreate().
3243: Level: developer
3245: Concepts: matrices^forward solves
3247: .seealso: MatSolve(), MatBackwardSolve()
3248: @*/
3249: PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x)
3250: {
3260: if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3261: if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3262: if (!mat->ops->forwardsolve) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3263: if (mat->cmap->N != x->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3264: if (mat->rmap->N != b->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3265: 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);
3266: MatPreallocated(mat);
3267: PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);
3268: (*mat->ops->forwardsolve)(mat,b,x);
3269: PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);
3270: PetscObjectStateIncrease((PetscObject)x);
3271: return(0);
3272: }
3276: /*@
3277: MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
3278: D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U,
3280: Neighbor-wise Collective on Mat and Vec
3282: Input Parameters:
3283: + mat - the factored matrix
3284: - b - the right-hand-side vector
3286: Output Parameter:
3287: . x - the result vector
3289: Notes:
3290: MatSolve() should be used for most applications, as it performs
3291: a forward solve followed by a backward solve.
3293: The vectors b and x cannot be the same. I.e., one cannot
3294: call MatBackwardSolve(A,x,x).
3296: For matrix in seqsbaij format with block size larger than 1,
3297: the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3298: MatForwardSolve() solves U^T*D y = b, and
3299: MatBackwardSolve() solves U x = y.
3300: Thus they do not provide a symmetric preconditioner.
3302: Most users should employ the simplified KSP interface for linear solvers
3303: instead of working directly with matrix algebra routines such as this.
3304: See, e.g., KSPCreate().
3306: Level: developer
3308: Concepts: matrices^backward solves
3310: .seealso: MatSolve(), MatForwardSolve()
3311: @*/
3312: PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x)
3313: {
3323: if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3324: if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3325: if (!mat->ops->backwardsolve) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3326: if (mat->cmap->N != x->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3327: if (mat->rmap->N != b->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3328: 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);
3329: MatPreallocated(mat);
3331: PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);
3332: (*mat->ops->backwardsolve)(mat,b,x);
3333: PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);
3334: PetscObjectStateIncrease((PetscObject)x);
3335: return(0);
3336: }
3340: /*@
3341: MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
3343: Neighbor-wise Collective on Mat and Vec
3345: Input Parameters:
3346: + mat - the factored matrix
3347: . b - the right-hand-side vector
3348: - y - the vector to be added to
3350: Output Parameter:
3351: . x - the result vector
3353: Notes:
3354: The vectors b and x cannot be the same. I.e., one cannot
3355: call MatSolveAdd(A,x,y,x).
3357: Most users should employ the simplified KSP interface for linear solvers
3358: instead of working directly with matrix algebra routines such as this.
3359: See, e.g., KSPCreate().
3361: Level: developer
3363: Concepts: matrices^triangular solves
3365: .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3366: @*/
3367: PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3368: {
3369: PetscScalar one = 1.0;
3370: Vec tmp;
3382: if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3383: if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3384: if (mat->cmap->N != x->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3385: if (mat->rmap->N != b->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3386: if (mat->rmap->N != y->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
3387: 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);
3388: 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);
3389: MatPreallocated(mat);
3391: PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);
3392: if (mat->ops->solveadd) {
3393: (*mat->ops->solveadd)(mat,b,y,x);
3394: } else {
3395: /* do the solve then the add manually */
3396: if (x != y) {
3397: MatSolve(mat,b,x);
3398: VecAXPY(x,one,y);
3399: } else {
3400: VecDuplicate(x,&tmp);
3401: PetscLogObjectParent(mat,tmp);
3402: VecCopy(x,tmp);
3403: MatSolve(mat,b,x);
3404: VecAXPY(x,one,tmp);
3405: VecDestroy(&tmp);
3406: }
3407: }
3408: PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);
3409: PetscObjectStateIncrease((PetscObject)x);
3410: return(0);
3411: }
3415: /*@
3416: MatSolveTranspose - Solves A' x = b, given a factored matrix.
3418: Neighbor-wise Collective on Mat and Vec
3420: Input Parameters:
3421: + mat - the factored matrix
3422: - b - the right-hand-side vector
3424: Output Parameter:
3425: . x - the result vector
3427: Notes:
3428: The vectors b and x cannot be the same. I.e., one cannot
3429: call MatSolveTranspose(A,x,x).
3431: Most users should employ the simplified KSP interface for linear solvers
3432: instead of working directly with matrix algebra routines such as this.
3433: See, e.g., KSPCreate().
3435: Level: developer
3437: Concepts: matrices^triangular solves
3439: .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
3440: @*/
3441: PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x)
3442: {
3452: if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3453: if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3454: if (!mat->ops->solvetranspose) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3455: if (mat->rmap->N != x->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
3456: if (mat->cmap->N != b->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->cmap->N,b->map->N);
3457: MatPreallocated(mat);
3458: PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);
3459: (*mat->ops->solvetranspose)(mat,b,x);
3460: PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);
3461: PetscObjectStateIncrease((PetscObject)x);
3462: return(0);
3463: }
3467: /*@
3468: MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
3469: factored matrix.
3471: Neighbor-wise Collective on Mat and Vec
3473: Input Parameters:
3474: + mat - the factored matrix
3475: . b - the right-hand-side vector
3476: - y - the vector to be added to
3478: Output Parameter:
3479: . x - the result vector
3481: Notes:
3482: The vectors b and x cannot be the same. I.e., one cannot
3483: call MatSolveTransposeAdd(A,x,y,x).
3485: Most users should employ the simplified KSP interface for linear solvers
3486: instead of working directly with matrix algebra routines such as this.
3487: See, e.g., KSPCreate().
3489: Level: developer
3491: Concepts: matrices^triangular solves
3493: .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3494: @*/
3495: PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3496: {
3497: PetscScalar one = 1.0;
3499: Vec tmp;
3510: if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3511: if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3512: if (mat->rmap->N != x->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
3513: if (mat->cmap->N != b->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->cmap->N,b->map->N);
3514: if (mat->cmap->N != y->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N);
3515: 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);
3516: MatPreallocated(mat);
3518: PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);
3519: if (mat->ops->solvetransposeadd) {
3520: (*mat->ops->solvetransposeadd)(mat,b,y,x);
3521: } else {
3522: /* do the solve then the add manually */
3523: if (x != y) {
3524: MatSolveTranspose(mat,b,x);
3525: VecAXPY(x,one,y);
3526: } else {
3527: VecDuplicate(x,&tmp);
3528: PetscLogObjectParent(mat,tmp);
3529: VecCopy(x,tmp);
3530: MatSolveTranspose(mat,b,x);
3531: VecAXPY(x,one,tmp);
3532: VecDestroy(&tmp);
3533: }
3534: }
3535: PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);
3536: PetscObjectStateIncrease((PetscObject)x);
3537: return(0);
3538: }
3539: /* ----------------------------------------------------------------*/
3543: /*@
3544: MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps.
3546: Neighbor-wise Collective on Mat and Vec
3548: Input Parameters:
3549: + mat - the matrix
3550: . b - the right hand side
3551: . omega - the relaxation factor
3552: . flag - flag indicating the type of SOR (see below)
3553: . shift - diagonal shift
3554: . its - the number of iterations
3555: - lits - the number of local iterations
3557: Output Parameters:
3558: . x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess)
3560: SOR Flags:
3561: . SOR_FORWARD_SWEEP - forward SOR
3562: . SOR_BACKWARD_SWEEP - backward SOR
3563: . SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3564: . SOR_LOCAL_FORWARD_SWEEP - local forward SOR
3565: . SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
3566: . SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3567: . SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
3568: upper/lower triangular part of matrix to
3569: vector (with omega)
3570: . SOR_ZERO_INITIAL_GUESS - zero initial guess
3572: Notes:
3573: SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3574: SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3575: on each processor.
3577: Application programmers will not generally use MatSOR() directly,
3578: but instead will employ the KSP/PC interface.
3580: Notes: for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing
3582: Notes for Advanced Users:
3583: The flags are implemented as bitwise inclusive or operations.
3584: For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3585: to specify a zero initial guess for SSOR.
3587: Most users should employ the simplified KSP interface for linear solvers
3588: instead of working directly with matrix algebra routines such as this.
3589: See, e.g., KSPCreate().
3591: Vectors x and b CANNOT be the same
3593: Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes
3595: Level: developer
3597: Concepts: matrices^relaxation
3598: Concepts: matrices^SOR
3599: Concepts: matrices^Gauss-Seidel
3601: @*/
3602: PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3603: {
3613: if (!mat->ops->sor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3614: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3615: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3616: if (mat->cmap->N != x->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3617: if (mat->rmap->N != b->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3618: 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);
3619: if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
3620: if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
3621: if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");
3623: MatPreallocated(mat);
3624: PetscLogEventBegin(MAT_SOR,mat,b,x,0);
3625: ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);
3626: PetscLogEventEnd(MAT_SOR,mat,b,x,0);
3627: PetscObjectStateIncrease((PetscObject)x);
3628: return(0);
3629: }
3633: /*
3634: Default matrix copy routine.
3635: */
3636: PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
3637: {
3638: PetscErrorCode ierr;
3639: PetscInt i,rstart = 0,rend = 0,nz;
3640: const PetscInt *cwork;
3641: const PetscScalar *vwork;
3644: if (B->assembled) {
3645: MatZeroEntries(B);
3646: }
3647: MatGetOwnershipRange(A,&rstart,&rend);
3648: for (i=rstart; i<rend; i++) {
3649: MatGetRow(A,i,&nz,&cwork,&vwork);
3650: MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);
3651: MatRestoreRow(A,i,&nz,&cwork,&vwork);
3652: }
3653: MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
3654: MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);
3655: PetscObjectStateIncrease((PetscObject)B);
3656: return(0);
3657: }
3661: /*@
3662: MatCopy - Copys a matrix to another matrix.
3664: Collective on Mat
3666: Input Parameters:
3667: + A - the matrix
3668: - str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
3670: Output Parameter:
3671: . B - where the copy is put
3673: Notes:
3674: If you use SAME_NONZERO_PATTERN then the two matrices had better have the
3675: same nonzero pattern or the routine will crash.
3677: MatCopy() copies the matrix entries of a matrix to another existing
3678: matrix (after first zeroing the second matrix). A related routine is
3679: MatConvert(), which first creates a new matrix and then copies the data.
3681: Level: intermediate
3682:
3683: Concepts: matrices^copying
3685: .seealso: MatConvert(), MatDuplicate()
3687: @*/
3688: PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str)
3689: {
3691: PetscInt i;
3699: MatPreallocated(B);
3700: if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3701: if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3702: if (A->rmap->N != B->rmap->N || A->cmap->N != B->cmap->N) SETERRQ4(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim (%D,%D) (%D,%D)",A->rmap->N,B->rmap->N,A->cmap->N,B->cmap->N);
3703: MatPreallocated(A);
3705: PetscLogEventBegin(MAT_Copy,A,B,0,0);
3706: if (A->ops->copy) {
3707: (*A->ops->copy)(A,B,str);
3708: } else { /* generic conversion */
3709: MatCopy_Basic(A,B,str);
3710: }
3712: B->stencil.dim = A->stencil.dim;
3713: B->stencil.noc = A->stencil.noc;
3714: for (i=0; i<=A->stencil.dim; i++) {
3715: B->stencil.dims[i] = A->stencil.dims[i];
3716: B->stencil.starts[i] = A->stencil.starts[i];
3717: }
3719: PetscLogEventEnd(MAT_Copy,A,B,0,0);
3720: PetscObjectStateIncrease((PetscObject)B);
3721: return(0);
3722: }
3726: /*@C
3727: MatConvert - Converts a matrix to another matrix, either of the same
3728: or different type.
3730: Collective on Mat
3732: Input Parameters:
3733: + mat - the matrix
3734: . newtype - new matrix type. Use MATSAME to create a new matrix of the
3735: same type as the original matrix.
3736: - reuse - denotes if the destination matrix is to be created or reused. Currently
3737: MAT_REUSE_MATRIX is only supported for inplace conversion, otherwise use
3738: MAT_INITIAL_MATRIX.
3740: Output Parameter:
3741: . M - pointer to place new matrix
3743: Notes:
3744: MatConvert() first creates a new matrix and then copies the data from
3745: the first matrix. A related routine is MatCopy(), which copies the matrix
3746: entries of one matrix to another already existing matrix context.
3748: Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
3749: the MPI communicator of the generated matrix is always the same as the communicator
3750: of the input matrix.
3752: Level: intermediate
3754: Concepts: matrices^converting between storage formats
3756: .seealso: MatCopy(), MatDuplicate()
3757: @*/
3758: PetscErrorCode MatConvert(Mat mat, const MatType newtype,MatReuse reuse,Mat *M)
3759: {
3760: PetscErrorCode ierr;
3761: PetscBool sametype,issame,flg;
3762: char convname[256],mtype[256];
3763: Mat B;
3769: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3770: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3771: MatPreallocated(mat);
3773: PetscOptionsGetString(((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);
3774: if (flg) {
3775: newtype = mtype;
3776: }
3777: PetscTypeCompare((PetscObject)mat,newtype,&sametype);
3778: PetscStrcmp(newtype,"same",&issame);
3779: if ((reuse == MAT_REUSE_MATRIX) && (mat != *M)) {
3780: SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"MAT_REUSE_MATRIX only supported for in-place conversion currently");
3781: }
3783: if ((reuse == MAT_REUSE_MATRIX) && (issame || sametype)) return(0);
3784:
3785: if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
3786: (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);
3787: } else {
3788: PetscErrorCode (*conv)(Mat, const MatType,MatReuse,Mat*)=PETSC_NULL;
3789: const char *prefix[3] = {"seq","mpi",""};
3790: PetscInt i;
3791: /*
3792: Order of precedence:
3793: 1) See if a specialized converter is known to the current matrix.
3794: 2) See if a specialized converter is known to the desired matrix class.
3795: 3) See if a good general converter is registered for the desired class
3796: (as of 6/27/03 only MATMPIADJ falls into this category).
3797: 4) See if a good general converter is known for the current matrix.
3798: 5) Use a really basic converter.
3799: */
3800:
3801: /* 1) See if a specialized converter is known to the current matrix and the desired class */
3802: for (i=0; i<3; i++) {
3803: PetscStrcpy(convname,"MatConvert_");
3804: PetscStrcat(convname,((PetscObject)mat)->type_name);
3805: PetscStrcat(convname,"_");
3806: PetscStrcat(convname,prefix[i]);
3807: PetscStrcat(convname,issame?((PetscObject)mat)->type_name:newtype);
3808: PetscStrcat(convname,"_C");
3809: PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);
3810: if (conv) goto foundconv;
3811: }
3813: /* 2) See if a specialized converter is known to the desired matrix class. */
3814: MatCreate(((PetscObject)mat)->comm,&B);
3815: MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);
3816: MatSetType(B,newtype);
3817: for (i=0; i<3; i++) {
3818: PetscStrcpy(convname,"MatConvert_");
3819: PetscStrcat(convname,((PetscObject)mat)->type_name);
3820: PetscStrcat(convname,"_");
3821: PetscStrcat(convname,prefix[i]);
3822: PetscStrcat(convname,newtype);
3823: PetscStrcat(convname,"_C");
3824: PetscObjectQueryFunction((PetscObject)B,convname,(void (**)(void))&conv);
3825: if (conv) {
3826: MatDestroy(&B);
3827: goto foundconv;
3828: }
3829: }
3831: /* 3) See if a good general converter is registered for the desired class */
3832: conv = B->ops->convertfrom;
3833: MatDestroy(&B);
3834: if (conv) goto foundconv;
3836: /* 4) See if a good general converter is known for the current matrix */
3837: if (mat->ops->convert) {
3838: conv = mat->ops->convert;
3839: }
3840: if (conv) goto foundconv;
3842: /* 5) Use a really basic converter. */
3843: conv = MatConvert_Basic;
3845: foundconv:
3846: PetscLogEventBegin(MAT_Convert,mat,0,0,0);
3847: (*conv)(mat,newtype,reuse,M);
3848: PetscLogEventEnd(MAT_Convert,mat,0,0,0);
3849: }
3850: PetscObjectStateIncrease((PetscObject)*M);
3852: /* Copy Mat options */
3853: if (mat->symmetric){MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);}
3854: if (mat->hermitian){MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);}
3855: return(0);
3856: }
3860: /*@C
3861: MatFactorGetSolverPackage - Returns name of the package providing the factorization routines
3863: Not Collective
3865: Input Parameter:
3866: . mat - the matrix, must be a factored matrix
3868: Output Parameter:
3869: . type - the string name of the package (do not free this string)
3871: Notes:
3872: In Fortran you pass in a empty string and the package name will be copied into it.
3873: (Make sure the string is long enough)
3875: Level: intermediate
3877: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
3878: @*/
3879: PetscErrorCode MatFactorGetSolverPackage(Mat mat, const MatSolverPackage *type)
3880: {
3881: PetscErrorCode ierr;
3882: PetscErrorCode (*conv)(Mat,const MatSolverPackage*);
3887: if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
3888: PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverPackage_C",(void (**)(void))&conv);
3889: if (!conv) {
3890: *type = MATSOLVERPETSC;
3891: } else {
3892: (*conv)(mat,type);
3893: }
3894: return(0);
3895: }
3899: /*@C
3900: MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic()
3902: Collective on Mat
3904: Input Parameters:
3905: + mat - the matrix
3906: . type - name of solver type, for example, spooles, superlu, plapack, petsc (to use PETSc's default)
3907: - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
3909: Output Parameters:
3910: . f - the factor matrix used with MatXXFactorSymbolic() calls
3912: Notes:
3913: Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
3914: such as pastix, superlu, mumps, spooles etc.
3916: PETSc must have been ./configure to use the external solver, using the option --download-package
3918: Level: intermediate
3920: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
3921: @*/
3922: PetscErrorCode MatGetFactor(Mat mat, const MatSolverPackage type,MatFactorType ftype,Mat *f)
3923: {
3924: PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
3925: char convname[256];
3931: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3932: MatPreallocated(mat);
3934: PetscStrcpy(convname,"MatGetFactor_");
3935: PetscStrcat(convname,type);
3936: PetscStrcat(convname,"_C");
3937: PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);
3938: if (!conv) {
3939: PetscBool flag;
3940: MPI_Comm comm;
3942: PetscObjectGetComm((PetscObject)mat,&comm);
3943: PetscStrcasecmp(MATSOLVERPETSC,type,&flag);
3944: if (flag) {
3945: SETERRQ2(comm,PETSC_ERR_SUP,"Matrix format %s does not have a built-in PETSc %s",((PetscObject)mat)->type_name,MatFactorTypes[ftype]);
3946: } else {
3947: 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);
3948: }
3949: }
3950: (*conv)(mat,ftype,f);
3951: return(0);
3952: }
3956: /*@C
3957: MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type
3959: Not Collective
3961: Input Parameters:
3962: + mat - the matrix
3963: . type - name of solver type, for example, spooles, superlu, plapack, petsc (to use PETSc's default)
3964: - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
3966: Output Parameter:
3967: . flg - PETSC_TRUE if the factorization is available
3969: Notes:
3970: Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
3971: such as pastix, superlu, mumps, spooles etc.
3973: PETSc must have been ./configure to use the external solver, using the option --download-package
3975: Level: intermediate
3977: .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
3978: @*/
3979: PetscErrorCode MatGetFactorAvailable(Mat mat, const MatSolverPackage type,MatFactorType ftype,PetscBool *flg)
3980: {
3981: PetscErrorCode ierr;
3982: char convname[256];
3983: PetscErrorCode (*conv)(Mat,MatFactorType,PetscBool *);
3989: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3990: MatPreallocated(mat);
3992: PetscStrcpy(convname,"MatGetFactorAvailable_");
3993: PetscStrcat(convname,type);
3994: PetscStrcat(convname,"_C");
3995: PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);
3996: if (!conv) {
3997: *flg = PETSC_FALSE;
3998: } else {
3999: (*conv)(mat,ftype,flg);
4000: }
4001: return(0);
4002: }
4007: /*@
4008: MatDuplicate - Duplicates a matrix including the non-zero structure.
4010: Collective on Mat
4012: Input Parameters:
4013: + mat - the matrix
4014: - op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy the numerical values in the matrix
4015: MAT_SHARE_NONZERO_PATTERN to share the nonzero patterns with the previous matrix and not copy them.
4017: Output Parameter:
4018: . M - pointer to place new matrix
4020: Level: intermediate
4022: Concepts: matrices^duplicating
4024: Notes: You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN.
4026: .seealso: MatCopy(), MatConvert()
4027: @*/
4028: PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4029: {
4031: Mat B;
4032: PetscInt i;
4038: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4039: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4040: MatPreallocated(mat);
4042: *M = 0;
4043: if (!mat->ops->duplicate) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Not written for this matrix type");
4044: PetscLogEventBegin(MAT_Convert,mat,0,0,0);
4045: (*mat->ops->duplicate)(mat,op,M);
4046: B = *M;
4047:
4048: B->stencil.dim = mat->stencil.dim;
4049: B->stencil.noc = mat->stencil.noc;
4050: for (i=0; i<=mat->stencil.dim; i++) {
4051: B->stencil.dims[i] = mat->stencil.dims[i];
4052: B->stencil.starts[i] = mat->stencil.starts[i];
4053: }
4055: B->nooffproczerorows = mat->nooffproczerorows;
4056: B->nooffprocentries = mat->nooffprocentries;
4057: PetscLogEventEnd(MAT_Convert,mat,0,0,0);
4058: PetscObjectStateIncrease((PetscObject)B);
4059: return(0);
4060: }
4064: /*@
4065: MatGetDiagonal - Gets the diagonal of a matrix.
4067: Logically Collective on Mat and Vec
4069: Input Parameters:
4070: + mat - the matrix
4071: - v - the vector for storing the diagonal
4073: Output Parameter:
4074: . v - the diagonal of the matrix
4076: Level: intermediate
4078: Concepts: matrices^accessing diagonals
4080: .seealso: MatGetRow(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs()
4081: @*/
4082: PetscErrorCode MatGetDiagonal(Mat mat,Vec v)
4083: {
4090: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4091: if (!mat->ops->getdiagonal) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4092: MatPreallocated(mat);
4094: (*mat->ops->getdiagonal)(mat,v);
4095: PetscObjectStateIncrease((PetscObject)v);
4096: return(0);
4097: }
4101: /*@
4102: MatGetRowMin - Gets the minimum value (of the real part) of each
4103: row of the matrix
4105: Logically Collective on Mat and Vec
4107: Input Parameters:
4108: . mat - the matrix
4110: Output Parameter:
4111: + v - the vector for storing the maximums
4112: - idx - the indices of the column found for each row (optional)
4114: Level: intermediate
4116: Notes: The result of this call are the same as if one converted the matrix to dense format
4117: and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4119: This code is only implemented for a couple of matrix formats.
4121: Concepts: matrices^getting row maximums
4123: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(),
4124: MatGetRowMax()
4125: @*/
4126: PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4127: {
4134: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4135: if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4136: MatPreallocated(mat);
4138: (*mat->ops->getrowmin)(mat,v,idx);
4139: PetscObjectStateIncrease((PetscObject)v);
4140: return(0);
4141: }
4145: /*@
4146: MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4147: row of the matrix
4149: Logically Collective on Mat and Vec
4151: Input Parameters:
4152: . mat - the matrix
4154: Output Parameter:
4155: + v - the vector for storing the minimums
4156: - idx - the indices of the column found for each row (optional)
4158: Level: intermediate
4160: Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
4161: row is 0 (the first column).
4163: This code is only implemented for a couple of matrix formats.
4165: Concepts: matrices^getting row maximums
4167: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4168: @*/
4169: PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4170: {
4177: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4178: if (!mat->ops->getrowminabs) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4179: MatPreallocated(mat);
4180: if (idx) {PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));}
4182: (*mat->ops->getrowminabs)(mat,v,idx);
4183: PetscObjectStateIncrease((PetscObject)v);
4184: return(0);
4185: }
4189: /*@
4190: MatGetRowMax - Gets the maximum value (of the real part) of each
4191: row of the matrix
4193: Logically Collective on Mat and Vec
4195: Input Parameters:
4196: . mat - the matrix
4198: Output Parameter:
4199: + v - the vector for storing the maximums
4200: - idx - the indices of the column found for each row (optional)
4202: Level: intermediate
4204: Notes: The result of this call are the same as if one converted the matrix to dense format
4205: and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4207: This code is only implemented for a couple of matrix formats.
4209: Concepts: matrices^getting row maximums
4211: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4212: @*/
4213: PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4214: {
4221: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4222: if (!mat->ops->getrowmax) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4223: MatPreallocated(mat);
4225: (*mat->ops->getrowmax)(mat,v,idx);
4226: PetscObjectStateIncrease((PetscObject)v);
4227: return(0);
4228: }
4232: /*@
4233: MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4234: row of the matrix
4236: Logically Collective on Mat and Vec
4238: Input Parameters:
4239: . mat - the matrix
4241: Output Parameter:
4242: + v - the vector for storing the maximums
4243: - idx - the indices of the column found for each row (optional)
4245: Level: intermediate
4247: Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
4248: row is 0 (the first column).
4250: This code is only implemented for a couple of matrix formats.
4252: Concepts: matrices^getting row maximums
4254: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4255: @*/
4256: PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4257: {
4264: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4265: if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4266: MatPreallocated(mat);
4267: if (idx) {PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));}
4269: (*mat->ops->getrowmaxabs)(mat,v,idx);
4270: PetscObjectStateIncrease((PetscObject)v);
4271: return(0);
4272: }
4276: /*@
4277: MatGetRowSum - Gets the sum of each row of the matrix
4279: Logically Collective on Mat and Vec
4281: Input Parameters:
4282: . mat - the matrix
4284: Output Parameter:
4285: . v - the vector for storing the sum of rows
4287: Level: intermediate
4289: Notes: This code is slow since it is not currently specialized for different formats
4291: Concepts: matrices^getting row sums
4293: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4294: @*/
4295: PetscErrorCode MatGetRowSum(Mat mat, Vec v)
4296: {
4297: PetscInt start = 0, end = 0, row;
4298: PetscScalar *array;
4305: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4306: MatPreallocated(mat);
4307: MatGetOwnershipRange(mat, &start, &end);
4308: VecGetArray(v, &array);
4309: for(row = start; row < end; ++row) {
4310: PetscInt ncols, col;
4311: const PetscInt *cols;
4312: const PetscScalar *vals;
4314: array[row - start] = 0.0;
4315: MatGetRow(mat, row, &ncols, &cols, &vals);
4316: for(col = 0; col < ncols; col++) {
4317: array[row - start] += vals[col];
4318: }
4319: MatRestoreRow(mat, row, &ncols, &cols, &vals);
4320: }
4321: VecRestoreArray(v, &array);
4322: PetscObjectStateIncrease((PetscObject) v);
4323: return(0);
4324: }
4328: /*@
4329: MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
4331: Collective on Mat
4333: Input Parameter:
4334: + mat - the matrix to transpose
4335: - reuse - store the transpose matrix in the provided B
4337: Output Parameters:
4338: . B - the transpose
4340: Notes:
4341: If you pass in &mat for B the transpose will be done in place, for example MatTranspose(mat,MAT_REUSE_MATRIX,&mat);
4343: Level: intermediate
4345: Concepts: matrices^transposing
4347: .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4348: @*/
4349: PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4350: {
4356: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4357: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4358: if (!mat->ops->transpose) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4359: MatPreallocated(mat);
4361: PetscLogEventBegin(MAT_Transpose,mat,0,0,0);
4362: (*mat->ops->transpose)(mat,reuse,B);
4363: PetscLogEventEnd(MAT_Transpose,mat,0,0,0);
4364: if (B) {PetscObjectStateIncrease((PetscObject)*B);}
4365: return(0);
4366: }
4370: /*@
4371: MatIsTranspose - Test whether a matrix is another one's transpose,
4372: or its own, in which case it tests symmetry.
4374: Collective on Mat
4376: Input Parameter:
4377: + A - the matrix to test
4378: - B - the matrix to test against, this can equal the first parameter
4380: Output Parameters:
4381: . flg - the result
4383: Notes:
4384: Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4385: has a running time of the order of the number of nonzeros; the parallel
4386: test involves parallel copies of the block-offdiagonal parts of the matrix.
4388: Level: intermediate
4390: Concepts: matrices^transposing, matrix^symmetry
4392: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4393: @*/
4394: PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg)
4395: {
4396: PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool *),(*g)(Mat,Mat,PetscReal,PetscBool *);
4402: PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",(void (**)(void))&f);
4403: PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",(void (**)(void))&g);
4404: *flg = PETSC_FALSE;
4405: if (f && g) {
4406: if (f == g) {
4407: (*f)(A,B,tol,flg);
4408: } else {
4409: SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4410: }
4411: } else {
4412: const MatType mattype;
4413: if (!f) {MatGetType(A,&mattype);}
4414: else {MatGetType(B,&mattype);}
4415: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
4416: }
4417: return(0);
4418: }
4422: /*@
4423: MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate.
4425: Collective on Mat
4427: Input Parameter:
4428: + mat - the matrix to transpose and complex conjugate
4429: - reuse - store the transpose matrix in the provided B
4431: Output Parameters:
4432: . B - the Hermitian
4434: Notes:
4435: If you pass in &mat for B the Hermitian will be done in place
4437: Level: intermediate
4439: Concepts: matrices^transposing, complex conjugatex
4441: .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4442: @*/
4443: PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
4444: {
4448: MatTranspose(mat,reuse,B);
4449: #if defined(PETSC_USE_COMPLEX)
4450: MatConjugate(*B);
4451: #endif
4452: return(0);
4453: }
4457: /*@
4458: MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,
4460: Collective on Mat
4462: Input Parameter:
4463: + A - the matrix to test
4464: - B - the matrix to test against, this can equal the first parameter
4466: Output Parameters:
4467: . flg - the result
4469: Notes:
4470: Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4471: has a running time of the order of the number of nonzeros; the parallel
4472: test involves parallel copies of the block-offdiagonal parts of the matrix.
4474: Level: intermediate
4476: Concepts: matrices^transposing, matrix^symmetry
4478: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
4479: @*/
4480: PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg)
4481: {
4482: PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool *),(*g)(Mat,Mat,PetscReal,PetscBool *);
4488: PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",(void (**)(void))&f);
4489: PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",(void (**)(void))&g);
4490: if (f && g) {
4491: if (f==g) {
4492: (*f)(A,B,tol,flg);
4493: } else {
4494: SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
4495: }
4496: }
4497: return(0);
4498: }
4502: /*@
4503: MatPermute - Creates a new matrix with rows and columns permuted from the
4504: original.
4506: Collective on Mat
4508: Input Parameters:
4509: + mat - the matrix to permute
4510: . row - row permutation, each processor supplies only the permutation for its rows
4511: - col - column permutation, each processor needs the entire column permutation, that is
4512: this is the same size as the total number of columns in the matrix. It can often
4513: be obtained with ISAllGather() on the row permutation
4515: Output Parameters:
4516: . B - the permuted matrix
4518: Level: advanced
4520: Concepts: matrices^permuting
4522: .seealso: MatGetOrdering(), ISAllGather()
4524: @*/
4525: PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
4526: {
4535: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4536: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4537: if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
4538: MatPreallocated(mat);
4540: (*mat->ops->permute)(mat,row,col,B);
4541: PetscObjectStateIncrease((PetscObject)*B);
4542: return(0);
4543: }
4547: /*@
4548: MatEqual - Compares two matrices.
4550: Collective on Mat
4552: Input Parameters:
4553: + A - the first matrix
4554: - B - the second matrix
4556: Output Parameter:
4557: . flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
4559: Level: intermediate
4561: Concepts: matrices^equality between
4562: @*/
4563: PetscErrorCode MatEqual(Mat A,Mat B,PetscBool *flg)
4564: {
4574: MatPreallocated(B);
4575: if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4576: if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4577: if (A->rmap->N != B->rmap->N || A->cmap->N != B->cmap->N) SETERRQ4(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %D %D %D %D",A->rmap->N,B->rmap->N,A->cmap->N,B->cmap->N);
4578: if (!A->ops->equal) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4579: if (!B->ops->equal) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4580: if (A->ops->equal != B->ops->equal) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_INCOMP,"A is type: %s\nB is type: %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
4581: MatPreallocated(A);
4583: (*A->ops->equal)(A,B,flg);
4584: return(0);
4585: }
4589: /*@
4590: MatDiagonalScale - Scales a matrix on the left and right by diagonal
4591: matrices that are stored as vectors. Either of the two scaling
4592: matrices can be PETSC_NULL.
4594: Collective on Mat
4596: Input Parameters:
4597: + mat - the matrix to be scaled
4598: . l - the left scaling vector (or PETSC_NULL)
4599: - r - the right scaling vector (or PETSC_NULL)
4601: Notes:
4602: MatDiagonalScale() computes A = LAR, where
4603: L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
4604: The L scales the rows of the matrix, the R scales the columns of the matrix.
4606: Level: intermediate
4608: Concepts: matrices^diagonal scaling
4609: Concepts: diagonal scaling of matrices
4611: .seealso: MatScale()
4612: @*/
4613: PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
4614: {
4620: if (!mat->ops->diagonalscale) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4623: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4624: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4625: MatPreallocated(mat);
4627: PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4628: (*mat->ops->diagonalscale)(mat,l,r);
4629: PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4630: PetscObjectStateIncrease((PetscObject)mat);
4631: #if defined(PETSC_HAVE_CUSP)
4632: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4633: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4634: }
4635: #endif
4636: return(0);
4637: }
4641: /*@
4642: MatScale - Scales all elements of a matrix by a given number.
4644: Logically Collective on Mat
4646: Input Parameters:
4647: + mat - the matrix to be scaled
4648: - a - the scaling value
4650: Output Parameter:
4651: . mat - the scaled matrix
4653: Level: intermediate
4655: Concepts: matrices^scaling all entries
4657: .seealso: MatDiagonalScale()
4658: @*/
4659: PetscErrorCode MatScale(Mat mat,PetscScalar a)
4660: {
4666: if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4667: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4668: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4670: MatPreallocated(mat);
4672: PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4673: if (a != (PetscScalar)1.0) {
4674: (*mat->ops->scale)(mat,a);
4675: PetscObjectStateIncrease((PetscObject)mat);
4676: }
4677: PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4678: #if defined(PETSC_HAVE_CUSP)
4679: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4680: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4681: }
4682: #endif
4683: return(0);
4684: }
4688: /*@
4689: MatNorm - Calculates various norms of a matrix.
4691: Collective on Mat
4693: Input Parameters:
4694: + mat - the matrix
4695: - type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
4697: Output Parameters:
4698: . nrm - the resulting norm
4700: Level: intermediate
4702: Concepts: matrices^norm
4703: Concepts: norm^of matrix
4704: @*/
4705: PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
4706: {
4714: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4715: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4716: if (!mat->ops->norm) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4717: MatPreallocated(mat);
4719: (*mat->ops->norm)(mat,type,nrm);
4720: return(0);
4721: }
4723: /*
4724: This variable is used to prevent counting of MatAssemblyBegin() that
4725: are called from within a MatAssemblyEnd().
4726: */
4727: static PetscInt MatAssemblyEnd_InUse = 0;
4730: /*@
4731: MatAssemblyBegin - Begins assembling the matrix. This routine should
4732: be called after completing all calls to MatSetValues().
4734: Collective on Mat
4736: Input Parameters:
4737: + mat - the matrix
4738: - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
4739:
4740: Notes:
4741: MatSetValues() generally caches the values. The matrix is ready to
4742: use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4743: Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4744: in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4745: using the matrix.
4747: Level: beginner
4749: Concepts: matrices^assembling
4751: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
4752: @*/
4753: PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
4754: {
4760: MatPreallocated(mat);
4761: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
4762: if (mat->assembled) {
4763: mat->was_assembled = PETSC_TRUE;
4764: mat->assembled = PETSC_FALSE;
4765: }
4766: if (!MatAssemblyEnd_InUse) {
4767: PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);
4768: if (mat->ops->assemblybegin){(*mat->ops->assemblybegin)(mat,type);}
4769: PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);
4770: } else {
4771: if (mat->ops->assemblybegin){(*mat->ops->assemblybegin)(mat,type);}
4772: }
4773: return(0);
4774: }
4778: /*@
4779: MatAssembled - Indicates if a matrix has been assembled and is ready for
4780: use; for example, in matrix-vector product.
4782: Not Collective
4784: Input Parameter:
4785: . mat - the matrix
4787: Output Parameter:
4788: . assembled - PETSC_TRUE or PETSC_FALSE
4790: Level: advanced
4792: Concepts: matrices^assembled?
4794: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
4795: @*/
4796: PetscErrorCode MatAssembled(Mat mat,PetscBool *assembled)
4797: {
4802: *assembled = mat->assembled;
4803: return(0);
4804: }
4808: /*
4809: Processes command line options to determine if/how a matrix
4810: is to be viewed. Called by MatAssemblyEnd() and MatLoad().
4811: */
4812: PetscErrorCode MatView_Private(Mat mat)
4813: {
4814: PetscErrorCode ierr;
4815: PetscBool flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE,flg4 = PETSC_FALSE,flg6 = PETSC_FALSE,flg7 = PETSC_FALSE,flg8 = PETSC_FALSE;
4816: static PetscBool incall = PETSC_FALSE;
4817: #if defined(PETSC_USE_SOCKET_VIEWER)
4818: PetscBool flg5 = PETSC_FALSE;
4819: #endif
4822: if (incall) return(0);
4823: incall = PETSC_TRUE;
4824: PetscObjectOptionsBegin((PetscObject)mat);
4825: PetscOptionsBool("-mat_view_info","Information on matrix size","MatView",flg1,&flg1,PETSC_NULL);
4826: PetscOptionsBool("-mat_view_info_detailed","Nonzeros in the matrix","MatView",flg2,&flg2,PETSC_NULL);
4827: PetscOptionsBool("-mat_view","Print matrix to stdout","MatView",flg3,&flg3,PETSC_NULL);
4828: PetscOptionsBool("-mat_view_matlab","Print matrix to stdout in a format Matlab can read","MatView",flg4,&flg4,PETSC_NULL);
4829: #if defined(PETSC_USE_SOCKET_VIEWER)
4830: PetscOptionsBool("-mat_view_socket","Send matrix to socket (can be read from matlab)","MatView",flg5,&flg5,PETSC_NULL);
4831: #endif
4832: PetscOptionsBool("-mat_view_binary","Save matrix to file in binary format","MatView",flg6,&flg6,PETSC_NULL);
4833: PetscOptionsBool("-mat_view_draw","Draw the matrix nonzero structure","MatView",flg7,&flg7,PETSC_NULL);
4834: PetscOptionsEnd();
4836: if (flg1) {
4837: PetscViewer viewer;
4839: PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4840: PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO);
4841: MatView(mat,viewer);
4842: PetscViewerPopFormat(viewer);
4843: }
4844: if (flg2) {
4845: PetscViewer viewer;
4847: PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4848: PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO_DETAIL);
4849: MatView(mat,viewer);
4850: PetscViewerPopFormat(viewer);
4851: }
4852: if (flg3) {
4853: PetscViewer viewer;
4855: PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4856: MatView(mat,viewer);
4857: }
4858: if (flg4) {
4859: PetscViewer viewer;
4861: PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4862: PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);
4863: MatView(mat,viewer);
4864: PetscViewerPopFormat(viewer);
4865: }
4866: #if defined(PETSC_USE_SOCKET_VIEWER)
4867: if (flg5) {
4868: MatView(mat,PETSC_VIEWER_SOCKET_(((PetscObject)mat)->comm));
4869: PetscViewerFlush(PETSC_VIEWER_SOCKET_(((PetscObject)mat)->comm));
4870: }
4871: #endif
4872: if (flg6) {
4873: MatView(mat,PETSC_VIEWER_BINARY_(((PetscObject)mat)->comm));
4874: PetscViewerFlush(PETSC_VIEWER_BINARY_(((PetscObject)mat)->comm));
4875: }
4876: if (flg7) {
4877: PetscOptionsGetBool(((PetscObject)mat)->prefix,"-mat_view_contour",&flg8,PETSC_NULL);
4878: if (flg8) {
4879: PetscViewerPushFormat(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm),PETSC_VIEWER_DRAW_CONTOUR);
4880: }
4881: MatView(mat,PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));
4882: PetscViewerFlush(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));
4883: if (flg8) {
4884: PetscViewerPopFormat(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));
4885: }
4886: }
4887: incall = PETSC_FALSE;
4888: return(0);
4889: }
4893: /*@
4894: MatAssemblyEnd - Completes assembling the matrix. This routine should
4895: be called after MatAssemblyBegin().
4897: Collective on Mat
4899: Input Parameters:
4900: + mat - the matrix
4901: - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
4903: Options Database Keys:
4904: + -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly()
4905: . -mat_view_info_detailed - Prints more detailed info
4906: . -mat_view - Prints matrix in ASCII format
4907: . -mat_view_matlab - Prints matrix in Matlab format
4908: . -mat_view_draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
4909: . -display <name> - Sets display name (default is host)
4910: . -draw_pause <sec> - Sets number of seconds to pause after display
4911: . -mat_view_socket - Sends matrix to socket, can be accessed from Matlab (See the <a href="../../docs/manual.pdf">users manual</a>)
4912: . -viewer_socket_machine <machine>
4913: . -viewer_socket_port <port>
4914: . -mat_view_binary - save matrix to file in binary format
4915: - -viewer_binary_filename <name>
4917: Notes:
4918: MatSetValues() generally caches the values. The matrix is ready to
4919: use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4920: Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4921: in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4922: using the matrix.
4924: Level: beginner
4926: .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), MatView(), MatAssembled(), PetscViewerSocketOpen()
4927: @*/
4928: PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
4929: {
4930: PetscErrorCode ierr;
4931: static PetscInt inassm = 0;
4932: PetscBool flg = PETSC_FALSE;
4938: inassm++;
4939: MatAssemblyEnd_InUse++;
4940: if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
4941: PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);
4942: if (mat->ops->assemblyend) {
4943: (*mat->ops->assemblyend)(mat,type);
4944: }
4945: PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);
4946: } else {
4947: if (mat->ops->assemblyend) {
4948: (*mat->ops->assemblyend)(mat,type);
4949: }
4950: }
4952: /* Flush assembly is not a true assembly */
4953: if (type != MAT_FLUSH_ASSEMBLY) {
4954: mat->assembled = PETSC_TRUE; mat->num_ass++;
4955: }
4956: mat->insertmode = NOT_SET_VALUES;
4957: MatAssemblyEnd_InUse--;
4958: PetscObjectStateIncrease((PetscObject)mat);
4959: if (!mat->symmetric_eternal) {
4960: mat->symmetric_set = PETSC_FALSE;
4961: mat->hermitian_set = PETSC_FALSE;
4962: mat->structurally_symmetric_set = PETSC_FALSE;
4963: }
4964: if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
4965: MatView_Private(mat);
4966: PetscOptionsGetBool(((PetscObject)mat)->prefix,"-mat_is_symmetric",&flg,PETSC_NULL);
4967: if (flg) {
4968: PetscReal tol = 0.0;
4969: PetscOptionsGetReal(((PetscObject)mat)->prefix,"-mat_is_symmetric",&tol,PETSC_NULL);
4970: MatIsSymmetric(mat,tol,&flg);
4971: if (flg) {
4972: PetscPrintf(((PetscObject)mat)->comm,"Matrix is symmetric (tolerance %G)\n",tol);
4973: } else {
4974: PetscPrintf(((PetscObject)mat)->comm,"Matrix is not symmetric (tolerance %G)\n",tol);
4975: }
4976: }
4977: }
4978: inassm--;
4979: #if defined(PETSC_HAVE_CUSP)
4980: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4981: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4982: }
4983: #endif
4984: return(0);
4985: }
4989: /*@
4990: MatSetOption - Sets a parameter option for a matrix. Some options
4991: may be specific to certain storage formats. Some options
4992: determine how values will be inserted (or added). Sorted,
4993: row-oriented input will generally assemble the fastest. The default
4994: is row-oriented, nonsorted input.
4996: Logically Collective on Mat
4998: Input Parameters:
4999: + mat - the matrix
5000: . option - the option, one of those listed below (and possibly others),
5001: - flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5003: Options Describing Matrix Structure:
5004: + MAT_SPD - symmetric positive definite
5005: - MAT_SYMMETRIC - symmetric in terms of both structure and value
5006: . MAT_HERMITIAN - transpose is the complex conjugation
5007: . MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5008: - MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5009: you set to be kept with all future use of the matrix
5010: including after MatAssemblyBegin/End() which could
5011: potentially change the symmetry structure, i.e. you
5012: KNOW the matrix will ALWAYS have the property you set.
5015: Options For Use with MatSetValues():
5016: Insert a logically dense subblock, which can be
5017: . MAT_ROW_ORIENTED - row-oriented (default)
5019: Note these options reflect the data you pass in with MatSetValues(); it has
5020: nothing to do with how the data is stored internally in the matrix
5021: data structure.
5023: When (re)assembling a matrix, we can restrict the input for
5024: efficiency/debugging purposes. These options include
5025: + MAT_NEW_NONZERO_LOCATIONS - additional insertions will be
5026: allowed if they generate a new nonzero
5027: . MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
5028: . MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
5029: . MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
5030: . MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
5031: + MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
5032: any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
5033: performance for very large process counts.
5035: Notes:
5036: Some options are relevant only for particular matrix types and
5037: are thus ignored by others. Other options are not supported by
5038: certain matrix types and will generate an error message if set.
5040: If using a Fortran 77 module to compute a matrix, one may need to
5041: use the column-oriented option (or convert to the row-oriented
5042: format).
5044: MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
5045: that would generate a new entry in the nonzero structure is instead
5046: ignored. Thus, if memory has not alredy been allocated for this particular
5047: data, then the insertion is ignored. For dense matrices, in which
5048: the entire array is allocated, no entries are ever ignored.
5049: Set after the first MatAssemblyEnd()
5051: MAT_NEW_NONZERO_LOCATION_ERR indicates that any add or insertion
5052: that would generate a new entry in the nonzero structure instead produces
5053: an error. (Currently supported for AIJ and BAIJ formats only.)
5054: This is a useful flag when using SAME_NONZERO_PATTERN in calling
5055: KSPSetOperators() to ensure that the nonzero pattern truely does
5056: remain unchanged. Set after the first MatAssemblyEnd()
5058: MAT_NEW_NONZERO_ALLOCATION_ERR indicates that any add or insertion
5059: that would generate a new entry that has not been preallocated will
5060: instead produce an error. (Currently supported for AIJ and BAIJ formats
5061: only.) This is a useful flag when debugging matrix memory preallocation.
5063: MAT_IGNORE_OFF_PROC_ENTRIES indicates entries destined for
5064: other processors should be dropped, rather than stashed.
5065: This is useful if you know that the "owning" processor is also
5066: always generating the correct matrix entries, so that PETSc need
5067: not transfer duplicate entries generated on another processor.
5068:
5069: MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5070: searches during matrix assembly. When this flag is set, the hash table
5071: is created during the first Matrix Assembly. This hash table is
5072: used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5073: to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5074: should be used with MAT_USE_HASH_TABLE flag. This option is currently
5075: supported by MATMPIBAIJ format only.
5077: MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries
5078: are kept in the nonzero structure
5080: MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
5081: a zero location in the matrix
5083: MAT_USE_INODES - indicates using inode version of the code - works with AIJ and
5084: ROWBS matrix types
5086: MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the
5087: zero row routines and thus improves performance for very large process counts.
5089: MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular
5090: part of the matrix (since they should match the upper triangular part).
5092: Level: intermediate
5094: Concepts: matrices^setting options
5096: @*/
5097: PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg)
5098: {
5107: if (((int) op) < 0 || ((int) op) >= NUM_MAT_OPTIONS) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Options %d is out of range",(int)op);
5108: if (!((PetscObject)mat)->type_name) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_TYPENOTSET,"Cannot set options until type and size have been set, see MatSetType() and MatSetSizes()");
5109: MatPreallocated(mat);
5110: switch (op) {
5111: case MAT_NO_OFF_PROC_ENTRIES:
5112: mat->nooffprocentries = flg;
5113: return(0);
5114: break;
5115: case MAT_NO_OFF_PROC_ZERO_ROWS:
5116: mat->nooffproczerorows = flg;
5117: return(0);
5118: break;
5119: case MAT_SPD:
5120: mat->spd_set = PETSC_TRUE;
5121: mat->spd = flg;
5122: if (flg) {
5123: mat->symmetric = PETSC_TRUE;
5124: mat->structurally_symmetric = PETSC_TRUE;
5125: mat->symmetric_set = PETSC_TRUE;
5126: mat->structurally_symmetric_set = PETSC_TRUE;
5127: }
5128: break;
5129: case MAT_SYMMETRIC:
5130: mat->symmetric = flg;
5131: if (flg) mat->structurally_symmetric = PETSC_TRUE;
5132: mat->symmetric_set = PETSC_TRUE;
5133: mat->structurally_symmetric_set = flg;
5134: break;
5135: case MAT_HERMITIAN:
5136: mat->hermitian = flg;
5137: if (flg) mat->structurally_symmetric = PETSC_TRUE;
5138: mat->hermitian_set = PETSC_TRUE;
5139: mat->structurally_symmetric_set = flg;
5140: break;
5141: case MAT_STRUCTURALLY_SYMMETRIC:
5142: mat->structurally_symmetric = flg;
5143: mat->structurally_symmetric_set = PETSC_TRUE;
5144: break;
5145: case MAT_SYMMETRY_ETERNAL:
5146: mat->symmetric_eternal = flg;
5147: break;
5148: default:
5149: break;
5150: }
5151: if (mat->ops->setoption) {
5152: (*mat->ops->setoption)(mat,op,flg);
5153: }
5154: return(0);
5155: }
5159: /*@
5160: MatZeroEntries - Zeros all entries of a matrix. For sparse matrices
5161: this routine retains the old nonzero structure.
5163: Logically Collective on Mat
5165: Input Parameters:
5166: . mat - the matrix
5168: Level: intermediate
5170: 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.
5171: See the Performance chapter of the users manual for information on preallocating matrices.
5173: Concepts: matrices^zeroing
5175: .seealso: MatZeroRows()
5176: @*/
5177: PetscErrorCode MatZeroEntries(Mat mat)
5178: {
5184: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5185: 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");
5186: if (!mat->ops->zeroentries) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5187: MatPreallocated(mat);
5189: PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);
5190: (*mat->ops->zeroentries)(mat);
5191: PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);
5192: PetscObjectStateIncrease((PetscObject)mat);
5193: #if defined(PETSC_HAVE_CUSP)
5194: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5195: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5196: }
5197: #endif
5198: return(0);
5199: }
5203: /*@C
5204: MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal)
5205: of a set of rows and columns of a matrix.
5207: Collective on Mat
5209: Input Parameters:
5210: + mat - the matrix
5211: . numRows - the number of rows to remove
5212: . rows - the global row indices
5213: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5214: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5215: - b - optional vector of right hand side, that will be adjusted by provided solution
5217: Notes:
5218: This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5220: The user can set a value in the diagonal entry (or for the AIJ and
5221: row formats can optionally remove the main diagonal entry from the
5222: nonzero structure as well, by passing 0.0 as the final argument).
5224: For the parallel case, all processes that share the matrix (i.e.,
5225: those in the communicator used for matrix creation) MUST call this
5226: routine, regardless of whether any rows being zeroed are owned by
5227: them.
5229: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5230: list only rows local to itself).
5232: The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5234: Level: intermediate
5236: Concepts: matrices^zeroing rows
5238: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumnsIS()
5239: @*/
5240: PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5241: {
5248: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5249: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5250: if (!mat->ops->zerorowscolumns) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5251: MatPreallocated(mat);
5253: (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);
5254: MatView_Private(mat);
5255: PetscObjectStateIncrease((PetscObject)mat);
5256: #if defined(PETSC_HAVE_CUSP)
5257: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5258: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5259: }
5260: #endif
5261: return(0);
5262: }
5266: /*@C
5267: MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
5268: of a set of rows and columns of a matrix.
5270: Collective on Mat
5272: Input Parameters:
5273: + mat - the matrix
5274: . is - the rows to zero
5275: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5276: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5277: - b - optional vector of right hand side, that will be adjusted by provided solution
5279: Notes:
5280: This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5282: The user can set a value in the diagonal entry (or for the AIJ and
5283: row formats can optionally remove the main diagonal entry from the
5284: nonzero structure as well, by passing 0.0 as the final argument).
5286: For the parallel case, all processes that share the matrix (i.e.,
5287: those in the communicator used for matrix creation) MUST call this
5288: routine, regardless of whether any rows being zeroed are owned by
5289: them.
5291: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5292: list only rows local to itself).
5294: The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5296: Level: intermediate
5298: Concepts: matrices^zeroing rows
5300: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumns()
5301: @*/
5302: PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5303: {
5305: PetscInt numRows;
5306: const PetscInt *rows;
5313: ISGetLocalSize(is,&numRows);
5314: ISGetIndices(is,&rows);
5315: MatZeroRowsColumns(mat,numRows,rows,diag,x,b);
5316: ISRestoreIndices(is,&rows);
5317: return(0);
5318: }
5322: /*@C
5323: MatZeroRows - Zeros all entries (except possibly the main diagonal)
5324: of a set of rows of a matrix.
5326: Collective on Mat
5328: Input Parameters:
5329: + mat - the matrix
5330: . numRows - the number of rows to remove
5331: . rows - the global row indices
5332: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5333: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5334: - b - optional vector of right hand side, that will be adjusted by provided solution
5336: Notes:
5337: For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5338: but does not release memory. For the dense and block diagonal
5339: formats this does not alter the nonzero structure.
5341: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5342: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5343: merely zeroed.
5345: The user can set a value in the diagonal entry (or for the AIJ and
5346: row formats can optionally remove the main diagonal entry from the
5347: nonzero structure as well, by passing 0.0 as the final argument).
5349: For the parallel case, all processes that share the matrix (i.e.,
5350: those in the communicator used for matrix creation) MUST call this
5351: routine, regardless of whether any rows being zeroed are owned by
5352: them.
5354: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5355: list only rows local to itself).
5357: You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5358: owns that are to be zeroed. This saves a global synchronization in the implementation.
5360: Level: intermediate
5362: Concepts: matrices^zeroing rows
5364: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5365: @*/
5366: PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5367: {
5374: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5375: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5376: if (!mat->ops->zerorows) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5377: MatPreallocated(mat);
5379: (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);
5380: MatView_Private(mat);
5381: PetscObjectStateIncrease((PetscObject)mat);
5382: #if defined(PETSC_HAVE_CUSP)
5383: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5384: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5385: }
5386: #endif
5387: return(0);
5388: }
5392: /*@C
5393: MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5394: of a set of rows of a matrix.
5396: Collective on Mat
5398: Input Parameters:
5399: + mat - the matrix
5400: . is - index set of rows to remove
5401: . diag - value put in all diagonals of eliminated rows
5402: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5403: - b - optional vector of right hand side, that will be adjusted by provided solution
5405: Notes:
5406: For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5407: but does not release memory. For the dense and block diagonal
5408: formats this does not alter the nonzero structure.
5410: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5411: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5412: merely zeroed.
5414: The user can set a value in the diagonal entry (or for the AIJ and
5415: row formats can optionally remove the main diagonal entry from the
5416: nonzero structure as well, by passing 0.0 as the final argument).
5418: For the parallel case, all processes that share the matrix (i.e.,
5419: those in the communicator used for matrix creation) MUST call this
5420: routine, regardless of whether any rows being zeroed are owned by
5421: them.
5423: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5424: list only rows local to itself).
5426: You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5427: owns that are to be zeroed. This saves a global synchronization in the implementation.
5429: Level: intermediate
5431: Concepts: matrices^zeroing rows
5433: .seealso: MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5434: @*/
5435: PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5436: {
5437: PetscInt numRows;
5438: const PetscInt *rows;
5445: ISGetLocalSize(is,&numRows);
5446: ISGetIndices(is,&rows);
5447: MatZeroRows(mat,numRows,rows,diag,x,b);
5448: ISRestoreIndices(is,&rows);
5449: return(0);
5450: }
5454: /*@C
5455: MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
5456: of a set of rows of a matrix. These rows must be local to the process.
5458: Collective on Mat
5460: Input Parameters:
5461: + mat - the matrix
5462: . numRows - the number of rows to remove
5463: . rows - the grid coordinates (and component number when dof > 1) for matrix rows
5464: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5465: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5466: - b - optional vector of right hand side, that will be adjusted by provided solution
5468: Notes:
5469: For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5470: but does not release memory. For the dense and block diagonal
5471: formats this does not alter the nonzero structure.
5473: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5474: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5475: merely zeroed.
5477: The user can set a value in the diagonal entry (or for the AIJ and
5478: row formats can optionally remove the main diagonal entry from the
5479: nonzero structure as well, by passing 0.0 as the final argument).
5481: For the parallel case, all processes that share the matrix (i.e.,
5482: those in the communicator used for matrix creation) MUST call this
5483: routine, regardless of whether any rows being zeroed are owned by
5484: them.
5486: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5487: list only rows local to itself).
5489: The grid coordinates are across the entire grid, not just the local portion
5491: In Fortran idxm and idxn should be declared as
5492: $ MatStencil idxm(4,m)
5493: and the values inserted using
5494: $ idxm(MatStencil_i,1) = i
5495: $ idxm(MatStencil_j,1) = j
5496: $ idxm(MatStencil_k,1) = k
5497: $ idxm(MatStencil_c,1) = c
5498: etc
5500: For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5501: obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5502: etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5503: DMDA_BOUNDARY_PERIODIC boundary type.
5505: 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
5506: a single value per point) you can skip filling those indices.
5508: Level: intermediate
5510: Concepts: matrices^zeroing rows
5512: .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5513: @*/
5514: PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5515: {
5516: PetscInt dim = mat->stencil.dim;
5517: PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc);
5518: PetscInt *dims = mat->stencil.dims+1;
5519: PetscInt *starts = mat->stencil.starts;
5520: PetscInt *dxm = (PetscInt *) rows;
5521: PetscInt *jdxm, i, j, tmp, numNewRows = 0;
5529: PetscMalloc(numRows*sizeof(PetscInt), &jdxm);
5530: for(i = 0; i < numRows; ++i) {
5531: /* Skip unused dimensions (they are ordered k, j, i, c) */
5532: for(j = 0; j < 3-sdim; ++j) dxm++;
5533: /* Local index in X dir */
5534: tmp = *dxm++ - starts[0];
5535: /* Loop over remaining dimensions */
5536: for(j = 0; j < dim-1; ++j) {
5537: /* If nonlocal, set index to be negative */
5538: if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5539: /* Update local index */
5540: else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5541: }
5542: /* Skip component slot if necessary */
5543: if (mat->stencil.noc) dxm++;
5544: /* Local row number */
5545: if (tmp >= 0) {
5546: jdxm[numNewRows++] = tmp;
5547: }
5548: }
5549: MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);
5550: PetscFree(jdxm);
5551: return(0);
5552: }
5556: /*@C
5557: MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
5558: of a set of rows of a matrix; using local numbering of rows.
5560: Collective on Mat
5562: Input Parameters:
5563: + mat - the matrix
5564: . numRows - the number of rows to remove
5565: . rows - the global row indices
5566: . diag - value put in all diagonals of eliminated rows
5567: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5568: - b - optional vector of right hand side, that will be adjusted by provided solution
5570: Notes:
5571: Before calling MatZeroRowsLocal(), the user must first set the
5572: local-to-global mapping by calling MatSetLocalToGlobalMapping().
5574: For the AIJ matrix formats this removes the old nonzero structure,
5575: but does not release memory. For the dense and block diagonal
5576: formats this does not alter the nonzero structure.
5578: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5579: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5580: merely zeroed.
5582: The user can set a value in the diagonal entry (or for the AIJ and
5583: row formats can optionally remove the main diagonal entry from the
5584: nonzero structure as well, by passing 0.0 as the final argument).
5586: You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5587: owns that are to be zeroed. This saves a global synchronization in the implementation.
5589: Level: intermediate
5591: Concepts: matrices^zeroing
5593: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5594: @*/
5595: PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5596: {
5598: PetscMPIInt size;
5604: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5605: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5606: MatPreallocated(mat);
5608: MPI_Comm_size(((PetscObject)mat)->comm,&size);
5609: if (mat->ops->zerorowslocal) {
5610: (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);
5611: } else if (size == 1) {
5612: (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);
5613: } else {
5614: IS is, newis;
5615: const PetscInt *newRows;
5617: if (!mat->rmap->mapping) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5618: ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
5619: ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);
5620: ISGetIndices(newis,&newRows);
5621: (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);
5622: ISRestoreIndices(newis,&newRows);
5623: ISDestroy(&newis);
5624: ISDestroy(&is);
5625: }
5626: PetscObjectStateIncrease((PetscObject)mat);
5627: #if defined(PETSC_HAVE_CUSP)
5628: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5629: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5630: }
5631: #endif
5632: return(0);
5633: }
5637: /*@C
5638: MatZeroRowsLocalIS - 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: . is - index set of rows to remove
5646: . diag - value put in all diagonals of eliminated rows
5647: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5648: - b - optional vector of right hand side, that will be adjusted by provided solution
5650: Notes:
5651: Before calling MatZeroRowsLocalIS(), the user must first set the
5652: local-to-global mapping by calling MatSetLocalToGlobalMapping().
5654: For the AIJ matrix formats this removes the old nonzero structure,
5655: but does not release memory. For the dense and block diagonal
5656: formats this does not alter the nonzero structure.
5658: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5659: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5660: merely zeroed.
5662: The user can set a value in the diagonal entry (or for the AIJ and
5663: row formats can optionally remove the main diagonal entry from the
5664: nonzero structure as well, by passing 0.0 as the final argument).
5666: You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5667: owns that are to be zeroed. This saves a global synchronization in the implementation.
5669: Level: intermediate
5671: Concepts: matrices^zeroing
5673: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5674: @*/
5675: PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5676: {
5678: PetscInt numRows;
5679: const PetscInt *rows;
5685: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5686: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5687: MatPreallocated(mat);
5689: ISGetLocalSize(is,&numRows);
5690: ISGetIndices(is,&rows);
5691: MatZeroRowsLocal(mat,numRows,rows,diag,x,b);
5692: ISRestoreIndices(is,&rows);
5693: return(0);
5694: }
5698: /*@C
5699: MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
5700: of a set of rows and columns of a matrix; using local numbering of rows.
5702: Collective on Mat
5704: Input Parameters:
5705: + mat - the matrix
5706: . numRows - the number of rows to remove
5707: . rows - the global row indices
5708: . diag - value put in all diagonals of eliminated rows
5709: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5710: - b - optional vector of right hand side, that will be adjusted by provided solution
5712: Notes:
5713: Before calling MatZeroRowsColumnsLocal(), the user must first set the
5714: local-to-global mapping by calling MatSetLocalToGlobalMapping().
5716: The user can set a value in the diagonal entry (or for the AIJ and
5717: row formats can optionally remove the main diagonal entry from the
5718: nonzero structure as well, by passing 0.0 as the final argument).
5720: Level: intermediate
5722: Concepts: matrices^zeroing
5724: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5725: @*/
5726: PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5727: {
5729: PetscMPIInt size;
5735: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5736: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5737: MatPreallocated(mat);
5739: MPI_Comm_size(((PetscObject)mat)->comm,&size);
5740: if (size == 1) {
5741: (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);
5742: } else {
5743: IS is, newis;
5744: const PetscInt *newRows;
5746: if (!mat->cmap->mapping) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5747: ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
5748: ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);
5749: ISGetIndices(newis,&newRows);
5750: (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);
5751: ISRestoreIndices(newis,&newRows);
5752: ISDestroy(&newis);
5753: ISDestroy(&is);
5754: }
5755: PetscObjectStateIncrease((PetscObject)mat);
5756: #if defined(PETSC_HAVE_CUSP)
5757: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5758: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5759: }
5760: #endif
5761: return(0);
5762: }
5766: /*@C
5767: MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
5768: of a set of rows and columns of a matrix; using local numbering of rows.
5770: Collective on Mat
5772: Input Parameters:
5773: + mat - the matrix
5774: . is - index set of rows to remove
5775: . diag - value put in all diagonals of eliminated rows
5776: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5777: - b - optional vector of right hand side, that will be adjusted by provided solution
5779: Notes:
5780: Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
5781: local-to-global mapping by calling MatSetLocalToGlobalMapping().
5783: The user can set a value in the diagonal entry (or for the AIJ and
5784: row formats can optionally remove the main diagonal entry from the
5785: nonzero structure as well, by passing 0.0 as the final argument).
5787: Level: intermediate
5789: Concepts: matrices^zeroing
5791: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5792: @*/
5793: PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5794: {
5796: PetscInt numRows;
5797: const PetscInt *rows;
5803: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5804: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5805: MatPreallocated(mat);
5807: ISGetLocalSize(is,&numRows);
5808: ISGetIndices(is,&rows);
5809: MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);
5810: ISRestoreIndices(is,&rows);
5811: return(0);
5812: }
5816: /*@
5817: MatGetSize - Returns the numbers of rows and columns in a matrix.
5819: Not Collective
5821: Input Parameter:
5822: . mat - the matrix
5824: Output Parameters:
5825: + m - the number of global rows
5826: - n - the number of global columns
5828: Note: both output parameters can be PETSC_NULL on input.
5830: Level: beginner
5832: Concepts: matrices^size
5834: .seealso: MatGetLocalSize()
5835: @*/
5836: PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt* n)
5837: {
5840: if (m) *m = mat->rmap->N;
5841: if (n) *n = mat->cmap->N;
5842: return(0);
5843: }
5847: /*@
5848: MatGetLocalSize - Returns the number of rows and columns in a matrix
5849: stored locally. This information may be implementation dependent, so
5850: use with care.
5852: Not Collective
5854: Input Parameters:
5855: . mat - the matrix
5857: Output Parameters:
5858: + m - the number of local rows
5859: - n - the number of local columns
5861: Note: both output parameters can be PETSC_NULL on input.
5863: Level: beginner
5865: Concepts: matrices^local size
5867: .seealso: MatGetSize()
5868: @*/
5869: PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt* n)
5870: {
5875: if (m) *m = mat->rmap->n;
5876: if (n) *n = mat->cmap->n;
5877: return(0);
5878: }
5882: /*@
5883: MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
5884: this processor. (The columns of the "diagonal block")
5886: Not Collective, unless matrix has not been allocated, then collective on Mat
5888: Input Parameters:
5889: . mat - the matrix
5891: Output Parameters:
5892: + m - the global index of the first local column
5893: - n - one more than the global index of the last local column
5895: Notes: both output parameters can be PETSC_NULL on input.
5897: Level: developer
5899: Concepts: matrices^column ownership
5901: .seealso: MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
5903: @*/
5904: PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt* n)
5905: {
5913: MatPreallocated(mat);
5914: if (m) *m = mat->cmap->rstart;
5915: if (n) *n = mat->cmap->rend;
5916: return(0);
5917: }
5921: /*@
5922: MatGetOwnershipRange - Returns the range of matrix rows owned by
5923: this processor, assuming that the matrix is laid out with the first
5924: n1 rows on the first processor, the next n2 rows on the second, etc.
5925: For certain parallel layouts this range may not be well defined.
5927: Not Collective, unless matrix has not been allocated, then collective on Mat
5929: Input Parameters:
5930: . mat - the matrix
5932: Output Parameters:
5933: + m - the global index of the first local row
5934: - n - one more than the global index of the last local row
5936: Note: both output parameters can be PETSC_NULL on input.
5938: Level: beginner
5940: Concepts: matrices^row ownership
5942: .seealso: MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
5944: @*/
5945: PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt* n)
5946: {
5954: MatPreallocated(mat);
5955: if (m) *m = mat->rmap->rstart;
5956: if (n) *n = mat->rmap->rend;
5957: return(0);
5958: }
5962: /*@C
5963: MatGetOwnershipRanges - Returns the range of matrix rows owned by
5964: each process
5966: Not Collective, unless matrix has not been allocated, then collective on Mat
5968: Input Parameters:
5969: . mat - the matrix
5971: Output Parameters:
5972: . ranges - start of each processors portion plus one more then the total length at the end
5974: Level: beginner
5976: Concepts: matrices^row ownership
5978: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
5980: @*/
5981: PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
5982: {
5988: MatPreallocated(mat);
5989: PetscLayoutGetRanges(mat->rmap,ranges);
5990: return(0);
5991: }
5995: /*@C
5996: MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
5997: this processor. (The columns of the "diagonal blocks" for each process)
5999: Not Collective, unless matrix has not been allocated, then collective on Mat
6001: Input Parameters:
6002: . mat - the matrix
6004: Output Parameters:
6005: . ranges - start of each processors portion plus one more then the total length at the end
6007: Level: beginner
6009: Concepts: matrices^column ownership
6011: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
6013: @*/
6014: PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6015: {
6021: MatPreallocated(mat);
6022: PetscLayoutGetRanges(mat->cmap,ranges);
6023: return(0);
6024: }
6028: /*@C
6029: MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6030: Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6031: to complete the factorization.
6033: Collective on Mat
6035: Input Parameters:
6036: + mat - the matrix
6037: . row - row permutation
6038: . column - column permutation
6039: - info - structure containing
6040: $ levels - number of levels of fill.
6041: $ expected fill - as ratio of original fill.
6042: $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6043: missing diagonal entries)
6045: Output Parameters:
6046: . fact - new matrix that has been symbolically factored
6048: Notes:
6049: See the <a href="../../docs/manual.pdf">users manual</a> for additional information about
6050: choosing the fill factor for better efficiency.
6052: Most users should employ the simplified KSP interface for linear solvers
6053: instead of working directly with matrix algebra routines such as this.
6054: See, e.g., KSPCreate().
6056: Level: developer
6058: Concepts: matrices^symbolic LU factorization
6059: Concepts: matrices^factorization
6060: Concepts: LU^symbolic factorization
6062: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6063: MatGetOrdering(), MatFactorInfo
6065: Developer Note: fortran interface is not autogenerated as the f90
6066: interface defintion cannot be generated correctly [due to MatFactorInfo]
6068: @*/
6069: PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6070: {
6080: if (info->levels < 0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6081: if (info->fill < 1.0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
6082: if (!(fact)->ops->ilufactorsymbolic) {
6083: const MatSolverPackage spackage;
6084: MatFactorGetSolverPackage(fact,&spackage);
6085: SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6086: }
6087: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6088: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6089: MatPreallocated(mat);
6091: PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);
6092: (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);
6093: PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);
6094: return(0);
6095: }
6099: /*@C
6100: MatICCFactorSymbolic - Performs symbolic incomplete
6101: Cholesky factorization for a symmetric matrix. Use
6102: MatCholeskyFactorNumeric() to complete the factorization.
6104: Collective on Mat
6106: Input Parameters:
6107: + mat - the matrix
6108: . perm - row and column permutation
6109: - info - structure containing
6110: $ levels - number of levels of fill.
6111: $ expected fill - as ratio of original fill.
6113: Output Parameter:
6114: . fact - the factored matrix
6116: Notes:
6117: Most users should employ the KSP interface for linear solvers
6118: instead of working directly with matrix algebra routines such as this.
6119: See, e.g., KSPCreate().
6121: Level: developer
6123: Concepts: matrices^symbolic incomplete Cholesky factorization
6124: Concepts: matrices^factorization
6125: Concepts: Cholsky^symbolic factorization
6127: .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
6129: Developer Note: fortran interface is not autogenerated as the f90
6130: interface defintion cannot be generated correctly [due to MatFactorInfo]
6132: @*/
6133: PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6134: {
6143: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6144: if (info->levels < 0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6145: if (info->fill < 1.0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
6146: if (!(fact)->ops->iccfactorsymbolic) {
6147: const MatSolverPackage spackage;
6148: MatFactorGetSolverPackage(fact,&spackage);
6149: SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6150: }
6151: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6152: MatPreallocated(mat);
6154: PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);
6155: (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);
6156: PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);
6157: return(0);
6158: }
6162: /*@C
6163: MatGetArray - Returns a pointer to the element values in the matrix.
6164: The result of this routine is dependent on the underlying matrix data
6165: structure, and may not even work for certain matrix types. You MUST
6166: call MatRestoreArray() when you no longer need to access the array.
6168: Not Collective
6170: Input Parameter:
6171: . mat - the matrix
6173: Output Parameter:
6174: . v - the location of the values
6177: Fortran Note:
6178: This routine is used differently from Fortran, e.g.,
6179: .vb
6180: Mat mat
6181: PetscScalar mat_array(1)
6182: PetscOffset i_mat
6183: PetscErrorCode ierr
6184: call MatGetArray(mat,mat_array,i_mat,ierr)
6186: C Access first local entry in matrix; note that array is
6187: C treated as one dimensional
6188: value = mat_array(i_mat + 1)
6190: [... other code ...]
6191: call MatRestoreArray(mat,mat_array,i_mat,ierr)
6192: .ve
6194: See the <a href="../../docs/manual.pdf#Chapter 10 PETSc for Fortran Users">Fortran chapter of the users manual</a> and
6195: src/mat/examples/tests for details.
6197: Level: advanced
6199: Concepts: matrices^access array
6201: .seealso: MatRestoreArray(), MatGetArrayF90(), MatGetRowIJ()
6202: @*/
6203: PetscErrorCode MatGetArray(Mat mat,PetscScalar *v[])
6204: {
6211: if (!mat->ops->getarray) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6212: MatPreallocated(mat);
6213: (*mat->ops->getarray)(mat,v);
6214: CHKMEMQ;
6215: return(0);
6216: }
6220: /*@C
6221: MatRestoreArray - Restores the matrix after MatGetArray() has been called.
6223: Not Collective
6225: Input Parameter:
6226: + mat - the matrix
6227: - v - the location of the values
6229: Fortran Note:
6230: This routine is used differently from Fortran, e.g.,
6231: .vb
6232: Mat mat
6233: PetscScalar mat_array(1)
6234: PetscOffset i_mat
6235: PetscErrorCode ierr
6236: call MatGetArray(mat,mat_array,i_mat,ierr)
6238: C Access first local entry in matrix; note that array is
6239: C treated as one dimensional
6240: value = mat_array(i_mat + 1)
6242: [... other code ...]
6243: call MatRestoreArray(mat,mat_array,i_mat,ierr)
6244: .ve
6246: See the <a href="../../docs/manual.pdf#Chapter 10 PETSc for Fortran Users">Fortran chapter of the users manual</a>
6247: src/mat/examples/tests for details
6249: Level: advanced
6251: .seealso: MatGetArray(), MatRestoreArrayF90()
6252: @*/
6253: PetscErrorCode MatRestoreArray(Mat mat,PetscScalar *v[])
6254: {
6261: CHKMEMQ;
6262: if (!mat->ops->restorearray) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6263: (*mat->ops->restorearray)(mat,v);
6264: PetscObjectStateIncrease((PetscObject)mat);
6265: #if defined(PETSC_HAVE_CUSP)
6266: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
6267: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
6268: }
6269: #endif
6270: return(0);
6271: }
6275: /*@C
6276: MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
6277: points to an array of valid matrices, they may be reused to store the new
6278: submatrices.
6280: Collective on Mat
6282: Input Parameters:
6283: + mat - the matrix
6284: . n - the number of submatrixes to be extracted (on this processor, may be zero)
6285: . irow, icol - index sets of rows and columns to extract
6286: - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6288: Output Parameter:
6289: . submat - the array of submatrices
6291: Notes:
6292: MatGetSubMatrices() can extract ONLY sequential submatrices
6293: (from both sequential and parallel matrices). Use MatGetSubMatrix()
6294: to extract a parallel submatrix.
6296: When extracting submatrices from a parallel matrix, each processor can
6297: form a different submatrix by setting the rows and columns of its
6298: individual index sets according to the local submatrix desired.
6300: When finished using the submatrices, the user should destroy
6301: them with MatDestroyMatrices().
6303: MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6304: original matrix has not changed from that last call to MatGetSubMatrices().
6306: This routine creates the matrices in submat; you should NOT create them before
6307: calling it. It also allocates the array of matrix pointers submat.
6309: For BAIJ matrices the index sets must respect the block structure, that is if they
6310: request one row/column in a block, they must request all rows/columns that are in
6311: that block. For example, if the block size is 2 you cannot request just row 0 and
6312: column 0.
6314: Fortran Note:
6315: The Fortran interface is slightly different from that given below; it
6316: requires one to pass in as submat a Mat (integer) array of size at least m.
6318: Level: advanced
6320: Concepts: matrices^accessing submatrices
6321: Concepts: submatrices
6323: .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6324: @*/
6325: PetscErrorCode MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6326: {
6328: PetscInt i;
6329: PetscBool eq;
6334: if (n) {
6339: }
6341: if (n && scall == MAT_REUSE_MATRIX) {
6344: }
6345: if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6346: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6347: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6348: MatPreallocated(mat);
6350: PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6351: (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);
6352: PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6353: for (i=0; i<n; i++) {
6354: if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6355: ISEqual(irow[i],icol[i],&eq);
6356: if (eq) {
6357: if (mat->symmetric){
6358: MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6359: } else if (mat->hermitian) {
6360: MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6361: } else if (mat->structurally_symmetric) {
6362: MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6363: }
6364: }
6365: }
6366: }
6367: return(0);
6368: }
6372: PetscErrorCode MatGetSubMatricesParallel(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6373: {
6375: PetscInt i;
6376: PetscBool eq;
6381: if (n) {
6386: }
6388: if (n && scall == MAT_REUSE_MATRIX) {
6391: }
6392: if (!mat->ops->getsubmatricesparallel) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6393: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6394: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6395: MatPreallocated(mat);
6397: PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6398: (*mat->ops->getsubmatricesparallel)(mat,n,irow,icol,scall,submat);
6399: PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6400: for (i=0; i<n; i++) {
6401: if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6402: ISEqual(irow[i],icol[i],&eq);
6403: if (eq) {
6404: if (mat->symmetric){
6405: MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6406: } else if (mat->hermitian) {
6407: MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6408: } else if (mat->structurally_symmetric) {
6409: MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6410: }
6411: }
6412: }
6413: }
6414: return(0);
6415: }
6419: /*@C
6420: MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().
6422: Collective on Mat
6424: Input Parameters:
6425: + n - the number of local matrices
6426: - mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6427: sequence of MatGetSubMatrices())
6429: Level: advanced
6431: Notes: Frees not only the matrices, but also the array that contains the matrices
6432: In Fortran will not free the array.
6434: .seealso: MatGetSubMatrices()
6435: @*/
6436: PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
6437: {
6439: PetscInt i;
6442: if (!*mat) return(0);
6443: if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6445: for (i=0; i<n; i++) {
6446: MatDestroy(&(*mat)[i]);
6447: }
6448: /* memory is allocated even if n = 0 */
6449: PetscFree(*mat);
6450: *mat = PETSC_NULL;
6451: return(0);
6452: }
6456: /*@C
6457: MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
6459: Collective on Mat
6461: Input Parameters:
6462: . mat - the matrix
6464: Output Parameter:
6465: . matstruct - the sequential matrix with the nonzero structure of mat
6467: Level: intermediate
6469: .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
6470: @*/
6471: PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6472: {
6478:
6480: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6481: MatPreallocated(mat);
6483: if (!mat->ops->getseqnonzerostructure) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6484: PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6485: (*mat->ops->getseqnonzerostructure)(mat,matstruct);
6486: PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6487: return(0);
6488: }
6492: /*@C
6493: MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
6495: Collective on Mat
6497: Input Parameters:
6498: . mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
6499: sequence of MatGetSequentialNonzeroStructure())
6501: Level: advanced
6503: Notes: Frees not only the matrices, but also the array that contains the matrices
6505: .seealso: MatGetSeqNonzeroStructure()
6506: @*/
6507: PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
6508: {
6513: MatDestroy(mat);
6514: return(0);
6515: }
6519: /*@
6520: MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6521: replaces the index sets by larger ones that represent submatrices with
6522: additional overlap.
6524: Collective on Mat
6526: Input Parameters:
6527: + mat - the matrix
6528: . n - the number of index sets
6529: . is - the array of index sets (these index sets will changed during the call)
6530: - ov - the additional overlap requested
6532: Level: developer
6534: Concepts: overlap
6535: Concepts: ASM^computing overlap
6537: .seealso: MatGetSubMatrices()
6538: @*/
6539: PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6540: {
6546: if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6547: if (n) {
6550: }
6551: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6552: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6553: MatPreallocated(mat);
6555: if (!ov) return(0);
6556: if (!mat->ops->increaseoverlap) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6557: PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
6558: (*mat->ops->increaseoverlap)(mat,n,is,ov);
6559: PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
6560: return(0);
6561: }
6565: /*@
6566: MatGetBlockSize - Returns the matrix block size; useful especially for the
6567: block row and block diagonal formats.
6568:
6569: Not Collective
6571: Input Parameter:
6572: . mat - the matrix
6574: Output Parameter:
6575: . bs - block size
6577: Notes:
6578: Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ
6580: Level: intermediate
6582: Concepts: matrices^block size
6584: .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ()
6585: @*/
6586: PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
6587: {
6594: MatPreallocated(mat);
6595: *bs = mat->rmap->bs;
6596: return(0);
6597: }
6601: /*@
6602: MatSetBlockSize - Sets the matrix block size; for many matrix types you
6603: cannot use this and MUST set the blocksize when you preallocate the matrix
6604:
6605: Logically Collective on Mat
6607: Input Parameters:
6608: + mat - the matrix
6609: - bs - block size
6611: Notes:
6612: For BAIJ matrices, this just checks that the block size agrees with the BAIJ size,
6613: it is not possible to change BAIJ block sizes after preallocation.
6615: Level: intermediate
6617: Concepts: matrices^block size
6619: .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ(), MatGetBlockSize()
6620: @*/
6621: PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
6622: {
6629: MatPreallocated(mat);
6630: if (bs < 1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Block size %D, must be positive",bs);
6631: if (mat->ops->setblocksize) {
6632: (*mat->ops->setblocksize)(mat,bs);
6633: } else {
6634: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Cannot set the blocksize for matrix type %s",((PetscObject)mat)->type_name);
6635: }
6636: return(0);
6637: }
6641: /*@C
6642: MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
6644: Collective on Mat
6646: Input Parameters:
6647: + mat - the matrix
6648: . shift - 0 or 1 indicating we want the indices starting at 0 or 1
6649: . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be symmetrized
6650: - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6651: inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6652: always used.
6654: Output Parameters:
6655: + n - number of rows in the (possibly compressed) matrix
6656: . ia - the row pointers [of length n+1]
6657: . ja - the column indices
6658: - done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
6659: are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
6661: Level: developer
6663: Notes: You CANNOT change any of the ia[] or ja[] values.
6665: Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values
6667: Fortran Node
6669: In Fortran use
6670: $ PetscInt ia(1), ja(1)
6671: $ PetscOffset iia, jja
6672: $ call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
6673: $
6674: $ or
6675: $
6676: $ PetscScalar, pointer :: xx_v(:)
6677: $ call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
6678:
6679:
6680: Acess the ith and jth entries via ia(iia + i) and ja(jja + j)
6682: .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatGetArray()
6683: @*/
6684: PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool *done)
6685: {
6695: MatPreallocated(mat);
6696: if (!mat->ops->getrowij) *done = PETSC_FALSE;
6697: else {
6698: *done = PETSC_TRUE;
6699: PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);
6700: (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6701: PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);
6702: }
6703: return(0);
6704: }
6708: /*@C
6709: MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
6711: Collective on Mat
6713: Input Parameters:
6714: + mat - the matrix
6715: . shift - 1 or zero indicating we want the indices starting at 0 or 1
6716: . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6717: symmetrized
6718: - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6719: inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6720: always used.
6722: Output Parameters:
6723: + n - number of columns in the (possibly compressed) matrix
6724: . ia - the column pointers
6725: . ja - the row indices
6726: - done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
6728: Level: developer
6730: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6731: @*/
6732: PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool *done)
6733: {
6743: MatPreallocated(mat);
6744: if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
6745: else {
6746: *done = PETSC_TRUE;
6747: (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6748: }
6749: return(0);
6750: }
6754: /*@C
6755: MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
6756: MatGetRowIJ().
6758: Collective on Mat
6760: Input Parameters:
6761: + mat - the matrix
6762: . shift - 1 or zero indicating we want the indices starting at 0 or 1
6763: . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6764: symmetrized
6765: - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6766: inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6767: always used.
6769: Output Parameters:
6770: + n - size of (possibly compressed) matrix
6771: . ia - the row pointers
6772: . ja - the column indices
6773: - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
6775: Level: developer
6777: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6778: @*/
6779: PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool *done)
6780: {
6789: MatPreallocated(mat);
6791: if (!mat->ops->restorerowij) *done = PETSC_FALSE;
6792: else {
6793: *done = PETSC_TRUE;
6794: (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6795: }
6796: return(0);
6797: }
6801: /*@C
6802: MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
6803: MatGetColumnIJ().
6805: Collective on Mat
6807: Input Parameters:
6808: + mat - the matrix
6809: . shift - 1 or zero indicating we want the indices starting at 0 or 1
6810: - symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6811: symmetrized
6812: - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6813: inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6814: always used.
6816: Output Parameters:
6817: + n - size of (possibly compressed) matrix
6818: . ia - the column pointers
6819: . ja - the row indices
6820: - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
6822: Level: developer
6824: .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
6825: @*/
6826: PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool *done)
6827: {
6836: MatPreallocated(mat);
6838: if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
6839: else {
6840: *done = PETSC_TRUE;
6841: (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6842: }
6843: return(0);
6844: }
6848: /*@C
6849: MatColoringPatch -Used inside matrix coloring routines that
6850: use MatGetRowIJ() and/or MatGetColumnIJ().
6852: Collective on Mat
6854: Input Parameters:
6855: + mat - the matrix
6856: . ncolors - max color value
6857: . n - number of entries in colorarray
6858: - colorarray - array indicating color for each column
6860: Output Parameters:
6861: . iscoloring - coloring generated using colorarray information
6863: Level: developer
6865: .seealso: MatGetRowIJ(), MatGetColumnIJ()
6867: @*/
6868: PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
6869: {
6877: MatPreallocated(mat);
6879: if (!mat->ops->coloringpatch){
6880: ISColoringCreate(((PetscObject)mat)->comm,ncolors,n,colorarray,iscoloring);
6881: } else {
6882: (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);
6883: }
6884: return(0);
6885: }
6890: /*@
6891: MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
6893: Logically Collective on Mat
6895: Input Parameter:
6896: . mat - the factored matrix to be reset
6898: Notes:
6899: This routine should be used only with factored matrices formed by in-place
6900: factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
6901: format). This option can save memory, for example, when solving nonlinear
6902: systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
6903: ILU(0) preconditioner.
6905: Note that one can specify in-place ILU(0) factorization by calling
6906: .vb
6907: PCType(pc,PCILU);
6908: PCFactorSeUseInPlace(pc);
6909: .ve
6910: or by using the options -pc_type ilu -pc_factor_in_place
6912: In-place factorization ILU(0) can also be used as a local
6913: solver for the blocks within the block Jacobi or additive Schwarz
6914: methods (runtime option: -sub_pc_factor_in_place). See the discussion
6915: of these preconditioners in the <a href="../../docs/manual.pdf#ch_pc">PC chapter of the users manual</a> for details on setting
6916: local solver options.
6918: Most users should employ the simplified KSP interface for linear solvers
6919: instead of working directly with matrix algebra routines such as this.
6920: See, e.g., KSPCreate().
6922: Level: developer
6924: .seealso: PCFactorSetUseInPlace()
6926: Concepts: matrices^unfactored
6928: @*/
6929: PetscErrorCode MatSetUnfactored(Mat mat)
6930: {
6936: MatPreallocated(mat);
6937: mat->factortype = MAT_FACTOR_NONE;
6938: if (!mat->ops->setunfactored) return(0);
6939: (*mat->ops->setunfactored)(mat);
6940: return(0);
6941: }
6943: /*MC
6944: MatGetArrayF90 - Accesses a matrix array from Fortran90.
6946: Synopsis:
6947: MatGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
6949: Not collective
6951: Input Parameter:
6952: . x - matrix
6954: Output Parameters:
6955: + xx_v - the Fortran90 pointer to the array
6956: - ierr - error code
6958: Example of Usage:
6959: .vb
6960: PetscScalar, pointer xx_v(:,:)
6961: ....
6962: call MatGetArrayF90(x,xx_v,ierr)
6963: a = xx_v(3)
6964: call MatRestoreArrayF90(x,xx_v,ierr)
6965: .ve
6967: Notes:
6968: Not yet supported for all F90 compilers
6970: Level: advanced
6972: .seealso: MatRestoreArrayF90(), MatGetArray(), MatRestoreArray()
6974: Concepts: matrices^accessing array
6976: M*/
6978: /*MC
6979: MatRestoreArrayF90 - Restores a matrix array that has been
6980: accessed with MatGetArrayF90().
6982: Synopsis:
6983: MatRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
6985: Not collective
6987: Input Parameters:
6988: + x - matrix
6989: - xx_v - the Fortran90 pointer to the array
6991: Output Parameter:
6992: . ierr - error code
6994: Example of Usage:
6995: .vb
6996: PetscScalar, pointer xx_v(:)
6997: ....
6998: call MatGetArrayF90(x,xx_v,ierr)
6999: a = xx_v(3)
7000: call MatRestoreArrayF90(x,xx_v,ierr)
7001: .ve
7002:
7003: Notes:
7004: Not yet supported for all F90 compilers
7006: Level: advanced
7008: .seealso: MatGetArrayF90(), MatGetArray(), MatRestoreArray()
7010: M*/
7015: /*@
7016: MatGetSubMatrix - Gets a single submatrix on the same number of processors
7017: as the original matrix.
7019: Collective on Mat
7021: Input Parameters:
7022: + mat - the original matrix
7023: . isrow - parallel IS containing the rows this processor should obtain
7024: . 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.
7025: - cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7027: Output Parameter:
7028: . newmat - the new submatrix, of the same type as the old
7030: Level: advanced
7032: Notes:
7033: The submatrix will be able to be multiplied with vectors using the same layout as iscol.
7035: The rows in isrow will be sorted into the same order as the original matrix on each process.
7037: The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7038: the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
7039: to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7040: will reuse the matrix generated the first time. You should call MatDestroy() on newmat when
7041: you are finished using it.
7043: The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7044: the input matrix.
7046: If iscol is PETSC_NULL then all columns are obtained (not supported in Fortran).
7048: Example usage:
7049: Consider the following 8x8 matrix with 34 non-zero values, that is
7050: assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7051: proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7052: as follows:
7054: .vb
7055: 1 2 0 | 0 3 0 | 0 4
7056: Proc0 0 5 6 | 7 0 0 | 8 0
7057: 9 0 10 | 11 0 0 | 12 0
7058: -------------------------------------
7059: 13 0 14 | 15 16 17 | 0 0
7060: Proc1 0 18 0 | 19 20 21 | 0 0
7061: 0 0 0 | 22 23 0 | 24 0
7062: -------------------------------------
7063: Proc2 25 26 27 | 0 0 28 | 29 0
7064: 30 0 0 | 31 32 33 | 0 34
7065: .ve
7067: Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6]. The resulting submatrix is
7069: .vb
7070: 2 0 | 0 3 0 | 0
7071: Proc0 5 6 | 7 0 0 | 8
7072: -------------------------------
7073: Proc1 18 0 | 19 20 21 | 0
7074: -------------------------------
7075: Proc2 26 27 | 0 0 28 | 29
7076: 0 0 | 31 32 33 | 0
7077: .ve
7080: Concepts: matrices^submatrices
7082: .seealso: MatGetSubMatrices()
7083: @*/
7084: PetscErrorCode MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7085: {
7087: PetscMPIInt size;
7088: Mat *local;
7089: IS iscoltmp;
7098: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7099: MatPreallocated(mat);
7100: MPI_Comm_size(((PetscObject)mat)->comm,&size);
7102: if (!iscol) {
7103: ISCreateStride(((PetscObject)mat)->comm,mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);
7104: } else {
7105: iscoltmp = iscol;
7106: }
7108: /* if original matrix is on just one processor then use submatrix generated */
7109: if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7110: MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);
7111: if (!iscol) {ISDestroy(&iscoltmp);}
7112: return(0);
7113: } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) {
7114: MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);
7115: *newmat = *local;
7116: PetscFree(local);
7117: if (!iscol) {ISDestroy(&iscoltmp);}
7118: return(0);
7119: } else if (!mat->ops->getsubmatrix) {
7120: /* Create a new matrix type that implements the operation using the full matrix */
7121: switch (cll) {
7122: case MAT_INITIAL_MATRIX:
7123: MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);
7124: break;
7125: case MAT_REUSE_MATRIX:
7126: MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);
7127: break;
7128: default: SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7129: }
7130: if (!iscol) {ISDestroy(&iscoltmp);}
7131: return(0);
7132: }
7134: if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7135: (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);
7136: if (!iscol) {ISDestroy(&iscoltmp);}
7137: if (*newmat && cll == MAT_INITIAL_MATRIX) {PetscObjectStateIncrease((PetscObject)*newmat);}
7138: return(0);
7139: }
7143: /*@
7144: MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7145: used during the assembly process to store values that belong to
7146: other processors.
7148: Not Collective
7150: Input Parameters:
7151: + mat - the matrix
7152: . size - the initial size of the stash.
7153: - bsize - the initial size of the block-stash(if used).
7155: Options Database Keys:
7156: + -matstash_initial_size <size> or <size0,size1,...sizep-1>
7157: - -matstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1>
7159: Level: intermediate
7161: Notes:
7162: The block-stash is used for values set with MatSetValuesBlocked() while
7163: the stash is used for values set with MatSetValues()
7165: Run with the option -info and look for output of the form
7166: MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7167: to determine the appropriate value, MM, to use for size and
7168: MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7169: to determine the value, BMM to use for bsize
7171: Concepts: stash^setting matrix size
7172: Concepts: matrices^stash
7174: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
7176: @*/
7177: PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7178: {
7184: MatStashSetInitialSize_Private(&mat->stash,size);
7185: MatStashSetInitialSize_Private(&mat->bstash,bsize);
7186: return(0);
7187: }
7191: /*@
7192: MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
7193: the matrix
7195: Neighbor-wise Collective on Mat
7197: Input Parameters:
7198: + mat - the matrix
7199: . x,y - the vectors
7200: - w - where the result is stored
7202: Level: intermediate
7204: Notes:
7205: w may be the same vector as y.
7207: This allows one to use either the restriction or interpolation (its transpose)
7208: matrix to do the interpolation
7210: Concepts: interpolation
7212: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7214: @*/
7215: PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7216: {
7218: PetscInt M,N,Ny;
7226: MatPreallocated(A);
7227: MatGetSize(A,&M,&N);
7228: VecGetSize(y,&Ny);
7229: if (M == Ny) {
7230: MatMultAdd(A,x,y,w);
7231: } else {
7232: MatMultTransposeAdd(A,x,y,w);
7233: }
7234: return(0);
7235: }
7239: /*@
7240: MatInterpolate - y = A*x or A'*x depending on the shape of
7241: the matrix
7243: Neighbor-wise Collective on Mat
7245: Input Parameters:
7246: + mat - the matrix
7247: - x,y - the vectors
7249: Level: intermediate
7251: Notes:
7252: This allows one to use either the restriction or interpolation (its transpose)
7253: matrix to do the interpolation
7255: Concepts: matrices^interpolation
7257: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7259: @*/
7260: PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
7261: {
7263: PetscInt M,N,Ny;
7270: MatPreallocated(A);
7271: MatGetSize(A,&M,&N);
7272: VecGetSize(y,&Ny);
7273: if (M == Ny) {
7274: MatMult(A,x,y);
7275: } else {
7276: MatMultTranspose(A,x,y);
7277: }
7278: return(0);
7279: }
7283: /*@
7284: MatRestrict - y = A*x or A'*x
7286: Neighbor-wise Collective on Mat
7288: Input Parameters:
7289: + mat - the matrix
7290: - x,y - the vectors
7292: Level: intermediate
7294: Notes:
7295: This allows one to use either the restriction or interpolation (its transpose)
7296: matrix to do the restriction
7298: Concepts: matrices^restriction
7300: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
7302: @*/
7303: PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
7304: {
7306: PetscInt M,N,Ny;
7313: MatPreallocated(A);
7315: MatGetSize(A,&M,&N);
7316: VecGetSize(y,&Ny);
7317: if (M == Ny) {
7318: MatMult(A,x,y);
7319: } else {
7320: MatMultTranspose(A,x,y);
7321: }
7322: return(0);
7323: }
7327: /*@
7328: MatNullSpaceAttach - attaches a null space to a matrix.
7329: This null space will be removed from the resulting vector whenever
7330: MatMult() is called
7332: Logically Collective on Mat and MatNullSpace
7334: Input Parameters:
7335: + mat - the matrix
7336: - nullsp - the null space object
7338: Level: developer
7340: Notes:
7341: Overwrites any previous null space that may have been attached
7343: Concepts: null space^attaching to matrix
7345: .seealso: MatCreate(), MatNullSpaceCreate()
7346: @*/
7347: PetscErrorCode MatNullSpaceAttach(Mat mat,MatNullSpace nullsp)
7348: {
7355: MatPreallocated(mat);
7356: PetscObjectReference((PetscObject)nullsp);
7357: if (mat->nullsp) { MatNullSpaceDestroy(&mat->nullsp); }
7358: mat->nullsp = nullsp;
7359: return(0);
7360: }
7364: /*@C
7365: MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
7367: Collective on Mat
7369: Input Parameters:
7370: + mat - the matrix
7371: . row - row/column permutation
7372: . fill - expected fill factor >= 1.0
7373: - level - level of fill, for ICC(k)
7375: Notes:
7376: Probably really in-place only when level of fill is zero, otherwise allocates
7377: new space to store factored matrix and deletes previous memory.
7379: Most users should employ the simplified KSP interface for linear solvers
7380: instead of working directly with matrix algebra routines such as this.
7381: See, e.g., KSPCreate().
7383: Level: developer
7385: Concepts: matrices^incomplete Cholesky factorization
7386: Concepts: Cholesky factorization
7388: .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
7390: Developer Note: fortran interface is not autogenerated as the f90
7391: interface defintion cannot be generated correctly [due to MatFactorInfo]
7393: @*/
7394: PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo* info)
7395: {
7403: if (mat->rmap->N != mat->cmap->N) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONG,"matrix must be square");
7404: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7405: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7406: if (!mat->ops->iccfactor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7407: MatPreallocated(mat);
7408: (*mat->ops->iccfactor)(mat,row,info);
7409: PetscObjectStateIncrease((PetscObject)mat);
7410: return(0);
7411: }
7415: /*@
7416: MatSetValuesAdic - Sets values computed with ADIC automatic differentiation into a matrix.
7418: Not Collective
7420: Input Parameters:
7421: + mat - the matrix
7422: - v - the values compute with ADIC
7424: Level: developer
7426: Notes:
7427: Must call MatSetColoring() before using this routine. Also this matrix must already
7428: have its nonzero pattern determined.
7430: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7431: MatSetValues(), MatSetColoring(), MatSetValuesAdifor()
7432: @*/
7433: PetscErrorCode MatSetValuesAdic(Mat mat,void *v)
7434: {
7442: if (!mat->assembled) {
7443: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7444: }
7445: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
7446: if (!mat->ops->setvaluesadic) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7447: (*mat->ops->setvaluesadic)(mat,v);
7448: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
7449: MatView_Private(mat);
7450: PetscObjectStateIncrease((PetscObject)mat);
7451: return(0);
7452: }
7457: /*@
7458: MatSetColoring - Sets a coloring used by calls to MatSetValuesAdic()
7460: Not Collective
7462: Input Parameters:
7463: + mat - the matrix
7464: - coloring - the coloring
7466: Level: developer
7468: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7469: MatSetValues(), MatSetValuesAdic()
7470: @*/
7471: PetscErrorCode MatSetColoring(Mat mat,ISColoring coloring)
7472: {
7480: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7481: if (!mat->ops->setcoloring) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7482: (*mat->ops->setcoloring)(mat,coloring);
7483: return(0);
7484: }
7488: /*@
7489: MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.
7491: Not Collective
7493: Input Parameters:
7494: + mat - the matrix
7495: . nl - leading dimension of v
7496: - v - the values compute with ADIFOR
7498: Level: developer
7500: Notes:
7501: Must call MatSetColoring() before using this routine. Also this matrix must already
7502: have its nonzero pattern determined.
7504: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7505: MatSetValues(), MatSetColoring()
7506: @*/
7507: PetscErrorCode MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
7508: {
7516: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7517: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
7518: if (!mat->ops->setvaluesadifor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7519: (*mat->ops->setvaluesadifor)(mat,nl,v);
7520: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
7521: PetscObjectStateIncrease((PetscObject)mat);
7522: return(0);
7523: }
7527: /*@
7528: MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
7529: ghosted ones.
7531: Not Collective
7533: Input Parameters:
7534: + mat - the matrix
7535: - diag = the diagonal values, including ghost ones
7537: Level: developer
7539: Notes: Works only for MPIAIJ and MPIBAIJ matrices
7540:
7541: .seealso: MatDiagonalScale()
7542: @*/
7543: PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
7544: {
7546: PetscMPIInt size;
7553: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7554: PetscLogEventBegin(MAT_Scale,mat,0,0,0);
7555: MPI_Comm_size(((PetscObject)mat)->comm,&size);
7556: if (size == 1) {
7557: PetscInt n,m;
7558: VecGetSize(diag,&n);
7559: MatGetSize(mat,0,&m);
7560: if (m == n) {
7561: MatDiagonalScale(mat,0,diag);
7562: } else {
7563: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
7564: }
7565: } else {
7566: PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));
7567: }
7568: PetscLogEventEnd(MAT_Scale,mat,0,0,0);
7569: PetscObjectStateIncrease((PetscObject)mat);
7570: return(0);
7571: }
7575: /*@
7576: MatGetInertia - Gets the inertia from a factored matrix
7578: Collective on Mat
7580: Input Parameter:
7581: . mat - the matrix
7583: Output Parameters:
7584: + nneg - number of negative eigenvalues
7585: . nzero - number of zero eigenvalues
7586: - npos - number of positive eigenvalues
7588: Level: advanced
7590: Notes: Matrix must have been factored by MatCholeskyFactor()
7593: @*/
7594: PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
7595: {
7601: if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7602: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
7603: if (!mat->ops->getinertia) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7604: (*mat->ops->getinertia)(mat,nneg,nzero,npos);
7605: return(0);
7606: }
7608: /* ----------------------------------------------------------------*/
7611: /*@C
7612: MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
7614: Neighbor-wise Collective on Mat and Vecs
7616: Input Parameters:
7617: + mat - the factored matrix
7618: - b - the right-hand-side vectors
7620: Output Parameter:
7621: . x - the result vectors
7623: Notes:
7624: The vectors b and x cannot be the same. I.e., one cannot
7625: call MatSolves(A,x,x).
7627: Notes:
7628: Most users should employ the simplified KSP interface for linear solvers
7629: instead of working directly with matrix algebra routines such as this.
7630: See, e.g., KSPCreate().
7632: Level: developer
7634: Concepts: matrices^triangular solves
7636: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
7637: @*/
7638: PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
7639: {
7645: if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
7646: if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7647: if (!mat->rmap->N && !mat->cmap->N) return(0);
7649: if (!mat->ops->solves) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7650: MatPreallocated(mat);
7651: PetscLogEventBegin(MAT_Solves,mat,0,0,0);
7652: (*mat->ops->solves)(mat,b,x);
7653: PetscLogEventEnd(MAT_Solves,mat,0,0,0);
7654: return(0);
7655: }
7659: /*@
7660: MatIsSymmetric - Test whether a matrix is symmetric
7662: Collective on Mat
7664: Input Parameter:
7665: + A - the matrix to test
7666: - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
7668: Output Parameters:
7669: . flg - the result
7671: Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
7673: Level: intermediate
7675: Concepts: matrix^symmetry
7677: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
7678: @*/
7679: PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool *flg)
7680: {
7687: if (!A->symmetric_set) {
7688: if (!A->ops->issymmetric) {
7689: const MatType mattype;
7690: MatGetType(A,&mattype);
7691: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7692: }
7693: (*A->ops->issymmetric)(A,tol,flg);
7694: if (!tol) {
7695: A->symmetric_set = PETSC_TRUE;
7696: A->symmetric = *flg;
7697: if (A->symmetric) {
7698: A->structurally_symmetric_set = PETSC_TRUE;
7699: A->structurally_symmetric = PETSC_TRUE;
7700: }
7701: }
7702: } else if (A->symmetric) {
7703: *flg = PETSC_TRUE;
7704: } else if (!tol) {
7705: *flg = PETSC_FALSE;
7706: } else {
7707: if (!A->ops->issymmetric) {
7708: const MatType mattype;
7709: MatGetType(A,&mattype);
7710: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7711: }
7712: (*A->ops->issymmetric)(A,tol,flg);
7713: }
7714: return(0);
7715: }
7719: /*@
7720: MatIsHermitian - Test whether a matrix is Hermitian
7722: Collective on Mat
7724: Input Parameter:
7725: + A - the matrix to test
7726: - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
7728: Output Parameters:
7729: . flg - the result
7731: Level: intermediate
7733: Concepts: matrix^symmetry
7735: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
7736: MatIsSymmetricKnown(), MatIsSymmetric()
7737: @*/
7738: PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool *flg)
7739: {
7746: if (!A->hermitian_set) {
7747: if (!A->ops->ishermitian) {
7748: const MatType mattype;
7749: MatGetType(A,&mattype);
7750: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7751: }
7752: (*A->ops->ishermitian)(A,tol,flg);
7753: if (!tol) {
7754: A->hermitian_set = PETSC_TRUE;
7755: A->hermitian = *flg;
7756: if (A->hermitian) {
7757: A->structurally_symmetric_set = PETSC_TRUE;
7758: A->structurally_symmetric = PETSC_TRUE;
7759: }
7760: }
7761: } else if (A->hermitian) {
7762: *flg = PETSC_TRUE;
7763: } else if (!tol) {
7764: *flg = PETSC_FALSE;
7765: } else {
7766: if (!A->ops->ishermitian) {
7767: const MatType mattype;
7768: MatGetType(A,&mattype);
7769: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7770: }
7771: (*A->ops->ishermitian)(A,tol,flg);
7772: }
7773: return(0);
7774: }
7778: /*@
7779: MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
7781: Not Collective
7783: Input Parameter:
7784: . A - the matrix to check
7786: Output Parameters:
7787: + set - if the symmetric flag is set (this tells you if the next flag is valid)
7788: - flg - the result
7790: Level: advanced
7792: Concepts: matrix^symmetry
7794: Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
7795: if you want it explicitly checked
7797: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
7798: @*/
7799: PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool *set,PetscBool *flg)
7800: {
7805: if (A->symmetric_set) {
7806: *set = PETSC_TRUE;
7807: *flg = A->symmetric;
7808: } else {
7809: *set = PETSC_FALSE;
7810: }
7811: return(0);
7812: }
7816: /*@
7817: MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
7819: Not Collective
7821: Input Parameter:
7822: . A - the matrix to check
7824: Output Parameters:
7825: + set - if the hermitian flag is set (this tells you if the next flag is valid)
7826: - flg - the result
7828: Level: advanced
7830: Concepts: matrix^symmetry
7832: Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
7833: if you want it explicitly checked
7835: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
7836: @*/
7837: PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg)
7838: {
7843: if (A->hermitian_set) {
7844: *set = PETSC_TRUE;
7845: *flg = A->hermitian;
7846: } else {
7847: *set = PETSC_FALSE;
7848: }
7849: return(0);
7850: }
7854: /*@
7855: MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
7857: Collective on Mat
7859: Input Parameter:
7860: . A - the matrix to test
7862: Output Parameters:
7863: . flg - the result
7865: Level: intermediate
7867: Concepts: matrix^symmetry
7869: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
7870: @*/
7871: PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg)
7872: {
7878: if (!A->structurally_symmetric_set) {
7879: if (!A->ops->isstructurallysymmetric) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
7880: (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);
7881: A->structurally_symmetric_set = PETSC_TRUE;
7882: }
7883: *flg = A->structurally_symmetric;
7884: return(0);
7885: }
7890: /*@
7891: MatStashGetInfo - Gets how many values are currently in the vector stash, i.e. need
7892: to be communicated to other processors during the MatAssemblyBegin/End() process
7894: Not collective
7896: Input Parameter:
7897: . vec - the vector
7899: Output Parameters:
7900: + nstash - the size of the stash
7901: . reallocs - the number of additional mallocs incurred.
7902: . bnstash - the size of the block stash
7903: - breallocs - the number of additional mallocs incurred.in the block stash
7904:
7905: Level: advanced
7907: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
7908:
7909: @*/
7910: PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
7911: {
7914: MatStashGetInfo_Private(&mat->stash,nstash,reallocs);
7915: MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);
7916: return(0);
7917: }
7921: /*@C
7922: MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same
7923: parallel layout
7924:
7925: Collective on Mat
7927: Input Parameter:
7928: . mat - the matrix
7930: Output Parameter:
7931: + right - (optional) vector that the matrix can be multiplied against
7932: - left - (optional) vector that the matrix vector product can be stored in
7934: Level: advanced
7936: .seealso: MatCreate()
7937: @*/
7938: PetscErrorCode MatGetVecs(Mat mat,Vec *right,Vec *left)
7939: {
7945: MatPreallocated(mat);
7946: if (mat->ops->getvecs) {
7947: (*mat->ops->getvecs)(mat,right,left);
7948: } else {
7949: PetscMPIInt size;
7950: MPI_Comm_size(((PetscObject)mat)->comm, &size);
7951: if (right) {
7952: VecCreate(((PetscObject)mat)->comm,right);
7953: VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);
7954: VecSetBlockSize(*right,mat->rmap->bs);
7955: VecSetType(*right,VECSTANDARD);
7956: PetscLayoutReference(mat->cmap,&(*right)->map);
7957: }
7958: if (left) {
7959: VecCreate(((PetscObject)mat)->comm,left);
7960: VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);
7961: VecSetBlockSize(*left,mat->rmap->bs);
7962: VecSetType(*left,VECSTANDARD);
7963: PetscLayoutReference(mat->rmap,&(*left)->map);
7964: }
7965: }
7966: return(0);
7967: }
7971: /*@C
7972: MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
7973: with default values.
7975: Not Collective
7977: Input Parameters:
7978: . info - the MatFactorInfo data structure
7981: Notes: The solvers are generally used through the KSP and PC objects, for example
7982: PCLU, PCILU, PCCHOLESKY, PCICC
7984: Level: developer
7986: .seealso: MatFactorInfo
7988: Developer Note: fortran interface is not autogenerated as the f90
7989: interface defintion cannot be generated correctly [due to MatFactorInfo]
7991: @*/
7993: PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
7994: {
7998: PetscMemzero(info,sizeof(MatFactorInfo));
7999: return(0);
8000: }
8004: /*@
8005: MatPtAP - Creates the matrix product C = P^T * A * P
8007: Neighbor-wise Collective on Mat
8009: Input Parameters:
8010: + A - the matrix
8011: . P - the projection matrix
8012: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8013: - fill - expected fill as ratio of nnz(C)/nnz(A)
8015: Output Parameters:
8016: . C - the product matrix
8018: Notes:
8019: C will be created and must be destroyed by the user with MatDestroy().
8021: This routine is currently only implemented for pairs of AIJ matrices and classes
8022: which inherit from AIJ.
8024: Level: intermediate
8026: .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult()
8027: @*/
8028: PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
8029: {
8035: if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8036: if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8039: MatPreallocated(P);
8040: if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8041: if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8043: if (P->rmap->N!=A->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
8044: if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8045: MatPreallocated(A);
8047: if (!A->ops->ptap) {
8048: const MatType mattype;
8049: MatGetType(A,&mattype);
8050: SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix of type <%s> does not support PtAP",mattype);
8051: }
8052: PetscLogEventBegin(MAT_PtAP,A,P,0,0);
8053: (*A->ops->ptap)(A,P,scall,fill,C);
8054: PetscLogEventEnd(MAT_PtAP,A,P,0,0);
8056: return(0);
8057: }
8061: /*@
8062: MatPtAPNumeric - Computes the matrix product C = P^T * A * P
8064: Neighbor-wise Collective on Mat
8066: Input Parameters:
8067: + A - the matrix
8068: - P - the projection matrix
8070: Output Parameters:
8071: . C - the product matrix
8073: Notes:
8074: C must have been created by calling MatPtAPSymbolic and must be destroyed by
8075: the user using MatDeatroy().
8077: This routine is currently only implemented for pairs of AIJ matrices and classes
8078: which inherit from AIJ. C will be of type MATAIJ.
8080: Level: intermediate
8082: .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
8083: @*/
8084: PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C)
8085: {
8091: if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8092: if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8095: MatPreallocated(P);
8096: if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8097: if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8100: MatPreallocated(C);
8101: if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8102: if (P->cmap->N!=C->rmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->rmap->N);
8103: if (P->rmap->N!=A->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
8104: if (A->rmap->N!=A->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
8105: if (P->cmap->N!=C->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->cmap->N);
8106: MatPreallocated(A);
8108: PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
8109: (*A->ops->ptapnumeric)(A,P,C);
8110: PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
8111: return(0);
8112: }
8116: /*@
8117: MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P
8119: Neighbor-wise Collective on Mat
8121: Input Parameters:
8122: + A - the matrix
8123: - P - the projection matrix
8125: Output Parameters:
8126: . C - the (i,j) structure of the product matrix
8128: Notes:
8129: C will be created and must be destroyed by the user with MatDestroy().
8131: This routine is currently only implemented for pairs of SeqAIJ matrices and classes
8132: which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using
8133: this (i,j) structure by calling MatPtAPNumeric().
8135: Level: intermediate
8137: .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
8138: @*/
8139: PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
8140: {
8146: if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8147: if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8148: if (fill <1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8151: MatPreallocated(P);
8152: if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8153: if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8156: if (P->rmap->N!=A->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
8157: if (A->rmap->N!=A->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
8158: MatPreallocated(A);
8159: PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);
8160: (*A->ops->ptapsymbolic)(A,P,fill,C);
8161: PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);
8163: MatSetBlockSize(*C,A->rmap->bs);
8165: return(0);
8166: }
8170: /*@
8171: MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
8173: Neighbor-wise Collective on Mat
8175: Input Parameters:
8176: + A - the left matrix
8177: . B - the right matrix
8178: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8179: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
8180: if the result is a dense matrix this is irrelevent
8182: Output Parameters:
8183: . C - the product matrix
8185: Notes:
8186: Unless scall is MAT_REUSE_MATRIX C will be created.
8188: MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8189:
8190: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8191: actually needed.
8193: If you have many matrices with the same non-zero structure to multiply, you
8194: should either
8195: $ 1) use MAT_REUSE_MATRIX in all calls but the first or
8196: $ 2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
8198: Level: intermediate
8200: .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatPtAP()
8201: @*/
8202: PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8203: {
8205: PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8206: PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8207: PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat *)=PETSC_NULL;
8212: if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8213: if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8216: MatPreallocated(B);
8217: if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8218: if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8220: if (B->rmap->N!=A->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
8221: if (scall == MAT_REUSE_MATRIX){
8224: }
8225: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8226: if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8227: MatPreallocated(A);
8229: fA = A->ops->matmult;
8230: fB = B->ops->matmult;
8231: if (fB == fA) {
8232: if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
8233: mult = fB;
8234: } else {
8235: /* dispatch based on the type of A and B */
8236: char multname[256];
8237: PetscStrcpy(multname,"MatMatMult_");
8238: PetscStrcat(multname,((PetscObject)A)->type_name);
8239: PetscStrcat(multname,"_");
8240: PetscStrcat(multname,((PetscObject)B)->type_name);
8241: PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
8242: PetscObjectQueryFunction((PetscObject)B,multname,(void (**)(void))&mult);
8243: if (!mult) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_INCOMP,"MatMatMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
8244: }
8245: PetscLogEventBegin(MAT_MatMult,A,B,0,0);
8246: (*mult)(A,B,scall,fill,C);
8247: PetscLogEventEnd(MAT_MatMult,A,B,0,0);
8248: return(0);
8249: }
8253: /*@
8254: MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
8255: of the matrix-matrix product C=A*B. Call this routine before calling MatMatMultNumeric().
8257: Neighbor-wise Collective on Mat
8259: Input Parameters:
8260: + A - the left matrix
8261: . B - the right matrix
8262: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
8263: if C is a dense matrix this is irrelevent
8264:
8265: Output Parameters:
8266: . C - the product matrix
8268: Notes:
8269: Unless scall is MAT_REUSE_MATRIX C will be created.
8271: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8272: actually needed.
8274: This routine is currently implemented for
8275: - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
8276: - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8277: - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
8279: Level: intermediate
8281: Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
8282: We should incorporate them into PETSc.
8284: .seealso: MatMatMult(), MatMatMultNumeric()
8285: @*/
8286: PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
8287: {
8289: PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat *);
8290: PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat *);
8291: PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat *)=PETSC_NULL;
8296: if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8297: if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8301: MatPreallocated(B);
8302: if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8303: if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8306: if (B->rmap->N!=A->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
8307: if (fill == PETSC_DEFAULT) fill = 2.0;
8308: if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8309: MatPreallocated(A);
8310:
8311: Asymbolic = A->ops->matmultsymbolic;
8312: Bsymbolic = B->ops->matmultsymbolic;
8313: if (Asymbolic == Bsymbolic){
8314: if (!Bsymbolic) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
8315: symbolic = Bsymbolic;
8316: } else { /* dispatch based on the type of A and B */
8317: char symbolicname[256];
8318: PetscStrcpy(symbolicname,"MatMatMultSymbolic_");
8319: PetscStrcat(symbolicname,((PetscObject)A)->type_name);
8320: PetscStrcat(symbolicname,"_");
8321: PetscStrcat(symbolicname,((PetscObject)B)->type_name);
8322: PetscStrcat(symbolicname,"_C");
8323: PetscObjectQueryFunction((PetscObject)B,symbolicname,(void (**)(void))&symbolic);
8324: if (!symbolic) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_INCOMP,"MatMatMultSymbolic requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
8325: }
8326: PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);
8327: (*symbolic)(A,B,fill,C);
8328: PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);
8329: return(0);
8330: }
8334: /*@
8335: MatMatMultNumeric - Performs the numeric matrix-matrix product.
8336: Call this routine after first calling MatMatMultSymbolic().
8338: Neighbor-wise Collective on Mat
8340: Input Parameters:
8341: + A - the left matrix
8342: - B - the right matrix
8344: Output Parameters:
8345: . C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
8347: Notes:
8348: C must have been created with MatMatMultSymbolic().
8350: This routine is currently implemented for
8351: - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
8352: - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8353: - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
8355: Level: intermediate
8357: .seealso: MatMatMult(), MatMatMultSymbolic()
8358: @*/
8359: PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C)
8360: {
8362: PetscErrorCode (*Anumeric)(Mat,Mat,Mat);
8363: PetscErrorCode (*Bnumeric)(Mat,Mat,Mat);
8364: PetscErrorCode (*numeric)(Mat,Mat,Mat)=PETSC_NULL;
8369: if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8370: if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8374: MatPreallocated(B);
8375: if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8376: if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8380: MatPreallocated(C);
8381: if (!C->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8382: if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8384: if (B->cmap->N!=C->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->cmap->N,C->cmap->N);
8385: if (B->rmap->N!=A->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
8386: if (A->rmap->N!=C->rmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",A->rmap->N,C->rmap->N);
8387: MatPreallocated(A);
8389: Anumeric = A->ops->matmultnumeric;
8390: Bnumeric = B->ops->matmultnumeric;
8391: if (Anumeric == Bnumeric){
8392: if (!Bnumeric) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMultNumeric not supported for B of type %s",((PetscObject)B)->type_name);
8393: numeric = Bnumeric;
8394: } else {
8395: char numericname[256];
8396: PetscStrcpy(numericname,"MatMatMultNumeric_");
8397: PetscStrcat(numericname,((PetscObject)A)->type_name);
8398: PetscStrcat(numericname,"_");
8399: PetscStrcat(numericname,((PetscObject)B)->type_name);
8400: PetscStrcat(numericname,"_C");
8401: PetscObjectQueryFunction((PetscObject)B,numericname,(void (**)(void))&numeric);
8402: if (!numeric)
8403: SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_INCOMP,"MatMatMultNumeric requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
8404: }
8405: PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);
8406: (*numeric)(A,B,C);
8407: PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);
8408: return(0);
8409: }
8413: /*@
8414: MatMatMultTranspose - Performs Matrix-Matrix Multiplication C=A^T*B.
8416: Neighbor-wise Collective on Mat
8418: Input Parameters:
8419: + A - the left matrix
8420: . B - the right matrix
8421: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8422: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
8424: Output Parameters:
8425: . C - the product matrix
8427: Notes:
8428: C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
8430: MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8432: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8433: actually needed.
8435: This routine is currently only implemented for pairs of SeqAIJ matrices and pairs of SeqDense matrices and classes
8436: which inherit from SeqAIJ. C will be of type MATSEQAIJ.
8438: Level: intermediate
8440: .seealso: MatMatMultTransposeSymbolic(), MatMatMultTransposeNumeric(), MatPtAP()
8441: @*/
8442: PetscErrorCode MatMatMultTranspose(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8443: {
8445: PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8446: PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8451: if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8452: if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8455: MatPreallocated(B);
8456: if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8457: if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8459: if (B->rmap->N!=A->rmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->rmap->N);
8460: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8461: if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8462: MatPreallocated(A);
8464: fA = A->ops->matmulttranspose;
8465: if (!fA) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMultTranspose not supported for A of type %s",((PetscObject)A)->type_name);
8466: fB = B->ops->matmulttranspose;
8467: if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMultTranspose not supported for B of type %s",((PetscObject)B)->type_name);
8468: if (fB!=fA) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_INCOMP,"MatMatMultTranspose requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
8470: PetscLogEventBegin(MAT_MatMultTranspose,A,B,0,0);
8471: (*A->ops->matmulttranspose)(A,B,scall,fill,C);
8472: PetscLogEventEnd(MAT_MatMultTranspose,A,B,0,0);
8473:
8474: return(0);
8475: }
8479: /*@C
8480: MatGetRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
8482: Collective on Mat
8484: Input Parameters:
8485: + mat - the matrix
8486: . nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
8487: . subcomm - MPI communicator split from the communicator where mat resides in
8488: . mlocal_red - number of local rows of the redundant matrix
8489: - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8491: Output Parameter:
8492: . matredundant - redundant matrix
8494: Notes:
8495: MAT_REUSE_MATRIX can only be used when the nonzero structure of the
8496: original matrix has not changed from that last call to MatGetRedundantMatrix().
8498: This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
8499: calling it.
8501: Only MPIAIJ matrix is supported.
8502:
8503: Level: advanced
8505: Concepts: subcommunicator
8506: Concepts: duplicate matrix
8508: .seealso: MatDestroy()
8509: @*/
8510: PetscErrorCode MatGetRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,PetscInt mlocal_red,MatReuse reuse,Mat *matredundant)
8511: {
8516: if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
8519: }
8520: if (!mat->ops->getredundantmatrix) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8521: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8522: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8523: MatPreallocated(mat);
8525: PetscLogEventBegin(MAT_GetRedundantMatrix,mat,0,0,0);
8526: (*mat->ops->getredundantmatrix)(mat,nsubcomm,subcomm,mlocal_red,reuse,matredundant);
8527: PetscLogEventEnd(MAT_GetRedundantMatrix,mat,0,0,0);
8528: return(0);
8529: }
8533: /*@C
8534: MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
8535: a given 'mat' object. Each submatrix can span multiple procs.
8537: Collective on Mat
8539: Input Parameters:
8540: + mat - the matrix
8541: - subcomm - the subcommunicator obtained by com_split(comm)
8543: Output Parameter:
8544: . subMat - 'parallel submatrices each spans a given subcomm
8546: Notes:
8547: The submatrix partition across processors is dicated by 'subComm' a
8548: communicator obtained by com_split(comm). The comm_split
8549: is not restriced to be grouped with consequitive original ranks.
8551: Due the comm_split() usage, the parallel layout of the submatrices
8552: map directly to the layout of the original matrix [wrt the local
8553: row,col partitioning]. So the original 'DiagonalMat' naturally maps
8554: into the 'DiagonalMat' of the subMat, hence it is used directly from
8555: the subMat. However the offDiagMat looses some columns - and this is
8556: reconstructed with MatSetValues()
8558: Level: advanced
8560: Concepts: subcommunicator
8561: Concepts: submatrices
8563: .seealso: MatGetSubMatrices()
8564: @*/
8565: PetscErrorCode MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, Mat* subMat)
8566: {
8568: PetscMPIInt commsize,subCommSize;
8571: MPI_Comm_size(((PetscObject)mat)->comm,&commsize);
8572: MPI_Comm_size(subComm,&subCommSize);
8573: if (subCommSize > commsize) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
8574:
8575: PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);
8576: (*mat->ops->getmultiprocblock)(mat,subComm,subMat);
8577: PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);
8578: return(0);
8579: }
8583: /*@
8584: MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
8586: Not Collective
8588: Input Arguments:
8589: mat - matrix to extract local submatrix from
8590: isrow - local row indices for submatrix
8591: iscol - local column indices for submatrix
8593: Output Arguments:
8594: submat - the submatrix
8596: Level: intermediate
8598: Notes:
8599: The submat should be returned with MatRestoreLocalSubMatrix().
8601: Depending on the format of mat, the returned submat may not implement MatMult(). Its communicator may be
8602: the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
8604: The submat always implements MatSetValuesLocal(). If isrow and iscol have the same block size, then
8605: MatSetValuesBlockedLocal() will also be implemented.
8607: .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef()
8608: @*/
8609: PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
8610: {
8620: if (mat->ops->getlocalsubmatrix) {
8621: (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);
8622: } else {
8623: MatCreateLocalRef(mat,isrow,iscol,submat);
8624: }
8625: return(0);
8626: }
8630: /*@
8631: MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
8633: Not Collective
8635: Input Arguments:
8636: mat - matrix to extract local submatrix from
8637: isrow - local row indices for submatrix
8638: iscol - local column indices for submatrix
8639: submat - the submatrix
8641: Level: intermediate
8643: .seealso: MatGetLocalSubMatrix()
8644: @*/
8645: PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
8646: {
8657: if (mat->ops->restorelocalsubmatrix) {
8658: (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);
8659: } else {
8660: MatDestroy(submat);
8661: }
8662: *submat = PETSC_NULL;
8663: return(0);
8664: }
8666: /* --------------------------------------------------------*/
8669: /*@
8670: MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no entry in the matrix
8672: Collective on Mat
8674: Input Parameter:
8675: . mat - the matrix
8677: Output Parameter:
8678: . is - if any rows have zero diagonals this contains the list of them
8680: Level: developer
8682: Concepts: matrix-vector product
8684: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
8685: @*/
8686: PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is)
8687: {
8693: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8694: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8696: if (!mat->ops->findzerodiagonals) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"This matrix type does not have a find zero diagonals defined");
8697: (*mat->ops->findzerodiagonals)(mat,is);
8698: return(0);
8699: }
8703: /*@
8704: MatInvertBlockDiagonal - Inverts the block diagonal entries.
8706: Collective on Mat
8708: Input Parameters:
8709: . mat - the matrix
8711: Output Parameters:
8712: . values - the block inverses in column major order (FORTRAN-like)
8714: Level: advanced
8715: @*/
8716: PetscErrorCode MatInvertBlockDiagonal(Mat mat,PetscScalar **values)
8717: {
8722: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8723: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8724: if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
8725: (*mat->ops->invertblockdiagonal)(mat,values);
8726: return(0);
8727: }