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: MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling
39: Not Collective
41: Input Parameters:
42: + mat - the matrix
43: - reuse - indicates you are passing in the a matrix and want it reused
45: Output Parameters:
46: + iscopy - indicates a copy of the diagonal matrix was created and you should use MatDestroy() on it
47: - a - the diagonal part (which is a SEQUENTIAL matrix)
49: Notes: see the manual page for MatCreateMPIAIJ() for more information on the "diagonal part" of the matrix
51: Level: advanced
53: @*/
54: PetscErrorCode MatGetDiagonalBlock(Mat A,PetscTruth *iscopy,MatReuse reuse,Mat *a)
55: {
56: PetscErrorCode ierr,(*f)(Mat,PetscTruth*,MatReuse,Mat*);
57: PetscMPIInt size;
60: MPI_Comm_size(((PetscObject)A)->comm,&size);
61: PetscObjectQueryFunction((PetscObject)A,"MatGetDiagonalBlock_C",(void (**)(void))&f);
62: if (f) {
63: (*f)(A,iscopy,reuse,a);
64: } else if (size == 1) {
65: *a = A;
66: } else {
67: SETERRQ(PETSC_ERR_SUP,"Cannot get diagonal part for this matrix");
68: }
69: return(0);
70: }
74: /*@
75: MatRealPart - Zeros out the imaginary part of the matrix
77: Collective on Mat
79: Input Parameters:
80: . mat - the matrix
82: Level: advanced
85: .seealso: MatImaginaryPart()
86: @*/
87: PetscErrorCode MatRealPart(Mat mat)
88: {
94: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
95: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
96: if (!mat->ops->realpart) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
97: MatPreallocated(mat);
98: (*mat->ops->realpart)(mat);
99: return(0);
100: }
105: /*@
106: MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part
108: Collective on Mat
110: Input Parameters:
111: . mat - the matrix
113: Level: advanced
116: .seealso: MatRealPart()
117: @*/
118: PetscErrorCode MatImaginaryPart(Mat mat)
119: {
125: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
126: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
127: if (!mat->ops->imaginarypart) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
128: MatPreallocated(mat);
129: (*mat->ops->imaginarypart)(mat);
130: return(0);
131: }
135: /*@
136: MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices)
138: Collective on Mat
140: Input Parameter:
141: . mat - the matrix
143: Output Parameters:
144: + missing - is any diagonal missing
145: - dd - first diagonal entry that is missing (optional)
147: Level: advanced
150: .seealso: MatRealPart()
151: @*/
152: PetscErrorCode MatMissingDiagonal(Mat mat,PetscTruth *missing,PetscInt *dd)
153: {
159: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
160: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
161: if (!mat->ops->missingdiagonal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
162: (*mat->ops->missingdiagonal)(mat,missing,dd);
163: return(0);
164: }
168: /*@C
169: MatGetRow - Gets a row of a matrix. You MUST call MatRestoreRow()
170: for each row that you get to ensure that your application does
171: not bleed memory.
173: Not Collective
175: Input Parameters:
176: + mat - the matrix
177: - row - the row to get
179: Output Parameters:
180: + ncols - if not NULL, the number of nonzeros in the row
181: . cols - if not NULL, the column numbers
182: - vals - if not NULL, the values
184: Notes:
185: This routine is provided for people who need to have direct access
186: to the structure of a matrix. We hope that we provide enough
187: high-level matrix routines that few users will need it.
189: MatGetRow() always returns 0-based column indices, regardless of
190: whether the internal representation is 0-based (default) or 1-based.
192: For better efficiency, set cols and/or vals to PETSC_NULL if you do
193: not wish to extract these quantities.
195: The user can only examine the values extracted with MatGetRow();
196: the values cannot be altered. To change the matrix entries, one
197: must use MatSetValues().
199: You can only have one call to MatGetRow() outstanding for a particular
200: matrix at a time, per processor. MatGetRow() can only obtain rows
201: associated with the given processor, it cannot get rows from the
202: other processors; for that we suggest using MatGetSubMatrices(), then
203: MatGetRow() on the submatrix. The row indix passed to MatGetRows()
204: is in the global number of rows.
206: Fortran Notes:
207: The calling sequence from Fortran is
208: .vb
209: MatGetRow(matrix,row,ncols,cols,values,ierr)
210: Mat matrix (input)
211: integer row (input)
212: integer ncols (output)
213: integer cols(maxcols) (output)
214: double precision (or double complex) values(maxcols) output
215: .ve
216: where maxcols >= maximum nonzeros in any row of the matrix.
219: Caution:
220: Do not try to change the contents of the output arrays (cols and vals).
221: In some cases, this may corrupt the matrix.
223: Level: advanced
225: Concepts: matrices^row access
227: .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatGetSubMatrices(), MatGetDiagonal()
228: @*/
229: PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
230: {
232: PetscInt incols;
237: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
238: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
239: if (!mat->ops->getrow) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
240: MatPreallocated(mat);
241: PetscLogEventBegin(MAT_GetRow,mat,0,0,0);
242: (*mat->ops->getrow)(mat,row,&incols,(PetscInt **)cols,(PetscScalar **)vals);
243: if (ncols) *ncols = incols;
244: PetscLogEventEnd(MAT_GetRow,mat,0,0,0);
245: return(0);
246: }
250: /*@
251: MatConjugate - replaces the matrix values with their complex conjugates
253: Collective on Mat
255: Input Parameters:
256: . mat - the matrix
258: Level: advanced
260: .seealso: VecConjugate()
261: @*/
262: PetscErrorCode MatConjugate(Mat mat)
263: {
268: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
269: if (!mat->ops->conjugate) SETERRQ(PETSC_ERR_SUP,"Not provided for this matrix format, send email to petsc-maint@mcs.anl.gov");
270: (*mat->ops->conjugate)(mat);
271: return(0);
272: }
276: /*@C
277: MatRestoreRow - Frees any temporary space allocated by MatGetRow().
279: Not Collective
281: Input Parameters:
282: + mat - the matrix
283: . row - the row to get
284: . ncols, cols - the number of nonzeros and their columns
285: - vals - if nonzero the column values
287: Notes:
288: This routine should be called after you have finished examining the entries.
290: Fortran Notes:
291: The calling sequence from Fortran is
292: .vb
293: MatRestoreRow(matrix,row,ncols,cols,values,ierr)
294: Mat matrix (input)
295: integer row (input)
296: integer ncols (output)
297: integer cols(maxcols) (output)
298: double precision (or double complex) values(maxcols) output
299: .ve
300: Where maxcols >= maximum nonzeros in any row of the matrix.
302: In Fortran MatRestoreRow() MUST be called after MatGetRow()
303: before another call to MatGetRow() can be made.
305: Level: advanced
307: .seealso: MatGetRow()
308: @*/
309: PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
310: {
316: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
317: if (!mat->ops->restorerow) return(0);
318: (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);
319: return(0);
320: }
324: /*@
325: MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format.
326: You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag.
328: Not Collective
330: Input Parameters:
331: + mat - the matrix
333: Notes:
334: 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.
336: Level: advanced
338: Concepts: matrices^row access
340: .seealso: MatRestoreRowRowUpperTriangular()
341: @*/
342: PetscErrorCode MatGetRowUpperTriangular(Mat mat)
343: {
349: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
350: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
351: if (!mat->ops->getrowuppertriangular) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
352: MatPreallocated(mat);
353: (*mat->ops->getrowuppertriangular)(mat);
354: return(0);
355: }
359: /*@
360: MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format.
362: Not Collective
364: Input Parameters:
365: + mat - the matrix
367: Notes:
368: This routine should be called after you have finished MatGetRow/MatRestoreRow().
371: Level: advanced
373: .seealso: MatGetRowUpperTriangular()
374: @*/
375: PetscErrorCode MatRestoreRowUpperTriangular(Mat mat)
376: {
381: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
382: if (!mat->ops->restorerowuppertriangular) return(0);
383: (*mat->ops->restorerowuppertriangular)(mat);
384: return(0);
385: }
389: /*@C
390: MatSetOptionsPrefix - Sets the prefix used for searching for all
391: Mat options in the database.
393: Collective on Mat
395: Input Parameter:
396: + A - the Mat context
397: - prefix - the prefix to prepend to all option names
399: Notes:
400: A hyphen (-) must NOT be given at the beginning of the prefix name.
401: The first character of all runtime options is AUTOMATICALLY the hyphen.
403: Level: advanced
405: .keywords: Mat, set, options, prefix, database
407: .seealso: MatSetFromOptions()
408: @*/
409: PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[])
410: {
415: PetscObjectSetOptionsPrefix((PetscObject)A,prefix);
416: return(0);
417: }
421: /*@C
422: MatAppendOptionsPrefix - Appends to the prefix used for searching for all
423: Mat options in the database.
425: Collective on Mat
427: Input Parameters:
428: + A - the Mat context
429: - prefix - the prefix to prepend to all option names
431: Notes:
432: A hyphen (-) must NOT be given at the beginning of the prefix name.
433: The first character of all runtime options is AUTOMATICALLY the hyphen.
435: Level: advanced
437: .keywords: Mat, append, options, prefix, database
439: .seealso: MatGetOptionsPrefix()
440: @*/
441: PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[])
442: {
444:
447: PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);
448: return(0);
449: }
453: /*@C
454: MatGetOptionsPrefix - Sets the prefix used for searching for all
455: Mat options in the database.
457: Not Collective
459: Input Parameter:
460: . A - the Mat context
462: Output Parameter:
463: . prefix - pointer to the prefix string used
465: Notes: On the fortran side, the user should pass in a string 'prefix' of
466: sufficient length to hold the prefix.
468: Level: advanced
470: .keywords: Mat, get, options, prefix, database
472: .seealso: MatAppendOptionsPrefix()
473: @*/
474: PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[])
475: {
480: PetscObjectGetOptionsPrefix((PetscObject)A,prefix);
481: return(0);
482: }
486: /*@
487: MatSetUp - Sets up the internal matrix data structures for the later use.
489: Collective on Mat
491: Input Parameters:
492: . A - the Mat context
494: Notes:
495: For basic use of the Mat classes the user need not explicitly call
496: MatSetUp(), since these actions will happen automatically.
498: Level: advanced
500: .keywords: Mat, setup
502: .seealso: MatCreate(), MatDestroy()
503: @*/
504: PetscErrorCode MatSetUp(Mat A)
505: {
506: PetscMPIInt size;
511: if (!((PetscObject)A)->type_name) {
512: MPI_Comm_size(((PetscObject)A)->comm, &size);
513: if (size == 1) {
514: MatSetType(A, MATSEQAIJ);
515: } else {
516: MatSetType(A, MATMPIAIJ);
517: }
518: }
519: MatSetUpPreallocation(A);
520: return(0);
521: }
525: /*@C
526: MatView - Visualizes a matrix object.
528: Collective on Mat
530: Input Parameters:
531: + mat - the matrix
532: - viewer - visualization context
534: Notes:
535: The available visualization contexts include
536: + PETSC_VIEWER_STDOUT_SELF - standard output (default)
537: . PETSC_VIEWER_STDOUT_WORLD - synchronized standard
538: output where only the first processor opens
539: the file. All other processors send their
540: data to the first processor to print.
541: - PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure
543: The user can open alternative visualization contexts with
544: + PetscViewerASCIIOpen() - Outputs matrix to a specified file
545: . PetscViewerBinaryOpen() - Outputs matrix in binary to a
546: specified file; corresponding input uses MatLoad()
547: . PetscViewerDrawOpen() - Outputs nonzero matrix structure to
548: an X window display
549: - PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
550: Currently only the sequential dense and AIJ
551: matrix types support the Socket viewer.
553: The user can call PetscViewerSetFormat() to specify the output
554: format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
555: PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen). Available formats include
556: + PETSC_VIEWER_DEFAULT - default, prints matrix contents
557: . PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
558: . PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
559: . PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse
560: format common among all matrix types
561: . PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific
562: format (which is in many cases the same as the default)
563: . PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
564: size and structure (not the matrix entries)
565: . PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about
566: the matrix structure
568: Options Database Keys:
569: + -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly()
570: . -mat_view_info_detailed - Prints more detailed info
571: . -mat_view - Prints matrix in ASCII format
572: . -mat_view_matlab - Prints matrix in Matlab format
573: . -mat_view_draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
574: . -display <name> - Sets display name (default is host)
575: . -draw_pause <sec> - Sets number of seconds to pause after display
576: . -mat_view_socket - Sends matrix to socket, can be accessed from Matlab (see users manual)
577: . -viewer_socket_machine <machine>
578: . -viewer_socket_port <port>
579: . -mat_view_binary - save matrix to file in binary format
580: - -viewer_binary_filename <name>
581: Level: beginner
583: Notes: see the manual page for MatLoad() for the exact format of the binary file when the binary
584: viewer is used.
586: See bin/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary
587: viewer is used.
589: Concepts: matrices^viewing
590: Concepts: matrices^plotting
591: Concepts: matrices^printing
593: .seealso: PetscViewerSetFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(),
594: PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
595: @*/
596: PetscErrorCode MatView(Mat mat,PetscViewer viewer)
597: {
598: PetscErrorCode ierr;
599: PetscInt rows,cols;
600: PetscTruth iascii;
601: const MatType cstr;
602: PetscViewerFormat format;
607: if (!viewer) {
608: PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
609: }
612: if (!mat->assembled) SETERRQ(PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
613: MatPreallocated(mat);
615: PetscLogEventBegin(MAT_View,mat,viewer,0,0);
616: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
617: if (iascii) {
618: PetscViewerGetFormat(viewer,&format);
619: if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
620: if (((PetscObject)mat)->prefix) {
621: PetscViewerASCIIPrintf(viewer,"Matrix Object:(%s)\n",((PetscObject)mat)->prefix);
622: } else {
623: PetscViewerASCIIPrintf(viewer,"Matrix Object:\n");
624: }
625: PetscViewerASCIIPushTab(viewer);
626: MatGetType(mat,&cstr);
627: MatGetSize(mat,&rows,&cols);
628: PetscViewerASCIIPrintf(viewer,"type=%s, rows=%D, cols=%D\n",cstr,rows,cols);
629: if (mat->factor) {
630: const MatSolverPackage solver;
631: MatFactorGetSolverPackage(mat,&solver);
632: PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);
633: }
634: if (mat->ops->getinfo) {
635: MatInfo info;
636: MatGetInfo(mat,MAT_GLOBAL_SUM,&info);
637: PetscViewerASCIIPrintf(viewer,"total: nonzeros=%D, allocated nonzeros=%D\n",(PetscInt)info.nz_used,(PetscInt)info.nz_allocated);
638: }
639: }
640: }
641: if (mat->ops->view) {
642: PetscViewerASCIIPushTab(viewer);
643: (*mat->ops->view)(mat,viewer);
644: PetscViewerASCIIPopTab(viewer);
645: } else if (!iascii) {
646: SETERRQ1(PETSC_ERR_SUP,"Viewer type %s not supported",((PetscObject)viewer)->type_name);
647: }
648: if (iascii) {
649: PetscViewerGetFormat(viewer,&format);
650: if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
651: PetscViewerASCIIPopTab(viewer);
652: }
653: }
654: PetscLogEventEnd(MAT_View,mat,viewer,0,0);
655: return(0);
656: }
660: /*@
661: MatScaleSystem - Scale a vector solution and right hand side to
662: match the scaling of a scaled matrix.
663:
664: Collective on Mat
666: Input Parameter:
667: + mat - the matrix
668: . b - right hand side vector (or PETSC_NULL)
669: - x - solution vector (or PETSC_NULL)
672: Notes:
673: For AIJ, and BAIJ matrix formats, the matrices are not
674: internally scaled, so this does nothing. For MPIROWBS it
675: permutes and diagonally scales.
677: The KSP methods automatically call this routine when required
678: (via PCPreSolve()) so it is rarely used directly.
680: Level: Developer
682: Concepts: matrices^scaling
684: .seealso: MatUseScaledForm(), MatUnScaleSystem()
685: @*/
686: PetscErrorCode MatScaleSystem(Mat mat,Vec b,Vec x)
687: {
693: MatPreallocated(mat);
697: if (mat->ops->scalesystem) {
698: (*mat->ops->scalesystem)(mat,b,x);
699: }
700: return(0);
701: }
705: /*@
706: MatUnScaleSystem - Unscales a vector solution and right hand side to
707: match the original scaling of a scaled matrix.
708:
709: Collective on Mat
711: Input Parameter:
712: + mat - the matrix
713: . b - right hand side vector (or PETSC_NULL)
714: - x - solution vector (or PETSC_NULL)
717: Notes:
718: For AIJ and BAIJ matrix formats, the matrices are not
719: internally scaled, so this does nothing. For MPIROWBS it
720: permutes and diagonally scales.
722: The KSP methods automatically call this routine when required
723: (via PCPreSolve()) so it is rarely used directly.
725: Level: Developer
727: .seealso: MatUseScaledForm(), MatScaleSystem()
728: @*/
729: PetscErrorCode MatUnScaleSystem(Mat mat,Vec b,Vec x)
730: {
736: MatPreallocated(mat);
739: if (mat->ops->unscalesystem) {
740: (*mat->ops->unscalesystem)(mat,b,x);
741: }
742: return(0);
743: }
747: /*@
748: MatUseScaledForm - For matrix storage formats that scale the
749: matrix (for example MPIRowBS matrices are diagonally scaled on
750: assembly) indicates matrix operations (MatMult() etc) are
751: applied using the scaled matrix.
752:
753: Collective on Mat
755: Input Parameter:
756: + mat - the matrix
757: - scaled - PETSC_TRUE for applying the scaled, PETSC_FALSE for
758: applying the original matrix
760: Notes:
761: For scaled matrix formats, applying the original, unscaled matrix
762: will be slightly more expensive
764: Level: Developer
766: .seealso: MatScaleSystem(), MatUnScaleSystem()
767: @*/
768: PetscErrorCode MatUseScaledForm(Mat mat,PetscTruth scaled)
769: {
775: MatPreallocated(mat);
776: if (mat->ops->usescaledform) {
777: (*mat->ops->usescaledform)(mat,scaled);
778: }
779: return(0);
780: }
784: /*@
785: MatDestroy - Frees space taken by a matrix.
786:
787: Collective on Mat
789: Input Parameter:
790: . A - the matrix
792: Level: beginner
794: @*/
795: PetscErrorCode MatDestroy(Mat A)
796: {
800: if (--((PetscObject)A)->refct > 0) return(0);
801: MatPreallocated(A);
802: /* if memory was published with AMS then destroy it */
803: PetscObjectDepublish(A);
804: if (A->ops->destroy) {
805: (*A->ops->destroy)(A);
806: }
807: if (A->mapping) {
808: ISLocalToGlobalMappingDestroy(A->mapping);
809: }
810: if (A->bmapping) {
811: ISLocalToGlobalMappingDestroy(A->bmapping);
812: }
814: if (A->spptr){PetscFree(A->spptr);}
815: PetscMapDestroy(A->rmap);
816: PetscMapDestroy(A->cmap);
817: PetscHeaderDestroy(A);
818: return(0);
819: }
823: /*@
824: MatValid - Checks whether a matrix object is valid.
826: Collective on Mat
828: Input Parameter:
829: . m - the matrix to check
831: Output Parameter:
832: flg - flag indicating matrix status, either
833: PETSC_TRUE if matrix is valid, or PETSC_FALSE otherwise.
835: Level: developer
837: Concepts: matrices^validity
838: @*/
839: PetscErrorCode MatValid(Mat m,PetscTruth *flg)
840: {
843: if (!m) *flg = PETSC_FALSE;
844: else if (((PetscObject)m)->cookie != MAT_COOKIE) *flg = PETSC_FALSE;
845: else *flg = PETSC_TRUE;
846: return(0);
847: }
851: /*@
852: MatSetValues - Inserts or adds a block of values into a matrix.
853: These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
854: MUST be called after all calls to MatSetValues() have been completed.
856: Not Collective
858: Input Parameters:
859: + mat - the matrix
860: . v - a logically two-dimensional array of values
861: . m, idxm - the number of rows and their global indices
862: . n, idxn - the number of columns and their global indices
863: - addv - either ADD_VALUES or INSERT_VALUES, where
864: ADD_VALUES adds values to any existing entries, and
865: INSERT_VALUES replaces existing entries with new values
867: Notes:
868: By default the values, v, are row-oriented and unsorted.
869: See MatSetOption() for other options.
871: Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
872: options cannot be mixed without intervening calls to the assembly
873: routines.
875: MatSetValues() uses 0-based row and column numbers in Fortran
876: as well as in C.
878: Negative indices may be passed in idxm and idxn, these rows and columns are
879: simply ignored. This allows easily inserting element stiffness matrices
880: with homogeneous Dirchlet boundary conditions that you don't want represented
881: in the matrix.
883: Efficiency Alert:
884: The routine MatSetValuesBlocked() may offer much better efficiency
885: for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
887: Level: beginner
889: Concepts: matrices^putting entries in
891: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
892: InsertMode, INSERT_VALUES, ADD_VALUES
893: @*/
894: PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
895: {
901: if (!m || !n) return(0); /* no values to insert */
904: MatPreallocated(mat);
905: if (mat->insertmode == NOT_SET_VALUES) {
906: mat->insertmode = addv;
907: }
908: #if defined(PETSC_USE_DEBUG)
909: else if (mat->insertmode != addv) {
910: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
911: }
912: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
913: #endif
915: if (mat->assembled) {
916: mat->was_assembled = PETSC_TRUE;
917: mat->assembled = PETSC_FALSE;
918: }
919: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
920: if (!mat->ops->setvalues) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
921: (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);
922: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
923: return(0);
924: }
929: /*@
930: MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
931: values into a matrix
933: Not Collective
935: Input Parameters:
936: + mat - the matrix
937: . row - the (block) row to set
938: - v - a logically two-dimensional array of values
940: Notes:
941: By the values, v, are column-oriented (for the block version) and sorted
943: All the nonzeros in the row must be provided
945: The matrix must have previously had its column indices set
947: The row must belong to this process
949: Level: intermediate
951: Concepts: matrices^putting entries in
953: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
954: InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping()
955: @*/
956: PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
957: {
964: MatSetValuesRow(mat, mat->mapping->indices[row],v);
965: return(0);
966: }
970: /*@
971: MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
972: values into a matrix
974: Not Collective
976: Input Parameters:
977: + mat - the matrix
978: . row - the (block) row to set
979: - v - a logically two-dimensional array of values
981: Notes:
982: By the values, v, are column-oriented (for the block version) and sorted
984: All the nonzeros in the row must be provided
986: The matrix must have previously had its column indices set
988: The row must belong to this process
990: Level: intermediate
992: Concepts: matrices^putting entries in
994: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
995: InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
996: @*/
997: PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
998: {
1005: #if defined(PETSC_USE_DEBUG)
1006: if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
1007: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1008: #endif
1009: mat->insertmode = INSERT_VALUES;
1011: if (mat->assembled) {
1012: mat->was_assembled = PETSC_TRUE;
1013: mat->assembled = PETSC_FALSE;
1014: }
1015: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1016: if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1017: (*mat->ops->setvaluesrow)(mat,row,v);
1018: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1019: return(0);
1020: }
1024: /*@
1025: MatSetValuesStencil - Inserts or adds a block of values into a matrix.
1026: Using structured grid indexing
1028: Not Collective
1030: Input Parameters:
1031: + mat - the matrix
1032: . v - a logically two-dimensional array of values
1033: . m - number of rows being entered
1034: . idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
1035: . n - number of columns being entered
1036: . idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered
1037: - addv - either ADD_VALUES or INSERT_VALUES, where
1038: ADD_VALUES adds values to any existing entries, and
1039: INSERT_VALUES replaces existing entries with new values
1041: Notes:
1042: By default the values, v, are row-oriented and unsorted.
1043: See MatSetOption() for other options.
1045: Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
1046: options cannot be mixed without intervening calls to the assembly
1047: routines.
1049: The grid coordinates are across the entire grid, not just the local portion
1051: MatSetValuesStencil() uses 0-based row and column numbers in Fortran
1052: as well as in C.
1054: For setting/accessing vector values via array coordinates you can use the DAVecGetArray() routine
1056: In order to use this routine you must either obtain the matrix with DAGetMatrix()
1057: or call MatSetLocalToGlobalMapping() and MatSetStencil() first.
1059: The columns and rows in the stencil passed in MUST be contained within the
1060: ghost region of the given process as set with DACreateXXX() or MatSetStencil(). For example,
1061: if you create a DA with an overlap of one grid level and on a particular process its first
1062: local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1063: first i index you can use in your column and row indices in MatSetStencil() is 5.
1065: In Fortran idxm and idxn should be declared as
1066: $ MatStencil idxm(4,m),idxn(4,n)
1067: and the values inserted using
1068: $ idxm(MatStencil_i,1) = i
1069: $ idxm(MatStencil_j,1) = j
1070: $ idxm(MatStencil_k,1) = k
1071: $ idxm(MatStencil_c,1) = c
1072: etc
1074: For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
1075: obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
1076: etc to obtain values that obtained by wrapping the values from the left edge.
1078: 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
1079: a single value per point) you can skip filling those indices.
1081: Inspired by the structured grid interface to the HYPRE package
1082: (http://www.llnl.gov/CASC/hypre)
1084: Efficiency Alert:
1085: The routine MatSetValuesBlockedStencil() may offer much better efficiency
1086: for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1088: Level: beginner
1090: Concepts: matrices^putting entries in
1092: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1093: MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DAGetMatrix(), DAVecGetArray(), MatStencil
1094: @*/
1095: PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1096: {
1098: PetscInt j,i,jdxm[128],jdxn[256],dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1099: PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1102: if (!m || !n) return(0); /* no values to insert */
1109: if (m > 128) SETERRQ1(PETSC_ERR_SUP,"Can only set 128 rows at a time; trying to set %D",m);
1110: if (n > 256) SETERRQ1(PETSC_ERR_SUP,"Can only set 256 columns at a time; trying to set %D",n);
1112: for (i=0; i<m; i++) {
1113: for (j=0; j<3-sdim; j++) dxm++;
1114: tmp = *dxm++ - starts[0];
1115: for (j=0; j<dim-1; j++) {
1116: if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1117: else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1118: }
1119: if (mat->stencil.noc) dxm++;
1120: jdxm[i] = tmp;
1121: }
1122: for (i=0; i<n; i++) {
1123: for (j=0; j<3-sdim; j++) dxn++;
1124: tmp = *dxn++ - starts[0];
1125: for (j=0; j<dim-1; j++) {
1126: if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1127: else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1128: }
1129: if (mat->stencil.noc) dxn++;
1130: jdxn[i] = tmp;
1131: }
1132: MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);
1133: return(0);
1134: }
1138: /*@C
1139: MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1140: Using structured grid indexing
1142: Not Collective
1144: Input Parameters:
1145: + mat - the matrix
1146: . v - a logically two-dimensional array of values
1147: . m - number of rows being entered
1148: . idxm - grid coordinates for matrix rows being entered
1149: . n - number of columns being entered
1150: . idxn - grid coordinates for matrix columns being entered
1151: - addv - either ADD_VALUES or INSERT_VALUES, where
1152: ADD_VALUES adds values to any existing entries, and
1153: INSERT_VALUES replaces existing entries with new values
1155: Notes:
1156: By default the values, v, are row-oriented and unsorted.
1157: See MatSetOption() for other options.
1159: Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
1160: options cannot be mixed without intervening calls to the assembly
1161: routines.
1163: The grid coordinates are across the entire grid, not just the local portion
1165: MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran
1166: as well as in C.
1168: For setting/accessing vector values via array coordinates you can use the DAVecGetArray() routine
1170: In order to use this routine you must either obtain the matrix with DAGetMatrix()
1171: or call MatSetLocalToGlobalMapping() and MatSetStencil() first.
1173: The columns and rows in the stencil passed in MUST be contained within the
1174: ghost region of the given process as set with DACreateXXX() or MatSetStencil(). For example,
1175: if you create a DA with an overlap of one grid level and on a particular process its first
1176: local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1177: first i index you can use in your column and row indices in MatSetStencil() is 5.
1179: In Fortran idxm and idxn should be declared as
1180: $ MatStencil idxm(4,m),idxn(4,n)
1181: and the values inserted using
1182: $ idxm(MatStencil_i,1) = i
1183: $ idxm(MatStencil_j,1) = j
1184: $ idxm(MatStencil_k,1) = k
1185: etc
1187: Negative indices may be passed in idxm and idxn, these rows and columns are
1188: simply ignored. This allows easily inserting element stiffness matrices
1189: with homogeneous Dirchlet boundary conditions that you don't want represented
1190: in the matrix.
1192: Inspired by the structured grid interface to the HYPRE package
1193: (http://www.llnl.gov/CASC/hypre)
1195: Level: beginner
1197: Concepts: matrices^putting entries in
1199: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1200: MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DAGetMatrix(), DAVecGetArray(), MatStencil
1201: @*/
1202: PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1203: {
1205: PetscInt j,i,jdxm[128],jdxn[256],dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1206: PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1209: if (!m || !n) return(0); /* no values to insert */
1216: if (m > 128) SETERRQ1(PETSC_ERR_SUP,"Can only set 128 rows at a time; trying to set %D",m);
1217: if (n > 128) SETERRQ1(PETSC_ERR_SUP,"Can only set 256 columns at a time; trying to set %D",n);
1219: for (i=0; i<m; i++) {
1220: for (j=0; j<3-sdim; j++) dxm++;
1221: tmp = *dxm++ - starts[0];
1222: for (j=0; j<sdim-1; j++) {
1223: if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1224: else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1225: }
1226: dxm++;
1227: jdxm[i] = tmp;
1228: }
1229: for (i=0; i<n; i++) {
1230: for (j=0; j<3-sdim; j++) dxn++;
1231: tmp = *dxn++ - starts[0];
1232: for (j=0; j<sdim-1; j++) {
1233: if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1234: else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1235: }
1236: dxn++;
1237: jdxn[i] = tmp;
1238: }
1239: MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);
1240: return(0);
1241: }
1245: /*@
1246: MatSetStencil - Sets the grid information for setting values into a matrix via
1247: MatSetValuesStencil()
1249: Not Collective
1251: Input Parameters:
1252: + mat - the matrix
1253: . dim - dimension of the grid 1, 2, or 3
1254: . dims - number of grid points in x, y, and z direction, including ghost points on your processor
1255: . starts - starting point of ghost nodes on your processor in x, y, and z direction
1256: - dof - number of degrees of freedom per node
1259: Inspired by the structured grid interface to the HYPRE package
1260: (www.llnl.gov/CASC/hyper)
1262: For matrices generated with DAGetMatrix() this routine is automatically called and so not needed by the
1263: user.
1264:
1265: Level: beginner
1267: Concepts: matrices^putting entries in
1269: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1270: MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
1271: @*/
1272: PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1273: {
1274: PetscInt i;
1281: mat->stencil.dim = dim + (dof > 1);
1282: for (i=0; i<dim; i++) {
1283: mat->stencil.dims[i] = dims[dim-i-1]; /* copy the values in backwards */
1284: mat->stencil.starts[i] = starts[dim-i-1];
1285: }
1286: mat->stencil.dims[dim] = dof;
1287: mat->stencil.starts[dim] = 0;
1288: mat->stencil.noc = (PetscTruth)(dof == 1);
1289: return(0);
1290: }
1294: /*@
1295: MatSetValuesBlocked - Inserts or adds a block of values into a matrix.
1297: Not Collective
1299: Input Parameters:
1300: + mat - the matrix
1301: . v - a logically two-dimensional array of values
1302: . m, idxm - the number of block rows and their global block indices
1303: . n, idxn - the number of block columns and their global block indices
1304: - addv - either ADD_VALUES or INSERT_VALUES, where
1305: ADD_VALUES adds values to any existing entries, and
1306: INSERT_VALUES replaces existing entries with new values
1308: Notes:
1309: The m and n count the NUMBER of blocks in the row direction and column direction,
1310: NOT the total number of rows/columns; for example, if the block size is 2 and
1311: you are passing in values for rows 2,3,4,5 then m would be 2 (not 4).
1312: The values in idxm would be 1 2; that is the first index for each block divided by
1313: the block size.
1315: By default the values, v, are row-oriented and unsorted. So the layout of
1316: v is the same as for MatSetValues(). See MatSetOption() for other options.
1318: Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
1319: options cannot be mixed without intervening calls to the assembly
1320: routines.
1322: MatSetValuesBlocked() uses 0-based row and column numbers in Fortran
1323: as well as in C.
1325: Negative indices may be passed in idxm and idxn, these rows and columns are
1326: simply ignored. This allows easily inserting element stiffness matrices
1327: with homogeneous Dirchlet boundary conditions that you don't want represented
1328: in the matrix.
1330: Each time an entry is set within a sparse matrix via MatSetValues(),
1331: internal searching must be done to determine where to place the the
1332: data in the matrix storage space. By instead inserting blocks of
1333: entries via MatSetValuesBlocked(), the overhead of matrix assembly is
1334: reduced.
1336: Example:
1337: $ Suppose m=n=2 and block size(bs) = 2 The array is
1338: $
1339: $ 1 2 | 3 4
1340: $ 5 6 | 7 8
1341: $ - - - | - - -
1342: $ 9 10 | 11 12
1343: $ 13 14 | 15 16
1344: $
1345: $ v[] should be passed in like
1346: $ v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
1347: $
1348: $ If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then
1349: $ v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16]
1351: Level: intermediate
1353: Concepts: matrices^putting entries in blocked
1355: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal()
1356: @*/
1357: PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1358: {
1364: if (!m || !n) return(0); /* no values to insert */
1368: MatPreallocated(mat);
1369: if (mat->insertmode == NOT_SET_VALUES) {
1370: mat->insertmode = addv;
1371: }
1372: #if defined(PETSC_USE_DEBUG)
1373: else if (mat->insertmode != addv) {
1374: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1375: }
1376: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1377: #endif
1379: if (mat->assembled) {
1380: mat->was_assembled = PETSC_TRUE;
1381: mat->assembled = PETSC_FALSE;
1382: }
1383: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1384: if (mat->ops->setvaluesblocked) {
1385: (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);
1386: } else {
1387: PetscInt buf[4096],*ibufm=0,*ibufn=0;
1388: PetscInt i,j,*iidxm,*iidxn,bs=mat->rmap->bs;
1389: if ((m+n)*bs <= 4096) {
1390: iidxm = buf; iidxn = buf + m*bs;
1391: } else {
1392: PetscMalloc2(m*bs,PetscInt,&ibufm,n*bs,PetscInt,&ibufn);
1393: iidxm = ibufm; iidxn = ibufn;
1394: }
1395: for (i=0; i<m; i++) {
1396: for (j=0; j<bs; j++) {
1397: iidxm[i*bs+j] = bs*idxm[i] + j;
1398: }
1399: }
1400: for (i=0; i<n; i++) {
1401: for (j=0; j<bs; j++) {
1402: iidxn[i*bs+j] = bs*idxn[i] + j;
1403: }
1404: }
1405: MatSetValues(mat,bs*m,iidxm,bs*n,iidxn,v,addv);
1406: PetscFree2(ibufm,ibufn);
1407: }
1408: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1409: return(0);
1410: }
1414: /*@
1415: MatGetValues - Gets a block of values from a matrix.
1417: Not Collective; currently only returns a local block
1419: Input Parameters:
1420: + mat - the matrix
1421: . v - a logically two-dimensional array for storing the values
1422: . m, idxm - the number of rows and their global indices
1423: - n, idxn - the number of columns and their global indices
1425: Notes:
1426: The user must allocate space (m*n PetscScalars) for the values, v.
1427: The values, v, are then returned in a row-oriented format,
1428: analogous to that used by default in MatSetValues().
1430: MatGetValues() uses 0-based row and column numbers in
1431: Fortran as well as in C.
1433: MatGetValues() requires that the matrix has been assembled
1434: with MatAssemblyBegin()/MatAssemblyEnd(). Thus, calls to
1435: MatSetValues() and MatGetValues() CANNOT be made in succession
1436: without intermediate matrix assembly.
1438: Negative row or column indices will be ignored and those locations in v[] will be
1439: left unchanged.
1441: Level: advanced
1443: Concepts: matrices^accessing values
1445: .seealso: MatGetRow(), MatGetSubMatrices(), MatSetValues()
1446: @*/
1447: PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1448: {
1457: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1458: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1459: if (!mat->ops->getvalues) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1460: MatPreallocated(mat);
1462: PetscLogEventBegin(MAT_GetValues,mat,0,0,0);
1463: (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);
1464: PetscLogEventEnd(MAT_GetValues,mat,0,0,0);
1465: return(0);
1466: }
1470: /*@
1471: MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
1472: the routine MatSetValuesLocal() to allow users to insert matrix entries
1473: using a local (per-processor) numbering.
1475: Not Collective
1477: Input Parameters:
1478: + x - the matrix
1479: - mapping - mapping created with ISLocalToGlobalMappingCreate()
1480: or ISLocalToGlobalMappingCreateIS()
1482: Level: intermediate
1484: Concepts: matrices^local to global mapping
1485: Concepts: local to global mapping^for matrices
1487: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
1488: @*/
1489: PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping mapping)
1490: {
1496: if (x->mapping) {
1497: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Mapping already set for matrix");
1498: }
1499: MatPreallocated(x);
1501: if (x->ops->setlocaltoglobalmapping) {
1502: (*x->ops->setlocaltoglobalmapping)(x,mapping);
1503: } else {
1504: PetscObjectReference((PetscObject)mapping);
1505: if (x->mapping) { ISLocalToGlobalMappingDestroy(x->mapping); }
1506: x->mapping = mapping;
1507: }
1508: return(0);
1509: }
1513: /*@
1514: MatSetLocalToGlobalMappingBlock - Sets a local-to-global numbering for use
1515: by the routine MatSetValuesBlockedLocal() to allow users to insert matrix
1516: entries using a local (per-processor) numbering.
1518: Not Collective
1520: Input Parameters:
1521: + x - the matrix
1522: - mapping - mapping created with ISLocalToGlobalMappingCreate() or
1523: ISLocalToGlobalMappingCreateIS()
1525: Level: intermediate
1527: Concepts: matrices^local to global mapping blocked
1528: Concepts: local to global mapping^for matrices, blocked
1530: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal(),
1531: MatSetValuesBlocked(), MatSetValuesLocal()
1532: @*/
1533: PetscErrorCode MatSetLocalToGlobalMappingBlock(Mat x,ISLocalToGlobalMapping mapping)
1534: {
1540: if (x->bmapping) {
1541: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Mapping already set for matrix");
1542: }
1543: PetscObjectReference((PetscObject)mapping);
1544: if (x->bmapping) { ISLocalToGlobalMappingDestroy(x->mapping); }
1545: x->bmapping = mapping;
1546: return(0);
1547: }
1551: /*@
1552: MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
1553: using a local ordering of the nodes.
1555: Not Collective
1557: Input Parameters:
1558: + x - the matrix
1559: . nrow, irow - number of rows and their local indices
1560: . ncol, icol - number of columns and their local indices
1561: . y - a logically two-dimensional array of values
1562: - addv - either INSERT_VALUES or ADD_VALUES, where
1563: ADD_VALUES adds values to any existing entries, and
1564: INSERT_VALUES replaces existing entries with new values
1566: Notes:
1567: Before calling MatSetValuesLocal(), the user must first set the
1568: local-to-global mapping by calling MatSetLocalToGlobalMapping().
1570: Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
1571: options cannot be mixed without intervening calls to the assembly
1572: routines.
1574: These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1575: MUST be called after all calls to MatSetValuesLocal() have been completed.
1577: Level: intermediate
1579: Concepts: matrices^putting entries in with local numbering
1581: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
1582: MatSetValueLocal()
1583: @*/
1584: PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
1585: {
1587: PetscInt irowm[2048],icolm[2048];
1592: if (!nrow || !ncol) return(0); /* no values to insert */
1596: MatPreallocated(mat);
1597: if (mat->insertmode == NOT_SET_VALUES) {
1598: mat->insertmode = addv;
1599: }
1600: #if defined(PETSC_USE_DEBUG)
1601: else if (mat->insertmode != addv) {
1602: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1603: }
1604: if (!mat->ops->setvalueslocal && (nrow > 2048 || ncol > 2048)) {
1605: SETERRQ2(PETSC_ERR_SUP,"Number column/row indices must be <= 2048: are %D %D",nrow,ncol);
1606: }
1607: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1608: #endif
1610: if (mat->assembled) {
1611: mat->was_assembled = PETSC_TRUE;
1612: mat->assembled = PETSC_FALSE;
1613: }
1614: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1615: if (!mat->ops->setvalueslocal) {
1616: ISLocalToGlobalMappingApply(mat->mapping,nrow,irow,irowm);
1617: ISLocalToGlobalMappingApply(mat->mapping,ncol,icol,icolm);
1618: (*mat->ops->setvalues)(mat,nrow,irowm,ncol,icolm,y,addv);
1619: } else {
1620: (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);
1621: }
1622: mat->same_nonzero = PETSC_FALSE;
1623: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1624: return(0);
1625: }
1629: /*@
1630: MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix,
1631: using a local ordering of the nodes a block at a time.
1633: Not Collective
1635: Input Parameters:
1636: + x - the matrix
1637: . nrow, irow - number of rows and their local indices
1638: . ncol, icol - number of columns and their local indices
1639: . y - a logically two-dimensional array of values
1640: - addv - either INSERT_VALUES or ADD_VALUES, where
1641: ADD_VALUES adds values to any existing entries, and
1642: INSERT_VALUES replaces existing entries with new values
1644: Notes:
1645: Before calling MatSetValuesBlockedLocal(), the user must first set the
1646: local-to-global mapping by calling MatSetLocalToGlobalMappingBlock(),
1647: where the mapping MUST be set for matrix blocks, not for matrix elements.
1649: Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
1650: options cannot be mixed without intervening calls to the assembly
1651: routines.
1653: These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1654: MUST be called after all calls to MatSetValuesBlockedLocal() have been completed.
1656: Level: intermediate
1658: Concepts: matrices^putting blocked values in with local numbering
1660: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesLocal(), MatSetLocalToGlobalMappingBlock(), MatSetValuesBlocked()
1661: @*/
1662: PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
1663: {
1665: PetscInt irowm[2048],icolm[2048];
1670: if (!nrow || !ncol) return(0); /* no values to insert */
1674: MatPreallocated(mat);
1675: if (mat->insertmode == NOT_SET_VALUES) {
1676: mat->insertmode = addv;
1677: }
1678: #if defined(PETSC_USE_DEBUG)
1679: else if (mat->insertmode != addv) {
1680: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1681: }
1682: if (!mat->bmapping) {
1683: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Local to global never set with MatSetLocalToGlobalMappingBlock()");
1684: }
1685: if (nrow > 2048 || ncol > 2048) {
1686: SETERRQ2(PETSC_ERR_SUP,"Number column/row indices must be <= 2048: are %D %D",nrow,ncol);
1687: }
1688: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1689: #endif
1691: if (mat->assembled) {
1692: mat->was_assembled = PETSC_TRUE;
1693: mat->assembled = PETSC_FALSE;
1694: }
1695: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1696: ISLocalToGlobalMappingApply(mat->bmapping,nrow,irow,irowm);
1697: ISLocalToGlobalMappingApply(mat->bmapping,ncol,icol,icolm);
1698: if (mat->ops->setvaluesblocked) {
1699: (*mat->ops->setvaluesblocked)(mat,nrow,irowm,ncol,icolm,y,addv);
1700: } else {
1701: PetscInt buf[4096],*ibufm=0,*ibufn=0;
1702: PetscInt i,j,*iirowm,*iicolm,bs=mat->rmap->bs;
1703: if ((nrow+ncol)*bs <= 4096) {
1704: iirowm = buf; iicolm = buf + nrow*bs;
1705: } else {
1706: PetscMalloc2(nrow*bs,PetscInt,&ibufm,ncol*bs,PetscInt,&ibufn);
1707: iirowm = ibufm; iicolm = ibufn;
1708: }
1709: for (i=0; i<nrow; i++) {
1710: for (j=0; j<bs; j++) {
1711: iirowm[i*bs+j] = bs*irowm[i] + j;
1712: }
1713: }
1714: for (i=0; i<ncol; i++) {
1715: for (j=0; j<bs; j++) {
1716: iicolm[i*bs+j] = bs*icolm[i] + j;
1717: }
1718: }
1719: MatSetValues(mat,bs*nrow,iirowm,bs*ncol,iicolm,y,addv);
1720: PetscFree2(ibufm,ibufn);
1721: }
1722: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1723: return(0);
1724: }
1726: /* --------------------------------------------------------*/
1729: /*@
1730: MatMult - Computes the matrix-vector product, y = Ax.
1732: Collective on Mat and Vec
1734: Input Parameters:
1735: + mat - the matrix
1736: - x - the vector to be multiplied
1738: Output Parameters:
1739: . y - the result
1741: Notes:
1742: The vectors x and y cannot be the same. I.e., one cannot
1743: call MatMult(A,y,y).
1745: Level: beginner
1747: Concepts: matrix-vector product
1749: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
1750: @*/
1751: PetscErrorCode MatMult(Mat mat,Vec x,Vec y)
1752: {
1761: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1762: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1763: if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1764: #ifndef PETSC_HAVE_CONSTRAINTS
1765: 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);
1766: 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);
1767: 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);
1768: #endif
1769: MatPreallocated(mat);
1771: if (mat->nullsp) {
1772: MatNullSpaceRemove(mat->nullsp,x,&x);
1773: }
1775: if (!mat->ops->mult) SETERRQ(PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
1776: PetscLogEventBegin(MAT_Mult,mat,x,y,0);
1777: (*mat->ops->mult)(mat,x,y);
1778: PetscLogEventEnd(MAT_Mult,mat,x,y,0);
1780: if (mat->nullsp) {
1781: MatNullSpaceRemove(mat->nullsp,y,PETSC_NULL);
1782: }
1783: PetscObjectStateIncrease((PetscObject)y);
1784: return(0);
1785: }
1789: /*@
1790: MatMultTranspose - Computes matrix transpose times a vector.
1792: Collective on Mat and Vec
1794: Input Parameters:
1795: + mat - the matrix
1796: - x - the vector to be multilplied
1798: Output Parameters:
1799: . y - the result
1801: Notes:
1802: The vectors x and y cannot be the same. I.e., one cannot
1803: call MatMultTranspose(A,y,y).
1805: Level: beginner
1807: Concepts: matrix vector product^transpose
1809: .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd()
1810: @*/
1811: PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y)
1812: {
1821: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1822: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1823: if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1824: #ifndef PETSC_HAVE_CONSTRAINTS
1825: 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);
1826: 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);
1827: #endif
1828: MatPreallocated(mat);
1830: if (!mat->ops->multtranspose) SETERRQ(PETSC_ERR_SUP,"This matrix type does not have a multiply tranpose defined");
1831: PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);
1832: (*mat->ops->multtranspose)(mat,x,y);
1833: PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);
1834: PetscObjectStateIncrease((PetscObject)y);
1835: return(0);
1836: }
1840: /*@
1841: MatMultAdd - Computes v3 = v2 + A * v1.
1843: Collective on Mat and Vec
1845: Input Parameters:
1846: + mat - the matrix
1847: - v1, v2 - the vectors
1849: Output Parameters:
1850: . v3 - the result
1852: Notes:
1853: The vectors v1 and v3 cannot be the same. I.e., one cannot
1854: call MatMultAdd(A,v1,v2,v1).
1856: Level: beginner
1858: Concepts: matrix vector product^addition
1860: .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
1861: @*/
1862: PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
1863: {
1873: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1874: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1875: 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);
1876: 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);
1877: 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);
1878: 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);
1879: 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);
1880: if (v1 == v3) SETERRQ(PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
1881: MatPreallocated(mat);
1883: PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);
1884: (*mat->ops->multadd)(mat,v1,v2,v3);
1885: PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);
1886: PetscObjectStateIncrease((PetscObject)v3);
1887: return(0);
1888: }
1892: /*@
1893: MatMultTransposeAdd - Computes v3 = v2 + A' * v1.
1895: Collective on Mat and Vec
1897: Input Parameters:
1898: + mat - the matrix
1899: - v1, v2 - the vectors
1901: Output Parameters:
1902: . v3 - the result
1904: Notes:
1905: The vectors v1 and v3 cannot be the same. I.e., one cannot
1906: call MatMultTransposeAdd(A,v1,v2,v1).
1908: Level: beginner
1910: Concepts: matrix vector product^transpose and addition
1912: .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
1913: @*/
1914: PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
1915: {
1925: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1926: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1927: if (!mat->ops->multtransposeadd) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1928: if (v1 == v3) SETERRQ(PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
1929: 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);
1930: 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);
1931: 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);
1932: MatPreallocated(mat);
1934: PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);
1935: (*mat->ops->multtransposeadd)(mat,v1,v2,v3);
1936: PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);
1937: PetscObjectStateIncrease((PetscObject)v3);
1938: return(0);
1939: }
1943: /*@
1944: MatMultConstrained - The inner multiplication routine for a
1945: constrained matrix P^T A P.
1947: Collective on Mat and Vec
1949: Input Parameters:
1950: + mat - the matrix
1951: - x - the vector to be multilplied
1953: Output Parameters:
1954: . y - the result
1956: Notes:
1957: The vectors x and y cannot be the same. I.e., one cannot
1958: call MatMult(A,y,y).
1960: Level: beginner
1962: .keywords: matrix, multiply, matrix-vector product, constraint
1963: .seealso: MatMult(), MatMultTrans(), MatMultAdd(), MatMultTransAdd()
1964: @*/
1965: PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y)
1966: {
1973: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1974: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1975: if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1976: 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);
1977: 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);
1978: 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);
1980: PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
1981: (*mat->ops->multconstrained)(mat,x,y);
1982: PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
1983: PetscObjectStateIncrease((PetscObject)y);
1985: return(0);
1986: }
1990: /*@
1991: MatMultTransposeConstrained - The inner multiplication routine for a
1992: constrained matrix P^T A^T P.
1994: Collective on Mat and Vec
1996: Input Parameters:
1997: + mat - the matrix
1998: - x - the vector to be multilplied
2000: Output Parameters:
2001: . y - the result
2003: Notes:
2004: The vectors x and y cannot be the same. I.e., one cannot
2005: call MatMult(A,y,y).
2007: Level: beginner
2009: .keywords: matrix, multiply, matrix-vector product, constraint
2010: .seealso: MatMult(), MatMultTrans(), MatMultAdd(), MatMultTransAdd()
2011: @*/
2012: PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2013: {
2020: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2021: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2022: if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2023: 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);
2024: 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);
2026: PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2027: (*mat->ops->multtransposeconstrained)(mat,x,y);
2028: PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2029: PetscObjectStateIncrease((PetscObject)y);
2031: return(0);
2032: }
2033: /* ------------------------------------------------------------*/
2036: /*@
2037: MatGetInfo - Returns information about matrix storage (number of
2038: nonzeros, memory, etc.).
2040: Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used
2041: as the flag
2043: Input Parameters:
2044: . mat - the matrix
2046: Output Parameters:
2047: + flag - flag indicating the type of parameters to be returned
2048: (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2049: MAT_GLOBAL_SUM - sum over all processors)
2050: - info - matrix information context
2052: Notes:
2053: The MatInfo context contains a variety of matrix data, including
2054: number of nonzeros allocated and used, number of mallocs during
2055: matrix assembly, etc. Additional information for factored matrices
2056: is provided (such as the fill ratio, number of mallocs during
2057: factorization, etc.). Much of this info is printed to PETSC_STDOUT
2058: when using the runtime options
2059: $ -info -mat_view_info
2061: Example for C/C++ Users:
2062: See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2063: data within the MatInfo context. For example,
2064: .vb
2065: MatInfo info;
2066: Mat A;
2067: double mal, nz_a, nz_u;
2069: MatGetInfo(A,MAT_LOCAL,&info);
2070: mal = info.mallocs;
2071: nz_a = info.nz_allocated;
2072: .ve
2074: Example for Fortran Users:
2075: Fortran users should declare info as a double precision
2076: array of dimension MAT_INFO_SIZE, and then extract the parameters
2077: of interest. See the file ${PETSC_DIR}/include/finclude/petscmat.h
2078: a complete list of parameter names.
2079: .vb
2080: double precision info(MAT_INFO_SIZE)
2081: double precision mal, nz_a
2082: Mat A
2083: integer ierr
2085: call MatGetInfo(A,MAT_LOCAL,info,ierr)
2086: mal = info(MAT_INFO_MALLOCS)
2087: nz_a = info(MAT_INFO_NZ_ALLOCATED)
2088: .ve
2090: Level: intermediate
2092: Concepts: matrices^getting information on
2093:
2094: @*/
2095: PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2096: {
2103: if (!mat->ops->getinfo) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2104: MatPreallocated(mat);
2105: (*mat->ops->getinfo)(mat,flag,info);
2106: return(0);
2107: }
2109: /* ----------------------------------------------------------*/
2112: /*@C
2113: MatILUDTFactor - Performs a drop tolerance ILU factorization.
2115: Collective on Mat
2117: Input Parameters:
2118: + mat - the matrix
2119: . row - row permutation
2120: . col - column permutation
2121: - info - information about the factorization to be done
2123: Output Parameters:
2124: . fact - the factored matrix
2126: Level: developer
2128: Notes:
2129: Most users should employ the simplified KSP interface for linear solvers
2130: instead of working directly with matrix algebra routines such as this.
2131: See, e.g., KSPCreate().
2133: This is currently only supported for the SeqAIJ matrix format using code
2134: from Yousef Saad's SPARSEKIT2 package (translated to C with f2c) and/or
2135: Matlab. SPARSEKIT2 is copyrighted by Yousef Saad with the GNU copyright
2136: and thus can be distributed with PETSc.
2138: Concepts: matrices^ILUDT factorization
2140: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
2141: @*/
2142: PetscErrorCode MatILUDTFactor(Mat mat,IS row,IS col,const MatFactorInfo *info,Mat *fact)
2143: {
2153: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2154: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2155: if (!mat->ops->iludtfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2156: MatPreallocated(mat);
2157: PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);
2158: (*mat->ops->iludtfactor)(mat,row,col,info,fact);
2159: PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);
2160: PetscObjectStateIncrease((PetscObject)*fact);
2162: return(0);
2163: }
2167: /*@
2168: MatLUFactor - Performs in-place LU factorization of matrix.
2170: Collective on Mat
2172: Input Parameters:
2173: + mat - the matrix
2174: . row - row permutation
2175: . col - column permutation
2176: - info - options for factorization, includes
2177: $ fill - expected fill as ratio of original fill.
2178: $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2179: $ Run with the option -info to determine an optimal value to use
2181: Notes:
2182: Most users should employ the simplified KSP interface for linear solvers
2183: instead of working directly with matrix algebra routines such as this.
2184: See, e.g., KSPCreate().
2186: This changes the state of the matrix to a factored matrix; it cannot be used
2187: for example with MatSetValues() unless one first calls MatSetUnfactored().
2189: Level: developer
2191: Concepts: matrices^LU factorization
2193: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2194: MatGetOrdering(), MatSetUnfactored(), MatFactorInfo
2196: @*/
2197: PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2198: {
2207: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2208: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2209: if (!mat->ops->lufactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2210: MatPreallocated(mat);
2212: PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);
2213: (*mat->ops->lufactor)(mat,row,col,info);
2214: PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);
2215: PetscObjectStateIncrease((PetscObject)mat);
2216: return(0);
2217: }
2221: /*@
2222: MatILUFactor - Performs in-place ILU factorization of matrix.
2224: Collective on Mat
2226: Input Parameters:
2227: + mat - the matrix
2228: . row - row permutation
2229: . col - column permutation
2230: - info - structure containing
2231: $ levels - number of levels of fill.
2232: $ expected fill - as ratio of original fill.
2233: $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2234: missing diagonal entries)
2236: Notes:
2237: Probably really in-place only when level of fill is zero, otherwise allocates
2238: new space to store factored matrix and deletes previous memory.
2240: Most users should employ the simplified KSP interface for linear solvers
2241: instead of working directly with matrix algebra routines such as this.
2242: See, e.g., KSPCreate().
2244: Level: developer
2246: Concepts: matrices^ILU factorization
2248: .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
2249: @*/
2250: PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2251: {
2260: if (mat->rmap->N != mat->cmap->N) SETERRQ(PETSC_ERR_ARG_WRONG,"matrix must be square");
2261: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2262: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2263: if (!mat->ops->ilufactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2264: MatPreallocated(mat);
2266: PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);
2267: (*mat->ops->ilufactor)(mat,row,col,info);
2268: PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);
2269: PetscObjectStateIncrease((PetscObject)mat);
2270: return(0);
2271: }
2275: /*@
2276: MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
2277: Call this routine before calling MatLUFactorNumeric().
2279: Collective on Mat
2281: Input Parameters:
2282: + fact - the factor matrix obtained with MatGetFactor()
2283: . mat - the matrix
2284: . row, col - row and column permutations
2285: - info - options for factorization, includes
2286: $ fill - expected fill as ratio of original fill.
2287: $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2288: $ Run with the option -info to determine an optimal value to use
2291: Notes:
2292: See the users manual for additional information about
2293: choosing the fill factor for better efficiency.
2295: Most users should employ the simplified KSP interface for linear solvers
2296: instead of working directly with matrix algebra routines such as this.
2297: See, e.g., KSPCreate().
2299: Level: developer
2301: Concepts: matrices^LU symbolic factorization
2303: .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
2304: @*/
2305: PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
2306: {
2316: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2317: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2318: if (!(fact)->ops->lufactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s symbolic LU",((PetscObject)mat)->type_name);
2319: MatPreallocated(mat);
2321: PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);
2322: (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);
2323: PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);
2324: PetscObjectStateIncrease((PetscObject)fact);
2325: return(0);
2326: }
2330: /*@
2331: MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
2332: Call this routine after first calling MatLUFactorSymbolic().
2334: Collective on Mat
2336: Input Parameters:
2337: + fact - the factor matrix obtained with MatGetFactor()
2338: . mat - the matrix
2339: - info - options for factorization
2341: Notes:
2342: See MatLUFactor() for in-place factorization. See
2343: MatCholeskyFactorNumeric() for the symmetric, positive definite case.
2345: Most users should employ the simplified KSP interface for linear solvers
2346: instead of working directly with matrix algebra routines such as this.
2347: See, e.g., KSPCreate().
2349: Level: developer
2351: Concepts: matrices^LU numeric factorization
2353: .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()
2354: @*/
2355: PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
2356: {
2364: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2365: if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) {
2366: 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);
2367: }
2368: if (!(fact)->ops->lufactornumeric) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2369: MatPreallocated(mat);
2370: PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);
2371: (fact->ops->lufactornumeric)(fact,mat,info);
2372: PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);
2374: MatView_Private(fact);
2375: PetscObjectStateIncrease((PetscObject)fact);
2376: return(0);
2377: }
2381: /*@
2382: MatCholeskyFactor - Performs in-place Cholesky factorization of a
2383: symmetric matrix.
2385: Collective on Mat
2387: Input Parameters:
2388: + mat - the matrix
2389: . perm - row and column permutations
2390: - f - expected fill as ratio of original fill
2392: Notes:
2393: See MatLUFactor() for the nonsymmetric case. See also
2394: MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().
2396: Most users should employ the simplified KSP interface for linear solvers
2397: instead of working directly with matrix algebra routines such as this.
2398: See, e.g., KSPCreate().
2400: Level: developer
2402: Concepts: matrices^Cholesky factorization
2404: .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
2405: MatGetOrdering()
2407: @*/
2408: PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
2409: {
2417: if (mat->rmap->N != mat->cmap->N) SETERRQ(PETSC_ERR_ARG_WRONG,"Matrix must be square");
2418: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2419: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2420: if (!mat->ops->choleskyfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2421: MatPreallocated(mat);
2423: PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);
2424: (*mat->ops->choleskyfactor)(mat,perm,info);
2425: PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);
2426: PetscObjectStateIncrease((PetscObject)mat);
2427: return(0);
2428: }
2432: /*@
2433: MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
2434: of a symmetric matrix.
2436: Collective on Mat
2438: Input Parameters:
2439: + fact - the factor matrix obtained with MatGetFactor()
2440: . mat - the matrix
2441: . perm - row and column permutations
2442: - info - options for factorization, includes
2443: $ fill - expected fill as ratio of original fill.
2444: $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2445: $ Run with the option -info to determine an optimal value to use
2447: Notes:
2448: See MatLUFactorSymbolic() for the nonsymmetric case. See also
2449: MatCholeskyFactor() and MatCholeskyFactorNumeric().
2451: Most users should employ the simplified KSP interface for linear solvers
2452: instead of working directly with matrix algebra routines such as this.
2453: See, e.g., KSPCreate().
2455: Level: developer
2457: Concepts: matrices^Cholesky symbolic factorization
2459: .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
2460: MatGetOrdering()
2462: @*/
2463: PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
2464: {
2473: if (mat->rmap->N != mat->cmap->N) SETERRQ(PETSC_ERR_ARG_WRONG,"Matrix must be square");
2474: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2475: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2476: if (!(fact)->ops->choleskyfactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2477: MatPreallocated(mat);
2479: PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
2480: (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);
2481: PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
2482: PetscObjectStateIncrease((PetscObject)fact);
2483: return(0);
2484: }
2488: /*@
2489: MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
2490: of a symmetric matrix. Call this routine after first calling
2491: MatCholeskyFactorSymbolic().
2493: Collective on Mat
2495: Input Parameters:
2496: + fact - the factor matrix obtained with MatGetFactor()
2497: . mat - the initial matrix
2498: . info - options for factorization
2499: - fact - the symbolic factor of mat
2502: Notes:
2503: Most users should employ the simplified KSP interface for linear solvers
2504: instead of working directly with matrix algebra routines such as this.
2505: See, e.g., KSPCreate().
2507: Level: developer
2509: Concepts: matrices^Cholesky numeric factorization
2511: .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
2512: @*/
2513: PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
2514: {
2522: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2523: if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2524: if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) {
2525: 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);
2526: }
2527: MatPreallocated(mat);
2529: PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);
2530: (fact->ops->choleskyfactornumeric)(fact,mat,info);
2531: PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);
2533: MatView_Private(fact);
2534: PetscObjectStateIncrease((PetscObject)fact);
2535: return(0);
2536: }
2538: /* ----------------------------------------------------------------*/
2541: /*@
2542: MatSolve - Solves A x = b, given a factored matrix.
2544: Collective on Mat and Vec
2546: Input Parameters:
2547: + mat - the factored matrix
2548: - b - the right-hand-side vector
2550: Output Parameter:
2551: . x - the result vector
2553: Notes:
2554: The vectors b and x cannot be the same. I.e., one cannot
2555: call MatSolve(A,x,x).
2557: Notes:
2558: Most users should employ the simplified KSP interface for linear solvers
2559: instead of working directly with matrix algebra routines such as this.
2560: See, e.g., KSPCreate().
2562: Level: developer
2564: Concepts: matrices^triangular solves
2566: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
2567: @*/
2568: PetscErrorCode MatSolve(Mat mat,Vec b,Vec x)
2569: {
2579: if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2580: if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2581: 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);
2582: 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);
2583: 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);
2584: if (!mat->rmap->N && !mat->cmap->N) return(0);
2585: if (!mat->ops->solve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2586: MatPreallocated(mat);
2588: PetscLogEventBegin(MAT_Solve,mat,b,x,0);
2589: (*mat->ops->solve)(mat,b,x);
2590: PetscLogEventEnd(MAT_Solve,mat,b,x,0);
2591: PetscObjectStateIncrease((PetscObject)x);
2592: return(0);
2593: }
2597: PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X)
2598: {
2600: Vec b,x;
2601: PetscInt m,N,i;
2602: PetscScalar *bb,*xx;
2605: MatGetArray(B,&bb);
2606: MatGetArray(X,&xx);
2607: MatGetLocalSize(B,&m,PETSC_NULL); /* number local rows */
2608: MatGetSize(B,PETSC_NULL,&N); /* total columns in dense matrix */
2609: VecCreateMPIWithArray(((PetscObject)A)->comm,m,PETSC_DETERMINE,PETSC_NULL,&b);
2610: VecCreateMPIWithArray(((PetscObject)A)->comm,m,PETSC_DETERMINE,PETSC_NULL,&x);
2611: for (i=0; i<N; i++) {
2612: VecPlaceArray(b,bb + i*m);
2613: VecPlaceArray(x,xx + i*m);
2614: MatSolve(A,b,x);
2615: VecResetArray(x);
2616: VecResetArray(b);
2617: }
2618: VecDestroy(b);
2619: VecDestroy(x);
2620: MatRestoreArray(B,&bb);
2621: MatRestoreArray(X,&xx);
2622: return(0);
2623: }
2627: /*@
2628: MatMatSolve - Solves A X = B, given a factored matrix.
2630: Collective on Mat
2632: Input Parameters:
2633: + mat - the factored matrix
2634: - B - the right-hand-side matrix (dense matrix)
2636: Output Parameter:
2637: . X - the result matrix (dense matrix)
2639: Notes:
2640: The matrices b and x cannot be the same. I.e., one cannot
2641: call MatMatSolve(A,x,x).
2643: Notes:
2644: Most users should usually employ the simplified KSP interface for linear solvers
2645: instead of working directly with matrix algebra routines such as this.
2646: See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
2647: at a time.
2649: Level: developer
2651: Concepts: matrices^triangular solves
2653: .seealso: MatMatSolveAdd(), MatMatSolveTranspose(), MatMatSolveTransposeAdd(), MatLUFactor(), MatCholeskyFactor()
2654: @*/
2655: PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X)
2656: {
2666: if (X == B) SETERRQ(PETSC_ERR_ARG_IDN,"X and B must be different matrices");
2667: if (!A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2668: 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);
2669: 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);
2670: 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);
2671: if (!A->rmap->N && !A->cmap->N) return(0);
2672: MatPreallocated(A);
2674: PetscLogEventBegin(MAT_MatSolve,A,B,X,0);
2675: if (!A->ops->matsolve) {
2676: PetscInfo1(A,"Mat type %s using basic MatMatSolve",((PetscObject)A)->type_name);
2677: MatMatSolve_Basic(A,B,X);
2678: } else {
2679: (*A->ops->matsolve)(A,B,X);
2680: }
2681: PetscLogEventEnd(MAT_MatSolve,A,B,X,0);
2682: PetscObjectStateIncrease((PetscObject)X);
2683: return(0);
2684: }
2689: /* @
2690: MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or
2691: U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U,
2693: Collective on Mat and Vec
2695: Input Parameters:
2696: + mat - the factored matrix
2697: - b - the right-hand-side vector
2699: Output Parameter:
2700: . x - the result vector
2702: Notes:
2703: MatSolve() should be used for most applications, as it performs
2704: a forward solve followed by a backward solve.
2706: The vectors b and x cannot be the same, i.e., one cannot
2707: call MatForwardSolve(A,x,x).
2709: For matrix in seqsbaij format with block size larger than 1,
2710: the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
2711: MatForwardSolve() solves U^T*D y = b, and
2712: MatBackwardSolve() solves U x = y.
2713: Thus they do not provide a symmetric preconditioner.
2715: Most users should employ the simplified KSP interface for linear solvers
2716: instead of working directly with matrix algebra routines such as this.
2717: See, e.g., KSPCreate().
2719: Level: developer
2721: Concepts: matrices^forward solves
2723: .seealso: MatSolve(), MatBackwardSolve()
2724: @ */
2725: PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x)
2726: {
2736: if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2737: if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2738: if (!mat->ops->forwardsolve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2739: 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);
2740: 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);
2741: 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);
2742: MatPreallocated(mat);
2743: PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);
2744: (*mat->ops->forwardsolve)(mat,b,x);
2745: PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);
2746: PetscObjectStateIncrease((PetscObject)x);
2747: return(0);
2748: }
2752: /* @
2753: MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
2754: D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U,
2756: Collective on Mat and Vec
2758: Input Parameters:
2759: + mat - the factored matrix
2760: - b - the right-hand-side vector
2762: Output Parameter:
2763: . x - the result vector
2765: Notes:
2766: MatSolve() should be used for most applications, as it performs
2767: a forward solve followed by a backward solve.
2769: The vectors b and x cannot be the same. I.e., one cannot
2770: call MatBackwardSolve(A,x,x).
2772: For matrix in seqsbaij format with block size larger than 1,
2773: the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
2774: MatForwardSolve() solves U^T*D y = b, and
2775: MatBackwardSolve() solves U x = y.
2776: Thus they do not provide a symmetric preconditioner.
2778: Most users should employ the simplified KSP interface for linear solvers
2779: instead of working directly with matrix algebra routines such as this.
2780: See, e.g., KSPCreate().
2782: Level: developer
2784: Concepts: matrices^backward solves
2786: .seealso: MatSolve(), MatForwardSolve()
2787: @ */
2788: PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x)
2789: {
2799: if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2800: if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2801: if (!mat->ops->backwardsolve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2802: 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);
2803: 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);
2804: 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);
2805: MatPreallocated(mat);
2807: PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);
2808: (*mat->ops->backwardsolve)(mat,b,x);
2809: PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);
2810: PetscObjectStateIncrease((PetscObject)x);
2811: return(0);
2812: }
2816: /*@
2817: MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
2819: Collective on Mat and Vec
2821: Input Parameters:
2822: + mat - the factored matrix
2823: . b - the right-hand-side vector
2824: - y - the vector to be added to
2826: Output Parameter:
2827: . x - the result vector
2829: Notes:
2830: The vectors b and x cannot be the same. I.e., one cannot
2831: call MatSolveAdd(A,x,y,x).
2833: Most users should employ the simplified KSP interface for linear solvers
2834: instead of working directly with matrix algebra routines such as this.
2835: See, e.g., KSPCreate().
2837: Level: developer
2839: Concepts: matrices^triangular solves
2841: .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
2842: @*/
2843: PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
2844: {
2845: PetscScalar one = 1.0;
2846: Vec tmp;
2858: if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2859: if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2860: 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);
2861: 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);
2862: 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);
2863: 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);
2864: 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);
2865: MatPreallocated(mat);
2867: PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);
2868: if (mat->ops->solveadd) {
2869: (*mat->ops->solveadd)(mat,b,y,x);
2870: } else {
2871: /* do the solve then the add manually */
2872: if (x != y) {
2873: MatSolve(mat,b,x);
2874: VecAXPY(x,one,y);
2875: } else {
2876: VecDuplicate(x,&tmp);
2877: PetscLogObjectParent(mat,tmp);
2878: VecCopy(x,tmp);
2879: MatSolve(mat,b,x);
2880: VecAXPY(x,one,tmp);
2881: VecDestroy(tmp);
2882: }
2883: }
2884: PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);
2885: PetscObjectStateIncrease((PetscObject)x);
2886: return(0);
2887: }
2891: /*@
2892: MatSolveTranspose - Solves A' x = b, given a factored matrix.
2894: Collective on Mat and Vec
2896: Input Parameters:
2897: + mat - the factored matrix
2898: - b - the right-hand-side vector
2900: Output Parameter:
2901: . x - the result vector
2903: Notes:
2904: The vectors b and x cannot be the same. I.e., one cannot
2905: call MatSolveTranspose(A,x,x).
2907: Most users should employ the simplified KSP interface for linear solvers
2908: instead of working directly with matrix algebra routines such as this.
2909: See, e.g., KSPCreate().
2911: Level: developer
2913: Concepts: matrices^triangular solves
2915: .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
2916: @*/
2917: PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x)
2918: {
2928: if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2929: if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2930: if (!mat->ops->solvetranspose) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
2931: 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);
2932: 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);
2933: MatPreallocated(mat);
2934: PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);
2935: (*mat->ops->solvetranspose)(mat,b,x);
2936: PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);
2937: PetscObjectStateIncrease((PetscObject)x);
2938: return(0);
2939: }
2943: /*@
2944: MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
2945: factored matrix.
2947: Collective on Mat and Vec
2949: Input Parameters:
2950: + mat - the factored matrix
2951: . b - the right-hand-side vector
2952: - y - the vector to be added to
2954: Output Parameter:
2955: . x - the result vector
2957: Notes:
2958: The vectors b and x cannot be the same. I.e., one cannot
2959: call MatSolveTransposeAdd(A,x,y,x).
2961: Most users should employ the simplified KSP interface for linear solvers
2962: instead of working directly with matrix algebra routines such as this.
2963: See, e.g., KSPCreate().
2965: Level: developer
2967: Concepts: matrices^triangular solves
2969: .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
2970: @*/
2971: PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
2972: {
2973: PetscScalar one = 1.0;
2975: Vec tmp;
2986: if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2987: if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2988: 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);
2989: 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);
2990: 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);
2991: 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);
2992: MatPreallocated(mat);
2994: PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);
2995: if (mat->ops->solvetransposeadd) {
2996: (*mat->ops->solvetransposeadd)(mat,b,y,x);
2997: } else {
2998: /* do the solve then the add manually */
2999: if (x != y) {
3000: MatSolveTranspose(mat,b,x);
3001: VecAXPY(x,one,y);
3002: } else {
3003: VecDuplicate(x,&tmp);
3004: PetscLogObjectParent(mat,tmp);
3005: VecCopy(x,tmp);
3006: MatSolveTranspose(mat,b,x);
3007: VecAXPY(x,one,tmp);
3008: VecDestroy(tmp);
3009: }
3010: }
3011: PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);
3012: PetscObjectStateIncrease((PetscObject)x);
3013: return(0);
3014: }
3015: /* ----------------------------------------------------------------*/
3019: /*@
3020: MatRelax - Computes relaxation (SOR, Gauss-Seidel) sweeps.
3022: Collective on Mat and Vec
3024: Input Parameters:
3025: + mat - the matrix
3026: . b - the right hand side
3027: . omega - the relaxation factor
3028: . flag - flag indicating the type of SOR (see below)
3029: . shift - diagonal shift
3030: . its - the number of iterations
3031: - lits - the number of local iterations
3033: Output Parameters:
3034: . x - the solution (can contain an initial guess)
3036: SOR Flags:
3037: . SOR_FORWARD_SWEEP - forward SOR
3038: . SOR_BACKWARD_SWEEP - backward SOR
3039: . SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3040: . SOR_LOCAL_FORWARD_SWEEP - local forward SOR
3041: . SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
3042: . SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3043: . SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
3044: upper/lower triangular part of matrix to
3045: vector (with omega)
3046: . SOR_ZERO_INITIAL_GUESS - zero initial guess
3048: Notes:
3049: SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3050: SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3051: on each processor.
3053: Application programmers will not generally use MatRelax() directly,
3054: but instead will employ the KSP/PC interface.
3056: Notes for Advanced Users:
3057: The flags are implemented as bitwise inclusive or operations.
3058: For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3059: to specify a zero initial guess for SSOR.
3061: Most users should employ the simplified KSP interface for linear solvers
3062: instead of working directly with matrix algebra routines such as this.
3063: See, e.g., KSPCreate().
3065: See also, MatPBRelax(). This routine will automatically call the point block
3066: version if the point version is not available.
3068: Level: developer
3070: Concepts: matrices^relaxation
3071: Concepts: matrices^SOR
3072: Concepts: matrices^Gauss-Seidel
3074: @*/
3075: PetscErrorCode MatRelax(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3076: {
3086: if (!mat->ops->relax && !mat->ops->pbrelax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3087: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3088: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3089: 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);
3090: 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);
3091: 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);
3092: if (its <= 0) SETERRQ1(PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
3093: if (lits <= 0) SETERRQ1(PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
3095: MatPreallocated(mat);
3096: PetscLogEventBegin(MAT_Relax,mat,b,x,0);
3097: if (mat->ops->relax) {
3098: ierr =(*mat->ops->relax)(mat,b,omega,flag,shift,its,lits,x);
3099: } else {
3100: ierr =(*mat->ops->pbrelax)(mat,b,omega,flag,shift,its,lits,x);
3101: }
3102: PetscLogEventEnd(MAT_Relax,mat,b,x,0);
3103: PetscObjectStateIncrease((PetscObject)x);
3104: return(0);
3105: }
3109: /*@
3110: MatPBRelax - Computes relaxation (SOR, Gauss-Seidel) sweeps.
3112: Collective on Mat and Vec
3114: See MatRelax() for usage
3116: For multi-component PDEs where the Jacobian is stored in a point block format
3117: (with the PETSc BAIJ matrix formats) the relaxation is done one point block at
3118: a time. That is, the small (for example, 4 by 4) blocks along the diagonal are solved
3119: simultaneously (that is a 4 by 4 linear solve is done) to update all the values at a point.
3121: Level: developer
3123: @*/
3124: PetscErrorCode MatPBRelax(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3125: {
3135: if (!mat->ops->pbrelax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3136: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3137: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3138: 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);
3139: 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);
3140: 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);
3141: MatPreallocated(mat);
3143: PetscLogEventBegin(MAT_Relax,mat,b,x,0);
3144: ierr =(*mat->ops->pbrelax)(mat,b,omega,flag,shift,its,lits,x);
3145: PetscLogEventEnd(MAT_Relax,mat,b,x,0);
3146: PetscObjectStateIncrease((PetscObject)x);
3147: return(0);
3148: }
3152: /*
3153: Default matrix copy routine.
3154: */
3155: PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
3156: {
3157: PetscErrorCode ierr;
3158: PetscInt i,rstart,rend,nz;
3159: const PetscInt *cwork;
3160: const PetscScalar *vwork;
3163: if (B->assembled) {
3164: MatZeroEntries(B);
3165: }
3166: MatGetOwnershipRange(A,&rstart,&rend);
3167: for (i=rstart; i<rend; i++) {
3168: MatGetRow(A,i,&nz,&cwork,&vwork);
3169: MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);
3170: MatRestoreRow(A,i,&nz,&cwork,&vwork);
3171: }
3172: MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
3173: MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);
3174: PetscObjectStateIncrease((PetscObject)B);
3175: return(0);
3176: }
3180: /*@
3181: MatCopy - Copys a matrix to another matrix.
3183: Collective on Mat
3185: Input Parameters:
3186: + A - the matrix
3187: - str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
3189: Output Parameter:
3190: . B - where the copy is put
3192: Notes:
3193: If you use SAME_NONZERO_PATTERN then the two matrices had better have the
3194: same nonzero pattern or the routine will crash.
3196: MatCopy() copies the matrix entries of a matrix to another existing
3197: matrix (after first zeroing the second matrix). A related routine is
3198: MatConvert(), which first creates a new matrix and then copies the data.
3200: Level: intermediate
3201:
3202: Concepts: matrices^copying
3204: .seealso: MatConvert(), MatDuplicate()
3206: @*/
3207: PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str)
3208: {
3210: PetscInt i;
3218: MatPreallocated(B);
3219: if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3220: if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3221: 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);
3222: MatPreallocated(A);
3224: PetscLogEventBegin(MAT_Copy,A,B,0,0);
3225: if (A->ops->copy) {
3226: (*A->ops->copy)(A,B,str);
3227: } else { /* generic conversion */
3228: MatCopy_Basic(A,B,str);
3229: }
3230: if (A->mapping) {
3231: if (B->mapping) {ISLocalToGlobalMappingDestroy(B->mapping);B->mapping = 0;}
3232: MatSetLocalToGlobalMapping(B,A->mapping);
3233: }
3234: if (A->bmapping) {
3235: if (B->bmapping) {ISLocalToGlobalMappingDestroy(B->bmapping);B->bmapping = 0;}
3236: MatSetLocalToGlobalMappingBlock(B,A->mapping);
3237: }
3239: B->stencil.dim = A->stencil.dim;
3240: B->stencil.noc = A->stencil.noc;
3241: for (i=0; i<=A->stencil.dim; i++) {
3242: B->stencil.dims[i] = A->stencil.dims[i];
3243: B->stencil.starts[i] = A->stencil.starts[i];
3244: }
3246: PetscLogEventEnd(MAT_Copy,A,B,0,0);
3247: PetscObjectStateIncrease((PetscObject)B);
3248: return(0);
3249: }
3253: /*@C
3254: MatConvert - Converts a matrix to another matrix, either of the same
3255: or different type.
3257: Collective on Mat
3259: Input Parameters:
3260: + mat - the matrix
3261: . newtype - new matrix type. Use MATSAME to create a new matrix of the
3262: same type as the original matrix.
3263: - reuse - denotes if the destination matrix is to be created or reused. Currently
3264: MAT_REUSE_MATRIX is only supported for inplace conversion, otherwise use
3265: MAT_INITIAL_MATRIX.
3267: Output Parameter:
3268: . M - pointer to place new matrix
3270: Notes:
3271: MatConvert() first creates a new matrix and then copies the data from
3272: the first matrix. A related routine is MatCopy(), which copies the matrix
3273: entries of one matrix to another already existing matrix context.
3275: Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
3276: the MPI communicator of the generated matrix is always the same as the communicator
3277: of the input matrix.
3279: Level: intermediate
3281: Concepts: matrices^converting between storage formats
3283: .seealso: MatCopy(), MatDuplicate()
3284: @*/
3285: PetscErrorCode MatConvert(Mat mat, const MatType newtype,MatReuse reuse,Mat *M)
3286: {
3287: PetscErrorCode ierr;
3288: PetscTruth sametype,issame,flg;
3289: char convname[256],mtype[256];
3290: Mat B;
3296: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3297: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3298: MatPreallocated(mat);
3300: PetscOptionsGetString(((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);
3301: if (flg) {
3302: newtype = mtype;
3303: }
3304: PetscTypeCompare((PetscObject)mat,newtype,&sametype);
3305: PetscStrcmp(newtype,"same",&issame);
3306: if ((reuse == MAT_REUSE_MATRIX) && (mat != *M)) {
3307: SETERRQ(PETSC_ERR_SUP,"MAT_REUSE_MATRIX only supported for in-place conversion currently");
3308: }
3310: if ((reuse == MAT_REUSE_MATRIX) && (issame || sametype)) return(0);
3311:
3312: if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
3313: (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);
3314: } else {
3315: PetscErrorCode (*conv)(Mat, const MatType,MatReuse,Mat*)=PETSC_NULL;
3316: const char *prefix[3] = {"seq","mpi",""};
3317: PetscInt i;
3318: /*
3319: Order of precedence:
3320: 1) See if a specialized converter is known to the current matrix.
3321: 2) See if a specialized converter is known to the desired matrix class.
3322: 3) See if a good general converter is registered for the desired class
3323: (as of 6/27/03 only MATMPIADJ falls into this category).
3324: 4) See if a good general converter is known for the current matrix.
3325: 5) Use a really basic converter.
3326: */
3327:
3328: /* 1) See if a specialized converter is known to the current matrix and the desired class */
3329: for (i=0; i<3; i++) {
3330: PetscStrcpy(convname,"MatConvert_");
3331: PetscStrcat(convname,((PetscObject)mat)->type_name);
3332: PetscStrcat(convname,"_");
3333: PetscStrcat(convname,prefix[i]);
3334: PetscStrcat(convname,newtype);
3335: PetscStrcat(convname,"_C");
3336: PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);
3337: if (conv) goto foundconv;
3338: }
3340: /* 2) See if a specialized converter is known to the desired matrix class. */
3341: MatCreate(((PetscObject)mat)->comm,&B);
3342: MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);
3343: MatSetType(B,newtype);
3344: for (i=0; i<3; i++) {
3345: PetscStrcpy(convname,"MatConvert_");
3346: PetscStrcat(convname,((PetscObject)mat)->type_name);
3347: PetscStrcat(convname,"_");
3348: PetscStrcat(convname,prefix[i]);
3349: PetscStrcat(convname,newtype);
3350: PetscStrcat(convname,"_C");
3351: PetscObjectQueryFunction((PetscObject)B,convname,(void (**)(void))&conv);
3352: if (conv) {
3353: MatDestroy(B);
3354: goto foundconv;
3355: }
3356: }
3358: /* 3) See if a good general converter is registered for the desired class */
3359: conv = B->ops->convertfrom;
3360: MatDestroy(B);
3361: if (conv) goto foundconv;
3363: /* 4) See if a good general converter is known for the current matrix */
3364: if (mat->ops->convert) {
3365: conv = mat->ops->convert;
3366: }
3367: if (conv) goto foundconv;
3369: /* 5) Use a really basic converter. */
3370: conv = MatConvert_Basic;
3372: foundconv:
3373: PetscLogEventBegin(MAT_Convert,mat,0,0,0);
3374: (*conv)(mat,newtype,reuse,M);
3375: PetscLogEventEnd(MAT_Convert,mat,0,0,0);
3376: }
3377: PetscObjectStateIncrease((PetscObject)*M);
3378: return(0);
3379: }
3383: /*@C
3384: MatFactorGetSolverPackage - Returns name of the package providing the factorization routines
3386: Not Collective
3388: Input Parameter:
3389: . mat - the matrix, must be a factored matrix
3391: Output Parameter:
3392: . type - the string name of the package (do not free this string)
3394: Notes:
3395: In Fortran you pass in a empty string and the package name will be copied into it.
3396: (Make sure the string is long enough)
3398: Level: intermediate
3400: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
3401: @*/
3402: PetscErrorCode MatFactorGetSolverPackage(Mat mat, const MatSolverPackage *type)
3403: {
3404: PetscErrorCode ierr;
3405: PetscErrorCode (*conv)(Mat,const MatSolverPackage*);
3410: if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
3411: PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverPackage_C",(void (**)(void))&conv);
3412: if (!conv) {
3413: *type = MAT_SOLVER_PETSC;
3414: } else {
3415: (*conv)(mat,type);
3416: }
3417: return(0);
3418: }
3422: /*@C
3423: MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic()
3425: Collective on Mat
3427: Input Parameters:
3428: + mat - the matrix
3429: . type - name of solver type, for example, spooles, superlu, plapack, petsc (to use PETSc's default)
3430: - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
3432: Output Parameters:
3433: . f - the factor matrix used with MatXXFactorSymbolic() calls
3435: Notes:
3436: Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
3437: such as pastix, superlu, mumps, spooles etc.
3439: PETSc must have been config/configure.py to use the external solver, using the option --download-package
3441: Level: intermediate
3443: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
3444: @*/
3445: PetscErrorCode MatGetFactor(Mat mat, const MatSolverPackage type,MatFactorType ftype,Mat *f)
3446: {
3447: PetscErrorCode ierr;
3448: char convname[256];
3449: PetscErrorCode (*conv)(Mat,MatFactorType,Mat*);
3455: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3456: MatPreallocated(mat);
3458: PetscStrcpy(convname,"MatGetFactor_");
3459: PetscStrcat(convname,((PetscObject)mat)->type_name);
3460: PetscStrcat(convname,"_");
3461: PetscStrcat(convname,type);
3462: PetscStrcat(convname,"_C");
3463: PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);
3464: if (!conv) {
3465: PetscTruth flag;
3466: PetscStrcasecmp(MAT_SOLVER_PETSC,type,&flag);
3467: if (flag) {
3468: SETERRQ1(PETSC_ERR_SUP,"Matrix format %s does not have a built-in PETSc direct solver",((PetscObject)mat)->type_name);
3469: } else {
3470: 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);
3471: }
3472: }
3473: (*conv)(mat,ftype,f);
3474: return(0);
3475: }
3479: /*@C
3480: MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type
3482: Collective on Mat
3484: Input Parameters:
3485: + mat - the matrix
3486: . type - name of solver type, for example, spooles, superlu, plapack, petsc (to use PETSc's default)
3487: - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
3489: Output Parameter:
3490: . flg - PETSC_TRUE if the factorization is available
3492: Notes:
3493: Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
3494: such as pastix, superlu, mumps, spooles etc.
3496: PETSc must have been config/configure.py to use the external solver, using the option --download-package
3498: Level: intermediate
3500: .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
3501: @*/
3502: PetscErrorCode MatGetFactorAvailable(Mat mat, const MatSolverPackage type,MatFactorType ftype,PetscTruth *flg)
3503: {
3504: PetscErrorCode ierr;
3505: char convname[256];
3506: PetscErrorCode (*conv)(Mat,MatFactorType,PetscTruth*);
3512: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3513: MatPreallocated(mat);
3515: PetscStrcpy(convname,"MatGetFactorAvailable_");
3516: PetscStrcat(convname,((PetscObject)mat)->type_name);
3517: PetscStrcat(convname,"_");
3518: PetscStrcat(convname,type);
3519: PetscStrcat(convname,"_C");
3520: PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);
3521: if (!conv) {
3522: *flg = PETSC_FALSE;
3523: } else {
3524: (*conv)(mat,ftype,flg);
3525: }
3526: return(0);
3527: }
3532: /*@
3533: MatDuplicate - Duplicates a matrix including the non-zero structure.
3535: Collective on Mat
3537: Input Parameters:
3538: + mat - the matrix
3539: - op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy nonzero
3540: values as well or not
3542: Output Parameter:
3543: . M - pointer to place new matrix
3545: Level: intermediate
3547: Concepts: matrices^duplicating
3549: .seealso: MatCopy(), MatConvert()
3550: @*/
3551: PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
3552: {
3554: Mat B;
3555: PetscInt i;
3561: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3562: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3563: MatPreallocated(mat);
3565: *M = 0;
3566: if (!mat->ops->duplicate) {
3567: SETERRQ(PETSC_ERR_SUP,"Not written for this matrix type");
3568: }
3569: PetscLogEventBegin(MAT_Convert,mat,0,0,0);
3570: (*mat->ops->duplicate)(mat,op,M);
3571: B = *M;
3572: if (mat->mapping) {
3573: MatSetLocalToGlobalMapping(B,mat->mapping);
3574: }
3575: if (mat->bmapping) {
3576: MatSetLocalToGlobalMappingBlock(B,mat->bmapping);
3577: }
3578: PetscMapCopy(((PetscObject)mat)->comm,mat->rmap,B->rmap);
3579: PetscMapCopy(((PetscObject)mat)->comm,mat->cmap,B->cmap);
3580:
3581: B->stencil.dim = mat->stencil.dim;
3582: B->stencil.noc = mat->stencil.noc;
3583: for (i=0; i<=mat->stencil.dim; i++) {
3584: B->stencil.dims[i] = mat->stencil.dims[i];
3585: B->stencil.starts[i] = mat->stencil.starts[i];
3586: }
3588: PetscLogEventEnd(MAT_Convert,mat,0,0,0);
3589: PetscObjectStateIncrease((PetscObject)B);
3590: return(0);
3591: }
3595: /*@
3596: MatGetDiagonal - Gets the diagonal of a matrix.
3598: Collective on Mat and Vec
3600: Input Parameters:
3601: + mat - the matrix
3602: - v - the vector for storing the diagonal
3604: Output Parameter:
3605: . v - the diagonal of the matrix
3607: Level: intermediate
3609: Concepts: matrices^accessing diagonals
3611: .seealso: MatGetRow(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs()
3612: @*/
3613: PetscErrorCode MatGetDiagonal(Mat mat,Vec v)
3614: {
3621: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3622: if (!mat->ops->getdiagonal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3623: MatPreallocated(mat);
3625: (*mat->ops->getdiagonal)(mat,v);
3626: PetscObjectStateIncrease((PetscObject)v);
3627: return(0);
3628: }
3632: /*@
3633: MatGetRowMin - Gets the minimum value (of the real part) of each
3634: row of the matrix
3636: Collective on Mat and Vec
3638: Input Parameters:
3639: . mat - the matrix
3641: Output Parameter:
3642: + v - the vector for storing the maximums
3643: - idx - the indices of the column found for each row (optional)
3645: Level: intermediate
3647: Notes: The result of this call are the same as if one converted the matrix to dense format
3648: and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
3650: This code is only implemented for a couple of matrix formats.
3652: Concepts: matrices^getting row maximums
3654: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(),
3655: MatGetRowMax()
3656: @*/
3657: PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
3658: {
3665: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3666: if (!mat->ops->getrowmax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3667: MatPreallocated(mat);
3669: (*mat->ops->getrowmin)(mat,v,idx);
3670: PetscObjectStateIncrease((PetscObject)v);
3671: return(0);
3672: }
3676: /*@
3677: MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
3678: row of the matrix
3680: Collective on Mat and Vec
3682: Input Parameters:
3683: . mat - the matrix
3685: Output Parameter:
3686: + v - the vector for storing the minimums
3687: - idx - the indices of the column found for each row (optional)
3689: Level: intermediate
3691: Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
3692: row is 0 (the first column).
3694: This code is only implemented for a couple of matrix formats.
3696: Concepts: matrices^getting row maximums
3698: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
3699: @*/
3700: PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
3701: {
3708: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3709: if (!mat->ops->getrowminabs) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3710: MatPreallocated(mat);
3711: if (idx) {PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));}
3713: (*mat->ops->getrowminabs)(mat,v,idx);
3714: PetscObjectStateIncrease((PetscObject)v);
3715: return(0);
3716: }
3720: /*@
3721: MatGetRowMax - Gets the maximum value (of the real part) of each
3722: row of the matrix
3724: Collective on Mat and Vec
3726: Input Parameters:
3727: . mat - the matrix
3729: Output Parameter:
3730: + v - the vector for storing the maximums
3731: - idx - the indices of the column found for each row (optional)
3733: Level: intermediate
3735: Notes: The result of this call are the same as if one converted the matrix to dense format
3736: and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
3738: This code is only implemented for a couple of matrix formats.
3740: Concepts: matrices^getting row maximums
3742: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(), MatGetRowMin()
3743: @*/
3744: PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
3745: {
3752: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3753: if (!mat->ops->getrowmax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3754: MatPreallocated(mat);
3756: (*mat->ops->getrowmax)(mat,v,idx);
3757: PetscObjectStateIncrease((PetscObject)v);
3758: return(0);
3759: }
3763: /*@
3764: MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
3765: row of the matrix
3767: Collective on Mat and Vec
3769: Input Parameters:
3770: . mat - the matrix
3772: Output Parameter:
3773: + v - the vector for storing the maximums
3774: - idx - the indices of the column found for each row (optional)
3776: Level: intermediate
3778: Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
3779: row is 0 (the first column).
3781: This code is only implemented for a couple of matrix formats.
3783: Concepts: matrices^getting row maximums
3785: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
3786: @*/
3787: PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
3788: {
3795: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3796: if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3797: MatPreallocated(mat);
3798: if (idx) {PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));}
3800: (*mat->ops->getrowmaxabs)(mat,v,idx);
3801: PetscObjectStateIncrease((PetscObject)v);
3802: return(0);
3803: }
3807: /*@
3808: MatGetRowSum - Gets the sum of each row of the matrix
3810: Collective on Mat and Vec
3812: Input Parameters:
3813: . mat - the matrix
3815: Output Parameter:
3816: . v - the vector for storing the maximums
3818: Level: intermediate
3820: Notes: This code is slow since it is not currently specialized for different formats
3822: Concepts: matrices^getting row sums
3824: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
3825: @*/
3826: PetscErrorCode MatGetRowSum(Mat mat, Vec v)
3827: {
3828: PetscInt start, end, row;
3829: PetscScalar *array;
3836: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3837: MatPreallocated(mat);
3838: MatGetOwnershipRange(mat, &start, &end);
3839: VecGetArray(v, &array);
3840: for(row = start; row < end; ++row) {
3841: PetscInt ncols, col;
3842: const PetscInt *cols;
3843: const PetscScalar *vals;
3845: array[row - start] = 0.0;
3846: MatGetRow(mat, row, &ncols, &cols, &vals);
3847: for(col = 0; col < ncols; col++) {
3848: array[row - start] += vals[col];
3849: }
3850: MatRestoreRow(mat, row, &ncols, &cols, &vals);
3851: }
3852: VecRestoreArray(v, &array);
3853: PetscObjectStateIncrease((PetscObject) v);
3854: return(0);
3855: }
3859: /*@
3860: MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
3862: Collective on Mat
3864: Input Parameter:
3865: + mat - the matrix to transpose
3866: - reuse - store the transpose matrix in the provided B
3868: Output Parameters:
3869: . B - the transpose
3871: Notes:
3872: If you pass in &mat for B the transpose will be done in place
3874: Level: intermediate
3876: Concepts: matrices^transposing
3878: .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose()
3879: @*/
3880: PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B)
3881: {
3887: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3888: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3889: if (!mat->ops->transpose) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3890: MatPreallocated(mat);
3892: PetscLogEventBegin(MAT_Transpose,mat,0,0,0);
3893: (*mat->ops->transpose)(mat,reuse,B);
3894: PetscLogEventEnd(MAT_Transpose,mat,0,0,0);
3895: if (B) {PetscObjectStateIncrease((PetscObject)*B);}
3896: return(0);
3897: }
3901: /*@
3902: MatIsTranspose - Test whether a matrix is another one's transpose,
3903: or its own, in which case it tests symmetry.
3905: Collective on Mat
3907: Input Parameter:
3908: + A - the matrix to test
3909: - B - the matrix to test against, this can equal the first parameter
3911: Output Parameters:
3912: . flg - the result
3914: Notes:
3915: Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
3916: has a running time of the order of the number of nonzeros; the parallel
3917: test involves parallel copies of the block-offdiagonal parts of the matrix.
3919: Level: intermediate
3921: Concepts: matrices^transposing, matrix^symmetry
3923: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
3924: @*/
3925: PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscTruth *flg)
3926: {
3927: PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscTruth*),(*g)(Mat,Mat,PetscReal,PetscTruth*);
3933: PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",(void (**)(void))&f);
3934: PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",(void (**)(void))&g);
3935: if (f && g) {
3936: if (f==g) {
3937: (*f)(A,B,tol,flg);
3938: } else {
3939: SETERRQ(PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
3940: }
3941: }
3942: return(0);
3943: }
3947: /*@
3948: MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,
3950: Collective on Mat
3952: Input Parameter:
3953: + A - the matrix to test
3954: - B - the matrix to test against, this can equal the first parameter
3956: Output Parameters:
3957: . flg - the result
3959: Notes:
3960: Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
3961: has a running time of the order of the number of nonzeros; the parallel
3962: test involves parallel copies of the block-offdiagonal parts of the matrix.
3964: Level: intermediate
3966: Concepts: matrices^transposing, matrix^symmetry
3968: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
3969: @*/
3970: PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscTruth *flg)
3971: {
3972: PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscTruth*),(*g)(Mat,Mat,PetscReal,PetscTruth*);
3978: PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",(void (**)(void))&f);
3979: PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",(void (**)(void))&g);
3980: if (f && g) {
3981: if (f==g) {
3982: (*f)(A,B,tol,flg);
3983: } else {
3984: SETERRQ(PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
3985: }
3986: }
3987: return(0);
3988: }
3992: /*@
3993: MatPermute - Creates a new matrix with rows and columns permuted from the
3994: original.
3996: Collective on Mat
3998: Input Parameters:
3999: + mat - the matrix to permute
4000: . row - row permutation, each processor supplies only the permutation for its rows
4001: - col - column permutation, each processor needs the entire column permutation, that is
4002: this is the same size as the total number of columns in the matrix
4004: Output Parameters:
4005: . B - the permuted matrix
4007: Level: advanced
4009: Concepts: matrices^permuting
4011: .seealso: MatGetOrdering()
4012: @*/
4013: PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
4014: {
4023: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4024: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4025: if (!mat->ops->permute) SETERRQ1(PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
4026: MatPreallocated(mat);
4028: (*mat->ops->permute)(mat,row,col,B);
4029: PetscObjectStateIncrease((PetscObject)*B);
4030: return(0);
4031: }
4035: /*@
4036: MatPermuteSparsify - Creates a new matrix with rows and columns permuted from the
4037: original and sparsified to the prescribed tolerance.
4039: Collective on Mat
4041: Input Parameters:
4042: + A - The matrix to permute
4043: . band - The half-bandwidth of the sparsified matrix, or PETSC_DECIDE
4044: . frac - The half-bandwidth as a fraction of the total size, or 0.0
4045: . tol - The drop tolerance
4046: . rowp - The row permutation
4047: - colp - The column permutation
4049: Output Parameter:
4050: . B - The permuted, sparsified matrix
4052: Level: advanced
4054: Note:
4055: The default behavior (band = PETSC_DECIDE and frac = 0.0) is to
4056: restrict the half-bandwidth of the resulting matrix to 5% of the
4057: total matrix size.
4059: .keywords: matrix, permute, sparsify
4061: .seealso: MatGetOrdering(), MatPermute()
4062: @*/
4063: PetscErrorCode MatPermuteSparsify(Mat A, PetscInt band, PetscReal frac, PetscReal tol, IS rowp, IS colp, Mat *B)
4064: {
4065: IS irowp, icolp;
4066: const PetscInt *rows, *cols;
4067: PetscInt M, N, locRowStart, locRowEnd;
4068: PetscInt nz, newNz;
4069: const PetscInt *cwork;
4070: PetscInt *cnew;
4071: const PetscScalar *vwork;
4072: PetscScalar *vnew;
4073: PetscInt bw, issize;
4074: PetscInt row, locRow, newRow, col, newCol;
4075: PetscErrorCode ierr;
4082: if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix");
4083: if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
4084: if (!A->ops->permutesparsify) {
4085: MatGetSize(A, &M, &N);
4086: MatGetOwnershipRange(A, &locRowStart, &locRowEnd);
4087: ISGetSize(rowp, &issize);
4088: if (issize != M) SETERRQ2(PETSC_ERR_ARG_WRONG, "Wrong size %D for row permutation, should be %D", issize, M);
4089: ISGetSize(colp, &issize);
4090: if (issize != N) SETERRQ2(PETSC_ERR_ARG_WRONG, "Wrong size %D for column permutation, should be %D", issize, N);
4091: ISInvertPermutation(rowp, 0, &irowp);
4092: ISGetIndices(irowp, &rows);
4093: ISInvertPermutation(colp, 0, &icolp);
4094: ISGetIndices(icolp, &cols);
4095: PetscMalloc(N * sizeof(PetscInt), &cnew);
4096: PetscMalloc(N * sizeof(PetscScalar), &vnew);
4098: /* Setup bandwidth to include */
4099: if (band == PETSC_DECIDE) {
4100: if (frac <= 0.0)
4101: bw = (PetscInt) (M * 0.05);
4102: else
4103: bw = (PetscInt) (M * frac);
4104: } else {
4105: if (band <= 0) SETERRQ(PETSC_ERR_ARG_WRONG, "Bandwidth must be a positive integer");
4106: bw = band;
4107: }
4109: /* Put values into new matrix */
4110: MatDuplicate(A, MAT_DO_NOT_COPY_VALUES, B);
4111: for(row = locRowStart, locRow = 0; row < locRowEnd; row++, locRow++) {
4112: MatGetRow(A, row, &nz, &cwork, &vwork);
4113: newRow = rows[locRow]+locRowStart;
4114: for(col = 0, newNz = 0; col < nz; col++) {
4115: newCol = cols[cwork[col]];
4116: if ((newCol >= newRow - bw) && (newCol < newRow + bw) && (PetscAbsScalar(vwork[col]) >= tol)) {
4117: cnew[newNz] = newCol;
4118: vnew[newNz] = vwork[col];
4119: newNz++;
4120: }
4121: }
4122: MatSetValues(*B, 1, &newRow, newNz, cnew, vnew, INSERT_VALUES);
4123: MatRestoreRow(A, row, &nz, &cwork, &vwork);
4124: }
4125: PetscFree(cnew);
4126: PetscFree(vnew);
4127: MatAssemblyBegin(*B, MAT_FINAL_ASSEMBLY);
4128: MatAssemblyEnd(*B, MAT_FINAL_ASSEMBLY);
4129: ISRestoreIndices(irowp, &rows);
4130: ISRestoreIndices(icolp, &cols);
4131: ISDestroy(irowp);
4132: ISDestroy(icolp);
4133: } else {
4134: (*A->ops->permutesparsify)(A, band, frac, tol, rowp, colp, B);
4135: }
4136: PetscObjectStateIncrease((PetscObject)*B);
4137: return(0);
4138: }
4142: /*@
4143: MatEqual - Compares two matrices.
4145: Collective on Mat
4147: Input Parameters:
4148: + A - the first matrix
4149: - B - the second matrix
4151: Output Parameter:
4152: . flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
4154: Level: intermediate
4156: Concepts: matrices^equality between
4157: @*/
4158: PetscErrorCode MatEqual(Mat A,Mat B,PetscTruth *flg)
4159: {
4169: MatPreallocated(B);
4170: if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4171: if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4172: 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);
4173: if (!A->ops->equal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4174: if (!B->ops->equal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4175: 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);
4176: MatPreallocated(A);
4178: (*A->ops->equal)(A,B,flg);
4179: return(0);
4180: }
4184: /*@
4185: MatDiagonalScale - Scales a matrix on the left and right by diagonal
4186: matrices that are stored as vectors. Either of the two scaling
4187: matrices can be PETSC_NULL.
4189: Collective on Mat
4191: Input Parameters:
4192: + mat - the matrix to be scaled
4193: . l - the left scaling vector (or PETSC_NULL)
4194: - r - the right scaling vector (or PETSC_NULL)
4196: Notes:
4197: MatDiagonalScale() computes A = LAR, where
4198: L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
4200: Level: intermediate
4202: Concepts: matrices^diagonal scaling
4203: Concepts: diagonal scaling of matrices
4205: .seealso: MatScale()
4206: @*/
4207: PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
4208: {
4214: if (!mat->ops->diagonalscale) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4217: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4218: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4219: MatPreallocated(mat);
4221: PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4222: (*mat->ops->diagonalscale)(mat,l,r);
4223: PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4224: PetscObjectStateIncrease((PetscObject)mat);
4225: return(0);
4226: }
4230: /*@
4231: MatScale - Scales all elements of a matrix by a given number.
4233: Collective on Mat
4235: Input Parameters:
4236: + mat - the matrix to be scaled
4237: - a - the scaling value
4239: Output Parameter:
4240: . mat - the scaled matrix
4242: Level: intermediate
4244: Concepts: matrices^scaling all entries
4246: .seealso: MatDiagonalScale()
4247: @*/
4248: PetscErrorCode MatScale(Mat mat,PetscScalar a)
4249: {
4255: if (a != 1.0 && !mat->ops->scale) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4256: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4257: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4258: MatPreallocated(mat);
4260: PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4261: if (a != 1.0) {
4262: (*mat->ops->scale)(mat,a);
4263: PetscObjectStateIncrease((PetscObject)mat);
4264: }
4265: PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4266: return(0);
4267: }
4271: /*@
4272: MatNorm - Calculates various norms of a matrix.
4274: Collective on Mat
4276: Input Parameters:
4277: + mat - the matrix
4278: - type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
4280: Output Parameters:
4281: . nrm - the resulting norm
4283: Level: intermediate
4285: Concepts: matrices^norm
4286: Concepts: norm^of matrix
4287: @*/
4288: PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
4289: {
4297: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4298: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4299: if (!mat->ops->norm) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4300: MatPreallocated(mat);
4302: (*mat->ops->norm)(mat,type,nrm);
4303: return(0);
4304: }
4306: /*
4307: This variable is used to prevent counting of MatAssemblyBegin() that
4308: are called from within a MatAssemblyEnd().
4309: */
4310: static PetscInt MatAssemblyEnd_InUse = 0;
4313: /*@
4314: MatAssemblyBegin - Begins assembling the matrix. This routine should
4315: be called after completing all calls to MatSetValues().
4317: Collective on Mat
4319: Input Parameters:
4320: + mat - the matrix
4321: - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
4322:
4323: Notes:
4324: MatSetValues() generally caches the values. The matrix is ready to
4325: use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4326: Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4327: in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4328: using the matrix.
4330: Level: beginner
4332: Concepts: matrices^assembling
4334: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
4335: @*/
4336: PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
4337: {
4343: MatPreallocated(mat);
4344: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
4345: if (mat->assembled) {
4346: mat->was_assembled = PETSC_TRUE;
4347: mat->assembled = PETSC_FALSE;
4348: }
4349: if (!MatAssemblyEnd_InUse) {
4350: PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);
4351: if (mat->ops->assemblybegin){(*mat->ops->assemblybegin)(mat,type);}
4352: PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);
4353: } else {
4354: if (mat->ops->assemblybegin){(*mat->ops->assemblybegin)(mat,type);}
4355: }
4356: return(0);
4357: }
4361: /*@
4362: MatAssembled - Indicates if a matrix has been assembled and is ready for
4363: use; for example, in matrix-vector product.
4365: Collective on Mat
4367: Input Parameter:
4368: . mat - the matrix
4370: Output Parameter:
4371: . assembled - PETSC_TRUE or PETSC_FALSE
4373: Level: advanced
4375: Concepts: matrices^assembled?
4377: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
4378: @*/
4379: PetscErrorCode MatAssembled(Mat mat,PetscTruth *assembled)
4380: {
4385: *assembled = mat->assembled;
4386: return(0);
4387: }
4391: /*
4392: Processes command line options to determine if/how a matrix
4393: is to be viewed. Called by MatAssemblyEnd() and MatLoad().
4394: */
4395: PetscErrorCode MatView_Private(Mat mat)
4396: {
4397: PetscErrorCode ierr;
4398: PetscTruth flg1,flg2,flg3,flg4,flg6,flg7,flg8;
4399: static PetscTruth incall = PETSC_FALSE;
4400: #if defined(PETSC_USE_SOCKET_VIEWER)
4401: PetscTruth flg5;
4402: #endif
4405: if (incall) return(0);
4406: incall = PETSC_TRUE;
4407: PetscOptionsBegin(((PetscObject)mat)->comm,((PetscObject)mat)->prefix,"Matrix Options","Mat");
4408: PetscOptionsName("-mat_view_info","Information on matrix size","MatView",&flg1);
4409: PetscOptionsName("-mat_view_info_detailed","Nonzeros in the matrix","MatView",&flg2);
4410: PetscOptionsName("-mat_view","Print matrix to stdout","MatView",&flg3);
4411: PetscOptionsName("-mat_view_matlab","Print matrix to stdout in a format Matlab can read","MatView",&flg4);
4412: #if defined(PETSC_USE_SOCKET_VIEWER)
4413: PetscOptionsName("-mat_view_socket","Send matrix to socket (can be read from matlab)","MatView",&flg5);
4414: #endif
4415: PetscOptionsName("-mat_view_binary","Save matrix to file in binary format","MatView",&flg6);
4416: PetscOptionsName("-mat_view_draw","Draw the matrix nonzero structure","MatView",&flg7);
4417: PetscOptionsEnd();
4419: if (flg1) {
4420: PetscViewer viewer;
4422: PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4423: PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO);
4424: MatView(mat,viewer);
4425: PetscViewerPopFormat(viewer);
4426: }
4427: if (flg2) {
4428: PetscViewer viewer;
4430: PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4431: PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO_DETAIL);
4432: MatView(mat,viewer);
4433: PetscViewerPopFormat(viewer);
4434: }
4435: if (flg3) {
4436: PetscViewer viewer;
4438: PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4439: MatView(mat,viewer);
4440: }
4441: if (flg4) {
4442: PetscViewer viewer;
4444: PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4445: PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);
4446: MatView(mat,viewer);
4447: PetscViewerPopFormat(viewer);
4448: }
4449: #if defined(PETSC_USE_SOCKET_VIEWER)
4450: if (flg5) {
4451: MatView(mat,PETSC_VIEWER_SOCKET_(((PetscObject)mat)->comm));
4452: PetscViewerFlush(PETSC_VIEWER_SOCKET_(((PetscObject)mat)->comm));
4453: }
4454: #endif
4455: if (flg6) {
4456: MatView(mat,PETSC_VIEWER_BINARY_(((PetscObject)mat)->comm));
4457: PetscViewerFlush(PETSC_VIEWER_BINARY_(((PetscObject)mat)->comm));
4458: }
4459: if (flg7) {
4460: PetscOptionsHasName(((PetscObject)mat)->prefix,"-mat_view_contour",&flg8);
4461: if (flg8) {
4462: PetscViewerPushFormat(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm),PETSC_VIEWER_DRAW_CONTOUR);
4463: }
4464: MatView(mat,PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));
4465: PetscViewerFlush(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));
4466: if (flg8) {
4467: PetscViewerPopFormat(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));
4468: }
4469: }
4470: incall = PETSC_FALSE;
4471: return(0);
4472: }
4476: /*@
4477: MatAssemblyEnd - Completes assembling the matrix. This routine should
4478: be called after MatAssemblyBegin().
4480: Collective on Mat
4482: Input Parameters:
4483: + mat - the matrix
4484: - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
4486: Options Database Keys:
4487: + -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly()
4488: . -mat_view_info_detailed - Prints more detailed info
4489: . -mat_view - Prints matrix in ASCII format
4490: . -mat_view_matlab - Prints matrix in Matlab format
4491: . -mat_view_draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
4492: . -display <name> - Sets display name (default is host)
4493: . -draw_pause <sec> - Sets number of seconds to pause after display
4494: . -mat_view_socket - Sends matrix to socket, can be accessed from Matlab (see users manual)
4495: . -viewer_socket_machine <machine>
4496: . -viewer_socket_port <port>
4497: . -mat_view_binary - save matrix to file in binary format
4498: - -viewer_binary_filename <name>
4500: Notes:
4501: MatSetValues() generally caches the values. The matrix is ready to
4502: use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4503: Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4504: in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4505: using the matrix.
4507: Level: beginner
4509: .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), MatView(), MatAssembled(), PetscViewerSocketOpen()
4510: @*/
4511: PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
4512: {
4513: PetscErrorCode ierr;
4514: static PetscInt inassm = 0;
4515: PetscTruth flg;
4521: inassm++;
4522: MatAssemblyEnd_InUse++;
4523: if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
4524: PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);
4525: if (mat->ops->assemblyend) {
4526: (*mat->ops->assemblyend)(mat,type);
4527: }
4528: PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);
4529: } else {
4530: if (mat->ops->assemblyend) {
4531: (*mat->ops->assemblyend)(mat,type);
4532: }
4533: }
4535: /* Flush assembly is not a true assembly */
4536: if (type != MAT_FLUSH_ASSEMBLY) {
4537: mat->assembled = PETSC_TRUE; mat->num_ass++;
4538: }
4539: mat->insertmode = NOT_SET_VALUES;
4540: MatAssemblyEnd_InUse--;
4541: PetscObjectStateIncrease((PetscObject)mat);
4542: if (!mat->symmetric_eternal) {
4543: mat->symmetric_set = PETSC_FALSE;
4544: mat->hermitian_set = PETSC_FALSE;
4545: mat->structurally_symmetric_set = PETSC_FALSE;
4546: }
4547: if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
4548: MatView_Private(mat);
4549: PetscOptionsHasName(((PetscObject)mat)->prefix,"-mat_is_symmetric",&flg);
4550: if (flg) {
4551: PetscReal tol = 0.0;
4552: PetscOptionsGetReal(((PetscObject)mat)->prefix,"-mat_is_symmetric",&tol,PETSC_NULL);
4553: MatIsSymmetric(mat,tol,&flg);
4554: if (flg) {
4555: PetscPrintf(((PetscObject)mat)->comm,"Matrix is symmetric (tolerance %G)\n",tol);
4556: } else {
4557: PetscPrintf(((PetscObject)mat)->comm,"Matrix is not symmetric (tolerance %G)\n",tol);
4558: }
4559: }
4560: }
4561: inassm--;
4562: return(0);
4563: }
4568: /*@
4569: MatCompress - Tries to store the matrix in as little space as
4570: possible. May fail if memory is already fully used, since it
4571: tries to allocate new space.
4573: Collective on Mat
4575: Input Parameters:
4576: . mat - the matrix
4578: Level: advanced
4580: @*/
4581: PetscErrorCode MatCompress(Mat mat)
4582: {
4588: MatPreallocated(mat);
4589: if (mat->ops->compress) {(*mat->ops->compress)(mat);}
4590: return(0);
4591: }
4595: /*@
4596: MatSetOption - Sets a parameter option for a matrix. Some options
4597: may be specific to certain storage formats. Some options
4598: determine how values will be inserted (or added). Sorted,
4599: row-oriented input will generally assemble the fastest. The default
4600: is row-oriented, nonsorted input.
4602: Collective on Mat
4604: Input Parameters:
4605: + mat - the matrix
4606: . option - the option, one of those listed below (and possibly others),
4607: - flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
4609: Options Describing Matrix Structure:
4610: + MAT_SYMMETRIC - symmetric in terms of both structure and value
4611: . MAT_HERMITIAN - transpose is the complex conjugation
4612: . MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
4613: - MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
4614: you set to be kept with all future use of the matrix
4615: including after MatAssemblyBegin/End() which could
4616: potentially change the symmetry structure, i.e. you
4617: KNOW the matrix will ALWAYS have the property you set.
4620: Options For Use with MatSetValues():
4621: Insert a logically dense subblock, which can be
4622: . MAT_ROW_ORIENTED - row-oriented (default)
4624: Note these options reflect the data you pass in with MatSetValues(); it has
4625: nothing to do with how the data is stored internally in the matrix
4626: data structure.
4628: When (re)assembling a matrix, we can restrict the input for
4629: efficiency/debugging purposes. These options include
4630: + MAT_NEW_NONZERO_LOCATIONS - additional insertions will be
4631: allowed if they generate a new nonzero
4632: . MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
4633: . MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
4634: . MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
4635: - MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
4637: Notes:
4638: Some options are relevant only for particular matrix types and
4639: are thus ignored by others. Other options are not supported by
4640: certain matrix types and will generate an error message if set.
4642: If using a Fortran 77 module to compute a matrix, one may need to
4643: use the column-oriented option (or convert to the row-oriented
4644: format).
4646: MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
4647: that would generate a new entry in the nonzero structure is instead
4648: ignored. Thus, if memory has not alredy been allocated for this particular
4649: data, then the insertion is ignored. For dense matrices, in which
4650: the entire array is allocated, no entries are ever ignored.
4651: Set after the first MatAssemblyEnd()
4653: MAT_NEW_NONZERO_LOCATION_ERR indicates that any add or insertion
4654: that would generate a new entry in the nonzero structure instead produces
4655: an error. (Currently supported for AIJ and BAIJ formats only.)
4656: This is a useful flag when using SAME_NONZERO_PATTERN in calling
4657: KSPSetOperators() to ensure that the nonzero pattern truely does
4658: remain unchanged. Set after the first MatAssemblyEnd()
4660: MAT_NEW_NONZERO_ALLOCATION_ERR indicates that any add or insertion
4661: that would generate a new entry that has not been preallocated will
4662: instead produce an error. (Currently supported for AIJ and BAIJ formats
4663: only.) This is a useful flag when debugging matrix memory preallocation.
4665: MAT_IGNORE_OFF_PROC_ENTRIES indicates entries destined for
4666: other processors should be dropped, rather than stashed.
4667: This is useful if you know that the "owning" processor is also
4668: always generating the correct matrix entries, so that PETSc need
4669: not transfer duplicate entries generated on another processor.
4670:
4671: MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
4672: searches during matrix assembly. When this flag is set, the hash table
4673: is created during the first Matrix Assembly. This hash table is
4674: used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
4675: to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
4676: should be used with MAT_USE_HASH_TABLE flag. This option is currently
4677: supported by MATMPIBAIJ format only.
4679: MAT_KEEP_ZEROED_ROWS indicates when MatZeroRows() is called the zeroed entries
4680: are kept in the nonzero structure
4682: MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
4683: a zero location in the matrix
4685: MAT_USE_INODES - indicates using inode version of the code - works with AIJ and
4686: ROWBS matrix types
4688: Level: intermediate
4690: Concepts: matrices^setting options
4692: @*/
4693: PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscTruth flg)
4694: {
4700: if (((int) op) < 0 || ((int) op) >= NUM_MAT_OPTIONS) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Options %d is out of range",(int)op);
4701: MatPreallocated(mat);
4702: switch (op) {
4703: case MAT_SYMMETRIC:
4704: mat->symmetric = flg;
4705: if (flg) mat->structurally_symmetric = PETSC_TRUE;
4706: mat->symmetric_set = PETSC_TRUE;
4707: mat->structurally_symmetric_set = flg;
4708: break;
4709: case MAT_HERMITIAN:
4710: mat->hermitian = flg;
4711: if (flg) mat->structurally_symmetric = PETSC_TRUE;
4712: mat->hermitian_set = PETSC_TRUE;
4713: mat->structurally_symmetric_set = flg;
4714: break;
4715: case MAT_STRUCTURALLY_SYMMETRIC:
4716: mat->structurally_symmetric = flg;
4717: mat->structurally_symmetric_set = PETSC_TRUE;
4718: break;
4719: case MAT_SYMMETRY_ETERNAL:
4720: mat->symmetric_eternal = flg;
4721: break;
4722: default:
4723: break;
4724: }
4725: if (mat->ops->setoption) {
4726: (*mat->ops->setoption)(mat,op,flg);
4727: }
4728: return(0);
4729: }
4733: /*@
4734: MatZeroEntries - Zeros all entries of a matrix. For sparse matrices
4735: this routine retains the old nonzero structure.
4737: Collective on Mat
4739: Input Parameters:
4740: . mat - the matrix
4742: Level: intermediate
4744: Concepts: matrices^zeroing
4746: .seealso: MatZeroRows()
4747: @*/
4748: PetscErrorCode MatZeroEntries(Mat mat)
4749: {
4755: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4756: if (mat->insertmode != NOT_SET_VALUES) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for matrices where you have set values but not yet assembled");
4757: if (!mat->ops->zeroentries) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4758: MatPreallocated(mat);
4760: PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);
4761: (*mat->ops->zeroentries)(mat);
4762: PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);
4763: PetscObjectStateIncrease((PetscObject)mat);
4764: return(0);
4765: }
4769: /*@C
4770: MatZeroRows - Zeros all entries (except possibly the main diagonal)
4771: of a set of rows of a matrix.
4773: Collective on Mat
4775: Input Parameters:
4776: + mat - the matrix
4777: . numRows - the number of rows to remove
4778: . rows - the global row indices
4779: - diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
4781: Notes:
4782: For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
4783: but does not release memory. For the dense and block diagonal
4784: formats this does not alter the nonzero structure.
4786: If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS,PETSC_TRUE) the nonzero structure
4787: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
4788: merely zeroed.
4790: The user can set a value in the diagonal entry (or for the AIJ and
4791: row formats can optionally remove the main diagonal entry from the
4792: nonzero structure as well, by passing 0.0 as the final argument).
4794: For the parallel case, all processes that share the matrix (i.e.,
4795: those in the communicator used for matrix creation) MUST call this
4796: routine, regardless of whether any rows being zeroed are owned by
4797: them.
4799: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
4800: list only rows local to itself).
4802: Level: intermediate
4804: Concepts: matrices^zeroing rows
4806: .seealso: MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
4807: @*/
4808: PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag)
4809: {
4816: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4817: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4818: if (!mat->ops->zerorows) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4819: MatPreallocated(mat);
4821: (*mat->ops->zerorows)(mat,numRows,rows,diag);
4822: MatView_Private(mat);
4823: PetscObjectStateIncrease((PetscObject)mat);
4824: return(0);
4825: }
4829: /*@C
4830: MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
4831: of a set of rows of a matrix.
4833: Collective on Mat
4835: Input Parameters:
4836: + mat - the matrix
4837: . is - index set of rows to remove
4838: - diag - value put in all diagonals of eliminated rows
4840: Notes:
4841: For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
4842: but does not release memory. For the dense and block diagonal
4843: formats this does not alter the nonzero structure.
4845: If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS,PETSC_TRUE) the nonzero structure
4846: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
4847: merely zeroed.
4849: The user can set a value in the diagonal entry (or for the AIJ and
4850: row formats can optionally remove the main diagonal entry from the
4851: nonzero structure as well, by passing 0.0 as the final argument).
4853: For the parallel case, all processes that share the matrix (i.e.,
4854: those in the communicator used for matrix creation) MUST call this
4855: routine, regardless of whether any rows being zeroed are owned by
4856: them.
4858: Each processor should list the rows that IT wants zeroed
4860: Level: intermediate
4862: Concepts: matrices^zeroing rows
4864: .seealso: MatZeroRows(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
4865: @*/
4866: PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag)
4867: {
4868: PetscInt numRows;
4869: const PetscInt *rows;
4876: ISGetLocalSize(is,&numRows);
4877: ISGetIndices(is,&rows);
4878: MatZeroRows(mat,numRows,rows,diag);
4879: ISRestoreIndices(is,&rows);
4880: return(0);
4881: }
4885: /*@C
4886: MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
4887: of a set of rows of a matrix; using local numbering of rows.
4889: Collective on Mat
4891: Input Parameters:
4892: + mat - the matrix
4893: . numRows - the number of rows to remove
4894: . rows - the global row indices
4895: - diag - value put in all diagonals of eliminated rows
4897: Notes:
4898: Before calling MatZeroRowsLocal(), the user must first set the
4899: local-to-global mapping by calling MatSetLocalToGlobalMapping().
4901: For the AIJ matrix formats this removes the old nonzero structure,
4902: but does not release memory. For the dense and block diagonal
4903: formats this does not alter the nonzero structure.
4905: If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS,PETSC_TRUE) the nonzero structure
4906: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
4907: merely zeroed.
4909: The user can set a value in the diagonal entry (or for the AIJ and
4910: row formats can optionally remove the main diagonal entry from the
4911: nonzero structure as well, by passing 0.0 as the final argument).
4913: Level: intermediate
4915: Concepts: matrices^zeroing
4917: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
4918: @*/
4919: PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag)
4920: {
4927: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4928: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4929: MatPreallocated(mat);
4931: if (mat->ops->zerorowslocal) {
4932: (*mat->ops->zerorowslocal)(mat,numRows,rows,diag);
4933: } else {
4934: IS is, newis;
4935: const PetscInt *newRows;
4937: if (!mat->mapping) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
4938: ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,&is);
4939: ISLocalToGlobalMappingApplyIS(mat->mapping,is,&newis);
4940: ISGetIndices(newis,&newRows);
4941: (*mat->ops->zerorows)(mat,numRows,newRows,diag);
4942: ISRestoreIndices(newis,&newRows);
4943: ISDestroy(newis);
4944: ISDestroy(is);
4945: }
4946: PetscObjectStateIncrease((PetscObject)mat);
4947: return(0);
4948: }
4952: /*@C
4953: MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
4954: of a set of rows of a matrix; using local numbering of rows.
4956: Collective on Mat
4958: Input Parameters:
4959: + mat - the matrix
4960: . is - index set of rows to remove
4961: - diag - value put in all diagonals of eliminated rows
4963: Notes:
4964: Before calling MatZeroRowsLocalIS(), the user must first set the
4965: local-to-global mapping by calling MatSetLocalToGlobalMapping().
4967: For the AIJ matrix formats this removes the old nonzero structure,
4968: but does not release memory. For the dense and block diagonal
4969: formats this does not alter the nonzero structure.
4971: If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS,PETSC_TRUE) the nonzero structure
4972: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
4973: merely zeroed.
4975: The user can set a value in the diagonal entry (or for the AIJ and
4976: row formats can optionally remove the main diagonal entry from the
4977: nonzero structure as well, by passing 0.0 as the final argument).
4979: Level: intermediate
4981: Concepts: matrices^zeroing
4983: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
4984: @*/
4985: PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag)
4986: {
4988: PetscInt numRows;
4989: const PetscInt *rows;
4995: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4996: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4997: MatPreallocated(mat);
4999: ISGetLocalSize(is,&numRows);
5000: ISGetIndices(is,&rows);
5001: MatZeroRowsLocal(mat,numRows,rows,diag);
5002: ISRestoreIndices(is,&rows);
5003: return(0);
5004: }
5008: /*@
5009: MatGetSize - Returns the numbers of rows and columns in a matrix.
5011: Not Collective
5013: Input Parameter:
5014: . mat - the matrix
5016: Output Parameters:
5017: + m - the number of global rows
5018: - n - the number of global columns
5020: Note: both output parameters can be PETSC_NULL on input.
5022: Level: beginner
5024: Concepts: matrices^size
5026: .seealso: MatGetLocalSize()
5027: @*/
5028: PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt* n)
5029: {
5032: if (m) *m = mat->rmap->N;
5033: if (n) *n = mat->cmap->N;
5034: return(0);
5035: }
5039: /*@
5040: MatGetLocalSize - Returns the number of rows and columns in a matrix
5041: stored locally. This information may be implementation dependent, so
5042: use with care.
5044: Not Collective
5046: Input Parameters:
5047: . mat - the matrix
5049: Output Parameters:
5050: + m - the number of local rows
5051: - n - the number of local columns
5053: Note: both output parameters can be PETSC_NULL on input.
5055: Level: beginner
5057: Concepts: matrices^local size
5059: .seealso: MatGetSize()
5060: @*/
5061: PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt* n)
5062: {
5067: if (m) *m = mat->rmap->n;
5068: if (n) *n = mat->cmap->n;
5069: return(0);
5070: }
5074: /*@
5075: MatGetOwnershipRangeColumn - Returns the range of matrix columns owned by
5076: this processor.
5078: Not Collective, unless matrix has not been allocated, then collective on Mat
5080: Input Parameters:
5081: . mat - the matrix
5083: Output Parameters:
5084: + m - the global index of the first local column
5085: - n - one more than the global index of the last local column
5087: Notes: both output parameters can be PETSC_NULL on input.
5089: Level: developer
5091: Concepts: matrices^column ownership
5093: .seealso: MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
5095: @*/
5096: PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt* n)
5097: {
5105: MatPreallocated(mat);
5106: if (m) *m = mat->cmap->rstart;
5107: if (n) *n = mat->cmap->rend;
5108: return(0);
5109: }
5113: /*@
5114: MatGetOwnershipRange - Returns the range of matrix rows owned by
5115: this processor, assuming that the matrix is laid out with the first
5116: n1 rows on the first processor, the next n2 rows on the second, etc.
5117: For certain parallel layouts this range may not be well defined.
5119: Not Collective, unless matrix has not been allocated, then collective on Mat
5121: Input Parameters:
5122: . mat - the matrix
5124: Output Parameters:
5125: + m - the global index of the first local row
5126: - n - one more than the global index of the last local row
5128: Note: both output parameters can be PETSC_NULL on input.
5130: Level: beginner
5132: Concepts: matrices^row ownership
5134: .seealso: MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
5136: @*/
5137: PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt* n)
5138: {
5146: MatPreallocated(mat);
5147: if (m) *m = mat->rmap->rstart;
5148: if (n) *n = mat->rmap->rend;
5149: return(0);
5150: }
5154: /*@C
5155: MatGetOwnershipRanges - Returns the range of matrix rows owned by
5156: each process
5158: Not Collective, unless matrix has not been allocated, then collective on Mat
5160: Input Parameters:
5161: . mat - the matrix
5163: Output Parameters:
5164: . ranges - start of each processors portion plus one more then the total length at the end
5166: Level: beginner
5168: Concepts: matrices^row ownership
5170: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
5172: @*/
5173: PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
5174: {
5180: MatPreallocated(mat);
5181: PetscMapGetRanges(mat->rmap,ranges);
5182: return(0);
5183: }
5187: /*@C
5188: MatGetOwnershipRangesColumn - Returns the range of local columns for each process
5190: Not Collective, unless matrix has not been allocated, then collective on Mat
5192: Input Parameters:
5193: . mat - the matrix
5195: Output Parameters:
5196: . ranges - start of each processors portion plus one more then the total length at the end
5198: Level: beginner
5200: Concepts: matrices^column ownership
5202: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
5204: @*/
5205: PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
5206: {
5212: MatPreallocated(mat);
5213: PetscMapGetRanges(mat->cmap,ranges);
5214: return(0);
5215: }
5219: /*@
5220: MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
5221: Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
5222: to complete the factorization.
5224: Collective on Mat
5226: Input Parameters:
5227: + mat - the matrix
5228: . row - row permutation
5229: . column - column permutation
5230: - info - structure containing
5231: $ levels - number of levels of fill.
5232: $ expected fill - as ratio of original fill.
5233: $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices
5234: missing diagonal entries)
5236: Output Parameters:
5237: . fact - new matrix that has been symbolically factored
5239: Notes:
5240: See the users manual for additional information about
5241: choosing the fill factor for better efficiency.
5243: Most users should employ the simplified KSP interface for linear solvers
5244: instead of working directly with matrix algebra routines such as this.
5245: See, e.g., KSPCreate().
5247: Level: developer
5249: Concepts: matrices^symbolic LU factorization
5250: Concepts: matrices^factorization
5251: Concepts: LU^symbolic factorization
5253: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
5254: MatGetOrdering(), MatFactorInfo
5256: @*/
5257: PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
5258: {
5268: if (info->levels < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
5269: if (info->fill < 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
5270: if (!(fact)->ops->ilufactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s symbolic ILU",((PetscObject)mat)->type_name);
5271: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5272: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5273: MatPreallocated(mat);
5275: PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);
5276: (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);
5277: PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);
5278: return(0);
5279: }
5283: /*@
5284: MatICCFactorSymbolic - Performs symbolic incomplete
5285: Cholesky factorization for a symmetric matrix. Use
5286: MatCholeskyFactorNumeric() to complete the factorization.
5288: Collective on Mat
5290: Input Parameters:
5291: + mat - the matrix
5292: . perm - row and column permutation
5293: - info - structure containing
5294: $ levels - number of levels of fill.
5295: $ expected fill - as ratio of original fill.
5297: Output Parameter:
5298: . fact - the factored matrix
5300: Notes:
5301: Most users should employ the KSP interface for linear solvers
5302: instead of working directly with matrix algebra routines such as this.
5303: See, e.g., KSPCreate().
5305: Level: developer
5307: Concepts: matrices^symbolic incomplete Cholesky factorization
5308: Concepts: matrices^factorization
5309: Concepts: Cholsky^symbolic factorization
5311: .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
5312: @*/
5313: PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
5314: {
5323: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5324: if (info->levels < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
5325: if (info->fill < 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
5326: if (!(fact)->ops->iccfactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s symbolic ICC",((PetscObject)mat)->type_name);
5327: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5328: MatPreallocated(mat);
5330: PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);
5331: (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);
5332: PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);
5333: return(0);
5334: }
5338: /*@C
5339: MatGetArray - Returns a pointer to the element values in the matrix.
5340: The result of this routine is dependent on the underlying matrix data
5341: structure, and may not even work for certain matrix types. You MUST
5342: call MatRestoreArray() when you no longer need to access the array.
5344: Not Collective
5346: Input Parameter:
5347: . mat - the matrix
5349: Output Parameter:
5350: . v - the location of the values
5353: Fortran Note:
5354: This routine is used differently from Fortran, e.g.,
5355: .vb
5356: Mat mat
5357: PetscScalar mat_array(1)
5358: PetscOffset i_mat
5359: PetscErrorCode ierr
5360: call MatGetArray(mat,mat_array,i_mat,ierr)
5362: C Access first local entry in matrix; note that array is
5363: C treated as one dimensional
5364: value = mat_array(i_mat + 1)
5366: [... other code ...]
5367: call MatRestoreArray(mat,mat_array,i_mat,ierr)
5368: .ve
5370: See the Fortran chapter of the users manual and
5371: petsc/src/mat/examples/tests for details.
5373: Level: advanced
5375: Concepts: matrices^access array
5377: .seealso: MatRestoreArray(), MatGetArrayF90(), MatGetRowIJ()
5378: @*/
5379: PetscErrorCode MatGetArray(Mat mat,PetscScalar *v[])
5380: {
5387: if (!mat->ops->getarray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5388: MatPreallocated(mat);
5389: (*mat->ops->getarray)(mat,v);
5390: CHKMEMQ;
5391: return(0);
5392: }
5396: /*@C
5397: MatRestoreArray - Restores the matrix after MatGetArray() has been called.
5399: Not Collective
5401: Input Parameter:
5402: + mat - the matrix
5403: - v - the location of the values
5405: Fortran Note:
5406: This routine is used differently from Fortran, e.g.,
5407: .vb
5408: Mat mat
5409: PetscScalar mat_array(1)
5410: PetscOffset i_mat
5411: PetscErrorCode ierr
5412: call MatGetArray(mat,mat_array,i_mat,ierr)
5414: C Access first local entry in matrix; note that array is
5415: C treated as one dimensional
5416: value = mat_array(i_mat + 1)
5418: [... other code ...]
5419: call MatRestoreArray(mat,mat_array,i_mat,ierr)
5420: .ve
5422: See the Fortran chapter of the users manual and
5423: petsc/src/mat/examples/tests for details
5425: Level: advanced
5427: .seealso: MatGetArray(), MatRestoreArrayF90()
5428: @*/
5429: PetscErrorCode MatRestoreArray(Mat mat,PetscScalar *v[])
5430: {
5437: #if defined(PETSC_USE_DEBUG)
5438: CHKMEMQ;
5439: #endif
5440: if (!mat->ops->restorearray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5441: (*mat->ops->restorearray)(mat,v);
5442: PetscObjectStateIncrease((PetscObject)mat);
5443: return(0);
5444: }
5448: /*@C
5449: MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
5450: points to an array of valid matrices, they may be reused to store the new
5451: submatrices.
5453: Collective on Mat
5455: Input Parameters:
5456: + mat - the matrix
5457: . n - the number of submatrixes to be extracted (on this processor, may be zero)
5458: . irow, icol - index sets of rows and columns to extract
5459: - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
5461: Output Parameter:
5462: . submat - the array of submatrices
5464: Notes:
5465: MatGetSubMatrices() can extract ONLY sequential submatrices
5466: (from both sequential and parallel matrices). Use MatGetSubMatrix()
5467: to extract a parallel submatrix.
5469: When extracting submatrices from a parallel matrix, each processor can
5470: form a different submatrix by setting the rows and columns of its
5471: individual index sets according to the local submatrix desired.
5473: When finished using the submatrices, the user should destroy
5474: them with MatDestroyMatrices().
5476: MAT_REUSE_MATRIX can only be used when the nonzero structure of the
5477: original matrix has not changed from that last call to MatGetSubMatrices().
5479: This routine creates the matrices in submat; you should NOT create them before
5480: calling it. It also allocates the array of matrix pointers submat.
5482: For BAIJ matrices the index sets must respect the block structure, that is if they
5483: request one row/column in a block, they must request all rows/columns that are in
5484: that block. For example, if the block size is 2 you cannot request just row 0 and
5485: column 0.
5487: Fortran Note:
5488: The Fortran interface is slightly different from that given below; it
5489: requires one to pass in as submat a Mat (integer) array of size at least m.
5491: Level: advanced
5493: Concepts: matrices^accessing submatrices
5494: Concepts: submatrices
5496: .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
5497: @*/
5498: PetscErrorCode MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
5499: {
5501: PetscInt i;
5502: PetscTruth eq;
5507: if (n) {
5512: }
5514: if (n && scall == MAT_REUSE_MATRIX) {
5517: }
5518: if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5519: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5520: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5521: MatPreallocated(mat);
5523: PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
5524: (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);
5525: PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
5526: for (i=0; i<n; i++) {
5527: if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
5528: ISEqual(irow[i],icol[i],&eq);
5529: if (eq) {
5530: if (mat->symmetric){
5531: MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
5532: } else if (mat->hermitian) {
5533: MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
5534: } else if (mat->structurally_symmetric) {
5535: MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
5536: }
5537: }
5538: }
5539: }
5540: return(0);
5541: }
5545: /*@C
5546: MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().
5548: Collective on Mat
5550: Input Parameters:
5551: + n - the number of local matrices
5552: - mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
5553: sequence of MatGetSubMatrices())
5555: Level: advanced
5557: Notes: Frees not only the matrices, but also the array that contains the matrices
5558: In Fortran will not free the array.
5560: .seealso: MatGetSubMatrices()
5561: @*/
5562: PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
5563: {
5565: PetscInt i;
5568: if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
5570: for (i=0; i<n; i++) {
5571: MatDestroy((*mat)[i]);
5572: }
5573: /* memory is allocated even if n = 0 */
5574: PetscFree(*mat);
5575: return(0);
5576: }
5580: /*@C
5581: MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
5583: Collective on Mat
5585: Input Parameters:
5586: . mat - the matrix
5588: Output Parameter:
5589: . matstruct - the sequential matrix with the nonzero structure of mat
5591: Level: intermediate
5593: .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
5594: @*/
5595: PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct[])
5596: {
5602:
5604: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5605: MatPreallocated(mat);
5607: PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);
5608: (*mat->ops->getseqnonzerostructure)(mat,matstruct);
5609: PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);
5610: return(0);
5611: }
5615: /*@C
5616: MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
5618: Collective on Mat
5620: Input Parameters:
5621: . mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
5622: sequence of MatGetSequentialNonzeroStructure())
5624: Level: advanced
5626: Notes: Frees not only the matrices, but also the array that contains the matrices
5628: .seealso: MatGetSeqNonzeroStructure()
5629: @*/
5630: PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat[])
5631: {
5636: MatDestroyMatrices(1,mat);
5637: return(0);
5638: }
5642: /*@
5643: MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
5644: replaces the index sets by larger ones that represent submatrices with
5645: additional overlap.
5647: Collective on Mat
5649: Input Parameters:
5650: + mat - the matrix
5651: . n - the number of index sets
5652: . is - the array of index sets (these index sets will changed during the call)
5653: - ov - the additional overlap requested
5655: Level: developer
5657: Concepts: overlap
5658: Concepts: ASM^computing overlap
5660: .seealso: MatGetSubMatrices()
5661: @*/
5662: PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
5663: {
5669: if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
5670: if (n) {
5673: }
5674: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5675: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5676: MatPreallocated(mat);
5678: if (!ov) return(0);
5679: if (!mat->ops->increaseoverlap) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5680: PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
5681: (*mat->ops->increaseoverlap)(mat,n,is,ov);
5682: PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
5683: return(0);
5684: }
5688: /*@
5689: MatGetBlockSize - Returns the matrix block size; useful especially for the
5690: block row and block diagonal formats.
5691:
5692: Not Collective
5694: Input Parameter:
5695: . mat - the matrix
5697: Output Parameter:
5698: . bs - block size
5700: Notes:
5701: Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ
5703: Level: intermediate
5705: Concepts: matrices^block size
5707: .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ()
5708: @*/
5709: PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
5710: {
5717: MatPreallocated(mat);
5718: *bs = mat->rmap->bs;
5719: return(0);
5720: }
5724: /*@
5725: MatSetBlockSize - Sets the matrix block size; for many matrix types you
5726: cannot use this and MUST set the blocksize when you preallocate the matrix
5727:
5728: Collective on Mat
5730: Input Parameters:
5731: + mat - the matrix
5732: - bs - block size
5734: Notes:
5735: Only works for shell and AIJ matrices
5737: Level: intermediate
5739: Concepts: matrices^block size
5741: .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ(), MatGetBlockSize()
5742: @*/
5743: PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
5744: {
5750: MatPreallocated(mat);
5751: if (mat->ops->setblocksize) {
5752: /* XXX should check if (bs < 1) ??? */
5753: PetscMapSetBlockSize(mat->rmap,bs);
5754: PetscMapSetBlockSize(mat->cmap,bs);
5755: (*mat->ops->setblocksize)(mat,bs);
5756: } else {
5757: SETERRQ1(PETSC_ERR_ARG_INCOMP,"Cannot set the blocksize for matrix type %s",((PetscObject)mat)->type_name);
5758: }
5759: return(0);
5760: }
5764: /*@C
5765: MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
5767: Collective on Mat
5769: Input Parameters:
5770: + mat - the matrix
5771: . shift - 0 or 1 indicating we want the indices starting at 0 or 1
5772: . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5773: symmetrized
5774: - blockcompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
5775: blockcompressed matrix is desired or not [inode, baij have blockcompressed
5776: nonzero structure which is different than the full nonzero structure]
5778: Output Parameters:
5779: + n - number of rows in the (possibly compressed) matrix
5780: . ia - the row pointers [of length n+1]
5781: . ja - the column indices
5782: - done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
5783: are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
5785: Level: developer
5787: Notes: You CANNOT change any of the ia[] or ja[] values.
5789: Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values
5791: Fortran Node
5793: In Fortran use
5794: $ PetscInt ia(1), ja(1)
5795: $ PetscOffset iia, jja
5796: $ call MatGetRowIJ(mat,shift,symmetric,blockcompressed,n,ia,iia,ja,jja,done,ierr)
5797:
5798: Acess the ith and jth entries via ia(iia + i) and ja(jja + j)
5800: .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatGetArray()
5801: @*/
5802: PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth blockcompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5803: {
5813: MatPreallocated(mat);
5814: if (!mat->ops->getrowij) *done = PETSC_FALSE;
5815: else {
5816: *done = PETSC_TRUE;
5817: PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);
5818: (*mat->ops->getrowij)(mat,shift,symmetric,blockcompressed,n,ia,ja,done);
5819: PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);
5820: }
5821: return(0);
5822: }
5826: /*@C
5827: MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
5829: Collective on Mat
5831: Input Parameters:
5832: + mat - the matrix
5833: . shift - 1 or zero indicating we want the indices starting at 0 or 1
5834: . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5835: symmetrized
5836: - blockcompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
5837: blockcompressed matrix is desired or not [inode, baij have blockcompressed
5838: nonzero structure which is different than the full nonzero structure]
5840: Output Parameters:
5841: + n - number of columns in the (possibly compressed) matrix
5842: . ia - the column pointers
5843: . ja - the row indices
5844: - done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
5846: Level: developer
5848: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
5849: @*/
5850: PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth blockcompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5851: {
5861: MatPreallocated(mat);
5862: if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
5863: else {
5864: *done = PETSC_TRUE;
5865: (*mat->ops->getcolumnij)(mat,shift,symmetric,blockcompressed,n,ia,ja,done);
5866: }
5867: return(0);
5868: }
5872: /*@C
5873: MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
5874: MatGetRowIJ().
5876: Collective on Mat
5878: Input Parameters:
5879: + mat - the matrix
5880: . shift - 1 or zero indicating we want the indices starting at 0 or 1
5881: . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5882: symmetrized
5883: - blockcompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
5884: blockcompressed matrix is desired or not [inode, baij have blockcompressed
5885: nonzero structure which is different than the full nonzero structure]
5887: Output Parameters:
5888: + n - size of (possibly compressed) matrix
5889: . ia - the row pointers
5890: . ja - the column indices
5891: - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
5893: Level: developer
5895: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
5896: @*/
5897: PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth blockcompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5898: {
5907: MatPreallocated(mat);
5909: if (!mat->ops->restorerowij) *done = PETSC_FALSE;
5910: else {
5911: *done = PETSC_TRUE;
5912: (*mat->ops->restorerowij)(mat,shift,symmetric,blockcompressed,n,ia,ja,done);
5913: }
5914: return(0);
5915: }
5919: /*@C
5920: MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
5921: MatGetColumnIJ().
5923: Collective on Mat
5925: Input Parameters:
5926: + mat - the matrix
5927: . shift - 1 or zero indicating we want the indices starting at 0 or 1
5928: - symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5929: symmetrized
5930: - blockcompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
5931: blockcompressed matrix is desired or not [inode, baij have blockcompressed
5932: nonzero structure which is different than the full nonzero structure]
5934: Output Parameters:
5935: + n - size of (possibly compressed) matrix
5936: . ia - the column pointers
5937: . ja - the row indices
5938: - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
5940: Level: developer
5942: .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
5943: @*/
5944: PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth blockcompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5945: {
5954: MatPreallocated(mat);
5956: if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
5957: else {
5958: *done = PETSC_TRUE;
5959: (*mat->ops->restorecolumnij)(mat,shift,symmetric,blockcompressed,n,ia,ja,done);
5960: }
5961: return(0);
5962: }
5966: /*@C
5967: MatColoringPatch -Used inside matrix coloring routines that
5968: use MatGetRowIJ() and/or MatGetColumnIJ().
5970: Collective on Mat
5972: Input Parameters:
5973: + mat - the matrix
5974: . ncolors - max color value
5975: . n - number of entries in colorarray
5976: - colorarray - array indicating color for each column
5978: Output Parameters:
5979: . iscoloring - coloring generated using colorarray information
5981: Level: developer
5983: .seealso: MatGetRowIJ(), MatGetColumnIJ()
5985: @*/
5986: PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
5987: {
5995: MatPreallocated(mat);
5997: if (!mat->ops->coloringpatch){
5998: ISColoringCreate(((PetscObject)mat)->comm,ncolors,n,colorarray,iscoloring);
5999: } else {
6000: (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);
6001: }
6002: return(0);
6003: }
6008: /*@
6009: MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
6011: Collective on Mat
6013: Input Parameter:
6014: . mat - the factored matrix to be reset
6016: Notes:
6017: This routine should be used only with factored matrices formed by in-place
6018: factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
6019: format). This option can save memory, for example, when solving nonlinear
6020: systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
6021: ILU(0) preconditioner.
6023: Note that one can specify in-place ILU(0) factorization by calling
6024: .vb
6025: PCType(pc,PCILU);
6026: PCFactorSeUseInPlace(pc);
6027: .ve
6028: or by using the options -pc_type ilu -pc_factor_in_place
6030: In-place factorization ILU(0) can also be used as a local
6031: solver for the blocks within the block Jacobi or additive Schwarz
6032: methods (runtime option: -sub_pc_factor_in_place). See the discussion
6033: of these preconditioners in the users manual for details on setting
6034: local solver options.
6036: Most users should employ the simplified KSP interface for linear solvers
6037: instead of working directly with matrix algebra routines such as this.
6038: See, e.g., KSPCreate().
6040: Level: developer
6042: .seealso: PCFactorSetUseInPlace()
6044: Concepts: matrices^unfactored
6046: @*/
6047: PetscErrorCode MatSetUnfactored(Mat mat)
6048: {
6054: MatPreallocated(mat);
6055: mat->factor = MAT_FACTOR_NONE;
6056: if (!mat->ops->setunfactored) return(0);
6057: (*mat->ops->setunfactored)(mat);
6058: return(0);
6059: }
6061: /*MC
6062: MatGetArrayF90 - Accesses a matrix array from Fortran90.
6064: Synopsis:
6065: MatGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
6067: Not collective
6069: Input Parameter:
6070: . x - matrix
6072: Output Parameters:
6073: + xx_v - the Fortran90 pointer to the array
6074: - ierr - error code
6076: Example of Usage:
6077: .vb
6078: PetscScalar, pointer xx_v(:)
6079: ....
6080: call MatGetArrayF90(x,xx_v,ierr)
6081: a = xx_v(3)
6082: call MatRestoreArrayF90(x,xx_v,ierr)
6083: .ve
6085: Notes:
6086: Not yet supported for all F90 compilers
6088: Level: advanced
6090: .seealso: MatRestoreArrayF90(), MatGetArray(), MatRestoreArray()
6092: Concepts: matrices^accessing array
6094: M*/
6096: /*MC
6097: MatRestoreArrayF90 - Restores a matrix array that has been
6098: accessed with MatGetArrayF90().
6100: Synopsis:
6101: MatRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
6103: Not collective
6105: Input Parameters:
6106: + x - matrix
6107: - xx_v - the Fortran90 pointer to the array
6109: Output Parameter:
6110: . ierr - error code
6112: Example of Usage:
6113: .vb
6114: PetscScalar, pointer xx_v(:)
6115: ....
6116: call MatGetArrayF90(x,xx_v,ierr)
6117: a = xx_v(3)
6118: call MatRestoreArrayF90(x,xx_v,ierr)
6119: .ve
6120:
6121: Notes:
6122: Not yet supported for all F90 compilers
6124: Level: advanced
6126: .seealso: MatGetArrayF90(), MatGetArray(), MatRestoreArray()
6128: M*/
6133: /*@
6134: MatGetSubMatrix - Gets a single submatrix on the same number of processors
6135: as the original matrix.
6137: Collective on Mat
6139: Input Parameters:
6140: + mat - the original matrix
6141: . isrow - rows this processor should obtain
6142: . iscol - columns for all processors you wish to keep
6143: . csize - number of columns "local" to this processor (does nothing for sequential
6144: matrices). This should match the result from VecGetLocalSize(x,...) if you
6145: plan to use the matrix in a A*x; alternatively, you can use PETSC_DECIDE
6146: - cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6148: Output Parameter:
6149: . newmat - the new submatrix, of the same type as the old
6151: Level: advanced
6153: Notes: the iscol argument MUST be the same on each processor. You might be
6154: able to create the iscol argument with ISAllGather(). The rows is isrow will be
6155: sorted into the same order as the original matrix.
6157: The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
6158: the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
6159: to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
6160: will reuse the matrix generated the first time. You should call MatDestroy() on newmat when
6161: you are finished using it.
6163: The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
6164: the input matrix.
6166: If iscol is PETSC_NULL then all columns are obtained (not supported in Fortran), you should
6167: use csize = PETSC_DECIDE also in this case.
6169: Concepts: matrices^submatrices
6171: .seealso: MatGetSubMatrices(), ISAllGather()
6172: @*/
6173: PetscErrorCode MatGetSubMatrix(Mat mat,IS isrow,IS iscol,PetscInt csize,MatReuse cll,Mat *newmat)
6174: {
6176: PetscMPIInt size;
6177: Mat *local;
6178: IS iscoltmp;
6187: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6188: MatPreallocated(mat);
6189: MPI_Comm_size(((PetscObject)mat)->comm,&size);
6191: if (!iscol) {
6192: if (csize == PETSC_DECIDE) csize = mat->cmap->n;
6193: ISCreateStride(((PetscObject)mat)->comm,mat->cmap->N,0,1,&iscoltmp);
6194: } else {
6195: iscoltmp = iscol;
6196: }
6198: /* if original matrix is on just one processor then use submatrix generated */
6199: if (!mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
6200: MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);
6201: if (!iscol) {ISDestroy(iscoltmp);}
6202: return(0);
6203: } else if (!mat->ops->getsubmatrix && size == 1) {
6204: MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);
6205: *newmat = *local;
6206: PetscFree(local);
6207: if (!iscol) {ISDestroy(iscoltmp);}
6208: return(0);
6209: }
6211: if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6212: (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,csize,cll,newmat);
6213: if (!iscol) {ISDestroy(iscoltmp);}
6214: PetscObjectStateIncrease((PetscObject)*newmat);
6215: return(0);
6216: }
6220: /*@
6221: MatGetSubMatrixRaw - Gets a single submatrix on the same number of processors
6222: as the original matrix.
6224: Collective on Mat
6226: Input Parameters:
6227: + mat - the original matrix
6228: . nrows - the number of rows this processor should obtain
6229: . rows - rows this processor should obtain
6230: . ncols - the number of columns for all processors you wish to keep
6231: . cols - columns for all processors you wish to keep
6232: . csize - number of columns "local" to this processor (does nothing for sequential
6233: matrices). This should match the result from VecGetLocalSize(x,...) if you
6234: plan to use the matrix in a A*x; alternatively, you can use PETSC_DECIDE
6235: - cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6237: Output Parameter:
6238: . newmat - the new submatrix, of the same type as the old
6240: Level: advanced
6242: Notes: the iscol argument MUST be the same on each processor. You might be
6243: able to create the iscol argument with ISAllGather().
6245: The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
6246: the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
6247: to this routine with a mat of the same nonzero structure and with a cll of MAT_REUSE_MATRIX
6248: will reuse the matrix generated the first time.
6250: Concepts: matrices^submatrices
6252: .seealso: MatGetSubMatrices(), ISAllGather()
6253: @*/
6254: PetscErrorCode MatGetSubMatrixRaw(Mat mat,PetscInt nrows,const PetscInt rows[],PetscInt ncols,const PetscInt cols[],PetscInt csize,MatReuse cll,Mat *newmat)
6255: {
6256: IS isrow, iscol;
6266: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6267: MatPreallocated(mat);
6268: ISCreateGeneralWithArray(PETSC_COMM_SELF, nrows, (PetscInt *) rows, &isrow);
6269: ISCreateGeneralWithArray(PETSC_COMM_SELF, ncols, (PetscInt *) cols, &iscol);
6270: MatGetSubMatrix(mat, isrow, iscol, csize, cll, newmat);
6271: ISDestroy(isrow);
6272: ISDestroy(iscol);
6273: return(0);
6274: }
6278: /*@
6279: MatStashSetInitialSize - sets the sizes of the matrix stash, that is
6280: used during the assembly process to store values that belong to
6281: other processors.
6283: Not Collective
6285: Input Parameters:
6286: + mat - the matrix
6287: . size - the initial size of the stash.
6288: - bsize - the initial size of the block-stash(if used).
6290: Options Database Keys:
6291: + -matstash_initial_size <size> or <size0,size1,...sizep-1>
6292: - -matstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1>
6294: Level: intermediate
6296: Notes:
6297: The block-stash is used for values set with MatSetValuesBlocked() while
6298: the stash is used for values set with MatSetValues()
6300: Run with the option -info and look for output of the form
6301: MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
6302: to determine the appropriate value, MM, to use for size and
6303: MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
6304: to determine the value, BMM to use for bsize
6306: Concepts: stash^setting matrix size
6307: Concepts: matrices^stash
6309: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
6311: @*/
6312: PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
6313: {
6319: MatStashSetInitialSize_Private(&mat->stash,size);
6320: MatStashSetInitialSize_Private(&mat->bstash,bsize);
6321: return(0);
6322: }
6326: /*@
6327: MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
6328: the matrix
6330: Collective on Mat
6332: Input Parameters:
6333: + mat - the matrix
6334: . x,y - the vectors
6335: - w - where the result is stored
6337: Level: intermediate
6339: Notes:
6340: w may be the same vector as y.
6342: This allows one to use either the restriction or interpolation (its transpose)
6343: matrix to do the interpolation
6345: Concepts: interpolation
6347: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
6349: @*/
6350: PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
6351: {
6353: PetscInt M,N;
6361: MatPreallocated(A);
6362: MatGetSize(A,&M,&N);
6363: if (N > M) {
6364: MatMultTransposeAdd(A,x,y,w);
6365: } else {
6366: MatMultAdd(A,x,y,w);
6367: }
6368: return(0);
6369: }
6373: /*@
6374: MatInterpolate - y = A*x or A'*x depending on the shape of
6375: the matrix
6377: Collective on Mat
6379: Input Parameters:
6380: + mat - the matrix
6381: - x,y - the vectors
6383: Level: intermediate
6385: Notes:
6386: This allows one to use either the restriction or interpolation (its transpose)
6387: matrix to do the interpolation
6389: Concepts: matrices^interpolation
6391: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
6393: @*/
6394: PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
6395: {
6397: PetscInt M,N;
6404: MatPreallocated(A);
6405: MatGetSize(A,&M,&N);
6406: if (N > M) {
6407: MatMultTranspose(A,x,y);
6408: } else {
6409: MatMult(A,x,y);
6410: }
6411: return(0);
6412: }
6416: /*@
6417: MatRestrict - y = A*x or A'*x
6419: Collective on Mat
6421: Input Parameters:
6422: + mat - the matrix
6423: - x,y - the vectors
6425: Level: intermediate
6427: Notes:
6428: This allows one to use either the restriction or interpolation (its transpose)
6429: matrix to do the restriction
6431: Concepts: matrices^restriction
6433: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
6435: @*/
6436: PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
6437: {
6439: PetscInt M,N;
6446: MatPreallocated(A);
6448: MatGetSize(A,&M,&N);
6449: if (N > M) {
6450: MatMult(A,x,y);
6451: } else {
6452: MatMultTranspose(A,x,y);
6453: }
6454: return(0);
6455: }
6459: /*@
6460: MatNullSpaceAttach - attaches a null space to a matrix.
6461: This null space will be removed from the resulting vector whenever
6462: MatMult() is called
6464: Collective on Mat
6466: Input Parameters:
6467: + mat - the matrix
6468: - nullsp - the null space object
6470: Level: developer
6472: Notes:
6473: Overwrites any previous null space that may have been attached
6475: Concepts: null space^attaching to matrix
6477: .seealso: MatCreate(), MatNullSpaceCreate()
6478: @*/
6479: PetscErrorCode MatNullSpaceAttach(Mat mat,MatNullSpace nullsp)
6480: {
6487: MatPreallocated(mat);
6488: PetscObjectReference((PetscObject)nullsp);
6489: if (mat->nullsp) { MatNullSpaceDestroy(mat->nullsp); }
6490: mat->nullsp = nullsp;
6491: return(0);
6492: }
6496: /*@
6497: MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
6499: Collective on Mat
6501: Input Parameters:
6502: + mat - the matrix
6503: . row - row/column permutation
6504: . fill - expected fill factor >= 1.0
6505: - level - level of fill, for ICC(k)
6507: Notes:
6508: Probably really in-place only when level of fill is zero, otherwise allocates
6509: new space to store factored matrix and deletes previous memory.
6511: Most users should employ the simplified KSP interface for linear solvers
6512: instead of working directly with matrix algebra routines such as this.
6513: See, e.g., KSPCreate().
6515: Level: developer
6517: Concepts: matrices^incomplete Cholesky factorization
6518: Concepts: Cholesky factorization
6520: .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6521: @*/
6522: PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo* info)
6523: {
6531: if (mat->rmap->N != mat->cmap->N) SETERRQ(PETSC_ERR_ARG_WRONG,"matrix must be square");
6532: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6533: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6534: if (!mat->ops->iccfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6535: MatPreallocated(mat);
6536: (*mat->ops->iccfactor)(mat,row,info);
6537: PetscObjectStateIncrease((PetscObject)mat);
6538: return(0);
6539: }
6543: /*@
6544: MatSetValuesAdic - Sets values computed with ADIC automatic differentiation into a matrix.
6546: Not Collective
6548: Input Parameters:
6549: + mat - the matrix
6550: - v - the values compute with ADIC
6552: Level: developer
6554: Notes:
6555: Must call MatSetColoring() before using this routine. Also this matrix must already
6556: have its nonzero pattern determined.
6558: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
6559: MatSetValues(), MatSetColoring(), MatSetValuesAdifor()
6560: @*/
6561: PetscErrorCode MatSetValuesAdic(Mat mat,void *v)
6562: {
6570: if (!mat->assembled) {
6571: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6572: }
6573: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
6574: if (!mat->ops->setvaluesadic) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6575: (*mat->ops->setvaluesadic)(mat,v);
6576: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
6577: MatView_Private(mat);
6578: PetscObjectStateIncrease((PetscObject)mat);
6579: return(0);
6580: }
6585: /*@
6586: MatSetColoring - Sets a coloring used by calls to MatSetValuesAdic()
6588: Not Collective
6590: Input Parameters:
6591: + mat - the matrix
6592: - coloring - the coloring
6594: Level: developer
6596: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
6597: MatSetValues(), MatSetValuesAdic()
6598: @*/
6599: PetscErrorCode MatSetColoring(Mat mat,ISColoring coloring)
6600: {
6608: if (!mat->assembled) {
6609: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6610: }
6611: if (!mat->ops->setcoloring) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6612: (*mat->ops->setcoloring)(mat,coloring);
6613: return(0);
6614: }
6618: /*@
6619: MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.
6621: Not Collective
6623: Input Parameters:
6624: + mat - the matrix
6625: . nl - leading dimension of v
6626: - v - the values compute with ADIFOR
6628: Level: developer
6630: Notes:
6631: Must call MatSetColoring() before using this routine. Also this matrix must already
6632: have its nonzero pattern determined.
6634: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
6635: MatSetValues(), MatSetColoring()
6636: @*/
6637: PetscErrorCode MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
6638: {
6646: if (!mat->assembled) {
6647: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6648: }
6649: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
6650: if (!mat->ops->setvaluesadifor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6651: (*mat->ops->setvaluesadifor)(mat,nl,v);
6652: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
6653: PetscObjectStateIncrease((PetscObject)mat);
6654: return(0);
6655: }
6659: /*@
6660: MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
6661: ghosted ones.
6663: Not Collective
6665: Input Parameters:
6666: + mat - the matrix
6667: - diag = the diagonal values, including ghost ones
6669: Level: developer
6671: Notes: Works only for MPIAIJ and MPIBAIJ matrices
6672:
6673: .seealso: MatDiagonalScale()
6674: @*/
6675: PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
6676: {
6678: PetscMPIInt size;
6685: if (!mat->assembled) {
6686: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6687: }
6688: PetscLogEventBegin(MAT_Scale,mat,0,0,0);
6689: MPI_Comm_size(((PetscObject)mat)->comm,&size);
6690: if (size == 1) {
6691: PetscInt n,m;
6692: VecGetSize(diag,&n);
6693: MatGetSize(mat,0,&m);
6694: if (m == n) {
6695: MatDiagonalScale(mat,0,diag);
6696: } else {
6697: SETERRQ(PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
6698: }
6699: } else {
6700: PetscErrorCode (*f)(Mat,Vec);
6701: PetscObjectQueryFunction((PetscObject)mat,"MatDiagonalScaleLocal_C",(void (**)(void))&f);
6702: if (f) {
6703: (*f)(mat,diag);
6704: } else {
6705: SETERRQ(PETSC_ERR_SUP,"Only supported for MPIAIJ and MPIBAIJ parallel matrices");
6706: }
6707: }
6708: PetscLogEventEnd(MAT_Scale,mat,0,0,0);
6709: PetscObjectStateIncrease((PetscObject)mat);
6710: return(0);
6711: }
6715: /*@
6716: MatGetInertia - Gets the inertia from a factored matrix
6718: Collective on Mat
6720: Input Parameter:
6721: . mat - the matrix
6723: Output Parameters:
6724: + nneg - number of negative eigenvalues
6725: . nzero - number of zero eigenvalues
6726: - npos - number of positive eigenvalues
6728: Level: advanced
6730: Notes: Matrix must have been factored by MatCholeskyFactor()
6733: @*/
6734: PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
6735: {
6741: if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
6742: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
6743: if (!mat->ops->getinertia) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6744: (*mat->ops->getinertia)(mat,nneg,nzero,npos);
6745: return(0);
6746: }
6748: /* ----------------------------------------------------------------*/
6751: /*@C
6752: MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
6754: Collective on Mat and Vecs
6756: Input Parameters:
6757: + mat - the factored matrix
6758: - b - the right-hand-side vectors
6760: Output Parameter:
6761: . x - the result vectors
6763: Notes:
6764: The vectors b and x cannot be the same. I.e., one cannot
6765: call MatSolves(A,x,x).
6767: Notes:
6768: Most users should employ the simplified KSP interface for linear solvers
6769: instead of working directly with matrix algebra routines such as this.
6770: See, e.g., KSPCreate().
6772: Level: developer
6774: Concepts: matrices^triangular solves
6776: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
6777: @*/
6778: PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
6779: {
6785: if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
6786: if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
6787: if (!mat->rmap->N && !mat->cmap->N) return(0);
6789: if (!mat->ops->solves) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6790: MatPreallocated(mat);
6791: PetscLogEventBegin(MAT_Solves,mat,0,0,0);
6792: (*mat->ops->solves)(mat,b,x);
6793: PetscLogEventEnd(MAT_Solves,mat,0,0,0);
6794: return(0);
6795: }
6799: /*@
6800: MatIsSymmetric - Test whether a matrix is symmetric
6802: Collective on Mat
6804: Input Parameter:
6805: + A - the matrix to test
6806: - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
6808: Output Parameters:
6809: . flg - the result
6811: Level: intermediate
6813: Concepts: matrix^symmetry
6815: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
6816: @*/
6817: PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscTruth *flg)
6818: {
6824: if (!A->symmetric_set) {
6825: if (!A->ops->issymmetric) {
6826: const MatType mattype;
6827: MatGetType(A,&mattype);
6828: SETERRQ1(PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
6829: }
6830: (*A->ops->issymmetric)(A,tol,&A->symmetric);
6831: A->symmetric_set = PETSC_TRUE;
6832: if (A->symmetric) {
6833: A->structurally_symmetric_set = PETSC_TRUE;
6834: A->structurally_symmetric = PETSC_TRUE;
6835: }
6836: }
6837: *flg = A->symmetric;
6838: return(0);
6839: }
6843: /*@
6844: MatIsHermitian - Test whether a matrix is Hermitian
6846: Collective on Mat
6848: Input Parameter:
6849: + A - the matrix to test
6850: - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
6852: Output Parameters:
6853: . flg - the result
6855: Level: intermediate
6857: Concepts: matrix^symmetry
6859: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
6860: @*/
6861: PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscTruth *flg)
6862: {
6868: if (!A->hermitian_set) {
6869: if (!A->ops->ishermitian) {
6870: const MatType mattype;
6871: MatGetType(A,&mattype);
6872: SETERRQ1(PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for Hermitian",mattype);
6873: }
6874: (*A->ops->ishermitian)(A,tol,&A->hermitian);
6875: A->hermitian_set = PETSC_TRUE;
6876: if (A->hermitian) {
6877: A->structurally_symmetric_set = PETSC_TRUE;
6878: A->structurally_symmetric = PETSC_TRUE;
6879: }
6880: }
6881: *flg = A->hermitian;
6882: return(0);
6883: }
6887: /*@
6888: MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
6890: Collective on Mat
6892: Input Parameter:
6893: . A - the matrix to check
6895: Output Parameters:
6896: + set - if the symmetric flag is set (this tells you if the next flag is valid)
6897: - flg - the result
6899: Level: advanced
6901: Concepts: matrix^symmetry
6903: Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
6904: if you want it explicitly checked
6906: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
6907: @*/
6908: PetscErrorCode MatIsSymmetricKnown(Mat A,PetscTruth *set,PetscTruth *flg)
6909: {
6914: if (A->symmetric_set) {
6915: *set = PETSC_TRUE;
6916: *flg = A->symmetric;
6917: } else {
6918: *set = PETSC_FALSE;
6919: }
6920: return(0);
6921: }
6925: /*@
6926: MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
6928: Collective on Mat
6930: Input Parameter:
6931: . A - the matrix to check
6933: Output Parameters:
6934: + set - if the hermitian flag is set (this tells you if the next flag is valid)
6935: - flg - the result
6937: Level: advanced
6939: Concepts: matrix^symmetry
6941: Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
6942: if you want it explicitly checked
6944: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
6945: @*/
6946: PetscErrorCode MatIsHermitianKnown(Mat A,PetscTruth *set,PetscTruth *flg)
6947: {
6952: if (A->hermitian_set) {
6953: *set = PETSC_TRUE;
6954: *flg = A->hermitian;
6955: } else {
6956: *set = PETSC_FALSE;
6957: }
6958: return(0);
6959: }
6963: /*@
6964: MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
6966: Collective on Mat
6968: Input Parameter:
6969: . A - the matrix to test
6971: Output Parameters:
6972: . flg - the result
6974: Level: intermediate
6976: Concepts: matrix^symmetry
6978: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
6979: @*/
6980: PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscTruth *flg)
6981: {
6987: if (!A->structurally_symmetric_set) {
6988: if (!A->ops->isstructurallysymmetric) SETERRQ(PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
6989: (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);
6990: A->structurally_symmetric_set = PETSC_TRUE;
6991: }
6992: *flg = A->structurally_symmetric;
6993: return(0);
6994: }
6999: /*@
7000: MatStashGetInfo - Gets how many values are currently in the vector stash, i.e. need
7001: to be communicated to other processors during the MatAssemblyBegin/End() process
7003: Not collective
7005: Input Parameter:
7006: . vec - the vector
7008: Output Parameters:
7009: + nstash - the size of the stash
7010: . reallocs - the number of additional mallocs incurred.
7011: . bnstash - the size of the block stash
7012: - breallocs - the number of additional mallocs incurred.in the block stash
7013:
7014: Level: advanced
7016: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
7017:
7018: @*/
7019: PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
7020: {
7023: MatStashGetInfo_Private(&mat->stash,nstash,reallocs);
7024: MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);
7025: return(0);
7026: }
7030: /*@C
7031: MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same
7032: parallel layout
7033:
7034: Collective on Mat
7036: Input Parameter:
7037: . mat - the matrix
7039: Output Parameter:
7040: + right - (optional) vector that the matrix can be multiplied against
7041: - left - (optional) vector that the matrix vector product can be stored in
7043: Level: advanced
7045: .seealso: MatCreate()
7046: @*/
7047: PetscErrorCode MatGetVecs(Mat mat,Vec *right,Vec *left)
7048: {
7054: MatPreallocated(mat);
7055: if (mat->ops->getvecs) {
7056: (*mat->ops->getvecs)(mat,right,left);
7057: } else {
7058: PetscMPIInt size;
7059: MPI_Comm_size(((PetscObject)mat)->comm, &size);
7060: if (right) {
7061: VecCreate(((PetscObject)mat)->comm,right);
7062: VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);
7063: VecSetBlockSize(*right,mat->rmap->bs);
7064: if (size > 1) {
7065: /* New vectors uses Mat cmap and does not create a new one */
7066: PetscMapDestroy((*right)->map);
7067: (*right)->map = mat->cmap;
7068: mat->cmap->refcnt++;
7070: VecSetType(*right,VECMPI);
7071: } else {VecSetType(*right,VECSEQ);}
7072: }
7073: if (left) {
7074: VecCreate(((PetscObject)mat)->comm,left);
7075: VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);
7076: VecSetBlockSize(*left,mat->rmap->bs);
7077: if (size > 1) {
7078: /* New vectors uses Mat rmap and does not create a new one */
7079: PetscMapDestroy((*left)->map);
7080: (*left)->map = mat->rmap;
7081: mat->rmap->refcnt++;
7083: VecSetType(*left,VECMPI);
7084: } else {VecSetType(*left,VECSEQ);}
7085: }
7086: }
7087: if (mat->mapping) {
7088: if (right) {VecSetLocalToGlobalMapping(*right,mat->mapping);}
7089: if (left) {VecSetLocalToGlobalMapping(*left,mat->mapping);}
7090: }
7091: if (mat->bmapping) {
7092: if (right) {VecSetLocalToGlobalMappingBlock(*right,mat->bmapping);}
7093: if (left) {VecSetLocalToGlobalMappingBlock(*left,mat->bmapping);}
7094: }
7095: return(0);
7096: }
7100: /*@
7101: MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
7102: with default values.
7104: Not Collective
7106: Input Parameters:
7107: . info - the MatFactorInfo data structure
7110: Notes: The solvers are generally used through the KSP and PC objects, for example
7111: PCLU, PCILU, PCCHOLESKY, PCICC
7113: Level: developer
7115: .seealso: MatFactorInfo
7116: @*/
7118: PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
7119: {
7123: PetscMemzero(info,sizeof(MatFactorInfo));
7124: return(0);
7125: }
7129: /*@
7130: MatPtAP - Creates the matrix projection C = P^T * A * P
7132: Collective on Mat
7134: Input Parameters:
7135: + A - the matrix
7136: . P - the projection matrix
7137: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7138: - fill - expected fill as ratio of nnz(C)/nnz(A)
7140: Output Parameters:
7141: . C - the product matrix
7143: Notes:
7144: C will be created and must be destroyed by the user with MatDestroy().
7146: This routine is currently only implemented for pairs of AIJ matrices and classes
7147: which inherit from AIJ.
7149: Level: intermediate
7151: .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult()
7152: @*/
7153: PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
7154: {
7160: if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7161: if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7164: MatPreallocated(P);
7165: if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7166: if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7168: if (P->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
7169: if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
7170: MatPreallocated(A);
7172: PetscLogEventBegin(MAT_PtAP,A,P,0,0);
7173: (*A->ops->ptap)(A,P,scall,fill,C);
7174: PetscLogEventEnd(MAT_PtAP,A,P,0,0);
7176: return(0);
7177: }
7181: /*@
7182: MatPtAPNumeric - Computes the matrix projection C = P^T * A * P
7184: Collective on Mat
7186: Input Parameters:
7187: + A - the matrix
7188: - P - the projection matrix
7190: Output Parameters:
7191: . C - the product matrix
7193: Notes:
7194: C must have been created by calling MatPtAPSymbolic and must be destroyed by
7195: the user using MatDeatroy().
7197: This routine is currently only implemented for pairs of AIJ matrices and classes
7198: which inherit from AIJ. C will be of type MATAIJ.
7200: Level: intermediate
7202: .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
7203: @*/
7204: PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C)
7205: {
7211: if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7212: if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7215: MatPreallocated(P);
7216: if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7217: if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7220: MatPreallocated(C);
7221: if (C->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7222: if (P->cmap->N!=C->rmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->rmap->N);
7223: if (P->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
7224: 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);
7225: if (P->cmap->N!=C->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->cmap->N);
7226: MatPreallocated(A);
7228: PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
7229: (*A->ops->ptapnumeric)(A,P,C);
7230: PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
7231: return(0);
7232: }
7236: /*@
7237: MatPtAPSymbolic - Creates the (i,j) structure of the matrix projection C = P^T * A * P
7239: Collective on Mat
7241: Input Parameters:
7242: + A - the matrix
7243: - P - the projection matrix
7245: Output Parameters:
7246: . C - the (i,j) structure of the product matrix
7248: Notes:
7249: C will be created and must be destroyed by the user with MatDestroy().
7251: This routine is currently only implemented for pairs of SeqAIJ matrices and classes
7252: which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using
7253: this (i,j) structure by calling MatPtAPNumeric().
7255: Level: intermediate
7257: .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
7258: @*/
7259: PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
7260: {
7266: if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7267: if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7268: if (fill <1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
7271: MatPreallocated(P);
7272: if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7273: if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7276: if (P->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
7277: 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);
7278: MatPreallocated(A);
7279: PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);
7280: (*A->ops->ptapsymbolic)(A,P,fill,C);
7281: PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);
7283: MatSetBlockSize(*C,A->rmap->bs);
7285: return(0);
7286: }
7290: /*@
7291: MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
7293: Collective on Mat
7295: Input Parameters:
7296: + A - the left matrix
7297: . B - the right matrix
7298: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7299: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
7300: if the result is a dense matrix this is irrelevent
7302: Output Parameters:
7303: . C - the product matrix
7305: Notes:
7306: Unless scall is MAT_REUSE_MATRIX C will be created.
7308: MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
7309:
7310: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
7311: actually needed.
7313: If you have many matrices with the same non-zero structure to multiply, you
7314: should either
7315: $ 1) use MAT_REUSE_MATRIX in all calls but the first or
7316: $ 2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
7318: Level: intermediate
7320: .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatPtAP()
7321: @*/
7322: PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
7323: {
7325: PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
7326: PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
7327: PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat *)=PETSC_NULL;
7332: if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7333: if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7336: MatPreallocated(B);
7337: if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7338: if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7340: if (B->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
7341: if (scall == MAT_REUSE_MATRIX){
7344: }
7345: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
7346: if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
7347: MatPreallocated(A);
7349: fA = A->ops->matmult;
7350: fB = B->ops->matmult;
7351: if (fB == fA) {
7352: if (!fB) SETERRQ1(PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
7353: mult = fB;
7354: } else {
7355: /* dispatch based on the type of A and B */
7356: char multname[256];
7357: PetscStrcpy(multname,"MatMatMult_");
7358: PetscStrcat(multname,((PetscObject)A)->type_name);
7359: PetscStrcat(multname,"_");
7360: PetscStrcat(multname,((PetscObject)B)->type_name);
7361: PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
7362: PetscObjectQueryFunction((PetscObject)B,multname,(void (**)(void))&mult);
7363: 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);
7364: }
7365: PetscLogEventBegin(MAT_MatMult,A,B,0,0);
7366: (*mult)(A,B,scall,fill,C);
7367: PetscLogEventEnd(MAT_MatMult,A,B,0,0);
7368: return(0);
7369: }
7373: /*@
7374: MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
7375: of the matrix-matrix product C=A*B. Call this routine before calling MatMatMultNumeric().
7377: Collective on Mat
7379: Input Parameters:
7380: + A - the left matrix
7381: . B - the right matrix
7382: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
7383: if C is a dense matrix this is irrelevent
7384:
7385: Output Parameters:
7386: . C - the product matrix
7388: Notes:
7389: Unless scall is MAT_REUSE_MATRIX C will be created.
7391: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
7392: actually needed.
7394: This routine is currently implemented for
7395: - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
7396: - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
7397: - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
7399: Level: intermediate
7401: .seealso: MatMatMult(), MatMatMultNumeric()
7402: @*/
7403: PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
7404: {
7406: PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat *);
7407: PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat *);
7408: PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat *)=PETSC_NULL;
7413: if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7414: if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7418: MatPreallocated(B);
7419: if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7420: if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7423: if (B->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
7424: if (fill == PETSC_DEFAULT) fill = 2.0;
7425: if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
7426: MatPreallocated(A);
7427:
7428: Asymbolic = A->ops->matmultsymbolic;
7429: Bsymbolic = B->ops->matmultsymbolic;
7430: if (Asymbolic == Bsymbolic){
7431: if (!Bsymbolic) SETERRQ1(PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
7432: symbolic = Bsymbolic;
7433: } else { /* dispatch based on the type of A and B */
7434: char symbolicname[256];
7435: PetscStrcpy(symbolicname,"MatMatMultSymbolic_");
7436: PetscStrcat(symbolicname,((PetscObject)A)->type_name);
7437: PetscStrcat(symbolicname,"_");
7438: PetscStrcat(symbolicname,((PetscObject)B)->type_name);
7439: PetscStrcat(symbolicname,"_C");
7440: PetscObjectQueryFunction((PetscObject)B,symbolicname,(void (**)(void))&symbolic);
7441: 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);
7442: }
7443: PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);
7444: (*symbolic)(A,B,fill,C);
7445: PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);
7446: return(0);
7447: }
7451: /*@
7452: MatMatMultNumeric - Performs the numeric matrix-matrix product.
7453: Call this routine after first calling MatMatMultSymbolic().
7455: Collective on Mat
7457: Input Parameters:
7458: + A - the left matrix
7459: - B - the right matrix
7461: Output Parameters:
7462: . C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
7464: Notes:
7465: C must have been created with MatMatMultSymbolic().
7467: This routine is currently implemented for
7468: - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
7469: - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
7470: - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
7472: Level: intermediate
7474: .seealso: MatMatMult(), MatMatMultSymbolic()
7475: @*/
7476: PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C)
7477: {
7479: PetscErrorCode (*Anumeric)(Mat,Mat,Mat);
7480: PetscErrorCode (*Bnumeric)(Mat,Mat,Mat);
7481: PetscErrorCode (*numeric)(Mat,Mat,Mat)=PETSC_NULL;
7486: if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7487: if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7491: MatPreallocated(B);
7492: if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7493: if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7497: MatPreallocated(C);
7498: if (!C->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7499: if (C->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7501: if (B->cmap->N!=C->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->cmap->N,C->cmap->N);
7502: if (B->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
7503: if (A->rmap->N!=C->rmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",A->rmap->N,C->rmap->N);
7504: MatPreallocated(A);
7506: Anumeric = A->ops->matmultnumeric;
7507: Bnumeric = B->ops->matmultnumeric;
7508: if (Anumeric == Bnumeric){
7509: if (!Bnumeric) SETERRQ1(PETSC_ERR_SUP,"MatMatMultNumeric not supported for B of type %s",((PetscObject)B)->type_name);
7510: numeric = Bnumeric;
7511: } else {
7512: char numericname[256];
7513: PetscStrcpy(numericname,"MatMatMultNumeric_");
7514: PetscStrcat(numericname,((PetscObject)A)->type_name);
7515: PetscStrcat(numericname,"_");
7516: PetscStrcat(numericname,((PetscObject)B)->type_name);
7517: PetscStrcat(numericname,"_C");
7518: PetscObjectQueryFunction((PetscObject)B,numericname,(void (**)(void))&numeric);
7519: if (!numeric)
7520: SETERRQ2(PETSC_ERR_ARG_INCOMP,"MatMatMultNumeric requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
7521: }
7522: PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);
7523: (*numeric)(A,B,C);
7524: PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);
7525: return(0);
7526: }
7530: /*@
7531: MatMatMultTranspose - Performs Matrix-Matrix Multiplication C=A^T*B.
7533: Collective on Mat
7535: Input Parameters:
7536: + A - the left matrix
7537: . B - the right matrix
7538: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7539: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
7541: Output Parameters:
7542: . C - the product matrix
7544: Notes:
7545: C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
7547: MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
7549: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
7550: actually needed.
7552: This routine is currently only implemented for pairs of SeqAIJ matrices and pairs of SeqDense matrices and classes
7553: which inherit from SeqAIJ. C will be of type MATSEQAIJ.
7555: Level: intermediate
7557: .seealso: MatMatMultTransposeSymbolic(), MatMatMultTransposeNumeric(), MatPtAP()
7558: @*/
7559: PetscErrorCode MatMatMultTranspose(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
7560: {
7562: PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
7563: PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
7568: if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7569: if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7572: MatPreallocated(B);
7573: if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7574: if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7576: if (B->rmap->N!=A->rmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->rmap->N);
7577: if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
7578: MatPreallocated(A);
7580: fA = A->ops->matmulttranspose;
7581: if (!fA) SETERRQ1(PETSC_ERR_SUP,"MatMatMultTranspose not supported for A of type %s",((PetscObject)A)->type_name);
7582: fB = B->ops->matmulttranspose;
7583: if (!fB) SETERRQ1(PETSC_ERR_SUP,"MatMatMultTranspose not supported for B of type %s",((PetscObject)B)->type_name);
7584: 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);
7586: PetscLogEventBegin(MAT_MatMultTranspose,A,B,0,0);
7587: (*A->ops->matmulttranspose)(A,B,scall,fill,C);
7588: PetscLogEventEnd(MAT_MatMultTranspose,A,B,0,0);
7589:
7590: return(0);
7591: }
7595: /*@C
7596: MatGetRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
7598: Collective on Mat
7600: Input Parameters:
7601: + mat - the matrix
7602: . nsubcomm - the number of subcommunicators (= number of redundant pareallel or sequential matrices)
7603: . subcomm - MPI communicator split from the communicator where mat resides in
7604: . mlocal_red - number of local rows of the redundant matrix
7605: - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7607: Output Parameter:
7608: . matredundant - redundant matrix
7610: Notes:
7611: MAT_REUSE_MATRIX can only be used when the nonzero structure of the
7612: original matrix has not changed from that last call to MatGetRedundantMatrix().
7614: This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
7615: calling it.
7617: Only MPIAIJ matrix is supported.
7618:
7619: Level: advanced
7621: Concepts: subcommunicator
7622: Concepts: duplicate matrix
7624: .seealso: MatDestroy()
7625: @*/
7626: PetscErrorCode MatGetRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,PetscInt mlocal_red,MatReuse reuse,Mat *matredundant)
7627: {
7632: if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
7635: }
7636: if (!mat->ops->getredundantmatrix) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7637: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7638: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7639: MatPreallocated(mat);
7641: PetscLogEventBegin(MAT_GetRedundantMatrix,mat,0,0,0);
7642: (*mat->ops->getredundantmatrix)(mat,nsubcomm,subcomm,mlocal_red,reuse,matredundant);
7643: PetscLogEventEnd(MAT_GetRedundantMatrix,mat,0,0,0);
7644: return(0);
7645: }