Actual source code: matrix.c
1: #define PETSCMAT_DLL
3: /*
4: This is where the abstract matrix operations are defined
5: */
7: #include private/matimpl.h
8: #include private/vecimpl.h
10: /* Logging support */
11: PetscCookie MAT_COOKIE;
12: PetscCookie MAT_FDCOLORING_COOKIE;
14: PetscLogEvent MAT_Mult, MAT_Mults, MAT_MultConstrained, MAT_MultAdd, MAT_MultTranspose;
15: PetscLogEvent MAT_MultTransposeConstrained, MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve;
16: PetscLogEvent MAT_SolveTransposeAdd, MAT_Relax, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic;
17: PetscLogEvent MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor;
18: PetscLogEvent MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin;
19: PetscLogEvent MAT_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetRowIJ, MAT_GetSubMatrices, MAT_GetColoring, MAT_GetOrdering, MAT_GetRedundantMatrix, MAT_GetSeqNonzeroStructure;
20: PetscLogEvent MAT_IncreaseOverlap, MAT_Partitioning, MAT_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate;
21: PetscLogEvent MAT_FDColoringApply,MAT_Transpose,MAT_FDColoringFunction;
22: PetscLogEvent MAT_MatMult, MAT_MatMultSymbolic, MAT_MatMultNumeric;
23: PetscLogEvent MAT_PtAP, MAT_PtAPSymbolic, MAT_PtAPNumeric;
24: PetscLogEvent MAT_MatMultTranspose, MAT_MatMultTransposeSymbolic, MAT_MatMultTransposeNumeric;
25: PetscLogEvent MAT_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;
29: /* nasty global values for MatSetValue() */
30: PetscInt MatSetValue_Row = 0;
31: PetscInt MatSetValue_Column = 0;
32: PetscScalar MatSetValue_Value = 0.0;
36: /*@
37: MatRealPart - Zeros out the imaginary part of the matrix
39: Collective on Mat
41: Input Parameters:
42: . mat - the matrix
44: Level: advanced
47: .seealso: MatImaginaryPart()
48: @*/
50: PetscErrorCode MatRealPart(Mat mat)
51: {
57: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
58: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
59: if (!mat->ops->realpart) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
60: MatPreallocated(mat);
61: (*mat->ops->realpart)(mat);
62: return(0);
63: }
68: /*@
69: MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part
71: Collective on Mat
73: Input Parameters:
74: . mat - the matrix
76: Level: advanced
79: .seealso: MatRealPart()
80: @*/
82: PetscErrorCode MatImaginaryPart(Mat mat)
83: {
89: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
90: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
91: if (!mat->ops->imaginarypart) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
92: MatPreallocated(mat);
93: (*mat->ops->imaginarypart)(mat);
94: return(0);
95: }
99: /*@
100: MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices)
102: Collective on Mat
104: Input Parameter:
105: . mat - the matrix
107: Output Parameters:
108: + missing - is any diagonal missing
109: - dd - first diagonal entry that is missing (optional)
111: Level: advanced
114: .seealso: MatRealPart()
115: @*/
117: PetscErrorCode MatMissingDiagonal(Mat mat,PetscTruth *missing,PetscInt *dd)
118: {
124: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
125: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
126: if (!mat->ops->missingdiagonal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
127: (*mat->ops->missingdiagonal)(mat,missing,dd);
128: return(0);
129: }
133: /*@C
134: MatGetRow - Gets a row of a matrix. You MUST call MatRestoreRow()
135: for each row that you get to ensure that your application does
136: not bleed memory.
138: Not Collective
140: Input Parameters:
141: + mat - the matrix
142: - row - the row to get
144: Output Parameters:
145: + ncols - if not NULL, the number of nonzeros in the row
146: . cols - if not NULL, the column numbers
147: - vals - if not NULL, the values
149: Notes:
150: This routine is provided for people who need to have direct access
151: to the structure of a matrix. We hope that we provide enough
152: high-level matrix routines that few users will need it.
154: MatGetRow() always returns 0-based column indices, regardless of
155: whether the internal representation is 0-based (default) or 1-based.
157: For better efficiency, set cols and/or vals to PETSC_NULL if you do
158: not wish to extract these quantities.
160: The user can only examine the values extracted with MatGetRow();
161: the values cannot be altered. To change the matrix entries, one
162: must use MatSetValues().
164: You can only have one call to MatGetRow() outstanding for a particular
165: matrix at a time, per processor. MatGetRow() can only obtain rows
166: associated with the given processor, it cannot get rows from the
167: other processors; for that we suggest using MatGetSubMatrices(), then
168: MatGetRow() on the submatrix. The row indix passed to MatGetRows()
169: is in the global number of rows.
171: Fortran Notes:
172: The calling sequence from Fortran is
173: .vb
174: MatGetRow(matrix,row,ncols,cols,values,ierr)
175: Mat matrix (input)
176: integer row (input)
177: integer ncols (output)
178: integer cols(maxcols) (output)
179: double precision (or double complex) values(maxcols) output
180: .ve
181: where maxcols >= maximum nonzeros in any row of the matrix.
184: Caution:
185: Do not try to change the contents of the output arrays (cols and vals).
186: In some cases, this may corrupt the matrix.
188: Level: advanced
190: Concepts: matrices^row access
192: .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatGetSubMatrices(), MatGetDiagonal()
193: @*/
195: PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
196: {
198: PetscInt incols;
203: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
204: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
205: if (!mat->ops->getrow) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
206: MatPreallocated(mat);
207: PetscLogEventBegin(MAT_GetRow,mat,0,0,0);
208: (*mat->ops->getrow)(mat,row,&incols,(PetscInt **)cols,(PetscScalar **)vals);
209: if (ncols) *ncols = incols;
210: PetscLogEventEnd(MAT_GetRow,mat,0,0,0);
211: return(0);
212: }
216: /*@
217: MatConjugate - replaces the matrix values with their complex conjugates
219: Collective on Mat
221: Input Parameters:
222: . mat - the matrix
224: Level: advanced
226: .seealso: VecConjugate()
227: @*/
228: PetscErrorCode MatConjugate(Mat mat)
229: {
234: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
235: if (!mat->ops->conjugate) SETERRQ(PETSC_ERR_SUP,"Not provided for this matrix format, send email to petsc-maint@mcs.anl.gov");
236: (*mat->ops->conjugate)(mat);
237: return(0);
238: }
242: /*@C
243: MatRestoreRow - Frees any temporary space allocated by MatGetRow().
245: Not Collective
247: Input Parameters:
248: + mat - the matrix
249: . row - the row to get
250: . ncols, cols - the number of nonzeros and their columns
251: - vals - if nonzero the column values
253: Notes:
254: This routine should be called after you have finished examining the entries.
256: Fortran Notes:
257: The calling sequence from Fortran is
258: .vb
259: MatRestoreRow(matrix,row,ncols,cols,values,ierr)
260: Mat matrix (input)
261: integer row (input)
262: integer ncols (output)
263: integer cols(maxcols) (output)
264: double precision (or double complex) values(maxcols) output
265: .ve
266: Where maxcols >= maximum nonzeros in any row of the matrix.
268: In Fortran MatRestoreRow() MUST be called after MatGetRow()
269: before another call to MatGetRow() can be made.
271: Level: advanced
273: .seealso: MatGetRow()
274: @*/
275: PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
276: {
282: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
283: if (!mat->ops->restorerow) return(0);
284: (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);
285: return(0);
286: }
290: /*@
291: MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format.
292: You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag.
294: Not Collective
296: Input Parameters:
297: + mat - the matrix
299: Notes:
300: 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.
302: Level: advanced
304: Concepts: matrices^row access
306: .seealso: MatRestoreRowRowUpperTriangular()
307: @*/
309: PetscErrorCode MatGetRowUpperTriangular(Mat mat)
310: {
316: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
317: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
318: if (!mat->ops->getrowuppertriangular) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
319: MatPreallocated(mat);
320: (*mat->ops->getrowuppertriangular)(mat);
321: return(0);
322: }
326: /*@
327: MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format.
329: Not Collective
331: Input Parameters:
332: + mat - the matrix
334: Notes:
335: This routine should be called after you have finished MatGetRow/MatRestoreRow().
338: Level: advanced
340: .seealso: MatGetRowUpperTriangular()
341: @*/
342: PetscErrorCode MatRestoreRowUpperTriangular(Mat mat)
343: {
348: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
349: if (!mat->ops->restorerowuppertriangular) return(0);
350: (*mat->ops->restorerowuppertriangular)(mat);
351: return(0);
352: }
356: /*@C
357: MatSetOptionsPrefix - Sets the prefix used for searching for all
358: Mat options in the database.
360: Collective on Mat
362: Input Parameter:
363: + A - the Mat context
364: - prefix - the prefix to prepend to all option names
366: Notes:
367: A hyphen (-) must NOT be given at the beginning of the prefix name.
368: The first character of all runtime options is AUTOMATICALLY the hyphen.
370: Level: advanced
372: .keywords: Mat, set, options, prefix, database
374: .seealso: MatSetFromOptions()
375: @*/
376: PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[])
377: {
382: PetscObjectSetOptionsPrefix((PetscObject)A,prefix);
383: return(0);
384: }
388: /*@C
389: MatAppendOptionsPrefix - Appends to the prefix used for searching for all
390: Mat options in the database.
392: Collective on Mat
394: Input Parameters:
395: + A - the Mat context
396: - prefix - the prefix to prepend to all option names
398: Notes:
399: A hyphen (-) must NOT be given at the beginning of the prefix name.
400: The first character of all runtime options is AUTOMATICALLY the hyphen.
402: Level: advanced
404: .keywords: Mat, append, options, prefix, database
406: .seealso: MatGetOptionsPrefix()
407: @*/
408: PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[])
409: {
411:
414: PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);
415: return(0);
416: }
420: /*@C
421: MatGetOptionsPrefix - Sets the prefix used for searching for all
422: Mat options in the database.
424: Not Collective
426: Input Parameter:
427: . A - the Mat context
429: Output Parameter:
430: . prefix - pointer to the prefix string used
432: Notes: On the fortran side, the user should pass in a string 'prefix' of
433: sufficient length to hold the prefix.
435: Level: advanced
437: .keywords: Mat, get, options, prefix, database
439: .seealso: MatAppendOptionsPrefix()
440: @*/
441: PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[])
442: {
447: PetscObjectGetOptionsPrefix((PetscObject)A,prefix);
448: return(0);
449: }
453: /*@
454: MatSetUp - Sets up the internal matrix data structures for the later use.
456: Collective on Mat
458: Input Parameters:
459: . A - the Mat context
461: Notes:
462: For basic use of the Mat classes the user need not explicitly call
463: MatSetUp(), since these actions will happen automatically.
465: Level: advanced
467: .keywords: Mat, setup
469: .seealso: MatCreate(), MatDestroy()
470: @*/
471: PetscErrorCode MatSetUp(Mat A)
472: {
473: PetscMPIInt size;
478: if (!((PetscObject)A)->type_name) {
479: MPI_Comm_size(((PetscObject)A)->comm, &size);
480: if (size == 1) {
481: MatSetType(A, MATSEQAIJ);
482: } else {
483: MatSetType(A, MATMPIAIJ);
484: }
485: }
486: MatSetUpPreallocation(A);
487: return(0);
488: }
492: /*@C
493: MatView - Visualizes a matrix object.
495: Collective on Mat
497: Input Parameters:
498: + mat - the matrix
499: - viewer - visualization context
501: Notes:
502: The available visualization contexts include
503: + PETSC_VIEWER_STDOUT_SELF - standard output (default)
504: . PETSC_VIEWER_STDOUT_WORLD - synchronized standard
505: output where only the first processor opens
506: the file. All other processors send their
507: data to the first processor to print.
508: - PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure
510: The user can open alternative visualization contexts with
511: + PetscViewerASCIIOpen() - Outputs matrix to a specified file
512: . PetscViewerBinaryOpen() - Outputs matrix in binary to a
513: specified file; corresponding input uses MatLoad()
514: . PetscViewerDrawOpen() - Outputs nonzero matrix structure to
515: an X window display
516: - PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
517: Currently only the sequential dense and AIJ
518: matrix types support the Socket viewer.
520: The user can call PetscViewerSetFormat() to specify the output
521: format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
522: PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen). Available formats include
523: + PETSC_VIEWER_DEFAULT - default, prints matrix contents
524: . PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
525: . PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
526: . PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse
527: format common among all matrix types
528: . PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific
529: format (which is in many cases the same as the default)
530: . PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
531: size and structure (not the matrix entries)
532: . PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about
533: the matrix structure
535: Options Database Keys:
536: + -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly()
537: . -mat_view_info_detailed - Prints more detailed info
538: . -mat_view - Prints matrix in ASCII format
539: . -mat_view_matlab - Prints matrix in Matlab format
540: . -mat_view_draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
541: . -display <name> - Sets display name (default is host)
542: . -draw_pause <sec> - Sets number of seconds to pause after display
543: . -mat_view_socket - Sends matrix to socket, can be accessed from Matlab (see users manual)
544: . -viewer_socket_machine <machine>
545: . -viewer_socket_port <port>
546: . -mat_view_binary - save matrix to file in binary format
547: - -viewer_binary_filename <name>
548: Level: beginner
550: Notes: see the manual page for MatLoad() for the exact format of the binary file when the binary
551: viewer is used.
553: See bin/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary
554: viewer is used.
556: Concepts: matrices^viewing
557: Concepts: matrices^plotting
558: Concepts: matrices^printing
560: .seealso: PetscViewerSetFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(),
561: PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
562: @*/
563: PetscErrorCode MatView(Mat mat,PetscViewer viewer)
564: {
565: PetscErrorCode ierr;
566: PetscInt rows,cols;
567: PetscTruth iascii;
568: const MatType cstr;
569: PetscViewerFormat format;
574: if (!viewer) {
575: PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
576: }
579: if (!mat->assembled) SETERRQ(PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
580: MatPreallocated(mat);
582: PetscLogEventBegin(MAT_View,mat,viewer,0,0);
583: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
584: if (iascii) {
585: PetscViewerGetFormat(viewer,&format);
586: if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
587: if (((PetscObject)mat)->prefix) {
588: PetscViewerASCIIPrintf(viewer,"Matrix Object:(%s)\n",((PetscObject)mat)->prefix);
589: } else {
590: PetscViewerASCIIPrintf(viewer,"Matrix Object:\n");
591: }
592: PetscViewerASCIIPushTab(viewer);
593: MatGetType(mat,&cstr);
594: MatGetSize(mat,&rows,&cols);
595: PetscViewerASCIIPrintf(viewer,"type=%s, rows=%D, cols=%D\n",cstr,rows,cols);
596: if (mat->factor) {
597: const MatSolverPackage solver;
598: MatFactorGetSolverPackage(mat,&solver);
599: PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);
600: }
601: if (mat->ops->getinfo) {
602: MatInfo info;
603: MatGetInfo(mat,MAT_GLOBAL_SUM,&info);
604: PetscViewerASCIIPrintf(viewer,"total: nonzeros=%D, allocated nonzeros=%D\n",(PetscInt)info.nz_used,(PetscInt)info.nz_allocated);
605: }
606: }
607: }
608: if (mat->ops->view) {
609: PetscViewerASCIIPushTab(viewer);
610: (*mat->ops->view)(mat,viewer);
611: PetscViewerASCIIPopTab(viewer);
612: } else if (!iascii) {
613: SETERRQ1(PETSC_ERR_SUP,"Viewer type %s not supported",((PetscObject)viewer)->type_name);
614: }
615: if (iascii) {
616: PetscViewerGetFormat(viewer,&format);
617: if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
618: PetscViewerASCIIPopTab(viewer);
619: }
620: }
621: PetscLogEventEnd(MAT_View,mat,viewer,0,0);
622: return(0);
623: }
627: /*@
628: MatScaleSystem - Scale a vector solution and right hand side to
629: match the scaling of a scaled matrix.
630:
631: Collective on Mat
633: Input Parameter:
634: + mat - the matrix
635: . b - right hand side vector (or PETSC_NULL)
636: - x - solution vector (or PETSC_NULL)
639: Notes:
640: For AIJ, and BAIJ matrix formats, the matrices are not
641: internally scaled, so this does nothing. For MPIROWBS it
642: permutes and diagonally scales.
644: The KSP methods automatically call this routine when required
645: (via PCPreSolve()) so it is rarely used directly.
647: Level: Developer
649: Concepts: matrices^scaling
651: .seealso: MatUseScaledForm(), MatUnScaleSystem()
652: @*/
653: PetscErrorCode MatScaleSystem(Mat mat,Vec b,Vec x)
654: {
660: MatPreallocated(mat);
664: if (mat->ops->scalesystem) {
665: (*mat->ops->scalesystem)(mat,b,x);
666: }
667: return(0);
668: }
672: /*@
673: MatUnScaleSystem - Unscales a vector solution and right hand side to
674: match the original scaling of a scaled matrix.
675:
676: Collective on Mat
678: Input Parameter:
679: + mat - the matrix
680: . b - right hand side vector (or PETSC_NULL)
681: - x - solution vector (or PETSC_NULL)
684: Notes:
685: For AIJ and BAIJ matrix formats, the matrices are not
686: internally scaled, so this does nothing. For MPIROWBS it
687: permutes and diagonally scales.
689: The KSP methods automatically call this routine when required
690: (via PCPreSolve()) so it is rarely used directly.
692: Level: Developer
694: .seealso: MatUseScaledForm(), MatScaleSystem()
695: @*/
696: PetscErrorCode MatUnScaleSystem(Mat mat,Vec b,Vec x)
697: {
703: MatPreallocated(mat);
706: if (mat->ops->unscalesystem) {
707: (*mat->ops->unscalesystem)(mat,b,x);
708: }
709: return(0);
710: }
714: /*@
715: MatUseScaledForm - For matrix storage formats that scale the
716: matrix (for example MPIRowBS matrices are diagonally scaled on
717: assembly) indicates matrix operations (MatMult() etc) are
718: applied using the scaled matrix.
719:
720: Collective on Mat
722: Input Parameter:
723: + mat - the matrix
724: - scaled - PETSC_TRUE for applying the scaled, PETSC_FALSE for
725: applying the original matrix
727: Notes:
728: For scaled matrix formats, applying the original, unscaled matrix
729: will be slightly more expensive
731: Level: Developer
733: .seealso: MatScaleSystem(), MatUnScaleSystem()
734: @*/
735: PetscErrorCode MatUseScaledForm(Mat mat,PetscTruth scaled)
736: {
742: MatPreallocated(mat);
743: if (mat->ops->usescaledform) {
744: (*mat->ops->usescaledform)(mat,scaled);
745: }
746: return(0);
747: }
751: /*@
752: MatDestroy - Frees space taken by a matrix.
753:
754: Collective on Mat
756: Input Parameter:
757: . A - the matrix
759: Level: beginner
761: @*/
762: PetscErrorCode MatDestroy(Mat A)
763: {
767: if (--((PetscObject)A)->refct > 0) return(0);
768: MatPreallocated(A);
769: /* if memory was published with AMS then destroy it */
770: PetscObjectDepublish(A);
771: if (A->ops->destroy) {
772: (*A->ops->destroy)(A);
773: }
774: if (A->mapping) {
775: ISLocalToGlobalMappingDestroy(A->mapping);
776: }
777: if (A->bmapping) {
778: ISLocalToGlobalMappingDestroy(A->bmapping);
779: }
781: if (A->spptr){PetscFree(A->spptr);}
782: PetscMapDestroy(A->rmap);
783: PetscMapDestroy(A->cmap);
784: PetscHeaderDestroy(A);
785: return(0);
786: }
790: /*@
791: MatValid - Checks whether a matrix object is valid.
793: Collective on Mat
795: Input Parameter:
796: . m - the matrix to check
798: Output Parameter:
799: flg - flag indicating matrix status, either
800: PETSC_TRUE if matrix is valid, or PETSC_FALSE otherwise.
802: Level: developer
804: Concepts: matrices^validity
805: @*/
806: PetscErrorCode MatValid(Mat m,PetscTruth *flg)
807: {
810: if (!m) *flg = PETSC_FALSE;
811: else if (((PetscObject)m)->cookie != MAT_COOKIE) *flg = PETSC_FALSE;
812: else *flg = PETSC_TRUE;
813: return(0);
814: }
818: /*@
819: MatSetValues - Inserts or adds a block of values into a matrix.
820: These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
821: MUST be called after all calls to MatSetValues() have been completed.
823: Not Collective
825: Input Parameters:
826: + mat - the matrix
827: . v - a logically two-dimensional array of values
828: . m, idxm - the number of rows and their global indices
829: . n, idxn - the number of columns and their global indices
830: - addv - either ADD_VALUES or INSERT_VALUES, where
831: ADD_VALUES adds values to any existing entries, and
832: INSERT_VALUES replaces existing entries with new values
834: Notes:
835: By default the values, v, are row-oriented and unsorted.
836: See MatSetOption() for other options.
838: Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
839: options cannot be mixed without intervening calls to the assembly
840: routines.
842: MatSetValues() uses 0-based row and column numbers in Fortran
843: as well as in C.
845: Negative indices may be passed in idxm and idxn, these rows and columns are
846: simply ignored. This allows easily inserting element stiffness matrices
847: with homogeneous Dirchlet boundary conditions that you don't want represented
848: in the matrix.
850: Efficiency Alert:
851: The routine MatSetValuesBlocked() may offer much better efficiency
852: for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
854: Level: beginner
856: Concepts: matrices^putting entries in
858: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
859: InsertMode, INSERT_VALUES, ADD_VALUES
860: @*/
861: PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
862: {
868: if (!m || !n) return(0); /* no values to insert */
871: MatPreallocated(mat);
872: if (mat->insertmode == NOT_SET_VALUES) {
873: mat->insertmode = addv;
874: }
875: #if defined(PETSC_USE_DEBUG)
876: else if (mat->insertmode != addv) {
877: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
878: }
879: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
880: #endif
882: if (mat->assembled) {
883: mat->was_assembled = PETSC_TRUE;
884: mat->assembled = PETSC_FALSE;
885: }
886: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
887: if (!mat->ops->setvalues) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
888: (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);
889: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
890: return(0);
891: }
896: /*@
897: MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
898: values into a matrix
900: Not Collective
902: Input Parameters:
903: + mat - the matrix
904: . row - the (block) row to set
905: - v - a logically two-dimensional array of values
907: Notes:
908: By the values, v, are column-oriented (for the block version) and sorted
910: All the nonzeros in the row must be provided
912: The matrix must have previously had its column indices set
914: The row must belong to this process
916: Level: intermediate
918: Concepts: matrices^putting entries in
920: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
921: InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping()
922: @*/
923: PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
924: {
931: MatSetValuesRow(mat, mat->mapping->indices[row],v);
932: return(0);
933: }
937: /*@
938: MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
939: values into a matrix
941: Not Collective
943: Input Parameters:
944: + mat - the matrix
945: . row - the (block) row to set
946: - v - a logically two-dimensional array of values
948: Notes:
949: By the values, v, are column-oriented (for the block version) and sorted
951: All the nonzeros in the row must be provided
953: The matrix must have previously had its column indices set
955: The row must belong to this process
957: Level: intermediate
959: Concepts: matrices^putting entries in
961: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
962: InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
963: @*/
964: PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
965: {
972: #if defined(PETSC_USE_DEBUG)
973: if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
974: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
975: #endif
976: mat->insertmode = INSERT_VALUES;
978: if (mat->assembled) {
979: mat->was_assembled = PETSC_TRUE;
980: mat->assembled = PETSC_FALSE;
981: }
982: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
983: if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
984: (*mat->ops->setvaluesrow)(mat,row,v);
985: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
986: return(0);
987: }
991: /*@
992: MatSetValuesStencil - Inserts or adds a block of values into a matrix.
993: Using structured grid indexing
995: Not Collective
997: Input Parameters:
998: + mat - the matrix
999: . v - a logically two-dimensional array of values
1000: . m - number of rows being entered
1001: . idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
1002: . n - number of columns being entered
1003: . idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered
1004: - addv - either ADD_VALUES or INSERT_VALUES, where
1005: ADD_VALUES adds values to any existing entries, and
1006: INSERT_VALUES replaces existing entries with new values
1008: Notes:
1009: By default the values, v, are row-oriented and unsorted.
1010: See MatSetOption() for other options.
1012: Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
1013: options cannot be mixed without intervening calls to the assembly
1014: routines.
1016: The grid coordinates are across the entire grid, not just the local portion
1018: MatSetValuesStencil() uses 0-based row and column numbers in Fortran
1019: as well as in C.
1021: For setting/accessing vector values via array coordinates you can use the DAVecGetArray() routine
1023: In order to use this routine you must either obtain the matrix with DAGetMatrix()
1024: or call MatSetLocalToGlobalMapping() and MatSetStencil() first.
1026: The columns and rows in the stencil passed in MUST be contained within the
1027: ghost region of the given process as set with DACreateXXX() or MatSetStencil(). For example,
1028: if you create a DA with an overlap of one grid level and on a particular process its first
1029: local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1030: first i index you can use in your column and row indices in MatSetStencil() is 5.
1032: In Fortran idxm and idxn should be declared as
1033: $ MatStencil idxm(4,m),idxn(4,n)
1034: and the values inserted using
1035: $ idxm(MatStencil_i,1) = i
1036: $ idxm(MatStencil_j,1) = j
1037: $ idxm(MatStencil_k,1) = k
1038: $ idxm(MatStencil_c,1) = c
1039: etc
1041: For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
1042: obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
1043: etc to obtain values that obtained by wrapping the values from the left edge.
1045: 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
1046: a single value per point) you can skip filling those indices.
1048: Inspired by the structured grid interface to the HYPRE package
1049: (http://www.llnl.gov/CASC/hypre)
1051: Efficiency Alert:
1052: The routine MatSetValuesBlockedStencil() may offer much better efficiency
1053: for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1055: Level: beginner
1057: Concepts: matrices^putting entries in
1059: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1060: MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DAGetMatrix(), DAVecGetArray(), MatStencil
1061: @*/
1062: PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1063: {
1065: PetscInt j,i,jdxm[128],jdxn[256],dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1066: PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1069: if (!m || !n) return(0); /* no values to insert */
1076: if (m > 128) SETERRQ1(PETSC_ERR_SUP,"Can only set 128 rows at a time; trying to set %D",m);
1077: if (n > 256) SETERRQ1(PETSC_ERR_SUP,"Can only set 256 columns at a time; trying to set %D",n);
1079: for (i=0; i<m; i++) {
1080: for (j=0; j<3-sdim; j++) dxm++;
1081: tmp = *dxm++ - starts[0];
1082: for (j=0; j<dim-1; j++) {
1083: if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1084: else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1085: }
1086: if (mat->stencil.noc) dxm++;
1087: jdxm[i] = tmp;
1088: }
1089: for (i=0; i<n; i++) {
1090: for (j=0; j<3-sdim; j++) dxn++;
1091: tmp = *dxn++ - starts[0];
1092: for (j=0; j<dim-1; j++) {
1093: if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1094: else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1095: }
1096: if (mat->stencil.noc) dxn++;
1097: jdxn[i] = tmp;
1098: }
1099: MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);
1100: return(0);
1101: }
1105: /*@C
1106: MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1107: Using structured grid indexing
1109: Not Collective
1111: Input Parameters:
1112: + mat - the matrix
1113: . v - a logically two-dimensional array of values
1114: . m - number of rows being entered
1115: . idxm - grid coordinates for matrix rows being entered
1116: . n - number of columns being entered
1117: . idxn - grid coordinates for matrix columns being entered
1118: - addv - either ADD_VALUES or INSERT_VALUES, where
1119: ADD_VALUES adds values to any existing entries, and
1120: INSERT_VALUES replaces existing entries with new values
1122: Notes:
1123: By default the values, v, are row-oriented and unsorted.
1124: See MatSetOption() for other options.
1126: Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
1127: options cannot be mixed without intervening calls to the assembly
1128: routines.
1130: The grid coordinates are across the entire grid, not just the local portion
1132: MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran
1133: as well as in C.
1135: For setting/accessing vector values via array coordinates you can use the DAVecGetArray() routine
1137: In order to use this routine you must either obtain the matrix with DAGetMatrix()
1138: or call MatSetLocalToGlobalMapping() and MatSetStencil() first.
1140: The columns and rows in the stencil passed in MUST be contained within the
1141: ghost region of the given process as set with DACreateXXX() or MatSetStencil(). For example,
1142: if you create a DA with an overlap of one grid level and on a particular process its first
1143: local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1144: first i index you can use in your column and row indices in MatSetStencil() is 5.
1146: In Fortran idxm and idxn should be declared as
1147: $ MatStencil idxm(4,m),idxn(4,n)
1148: and the values inserted using
1149: $ idxm(MatStencil_i,1) = i
1150: $ idxm(MatStencil_j,1) = j
1151: $ idxm(MatStencil_k,1) = k
1152: etc
1154: Negative indices may be passed in idxm and idxn, these rows and columns are
1155: simply ignored. This allows easily inserting element stiffness matrices
1156: with homogeneous Dirchlet boundary conditions that you don't want represented
1157: in the matrix.
1159: Inspired by the structured grid interface to the HYPRE package
1160: (http://www.llnl.gov/CASC/hypre)
1162: Level: beginner
1164: Concepts: matrices^putting entries in
1166: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1167: MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DAGetMatrix(), DAVecGetArray(), MatStencil
1168: @*/
1169: PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1170: {
1172: PetscInt j,i,jdxm[128],jdxn[256],dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1173: PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1176: if (!m || !n) return(0); /* no values to insert */
1183: if (m > 128) SETERRQ1(PETSC_ERR_SUP,"Can only set 128 rows at a time; trying to set %D",m);
1184: if (n > 128) SETERRQ1(PETSC_ERR_SUP,"Can only set 256 columns at a time; trying to set %D",n);
1186: for (i=0; i<m; i++) {
1187: for (j=0; j<3-sdim; j++) dxm++;
1188: tmp = *dxm++ - starts[0];
1189: for (j=0; j<sdim-1; j++) {
1190: if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1191: else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1192: }
1193: dxm++;
1194: jdxm[i] = tmp;
1195: }
1196: for (i=0; i<n; i++) {
1197: for (j=0; j<3-sdim; j++) dxn++;
1198: tmp = *dxn++ - starts[0];
1199: for (j=0; j<sdim-1; j++) {
1200: if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1201: else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1202: }
1203: dxn++;
1204: jdxn[i] = tmp;
1205: }
1206: MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);
1207: return(0);
1208: }
1212: /*@
1213: MatSetStencil - Sets the grid information for setting values into a matrix via
1214: MatSetValuesStencil()
1216: Not Collective
1218: Input Parameters:
1219: + mat - the matrix
1220: . dim - dimension of the grid 1, 2, or 3
1221: . dims - number of grid points in x, y, and z direction, including ghost points on your processor
1222: . starts - starting point of ghost nodes on your processor in x, y, and z direction
1223: - dof - number of degrees of freedom per node
1226: Inspired by the structured grid interface to the HYPRE package
1227: (www.llnl.gov/CASC/hyper)
1229: For matrices generated with DAGetMatrix() this routine is automatically called and so not needed by the
1230: user.
1231:
1232: Level: beginner
1234: Concepts: matrices^putting entries in
1236: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1237: MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
1238: @*/
1239: PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1240: {
1241: PetscInt i;
1248: mat->stencil.dim = dim + (dof > 1);
1249: for (i=0; i<dim; i++) {
1250: mat->stencil.dims[i] = dims[dim-i-1]; /* copy the values in backwards */
1251: mat->stencil.starts[i] = starts[dim-i-1];
1252: }
1253: mat->stencil.dims[dim] = dof;
1254: mat->stencil.starts[dim] = 0;
1255: mat->stencil.noc = (PetscTruth)(dof == 1);
1256: return(0);
1257: }
1261: /*@
1262: MatSetValuesBlocked - Inserts or adds a block of values into a matrix.
1264: Not Collective
1266: Input Parameters:
1267: + mat - the matrix
1268: . v - a logically two-dimensional array of values
1269: . m, idxm - the number of block rows and their global block indices
1270: . n, idxn - the number of block columns and their global block indices
1271: - addv - either ADD_VALUES or INSERT_VALUES, where
1272: ADD_VALUES adds values to any existing entries, and
1273: INSERT_VALUES replaces existing entries with new values
1275: Notes:
1276: The m and n count the NUMBER of blocks in the row direction and column direction,
1277: NOT the total number of rows/columns; for example, if the block size is 2 and
1278: you are passing in values for rows 2,3,4,5 then m would be 2 (not 4).
1279: The values in idxm would be 1 2; that is the first index for each block divided by
1280: the block size.
1282: By default the values, v, are row-oriented and unsorted. So the layout of
1283: v is the same as for MatSetValues(). See MatSetOption() for other options.
1285: Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
1286: options cannot be mixed without intervening calls to the assembly
1287: routines.
1289: MatSetValuesBlocked() uses 0-based row and column numbers in Fortran
1290: as well as in C.
1292: Negative indices may be passed in idxm and idxn, these rows and columns are
1293: simply ignored. This allows easily inserting element stiffness matrices
1294: with homogeneous Dirchlet boundary conditions that you don't want represented
1295: in the matrix.
1297: Each time an entry is set within a sparse matrix via MatSetValues(),
1298: internal searching must be done to determine where to place the the
1299: data in the matrix storage space. By instead inserting blocks of
1300: entries via MatSetValuesBlocked(), the overhead of matrix assembly is
1301: reduced.
1303: Example:
1304: $ Suppose m=n=2 and block size(bs) = 2 The array is
1305: $
1306: $ 1 2 | 3 4
1307: $ 5 6 | 7 8
1308: $ - - - | - - -
1309: $ 9 10 | 11 12
1310: $ 13 14 | 15 16
1311: $
1312: $ v[] should be passed in like
1313: $ v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
1314: $
1315: $ If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then
1316: $ v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16]
1318: Level: intermediate
1320: Concepts: matrices^putting entries in blocked
1322: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal()
1323: @*/
1324: PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1325: {
1331: if (!m || !n) return(0); /* no values to insert */
1335: MatPreallocated(mat);
1336: if (mat->insertmode == NOT_SET_VALUES) {
1337: mat->insertmode = addv;
1338: }
1339: #if defined(PETSC_USE_DEBUG)
1340: else if (mat->insertmode != addv) {
1341: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1342: }
1343: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1344: #endif
1346: if (mat->assembled) {
1347: mat->was_assembled = PETSC_TRUE;
1348: mat->assembled = PETSC_FALSE;
1349: }
1350: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1351: if (mat->ops->setvaluesblocked) {
1352: (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);
1353: } else {
1354: PetscInt buf[4096],*ibufm=0,*ibufn=0;
1355: PetscInt i,j,*iidxm,*iidxn,bs=mat->rmap->bs;
1356: if ((m+n)*bs <= 4096) {
1357: iidxm = buf; iidxn = buf + m*bs;
1358: } else {
1359: PetscMalloc2(m*bs,PetscInt,&ibufm,n*bs,PetscInt,&ibufn);
1360: iidxm = ibufm; iidxn = ibufn;
1361: }
1362: for (i=0; i<m; i++) {
1363: for (j=0; j<bs; j++) {
1364: iidxm[i*bs+j] = bs*idxm[i] + j;
1365: }
1366: }
1367: for (i=0; i<n; i++) {
1368: for (j=0; j<bs; j++) {
1369: iidxn[i*bs+j] = bs*idxn[i] + j;
1370: }
1371: }
1372: MatSetValues(mat,bs*m,iidxm,bs*n,iidxn,v,addv);
1373: PetscFree2(ibufm,ibufn);
1374: }
1375: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1376: return(0);
1377: }
1381: /*@
1382: MatGetValues - Gets a block of values from a matrix.
1384: Not Collective; currently only returns a local block
1386: Input Parameters:
1387: + mat - the matrix
1388: . v - a logically two-dimensional array for storing the values
1389: . m, idxm - the number of rows and their global indices
1390: - n, idxn - the number of columns and their global indices
1392: Notes:
1393: The user must allocate space (m*n PetscScalars) for the values, v.
1394: The values, v, are then returned in a row-oriented format,
1395: analogous to that used by default in MatSetValues().
1397: MatGetValues() uses 0-based row and column numbers in
1398: Fortran as well as in C.
1400: MatGetValues() requires that the matrix has been assembled
1401: with MatAssemblyBegin()/MatAssemblyEnd(). Thus, calls to
1402: MatSetValues() and MatGetValues() CANNOT be made in succession
1403: without intermediate matrix assembly.
1405: Negative row or column indices will be ignored and those locations in v[] will be
1406: left unchanged.
1408: Level: advanced
1410: Concepts: matrices^accessing values
1412: .seealso: MatGetRow(), MatGetSubMatrices(), MatSetValues()
1413: @*/
1414: PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1415: {
1424: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1425: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1426: if (!mat->ops->getvalues) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1427: MatPreallocated(mat);
1429: PetscLogEventBegin(MAT_GetValues,mat,0,0,0);
1430: (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);
1431: PetscLogEventEnd(MAT_GetValues,mat,0,0,0);
1432: return(0);
1433: }
1437: /*@
1438: MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
1439: the routine MatSetValuesLocal() to allow users to insert matrix entries
1440: using a local (per-processor) numbering.
1442: Not Collective
1444: Input Parameters:
1445: + x - the matrix
1446: - mapping - mapping created with ISLocalToGlobalMappingCreate()
1447: or ISLocalToGlobalMappingCreateIS()
1449: Level: intermediate
1451: Concepts: matrices^local to global mapping
1452: Concepts: local to global mapping^for matrices
1454: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
1455: @*/
1456: PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping mapping)
1457: {
1463: if (x->mapping) {
1464: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Mapping already set for matrix");
1465: }
1466: MatPreallocated(x);
1468: if (x->ops->setlocaltoglobalmapping) {
1469: (*x->ops->setlocaltoglobalmapping)(x,mapping);
1470: } else {
1471: PetscObjectReference((PetscObject)mapping);
1472: if (x->mapping) { ISLocalToGlobalMappingDestroy(x->mapping); }
1473: x->mapping = mapping;
1474: }
1475: return(0);
1476: }
1480: /*@
1481: MatSetLocalToGlobalMappingBlock - Sets a local-to-global numbering for use
1482: by the routine MatSetValuesBlockedLocal() to allow users to insert matrix
1483: entries using a local (per-processor) numbering.
1485: Not Collective
1487: Input Parameters:
1488: + x - the matrix
1489: - mapping - mapping created with ISLocalToGlobalMappingCreate() or
1490: ISLocalToGlobalMappingCreateIS()
1492: Level: intermediate
1494: Concepts: matrices^local to global mapping blocked
1495: Concepts: local to global mapping^for matrices, blocked
1497: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal(),
1498: MatSetValuesBlocked(), MatSetValuesLocal()
1499: @*/
1500: PetscErrorCode MatSetLocalToGlobalMappingBlock(Mat x,ISLocalToGlobalMapping mapping)
1501: {
1507: if (x->bmapping) {
1508: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Mapping already set for matrix");
1509: }
1510: PetscObjectReference((PetscObject)mapping);
1511: if (x->bmapping) { ISLocalToGlobalMappingDestroy(x->mapping); }
1512: x->bmapping = mapping;
1513: return(0);
1514: }
1518: /*@
1519: MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
1520: using a local ordering of the nodes.
1522: Not Collective
1524: Input Parameters:
1525: + x - the matrix
1526: . nrow, irow - number of rows and their local indices
1527: . ncol, icol - number of columns and their local indices
1528: . y - a logically two-dimensional array of values
1529: - addv - either INSERT_VALUES or ADD_VALUES, where
1530: ADD_VALUES adds values to any existing entries, and
1531: INSERT_VALUES replaces existing entries with new values
1533: Notes:
1534: Before calling MatSetValuesLocal(), the user must first set the
1535: local-to-global mapping by calling MatSetLocalToGlobalMapping().
1537: Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
1538: options cannot be mixed without intervening calls to the assembly
1539: routines.
1541: These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1542: MUST be called after all calls to MatSetValuesLocal() have been completed.
1544: Level: intermediate
1546: Concepts: matrices^putting entries in with local numbering
1548: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
1549: MatSetValueLocal()
1550: @*/
1551: PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
1552: {
1554: PetscInt irowm[2048],icolm[2048];
1559: if (!nrow || !ncol) return(0); /* no values to insert */
1563: MatPreallocated(mat);
1564: if (mat->insertmode == NOT_SET_VALUES) {
1565: mat->insertmode = addv;
1566: }
1567: #if defined(PETSC_USE_DEBUG)
1568: else if (mat->insertmode != addv) {
1569: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1570: }
1571: if (!mat->ops->setvalueslocal && (nrow > 2048 || ncol > 2048)) {
1572: SETERRQ2(PETSC_ERR_SUP,"Number column/row indices must be <= 2048: are %D %D",nrow,ncol);
1573: }
1574: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1575: #endif
1577: if (mat->assembled) {
1578: mat->was_assembled = PETSC_TRUE;
1579: mat->assembled = PETSC_FALSE;
1580: }
1581: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1582: if (!mat->ops->setvalueslocal) {
1583: ISLocalToGlobalMappingApply(mat->mapping,nrow,irow,irowm);
1584: ISLocalToGlobalMappingApply(mat->mapping,ncol,icol,icolm);
1585: (*mat->ops->setvalues)(mat,nrow,irowm,ncol,icolm,y,addv);
1586: } else {
1587: (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);
1588: }
1589: mat->same_nonzero = PETSC_FALSE;
1590: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1591: return(0);
1592: }
1596: /*@
1597: MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix,
1598: using a local ordering of the nodes a block at a time.
1600: Not Collective
1602: Input Parameters:
1603: + x - the matrix
1604: . nrow, irow - number of rows and their local indices
1605: . ncol, icol - number of columns and their local indices
1606: . y - a logically two-dimensional array of values
1607: - addv - either INSERT_VALUES or ADD_VALUES, where
1608: ADD_VALUES adds values to any existing entries, and
1609: INSERT_VALUES replaces existing entries with new values
1611: Notes:
1612: Before calling MatSetValuesBlockedLocal(), the user must first set the
1613: local-to-global mapping by calling MatSetLocalToGlobalMappingBlock(),
1614: where the mapping MUST be set for matrix blocks, not for matrix elements.
1616: Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
1617: options cannot be mixed without intervening calls to the assembly
1618: routines.
1620: These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1621: MUST be called after all calls to MatSetValuesBlockedLocal() have been completed.
1623: Level: intermediate
1625: Concepts: matrices^putting blocked values in with local numbering
1627: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesLocal(), MatSetLocalToGlobalMappingBlock(), MatSetValuesBlocked()
1628: @*/
1629: PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
1630: {
1632: PetscInt irowm[2048],icolm[2048];
1637: if (!nrow || !ncol) return(0); /* no values to insert */
1641: MatPreallocated(mat);
1642: if (mat->insertmode == NOT_SET_VALUES) {
1643: mat->insertmode = addv;
1644: }
1645: #if defined(PETSC_USE_DEBUG)
1646: else if (mat->insertmode != addv) {
1647: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1648: }
1649: if (!mat->bmapping) {
1650: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Local to global never set with MatSetLocalToGlobalMappingBlock()");
1651: }
1652: if (nrow > 2048 || ncol > 2048) {
1653: SETERRQ2(PETSC_ERR_SUP,"Number column/row indices must be <= 2048: are %D %D",nrow,ncol);
1654: }
1655: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1656: #endif
1658: if (mat->assembled) {
1659: mat->was_assembled = PETSC_TRUE;
1660: mat->assembled = PETSC_FALSE;
1661: }
1662: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1663: ISLocalToGlobalMappingApply(mat->bmapping,nrow,irow,irowm);
1664: ISLocalToGlobalMappingApply(mat->bmapping,ncol,icol,icolm);
1665: if (mat->ops->setvaluesblocked) {
1666: (*mat->ops->setvaluesblocked)(mat,nrow,irowm,ncol,icolm,y,addv);
1667: } else {
1668: PetscInt buf[4096],*ibufm=0,*ibufn=0;
1669: PetscInt i,j,*iirowm,*iicolm,bs=mat->rmap->bs;
1670: if ((nrow+ncol)*bs <= 4096) {
1671: iirowm = buf; iicolm = buf + nrow*bs;
1672: } else {
1673: PetscMalloc2(nrow*bs,PetscInt,&ibufm,ncol*bs,PetscInt,&ibufn);
1674: iirowm = ibufm; iicolm = ibufn;
1675: }
1676: for (i=0; i<nrow; i++) {
1677: for (j=0; j<bs; j++) {
1678: iirowm[i*bs+j] = bs*irowm[i] + j;
1679: }
1680: }
1681: for (i=0; i<ncol; i++) {
1682: for (j=0; j<bs; j++) {
1683: iicolm[i*bs+j] = bs*icolm[i] + j;
1684: }
1685: }
1686: MatSetValues(mat,bs*nrow,iirowm,bs*ncol,iicolm,y,addv);
1687: PetscFree2(ibufm,ibufn);
1688: }
1689: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1690: return(0);
1691: }
1693: /* --------------------------------------------------------*/
1696: /*@
1697: MatMult - Computes the matrix-vector product, y = Ax.
1699: Collective on Mat and Vec
1701: Input Parameters:
1702: + mat - the matrix
1703: - x - the vector to be multiplied
1705: Output Parameters:
1706: . y - the result
1708: Notes:
1709: The vectors x and y cannot be the same. I.e., one cannot
1710: call MatMult(A,y,y).
1712: Level: beginner
1714: Concepts: matrix-vector product
1716: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
1717: @*/
1718: PetscErrorCode MatMult(Mat mat,Vec x,Vec y)
1719: {
1728: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1729: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1730: if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1731: #ifndef PETSC_HAVE_CONSTRAINTS
1732: if (mat->cmap->N != x->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
1733: if (mat->rmap->N != y->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
1734: if (mat->rmap->n != y->map->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %D %D",mat->rmap->n,y->map->n);
1735: #endif
1736: MatPreallocated(mat);
1738: if (mat->nullsp) {
1739: MatNullSpaceRemove(mat->nullsp,x,&x);
1740: }
1742: if (!mat->ops->mult) SETERRQ(PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
1743: PetscLogEventBegin(MAT_Mult,mat,x,y,0);
1744: (*mat->ops->mult)(mat,x,y);
1745: PetscLogEventEnd(MAT_Mult,mat,x,y,0);
1747: if (mat->nullsp) {
1748: MatNullSpaceRemove(mat->nullsp,y,PETSC_NULL);
1749: }
1750: PetscObjectStateIncrease((PetscObject)y);
1751: return(0);
1752: }
1756: /*@
1757: MatMultTranspose - Computes matrix transpose times a vector.
1759: Collective on Mat and Vec
1761: Input Parameters:
1762: + mat - the matrix
1763: - x - the vector to be multilplied
1765: Output Parameters:
1766: . y - the result
1768: Notes:
1769: The vectors x and y cannot be the same. I.e., one cannot
1770: call MatMultTranspose(A,y,y).
1772: Level: beginner
1774: Concepts: matrix vector product^transpose
1776: .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd()
1777: @*/
1778: PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y)
1779: {
1788: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1789: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1790: if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1791: #ifndef PETSC_HAVE_CONSTRAINTS
1792: if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
1793: if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N);
1794: #endif
1795: MatPreallocated(mat);
1797: if (!mat->ops->multtranspose) SETERRQ(PETSC_ERR_SUP,"This matrix type does not have a multiply tranpose defined");
1798: PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);
1799: (*mat->ops->multtranspose)(mat,x,y);
1800: PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);
1801: PetscObjectStateIncrease((PetscObject)y);
1802: return(0);
1803: }
1807: /*@
1808: MatMultAdd - Computes v3 = v2 + A * v1.
1810: Collective on Mat and Vec
1812: Input Parameters:
1813: + mat - the matrix
1814: - v1, v2 - the vectors
1816: Output Parameters:
1817: . v3 - the result
1819: Notes:
1820: The vectors v1 and v3 cannot be the same. I.e., one cannot
1821: call MatMultAdd(A,v1,v2,v1).
1823: Level: beginner
1825: Concepts: matrix vector product^addition
1827: .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
1828: @*/
1829: PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
1830: {
1840: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1841: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1842: if (mat->cmap->N != v1->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->cmap->N,v1->map->N);
1843: if (mat->rmap->N != v2->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->rmap->N,v2->map->N);
1844: if (mat->rmap->N != v3->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->rmap->N,v3->map->N);
1845: if (mat->rmap->n != v3->map->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: local dim %D %D",mat->rmap->n,v3->map->n);
1846: if (mat->rmap->n != v2->map->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: local dim %D %D",mat->rmap->n,v2->map->n);
1847: if (v1 == v3) SETERRQ(PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
1848: MatPreallocated(mat);
1850: PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);
1851: (*mat->ops->multadd)(mat,v1,v2,v3);
1852: PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);
1853: PetscObjectStateIncrease((PetscObject)v3);
1854: return(0);
1855: }
1859: /*@
1860: MatMultTransposeAdd - Computes v3 = v2 + A' * v1.
1862: Collective on Mat and Vec
1864: Input Parameters:
1865: + mat - the matrix
1866: - v1, v2 - the vectors
1868: Output Parameters:
1869: . v3 - the result
1871: Notes:
1872: The vectors v1 and v3 cannot be the same. I.e., one cannot
1873: call MatMultTransposeAdd(A,v1,v2,v1).
1875: Level: beginner
1877: Concepts: matrix vector product^transpose and addition
1879: .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
1880: @*/
1881: PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
1882: {
1892: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1893: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1894: if (!mat->ops->multtransposeadd) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1895: if (v1 == v3) SETERRQ(PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
1896: if (mat->rmap->N != v1->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->rmap->N,v1->map->N);
1897: if (mat->cmap->N != v2->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->cmap->N,v2->map->N);
1898: if (mat->cmap->N != v3->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->cmap->N,v3->map->N);
1899: MatPreallocated(mat);
1901: PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);
1902: (*mat->ops->multtransposeadd)(mat,v1,v2,v3);
1903: PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);
1904: PetscObjectStateIncrease((PetscObject)v3);
1905: return(0);
1906: }
1910: /*@
1911: MatMultConstrained - The inner multiplication routine for a
1912: constrained matrix P^T A P.
1914: Collective on Mat and Vec
1916: Input Parameters:
1917: + mat - the matrix
1918: - x - the vector to be multilplied
1920: Output Parameters:
1921: . y - the result
1923: Notes:
1924: The vectors x and y cannot be the same. I.e., one cannot
1925: call MatMult(A,y,y).
1927: Level: beginner
1929: .keywords: matrix, multiply, matrix-vector product, constraint
1930: .seealso: MatMult(), MatMultTrans(), MatMultAdd(), MatMultTransAdd()
1931: @*/
1932: PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y)
1933: {
1940: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1941: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1942: if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1943: if (mat->cmap->N != x->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
1944: if (mat->rmap->N != y->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
1945: if (mat->rmap->n != y->map->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %D %D",mat->rmap->n,y->map->n);
1947: PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
1948: (*mat->ops->multconstrained)(mat,x,y);
1949: PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
1950: PetscObjectStateIncrease((PetscObject)y);
1952: return(0);
1953: }
1957: /*@
1958: MatMultTransposeConstrained - The inner multiplication routine for a
1959: constrained matrix P^T A^T P.
1961: Collective on Mat and Vec
1963: Input Parameters:
1964: + mat - the matrix
1965: - x - the vector to be multilplied
1967: Output Parameters:
1968: . y - the result
1970: Notes:
1971: The vectors x and y cannot be the same. I.e., one cannot
1972: call MatMult(A,y,y).
1974: Level: beginner
1976: .keywords: matrix, multiply, matrix-vector product, constraint
1977: .seealso: MatMult(), MatMultTrans(), MatMultAdd(), MatMultTransAdd()
1978: @*/
1979: PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
1980: {
1987: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1988: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1989: if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1990: if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
1991: if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
1993: PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
1994: (*mat->ops->multtransposeconstrained)(mat,x,y);
1995: PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
1996: PetscObjectStateIncrease((PetscObject)y);
1998: return(0);
1999: }
2000: /* ------------------------------------------------------------*/
2003: /*@
2004: MatGetInfo - Returns information about matrix storage (number of
2005: nonzeros, memory, etc.).
2007: Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used
2008: as the flag
2010: Input Parameters:
2011: . mat - the matrix
2013: Output Parameters:
2014: + flag - flag indicating the type of parameters to be returned
2015: (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2016: MAT_GLOBAL_SUM - sum over all processors)
2017: - info - matrix information context
2019: Notes:
2020: The MatInfo context contains a variety of matrix data, including
2021: number of nonzeros allocated and used, number of mallocs during
2022: matrix assembly, etc. Additional information for factored matrices
2023: is provided (such as the fill ratio, number of mallocs during
2024: factorization, etc.). Much of this info is printed to PETSC_STDOUT
2025: when using the runtime options
2026: $ -info -mat_view_info
2028: Example for C/C++ Users:
2029: See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2030: data within the MatInfo context. For example,
2031: .vb
2032: MatInfo info;
2033: Mat A;
2034: double mal, nz_a, nz_u;
2036: MatGetInfo(A,MAT_LOCAL,&info);
2037: mal = info.mallocs;
2038: nz_a = info.nz_allocated;
2039: .ve
2041: Example for Fortran Users:
2042: Fortran users should declare info as a double precision
2043: array of dimension MAT_INFO_SIZE, and then extract the parameters
2044: of interest. See the file ${PETSC_DIR}/include/finclude/petscmat.h
2045: a complete list of parameter names.
2046: .vb
2047: double precision info(MAT_INFO_SIZE)
2048: double precision mal, nz_a
2049: Mat A
2050: integer ierr
2052: call MatGetInfo(A,MAT_LOCAL,info,ierr)
2053: mal = info(MAT_INFO_MALLOCS)
2054: nz_a = info(MAT_INFO_NZ_ALLOCATED)
2055: .ve
2057: Level: intermediate
2059: Concepts: matrices^getting information on
2060:
2061: @*/
2062: PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2063: {
2070: if (!mat->ops->getinfo) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2071: MatPreallocated(mat);
2072: (*mat->ops->getinfo)(mat,flag,info);
2073: return(0);
2074: }
2076: /* ----------------------------------------------------------*/
2079: /*@C
2080: MatILUDTFactor - Performs a drop tolerance ILU factorization.
2082: Collective on Mat
2084: Input Parameters:
2085: + mat - the matrix
2086: . row - row permutation
2087: . col - column permutation
2088: - info - information about the factorization to be done
2090: Output Parameters:
2091: . fact - the factored matrix
2093: Level: developer
2095: Notes:
2096: Most users should employ the simplified KSP interface for linear solvers
2097: instead of working directly with matrix algebra routines such as this.
2098: See, e.g., KSPCreate().
2100: This is currently only supported for the SeqAIJ matrix format using code
2101: from Yousef Saad's SPARSEKIT2 package (translated to C with f2c) and/or
2102: Matlab. SPARSEKIT2 is copyrighted by Yousef Saad with the GNU copyright
2103: and thus can be distributed with PETSc.
2105: Concepts: matrices^ILUDT factorization
2107: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
2108: @*/
2109: PetscErrorCode MatILUDTFactor(Mat mat,IS row,IS col,const MatFactorInfo *info,Mat *fact)
2110: {
2120: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2121: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2122: if (!mat->ops->iludtfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2123: MatPreallocated(mat);
2124: PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);
2125: (*mat->ops->iludtfactor)(mat,row,col,info,fact);
2126: PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);
2127: PetscObjectStateIncrease((PetscObject)*fact);
2129: return(0);
2130: }
2134: /*@
2135: MatLUFactor - Performs in-place LU factorization of matrix.
2137: Collective on Mat
2139: Input Parameters:
2140: + mat - the matrix
2141: . row - row permutation
2142: . col - column permutation
2143: - info - options for factorization, includes
2144: $ fill - expected fill as ratio of original fill.
2145: $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2146: $ Run with the option -info to determine an optimal value to use
2148: Notes:
2149: Most users should employ the simplified KSP interface for linear solvers
2150: instead of working directly with matrix algebra routines such as this.
2151: See, e.g., KSPCreate().
2153: This changes the state of the matrix to a factored matrix; it cannot be used
2154: for example with MatSetValues() unless one first calls MatSetUnfactored().
2156: Level: developer
2158: Concepts: matrices^LU factorization
2160: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2161: MatGetOrdering(), MatSetUnfactored(), MatFactorInfo
2163: @*/
2164: PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2165: {
2174: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2175: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2176: if (!mat->ops->lufactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2177: MatPreallocated(mat);
2179: PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);
2180: (*mat->ops->lufactor)(mat,row,col,info);
2181: PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);
2182: PetscObjectStateIncrease((PetscObject)mat);
2183: return(0);
2184: }
2188: /*@
2189: MatILUFactor - Performs in-place ILU factorization of matrix.
2191: Collective on Mat
2193: Input Parameters:
2194: + mat - the matrix
2195: . row - row permutation
2196: . col - column permutation
2197: - info - structure containing
2198: $ levels - number of levels of fill.
2199: $ expected fill - as ratio of original fill.
2200: $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2201: missing diagonal entries)
2203: Notes:
2204: Probably really in-place only when level of fill is zero, otherwise allocates
2205: new space to store factored matrix and deletes previous memory.
2207: Most users should employ the simplified KSP interface for linear solvers
2208: instead of working directly with matrix algebra routines such as this.
2209: See, e.g., KSPCreate().
2211: Level: developer
2213: Concepts: matrices^ILU factorization
2215: .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
2216: @*/
2217: PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2218: {
2227: if (mat->rmap->N != mat->cmap->N) SETERRQ(PETSC_ERR_ARG_WRONG,"matrix must be square");
2228: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2229: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2230: if (!mat->ops->ilufactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2231: MatPreallocated(mat);
2233: PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);
2234: (*mat->ops->ilufactor)(mat,row,col,info);
2235: PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);
2236: PetscObjectStateIncrease((PetscObject)mat);
2237: return(0);
2238: }
2242: /*@
2243: MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
2244: Call this routine before calling MatLUFactorNumeric().
2246: Collective on Mat
2248: Input Parameters:
2249: + fact - the factor matrix obtained with MatGetFactor()
2250: . mat - the matrix
2251: . row, col - row and column permutations
2252: - info - options for factorization, includes
2253: $ fill - expected fill as ratio of original fill.
2254: $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2255: $ Run with the option -info to determine an optimal value to use
2258: Notes:
2259: See the users manual for additional information about
2260: choosing the fill factor for better efficiency.
2262: Most users should employ the simplified KSP interface for linear solvers
2263: instead of working directly with matrix algebra routines such as this.
2264: See, e.g., KSPCreate().
2266: Level: developer
2268: Concepts: matrices^LU symbolic factorization
2270: .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
2271: @*/
2272: PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
2273: {
2283: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2284: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2285: if (!(fact)->ops->lufactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s symbolic LU",((PetscObject)mat)->type_name);
2286: MatPreallocated(mat);
2288: PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);
2289: (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);
2290: PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);
2291: PetscObjectStateIncrease((PetscObject)fact);
2292: return(0);
2293: }
2297: /*@
2298: MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
2299: Call this routine after first calling MatLUFactorSymbolic().
2301: Collective on Mat
2303: Input Parameters:
2304: + fact - the factor matrix obtained with MatGetFactor()
2305: . mat - the matrix
2306: - info - options for factorization
2308: Notes:
2309: See MatLUFactor() for in-place factorization. See
2310: MatCholeskyFactorNumeric() for the symmetric, positive definite case.
2312: Most users should employ the simplified KSP interface for linear solvers
2313: instead of working directly with matrix algebra routines such as this.
2314: See, e.g., KSPCreate().
2316: Level: developer
2318: Concepts: matrices^LU numeric factorization
2320: .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()
2321: @*/
2322: PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
2323: {
2331: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2332: if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) {
2333: SETERRQ4(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);
2334: }
2335: if (!(fact)->ops->lufactornumeric) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2336: MatPreallocated(mat);
2337: PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);
2338: (fact->ops->lufactornumeric)(fact,mat,info);
2339: PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);
2341: MatView_Private(fact);
2342: PetscObjectStateIncrease((PetscObject)fact);
2343: return(0);
2344: }
2348: /*@
2349: MatCholeskyFactor - Performs in-place Cholesky factorization of a
2350: symmetric matrix.
2352: Collective on Mat
2354: Input Parameters:
2355: + mat - the matrix
2356: . perm - row and column permutations
2357: - f - expected fill as ratio of original fill
2359: Notes:
2360: See MatLUFactor() for the nonsymmetric case. See also
2361: MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().
2363: Most users should employ the simplified KSP interface for linear solvers
2364: instead of working directly with matrix algebra routines such as this.
2365: See, e.g., KSPCreate().
2367: Level: developer
2369: Concepts: matrices^Cholesky factorization
2371: .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
2372: MatGetOrdering()
2374: @*/
2375: PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
2376: {
2384: if (mat->rmap->N != mat->cmap->N) SETERRQ(PETSC_ERR_ARG_WRONG,"Matrix must be square");
2385: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2386: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2387: if (!mat->ops->choleskyfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2388: MatPreallocated(mat);
2390: PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);
2391: (*mat->ops->choleskyfactor)(mat,perm,info);
2392: PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);
2393: PetscObjectStateIncrease((PetscObject)mat);
2394: return(0);
2395: }
2399: /*@
2400: MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
2401: of a symmetric matrix.
2403: Collective on Mat
2405: Input Parameters:
2406: + fact - the factor matrix obtained with MatGetFactor()
2407: . mat - the matrix
2408: . perm - row and column permutations
2409: - info - options for factorization, includes
2410: $ fill - expected fill as ratio of original fill.
2411: $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2412: $ Run with the option -info to determine an optimal value to use
2414: Notes:
2415: See MatLUFactorSymbolic() for the nonsymmetric case. See also
2416: MatCholeskyFactor() and MatCholeskyFactorNumeric().
2418: Most users should employ the simplified KSP interface for linear solvers
2419: instead of working directly with matrix algebra routines such as this.
2420: See, e.g., KSPCreate().
2422: Level: developer
2424: Concepts: matrices^Cholesky symbolic factorization
2426: .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
2427: MatGetOrdering()
2429: @*/
2430: PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
2431: {
2440: if (mat->rmap->N != mat->cmap->N) SETERRQ(PETSC_ERR_ARG_WRONG,"Matrix must be square");
2441: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2442: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2443: if (!(fact)->ops->choleskyfactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2444: MatPreallocated(mat);
2446: PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
2447: (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);
2448: PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
2449: PetscObjectStateIncrease((PetscObject)fact);
2450: return(0);
2451: }
2455: /*@
2456: MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
2457: of a symmetric matrix. Call this routine after first calling
2458: MatCholeskyFactorSymbolic().
2460: Collective on Mat
2462: Input Parameters:
2463: + fact - the factor matrix obtained with MatGetFactor()
2464: . mat - the initial matrix
2465: . info - options for factorization
2466: - fact - the symbolic factor of mat
2469: Notes:
2470: Most users should employ the simplified KSP interface for linear solvers
2471: instead of working directly with matrix algebra routines such as this.
2472: See, e.g., KSPCreate().
2474: Level: developer
2476: Concepts: matrices^Cholesky numeric factorization
2478: .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
2479: @*/
2480: PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
2481: {
2489: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2490: if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2491: if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) {
2492: SETERRQ4(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);
2493: }
2494: MatPreallocated(mat);
2496: PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);
2497: (fact->ops->choleskyfactornumeric)(fact,mat,info);
2498: PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);
2500: MatView_Private(fact);
2501: PetscObjectStateIncrease((PetscObject)fact);
2502: return(0);
2503: }
2505: /* ----------------------------------------------------------------*/
2508: /*@
2509: MatSolve - Solves A x = b, given a factored matrix.
2511: Collective on Mat and Vec
2513: Input Parameters:
2514: + mat - the factored matrix
2515: - b - the right-hand-side vector
2517: Output Parameter:
2518: . x - the result vector
2520: Notes:
2521: The vectors b and x cannot be the same. I.e., one cannot
2522: call MatSolve(A,x,x).
2524: Notes:
2525: Most users should employ the simplified KSP interface for linear solvers
2526: instead of working directly with matrix algebra routines such as this.
2527: See, e.g., KSPCreate().
2529: Level: developer
2531: Concepts: matrices^triangular solves
2533: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
2534: @*/
2535: PetscErrorCode MatSolve(Mat mat,Vec b,Vec x)
2536: {
2546: if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2547: if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2548: if (mat->cmap->N != x->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
2549: if (mat->rmap->N != b->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
2550: if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
2551: if (!mat->rmap->N && !mat->cmap->N) return(0);
2552: if (!mat->ops->solve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2553: MatPreallocated(mat);
2555: PetscLogEventBegin(MAT_Solve,mat,b,x,0);
2556: (*mat->ops->solve)(mat,b,x);
2557: PetscLogEventEnd(MAT_Solve,mat,b,x,0);
2558: PetscObjectStateIncrease((PetscObject)x);
2559: return(0);
2560: }
2564: PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X)
2565: {
2567: Vec b,x;
2568: PetscInt m,N,i;
2569: PetscScalar *bb,*xx;
2572: MatGetArray(B,&bb);
2573: MatGetArray(X,&xx);
2574: MatGetLocalSize(B,&m,PETSC_NULL); /* number local rows */
2575: MatGetSize(B,PETSC_NULL,&N); /* total columns in dense matrix */
2576: VecCreateMPIWithArray(((PetscObject)A)->comm,m,PETSC_DETERMINE,PETSC_NULL,&b);
2577: VecCreateMPIWithArray(((PetscObject)A)->comm,m,PETSC_DETERMINE,PETSC_NULL,&x);
2578: for (i=0; i<N; i++) {
2579: VecPlaceArray(b,bb + i*m);
2580: VecPlaceArray(x,xx + i*m);
2581: MatSolve(A,b,x);
2582: VecResetArray(x);
2583: VecResetArray(b);
2584: }
2585: VecDestroy(b);
2586: VecDestroy(x);
2587: MatRestoreArray(B,&bb);
2588: MatRestoreArray(X,&xx);
2589: return(0);
2590: }
2594: /*@
2595: MatMatSolve - Solves A X = B, given a factored matrix.
2597: Collective on Mat
2599: Input Parameters:
2600: + mat - the factored matrix
2601: - B - the right-hand-side matrix (dense matrix)
2603: Output Parameter:
2604: . X - the result matrix (dense matrix)
2606: Notes:
2607: The matrices b and x cannot be the same. I.e., one cannot
2608: call MatMatSolve(A,x,x).
2610: Notes:
2611: Most users should usually employ the simplified KSP interface for linear solvers
2612: instead of working directly with matrix algebra routines such as this.
2613: See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
2614: at a time.
2616: Level: developer
2618: Concepts: matrices^triangular solves
2620: .seealso: MatMatSolveAdd(), MatMatSolveTranspose(), MatMatSolveTransposeAdd(), MatLUFactor(), MatCholeskyFactor()
2621: @*/
2622: PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X)
2623: {
2633: if (X == B) SETERRQ(PETSC_ERR_ARG_IDN,"X and B must be different matrices");
2634: if (!A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2635: if (A->cmap->N != X->rmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %D %D",A->cmap->N,X->rmap->N);
2636: if (A->rmap->N != B->rmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %D %D",A->rmap->N,B->rmap->N);
2637: if (A->rmap->n != B->rmap->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat A,Mat B: local dim %D %D",A->rmap->n,B->rmap->n);
2638: if (!A->rmap->N && !A->cmap->N) return(0);
2639: MatPreallocated(A);
2641: PetscLogEventBegin(MAT_MatSolve,A,B,X,0);
2642: if (!A->ops->matsolve) {
2643: PetscInfo1(A,"Mat type %s using basic MatMatSolve",((PetscObject)A)->type_name);
2644: MatMatSolve_Basic(A,B,X);
2645: } else {
2646: (*A->ops->matsolve)(A,B,X);
2647: }
2648: PetscLogEventEnd(MAT_MatSolve,A,B,X,0);
2649: PetscObjectStateIncrease((PetscObject)X);
2650: return(0);
2651: }
2656: /* @
2657: MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or
2658: U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U,
2660: Collective on Mat and Vec
2662: Input Parameters:
2663: + mat - the factored matrix
2664: - b - the right-hand-side vector
2666: Output Parameter:
2667: . x - the result vector
2669: Notes:
2670: MatSolve() should be used for most applications, as it performs
2671: a forward solve followed by a backward solve.
2673: The vectors b and x cannot be the same, i.e., one cannot
2674: call MatForwardSolve(A,x,x).
2676: For matrix in seqsbaij format with block size larger than 1,
2677: the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
2678: MatForwardSolve() solves U^T*D y = b, and
2679: MatBackwardSolve() solves U x = y.
2680: Thus they do not provide a symmetric preconditioner.
2682: Most users should employ the simplified KSP interface for linear solvers
2683: instead of working directly with matrix algebra routines such as this.
2684: See, e.g., KSPCreate().
2686: Level: developer
2688: Concepts: matrices^forward solves
2690: .seealso: MatSolve(), MatBackwardSolve()
2691: @ */
2692: PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x)
2693: {
2703: if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2704: if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2705: if (!mat->ops->forwardsolve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2706: if (mat->cmap->N != x->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
2707: if (mat->rmap->N != b->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
2708: if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
2709: MatPreallocated(mat);
2710: PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);
2711: (*mat->ops->forwardsolve)(mat,b,x);
2712: PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);
2713: PetscObjectStateIncrease((PetscObject)x);
2714: return(0);
2715: }
2719: /* @
2720: MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
2721: D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U,
2723: Collective on Mat and Vec
2725: Input Parameters:
2726: + mat - the factored matrix
2727: - b - the right-hand-side vector
2729: Output Parameter:
2730: . x - the result vector
2732: Notes:
2733: MatSolve() should be used for most applications, as it performs
2734: a forward solve followed by a backward solve.
2736: The vectors b and x cannot be the same. I.e., one cannot
2737: call MatBackwardSolve(A,x,x).
2739: For matrix in seqsbaij format with block size larger than 1,
2740: the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
2741: MatForwardSolve() solves U^T*D y = b, and
2742: MatBackwardSolve() solves U x = y.
2743: Thus they do not provide a symmetric preconditioner.
2745: Most users should employ the simplified KSP interface for linear solvers
2746: instead of working directly with matrix algebra routines such as this.
2747: See, e.g., KSPCreate().
2749: Level: developer
2751: Concepts: matrices^backward solves
2753: .seealso: MatSolve(), MatForwardSolve()
2754: @ */
2755: PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x)
2756: {
2766: if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2767: if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2768: if (!mat->ops->backwardsolve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2769: if (mat->cmap->N != x->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
2770: if (mat->rmap->N != b->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
2771: if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
2772: MatPreallocated(mat);
2774: PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);
2775: (*mat->ops->backwardsolve)(mat,b,x);
2776: PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);
2777: PetscObjectStateIncrease((PetscObject)x);
2778: return(0);
2779: }
2783: /*@
2784: MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
2786: Collective on Mat and Vec
2788: Input Parameters:
2789: + mat - the factored matrix
2790: . b - the right-hand-side vector
2791: - y - the vector to be added to
2793: Output Parameter:
2794: . x - the result vector
2796: Notes:
2797: The vectors b and x cannot be the same. I.e., one cannot
2798: call MatSolveAdd(A,x,y,x).
2800: Most users should employ the simplified KSP interface for linear solvers
2801: instead of working directly with matrix algebra routines such as this.
2802: See, e.g., KSPCreate().
2804: Level: developer
2806: Concepts: matrices^triangular solves
2808: .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
2809: @*/
2810: PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
2811: {
2812: PetscScalar one = 1.0;
2813: Vec tmp;
2825: if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2826: if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2827: if (mat->cmap->N != x->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
2828: if (mat->rmap->N != b->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
2829: if (mat->rmap->N != y->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
2830: if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
2831: if (x->map->n != y->map->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %D %D",x->map->n,y->map->n);
2832: MatPreallocated(mat);
2834: PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);
2835: if (mat->ops->solveadd) {
2836: (*mat->ops->solveadd)(mat,b,y,x);
2837: } else {
2838: /* do the solve then the add manually */
2839: if (x != y) {
2840: MatSolve(mat,b,x);
2841: VecAXPY(x,one,y);
2842: } else {
2843: VecDuplicate(x,&tmp);
2844: PetscLogObjectParent(mat,tmp);
2845: VecCopy(x,tmp);
2846: MatSolve(mat,b,x);
2847: VecAXPY(x,one,tmp);
2848: VecDestroy(tmp);
2849: }
2850: }
2851: PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);
2852: PetscObjectStateIncrease((PetscObject)x);
2853: return(0);
2854: }
2858: /*@
2859: MatSolveTranspose - Solves A' x = b, given a factored matrix.
2861: Collective on Mat and Vec
2863: Input Parameters:
2864: + mat - the factored matrix
2865: - b - the right-hand-side vector
2867: Output Parameter:
2868: . x - the result vector
2870: Notes:
2871: The vectors b and x cannot be the same. I.e., one cannot
2872: call MatSolveTranspose(A,x,x).
2874: Most users should employ the simplified KSP interface for linear solvers
2875: instead of working directly with matrix algebra routines such as this.
2876: See, e.g., KSPCreate().
2878: Level: developer
2880: Concepts: matrices^triangular solves
2882: .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
2883: @*/
2884: PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x)
2885: {
2895: if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2896: if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2897: if (!mat->ops->solvetranspose) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
2898: if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
2899: if (mat->cmap->N != b->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->cmap->N,b->map->N);
2900: MatPreallocated(mat);
2901: PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);
2902: (*mat->ops->solvetranspose)(mat,b,x);
2903: PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);
2904: PetscObjectStateIncrease((PetscObject)x);
2905: return(0);
2906: }
2910: /*@
2911: MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
2912: factored matrix.
2914: Collective on Mat and Vec
2916: Input Parameters:
2917: + mat - the factored matrix
2918: . b - the right-hand-side vector
2919: - y - the vector to be added to
2921: Output Parameter:
2922: . x - the result vector
2924: Notes:
2925: The vectors b and x cannot be the same. I.e., one cannot
2926: call MatSolveTransposeAdd(A,x,y,x).
2928: Most users should employ the simplified KSP interface for linear solvers
2929: instead of working directly with matrix algebra routines such as this.
2930: See, e.g., KSPCreate().
2932: Level: developer
2934: Concepts: matrices^triangular solves
2936: .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
2937: @*/
2938: PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
2939: {
2940: PetscScalar one = 1.0;
2942: Vec tmp;
2953: if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2954: if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2955: if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
2956: if (mat->cmap->N != b->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->cmap->N,b->map->N);
2957: if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N);
2958: if (x->map->n != y->map->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %D %D",x->map->n,y->map->n);
2959: MatPreallocated(mat);
2961: PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);
2962: if (mat->ops->solvetransposeadd) {
2963: (*mat->ops->solvetransposeadd)(mat,b,y,x);
2964: } else {
2965: /* do the solve then the add manually */
2966: if (x != y) {
2967: MatSolveTranspose(mat,b,x);
2968: VecAXPY(x,one,y);
2969: } else {
2970: VecDuplicate(x,&tmp);
2971: PetscLogObjectParent(mat,tmp);
2972: VecCopy(x,tmp);
2973: MatSolveTranspose(mat,b,x);
2974: VecAXPY(x,one,tmp);
2975: VecDestroy(tmp);
2976: }
2977: }
2978: PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);
2979: PetscObjectStateIncrease((PetscObject)x);
2980: return(0);
2981: }
2982: /* ----------------------------------------------------------------*/
2986: /*@
2987: MatRelax - Computes relaxation (SOR, Gauss-Seidel) sweeps.
2989: Collective on Mat and Vec
2991: Input Parameters:
2992: + mat - the matrix
2993: . b - the right hand side
2994: . omega - the relaxation factor
2995: . flag - flag indicating the type of SOR (see below)
2996: . shift - diagonal shift
2997: . its - the number of iterations
2998: - lits - the number of local iterations
3000: Output Parameters:
3001: . x - the solution (can contain an initial guess)
3003: SOR Flags:
3004: . SOR_FORWARD_SWEEP - forward SOR
3005: . SOR_BACKWARD_SWEEP - backward SOR
3006: . SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3007: . SOR_LOCAL_FORWARD_SWEEP - local forward SOR
3008: . SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
3009: . SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3010: . SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
3011: upper/lower triangular part of matrix to
3012: vector (with omega)
3013: . SOR_ZERO_INITIAL_GUESS - zero initial guess
3015: Notes:
3016: SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3017: SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3018: on each processor.
3020: Application programmers will not generally use MatRelax() directly,
3021: but instead will employ the KSP/PC interface.
3023: Notes for Advanced Users:
3024: The flags are implemented as bitwise inclusive or operations.
3025: For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3026: to specify a zero initial guess for SSOR.
3028: Most users should employ the simplified KSP interface for linear solvers
3029: instead of working directly with matrix algebra routines such as this.
3030: See, e.g., KSPCreate().
3032: See also, MatPBRelax(). This routine will automatically call the point block
3033: version if the point version is not available.
3035: Level: developer
3037: Concepts: matrices^relaxation
3038: Concepts: matrices^SOR
3039: Concepts: matrices^Gauss-Seidel
3041: @*/
3042: PetscErrorCode MatRelax(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3043: {
3053: if (!mat->ops->relax && !mat->ops->pbrelax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3054: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3055: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3056: if (mat->cmap->N != x->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3057: if (mat->rmap->N != b->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3058: if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3059: if (its <= 0) SETERRQ1(PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
3060: if (lits <= 0) SETERRQ1(PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
3062: MatPreallocated(mat);
3063: PetscLogEventBegin(MAT_Relax,mat,b,x,0);
3064: if (mat->ops->relax) {
3065: ierr =(*mat->ops->relax)(mat,b,omega,flag,shift,its,lits,x);
3066: } else {
3067: ierr =(*mat->ops->pbrelax)(mat,b,omega,flag,shift,its,lits,x);
3068: }
3069: PetscLogEventEnd(MAT_Relax,mat,b,x,0);
3070: PetscObjectStateIncrease((PetscObject)x);
3071: return(0);
3072: }
3076: /*@
3077: MatPBRelax - Computes relaxation (SOR, Gauss-Seidel) sweeps.
3079: Collective on Mat and Vec
3081: See MatRelax() for usage
3083: For multi-component PDEs where the Jacobian is stored in a point block format
3084: (with the PETSc BAIJ matrix formats) the relaxation is done one point block at
3085: a time. That is, the small (for example, 4 by 4) blocks along the diagonal are solved
3086: simultaneously (that is a 4 by 4 linear solve is done) to update all the values at a point.
3088: Level: developer
3090: @*/
3091: PetscErrorCode MatPBRelax(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3092: {
3102: if (!mat->ops->pbrelax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3103: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3104: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3105: if (mat->cmap->N != x->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3106: if (mat->rmap->N != b->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3107: if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3108: MatPreallocated(mat);
3110: PetscLogEventBegin(MAT_Relax,mat,b,x,0);
3111: ierr =(*mat->ops->pbrelax)(mat,b,omega,flag,shift,its,lits,x);
3112: PetscLogEventEnd(MAT_Relax,mat,b,x,0);
3113: PetscObjectStateIncrease((PetscObject)x);
3114: return(0);
3115: }
3119: /*
3120: Default matrix copy routine.
3121: */
3122: PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
3123: {
3124: PetscErrorCode ierr;
3125: PetscInt i,rstart,rend,nz;
3126: const PetscInt *cwork;
3127: const PetscScalar *vwork;
3130: if (B->assembled) {
3131: MatZeroEntries(B);
3132: }
3133: MatGetOwnershipRange(A,&rstart,&rend);
3134: for (i=rstart; i<rend; i++) {
3135: MatGetRow(A,i,&nz,&cwork,&vwork);
3136: MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);
3137: MatRestoreRow(A,i,&nz,&cwork,&vwork);
3138: }
3139: MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
3140: MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);
3141: PetscObjectStateIncrease((PetscObject)B);
3142: return(0);
3143: }
3147: /*@
3148: MatCopy - Copys a matrix to another matrix.
3150: Collective on Mat
3152: Input Parameters:
3153: + A - the matrix
3154: - str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
3156: Output Parameter:
3157: . B - where the copy is put
3159: Notes:
3160: If you use SAME_NONZERO_PATTERN then the two matrices had better have the
3161: same nonzero pattern or the routine will crash.
3163: MatCopy() copies the matrix entries of a matrix to another existing
3164: matrix (after first zeroing the second matrix). A related routine is
3165: MatConvert(), which first creates a new matrix and then copies the data.
3167: Level: intermediate
3168:
3169: Concepts: matrices^copying
3171: .seealso: MatConvert(), MatDuplicate()
3173: @*/
3174: PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str)
3175: {
3184: MatPreallocated(B);
3185: if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3186: if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3187: if (A->rmap->N != B->rmap->N || A->cmap->N != B->cmap->N) SETERRQ4(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);
3188: MatPreallocated(A);
3190: PetscLogEventBegin(MAT_Copy,A,B,0,0);
3191: if (A->ops->copy) {
3192: (*A->ops->copy)(A,B,str);
3193: } else { /* generic conversion */
3194: MatCopy_Basic(A,B,str);
3195: }
3196: if (A->mapping) {
3197: if (B->mapping) {ISLocalToGlobalMappingDestroy(B->mapping);B->mapping = 0;}
3198: MatSetLocalToGlobalMapping(B,A->mapping);
3199: }
3200: if (A->bmapping) {
3201: if (B->bmapping) {ISLocalToGlobalMappingDestroy(B->bmapping);B->bmapping = 0;}
3202: MatSetLocalToGlobalMappingBlock(B,A->mapping);
3203: }
3204: PetscLogEventEnd(MAT_Copy,A,B,0,0);
3205: PetscObjectStateIncrease((PetscObject)B);
3206: return(0);
3207: }
3211: /*@C
3212: MatConvert - Converts a matrix to another matrix, either of the same
3213: or different type.
3215: Collective on Mat
3217: Input Parameters:
3218: + mat - the matrix
3219: . newtype - new matrix type. Use MATSAME to create a new matrix of the
3220: same type as the original matrix.
3221: - reuse - denotes if the destination matrix is to be created or reused. Currently
3222: MAT_REUSE_MATRIX is only supported for inplace conversion, otherwise use
3223: MAT_INITIAL_MATRIX.
3225: Output Parameter:
3226: . M - pointer to place new matrix
3228: Notes:
3229: MatConvert() first creates a new matrix and then copies the data from
3230: the first matrix. A related routine is MatCopy(), which copies the matrix
3231: entries of one matrix to another already existing matrix context.
3233: Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
3234: the MPI communicator of the generated matrix is always the same as the communicator
3235: of the input matrix.
3237: Level: intermediate
3239: Concepts: matrices^converting between storage formats
3241: .seealso: MatCopy(), MatDuplicate()
3242: @*/
3243: PetscErrorCode MatConvert(Mat mat, const MatType newtype,MatReuse reuse,Mat *M)
3244: {
3245: PetscErrorCode ierr;
3246: PetscTruth sametype,issame,flg;
3247: char convname[256],mtype[256];
3248: Mat B;
3254: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3255: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3256: MatPreallocated(mat);
3258: PetscOptionsGetString(((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);
3259: if (flg) {
3260: newtype = mtype;
3261: }
3262: PetscTypeCompare((PetscObject)mat,newtype,&sametype);
3263: PetscStrcmp(newtype,"same",&issame);
3264: if ((reuse == MAT_REUSE_MATRIX) && (mat != *M)) {
3265: SETERRQ(PETSC_ERR_SUP,"MAT_REUSE_MATRIX only supported for in-place conversion currently");
3266: }
3268: if ((reuse == MAT_REUSE_MATRIX) && (issame || sametype)) return(0);
3269:
3270: if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
3271: (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);
3272: } else {
3273: PetscErrorCode (*conv)(Mat, const MatType,MatReuse,Mat*)=PETSC_NULL;
3274: const char *prefix[3] = {"seq","mpi",""};
3275: PetscInt i;
3276: /*
3277: Order of precedence:
3278: 1) See if a specialized converter is known to the current matrix.
3279: 2) See if a specialized converter is known to the desired matrix class.
3280: 3) See if a good general converter is registered for the desired class
3281: (as of 6/27/03 only MATMPIADJ falls into this category).
3282: 4) See if a good general converter is known for the current matrix.
3283: 5) Use a really basic converter.
3284: */
3285:
3286: /* 1) See if a specialized converter is known to the current matrix and the desired class */
3287: for (i=0; i<3; i++) {
3288: PetscStrcpy(convname,"MatConvert_");
3289: PetscStrcat(convname,((PetscObject)mat)->type_name);
3290: PetscStrcat(convname,"_");
3291: PetscStrcat(convname,prefix[i]);
3292: PetscStrcat(convname,newtype);
3293: PetscStrcat(convname,"_C");
3294: PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);
3295: if (conv) goto foundconv;
3296: }
3298: /* 2) See if a specialized converter is known to the desired matrix class. */
3299: MatCreate(((PetscObject)mat)->comm,&B);
3300: MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);
3301: MatSetType(B,newtype);
3302: for (i=0; i<3; i++) {
3303: PetscStrcpy(convname,"MatConvert_");
3304: PetscStrcat(convname,((PetscObject)mat)->type_name);
3305: PetscStrcat(convname,"_");
3306: PetscStrcat(convname,prefix[i]);
3307: PetscStrcat(convname,newtype);
3308: PetscStrcat(convname,"_C");
3309: PetscObjectQueryFunction((PetscObject)B,convname,(void (**)(void))&conv);
3310: if (conv) {
3311: MatDestroy(B);
3312: goto foundconv;
3313: }
3314: }
3316: /* 3) See if a good general converter is registered for the desired class */
3317: conv = B->ops->convertfrom;
3318: MatDestroy(B);
3319: if (conv) goto foundconv;
3321: /* 4) See if a good general converter is known for the current matrix */
3322: if (mat->ops->convert) {
3323: conv = mat->ops->convert;
3324: }
3325: if (conv) goto foundconv;
3327: /* 5) Use a really basic converter. */
3328: conv = MatConvert_Basic;
3330: foundconv:
3331: PetscLogEventBegin(MAT_Convert,mat,0,0,0);
3332: (*conv)(mat,newtype,reuse,M);
3333: PetscLogEventEnd(MAT_Convert,mat,0,0,0);
3334: }
3335: PetscObjectStateIncrease((PetscObject)*M);
3336: return(0);
3337: }
3341: /*@C
3342: MatFactorGetSolverPackage - Returns name of the package providing the factorization routines
3344: Not Collective
3346: Input Parameter:
3347: . mat - the matrix, must be a factored matrix
3349: Output Parameter:
3350: . type - the string name of the package (do not free this string)
3352: Notes:
3353: In Fortran you pass in a empty string and the package name will be copied into it.
3354: (Make sure the string is long enough)
3356: Level: intermediate
3358: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
3359: @*/
3360: PetscErrorCode MatFactorGetSolverPackage(Mat mat, const MatSolverPackage *type)
3361: {
3362: PetscErrorCode ierr;
3363: PetscErrorCode (*conv)(Mat,const MatSolverPackage*);
3368: if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
3369: PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverPackage_C",(void (**)(void))&conv);
3370: if (!conv) {
3371: *type = MAT_SOLVER_PETSC;
3372: } else {
3373: (*conv)(mat,type);
3374: }
3375: return(0);
3376: }
3380: /*@C
3381: MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic()
3383: Collective on Mat
3385: Input Parameters:
3386: + mat - the matrix
3387: . type - name of solver type, for example, spooles, superlu, plapack, petsc (to use PETSc's default)
3388: - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
3390: Output Parameters:
3391: . f - the factor matrix used with MatXXFactorSymbolic() calls
3393: Notes:
3394: Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
3395: such as pastix, superlu, mumps, spooles etc.
3397: PETSc must have been config/configure.py to use the external solver, using the option --download-package
3399: Level: intermediate
3401: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
3402: @*/
3403: PetscErrorCode MatGetFactor(Mat mat, const MatSolverPackage type,MatFactorType ftype,Mat *f)
3404: {
3405: PetscErrorCode ierr;
3406: char convname[256];
3407: PetscErrorCode (*conv)(Mat,MatFactorType,Mat*);
3413: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3414: MatPreallocated(mat);
3416: PetscStrcpy(convname,"MatGetFactor_");
3417: PetscStrcat(convname,((PetscObject)mat)->type_name);
3418: PetscStrcat(convname,"_");
3419: PetscStrcat(convname,type);
3420: PetscStrcat(convname,"_C");
3421: PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);
3422: if (!conv) {
3423: PetscTruth flag;
3424: PetscStrcasecmp(MAT_SOLVER_PETSC,type,&flag);
3425: if (flag) {
3426: SETERRQ1(PETSC_ERR_SUP,"Matrix format %s does not have a built-in PETSc direct solver",((PetscObject)mat)->type_name);
3427: } else {
3428: SETERRQ3(PETSC_ERR_SUP,"Matrix format %s does not have a solver %s. Perhaps you must config/configure.py with --download-%s",((PetscObject)mat)->type_name,type,type);
3429: }
3430: }
3431: (*conv)(mat,ftype,f);
3432: return(0);
3433: }
3437: /*@C
3438: MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type
3440: Collective on Mat
3442: Input Parameters:
3443: + mat - the matrix
3444: . type - name of solver type, for example, spooles, superlu, plapack, petsc (to use PETSc's default)
3445: - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
3447: Output Parameter:
3448: . flg - PETSC_TRUE if the factorization is available
3450: Notes:
3451: Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
3452: such as pastix, superlu, mumps, spooles etc.
3454: PETSc must have been config/configure.py to use the external solver, using the option --download-package
3456: Level: intermediate
3458: .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
3459: @*/
3460: PetscErrorCode MatGetFactorAvailable(Mat mat, const MatSolverPackage type,MatFactorType ftype,PetscTruth *flg)
3461: {
3462: PetscErrorCode ierr;
3463: char convname[256];
3464: PetscErrorCode (*conv)(Mat,MatFactorType,PetscTruth*);
3470: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3471: MatPreallocated(mat);
3473: PetscStrcpy(convname,"MatGetFactorAvailable_");
3474: PetscStrcat(convname,((PetscObject)mat)->type_name);
3475: PetscStrcat(convname,"_");
3476: PetscStrcat(convname,type);
3477: PetscStrcat(convname,"_C");
3478: PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);
3479: if (!conv) {
3480: *flg = PETSC_FALSE;
3481: } else {
3482: (*conv)(mat,ftype,flg);
3483: }
3484: return(0);
3485: }
3490: /*@
3491: MatDuplicate - Duplicates a matrix including the non-zero structure.
3493: Collective on Mat
3495: Input Parameters:
3496: + mat - the matrix
3497: - op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy nonzero
3498: values as well or not
3500: Output Parameter:
3501: . M - pointer to place new matrix
3503: Level: intermediate
3505: Concepts: matrices^duplicating
3507: .seealso: MatCopy(), MatConvert()
3508: @*/
3509: PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
3510: {
3512: Mat B;
3518: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3519: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3520: MatPreallocated(mat);
3522: *M = 0;
3523: if (!mat->ops->duplicate) {
3524: SETERRQ(PETSC_ERR_SUP,"Not written for this matrix type");
3525: }
3526: PetscLogEventBegin(MAT_Convert,mat,0,0,0);
3527: (*mat->ops->duplicate)(mat,op,M);
3528: B = *M;
3529: if (mat->mapping) {
3530: MatSetLocalToGlobalMapping(B,mat->mapping);
3531: }
3532: if (mat->bmapping) {
3533: MatSetLocalToGlobalMappingBlock(B,mat->bmapping);
3534: }
3535: PetscMapCopy(((PetscObject)mat)->comm,mat->rmap,B->rmap);
3536: PetscMapCopy(((PetscObject)mat)->comm,mat->cmap,B->cmap);
3537:
3538: PetscLogEventEnd(MAT_Convert,mat,0,0,0);
3539: PetscObjectStateIncrease((PetscObject)B);
3540: return(0);
3541: }
3545: /*@
3546: MatGetDiagonal - Gets the diagonal of a matrix.
3548: Collective on Mat and Vec
3550: Input Parameters:
3551: + mat - the matrix
3552: - v - the vector for storing the diagonal
3554: Output Parameter:
3555: . v - the diagonal of the matrix
3557: Level: intermediate
3559: Concepts: matrices^accessing diagonals
3561: .seealso: MatGetRow(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs()
3562: @*/
3563: PetscErrorCode MatGetDiagonal(Mat mat,Vec v)
3564: {
3571: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3572: if (!mat->ops->getdiagonal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3573: MatPreallocated(mat);
3575: (*mat->ops->getdiagonal)(mat,v);
3576: PetscObjectStateIncrease((PetscObject)v);
3577: return(0);
3578: }
3582: /*@
3583: MatGetRowMin - Gets the minimum value (of the real part) of each
3584: row of the matrix
3586: Collective on Mat and Vec
3588: Input Parameters:
3589: . mat - the matrix
3591: Output Parameter:
3592: + v - the vector for storing the maximums
3593: - idx - the indices of the column found for each row (optional)
3595: Level: intermediate
3597: Notes: The result of this call are the same as if one converted the matrix to dense format
3598: and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
3600: This code is only implemented for a couple of matrix formats.
3602: Concepts: matrices^getting row maximums
3604: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(),
3605: MatGetRowMax()
3606: @*/
3607: PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
3608: {
3615: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3616: if (!mat->ops->getrowmax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3617: MatPreallocated(mat);
3619: (*mat->ops->getrowmin)(mat,v,idx);
3620: PetscObjectStateIncrease((PetscObject)v);
3621: return(0);
3622: }
3626: /*@
3627: MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
3628: row of the matrix
3630: Collective on Mat and Vec
3632: Input Parameters:
3633: . mat - the matrix
3635: Output Parameter:
3636: + v - the vector for storing the minimums
3637: - idx - the indices of the column found for each row (optional)
3639: Level: intermediate
3641: Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
3642: row is 0 (the first column).
3644: This code is only implemented for a couple of matrix formats.
3646: Concepts: matrices^getting row maximums
3648: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
3649: @*/
3650: PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
3651: {
3658: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3659: if (!mat->ops->getrowminabs) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3660: MatPreallocated(mat);
3661: if (idx) {PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));}
3663: (*mat->ops->getrowminabs)(mat,v,idx);
3664: PetscObjectStateIncrease((PetscObject)v);
3665: return(0);
3666: }
3670: /*@
3671: MatGetRowMax - Gets the maximum value (of the real part) of each
3672: row of the matrix
3674: Collective on Mat and Vec
3676: Input Parameters:
3677: . mat - the matrix
3679: Output Parameter:
3680: + v - the vector for storing the maximums
3681: - idx - the indices of the column found for each row (optional)
3683: Level: intermediate
3685: Notes: The result of this call are the same as if one converted the matrix to dense format
3686: and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
3688: This code is only implemented for a couple of matrix formats.
3690: Concepts: matrices^getting row maximums
3692: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(), MatGetRowMin()
3693: @*/
3694: PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
3695: {
3702: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3703: if (!mat->ops->getrowmax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3704: MatPreallocated(mat);
3706: (*mat->ops->getrowmax)(mat,v,idx);
3707: PetscObjectStateIncrease((PetscObject)v);
3708: return(0);
3709: }
3713: /*@
3714: MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
3715: row of the matrix
3717: Collective on Mat and Vec
3719: Input Parameters:
3720: . mat - the matrix
3722: Output Parameter:
3723: + v - the vector for storing the maximums
3724: - idx - the indices of the column found for each row (optional)
3726: Level: intermediate
3728: Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
3729: row is 0 (the first column).
3731: This code is only implemented for a couple of matrix formats.
3733: Concepts: matrices^getting row maximums
3735: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
3736: @*/
3737: PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
3738: {
3745: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3746: if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3747: MatPreallocated(mat);
3748: if (idx) {PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));}
3750: (*mat->ops->getrowmaxabs)(mat,v,idx);
3751: PetscObjectStateIncrease((PetscObject)v);
3752: return(0);
3753: }
3757: /*@
3758: MatGetRowSum - Gets the sum of each row of the matrix
3760: Collective on Mat and Vec
3762: Input Parameters:
3763: . mat - the matrix
3765: Output Parameter:
3766: . v - the vector for storing the maximums
3768: Level: intermediate
3770: Notes: This code is slow since it is not currently specialized for different formats
3772: Concepts: matrices^getting row sums
3774: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
3775: @*/
3776: PetscErrorCode MatGetRowSum(Mat mat, Vec v)
3777: {
3778: PetscInt start, end, row;
3779: PetscScalar *array;
3786: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3787: MatPreallocated(mat);
3788: MatGetOwnershipRange(mat, &start, &end);
3789: VecGetArray(v, &array);
3790: for(row = start; row < end; ++row) {
3791: PetscInt ncols, col;
3792: const PetscInt *cols;
3793: const PetscScalar *vals;
3795: array[row - start] = 0.0;
3796: MatGetRow(mat, row, &ncols, &cols, &vals);
3797: for(col = 0; col < ncols; col++) {
3798: array[row - start] += vals[col];
3799: }
3800: MatRestoreRow(mat, row, &ncols, &cols, &vals);
3801: }
3802: VecRestoreArray(v, &array);
3803: PetscObjectStateIncrease((PetscObject) v);
3804: return(0);
3805: }
3809: /*@
3810: MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
3812: Collective on Mat
3814: Input Parameter:
3815: + mat - the matrix to transpose
3816: - reuse - store the transpose matrix in the provided B
3818: Output Parameters:
3819: . B - the transpose
3821: Notes:
3822: If you pass in &mat for B the transpose will be done in place
3824: Level: intermediate
3826: Concepts: matrices^transposing
3828: .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose()
3829: @*/
3830: PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B)
3831: {
3837: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3838: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3839: if (!mat->ops->transpose) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3840: MatPreallocated(mat);
3842: PetscLogEventBegin(MAT_Transpose,mat,0,0,0);
3843: (*mat->ops->transpose)(mat,reuse,B);
3844: PetscLogEventEnd(MAT_Transpose,mat,0,0,0);
3845: if (B) {PetscObjectStateIncrease((PetscObject)*B);}
3846: return(0);
3847: }
3851: /*@
3852: MatIsTranspose - Test whether a matrix is another one's transpose,
3853: or its own, in which case it tests symmetry.
3855: Collective on Mat
3857: Input Parameter:
3858: + A - the matrix to test
3859: - B - the matrix to test against, this can equal the first parameter
3861: Output Parameters:
3862: . flg - the result
3864: Notes:
3865: Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
3866: has a running time of the order of the number of nonzeros; the parallel
3867: test involves parallel copies of the block-offdiagonal parts of the matrix.
3869: Level: intermediate
3871: Concepts: matrices^transposing, matrix^symmetry
3873: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
3874: @*/
3875: PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscTruth *flg)
3876: {
3877: PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscTruth*),(*g)(Mat,Mat,PetscReal,PetscTruth*);
3883: PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",(void (**)(void))&f);
3884: PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",(void (**)(void))&g);
3885: if (f && g) {
3886: if (f==g) {
3887: (*f)(A,B,tol,flg);
3888: } else {
3889: SETERRQ(PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
3890: }
3891: }
3892: return(0);
3893: }
3897: /*@
3898: MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,
3900: Collective on Mat
3902: Input Parameter:
3903: + A - the matrix to test
3904: - B - the matrix to test against, this can equal the first parameter
3906: Output Parameters:
3907: . flg - the result
3909: Notes:
3910: Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
3911: has a running time of the order of the number of nonzeros; the parallel
3912: test involves parallel copies of the block-offdiagonal parts of the matrix.
3914: Level: intermediate
3916: Concepts: matrices^transposing, matrix^symmetry
3918: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
3919: @*/
3920: PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscTruth *flg)
3921: {
3922: PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscTruth*),(*g)(Mat,Mat,PetscReal,PetscTruth*);
3928: PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",(void (**)(void))&f);
3929: PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",(void (**)(void))&g);
3930: if (f && g) {
3931: if (f==g) {
3932: (*f)(A,B,tol,flg);
3933: } else {
3934: SETERRQ(PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
3935: }
3936: }
3937: return(0);
3938: }
3942: /*@
3943: MatPermute - Creates a new matrix with rows and columns permuted from the
3944: original.
3946: Collective on Mat
3948: Input Parameters:
3949: + mat - the matrix to permute
3950: . row - row permutation, each processor supplies only the permutation for its rows
3951: - col - column permutation, each processor needs the entire column permutation, that is
3952: this is the same size as the total number of columns in the matrix
3954: Output Parameters:
3955: . B - the permuted matrix
3957: Level: advanced
3959: Concepts: matrices^permuting
3961: .seealso: MatGetOrdering()
3962: @*/
3963: PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
3964: {
3973: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3974: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3975: if (!mat->ops->permute) SETERRQ1(PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
3976: MatPreallocated(mat);
3978: (*mat->ops->permute)(mat,row,col,B);
3979: PetscObjectStateIncrease((PetscObject)*B);
3980: return(0);
3981: }
3985: /*@
3986: MatPermuteSparsify - Creates a new matrix with rows and columns permuted from the
3987: original and sparsified to the prescribed tolerance.
3989: Collective on Mat
3991: Input Parameters:
3992: + A - The matrix to permute
3993: . band - The half-bandwidth of the sparsified matrix, or PETSC_DECIDE
3994: . frac - The half-bandwidth as a fraction of the total size, or 0.0
3995: . tol - The drop tolerance
3996: . rowp - The row permutation
3997: - colp - The column permutation
3999: Output Parameter:
4000: . B - The permuted, sparsified matrix
4002: Level: advanced
4004: Note:
4005: The default behavior (band = PETSC_DECIDE and frac = 0.0) is to
4006: restrict the half-bandwidth of the resulting matrix to 5% of the
4007: total matrix size.
4009: .keywords: matrix, permute, sparsify
4011: .seealso: MatGetOrdering(), MatPermute()
4012: @*/
4013: PetscErrorCode MatPermuteSparsify(Mat A, PetscInt band, PetscReal frac, PetscReal tol, IS rowp, IS colp, Mat *B)
4014: {
4015: IS irowp, icolp;
4016: const PetscInt *rows, *cols;
4017: PetscInt M, N, locRowStart, locRowEnd;
4018: PetscInt nz, newNz;
4019: const PetscInt *cwork;
4020: PetscInt *cnew;
4021: const PetscScalar *vwork;
4022: PetscScalar *vnew;
4023: PetscInt bw, issize;
4024: PetscInt row, locRow, newRow, col, newCol;
4025: PetscErrorCode ierr;
4032: if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix");
4033: if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
4034: if (!A->ops->permutesparsify) {
4035: MatGetSize(A, &M, &N);
4036: MatGetOwnershipRange(A, &locRowStart, &locRowEnd);
4037: ISGetSize(rowp, &issize);
4038: if (issize != M) SETERRQ2(PETSC_ERR_ARG_WRONG, "Wrong size %D for row permutation, should be %D", issize, M);
4039: ISGetSize(colp, &issize);
4040: if (issize != N) SETERRQ2(PETSC_ERR_ARG_WRONG, "Wrong size %D for column permutation, should be %D", issize, N);
4041: ISInvertPermutation(rowp, 0, &irowp);
4042: ISGetIndices(irowp, &rows);
4043: ISInvertPermutation(colp, 0, &icolp);
4044: ISGetIndices(icolp, &cols);
4045: PetscMalloc(N * sizeof(PetscInt), &cnew);
4046: PetscMalloc(N * sizeof(PetscScalar), &vnew);
4048: /* Setup bandwidth to include */
4049: if (band == PETSC_DECIDE) {
4050: if (frac <= 0.0)
4051: bw = (PetscInt) (M * 0.05);
4052: else
4053: bw = (PetscInt) (M * frac);
4054: } else {
4055: if (band <= 0) SETERRQ(PETSC_ERR_ARG_WRONG, "Bandwidth must be a positive integer");
4056: bw = band;
4057: }
4059: /* Put values into new matrix */
4060: MatDuplicate(A, MAT_DO_NOT_COPY_VALUES, B);
4061: for(row = locRowStart, locRow = 0; row < locRowEnd; row++, locRow++) {
4062: MatGetRow(A, row, &nz, &cwork, &vwork);
4063: newRow = rows[locRow]+locRowStart;
4064: for(col = 0, newNz = 0; col < nz; col++) {
4065: newCol = cols[cwork[col]];
4066: if ((newCol >= newRow - bw) && (newCol < newRow + bw) && (PetscAbsScalar(vwork[col]) >= tol)) {
4067: cnew[newNz] = newCol;
4068: vnew[newNz] = vwork[col];
4069: newNz++;
4070: }
4071: }
4072: MatSetValues(*B, 1, &newRow, newNz, cnew, vnew, INSERT_VALUES);
4073: MatRestoreRow(A, row, &nz, &cwork, &vwork);
4074: }
4075: PetscFree(cnew);
4076: PetscFree(vnew);
4077: MatAssemblyBegin(*B, MAT_FINAL_ASSEMBLY);
4078: MatAssemblyEnd(*B, MAT_FINAL_ASSEMBLY);
4079: ISRestoreIndices(irowp, &rows);
4080: ISRestoreIndices(icolp, &cols);
4081: ISDestroy(irowp);
4082: ISDestroy(icolp);
4083: } else {
4084: (*A->ops->permutesparsify)(A, band, frac, tol, rowp, colp, B);
4085: }
4086: PetscObjectStateIncrease((PetscObject)*B);
4087: return(0);
4088: }
4092: /*@
4093: MatEqual - Compares two matrices.
4095: Collective on Mat
4097: Input Parameters:
4098: + A - the first matrix
4099: - B - the second matrix
4101: Output Parameter:
4102: . flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
4104: Level: intermediate
4106: Concepts: matrices^equality between
4107: @*/
4108: PetscErrorCode MatEqual(Mat A,Mat B,PetscTruth *flg)
4109: {
4119: MatPreallocated(B);
4120: if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4121: if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4122: if (A->rmap->N != B->rmap->N || A->cmap->N != B->cmap->N) SETERRQ4(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);
4123: if (!A->ops->equal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4124: if (!B->ops->equal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4125: if (A->ops->equal != B->ops->equal) SETERRQ2(PETSC_ERR_ARG_INCOMP,"A is type: %s\nB is type: %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
4126: MatPreallocated(A);
4128: (*A->ops->equal)(A,B,flg);
4129: return(0);
4130: }
4134: /*@
4135: MatDiagonalScale - Scales a matrix on the left and right by diagonal
4136: matrices that are stored as vectors. Either of the two scaling
4137: matrices can be PETSC_NULL.
4139: Collective on Mat
4141: Input Parameters:
4142: + mat - the matrix to be scaled
4143: . l - the left scaling vector (or PETSC_NULL)
4144: - r - the right scaling vector (or PETSC_NULL)
4146: Notes:
4147: MatDiagonalScale() computes A = LAR, where
4148: L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
4150: Level: intermediate
4152: Concepts: matrices^diagonal scaling
4153: Concepts: diagonal scaling of matrices
4155: .seealso: MatScale()
4156: @*/
4157: PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
4158: {
4164: if (!mat->ops->diagonalscale) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4167: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4168: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4169: MatPreallocated(mat);
4171: PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4172: (*mat->ops->diagonalscale)(mat,l,r);
4173: PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4174: PetscObjectStateIncrease((PetscObject)mat);
4175: return(0);
4176: }
4180: /*@
4181: MatScale - Scales all elements of a matrix by a given number.
4183: Collective on Mat
4185: Input Parameters:
4186: + mat - the matrix to be scaled
4187: - a - the scaling value
4189: Output Parameter:
4190: . mat - the scaled matrix
4192: Level: intermediate
4194: Concepts: matrices^scaling all entries
4196: .seealso: MatDiagonalScale()
4197: @*/
4198: PetscErrorCode MatScale(Mat mat,PetscScalar a)
4199: {
4205: if (a != 1.0 && !mat->ops->scale) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4206: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4207: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4208: MatPreallocated(mat);
4210: PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4211: if (a != 1.0) {
4212: (*mat->ops->scale)(mat,a);
4213: PetscObjectStateIncrease((PetscObject)mat);
4214: }
4215: PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4216: return(0);
4217: }
4221: /*@
4222: MatNorm - Calculates various norms of a matrix.
4224: Collective on Mat
4226: Input Parameters:
4227: + mat - the matrix
4228: - type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
4230: Output Parameters:
4231: . nrm - the resulting norm
4233: Level: intermediate
4235: Concepts: matrices^norm
4236: Concepts: norm^of matrix
4237: @*/
4238: PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
4239: {
4247: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4248: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4249: if (!mat->ops->norm) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4250: MatPreallocated(mat);
4252: (*mat->ops->norm)(mat,type,nrm);
4253: return(0);
4254: }
4256: /*
4257: This variable is used to prevent counting of MatAssemblyBegin() that
4258: are called from within a MatAssemblyEnd().
4259: */
4260: static PetscInt MatAssemblyEnd_InUse = 0;
4263: /*@
4264: MatAssemblyBegin - Begins assembling the matrix. This routine should
4265: be called after completing all calls to MatSetValues().
4267: Collective on Mat
4269: Input Parameters:
4270: + mat - the matrix
4271: - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
4272:
4273: Notes:
4274: MatSetValues() generally caches the values. The matrix is ready to
4275: use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4276: Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4277: in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4278: using the matrix.
4280: Level: beginner
4282: Concepts: matrices^assembling
4284: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
4285: @*/
4286: PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
4287: {
4293: MatPreallocated(mat);
4294: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
4295: if (mat->assembled) {
4296: mat->was_assembled = PETSC_TRUE;
4297: mat->assembled = PETSC_FALSE;
4298: }
4299: if (!MatAssemblyEnd_InUse) {
4300: PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);
4301: if (mat->ops->assemblybegin){(*mat->ops->assemblybegin)(mat,type);}
4302: PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);
4303: } else {
4304: if (mat->ops->assemblybegin){(*mat->ops->assemblybegin)(mat,type);}
4305: }
4306: return(0);
4307: }
4311: /*@
4312: MatAssembled - Indicates if a matrix has been assembled and is ready for
4313: use; for example, in matrix-vector product.
4315: Collective on Mat
4317: Input Parameter:
4318: . mat - the matrix
4320: Output Parameter:
4321: . assembled - PETSC_TRUE or PETSC_FALSE
4323: Level: advanced
4325: Concepts: matrices^assembled?
4327: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
4328: @*/
4329: PetscErrorCode MatAssembled(Mat mat,PetscTruth *assembled)
4330: {
4335: *assembled = mat->assembled;
4336: return(0);
4337: }
4341: /*
4342: Processes command line options to determine if/how a matrix
4343: is to be viewed. Called by MatAssemblyEnd() and MatLoad().
4344: */
4345: PetscErrorCode MatView_Private(Mat mat)
4346: {
4347: PetscErrorCode ierr;
4348: PetscTruth flg1,flg2,flg3,flg4,flg6,flg7,flg8;
4349: static PetscTruth incall = PETSC_FALSE;
4350: #if defined(PETSC_USE_SOCKET_VIEWER)
4351: PetscTruth flg5;
4352: #endif
4355: if (incall) return(0);
4356: incall = PETSC_TRUE;
4357: PetscOptionsBegin(((PetscObject)mat)->comm,((PetscObject)mat)->prefix,"Matrix Options","Mat");
4358: PetscOptionsName("-mat_view_info","Information on matrix size","MatView",&flg1);
4359: PetscOptionsName("-mat_view_info_detailed","Nonzeros in the matrix","MatView",&flg2);
4360: PetscOptionsName("-mat_view","Print matrix to stdout","MatView",&flg3);
4361: PetscOptionsName("-mat_view_matlab","Print matrix to stdout in a format Matlab can read","MatView",&flg4);
4362: #if defined(PETSC_USE_SOCKET_VIEWER)
4363: PetscOptionsName("-mat_view_socket","Send matrix to socket (can be read from matlab)","MatView",&flg5);
4364: #endif
4365: PetscOptionsName("-mat_view_binary","Save matrix to file in binary format","MatView",&flg6);
4366: PetscOptionsName("-mat_view_draw","Draw the matrix nonzero structure","MatView",&flg7);
4367: PetscOptionsEnd();
4369: if (flg1) {
4370: PetscViewer viewer;
4372: PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4373: PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO);
4374: MatView(mat,viewer);
4375: PetscViewerPopFormat(viewer);
4376: }
4377: if (flg2) {
4378: PetscViewer viewer;
4380: PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4381: PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO_DETAIL);
4382: MatView(mat,viewer);
4383: PetscViewerPopFormat(viewer);
4384: }
4385: if (flg3) {
4386: PetscViewer viewer;
4388: PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4389: MatView(mat,viewer);
4390: }
4391: if (flg4) {
4392: PetscViewer viewer;
4394: PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4395: PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);
4396: MatView(mat,viewer);
4397: PetscViewerPopFormat(viewer);
4398: }
4399: #if defined(PETSC_USE_SOCKET_VIEWER)
4400: if (flg5) {
4401: MatView(mat,PETSC_VIEWER_SOCKET_(((PetscObject)mat)->comm));
4402: PetscViewerFlush(PETSC_VIEWER_SOCKET_(((PetscObject)mat)->comm));
4403: }
4404: #endif
4405: if (flg6) {
4406: MatView(mat,PETSC_VIEWER_BINARY_(((PetscObject)mat)->comm));
4407: PetscViewerFlush(PETSC_VIEWER_BINARY_(((PetscObject)mat)->comm));
4408: }
4409: if (flg7) {
4410: PetscOptionsHasName(((PetscObject)mat)->prefix,"-mat_view_contour",&flg8);
4411: if (flg8) {
4412: PetscViewerPushFormat(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm),PETSC_VIEWER_DRAW_CONTOUR);
4413: }
4414: MatView(mat,PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));
4415: PetscViewerFlush(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));
4416: if (flg8) {
4417: PetscViewerPopFormat(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));
4418: }
4419: }
4420: incall = PETSC_FALSE;
4421: return(0);
4422: }
4426: /*@
4427: MatAssemblyEnd - Completes assembling the matrix. This routine should
4428: be called after MatAssemblyBegin().
4430: Collective on Mat
4432: Input Parameters:
4433: + mat - the matrix
4434: - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
4436: Options Database Keys:
4437: + -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly()
4438: . -mat_view_info_detailed - Prints more detailed info
4439: . -mat_view - Prints matrix in ASCII format
4440: . -mat_view_matlab - Prints matrix in Matlab format
4441: . -mat_view_draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
4442: . -display <name> - Sets display name (default is host)
4443: . -draw_pause <sec> - Sets number of seconds to pause after display
4444: . -mat_view_socket - Sends matrix to socket, can be accessed from Matlab (see users manual)
4445: . -viewer_socket_machine <machine>
4446: . -viewer_socket_port <port>
4447: . -mat_view_binary - save matrix to file in binary format
4448: - -viewer_binary_filename <name>
4450: Notes:
4451: MatSetValues() generally caches the values. The matrix is ready to
4452: use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4453: Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4454: in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4455: using the matrix.
4457: Level: beginner
4459: .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), MatView(), MatAssembled(), PetscViewerSocketOpen()
4460: @*/
4461: PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
4462: {
4463: PetscErrorCode ierr;
4464: static PetscInt inassm = 0;
4465: PetscTruth flg;
4471: inassm++;
4472: MatAssemblyEnd_InUse++;
4473: if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
4474: PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);
4475: if (mat->ops->assemblyend) {
4476: (*mat->ops->assemblyend)(mat,type);
4477: }
4478: PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);
4479: } else {
4480: if (mat->ops->assemblyend) {
4481: (*mat->ops->assemblyend)(mat,type);
4482: }
4483: }
4485: /* Flush assembly is not a true assembly */
4486: if (type != MAT_FLUSH_ASSEMBLY) {
4487: mat->assembled = PETSC_TRUE; mat->num_ass++;
4488: }
4489: mat->insertmode = NOT_SET_VALUES;
4490: MatAssemblyEnd_InUse--;
4491: PetscObjectStateIncrease((PetscObject)mat);
4492: if (!mat->symmetric_eternal) {
4493: mat->symmetric_set = PETSC_FALSE;
4494: mat->hermitian_set = PETSC_FALSE;
4495: mat->structurally_symmetric_set = PETSC_FALSE;
4496: }
4497: if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
4498: MatView_Private(mat);
4499: PetscOptionsHasName(((PetscObject)mat)->prefix,"-mat_is_symmetric",&flg);
4500: if (flg) {
4501: PetscReal tol = 0.0;
4502: PetscOptionsGetReal(((PetscObject)mat)->prefix,"-mat_is_symmetric",&tol,PETSC_NULL);
4503: MatIsSymmetric(mat,tol,&flg);
4504: if (flg) {
4505: PetscPrintf(((PetscObject)mat)->comm,"Matrix is symmetric (tolerance %G)\n",tol);
4506: } else {
4507: PetscPrintf(((PetscObject)mat)->comm,"Matrix is not symmetric (tolerance %G)\n",tol);
4508: }
4509: }
4510: }
4511: inassm--;
4512: return(0);
4513: }
4518: /*@
4519: MatCompress - Tries to store the matrix in as little space as
4520: possible. May fail if memory is already fully used, since it
4521: tries to allocate new space.
4523: Collective on Mat
4525: Input Parameters:
4526: . mat - the matrix
4528: Level: advanced
4530: @*/
4531: PetscErrorCode MatCompress(Mat mat)
4532: {
4538: MatPreallocated(mat);
4539: if (mat->ops->compress) {(*mat->ops->compress)(mat);}
4540: return(0);
4541: }
4545: /*@
4546: MatSetOption - Sets a parameter option for a matrix. Some options
4547: may be specific to certain storage formats. Some options
4548: determine how values will be inserted (or added). Sorted,
4549: row-oriented input will generally assemble the fastest. The default
4550: is row-oriented, nonsorted input.
4552: Collective on Mat
4554: Input Parameters:
4555: + mat - the matrix
4556: . option - the option, one of those listed below (and possibly others),
4557: - flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
4559: Options Describing Matrix Structure:
4560: + MAT_SYMMETRIC - symmetric in terms of both structure and value
4561: . MAT_HERMITIAN - transpose is the complex conjugation
4562: . MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
4563: - MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
4564: you set to be kept with all future use of the matrix
4565: including after MatAssemblyBegin/End() which could
4566: potentially change the symmetry structure, i.e. you
4567: KNOW the matrix will ALWAYS have the property you set.
4570: Options For Use with MatSetValues():
4571: Insert a logically dense subblock, which can be
4572: . MAT_ROW_ORIENTED - row-oriented (default)
4574: Note these options reflect the data you pass in with MatSetValues(); it has
4575: nothing to do with how the data is stored internally in the matrix
4576: data structure.
4578: When (re)assembling a matrix, we can restrict the input for
4579: efficiency/debugging purposes. These options include
4580: + MAT_NEW_NONZERO_LOCATIONS - additional insertions will be
4581: allowed if they generate a new nonzero
4582: . MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
4583: . MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
4584: . MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
4585: - MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
4587: Notes:
4588: Some options are relevant only for particular matrix types and
4589: are thus ignored by others. Other options are not supported by
4590: certain matrix types and will generate an error message if set.
4592: If using a Fortran 77 module to compute a matrix, one may need to
4593: use the column-oriented option (or convert to the row-oriented
4594: format).
4596: MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
4597: that would generate a new entry in the nonzero structure is instead
4598: ignored. Thus, if memory has not alredy been allocated for this particular
4599: data, then the insertion is ignored. For dense matrices, in which
4600: the entire array is allocated, no entries are ever ignored.
4601: Set after the first MatAssemblyEnd()
4603: MAT_NEW_NONZERO_LOCATION_ERR indicates that any add or insertion
4604: that would generate a new entry in the nonzero structure instead produces
4605: an error. (Currently supported for AIJ and BAIJ formats only.)
4606: This is a useful flag when using SAME_NONZERO_PATTERN in calling
4607: KSPSetOperators() to ensure that the nonzero pattern truely does
4608: remain unchanged. Set after the first MatAssemblyEnd()
4610: MAT_NEW_NONZERO_ALLOCATION_ERR indicates that any add or insertion
4611: that would generate a new entry that has not been preallocated will
4612: instead produce an error. (Currently supported for AIJ and BAIJ formats
4613: only.) This is a useful flag when debugging matrix memory preallocation.
4615: MAT_IGNORE_OFF_PROC_ENTRIES indicates entries destined for
4616: other processors should be dropped, rather than stashed.
4617: This is useful if you know that the "owning" processor is also
4618: always generating the correct matrix entries, so that PETSc need
4619: not transfer duplicate entries generated on another processor.
4620:
4621: MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
4622: searches during matrix assembly. When this flag is set, the hash table
4623: is created during the first Matrix Assembly. This hash table is
4624: used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
4625: to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
4626: should be used with MAT_USE_HASH_TABLE flag. This option is currently
4627: supported by MATMPIBAIJ format only.
4629: MAT_KEEP_ZEROED_ROWS indicates when MatZeroRows() is called the zeroed entries
4630: are kept in the nonzero structure
4632: MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
4633: a zero location in the matrix
4635: MAT_USE_INODES - indicates using inode version of the code - works with AIJ and
4636: ROWBS matrix types
4638: Level: intermediate
4640: Concepts: matrices^setting options
4642: @*/
4643: PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscTruth flg)
4644: {
4650: if (((int) op) < 0 || ((int) op) >= NUM_MAT_OPTIONS) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Options %d is out of range",(int)op);
4651: MatPreallocated(mat);
4652: switch (op) {
4653: case MAT_SYMMETRIC:
4654: mat->symmetric = flg;
4655: if (flg) mat->structurally_symmetric = PETSC_TRUE;
4656: mat->symmetric_set = PETSC_TRUE;
4657: mat->structurally_symmetric_set = flg;
4658: break;
4659: case MAT_HERMITIAN:
4660: mat->hermitian = flg;
4661: if (flg) mat->structurally_symmetric = PETSC_TRUE;
4662: mat->hermitian_set = PETSC_TRUE;
4663: mat->structurally_symmetric_set = flg;
4664: break;
4665: case MAT_STRUCTURALLY_SYMMETRIC:
4666: mat->structurally_symmetric = flg;
4667: mat->structurally_symmetric_set = PETSC_TRUE;
4668: break;
4669: case MAT_SYMMETRY_ETERNAL:
4670: mat->symmetric_eternal = flg;
4671: break;
4672: default:
4673: break;
4674: }
4675: if (mat->ops->setoption) {
4676: (*mat->ops->setoption)(mat,op,flg);
4677: }
4678: return(0);
4679: }
4683: /*@
4684: MatZeroEntries - Zeros all entries of a matrix. For sparse matrices
4685: this routine retains the old nonzero structure.
4687: Collective on Mat
4689: Input Parameters:
4690: . mat - the matrix
4692: Level: intermediate
4694: Concepts: matrices^zeroing
4696: .seealso: MatZeroRows()
4697: @*/
4698: PetscErrorCode MatZeroEntries(Mat mat)
4699: {
4705: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4706: if (mat->insertmode != NOT_SET_VALUES) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for matrices where you have set values but not yet assembled");
4707: if (!mat->ops->zeroentries) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4708: MatPreallocated(mat);
4710: PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);
4711: (*mat->ops->zeroentries)(mat);
4712: PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);
4713: PetscObjectStateIncrease((PetscObject)mat);
4714: return(0);
4715: }
4719: /*@C
4720: MatZeroRows - Zeros all entries (except possibly the main diagonal)
4721: of a set of rows of a matrix.
4723: Collective on Mat
4725: Input Parameters:
4726: + mat - the matrix
4727: . numRows - the number of rows to remove
4728: . rows - the global row indices
4729: - diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
4731: Notes:
4732: For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
4733: but does not release memory. For the dense and block diagonal
4734: formats this does not alter the nonzero structure.
4736: If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS,PETSC_TRUE) the nonzero structure
4737: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
4738: merely zeroed.
4740: The user can set a value in the diagonal entry (or for the AIJ and
4741: row formats can optionally remove the main diagonal entry from the
4742: nonzero structure as well, by passing 0.0 as the final argument).
4744: For the parallel case, all processes that share the matrix (i.e.,
4745: those in the communicator used for matrix creation) MUST call this
4746: routine, regardless of whether any rows being zeroed are owned by
4747: them.
4749: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
4750: list only rows local to itself).
4752: Level: intermediate
4754: Concepts: matrices^zeroing rows
4756: .seealso: MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
4757: @*/
4758: PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag)
4759: {
4766: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4767: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4768: if (!mat->ops->zerorows) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4769: MatPreallocated(mat);
4771: (*mat->ops->zerorows)(mat,numRows,rows,diag);
4772: MatView_Private(mat);
4773: PetscObjectStateIncrease((PetscObject)mat);
4774: return(0);
4775: }
4779: /*@C
4780: MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
4781: of a set of rows of a matrix.
4783: Collective on Mat
4785: Input Parameters:
4786: + mat - the matrix
4787: . is - index set of rows to remove
4788: - diag - value put in all diagonals of eliminated rows
4790: Notes:
4791: For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
4792: but does not release memory. For the dense and block diagonal
4793: formats this does not alter the nonzero structure.
4795: If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS,PETSC_TRUE) the nonzero structure
4796: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
4797: merely zeroed.
4799: The user can set a value in the diagonal entry (or for the AIJ and
4800: row formats can optionally remove the main diagonal entry from the
4801: nonzero structure as well, by passing 0.0 as the final argument).
4803: For the parallel case, all processes that share the matrix (i.e.,
4804: those in the communicator used for matrix creation) MUST call this
4805: routine, regardless of whether any rows being zeroed are owned by
4806: them.
4808: Each processor should list the rows that IT wants zeroed
4810: Level: intermediate
4812: Concepts: matrices^zeroing rows
4814: .seealso: MatZeroRows(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
4815: @*/
4816: PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag)
4817: {
4818: PetscInt numRows;
4819: const PetscInt *rows;
4826: ISGetLocalSize(is,&numRows);
4827: ISGetIndices(is,&rows);
4828: MatZeroRows(mat,numRows,rows,diag);
4829: ISRestoreIndices(is,&rows);
4830: return(0);
4831: }
4835: /*@C
4836: MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
4837: of a set of rows of a matrix; using local numbering of rows.
4839: Collective on Mat
4841: Input Parameters:
4842: + mat - the matrix
4843: . numRows - the number of rows to remove
4844: . rows - the global row indices
4845: - diag - value put in all diagonals of eliminated rows
4847: Notes:
4848: Before calling MatZeroRowsLocal(), the user must first set the
4849: local-to-global mapping by calling MatSetLocalToGlobalMapping().
4851: For the AIJ matrix formats this removes the old nonzero structure,
4852: but does not release memory. For the dense and block diagonal
4853: formats this does not alter the nonzero structure.
4855: If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS,PETSC_TRUE) the nonzero structure
4856: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
4857: merely zeroed.
4859: The user can set a value in the diagonal entry (or for the AIJ and
4860: row formats can optionally remove the main diagonal entry from the
4861: nonzero structure as well, by passing 0.0 as the final argument).
4863: Level: intermediate
4865: Concepts: matrices^zeroing
4867: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
4868: @*/
4869: PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag)
4870: {
4877: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4878: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4879: MatPreallocated(mat);
4881: if (mat->ops->zerorowslocal) {
4882: (*mat->ops->zerorowslocal)(mat,numRows,rows,diag);
4883: } else {
4884: IS is, newis;
4885: const PetscInt *newRows;
4887: if (!mat->mapping) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
4888: ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,&is);
4889: ISLocalToGlobalMappingApplyIS(mat->mapping,is,&newis);
4890: ISGetIndices(newis,&newRows);
4891: (*mat->ops->zerorows)(mat,numRows,newRows,diag);
4892: ISRestoreIndices(newis,&newRows);
4893: ISDestroy(newis);
4894: ISDestroy(is);
4895: }
4896: PetscObjectStateIncrease((PetscObject)mat);
4897: return(0);
4898: }
4902: /*@C
4903: MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
4904: of a set of rows of a matrix; using local numbering of rows.
4906: Collective on Mat
4908: Input Parameters:
4909: + mat - the matrix
4910: . is - index set of rows to remove
4911: - diag - value put in all diagonals of eliminated rows
4913: Notes:
4914: Before calling MatZeroRowsLocalIS(), the user must first set the
4915: local-to-global mapping by calling MatSetLocalToGlobalMapping().
4917: For the AIJ matrix formats this removes the old nonzero structure,
4918: but does not release memory. For the dense and block diagonal
4919: formats this does not alter the nonzero structure.
4921: If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS,PETSC_TRUE) the nonzero structure
4922: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
4923: merely zeroed.
4925: The user can set a value in the diagonal entry (or for the AIJ and
4926: row formats can optionally remove the main diagonal entry from the
4927: nonzero structure as well, by passing 0.0 as the final argument).
4929: Level: intermediate
4931: Concepts: matrices^zeroing
4933: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
4934: @*/
4935: PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag)
4936: {
4938: PetscInt numRows;
4939: const PetscInt *rows;
4945: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4946: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4947: MatPreallocated(mat);
4949: ISGetLocalSize(is,&numRows);
4950: ISGetIndices(is,&rows);
4951: MatZeroRowsLocal(mat,numRows,rows,diag);
4952: ISRestoreIndices(is,&rows);
4953: return(0);
4954: }
4958: /*@
4959: MatGetSize - Returns the numbers of rows and columns in a matrix.
4961: Not Collective
4963: Input Parameter:
4964: . mat - the matrix
4966: Output Parameters:
4967: + m - the number of global rows
4968: - n - the number of global columns
4970: Note: both output parameters can be PETSC_NULL on input.
4972: Level: beginner
4974: Concepts: matrices^size
4976: .seealso: MatGetLocalSize()
4977: @*/
4978: PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt* n)
4979: {
4982: if (m) *m = mat->rmap->N;
4983: if (n) *n = mat->cmap->N;
4984: return(0);
4985: }
4989: /*@
4990: MatGetLocalSize - Returns the number of rows and columns in a matrix
4991: stored locally. This information may be implementation dependent, so
4992: use with care.
4994: Not Collective
4996: Input Parameters:
4997: . mat - the matrix
4999: Output Parameters:
5000: + m - the number of local rows
5001: - n - the number of local columns
5003: Note: both output parameters can be PETSC_NULL on input.
5005: Level: beginner
5007: Concepts: matrices^local size
5009: .seealso: MatGetSize()
5010: @*/
5011: PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt* n)
5012: {
5017: if (m) *m = mat->rmap->n;
5018: if (n) *n = mat->cmap->n;
5019: return(0);
5020: }
5024: /*@
5025: MatGetOwnershipRangeColumn - Returns the range of matrix columns owned by
5026: this processor.
5028: Not Collective, unless matrix has not been allocated, then collective on Mat
5030: Input Parameters:
5031: . mat - the matrix
5033: Output Parameters:
5034: + m - the global index of the first local column
5035: - n - one more than the global index of the last local column
5037: Notes: both output parameters can be PETSC_NULL on input.
5039: Level: developer
5041: Concepts: matrices^column ownership
5043: .seealso: MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
5045: @*/
5046: PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt* n)
5047: {
5055: MatPreallocated(mat);
5056: if (m) *m = mat->cmap->rstart;
5057: if (n) *n = mat->cmap->rend;
5058: return(0);
5059: }
5063: /*@
5064: MatGetOwnershipRange - Returns the range of matrix rows owned by
5065: this processor, assuming that the matrix is laid out with the first
5066: n1 rows on the first processor, the next n2 rows on the second, etc.
5067: For certain parallel layouts this range may not be well defined.
5069: Not Collective, unless matrix has not been allocated, then collective on Mat
5071: Input Parameters:
5072: . mat - the matrix
5074: Output Parameters:
5075: + m - the global index of the first local row
5076: - n - one more than the global index of the last local row
5078: Note: both output parameters can be PETSC_NULL on input.
5080: Level: beginner
5082: Concepts: matrices^row ownership
5084: .seealso: MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
5086: @*/
5087: PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt* n)
5088: {
5096: MatPreallocated(mat);
5097: if (m) *m = mat->rmap->rstart;
5098: if (n) *n = mat->rmap->rend;
5099: return(0);
5100: }
5104: /*@C
5105: MatGetOwnershipRanges - Returns the range of matrix rows owned by
5106: each process
5108: Not Collective, unless matrix has not been allocated, then collective on Mat
5110: Input Parameters:
5111: . mat - the matrix
5113: Output Parameters:
5114: . ranges - start of each processors portion plus one more then the total length at the end
5116: Level: beginner
5118: Concepts: matrices^row ownership
5120: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
5122: @*/
5123: PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
5124: {
5130: MatPreallocated(mat);
5131: PetscMapGetRanges(mat->rmap,ranges);
5132: return(0);
5133: }
5137: /*@C
5138: MatGetOwnershipRangesColumn - Returns the range of local columns for each process
5140: Not Collective, unless matrix has not been allocated, then collective on Mat
5142: Input Parameters:
5143: . mat - the matrix
5145: Output Parameters:
5146: . ranges - start of each processors portion plus one more then the total length at the end
5148: Level: beginner
5150: Concepts: matrices^column ownership
5152: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
5154: @*/
5155: PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
5156: {
5162: MatPreallocated(mat);
5163: PetscMapGetRanges(mat->cmap,ranges);
5164: return(0);
5165: }
5169: /*@
5170: MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
5171: Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
5172: to complete the factorization.
5174: Collective on Mat
5176: Input Parameters:
5177: + mat - the matrix
5178: . row - row permutation
5179: . column - column permutation
5180: - info - structure containing
5181: $ levels - number of levels of fill.
5182: $ expected fill - as ratio of original fill.
5183: $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices
5184: missing diagonal entries)
5186: Output Parameters:
5187: . fact - new matrix that has been symbolically factored
5189: Notes:
5190: See the users manual for additional information about
5191: choosing the fill factor for better efficiency.
5193: Most users should employ the simplified KSP interface for linear solvers
5194: instead of working directly with matrix algebra routines such as this.
5195: See, e.g., KSPCreate().
5197: Level: developer
5199: Concepts: matrices^symbolic LU factorization
5200: Concepts: matrices^factorization
5201: Concepts: LU^symbolic factorization
5203: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
5204: MatGetOrdering(), MatFactorInfo
5206: @*/
5207: PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
5208: {
5218: if (info->levels < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
5219: if (info->fill < 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
5220: if (!(fact)->ops->ilufactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s symbolic ILU",((PetscObject)mat)->type_name);
5221: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5222: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5223: MatPreallocated(mat);
5225: PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);
5226: (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);
5227: PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);
5228: return(0);
5229: }
5233: /*@
5234: MatICCFactorSymbolic - Performs symbolic incomplete
5235: Cholesky factorization for a symmetric matrix. Use
5236: MatCholeskyFactorNumeric() to complete the factorization.
5238: Collective on Mat
5240: Input Parameters:
5241: + mat - the matrix
5242: . perm - row and column permutation
5243: - info - structure containing
5244: $ levels - number of levels of fill.
5245: $ expected fill - as ratio of original fill.
5247: Output Parameter:
5248: . fact - the factored matrix
5250: Notes:
5251: Most users should employ the KSP interface for linear solvers
5252: instead of working directly with matrix algebra routines such as this.
5253: See, e.g., KSPCreate().
5255: Level: developer
5257: Concepts: matrices^symbolic incomplete Cholesky factorization
5258: Concepts: matrices^factorization
5259: Concepts: Cholsky^symbolic factorization
5261: .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
5262: @*/
5263: PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
5264: {
5273: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5274: if (info->levels < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
5275: if (info->fill < 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
5276: if (!(fact)->ops->iccfactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s symbolic ICC",((PetscObject)mat)->type_name);
5277: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5278: MatPreallocated(mat);
5280: PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);
5281: (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);
5282: PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);
5283: return(0);
5284: }
5288: /*@C
5289: MatGetArray - Returns a pointer to the element values in the matrix.
5290: The result of this routine is dependent on the underlying matrix data
5291: structure, and may not even work for certain matrix types. You MUST
5292: call MatRestoreArray() when you no longer need to access the array.
5294: Not Collective
5296: Input Parameter:
5297: . mat - the matrix
5299: Output Parameter:
5300: . v - the location of the values
5303: Fortran Note:
5304: This routine is used differently from Fortran, e.g.,
5305: .vb
5306: Mat mat
5307: PetscScalar mat_array(1)
5308: PetscOffset i_mat
5309: PetscErrorCode ierr
5310: call MatGetArray(mat,mat_array,i_mat,ierr)
5312: C Access first local entry in matrix; note that array is
5313: C treated as one dimensional
5314: value = mat_array(i_mat + 1)
5316: [... other code ...]
5317: call MatRestoreArray(mat,mat_array,i_mat,ierr)
5318: .ve
5320: See the Fortran chapter of the users manual and
5321: petsc/src/mat/examples/tests for details.
5323: Level: advanced
5325: Concepts: matrices^access array
5327: .seealso: MatRestoreArray(), MatGetArrayF90(), MatGetRowIJ()
5328: @*/
5329: PetscErrorCode MatGetArray(Mat mat,PetscScalar *v[])
5330: {
5337: if (!mat->ops->getarray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5338: MatPreallocated(mat);
5339: (*mat->ops->getarray)(mat,v);
5340: CHKMEMQ;
5341: return(0);
5342: }
5346: /*@C
5347: MatRestoreArray - Restores the matrix after MatGetArray() has been called.
5349: Not Collective
5351: Input Parameter:
5352: + mat - the matrix
5353: - v - the location of the values
5355: Fortran Note:
5356: This routine is used differently from Fortran, e.g.,
5357: .vb
5358: Mat mat
5359: PetscScalar mat_array(1)
5360: PetscOffset i_mat
5361: PetscErrorCode ierr
5362: call MatGetArray(mat,mat_array,i_mat,ierr)
5364: C Access first local entry in matrix; note that array is
5365: C treated as one dimensional
5366: value = mat_array(i_mat + 1)
5368: [... other code ...]
5369: call MatRestoreArray(mat,mat_array,i_mat,ierr)
5370: .ve
5372: See the Fortran chapter of the users manual and
5373: petsc/src/mat/examples/tests for details
5375: Level: advanced
5377: .seealso: MatGetArray(), MatRestoreArrayF90()
5378: @*/
5379: PetscErrorCode MatRestoreArray(Mat mat,PetscScalar *v[])
5380: {
5387: #if defined(PETSC_USE_DEBUG)
5388: CHKMEMQ;
5389: #endif
5390: if (!mat->ops->restorearray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5391: (*mat->ops->restorearray)(mat,v);
5392: PetscObjectStateIncrease((PetscObject)mat);
5393: return(0);
5394: }
5398: /*@C
5399: MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
5400: points to an array of valid matrices, they may be reused to store the new
5401: submatrices.
5403: Collective on Mat
5405: Input Parameters:
5406: + mat - the matrix
5407: . n - the number of submatrixes to be extracted (on this processor, may be zero)
5408: . irow, icol - index sets of rows and columns to extract
5409: - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
5411: Output Parameter:
5412: . submat - the array of submatrices
5414: Notes:
5415: MatGetSubMatrices() can extract ONLY sequential submatrices
5416: (from both sequential and parallel matrices). Use MatGetSubMatrix()
5417: to extract a parallel submatrix.
5419: When extracting submatrices from a parallel matrix, each processor can
5420: form a different submatrix by setting the rows and columns of its
5421: individual index sets according to the local submatrix desired.
5423: When finished using the submatrices, the user should destroy
5424: them with MatDestroyMatrices().
5426: MAT_REUSE_MATRIX can only be used when the nonzero structure of the
5427: original matrix has not changed from that last call to MatGetSubMatrices().
5429: This routine creates the matrices in submat; you should NOT create them before
5430: calling it. It also allocates the array of matrix pointers submat.
5432: For BAIJ matrices the index sets must respect the block structure, that is if they
5433: request one row/column in a block, they must request all rows/columns that are in
5434: that block. For example, if the block size is 2 you cannot request just row 0 and
5435: column 0.
5437: Fortran Note:
5438: The Fortran interface is slightly different from that given below; it
5439: requires one to pass in as submat a Mat (integer) array of size at least m.
5441: Level: advanced
5443: Concepts: matrices^accessing submatrices
5444: Concepts: submatrices
5446: .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
5447: @*/
5448: PetscErrorCode MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
5449: {
5451: PetscInt i;
5452: PetscTruth eq;
5457: if (n) {
5462: }
5464: if (n && scall == MAT_REUSE_MATRIX) {
5467: }
5468: if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5469: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5470: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5471: MatPreallocated(mat);
5473: PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
5474: (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);
5475: PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
5476: for (i=0; i<n; i++) {
5477: if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
5478: ISEqual(irow[i],icol[i],&eq);
5479: if (eq) {
5480: if (mat->symmetric){
5481: MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
5482: } else if (mat->hermitian) {
5483: MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
5484: } else if (mat->structurally_symmetric) {
5485: MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
5486: }
5487: }
5488: }
5489: }
5490: return(0);
5491: }
5495: /*@C
5496: MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().
5498: Collective on Mat
5500: Input Parameters:
5501: + n - the number of local matrices
5502: - mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
5503: sequence of MatGetSubMatrices())
5505: Level: advanced
5507: Notes: Frees not only the matrices, but also the array that contains the matrices
5508: In Fortran will not free the array.
5510: .seealso: MatGetSubMatrices()
5511: @*/
5512: PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
5513: {
5515: PetscInt i;
5518: if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
5520: for (i=0; i<n; i++) {
5521: MatDestroy((*mat)[i]);
5522: }
5523: /* memory is allocated even if n = 0 */
5524: PetscFree(*mat);
5525: return(0);
5526: }
5530: /*@C
5531: MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
5533: Collective on Mat
5535: Input Parameters:
5536: . mat - the matrix
5538: Output Parameter:
5539: . matstruct - the sequential matrix with the nonzero structure of mat
5541: Level: intermediate
5543: .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
5544: @*/
5545: PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct[])
5546: {
5552:
5554: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5555: MatPreallocated(mat);
5557: PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);
5558: (*mat->ops->getseqnonzerostructure)(mat,matstruct);
5559: PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);
5560: return(0);
5561: }
5565: /*@C
5566: MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
5568: Collective on Mat
5570: Input Parameters:
5571: . mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
5572: sequence of MatGetSequentialNonzeroStructure())
5574: Level: advanced
5576: Notes: Frees not only the matrices, but also the array that contains the matrices
5578: .seealso: MatGetSeqNonzeroStructure()
5579: @*/
5580: PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat[])
5581: {
5586: MatDestroyMatrices(1,mat);
5587: return(0);
5588: }
5592: /*@
5593: MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
5594: replaces the index sets by larger ones that represent submatrices with
5595: additional overlap.
5597: Collective on Mat
5599: Input Parameters:
5600: + mat - the matrix
5601: . n - the number of index sets
5602: . is - the array of index sets (these index sets will changed during the call)
5603: - ov - the additional overlap requested
5605: Level: developer
5607: Concepts: overlap
5608: Concepts: ASM^computing overlap
5610: .seealso: MatGetSubMatrices()
5611: @*/
5612: PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
5613: {
5619: if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
5620: if (n) {
5623: }
5624: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5625: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5626: MatPreallocated(mat);
5628: if (!ov) return(0);
5629: if (!mat->ops->increaseoverlap) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5630: PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
5631: (*mat->ops->increaseoverlap)(mat,n,is,ov);
5632: PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
5633: return(0);
5634: }
5638: /*@
5639: MatGetBlockSize - Returns the matrix block size; useful especially for the
5640: block row and block diagonal formats.
5641:
5642: Not Collective
5644: Input Parameter:
5645: . mat - the matrix
5647: Output Parameter:
5648: . bs - block size
5650: Notes:
5651: Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ
5653: Level: intermediate
5655: Concepts: matrices^block size
5657: .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ()
5658: @*/
5659: PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
5660: {
5667: MatPreallocated(mat);
5668: *bs = mat->rmap->bs;
5669: return(0);
5670: }
5674: /*@
5675: MatSetBlockSize - Sets the matrix block size; for many matrix types you
5676: cannot use this and MUST set the blocksize when you preallocate the matrix
5677:
5678: Collective on Mat
5680: Input Parameters:
5681: + mat - the matrix
5682: - bs - block size
5684: Notes:
5685: Only works for shell and AIJ matrices
5687: Level: intermediate
5689: Concepts: matrices^block size
5691: .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ(), MatGetBlockSize()
5692: @*/
5693: PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
5694: {
5700: MatPreallocated(mat);
5701: if (mat->ops->setblocksize) {
5702: /* XXX should check if (bs < 1) ??? */
5703: PetscMapSetBlockSize(mat->rmap,bs);
5704: PetscMapSetBlockSize(mat->cmap,bs);
5705: (*mat->ops->setblocksize)(mat,bs);
5706: } else {
5707: SETERRQ1(PETSC_ERR_ARG_INCOMP,"Cannot set the blocksize for matrix type %s",((PetscObject)mat)->type_name);
5708: }
5709: return(0);
5710: }
5714: /*@C
5715: MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
5717: Collective on Mat
5719: Input Parameters:
5720: + mat - the matrix
5721: . shift - 0 or 1 indicating we want the indices starting at 0 or 1
5722: . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5723: symmetrized
5724: - blockcompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
5725: blockcompressed matrix is desired or not [inode, baij have blockcompressed
5726: nonzero structure which is different than the full nonzero structure]
5728: Output Parameters:
5729: + n - number of rows in the (possibly compressed) matrix
5730: . ia - the row pointers [of length n+1]
5731: . ja - the column indices
5732: - done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
5733: are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
5735: Level: developer
5737: Notes: You CANNOT change any of the ia[] or ja[] values.
5739: Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values
5741: Fortran Node
5743: In Fortran use
5744: $ PetscInt ia(1), ja(1)
5745: $ PetscOffset iia, jja
5746: $ call MatGetRowIJ(mat,shift,symmetric,blockcompressed,n,ia,iia,ja,jja,done,ierr)
5747:
5748: Acess the ith and jth entries via ia(iia + i) and ja(jja + j)
5750: .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatGetArray()
5751: @*/
5752: PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth blockcompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5753: {
5763: MatPreallocated(mat);
5764: if (!mat->ops->getrowij) *done = PETSC_FALSE;
5765: else {
5766: *done = PETSC_TRUE;
5767: PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);
5768: (*mat->ops->getrowij)(mat,shift,symmetric,blockcompressed,n,ia,ja,done);
5769: PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);
5770: }
5771: return(0);
5772: }
5776: /*@C
5777: MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
5779: Collective on Mat
5781: Input Parameters:
5782: + mat - the matrix
5783: . shift - 1 or zero indicating we want the indices starting at 0 or 1
5784: . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5785: symmetrized
5786: - blockcompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
5787: blockcompressed matrix is desired or not [inode, baij have blockcompressed
5788: nonzero structure which is different than the full nonzero structure]
5790: Output Parameters:
5791: + n - number of columns in the (possibly compressed) matrix
5792: . ia - the column pointers
5793: . ja - the row indices
5794: - done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
5796: Level: developer
5798: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
5799: @*/
5800: PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth blockcompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5801: {
5811: MatPreallocated(mat);
5812: if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
5813: else {
5814: *done = PETSC_TRUE;
5815: (*mat->ops->getcolumnij)(mat,shift,symmetric,blockcompressed,n,ia,ja,done);
5816: }
5817: return(0);
5818: }
5822: /*@C
5823: MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
5824: MatGetRowIJ().
5826: Collective on Mat
5828: Input Parameters:
5829: + mat - the matrix
5830: . shift - 1 or zero indicating we want the indices starting at 0 or 1
5831: . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5832: symmetrized
5833: - blockcompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
5834: blockcompressed matrix is desired or not [inode, baij have blockcompressed
5835: nonzero structure which is different than the full nonzero structure]
5837: Output Parameters:
5838: + n - size of (possibly compressed) matrix
5839: . ia - the row pointers
5840: . ja - the column indices
5841: - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
5843: Level: developer
5845: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
5846: @*/
5847: PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth blockcompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5848: {
5857: MatPreallocated(mat);
5859: if (!mat->ops->restorerowij) *done = PETSC_FALSE;
5860: else {
5861: *done = PETSC_TRUE;
5862: (*mat->ops->restorerowij)(mat,shift,symmetric,blockcompressed,n,ia,ja,done);
5863: }
5864: return(0);
5865: }
5869: /*@C
5870: MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
5871: MatGetColumnIJ().
5873: Collective on Mat
5875: Input Parameters:
5876: + mat - the matrix
5877: . shift - 1 or zero indicating we want the indices starting at 0 or 1
5878: - symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5879: symmetrized
5880: - blockcompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
5881: blockcompressed matrix is desired or not [inode, baij have blockcompressed
5882: nonzero structure which is different than the full nonzero structure]
5884: Output Parameters:
5885: + n - size of (possibly compressed) matrix
5886: . ia - the column pointers
5887: . ja - the row indices
5888: - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
5890: Level: developer
5892: .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
5893: @*/
5894: PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth blockcompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5895: {
5904: MatPreallocated(mat);
5906: if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
5907: else {
5908: *done = PETSC_TRUE;
5909: (*mat->ops->restorecolumnij)(mat,shift,symmetric,blockcompressed,n,ia,ja,done);
5910: }
5911: return(0);
5912: }
5916: /*@C
5917: MatColoringPatch -Used inside matrix coloring routines that
5918: use MatGetRowIJ() and/or MatGetColumnIJ().
5920: Collective on Mat
5922: Input Parameters:
5923: + mat - the matrix
5924: . ncolors - max color value
5925: . n - number of entries in colorarray
5926: - colorarray - array indicating color for each column
5928: Output Parameters:
5929: . iscoloring - coloring generated using colorarray information
5931: Level: developer
5933: .seealso: MatGetRowIJ(), MatGetColumnIJ()
5935: @*/
5936: PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
5937: {
5945: MatPreallocated(mat);
5947: if (!mat->ops->coloringpatch){
5948: ISColoringCreate(((PetscObject)mat)->comm,ncolors,n,colorarray,iscoloring);
5949: } else {
5950: (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);
5951: }
5952: return(0);
5953: }
5958: /*@
5959: MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
5961: Collective on Mat
5963: Input Parameter:
5964: . mat - the factored matrix to be reset
5966: Notes:
5967: This routine should be used only with factored matrices formed by in-place
5968: factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
5969: format). This option can save memory, for example, when solving nonlinear
5970: systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
5971: ILU(0) preconditioner.
5973: Note that one can specify in-place ILU(0) factorization by calling
5974: .vb
5975: PCType(pc,PCILU);
5976: PCFactorSeUseInPlace(pc);
5977: .ve
5978: or by using the options -pc_type ilu -pc_factor_in_place
5980: In-place factorization ILU(0) can also be used as a local
5981: solver for the blocks within the block Jacobi or additive Schwarz
5982: methods (runtime option: -sub_pc_factor_in_place). See the discussion
5983: of these preconditioners in the users manual for details on setting
5984: local solver options.
5986: Most users should employ the simplified KSP interface for linear solvers
5987: instead of working directly with matrix algebra routines such as this.
5988: See, e.g., KSPCreate().
5990: Level: developer
5992: .seealso: PCFactorSetUseInPlace()
5994: Concepts: matrices^unfactored
5996: @*/
5997: PetscErrorCode MatSetUnfactored(Mat mat)
5998: {
6004: MatPreallocated(mat);
6005: mat->factor = MAT_FACTOR_NONE;
6006: if (!mat->ops->setunfactored) return(0);
6007: (*mat->ops->setunfactored)(mat);
6008: return(0);
6009: }
6011: /*MC
6012: MatGetArrayF90 - Accesses a matrix array from Fortran90.
6014: Synopsis:
6015: MatGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
6017: Not collective
6019: Input Parameter:
6020: . x - matrix
6022: Output Parameters:
6023: + xx_v - the Fortran90 pointer to the array
6024: - ierr - error code
6026: Example of Usage:
6027: .vb
6028: PetscScalar, pointer xx_v(:)
6029: ....
6030: call MatGetArrayF90(x,xx_v,ierr)
6031: a = xx_v(3)
6032: call MatRestoreArrayF90(x,xx_v,ierr)
6033: .ve
6035: Notes:
6036: Not yet supported for all F90 compilers
6038: Level: advanced
6040: .seealso: MatRestoreArrayF90(), MatGetArray(), MatRestoreArray()
6042: Concepts: matrices^accessing array
6044: M*/
6046: /*MC
6047: MatRestoreArrayF90 - Restores a matrix array that has been
6048: accessed with MatGetArrayF90().
6050: Synopsis:
6051: MatRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
6053: Not collective
6055: Input Parameters:
6056: + x - matrix
6057: - xx_v - the Fortran90 pointer to the array
6059: Output Parameter:
6060: . ierr - error code
6062: Example of Usage:
6063: .vb
6064: PetscScalar, pointer xx_v(:)
6065: ....
6066: call MatGetArrayF90(x,xx_v,ierr)
6067: a = xx_v(3)
6068: call MatRestoreArrayF90(x,xx_v,ierr)
6069: .ve
6070:
6071: Notes:
6072: Not yet supported for all F90 compilers
6074: Level: advanced
6076: .seealso: MatGetArrayF90(), MatGetArray(), MatRestoreArray()
6078: M*/
6083: /*@
6084: MatGetSubMatrix - Gets a single submatrix on the same number of processors
6085: as the original matrix.
6087: Collective on Mat
6089: Input Parameters:
6090: + mat - the original matrix
6091: . isrow - rows this processor should obtain
6092: . iscol - columns for all processors you wish to keep
6093: . csize - number of columns "local" to this processor (does nothing for sequential
6094: matrices). This should match the result from VecGetLocalSize(x,...) if you
6095: plan to use the matrix in a A*x; alternatively, you can use PETSC_DECIDE
6096: - cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6098: Output Parameter:
6099: . newmat - the new submatrix, of the same type as the old
6101: Level: advanced
6103: Notes: the iscol argument MUST be the same on each processor. You might be
6104: able to create the iscol argument with ISAllGather(). The rows is isrow will be
6105: sorted into the same order as the original matrix.
6107: The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
6108: the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
6109: to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
6110: will reuse the matrix generated the first time. You should call MatDestroy() on newmat when
6111: you are finished using it.
6113: The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
6114: the input matrix.
6116: If iscol is PETSC_NULL then all columns are obtained (not supported in Fortran), you should
6117: use csize = PETSC_DECIDE also in this case.
6119: Concepts: matrices^submatrices
6121: .seealso: MatGetSubMatrices(), ISAllGather()
6122: @*/
6123: PetscErrorCode MatGetSubMatrix(Mat mat,IS isrow,IS iscol,PetscInt csize,MatReuse cll,Mat *newmat)
6124: {
6126: PetscMPIInt size;
6127: Mat *local;
6128: IS iscoltmp;
6137: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6138: MatPreallocated(mat);
6139: MPI_Comm_size(((PetscObject)mat)->comm,&size);
6141: if (!iscol) {
6142: if (csize == PETSC_DECIDE) csize = mat->cmap->n;
6143: ISCreateStride(((PetscObject)mat)->comm,mat->cmap->N,0,1,&iscoltmp);
6144: } else {
6145: iscoltmp = iscol;
6146: }
6148: /* if original matrix is on just one processor then use submatrix generated */
6149: if (!mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
6150: MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);
6151: if (!iscol) {ISDestroy(iscoltmp);}
6152: return(0);
6153: } else if (!mat->ops->getsubmatrix && size == 1) {
6154: MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);
6155: *newmat = *local;
6156: PetscFree(local);
6157: if (!iscol) {ISDestroy(iscoltmp);}
6158: return(0);
6159: }
6161: if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6162: (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,csize,cll,newmat);
6163: if (!iscol) {ISDestroy(iscoltmp);}
6164: PetscObjectStateIncrease((PetscObject)*newmat);
6165: return(0);
6166: }
6170: /*@
6171: MatGetSubMatrixRaw - Gets a single submatrix on the same number of processors
6172: as the original matrix.
6174: Collective on Mat
6176: Input Parameters:
6177: + mat - the original matrix
6178: . nrows - the number of rows this processor should obtain
6179: . rows - rows this processor should obtain
6180: . ncols - the number of columns for all processors you wish to keep
6181: . cols - columns for all processors you wish to keep
6182: . csize - number of columns "local" to this processor (does nothing for sequential
6183: matrices). This should match the result from VecGetLocalSize(x,...) if you
6184: plan to use the matrix in a A*x; alternatively, you can use PETSC_DECIDE
6185: - cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6187: Output Parameter:
6188: . newmat - the new submatrix, of the same type as the old
6190: Level: advanced
6192: Notes: the iscol argument MUST be the same on each processor. You might be
6193: able to create the iscol argument with ISAllGather().
6195: The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
6196: the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
6197: to this routine with a mat of the same nonzero structure and with a cll of MAT_REUSE_MATRIX
6198: will reuse the matrix generated the first time.
6200: Concepts: matrices^submatrices
6202: .seealso: MatGetSubMatrices(), ISAllGather()
6203: @*/
6204: PetscErrorCode MatGetSubMatrixRaw(Mat mat,PetscInt nrows,const PetscInt rows[],PetscInt ncols,const PetscInt cols[],PetscInt csize,MatReuse cll,Mat *newmat)
6205: {
6206: IS isrow, iscol;
6216: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6217: MatPreallocated(mat);
6218: ISCreateGeneralWithArray(PETSC_COMM_SELF, nrows, (PetscInt *) rows, &isrow);
6219: ISCreateGeneralWithArray(PETSC_COMM_SELF, ncols, (PetscInt *) cols, &iscol);
6220: MatGetSubMatrix(mat, isrow, iscol, csize, cll, newmat);
6221: ISDestroy(isrow);
6222: ISDestroy(iscol);
6223: return(0);
6224: }
6228: /*@
6229: MatStashSetInitialSize - sets the sizes of the matrix stash, that is
6230: used during the assembly process to store values that belong to
6231: other processors.
6233: Not Collective
6235: Input Parameters:
6236: + mat - the matrix
6237: . size - the initial size of the stash.
6238: - bsize - the initial size of the block-stash(if used).
6240: Options Database Keys:
6241: + -matstash_initial_size <size> or <size0,size1,...sizep-1>
6242: - -matstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1>
6244: Level: intermediate
6246: Notes:
6247: The block-stash is used for values set with MatSetValuesBlocked() while
6248: the stash is used for values set with MatSetValues()
6250: Run with the option -info and look for output of the form
6251: MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
6252: to determine the appropriate value, MM, to use for size and
6253: MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
6254: to determine the value, BMM to use for bsize
6256: Concepts: stash^setting matrix size
6257: Concepts: matrices^stash
6259: @*/
6260: PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
6261: {
6267: MatStashSetInitialSize_Private(&mat->stash,size);
6268: MatStashSetInitialSize_Private(&mat->bstash,bsize);
6269: return(0);
6270: }
6274: /*@
6275: MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
6276: the matrix
6278: Collective on Mat
6280: Input Parameters:
6281: + mat - the matrix
6282: . x,y - the vectors
6283: - w - where the result is stored
6285: Level: intermediate
6287: Notes:
6288: w may be the same vector as y.
6290: This allows one to use either the restriction or interpolation (its transpose)
6291: matrix to do the interpolation
6293: Concepts: interpolation
6295: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
6297: @*/
6298: PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
6299: {
6301: PetscInt M,N;
6309: MatPreallocated(A);
6310: MatGetSize(A,&M,&N);
6311: if (N > M) {
6312: MatMultTransposeAdd(A,x,y,w);
6313: } else {
6314: MatMultAdd(A,x,y,w);
6315: }
6316: return(0);
6317: }
6321: /*@
6322: MatInterpolate - y = A*x or A'*x depending on the shape of
6323: the matrix
6325: Collective on Mat
6327: Input Parameters:
6328: + mat - the matrix
6329: - x,y - the vectors
6331: Level: intermediate
6333: Notes:
6334: This allows one to use either the restriction or interpolation (its transpose)
6335: matrix to do the interpolation
6337: Concepts: matrices^interpolation
6339: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
6341: @*/
6342: PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
6343: {
6345: PetscInt M,N;
6352: MatPreallocated(A);
6353: MatGetSize(A,&M,&N);
6354: if (N > M) {
6355: MatMultTranspose(A,x,y);
6356: } else {
6357: MatMult(A,x,y);
6358: }
6359: return(0);
6360: }
6364: /*@
6365: MatRestrict - y = A*x or A'*x
6367: Collective on Mat
6369: Input Parameters:
6370: + mat - the matrix
6371: - x,y - the vectors
6373: Level: intermediate
6375: Notes:
6376: This allows one to use either the restriction or interpolation (its transpose)
6377: matrix to do the restriction
6379: Concepts: matrices^restriction
6381: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
6383: @*/
6384: PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
6385: {
6387: PetscInt M,N;
6394: MatPreallocated(A);
6396: MatGetSize(A,&M,&N);
6397: if (N > M) {
6398: MatMult(A,x,y);
6399: } else {
6400: MatMultTranspose(A,x,y);
6401: }
6402: return(0);
6403: }
6407: /*@
6408: MatNullSpaceAttach - attaches a null space to a matrix.
6409: This null space will be removed from the resulting vector whenever
6410: MatMult() is called
6412: Collective on Mat
6414: Input Parameters:
6415: + mat - the matrix
6416: - nullsp - the null space object
6418: Level: developer
6420: Notes:
6421: Overwrites any previous null space that may have been attached
6423: Concepts: null space^attaching to matrix
6425: .seealso: MatCreate(), MatNullSpaceCreate()
6426: @*/
6427: PetscErrorCode MatNullSpaceAttach(Mat mat,MatNullSpace nullsp)
6428: {
6435: MatPreallocated(mat);
6436: PetscObjectReference((PetscObject)nullsp);
6437: if (mat->nullsp) { MatNullSpaceDestroy(mat->nullsp); }
6438: mat->nullsp = nullsp;
6439: return(0);
6440: }
6444: /*@
6445: MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
6447: Collective on Mat
6449: Input Parameters:
6450: + mat - the matrix
6451: . row - row/column permutation
6452: . fill - expected fill factor >= 1.0
6453: - level - level of fill, for ICC(k)
6455: Notes:
6456: Probably really in-place only when level of fill is zero, otherwise allocates
6457: new space to store factored matrix and deletes previous memory.
6459: Most users should employ the simplified KSP interface for linear solvers
6460: instead of working directly with matrix algebra routines such as this.
6461: See, e.g., KSPCreate().
6463: Level: developer
6465: Concepts: matrices^incomplete Cholesky factorization
6466: Concepts: Cholesky factorization
6468: .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6469: @*/
6470: PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo* info)
6471: {
6479: if (mat->rmap->N != mat->cmap->N) SETERRQ(PETSC_ERR_ARG_WRONG,"matrix must be square");
6480: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6481: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6482: if (!mat->ops->iccfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6483: MatPreallocated(mat);
6484: (*mat->ops->iccfactor)(mat,row,info);
6485: PetscObjectStateIncrease((PetscObject)mat);
6486: return(0);
6487: }
6491: /*@
6492: MatSetValuesAdic - Sets values computed with ADIC automatic differentiation into a matrix.
6494: Not Collective
6496: Input Parameters:
6497: + mat - the matrix
6498: - v - the values compute with ADIC
6500: Level: developer
6502: Notes:
6503: Must call MatSetColoring() before using this routine. Also this matrix must already
6504: have its nonzero pattern determined.
6506: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
6507: MatSetValues(), MatSetColoring(), MatSetValuesAdifor()
6508: @*/
6509: PetscErrorCode MatSetValuesAdic(Mat mat,void *v)
6510: {
6518: if (!mat->assembled) {
6519: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6520: }
6521: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
6522: if (!mat->ops->setvaluesadic) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6523: (*mat->ops->setvaluesadic)(mat,v);
6524: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
6525: MatView_Private(mat);
6526: PetscObjectStateIncrease((PetscObject)mat);
6527: return(0);
6528: }
6533: /*@
6534: MatSetColoring - Sets a coloring used by calls to MatSetValuesAdic()
6536: Not Collective
6538: Input Parameters:
6539: + mat - the matrix
6540: - coloring - the coloring
6542: Level: developer
6544: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
6545: MatSetValues(), MatSetValuesAdic()
6546: @*/
6547: PetscErrorCode MatSetColoring(Mat mat,ISColoring coloring)
6548: {
6556: if (!mat->assembled) {
6557: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6558: }
6559: if (!mat->ops->setcoloring) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6560: (*mat->ops->setcoloring)(mat,coloring);
6561: return(0);
6562: }
6566: /*@
6567: MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.
6569: Not Collective
6571: Input Parameters:
6572: + mat - the matrix
6573: . nl - leading dimension of v
6574: - v - the values compute with ADIFOR
6576: Level: developer
6578: Notes:
6579: Must call MatSetColoring() before using this routine. Also this matrix must already
6580: have its nonzero pattern determined.
6582: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
6583: MatSetValues(), MatSetColoring()
6584: @*/
6585: PetscErrorCode MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
6586: {
6594: if (!mat->assembled) {
6595: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6596: }
6597: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
6598: if (!mat->ops->setvaluesadifor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6599: (*mat->ops->setvaluesadifor)(mat,nl,v);
6600: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
6601: PetscObjectStateIncrease((PetscObject)mat);
6602: return(0);
6603: }
6607: /*@
6608: MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
6609: ghosted ones.
6611: Not Collective
6613: Input Parameters:
6614: + mat - the matrix
6615: - diag = the diagonal values, including ghost ones
6617: Level: developer
6619: Notes: Works only for MPIAIJ and MPIBAIJ matrices
6620:
6621: .seealso: MatDiagonalScale()
6622: @*/
6623: PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
6624: {
6626: PetscMPIInt size;
6633: if (!mat->assembled) {
6634: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6635: }
6636: PetscLogEventBegin(MAT_Scale,mat,0,0,0);
6637: MPI_Comm_size(((PetscObject)mat)->comm,&size);
6638: if (size == 1) {
6639: PetscInt n,m;
6640: VecGetSize(diag,&n);
6641: MatGetSize(mat,0,&m);
6642: if (m == n) {
6643: MatDiagonalScale(mat,0,diag);
6644: } else {
6645: SETERRQ(PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
6646: }
6647: } else {
6648: PetscErrorCode (*f)(Mat,Vec);
6649: PetscObjectQueryFunction((PetscObject)mat,"MatDiagonalScaleLocal_C",(void (**)(void))&f);
6650: if (f) {
6651: (*f)(mat,diag);
6652: } else {
6653: SETERRQ(PETSC_ERR_SUP,"Only supported for MPIAIJ and MPIBAIJ parallel matrices");
6654: }
6655: }
6656: PetscLogEventEnd(MAT_Scale,mat,0,0,0);
6657: PetscObjectStateIncrease((PetscObject)mat);
6658: return(0);
6659: }
6663: /*@
6664: MatGetInertia - Gets the inertia from a factored matrix
6666: Collective on Mat
6668: Input Parameter:
6669: . mat - the matrix
6671: Output Parameters:
6672: + nneg - number of negative eigenvalues
6673: . nzero - number of zero eigenvalues
6674: - npos - number of positive eigenvalues
6676: Level: advanced
6678: Notes: Matrix must have been factored by MatCholeskyFactor()
6681: @*/
6682: PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
6683: {
6689: if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
6690: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
6691: if (!mat->ops->getinertia) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6692: (*mat->ops->getinertia)(mat,nneg,nzero,npos);
6693: return(0);
6694: }
6696: /* ----------------------------------------------------------------*/
6699: /*@C
6700: MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
6702: Collective on Mat and Vecs
6704: Input Parameters:
6705: + mat - the factored matrix
6706: - b - the right-hand-side vectors
6708: Output Parameter:
6709: . x - the result vectors
6711: Notes:
6712: The vectors b and x cannot be the same. I.e., one cannot
6713: call MatSolves(A,x,x).
6715: Notes:
6716: Most users should employ the simplified KSP interface for linear solvers
6717: instead of working directly with matrix algebra routines such as this.
6718: See, e.g., KSPCreate().
6720: Level: developer
6722: Concepts: matrices^triangular solves
6724: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
6725: @*/
6726: PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
6727: {
6733: if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
6734: if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
6735: if (!mat->rmap->N && !mat->cmap->N) return(0);
6737: if (!mat->ops->solves) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6738: MatPreallocated(mat);
6739: PetscLogEventBegin(MAT_Solves,mat,0,0,0);
6740: (*mat->ops->solves)(mat,b,x);
6741: PetscLogEventEnd(MAT_Solves,mat,0,0,0);
6742: return(0);
6743: }
6747: /*@
6748: MatIsSymmetric - Test whether a matrix is symmetric
6750: Collective on Mat
6752: Input Parameter:
6753: + A - the matrix to test
6754: - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
6756: Output Parameters:
6757: . flg - the result
6759: Level: intermediate
6761: Concepts: matrix^symmetry
6763: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
6764: @*/
6765: PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscTruth *flg)
6766: {
6772: if (!A->symmetric_set) {
6773: if (!A->ops->issymmetric) {
6774: const MatType mattype;
6775: MatGetType(A,&mattype);
6776: SETERRQ1(PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
6777: }
6778: (*A->ops->issymmetric)(A,tol,&A->symmetric);
6779: A->symmetric_set = PETSC_TRUE;
6780: if (A->symmetric) {
6781: A->structurally_symmetric_set = PETSC_TRUE;
6782: A->structurally_symmetric = PETSC_TRUE;
6783: }
6784: }
6785: *flg = A->symmetric;
6786: return(0);
6787: }
6791: /*@
6792: MatIsHermitian - Test whether a matrix is Hermitian
6794: Collective on Mat
6796: Input Parameter:
6797: + A - the matrix to test
6798: - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
6800: Output Parameters:
6801: . flg - the result
6803: Level: intermediate
6805: Concepts: matrix^symmetry
6807: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
6808: @*/
6809: PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscTruth *flg)
6810: {
6816: if (!A->hermitian_set) {
6817: if (!A->ops->ishermitian) {
6818: const MatType mattype;
6819: MatGetType(A,&mattype);
6820: SETERRQ1(PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for Hermitian",mattype);
6821: }
6822: (*A->ops->ishermitian)(A,tol,&A->hermitian);
6823: A->hermitian_set = PETSC_TRUE;
6824: if (A->hermitian) {
6825: A->structurally_symmetric_set = PETSC_TRUE;
6826: A->structurally_symmetric = PETSC_TRUE;
6827: }
6828: }
6829: *flg = A->hermitian;
6830: return(0);
6831: }
6835: /*@
6836: MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
6838: Collective on Mat
6840: Input Parameter:
6841: . A - the matrix to check
6843: Output Parameters:
6844: + set - if the symmetric flag is set (this tells you if the next flag is valid)
6845: - flg - the result
6847: Level: advanced
6849: Concepts: matrix^symmetry
6851: Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
6852: if you want it explicitly checked
6854: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
6855: @*/
6856: PetscErrorCode MatIsSymmetricKnown(Mat A,PetscTruth *set,PetscTruth *flg)
6857: {
6862: if (A->symmetric_set) {
6863: *set = PETSC_TRUE;
6864: *flg = A->symmetric;
6865: } else {
6866: *set = PETSC_FALSE;
6867: }
6868: return(0);
6869: }
6873: /*@
6874: MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
6876: Collective on Mat
6878: Input Parameter:
6879: . A - the matrix to check
6881: Output Parameters:
6882: + set - if the hermitian flag is set (this tells you if the next flag is valid)
6883: - flg - the result
6885: Level: advanced
6887: Concepts: matrix^symmetry
6889: Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
6890: if you want it explicitly checked
6892: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
6893: @*/
6894: PetscErrorCode MatIsHermitianKnown(Mat A,PetscTruth *set,PetscTruth *flg)
6895: {
6900: if (A->hermitian_set) {
6901: *set = PETSC_TRUE;
6902: *flg = A->hermitian;
6903: } else {
6904: *set = PETSC_FALSE;
6905: }
6906: return(0);
6907: }
6911: /*@
6912: MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
6914: Collective on Mat
6916: Input Parameter:
6917: . A - the matrix to test
6919: Output Parameters:
6920: . flg - the result
6922: Level: intermediate
6924: Concepts: matrix^symmetry
6926: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
6927: @*/
6928: PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscTruth *flg)
6929: {
6935: if (!A->structurally_symmetric_set) {
6936: if (!A->ops->isstructurallysymmetric) SETERRQ(PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
6937: (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);
6938: A->structurally_symmetric_set = PETSC_TRUE;
6939: }
6940: *flg = A->structurally_symmetric;
6941: return(0);
6942: }
6947: /*@
6948: MatStashGetInfo - Gets how many values are currently in the vector stash, i.e. need
6949: to be communicated to other processors during the MatAssemblyBegin/End() process
6951: Not collective
6953: Input Parameter:
6954: . vec - the vector
6956: Output Parameters:
6957: + nstash - the size of the stash
6958: . reallocs - the number of additional mallocs incurred.
6959: . bnstash - the size of the block stash
6960: - breallocs - the number of additional mallocs incurred.in the block stash
6961:
6962: Level: advanced
6964: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
6965:
6966: @*/
6967: PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
6968: {
6971: MatStashGetInfo_Private(&mat->stash,nstash,reallocs);
6972: MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);
6973: return(0);
6974: }
6978: /*@C
6979: MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same
6980: parallel layout
6981:
6982: Collective on Mat
6984: Input Parameter:
6985: . mat - the matrix
6987: Output Parameter:
6988: + right - (optional) vector that the matrix can be multiplied against
6989: - left - (optional) vector that the matrix vector product can be stored in
6991: Level: advanced
6993: .seealso: MatCreate()
6994: @*/
6995: PetscErrorCode MatGetVecs(Mat mat,Vec *right,Vec *left)
6996: {
7002: MatPreallocated(mat);
7003: if (mat->ops->getvecs) {
7004: (*mat->ops->getvecs)(mat,right,left);
7005: } else {
7006: PetscMPIInt size;
7007: MPI_Comm_size(((PetscObject)mat)->comm, &size);
7008: if (right) {
7009: VecCreate(((PetscObject)mat)->comm,right);
7010: VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);
7011: VecSetBlockSize(*right,mat->rmap->bs);
7012: if (size > 1) {
7013: /* New vectors uses Mat cmap and does not create a new one */
7014: PetscMapDestroy((*right)->map);
7015: (*right)->map = mat->cmap;
7016: mat->cmap->refcnt++;
7018: VecSetType(*right,VECMPI);
7019: } else {VecSetType(*right,VECSEQ);}
7020: }
7021: if (left) {
7022: VecCreate(((PetscObject)mat)->comm,left);
7023: VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);
7024: VecSetBlockSize(*left,mat->rmap->bs);
7025: if (size > 1) {
7026: /* New vectors uses Mat rmap and does not create a new one */
7027: PetscMapDestroy((*left)->map);
7028: (*left)->map = mat->rmap;
7029: mat->rmap->refcnt++;
7031: VecSetType(*left,VECMPI);
7032: } else {VecSetType(*left,VECSEQ);}
7033: }
7034: }
7035: if (mat->mapping) {
7036: if (right) {VecSetLocalToGlobalMapping(*right,mat->mapping);}
7037: if (left) {VecSetLocalToGlobalMapping(*left,mat->mapping);}
7038: }
7039: if (mat->bmapping) {
7040: if (right) {VecSetLocalToGlobalMappingBlock(*right,mat->bmapping);}
7041: if (left) {VecSetLocalToGlobalMappingBlock(*left,mat->bmapping);}
7042: }
7043: return(0);
7044: }
7048: /*@
7049: MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
7050: with default values.
7052: Not Collective
7054: Input Parameters:
7055: . info - the MatFactorInfo data structure
7058: Notes: The solvers are generally used through the KSP and PC objects, for example
7059: PCLU, PCILU, PCCHOLESKY, PCICC
7061: Level: developer
7063: .seealso: MatFactorInfo
7064: @*/
7066: PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
7067: {
7071: PetscMemzero(info,sizeof(MatFactorInfo));
7072: return(0);
7073: }
7077: /*@
7078: MatPtAP - Creates the matrix projection C = P^T * A * P
7080: Collective on Mat
7082: Input Parameters:
7083: + A - the matrix
7084: . P - the projection matrix
7085: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7086: - fill - expected fill as ratio of nnz(C)/nnz(A)
7088: Output Parameters:
7089: . C - the product matrix
7091: Notes:
7092: C will be created and must be destroyed by the user with MatDestroy().
7094: This routine is currently only implemented for pairs of AIJ matrices and classes
7095: which inherit from AIJ.
7097: Level: intermediate
7099: .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult()
7100: @*/
7101: PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
7102: {
7108: if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7109: if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7112: MatPreallocated(P);
7113: if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7114: if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7116: if (P->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
7117: if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
7118: MatPreallocated(A);
7120: PetscLogEventBegin(MAT_PtAP,A,P,0,0);
7121: (*A->ops->ptap)(A,P,scall,fill,C);
7122: PetscLogEventEnd(MAT_PtAP,A,P,0,0);
7124: return(0);
7125: }
7129: /*@
7130: MatPtAPNumeric - Computes the matrix projection C = P^T * A * P
7132: Collective on Mat
7134: Input Parameters:
7135: + A - the matrix
7136: - P - the projection matrix
7138: Output Parameters:
7139: . C - the product matrix
7141: Notes:
7142: C must have been created by calling MatPtAPSymbolic and must be destroyed by
7143: the user using MatDeatroy().
7145: This routine is currently only implemented for pairs of AIJ matrices and classes
7146: which inherit from AIJ. C will be of type MATAIJ.
7148: Level: intermediate
7150: .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
7151: @*/
7152: PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C)
7153: {
7159: if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7160: if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7163: MatPreallocated(P);
7164: if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7165: if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7168: MatPreallocated(C);
7169: if (C->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7170: if (P->cmap->N!=C->rmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->rmap->N);
7171: if (P->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
7172: if (A->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
7173: if (P->cmap->N!=C->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->cmap->N);
7174: MatPreallocated(A);
7176: PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
7177: (*A->ops->ptapnumeric)(A,P,C);
7178: PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
7179: return(0);
7180: }
7184: /*@
7185: MatPtAPSymbolic - Creates the (i,j) structure of the matrix projection C = P^T * A * P
7187: Collective on Mat
7189: Input Parameters:
7190: + A - the matrix
7191: - P - the projection matrix
7193: Output Parameters:
7194: . C - the (i,j) structure of the product matrix
7196: Notes:
7197: C will be created and must be destroyed by the user with MatDestroy().
7199: This routine is currently only implemented for pairs of SeqAIJ matrices and classes
7200: which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using
7201: this (i,j) structure by calling MatPtAPNumeric().
7203: Level: intermediate
7205: .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
7206: @*/
7207: PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
7208: {
7214: if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7215: if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7216: if (fill <1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
7219: MatPreallocated(P);
7220: if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7221: if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7224: if (P->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
7225: if (A->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
7226: MatPreallocated(A);
7227: PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);
7228: (*A->ops->ptapsymbolic)(A,P,fill,C);
7229: PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);
7231: MatSetBlockSize(*C,A->rmap->bs);
7233: return(0);
7234: }
7238: /*@
7239: MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
7241: Collective on Mat
7243: Input Parameters:
7244: + A - the left matrix
7245: . B - the right matrix
7246: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7247: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
7248: if the result is a dense matrix this is irrelevent
7250: Output Parameters:
7251: . C - the product matrix
7253: Notes:
7254: Unless scall is MAT_REUSE_MATRIX C will be created.
7256: MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
7257:
7258: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
7259: actually needed.
7261: If you have many matrices with the same non-zero structure to multiply, you
7262: should either
7263: $ 1) use MAT_REUSE_MATRIX in all calls but the first or
7264: $ 2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
7266: Level: intermediate
7268: .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatPtAP()
7269: @*/
7270: PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
7271: {
7273: PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
7274: PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
7275: PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat *)=PETSC_NULL;
7280: if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7281: if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7284: MatPreallocated(B);
7285: if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7286: if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7288: if (B->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
7289: if (scall == MAT_REUSE_MATRIX){
7292: }
7293: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
7294: if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
7295: MatPreallocated(A);
7297: fA = A->ops->matmult;
7298: fB = B->ops->matmult;
7299: if (fB == fA) {
7300: if (!fB) SETERRQ1(PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
7301: mult = fB;
7302: } else {
7303: /* dispatch based on the type of A and B */
7304: char multname[256];
7305: PetscStrcpy(multname,"MatMatMult_");
7306: PetscStrcat(multname,((PetscObject)A)->type_name);
7307: PetscStrcat(multname,"_");
7308: PetscStrcat(multname,((PetscObject)B)->type_name);
7309: PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
7310: PetscObjectQueryFunction((PetscObject)B,multname,(void (**)(void))&mult);
7311: if (!mult) SETERRQ2(PETSC_ERR_ARG_INCOMP,"MatMatMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
7312: }
7313: PetscLogEventBegin(MAT_MatMult,A,B,0,0);
7314: (*mult)(A,B,scall,fill,C);
7315: PetscLogEventEnd(MAT_MatMult,A,B,0,0);
7316: return(0);
7317: }
7321: /*@
7322: MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
7323: of the matrix-matrix product C=A*B. Call this routine before calling MatMatMultNumeric().
7325: Collective on Mat
7327: Input Parameters:
7328: + A - the left matrix
7329: . B - the right matrix
7330: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
7331: if C is a dense matrix this is irrelevent
7332:
7333: Output Parameters:
7334: . C - the product matrix
7336: Notes:
7337: Unless scall is MAT_REUSE_MATRIX C will be created.
7339: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
7340: actually needed.
7342: This routine is currently implemented for
7343: - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
7344: - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
7345: - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
7347: Level: intermediate
7349: .seealso: MatMatMult(), MatMatMultNumeric()
7350: @*/
7351: PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
7352: {
7354: PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat *);
7355: PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat *);
7356: PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat *)=PETSC_NULL;
7361: if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7362: if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7366: MatPreallocated(B);
7367: if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7368: if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7371: if (B->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
7372: if (fill == PETSC_DEFAULT) fill = 2.0;
7373: if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
7374: MatPreallocated(A);
7375:
7376: Asymbolic = A->ops->matmultsymbolic;
7377: Bsymbolic = B->ops->matmultsymbolic;
7378: if (Asymbolic == Bsymbolic){
7379: if (!Bsymbolic) SETERRQ1(PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
7380: symbolic = Bsymbolic;
7381: } else { /* dispatch based on the type of A and B */
7382: char symbolicname[256];
7383: PetscStrcpy(symbolicname,"MatMatMultSymbolic_");
7384: PetscStrcat(symbolicname,((PetscObject)A)->type_name);
7385: PetscStrcat(symbolicname,"_");
7386: PetscStrcat(symbolicname,((PetscObject)B)->type_name);
7387: PetscStrcat(symbolicname,"_C");
7388: PetscObjectQueryFunction((PetscObject)B,symbolicname,(void (**)(void))&symbolic);
7389: if (!symbolic) SETERRQ2(PETSC_ERR_ARG_INCOMP,"MatMatMultSymbolic requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
7390: }
7391: PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);
7392: (*symbolic)(A,B,fill,C);
7393: PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);
7394: return(0);
7395: }
7399: /*@
7400: MatMatMultNumeric - Performs the numeric matrix-matrix product.
7401: Call this routine after first calling MatMatMultSymbolic().
7403: Collective on Mat
7405: Input Parameters:
7406: + A - the left matrix
7407: - B - the right matrix
7409: Output Parameters:
7410: . C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
7412: Notes:
7413: C must have been created with MatMatMultSymbolic().
7415: This routine is currently implemented for
7416: - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
7417: - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
7418: - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
7420: Level: intermediate
7422: .seealso: MatMatMult(), MatMatMultSymbolic()
7423: @*/
7424: PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C)
7425: {
7427: PetscErrorCode (*Anumeric)(Mat,Mat,Mat);
7428: PetscErrorCode (*Bnumeric)(Mat,Mat,Mat);
7429: PetscErrorCode (*numeric)(Mat,Mat,Mat)=PETSC_NULL;
7434: if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7435: if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7439: MatPreallocated(B);
7440: if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7441: if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7445: MatPreallocated(C);
7446: if (!C->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7447: if (C->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7449: if (B->cmap->N!=C->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->cmap->N,C->cmap->N);
7450: if (B->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
7451: if (A->rmap->N!=C->rmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",A->rmap->N,C->rmap->N);
7452: MatPreallocated(A);
7454: Anumeric = A->ops->matmultnumeric;
7455: Bnumeric = B->ops->matmultnumeric;
7456: if (Anumeric == Bnumeric){
7457: if (!Bnumeric) SETERRQ1(PETSC_ERR_SUP,"MatMatMultNumeric not supported for B of type %s",((PetscObject)B)->type_name);
7458: numeric = Bnumeric;
7459: } else {
7460: char numericname[256];
7461: PetscStrcpy(numericname,"MatMatMultNumeric_");
7462: PetscStrcat(numericname,((PetscObject)A)->type_name);
7463: PetscStrcat(numericname,"_");
7464: PetscStrcat(numericname,((PetscObject)B)->type_name);
7465: PetscStrcat(numericname,"_C");
7466: PetscObjectQueryFunction((PetscObject)B,numericname,(void (**)(void))&numeric);
7467: if (!numeric)
7468: SETERRQ2(PETSC_ERR_ARG_INCOMP,"MatMatMultNumeric requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
7469: }
7470: PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);
7471: (*numeric)(A,B,C);
7472: PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);
7473: return(0);
7474: }
7478: /*@
7479: MatMatMultTranspose - Performs Matrix-Matrix Multiplication C=A^T*B.
7481: Collective on Mat
7483: Input Parameters:
7484: + A - the left matrix
7485: . B - the right matrix
7486: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7487: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
7489: Output Parameters:
7490: . C - the product matrix
7492: Notes:
7493: C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
7495: MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
7497: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
7498: actually needed.
7500: This routine is currently only implemented for pairs of SeqAIJ matrices and pairs of SeqDense matrices and classes
7501: which inherit from SeqAIJ. C will be of type MATSEQAIJ.
7503: Level: intermediate
7505: .seealso: MatMatMultTransposeSymbolic(), MatMatMultTransposeNumeric(), MatPtAP()
7506: @*/
7507: PetscErrorCode MatMatMultTranspose(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
7508: {
7510: PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
7511: PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
7516: if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7517: if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7520: MatPreallocated(B);
7521: if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7522: if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7524: if (B->rmap->N!=A->rmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->rmap->N);
7525: if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
7526: MatPreallocated(A);
7528: fA = A->ops->matmulttranspose;
7529: if (!fA) SETERRQ1(PETSC_ERR_SUP,"MatMatMultTranspose not supported for A of type %s",((PetscObject)A)->type_name);
7530: fB = B->ops->matmulttranspose;
7531: if (!fB) SETERRQ1(PETSC_ERR_SUP,"MatMatMultTranspose not supported for B of type %s",((PetscObject)B)->type_name);
7532: if (fB!=fA) SETERRQ2(PETSC_ERR_ARG_INCOMP,"MatMatMultTranspose requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
7534: PetscLogEventBegin(MAT_MatMultTranspose,A,B,0,0);
7535: (*A->ops->matmulttranspose)(A,B,scall,fill,C);
7536: PetscLogEventEnd(MAT_MatMultTranspose,A,B,0,0);
7537:
7538: return(0);
7539: }
7543: /*@C
7544: MatGetRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
7546: Collective on Mat
7548: Input Parameters:
7549: + mat - the matrix
7550: . nsubcomm - the number of subcommunicators (= number of redundant pareallel or sequential matrices)
7551: . subcomm - MPI communicator split from the communicator where mat resides in
7552: . mlocal_red - number of local rows of the redundant matrix
7553: - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7555: Output Parameter:
7556: . matredundant - redundant matrix
7558: Notes:
7559: MAT_REUSE_MATRIX can only be used when the nonzero structure of the
7560: original matrix has not changed from that last call to MatGetRedundantMatrix().
7562: This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
7563: calling it.
7565: Only MPIAIJ matrix is supported.
7566:
7567: Level: advanced
7569: Concepts: subcommunicator
7570: Concepts: duplicate matrix
7572: .seealso: MatDestroy()
7573: @*/
7574: PetscErrorCode MatGetRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,PetscInt mlocal_red,MatReuse reuse,Mat *matredundant)
7575: {
7580: if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
7583: }
7584: if (!mat->ops->getredundantmatrix) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7585: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7586: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7587: MatPreallocated(mat);
7589: PetscLogEventBegin(MAT_GetRedundantMatrix,mat,0,0,0);
7590: (*mat->ops->getredundantmatrix)(mat,nsubcomm,subcomm,mlocal_red,reuse,matredundant);
7591: PetscLogEventEnd(MAT_GetRedundantMatrix,mat,0,0,0);
7592: return(0);
7593: }