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. This does not work for the DA_NONPERIODIC
1077: wrap.
1079: 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
1080: a single value per point) you can skip filling those indices.
1082: Inspired by the structured grid interface to the HYPRE package
1083: (http://www.llnl.gov/CASC/hypre)
1085: Efficiency Alert:
1086: The routine MatSetValuesBlockedStencil() may offer much better efficiency
1087: for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1089: Level: beginner
1091: Concepts: matrices^putting entries in
1093: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1094: MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DAGetMatrix(), DAVecGetArray(), MatStencil
1095: @*/
1096: PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1097: {
1099: PetscInt j,i,jdxm[128],jdxn[256],dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1100: PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1103: if (!m || !n) return(0); /* no values to insert */
1110: if (m > 128) SETERRQ1(PETSC_ERR_SUP,"Can only set 128 rows at a time; trying to set %D",m);
1111: if (n > 256) SETERRQ1(PETSC_ERR_SUP,"Can only set 256 columns at a time; trying to set %D",n);
1113: for (i=0; i<m; i++) {
1114: for (j=0; j<3-sdim; j++) dxm++;
1115: tmp = *dxm++ - starts[0];
1116: for (j=0; j<dim-1; j++) {
1117: if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1118: else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1119: }
1120: if (mat->stencil.noc) dxm++;
1121: jdxm[i] = tmp;
1122: }
1123: for (i=0; i<n; i++) {
1124: for (j=0; j<3-sdim; j++) dxn++;
1125: tmp = *dxn++ - starts[0];
1126: for (j=0; j<dim-1; j++) {
1127: if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1128: else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1129: }
1130: if (mat->stencil.noc) dxn++;
1131: jdxn[i] = tmp;
1132: }
1133: MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);
1134: return(0);
1135: }
1139: /*@C
1140: MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1141: Using structured grid indexing
1143: Not Collective
1145: Input Parameters:
1146: + mat - the matrix
1147: . v - a logically two-dimensional array of values
1148: . m - number of rows being entered
1149: . idxm - grid coordinates for matrix rows being entered
1150: . n - number of columns being entered
1151: . idxn - grid coordinates for matrix columns being entered
1152: - addv - either ADD_VALUES or INSERT_VALUES, where
1153: ADD_VALUES adds values to any existing entries, and
1154: INSERT_VALUES replaces existing entries with new values
1156: Notes:
1157: By default the values, v, are row-oriented and unsorted.
1158: See MatSetOption() for other options.
1160: Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
1161: options cannot be mixed without intervening calls to the assembly
1162: routines.
1164: The grid coordinates are across the entire grid, not just the local portion
1166: MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran
1167: as well as in C.
1169: For setting/accessing vector values via array coordinates you can use the DAVecGetArray() routine
1171: In order to use this routine you must either obtain the matrix with DAGetMatrix()
1172: or call MatSetLocalToGlobalMapping() and MatSetStencil() first.
1174: The columns and rows in the stencil passed in MUST be contained within the
1175: ghost region of the given process as set with DACreateXXX() or MatSetStencil(). For example,
1176: if you create a DA with an overlap of one grid level and on a particular process its first
1177: local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1178: first i index you can use in your column and row indices in MatSetStencil() is 5.
1180: In Fortran idxm and idxn should be declared as
1181: $ MatStencil idxm(4,m),idxn(4,n)
1182: and the values inserted using
1183: $ idxm(MatStencil_i,1) = i
1184: $ idxm(MatStencil_j,1) = j
1185: $ idxm(MatStencil_k,1) = k
1186: etc
1188: Negative indices may be passed in idxm and idxn, these rows and columns are
1189: simply ignored. This allows easily inserting element stiffness matrices
1190: with homogeneous Dirchlet boundary conditions that you don't want represented
1191: in the matrix.
1193: Inspired by the structured grid interface to the HYPRE package
1194: (http://www.llnl.gov/CASC/hypre)
1196: Level: beginner
1198: Concepts: matrices^putting entries in
1200: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1201: MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DAGetMatrix(), DAVecGetArray(), MatStencil
1202: @*/
1203: PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1204: {
1206: PetscInt j,i,jdxm[128],jdxn[256],dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1207: PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1210: if (!m || !n) return(0); /* no values to insert */
1217: if (m > 128) SETERRQ1(PETSC_ERR_SUP,"Can only set 128 rows at a time; trying to set %D",m);
1218: if (n > 128) SETERRQ1(PETSC_ERR_SUP,"Can only set 256 columns at a time; trying to set %D",n);
1220: for (i=0; i<m; i++) {
1221: for (j=0; j<3-sdim; j++) dxm++;
1222: tmp = *dxm++ - starts[0];
1223: for (j=0; j<sdim-1; j++) {
1224: if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1225: else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1226: }
1227: dxm++;
1228: jdxm[i] = tmp;
1229: }
1230: for (i=0; i<n; i++) {
1231: for (j=0; j<3-sdim; j++) dxn++;
1232: tmp = *dxn++ - starts[0];
1233: for (j=0; j<sdim-1; j++) {
1234: if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1235: else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1236: }
1237: dxn++;
1238: jdxn[i] = tmp;
1239: }
1240: MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);
1241: return(0);
1242: }
1246: /*@
1247: MatSetStencil - Sets the grid information for setting values into a matrix via
1248: MatSetValuesStencil()
1250: Not Collective
1252: Input Parameters:
1253: + mat - the matrix
1254: . dim - dimension of the grid 1, 2, or 3
1255: . dims - number of grid points in x, y, and z direction, including ghost points on your processor
1256: . starts - starting point of ghost nodes on your processor in x, y, and z direction
1257: - dof - number of degrees of freedom per node
1260: Inspired by the structured grid interface to the HYPRE package
1261: (www.llnl.gov/CASC/hyper)
1263: For matrices generated with DAGetMatrix() this routine is automatically called and so not needed by the
1264: user.
1265:
1266: Level: beginner
1268: Concepts: matrices^putting entries in
1270: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1271: MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
1272: @*/
1273: PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1274: {
1275: PetscInt i;
1282: mat->stencil.dim = dim + (dof > 1);
1283: for (i=0; i<dim; i++) {
1284: mat->stencil.dims[i] = dims[dim-i-1]; /* copy the values in backwards */
1285: mat->stencil.starts[i] = starts[dim-i-1];
1286: }
1287: mat->stencil.dims[dim] = dof;
1288: mat->stencil.starts[dim] = 0;
1289: mat->stencil.noc = (PetscTruth)(dof == 1);
1290: return(0);
1291: }
1295: /*@
1296: MatSetValuesBlocked - Inserts or adds a block of values into a matrix.
1298: Not Collective
1300: Input Parameters:
1301: + mat - the matrix
1302: . v - a logically two-dimensional array of values
1303: . m, idxm - the number of block rows and their global block indices
1304: . n, idxn - the number of block columns and their global block indices
1305: - addv - either ADD_VALUES or INSERT_VALUES, where
1306: ADD_VALUES adds values to any existing entries, and
1307: INSERT_VALUES replaces existing entries with new values
1309: Notes:
1310: The m and n count the NUMBER of blocks in the row direction and column direction,
1311: NOT the total number of rows/columns; for example, if the block size is 2 and
1312: you are passing in values for rows 2,3,4,5 then m would be 2 (not 4).
1313: The values in idxm would be 1 2; that is the first index for each block divided by
1314: the block size.
1316: By default the values, v, are row-oriented and unsorted. So the layout of
1317: v is the same as for MatSetValues(). See MatSetOption() for other options.
1319: Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
1320: options cannot be mixed without intervening calls to the assembly
1321: routines.
1323: MatSetValuesBlocked() uses 0-based row and column numbers in Fortran
1324: as well as in C.
1326: Negative indices may be passed in idxm and idxn, these rows and columns are
1327: simply ignored. This allows easily inserting element stiffness matrices
1328: with homogeneous Dirchlet boundary conditions that you don't want represented
1329: in the matrix.
1331: Each time an entry is set within a sparse matrix via MatSetValues(),
1332: internal searching must be done to determine where to place the the
1333: data in the matrix storage space. By instead inserting blocks of
1334: entries via MatSetValuesBlocked(), the overhead of matrix assembly is
1335: reduced.
1337: Example:
1338: $ Suppose m=n=2 and block size(bs) = 2 The array is
1339: $
1340: $ 1 2 | 3 4
1341: $ 5 6 | 7 8
1342: $ - - - | - - -
1343: $ 9 10 | 11 12
1344: $ 13 14 | 15 16
1345: $
1346: $ v[] should be passed in like
1347: $ v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
1348: $
1349: $ If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then
1350: $ v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16]
1352: Level: intermediate
1354: Concepts: matrices^putting entries in blocked
1356: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal()
1357: @*/
1358: PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1359: {
1365: if (!m || !n) return(0); /* no values to insert */
1369: MatPreallocated(mat);
1370: if (mat->insertmode == NOT_SET_VALUES) {
1371: mat->insertmode = addv;
1372: }
1373: #if defined(PETSC_USE_DEBUG)
1374: else if (mat->insertmode != addv) {
1375: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1376: }
1377: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1378: #endif
1380: if (mat->assembled) {
1381: mat->was_assembled = PETSC_TRUE;
1382: mat->assembled = PETSC_FALSE;
1383: }
1384: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1385: if (mat->ops->setvaluesblocked) {
1386: (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);
1387: } else {
1388: PetscInt buf[4096],*ibufm=0,*ibufn=0;
1389: PetscInt i,j,*iidxm,*iidxn,bs=mat->rmap->bs;
1390: if ((m+n)*bs <= 4096) {
1391: iidxm = buf; iidxn = buf + m*bs;
1392: } else {
1393: PetscMalloc2(m*bs,PetscInt,&ibufm,n*bs,PetscInt,&ibufn);
1394: iidxm = ibufm; iidxn = ibufn;
1395: }
1396: for (i=0; i<m; i++) {
1397: for (j=0; j<bs; j++) {
1398: iidxm[i*bs+j] = bs*idxm[i] + j;
1399: }
1400: }
1401: for (i=0; i<n; i++) {
1402: for (j=0; j<bs; j++) {
1403: iidxn[i*bs+j] = bs*idxn[i] + j;
1404: }
1405: }
1406: MatSetValues(mat,bs*m,iidxm,bs*n,iidxn,v,addv);
1407: PetscFree2(ibufm,ibufn);
1408: }
1409: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1410: return(0);
1411: }
1415: /*@
1416: MatGetValues - Gets a block of values from a matrix.
1418: Not Collective; currently only returns a local block
1420: Input Parameters:
1421: + mat - the matrix
1422: . v - a logically two-dimensional array for storing the values
1423: . m, idxm - the number of rows and their global indices
1424: - n, idxn - the number of columns and their global indices
1426: Notes:
1427: The user must allocate space (m*n PetscScalars) for the values, v.
1428: The values, v, are then returned in a row-oriented format,
1429: analogous to that used by default in MatSetValues().
1431: MatGetValues() uses 0-based row and column numbers in
1432: Fortran as well as in C.
1434: MatGetValues() requires that the matrix has been assembled
1435: with MatAssemblyBegin()/MatAssemblyEnd(). Thus, calls to
1436: MatSetValues() and MatGetValues() CANNOT be made in succession
1437: without intermediate matrix assembly.
1439: Negative row or column indices will be ignored and those locations in v[] will be
1440: left unchanged.
1442: Level: advanced
1444: Concepts: matrices^accessing values
1446: .seealso: MatGetRow(), MatGetSubMatrices(), MatSetValues()
1447: @*/
1448: PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1449: {
1458: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1459: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1460: if (!mat->ops->getvalues) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1461: MatPreallocated(mat);
1463: PetscLogEventBegin(MAT_GetValues,mat,0,0,0);
1464: (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);
1465: PetscLogEventEnd(MAT_GetValues,mat,0,0,0);
1466: return(0);
1467: }
1471: /*@
1472: MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
1473: the routine MatSetValuesLocal() to allow users to insert matrix entries
1474: using a local (per-processor) numbering.
1476: Not Collective
1478: Input Parameters:
1479: + x - the matrix
1480: - mapping - mapping created with ISLocalToGlobalMappingCreate()
1481: or ISLocalToGlobalMappingCreateIS()
1483: Level: intermediate
1485: Concepts: matrices^local to global mapping
1486: Concepts: local to global mapping^for matrices
1488: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
1489: @*/
1490: PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping mapping)
1491: {
1497: if (x->mapping) {
1498: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Mapping already set for matrix");
1499: }
1500: MatPreallocated(x);
1502: if (x->ops->setlocaltoglobalmapping) {
1503: (*x->ops->setlocaltoglobalmapping)(x,mapping);
1504: } else {
1505: PetscObjectReference((PetscObject)mapping);
1506: if (x->mapping) { ISLocalToGlobalMappingDestroy(x->mapping); }
1507: x->mapping = mapping;
1508: }
1509: return(0);
1510: }
1514: /*@
1515: MatSetLocalToGlobalMappingBlock - Sets a local-to-global numbering for use
1516: by the routine MatSetValuesBlockedLocal() to allow users to insert matrix
1517: entries using a local (per-processor) numbering.
1519: Not Collective
1521: Input Parameters:
1522: + x - the matrix
1523: - mapping - mapping created with ISLocalToGlobalMappingCreate() or
1524: ISLocalToGlobalMappingCreateIS()
1526: Level: intermediate
1528: Concepts: matrices^local to global mapping blocked
1529: Concepts: local to global mapping^for matrices, blocked
1531: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal(),
1532: MatSetValuesBlocked(), MatSetValuesLocal()
1533: @*/
1534: PetscErrorCode MatSetLocalToGlobalMappingBlock(Mat x,ISLocalToGlobalMapping mapping)
1535: {
1541: if (x->bmapping) {
1542: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Mapping already set for matrix");
1543: }
1544: PetscObjectReference((PetscObject)mapping);
1545: if (x->bmapping) { ISLocalToGlobalMappingDestroy(x->mapping); }
1546: x->bmapping = mapping;
1547: return(0);
1548: }
1552: /*@
1553: MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
1554: using a local ordering of the nodes.
1556: Not Collective
1558: Input Parameters:
1559: + x - the matrix
1560: . nrow, irow - number of rows and their local indices
1561: . ncol, icol - number of columns and their local indices
1562: . y - a logically two-dimensional array of values
1563: - addv - either INSERT_VALUES or ADD_VALUES, where
1564: ADD_VALUES adds values to any existing entries, and
1565: INSERT_VALUES replaces existing entries with new values
1567: Notes:
1568: Before calling MatSetValuesLocal(), the user must first set the
1569: local-to-global mapping by calling MatSetLocalToGlobalMapping().
1571: Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
1572: options cannot be mixed without intervening calls to the assembly
1573: routines.
1575: These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1576: MUST be called after all calls to MatSetValuesLocal() have been completed.
1578: Level: intermediate
1580: Concepts: matrices^putting entries in with local numbering
1582: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
1583: MatSetValueLocal()
1584: @*/
1585: PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
1586: {
1588: PetscInt irowm[2048],icolm[2048];
1593: if (!nrow || !ncol) return(0); /* no values to insert */
1597: MatPreallocated(mat);
1598: if (mat->insertmode == NOT_SET_VALUES) {
1599: mat->insertmode = addv;
1600: }
1601: #if defined(PETSC_USE_DEBUG)
1602: else if (mat->insertmode != addv) {
1603: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1604: }
1605: if (!mat->ops->setvalueslocal && (nrow > 2048 || ncol > 2048)) {
1606: SETERRQ2(PETSC_ERR_SUP,"Number column/row indices must be <= 2048: are %D %D",nrow,ncol);
1607: }
1608: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1609: #endif
1611: if (mat->assembled) {
1612: mat->was_assembled = PETSC_TRUE;
1613: mat->assembled = PETSC_FALSE;
1614: }
1615: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1616: if (!mat->ops->setvalueslocal) {
1617: ISLocalToGlobalMappingApply(mat->mapping,nrow,irow,irowm);
1618: ISLocalToGlobalMappingApply(mat->mapping,ncol,icol,icolm);
1619: (*mat->ops->setvalues)(mat,nrow,irowm,ncol,icolm,y,addv);
1620: } else {
1621: (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);
1622: }
1623: mat->same_nonzero = PETSC_FALSE;
1624: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1625: return(0);
1626: }
1630: /*@
1631: MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix,
1632: using a local ordering of the nodes a block at a time.
1634: Not Collective
1636: Input Parameters:
1637: + x - the matrix
1638: . nrow, irow - number of rows and their local indices
1639: . ncol, icol - number of columns and their local indices
1640: . y - a logically two-dimensional array of values
1641: - addv - either INSERT_VALUES or ADD_VALUES, where
1642: ADD_VALUES adds values to any existing entries, and
1643: INSERT_VALUES replaces existing entries with new values
1645: Notes:
1646: Before calling MatSetValuesBlockedLocal(), the user must first set the
1647: local-to-global mapping by calling MatSetLocalToGlobalMappingBlock(),
1648: where the mapping MUST be set for matrix blocks, not for matrix elements.
1650: Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
1651: options cannot be mixed without intervening calls to the assembly
1652: routines.
1654: These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1655: MUST be called after all calls to MatSetValuesBlockedLocal() have been completed.
1657: Level: intermediate
1659: Concepts: matrices^putting blocked values in with local numbering
1661: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesLocal(), MatSetLocalToGlobalMappingBlock(), MatSetValuesBlocked()
1662: @*/
1663: PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
1664: {
1666: PetscInt irowm[2048],icolm[2048];
1671: if (!nrow || !ncol) return(0); /* no values to insert */
1675: MatPreallocated(mat);
1676: if (mat->insertmode == NOT_SET_VALUES) {
1677: mat->insertmode = addv;
1678: }
1679: #if defined(PETSC_USE_DEBUG)
1680: else if (mat->insertmode != addv) {
1681: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1682: }
1683: if (!mat->bmapping) {
1684: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Local to global never set with MatSetLocalToGlobalMappingBlock()");
1685: }
1686: if (nrow > 2048 || ncol > 2048) {
1687: SETERRQ2(PETSC_ERR_SUP,"Number column/row indices must be <= 2048: are %D %D",nrow,ncol);
1688: }
1689: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1690: #endif
1692: if (mat->assembled) {
1693: mat->was_assembled = PETSC_TRUE;
1694: mat->assembled = PETSC_FALSE;
1695: }
1696: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1697: ISLocalToGlobalMappingApply(mat->bmapping,nrow,irow,irowm);
1698: ISLocalToGlobalMappingApply(mat->bmapping,ncol,icol,icolm);
1699: if (mat->ops->setvaluesblocked) {
1700: (*mat->ops->setvaluesblocked)(mat,nrow,irowm,ncol,icolm,y,addv);
1701: } else {
1702: PetscInt buf[4096],*ibufm=0,*ibufn=0;
1703: PetscInt i,j,*iirowm,*iicolm,bs=mat->rmap->bs;
1704: if ((nrow+ncol)*bs <= 4096) {
1705: iirowm = buf; iicolm = buf + nrow*bs;
1706: } else {
1707: PetscMalloc2(nrow*bs,PetscInt,&ibufm,ncol*bs,PetscInt,&ibufn);
1708: iirowm = ibufm; iicolm = ibufn;
1709: }
1710: for (i=0; i<nrow; i++) {
1711: for (j=0; j<bs; j++) {
1712: iirowm[i*bs+j] = bs*irowm[i] + j;
1713: }
1714: }
1715: for (i=0; i<ncol; i++) {
1716: for (j=0; j<bs; j++) {
1717: iicolm[i*bs+j] = bs*icolm[i] + j;
1718: }
1719: }
1720: MatSetValues(mat,bs*nrow,iirowm,bs*ncol,iicolm,y,addv);
1721: PetscFree2(ibufm,ibufn);
1722: }
1723: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1724: return(0);
1725: }
1727: /* --------------------------------------------------------*/
1730: /*@
1731: MatMult - Computes the matrix-vector product, y = Ax.
1733: Collective on Mat and Vec
1735: Input Parameters:
1736: + mat - the matrix
1737: - x - the vector to be multiplied
1739: Output Parameters:
1740: . y - the result
1742: Notes:
1743: The vectors x and y cannot be the same. I.e., one cannot
1744: call MatMult(A,y,y).
1746: Level: beginner
1748: Concepts: matrix-vector product
1750: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
1751: @*/
1752: PetscErrorCode MatMult(Mat mat,Vec x,Vec y)
1753: {
1762: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1763: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1764: if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1765: #ifndef PETSC_HAVE_CONSTRAINTS
1766: 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);
1767: 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);
1768: 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);
1769: #endif
1770: MatPreallocated(mat);
1772: if (mat->nullsp) {
1773: MatNullSpaceRemove(mat->nullsp,x,&x);
1774: }
1776: if (!mat->ops->mult) SETERRQ(PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
1777: PetscLogEventBegin(MAT_Mult,mat,x,y,0);
1778: (*mat->ops->mult)(mat,x,y);
1779: PetscLogEventEnd(MAT_Mult,mat,x,y,0);
1781: if (mat->nullsp) {
1782: MatNullSpaceRemove(mat->nullsp,y,PETSC_NULL);
1783: }
1784: PetscObjectStateIncrease((PetscObject)y);
1785: return(0);
1786: }
1790: /*@
1791: MatMultTranspose - Computes matrix transpose times a vector.
1793: Collective on Mat and Vec
1795: Input Parameters:
1796: + mat - the matrix
1797: - x - the vector to be multilplied
1799: Output Parameters:
1800: . y - the result
1802: Notes:
1803: The vectors x and y cannot be the same. I.e., one cannot
1804: call MatMultTranspose(A,y,y).
1806: Level: beginner
1808: Concepts: matrix vector product^transpose
1810: .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd()
1811: @*/
1812: PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y)
1813: {
1822: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1823: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1824: if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1825: #ifndef PETSC_HAVE_CONSTRAINTS
1826: 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);
1827: 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);
1828: #endif
1829: MatPreallocated(mat);
1831: if (!mat->ops->multtranspose) SETERRQ(PETSC_ERR_SUP,"This matrix type does not have a multiply tranpose defined");
1832: PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);
1833: (*mat->ops->multtranspose)(mat,x,y);
1834: PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);
1835: PetscObjectStateIncrease((PetscObject)y);
1836: return(0);
1837: }
1841: /*@
1842: MatMultAdd - Computes v3 = v2 + A * v1.
1844: Collective on Mat and Vec
1846: Input Parameters:
1847: + mat - the matrix
1848: - v1, v2 - the vectors
1850: Output Parameters:
1851: . v3 - the result
1853: Notes:
1854: The vectors v1 and v3 cannot be the same. I.e., one cannot
1855: call MatMultAdd(A,v1,v2,v1).
1857: Level: beginner
1859: Concepts: matrix vector product^addition
1861: .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
1862: @*/
1863: PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
1864: {
1874: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1875: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1876: 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);
1877: 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);
1878: 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);
1879: 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);
1880: 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);
1881: if (v1 == v3) SETERRQ(PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
1882: MatPreallocated(mat);
1884: PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);
1885: (*mat->ops->multadd)(mat,v1,v2,v3);
1886: PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);
1887: PetscObjectStateIncrease((PetscObject)v3);
1888: return(0);
1889: }
1893: /*@
1894: MatMultTransposeAdd - Computes v3 = v2 + A' * v1.
1896: Collective on Mat and Vec
1898: Input Parameters:
1899: + mat - the matrix
1900: - v1, v2 - the vectors
1902: Output Parameters:
1903: . v3 - the result
1905: Notes:
1906: The vectors v1 and v3 cannot be the same. I.e., one cannot
1907: call MatMultTransposeAdd(A,v1,v2,v1).
1909: Level: beginner
1911: Concepts: matrix vector product^transpose and addition
1913: .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
1914: @*/
1915: PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
1916: {
1926: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1927: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1928: if (!mat->ops->multtransposeadd) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1929: if (v1 == v3) SETERRQ(PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
1930: 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);
1931: 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);
1932: 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);
1933: MatPreallocated(mat);
1935: PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);
1936: (*mat->ops->multtransposeadd)(mat,v1,v2,v3);
1937: PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);
1938: PetscObjectStateIncrease((PetscObject)v3);
1939: return(0);
1940: }
1944: /*@
1945: MatMultConstrained - The inner multiplication routine for a
1946: constrained matrix P^T A P.
1948: Collective on Mat and Vec
1950: Input Parameters:
1951: + mat - the matrix
1952: - x - the vector to be multilplied
1954: Output Parameters:
1955: . y - the result
1957: Notes:
1958: The vectors x and y cannot be the same. I.e., one cannot
1959: call MatMult(A,y,y).
1961: Level: beginner
1963: .keywords: matrix, multiply, matrix-vector product, constraint
1964: .seealso: MatMult(), MatMultTrans(), MatMultAdd(), MatMultTransAdd()
1965: @*/
1966: PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y)
1967: {
1974: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1975: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1976: if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1977: 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);
1978: 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);
1979: 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);
1981: PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
1982: (*mat->ops->multconstrained)(mat,x,y);
1983: PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
1984: PetscObjectStateIncrease((PetscObject)y);
1986: return(0);
1987: }
1991: /*@
1992: MatMultTransposeConstrained - The inner multiplication routine for a
1993: constrained matrix P^T A^T P.
1995: Collective on Mat and Vec
1997: Input Parameters:
1998: + mat - the matrix
1999: - x - the vector to be multilplied
2001: Output Parameters:
2002: . y - the result
2004: Notes:
2005: The vectors x and y cannot be the same. I.e., one cannot
2006: call MatMult(A,y,y).
2008: Level: beginner
2010: .keywords: matrix, multiply, matrix-vector product, constraint
2011: .seealso: MatMult(), MatMultTrans(), MatMultAdd(), MatMultTransAdd()
2012: @*/
2013: PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2014: {
2021: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2022: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2023: if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2024: 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);
2025: 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);
2027: PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2028: (*mat->ops->multtransposeconstrained)(mat,x,y);
2029: PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2030: PetscObjectStateIncrease((PetscObject)y);
2032: return(0);
2033: }
2034: /* ------------------------------------------------------------*/
2037: /*@C
2038: MatGetInfo - Returns information about matrix storage (number of
2039: nonzeros, memory, etc.).
2041: Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used
2042: as the flag
2044: Input Parameters:
2045: . mat - the matrix
2047: Output Parameters:
2048: + flag - flag indicating the type of parameters to be returned
2049: (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2050: MAT_GLOBAL_SUM - sum over all processors)
2051: - info - matrix information context
2053: Notes:
2054: The MatInfo context contains a variety of matrix data, including
2055: number of nonzeros allocated and used, number of mallocs during
2056: matrix assembly, etc. Additional information for factored matrices
2057: is provided (such as the fill ratio, number of mallocs during
2058: factorization, etc.). Much of this info is printed to PETSC_STDOUT
2059: when using the runtime options
2060: $ -info -mat_view_info
2062: Example for C/C++ Users:
2063: See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2064: data within the MatInfo context. For example,
2065: .vb
2066: MatInfo info;
2067: Mat A;
2068: double mal, nz_a, nz_u;
2070: MatGetInfo(A,MAT_LOCAL,&info);
2071: mal = info.mallocs;
2072: nz_a = info.nz_allocated;
2073: .ve
2075: Example for Fortran Users:
2076: Fortran users should declare info as a double precision
2077: array of dimension MAT_INFO_SIZE, and then extract the parameters
2078: of interest. See the file ${PETSC_DIR}/include/finclude/petscmat.h
2079: a complete list of parameter names.
2080: .vb
2081: double precision info(MAT_INFO_SIZE)
2082: double precision mal, nz_a
2083: Mat A
2084: integer ierr
2086: call MatGetInfo(A,MAT_LOCAL,info,ierr)
2087: mal = info(MAT_INFO_MALLOCS)
2088: nz_a = info(MAT_INFO_NZ_ALLOCATED)
2089: .ve
2091: Level: intermediate
2093: Concepts: matrices^getting information on
2094:
2095: Developer Note: fortran interface is not autogenerated as the f90
2096: interface defintion cannot be generated correctly [due to MatInfo]
2097:
2098: @*/
2099: PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2100: {
2107: if (!mat->ops->getinfo) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2108: MatPreallocated(mat);
2109: (*mat->ops->getinfo)(mat,flag,info);
2110: return(0);
2111: }
2113: /* ----------------------------------------------------------*/
2116: /*@C
2117: MatILUDTFactor - Performs a drop tolerance ILU factorization.
2119: Collective on Mat
2121: Input Parameters:
2122: + mat - the matrix
2123: . row - row permutation
2124: . col - column permutation
2125: - info - information about the factorization to be done
2127: Output Parameters:
2128: . fact - the factored matrix
2130: Level: developer
2132: Notes:
2133: Most users should employ the simplified KSP interface for linear solvers
2134: instead of working directly with matrix algebra routines such as this.
2135: See, e.g., KSPCreate().
2137: This is currently only supported for the SeqAIJ matrix format using code
2138: from Yousef Saad's SPARSEKIT2 package (translated to C with f2c) and/or
2139: Matlab. SPARSEKIT2 is copyrighted by Yousef Saad with the GNU copyright
2140: and thus can be distributed with PETSc.
2142: Concepts: matrices^ILUDT factorization
2144: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
2145: @*/
2146: PetscErrorCode MatILUDTFactor(Mat mat,IS row,IS col,const MatFactorInfo *info,Mat *fact)
2147: {
2157: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2158: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2159: if (!mat->ops->iludtfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2160: MatPreallocated(mat);
2161: PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);
2162: (*mat->ops->iludtfactor)(mat,row,col,info,fact);
2163: PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);
2164: PetscObjectStateIncrease((PetscObject)*fact);
2166: return(0);
2167: }
2171: /*@C
2172: MatLUFactor - Performs in-place LU factorization of matrix.
2174: Collective on Mat
2176: Input Parameters:
2177: + mat - the matrix
2178: . row - row permutation
2179: . col - column permutation
2180: - info - options for factorization, includes
2181: $ fill - expected fill as ratio of original fill.
2182: $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2183: $ Run with the option -info to determine an optimal value to use
2185: Notes:
2186: Most users should employ the simplified KSP interface for linear solvers
2187: instead of working directly with matrix algebra routines such as this.
2188: See, e.g., KSPCreate().
2190: This changes the state of the matrix to a factored matrix; it cannot be used
2191: for example with MatSetValues() unless one first calls MatSetUnfactored().
2193: Level: developer
2195: Concepts: matrices^LU factorization
2197: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2198: MatGetOrdering(), MatSetUnfactored(), MatFactorInfo
2200: Developer Note: fortran interface is not autogenerated as the f90
2201: interface defintion cannot be generated correctly [due to MatFactorInfo]
2203: @*/
2204: PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2205: {
2214: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2215: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2216: if (!mat->ops->lufactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2217: MatPreallocated(mat);
2219: PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);
2220: (*mat->ops->lufactor)(mat,row,col,info);
2221: PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);
2222: PetscObjectStateIncrease((PetscObject)mat);
2223: return(0);
2224: }
2228: /*@C
2229: MatILUFactor - Performs in-place ILU factorization of matrix.
2231: Collective on Mat
2233: Input Parameters:
2234: + mat - the matrix
2235: . row - row permutation
2236: . col - column permutation
2237: - info - structure containing
2238: $ levels - number of levels of fill.
2239: $ expected fill - as ratio of original fill.
2240: $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2241: missing diagonal entries)
2243: Notes:
2244: Probably really in-place only when level of fill is zero, otherwise allocates
2245: new space to store factored matrix and deletes previous memory.
2247: Most users should employ the simplified KSP interface for linear solvers
2248: instead of working directly with matrix algebra routines such as this.
2249: See, e.g., KSPCreate().
2251: Level: developer
2253: Concepts: matrices^ILU factorization
2255: .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
2257: Developer Note: fortran interface is not autogenerated as the f90
2258: interface defintion cannot be generated correctly [due to MatFactorInfo]
2260: @*/
2261: PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2262: {
2271: if (mat->rmap->N != mat->cmap->N) SETERRQ(PETSC_ERR_ARG_WRONG,"matrix must be square");
2272: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2273: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2274: if (!mat->ops->ilufactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2275: MatPreallocated(mat);
2277: PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);
2278: (*mat->ops->ilufactor)(mat,row,col,info);
2279: PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);
2280: PetscObjectStateIncrease((PetscObject)mat);
2281: return(0);
2282: }
2286: /*@C
2287: MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
2288: Call this routine before calling MatLUFactorNumeric().
2290: Collective on Mat
2292: Input Parameters:
2293: + fact - the factor matrix obtained with MatGetFactor()
2294: . mat - the matrix
2295: . row, col - row and column permutations
2296: - info - options for factorization, includes
2297: $ fill - expected fill as ratio of original fill.
2298: $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2299: $ Run with the option -info to determine an optimal value to use
2302: Notes:
2303: See the users manual for additional information about
2304: choosing the fill factor for better efficiency.
2306: Most users should employ the simplified KSP interface for linear solvers
2307: instead of working directly with matrix algebra routines such as this.
2308: See, e.g., KSPCreate().
2310: Level: developer
2312: Concepts: matrices^LU symbolic factorization
2314: .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
2316: Developer Note: fortran interface is not autogenerated as the f90
2317: interface defintion cannot be generated correctly [due to MatFactorInfo]
2319: @*/
2320: PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
2321: {
2331: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2332: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2333: if (!(fact)->ops->lufactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s symbolic LU",((PetscObject)mat)->type_name);
2334: MatPreallocated(mat);
2336: PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);
2337: (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);
2338: PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);
2339: PetscObjectStateIncrease((PetscObject)fact);
2340: return(0);
2341: }
2345: /*@C
2346: MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
2347: Call this routine after first calling MatLUFactorSymbolic().
2349: Collective on Mat
2351: Input Parameters:
2352: + fact - the factor matrix obtained with MatGetFactor()
2353: . mat - the matrix
2354: - info - options for factorization
2356: Notes:
2357: See MatLUFactor() for in-place factorization. See
2358: MatCholeskyFactorNumeric() for the symmetric, positive definite case.
2360: Most users should employ the simplified KSP interface for linear solvers
2361: instead of working directly with matrix algebra routines such as this.
2362: See, e.g., KSPCreate().
2364: Level: developer
2366: Concepts: matrices^LU numeric factorization
2368: .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()
2370: Developer Note: fortran interface is not autogenerated as the f90
2371: interface defintion cannot be generated correctly [due to MatFactorInfo]
2373: @*/
2374: PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
2375: {
2383: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2384: if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) {
2385: 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);
2386: }
2387: if (!(fact)->ops->lufactornumeric) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2388: MatPreallocated(mat);
2389: PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);
2390: (fact->ops->lufactornumeric)(fact,mat,info);
2391: PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);
2393: MatView_Private(fact);
2394: PetscObjectStateIncrease((PetscObject)fact);
2395: return(0);
2396: }
2400: /*@C
2401: MatCholeskyFactor - Performs in-place Cholesky factorization of a
2402: symmetric matrix.
2404: Collective on Mat
2406: Input Parameters:
2407: + mat - the matrix
2408: . perm - row and column permutations
2409: - f - expected fill as ratio of original fill
2411: Notes:
2412: See MatLUFactor() for the nonsymmetric case. See also
2413: MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().
2415: Most users should employ the simplified KSP interface for linear solvers
2416: instead of working directly with matrix algebra routines such as this.
2417: See, e.g., KSPCreate().
2419: Level: developer
2421: Concepts: matrices^Cholesky factorization
2423: .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
2424: MatGetOrdering()
2426: Developer Note: fortran interface is not autogenerated as the f90
2427: interface defintion cannot be generated correctly [due to MatFactorInfo]
2429: @*/
2430: PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
2431: {
2439: if (mat->rmap->N != mat->cmap->N) SETERRQ(PETSC_ERR_ARG_WRONG,"Matrix must be square");
2440: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2441: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2442: if (!mat->ops->choleskyfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2443: MatPreallocated(mat);
2445: PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);
2446: (*mat->ops->choleskyfactor)(mat,perm,info);
2447: PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);
2448: PetscObjectStateIncrease((PetscObject)mat);
2449: return(0);
2450: }
2454: /*@C
2455: MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
2456: of a symmetric matrix.
2458: Collective on Mat
2460: Input Parameters:
2461: + fact - the factor matrix obtained with MatGetFactor()
2462: . mat - the matrix
2463: . perm - row and column permutations
2464: - info - options for factorization, includes
2465: $ fill - expected fill as ratio of original fill.
2466: $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2467: $ Run with the option -info to determine an optimal value to use
2469: Notes:
2470: See MatLUFactorSymbolic() for the nonsymmetric case. See also
2471: MatCholeskyFactor() and MatCholeskyFactorNumeric().
2473: Most users should employ the simplified KSP interface for linear solvers
2474: instead of working directly with matrix algebra routines such as this.
2475: See, e.g., KSPCreate().
2477: Level: developer
2479: Concepts: matrices^Cholesky symbolic factorization
2481: .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
2482: MatGetOrdering()
2484: Developer Note: fortran interface is not autogenerated as the f90
2485: interface defintion cannot be generated correctly [due to MatFactorInfo]
2487: @*/
2488: PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
2489: {
2498: if (mat->rmap->N != mat->cmap->N) SETERRQ(PETSC_ERR_ARG_WRONG,"Matrix must be square");
2499: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2500: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2501: if (!(fact)->ops->choleskyfactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2502: MatPreallocated(mat);
2504: PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
2505: (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);
2506: PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
2507: PetscObjectStateIncrease((PetscObject)fact);
2508: return(0);
2509: }
2513: /*@C
2514: MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
2515: of a symmetric matrix. Call this routine after first calling
2516: MatCholeskyFactorSymbolic().
2518: Collective on Mat
2520: Input Parameters:
2521: + fact - the factor matrix obtained with MatGetFactor()
2522: . mat - the initial matrix
2523: . info - options for factorization
2524: - fact - the symbolic factor of mat
2527: Notes:
2528: Most users should employ the simplified KSP interface for linear solvers
2529: instead of working directly with matrix algebra routines such as this.
2530: See, e.g., KSPCreate().
2532: Level: developer
2534: Concepts: matrices^Cholesky numeric factorization
2536: .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
2538: Developer Note: fortran interface is not autogenerated as the f90
2539: interface defintion cannot be generated correctly [due to MatFactorInfo]
2541: @*/
2542: PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
2543: {
2551: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2552: if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2553: if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) {
2554: 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);
2555: }
2556: MatPreallocated(mat);
2558: PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);
2559: (fact->ops->choleskyfactornumeric)(fact,mat,info);
2560: PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);
2562: MatView_Private(fact);
2563: PetscObjectStateIncrease((PetscObject)fact);
2564: return(0);
2565: }
2567: /* ----------------------------------------------------------------*/
2570: /*@
2571: MatSolve - Solves A x = b, given a factored matrix.
2573: Collective on Mat and Vec
2575: Input Parameters:
2576: + mat - the factored matrix
2577: - b - the right-hand-side vector
2579: Output Parameter:
2580: . x - the result vector
2582: Notes:
2583: The vectors b and x cannot be the same. I.e., one cannot
2584: call MatSolve(A,x,x).
2586: Notes:
2587: Most users should employ the simplified KSP interface for linear solvers
2588: instead of working directly with matrix algebra routines such as this.
2589: See, e.g., KSPCreate().
2591: Level: developer
2593: Concepts: matrices^triangular solves
2595: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
2596: @*/
2597: PetscErrorCode MatSolve(Mat mat,Vec b,Vec x)
2598: {
2608: if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2609: if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2610: 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);
2611: 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);
2612: 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);
2613: if (!mat->rmap->N && !mat->cmap->N) return(0);
2614: if (!mat->ops->solve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2615: MatPreallocated(mat);
2617: PetscLogEventBegin(MAT_Solve,mat,b,x,0);
2618: (*mat->ops->solve)(mat,b,x);
2619: PetscLogEventEnd(MAT_Solve,mat,b,x,0);
2620: PetscObjectStateIncrease((PetscObject)x);
2621: return(0);
2622: }
2626: PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X)
2627: {
2629: Vec b,x;
2630: PetscInt m,N,i;
2631: PetscScalar *bb,*xx;
2634: MatGetArray(B,&bb);
2635: MatGetArray(X,&xx);
2636: MatGetLocalSize(B,&m,PETSC_NULL); /* number local rows */
2637: MatGetSize(B,PETSC_NULL,&N); /* total columns in dense matrix */
2638: VecCreateMPIWithArray(((PetscObject)A)->comm,m,PETSC_DETERMINE,PETSC_NULL,&b);
2639: VecCreateMPIWithArray(((PetscObject)A)->comm,m,PETSC_DETERMINE,PETSC_NULL,&x);
2640: for (i=0; i<N; i++) {
2641: VecPlaceArray(b,bb + i*m);
2642: VecPlaceArray(x,xx + i*m);
2643: MatSolve(A,b,x);
2644: VecResetArray(x);
2645: VecResetArray(b);
2646: }
2647: VecDestroy(b);
2648: VecDestroy(x);
2649: MatRestoreArray(B,&bb);
2650: MatRestoreArray(X,&xx);
2651: return(0);
2652: }
2656: /*@
2657: MatMatSolve - Solves A X = B, given a factored matrix.
2659: Collective on Mat
2661: Input Parameters:
2662: + mat - the factored matrix
2663: - B - the right-hand-side matrix (dense matrix)
2665: Output Parameter:
2666: . X - the result matrix (dense matrix)
2668: Notes:
2669: The matrices b and x cannot be the same. I.e., one cannot
2670: call MatMatSolve(A,x,x).
2672: Notes:
2673: Most users should usually employ the simplified KSP interface for linear solvers
2674: instead of working directly with matrix algebra routines such as this.
2675: See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
2676: at a time.
2678: Level: developer
2680: Concepts: matrices^triangular solves
2682: .seealso: MatMatSolveAdd(), MatMatSolveTranspose(), MatMatSolveTransposeAdd(), MatLUFactor(), MatCholeskyFactor()
2683: @*/
2684: PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X)
2685: {
2695: if (X == B) SETERRQ(PETSC_ERR_ARG_IDN,"X and B must be different matrices");
2696: if (!A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2697: 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);
2698: 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);
2699: 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);
2700: if (!A->rmap->N && !A->cmap->N) return(0);
2701: MatPreallocated(A);
2703: PetscLogEventBegin(MAT_MatSolve,A,B,X,0);
2704: if (!A->ops->matsolve) {
2705: PetscInfo1(A,"Mat type %s using basic MatMatSolve",((PetscObject)A)->type_name);
2706: MatMatSolve_Basic(A,B,X);
2707: } else {
2708: (*A->ops->matsolve)(A,B,X);
2709: }
2710: PetscLogEventEnd(MAT_MatSolve,A,B,X,0);
2711: PetscObjectStateIncrease((PetscObject)X);
2712: return(0);
2713: }
2718: /* @
2719: MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or
2720: U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U,
2722: Collective on Mat and Vec
2724: Input Parameters:
2725: + mat - the factored matrix
2726: - b - the right-hand-side vector
2728: Output Parameter:
2729: . x - the result vector
2731: Notes:
2732: MatSolve() should be used for most applications, as it performs
2733: a forward solve followed by a backward solve.
2735: The vectors b and x cannot be the same, i.e., one cannot
2736: call MatForwardSolve(A,x,x).
2738: For matrix in seqsbaij format with block size larger than 1,
2739: the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
2740: MatForwardSolve() solves U^T*D y = b, and
2741: MatBackwardSolve() solves U x = y.
2742: Thus they do not provide a symmetric preconditioner.
2744: Most users should employ the simplified KSP interface for linear solvers
2745: instead of working directly with matrix algebra routines such as this.
2746: See, e.g., KSPCreate().
2748: Level: developer
2750: Concepts: matrices^forward solves
2752: .seealso: MatSolve(), MatBackwardSolve()
2753: @ */
2754: PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x)
2755: {
2765: if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2766: if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2767: if (!mat->ops->forwardsolve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2768: 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);
2769: 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);
2770: 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);
2771: MatPreallocated(mat);
2772: PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);
2773: (*mat->ops->forwardsolve)(mat,b,x);
2774: PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);
2775: PetscObjectStateIncrease((PetscObject)x);
2776: return(0);
2777: }
2781: /* @
2782: MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
2783: D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U,
2785: Collective on Mat and Vec
2787: Input Parameters:
2788: + mat - the factored matrix
2789: - b - the right-hand-side vector
2791: Output Parameter:
2792: . x - the result vector
2794: Notes:
2795: MatSolve() should be used for most applications, as it performs
2796: a forward solve followed by a backward solve.
2798: The vectors b and x cannot be the same. I.e., one cannot
2799: call MatBackwardSolve(A,x,x).
2801: For matrix in seqsbaij format with block size larger than 1,
2802: the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
2803: MatForwardSolve() solves U^T*D y = b, and
2804: MatBackwardSolve() solves U x = y.
2805: Thus they do not provide a symmetric preconditioner.
2807: Most users should employ the simplified KSP interface for linear solvers
2808: instead of working directly with matrix algebra routines such as this.
2809: See, e.g., KSPCreate().
2811: Level: developer
2813: Concepts: matrices^backward solves
2815: .seealso: MatSolve(), MatForwardSolve()
2816: @ */
2817: PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x)
2818: {
2828: if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2829: if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2830: if (!mat->ops->backwardsolve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2831: 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);
2832: 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);
2833: 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);
2834: MatPreallocated(mat);
2836: PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);
2837: (*mat->ops->backwardsolve)(mat,b,x);
2838: PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);
2839: PetscObjectStateIncrease((PetscObject)x);
2840: return(0);
2841: }
2845: /*@
2846: MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
2848: Collective on Mat and Vec
2850: Input Parameters:
2851: + mat - the factored matrix
2852: . b - the right-hand-side vector
2853: - y - the vector to be added to
2855: Output Parameter:
2856: . x - the result vector
2858: Notes:
2859: The vectors b and x cannot be the same. I.e., one cannot
2860: call MatSolveAdd(A,x,y,x).
2862: Most users should employ the simplified KSP interface for linear solvers
2863: instead of working directly with matrix algebra routines such as this.
2864: See, e.g., KSPCreate().
2866: Level: developer
2868: Concepts: matrices^triangular solves
2870: .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
2871: @*/
2872: PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
2873: {
2874: PetscScalar one = 1.0;
2875: Vec tmp;
2887: if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2888: if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2889: 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);
2890: 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);
2891: 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);
2892: 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);
2893: 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);
2894: MatPreallocated(mat);
2896: PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);
2897: if (mat->ops->solveadd) {
2898: (*mat->ops->solveadd)(mat,b,y,x);
2899: } else {
2900: /* do the solve then the add manually */
2901: if (x != y) {
2902: MatSolve(mat,b,x);
2903: VecAXPY(x,one,y);
2904: } else {
2905: VecDuplicate(x,&tmp);
2906: PetscLogObjectParent(mat,tmp);
2907: VecCopy(x,tmp);
2908: MatSolve(mat,b,x);
2909: VecAXPY(x,one,tmp);
2910: VecDestroy(tmp);
2911: }
2912: }
2913: PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);
2914: PetscObjectStateIncrease((PetscObject)x);
2915: return(0);
2916: }
2920: /*@
2921: MatSolveTranspose - Solves A' x = b, given a factored matrix.
2923: Collective on Mat and Vec
2925: Input Parameters:
2926: + mat - the factored matrix
2927: - b - the right-hand-side vector
2929: Output Parameter:
2930: . x - the result vector
2932: Notes:
2933: The vectors b and x cannot be the same. I.e., one cannot
2934: call MatSolveTranspose(A,x,x).
2936: Most users should employ the simplified KSP interface for linear solvers
2937: instead of working directly with matrix algebra routines such as this.
2938: See, e.g., KSPCreate().
2940: Level: developer
2942: Concepts: matrices^triangular solves
2944: .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
2945: @*/
2946: PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x)
2947: {
2957: if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2958: if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2959: if (!mat->ops->solvetranspose) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
2960: 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);
2961: 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);
2962: MatPreallocated(mat);
2963: PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);
2964: (*mat->ops->solvetranspose)(mat,b,x);
2965: PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);
2966: PetscObjectStateIncrease((PetscObject)x);
2967: return(0);
2968: }
2972: /*@
2973: MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
2974: factored matrix.
2976: Collective on Mat and Vec
2978: Input Parameters:
2979: + mat - the factored matrix
2980: . b - the right-hand-side vector
2981: - y - the vector to be added to
2983: Output Parameter:
2984: . x - the result vector
2986: Notes:
2987: The vectors b and x cannot be the same. I.e., one cannot
2988: call MatSolveTransposeAdd(A,x,y,x).
2990: Most users should employ the simplified KSP interface for linear solvers
2991: instead of working directly with matrix algebra routines such as this.
2992: See, e.g., KSPCreate().
2994: Level: developer
2996: Concepts: matrices^triangular solves
2998: .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
2999: @*/
3000: PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3001: {
3002: PetscScalar one = 1.0;
3004: Vec tmp;
3015: if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3016: if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3017: 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);
3018: 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);
3019: 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);
3020: 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);
3021: MatPreallocated(mat);
3023: PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);
3024: if (mat->ops->solvetransposeadd) {
3025: (*mat->ops->solvetransposeadd)(mat,b,y,x);
3026: } else {
3027: /* do the solve then the add manually */
3028: if (x != y) {
3029: MatSolveTranspose(mat,b,x);
3030: VecAXPY(x,one,y);
3031: } else {
3032: VecDuplicate(x,&tmp);
3033: PetscLogObjectParent(mat,tmp);
3034: VecCopy(x,tmp);
3035: MatSolveTranspose(mat,b,x);
3036: VecAXPY(x,one,tmp);
3037: VecDestroy(tmp);
3038: }
3039: }
3040: PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);
3041: PetscObjectStateIncrease((PetscObject)x);
3042: return(0);
3043: }
3044: /* ----------------------------------------------------------------*/
3048: /*@
3049: MatRelax - Computes relaxation (SOR, Gauss-Seidel) sweeps.
3051: Collective on Mat and Vec
3053: Input Parameters:
3054: + mat - the matrix
3055: . b - the right hand side
3056: . omega - the relaxation factor
3057: . flag - flag indicating the type of SOR (see below)
3058: . shift - diagonal shift
3059: . its - the number of iterations
3060: - lits - the number of local iterations
3062: Output Parameters:
3063: . x - the solution (can contain an initial guess)
3065: SOR Flags:
3066: . SOR_FORWARD_SWEEP - forward SOR
3067: . SOR_BACKWARD_SWEEP - backward SOR
3068: . SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3069: . SOR_LOCAL_FORWARD_SWEEP - local forward SOR
3070: . SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
3071: . SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3072: . SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
3073: upper/lower triangular part of matrix to
3074: vector (with omega)
3075: . SOR_ZERO_INITIAL_GUESS - zero initial guess
3077: Notes:
3078: SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3079: SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3080: on each processor.
3082: Application programmers will not generally use MatRelax() directly,
3083: but instead will employ the KSP/PC interface.
3085: Notes for Advanced Users:
3086: The flags are implemented as bitwise inclusive or operations.
3087: For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3088: to specify a zero initial guess for SSOR.
3090: Most users should employ the simplified KSP interface for linear solvers
3091: instead of working directly with matrix algebra routines such as this.
3092: See, e.g., KSPCreate().
3094: See also, MatPBRelax(). This routine will automatically call the point block
3095: version if the point version is not available.
3097: Level: developer
3099: Concepts: matrices^relaxation
3100: Concepts: matrices^SOR
3101: Concepts: matrices^Gauss-Seidel
3103: @*/
3104: PetscErrorCode MatRelax(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3105: {
3115: if (!mat->ops->relax && !mat->ops->pbrelax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3116: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3117: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3118: 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);
3119: 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);
3120: 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);
3121: if (its <= 0) SETERRQ1(PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
3122: if (lits <= 0) SETERRQ1(PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
3124: MatPreallocated(mat);
3125: PetscLogEventBegin(MAT_Relax,mat,b,x,0);
3126: if (mat->ops->relax) {
3127: ierr =(*mat->ops->relax)(mat,b,omega,flag,shift,its,lits,x);
3128: } else {
3129: ierr =(*mat->ops->pbrelax)(mat,b,omega,flag,shift,its,lits,x);
3130: }
3131: PetscLogEventEnd(MAT_Relax,mat,b,x,0);
3132: PetscObjectStateIncrease((PetscObject)x);
3133: return(0);
3134: }
3138: /*@
3139: MatPBRelax - Computes relaxation (SOR, Gauss-Seidel) sweeps.
3141: Collective on Mat and Vec
3143: See MatRelax() for usage
3145: For multi-component PDEs where the Jacobian is stored in a point block format
3146: (with the PETSc BAIJ matrix formats) the relaxation is done one point block at
3147: a time. That is, the small (for example, 4 by 4) blocks along the diagonal are solved
3148: simultaneously (that is a 4 by 4 linear solve is done) to update all the values at a point.
3150: Level: developer
3152: @*/
3153: PetscErrorCode MatPBRelax(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3154: {
3164: if (!mat->ops->pbrelax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3165: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3166: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3167: 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);
3168: 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);
3169: 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);
3170: MatPreallocated(mat);
3172: PetscLogEventBegin(MAT_Relax,mat,b,x,0);
3173: ierr =(*mat->ops->pbrelax)(mat,b,omega,flag,shift,its,lits,x);
3174: PetscLogEventEnd(MAT_Relax,mat,b,x,0);
3175: PetscObjectStateIncrease((PetscObject)x);
3176: return(0);
3177: }
3181: /*
3182: Default matrix copy routine.
3183: */
3184: PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
3185: {
3186: PetscErrorCode ierr;
3187: PetscInt i,rstart,rend,nz;
3188: const PetscInt *cwork;
3189: const PetscScalar *vwork;
3192: if (B->assembled) {
3193: MatZeroEntries(B);
3194: }
3195: MatGetOwnershipRange(A,&rstart,&rend);
3196: for (i=rstart; i<rend; i++) {
3197: MatGetRow(A,i,&nz,&cwork,&vwork);
3198: MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);
3199: MatRestoreRow(A,i,&nz,&cwork,&vwork);
3200: }
3201: MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
3202: MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);
3203: PetscObjectStateIncrease((PetscObject)B);
3204: return(0);
3205: }
3209: /*@
3210: MatCopy - Copys a matrix to another matrix.
3212: Collective on Mat
3214: Input Parameters:
3215: + A - the matrix
3216: - str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
3218: Output Parameter:
3219: . B - where the copy is put
3221: Notes:
3222: If you use SAME_NONZERO_PATTERN then the two matrices had better have the
3223: same nonzero pattern or the routine will crash.
3225: MatCopy() copies the matrix entries of a matrix to another existing
3226: matrix (after first zeroing the second matrix). A related routine is
3227: MatConvert(), which first creates a new matrix and then copies the data.
3229: Level: intermediate
3230:
3231: Concepts: matrices^copying
3233: .seealso: MatConvert(), MatDuplicate()
3235: @*/
3236: PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str)
3237: {
3239: PetscInt i;
3247: MatPreallocated(B);
3248: if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3249: if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3250: 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);
3251: MatPreallocated(A);
3253: PetscLogEventBegin(MAT_Copy,A,B,0,0);
3254: if (A->ops->copy) {
3255: (*A->ops->copy)(A,B,str);
3256: } else { /* generic conversion */
3257: MatCopy_Basic(A,B,str);
3258: }
3259: if (A->mapping) {
3260: if (B->mapping) {ISLocalToGlobalMappingDestroy(B->mapping);B->mapping = 0;}
3261: MatSetLocalToGlobalMapping(B,A->mapping);
3262: }
3263: if (A->bmapping) {
3264: if (B->bmapping) {ISLocalToGlobalMappingDestroy(B->bmapping);B->bmapping = 0;}
3265: MatSetLocalToGlobalMappingBlock(B,A->mapping);
3266: }
3268: B->stencil.dim = A->stencil.dim;
3269: B->stencil.noc = A->stencil.noc;
3270: for (i=0; i<=A->stencil.dim; i++) {
3271: B->stencil.dims[i] = A->stencil.dims[i];
3272: B->stencil.starts[i] = A->stencil.starts[i];
3273: }
3275: PetscLogEventEnd(MAT_Copy,A,B,0,0);
3276: PetscObjectStateIncrease((PetscObject)B);
3277: return(0);
3278: }
3282: /*@C
3283: MatConvert - Converts a matrix to another matrix, either of the same
3284: or different type.
3286: Collective on Mat
3288: Input Parameters:
3289: + mat - the matrix
3290: . newtype - new matrix type. Use MATSAME to create a new matrix of the
3291: same type as the original matrix.
3292: - reuse - denotes if the destination matrix is to be created or reused. Currently
3293: MAT_REUSE_MATRIX is only supported for inplace conversion, otherwise use
3294: MAT_INITIAL_MATRIX.
3296: Output Parameter:
3297: . M - pointer to place new matrix
3299: Notes:
3300: MatConvert() first creates a new matrix and then copies the data from
3301: the first matrix. A related routine is MatCopy(), which copies the matrix
3302: entries of one matrix to another already existing matrix context.
3304: Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
3305: the MPI communicator of the generated matrix is always the same as the communicator
3306: of the input matrix.
3308: Level: intermediate
3310: Concepts: matrices^converting between storage formats
3312: .seealso: MatCopy(), MatDuplicate()
3313: @*/
3314: PetscErrorCode MatConvert(Mat mat, const MatType newtype,MatReuse reuse,Mat *M)
3315: {
3316: PetscErrorCode ierr;
3317: PetscTruth sametype,issame,flg;
3318: char convname[256],mtype[256];
3319: Mat B;
3325: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3326: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3327: MatPreallocated(mat);
3329: PetscOptionsGetString(((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);
3330: if (flg) {
3331: newtype = mtype;
3332: }
3333: PetscTypeCompare((PetscObject)mat,newtype,&sametype);
3334: PetscStrcmp(newtype,"same",&issame);
3335: if ((reuse == MAT_REUSE_MATRIX) && (mat != *M)) {
3336: SETERRQ(PETSC_ERR_SUP,"MAT_REUSE_MATRIX only supported for in-place conversion currently");
3337: }
3339: if ((reuse == MAT_REUSE_MATRIX) && (issame || sametype)) return(0);
3340:
3341: if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
3342: (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);
3343: } else {
3344: PetscErrorCode (*conv)(Mat, const MatType,MatReuse,Mat*)=PETSC_NULL;
3345: const char *prefix[3] = {"seq","mpi",""};
3346: PetscInt i;
3347: /*
3348: Order of precedence:
3349: 1) See if a specialized converter is known to the current matrix.
3350: 2) See if a specialized converter is known to the desired matrix class.
3351: 3) See if a good general converter is registered for the desired class
3352: (as of 6/27/03 only MATMPIADJ falls into this category).
3353: 4) See if a good general converter is known for the current matrix.
3354: 5) Use a really basic converter.
3355: */
3356:
3357: /* 1) See if a specialized converter is known to the current matrix and the desired class */
3358: for (i=0; i<3; i++) {
3359: PetscStrcpy(convname,"MatConvert_");
3360: PetscStrcat(convname,((PetscObject)mat)->type_name);
3361: PetscStrcat(convname,"_");
3362: PetscStrcat(convname,prefix[i]);
3363: PetscStrcat(convname,newtype);
3364: PetscStrcat(convname,"_C");
3365: PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);
3366: if (conv) goto foundconv;
3367: }
3369: /* 2) See if a specialized converter is known to the desired matrix class. */
3370: MatCreate(((PetscObject)mat)->comm,&B);
3371: MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);
3372: MatSetType(B,newtype);
3373: for (i=0; i<3; i++) {
3374: PetscStrcpy(convname,"MatConvert_");
3375: PetscStrcat(convname,((PetscObject)mat)->type_name);
3376: PetscStrcat(convname,"_");
3377: PetscStrcat(convname,prefix[i]);
3378: PetscStrcat(convname,newtype);
3379: PetscStrcat(convname,"_C");
3380: PetscObjectQueryFunction((PetscObject)B,convname,(void (**)(void))&conv);
3381: if (conv) {
3382: MatDestroy(B);
3383: goto foundconv;
3384: }
3385: }
3387: /* 3) See if a good general converter is registered for the desired class */
3388: conv = B->ops->convertfrom;
3389: MatDestroy(B);
3390: if (conv) goto foundconv;
3392: /* 4) See if a good general converter is known for the current matrix */
3393: if (mat->ops->convert) {
3394: conv = mat->ops->convert;
3395: }
3396: if (conv) goto foundconv;
3398: /* 5) Use a really basic converter. */
3399: conv = MatConvert_Basic;
3401: foundconv:
3402: PetscLogEventBegin(MAT_Convert,mat,0,0,0);
3403: (*conv)(mat,newtype,reuse,M);
3404: PetscLogEventEnd(MAT_Convert,mat,0,0,0);
3405: }
3406: PetscObjectStateIncrease((PetscObject)*M);
3407: return(0);
3408: }
3412: /*@C
3413: MatFactorGetSolverPackage - Returns name of the package providing the factorization routines
3415: Not Collective
3417: Input Parameter:
3418: . mat - the matrix, must be a factored matrix
3420: Output Parameter:
3421: . type - the string name of the package (do not free this string)
3423: Notes:
3424: In Fortran you pass in a empty string and the package name will be copied into it.
3425: (Make sure the string is long enough)
3427: Level: intermediate
3429: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
3430: @*/
3431: PetscErrorCode MatFactorGetSolverPackage(Mat mat, const MatSolverPackage *type)
3432: {
3433: PetscErrorCode ierr;
3434: PetscErrorCode (*conv)(Mat,const MatSolverPackage*);
3439: if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
3440: PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverPackage_C",(void (**)(void))&conv);
3441: if (!conv) {
3442: *type = MAT_SOLVER_PETSC;
3443: } else {
3444: (*conv)(mat,type);
3445: }
3446: return(0);
3447: }
3451: /*@C
3452: MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic()
3454: Collective on Mat
3456: Input Parameters:
3457: + mat - the matrix
3458: . type - name of solver type, for example, spooles, superlu, plapack, petsc (to use PETSc's default)
3459: - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
3461: Output Parameters:
3462: . f - the factor matrix used with MatXXFactorSymbolic() calls
3464: Notes:
3465: Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
3466: such as pastix, superlu, mumps, spooles etc.
3468: PETSc must have been config/configure.py to use the external solver, using the option --download-package
3470: Level: intermediate
3472: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
3473: @*/
3474: PetscErrorCode MatGetFactor(Mat mat, const MatSolverPackage type,MatFactorType ftype,Mat *f)
3475: {
3476: PetscErrorCode ierr;
3477: char convname[256];
3478: PetscErrorCode (*conv)(Mat,MatFactorType,Mat*);
3484: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3485: MatPreallocated(mat);
3487: PetscStrcpy(convname,"MatGetFactor_");
3488: PetscStrcat(convname,((PetscObject)mat)->type_name);
3489: PetscStrcat(convname,"_");
3490: PetscStrcat(convname,type);
3491: PetscStrcat(convname,"_C");
3492: PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);
3493: if (!conv) {
3494: PetscTruth flag;
3495: PetscStrcasecmp(MAT_SOLVER_PETSC,type,&flag);
3496: if (flag) {
3497: SETERRQ1(PETSC_ERR_SUP,"Matrix format %s does not have a built-in PETSc direct solver",((PetscObject)mat)->type_name);
3498: } else {
3499: 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);
3500: }
3501: }
3502: (*conv)(mat,ftype,f);
3503: return(0);
3504: }
3508: /*@C
3509: MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type
3511: Collective on Mat
3513: Input Parameters:
3514: + mat - the matrix
3515: . type - name of solver type, for example, spooles, superlu, plapack, petsc (to use PETSc's default)
3516: - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
3518: Output Parameter:
3519: . flg - PETSC_TRUE if the factorization is available
3521: Notes:
3522: Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
3523: such as pastix, superlu, mumps, spooles etc.
3525: PETSc must have been config/configure.py to use the external solver, using the option --download-package
3527: Level: intermediate
3529: .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
3530: @*/
3531: PetscErrorCode MatGetFactorAvailable(Mat mat, const MatSolverPackage type,MatFactorType ftype,PetscTruth *flg)
3532: {
3533: PetscErrorCode ierr;
3534: char convname[256];
3535: PetscErrorCode (*conv)(Mat,MatFactorType,PetscTruth*);
3541: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3542: MatPreallocated(mat);
3544: PetscStrcpy(convname,"MatGetFactorAvailable_");
3545: PetscStrcat(convname,((PetscObject)mat)->type_name);
3546: PetscStrcat(convname,"_");
3547: PetscStrcat(convname,type);
3548: PetscStrcat(convname,"_C");
3549: PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);
3550: if (!conv) {
3551: *flg = PETSC_FALSE;
3552: } else {
3553: (*conv)(mat,ftype,flg);
3554: }
3555: return(0);
3556: }
3561: /*@
3562: MatDuplicate - Duplicates a matrix including the non-zero structure.
3564: Collective on Mat
3566: Input Parameters:
3567: + mat - the matrix
3568: - op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy nonzero
3569: values as well or not
3571: Output Parameter:
3572: . M - pointer to place new matrix
3574: Level: intermediate
3576: Concepts: matrices^duplicating
3578: .seealso: MatCopy(), MatConvert()
3579: @*/
3580: PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
3581: {
3583: Mat B;
3584: PetscInt i;
3590: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3591: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3592: MatPreallocated(mat);
3594: *M = 0;
3595: if (!mat->ops->duplicate) {
3596: SETERRQ(PETSC_ERR_SUP,"Not written for this matrix type");
3597: }
3598: PetscLogEventBegin(MAT_Convert,mat,0,0,0);
3599: (*mat->ops->duplicate)(mat,op,M);
3600: B = *M;
3601: if (mat->mapping) {
3602: MatSetLocalToGlobalMapping(B,mat->mapping);
3603: }
3604: if (mat->bmapping) {
3605: MatSetLocalToGlobalMappingBlock(B,mat->bmapping);
3606: }
3607: PetscMapCopy(((PetscObject)mat)->comm,mat->rmap,B->rmap);
3608: PetscMapCopy(((PetscObject)mat)->comm,mat->cmap,B->cmap);
3609:
3610: B->stencil.dim = mat->stencil.dim;
3611: B->stencil.noc = mat->stencil.noc;
3612: for (i=0; i<=mat->stencil.dim; i++) {
3613: B->stencil.dims[i] = mat->stencil.dims[i];
3614: B->stencil.starts[i] = mat->stencil.starts[i];
3615: }
3617: PetscLogEventEnd(MAT_Convert,mat,0,0,0);
3618: PetscObjectStateIncrease((PetscObject)B);
3619: return(0);
3620: }
3624: /*@
3625: MatGetDiagonal - Gets the diagonal of a matrix.
3627: Collective on Mat and Vec
3629: Input Parameters:
3630: + mat - the matrix
3631: - v - the vector for storing the diagonal
3633: Output Parameter:
3634: . v - the diagonal of the matrix
3636: Level: intermediate
3638: Concepts: matrices^accessing diagonals
3640: .seealso: MatGetRow(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs()
3641: @*/
3642: PetscErrorCode MatGetDiagonal(Mat mat,Vec v)
3643: {
3650: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3651: if (!mat->ops->getdiagonal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3652: MatPreallocated(mat);
3654: (*mat->ops->getdiagonal)(mat,v);
3655: PetscObjectStateIncrease((PetscObject)v);
3656: return(0);
3657: }
3661: /*@
3662: MatGetRowMin - Gets the minimum value (of the real part) of each
3663: row of the matrix
3665: Collective on Mat and Vec
3667: Input Parameters:
3668: . mat - the matrix
3670: Output Parameter:
3671: + v - the vector for storing the maximums
3672: - idx - the indices of the column found for each row (optional)
3674: Level: intermediate
3676: Notes: The result of this call are the same as if one converted the matrix to dense format
3677: and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
3679: This code is only implemented for a couple of matrix formats.
3681: Concepts: matrices^getting row maximums
3683: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(),
3684: MatGetRowMax()
3685: @*/
3686: PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
3687: {
3694: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3695: if (!mat->ops->getrowmax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3696: MatPreallocated(mat);
3698: (*mat->ops->getrowmin)(mat,v,idx);
3699: PetscObjectStateIncrease((PetscObject)v);
3700: return(0);
3701: }
3705: /*@
3706: MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
3707: row of the matrix
3709: Collective on Mat and Vec
3711: Input Parameters:
3712: . mat - the matrix
3714: Output Parameter:
3715: + v - the vector for storing the minimums
3716: - idx - the indices of the column found for each row (optional)
3718: Level: intermediate
3720: Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
3721: row is 0 (the first column).
3723: This code is only implemented for a couple of matrix formats.
3725: Concepts: matrices^getting row maximums
3727: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
3728: @*/
3729: PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
3730: {
3737: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3738: if (!mat->ops->getrowminabs) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3739: MatPreallocated(mat);
3740: if (idx) {PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));}
3742: (*mat->ops->getrowminabs)(mat,v,idx);
3743: PetscObjectStateIncrease((PetscObject)v);
3744: return(0);
3745: }
3749: /*@
3750: MatGetRowMax - Gets the maximum value (of the real part) of each
3751: row of the matrix
3753: Collective on Mat and Vec
3755: Input Parameters:
3756: . mat - the matrix
3758: Output Parameter:
3759: + v - the vector for storing the maximums
3760: - idx - the indices of the column found for each row (optional)
3762: Level: intermediate
3764: Notes: The result of this call are the same as if one converted the matrix to dense format
3765: and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
3767: This code is only implemented for a couple of matrix formats.
3769: Concepts: matrices^getting row maximums
3771: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(), MatGetRowMin()
3772: @*/
3773: PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
3774: {
3781: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3782: if (!mat->ops->getrowmax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3783: MatPreallocated(mat);
3785: (*mat->ops->getrowmax)(mat,v,idx);
3786: PetscObjectStateIncrease((PetscObject)v);
3787: return(0);
3788: }
3792: /*@
3793: MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
3794: row of the matrix
3796: Collective on Mat and Vec
3798: Input Parameters:
3799: . mat - the matrix
3801: Output Parameter:
3802: + v - the vector for storing the maximums
3803: - idx - the indices of the column found for each row (optional)
3805: Level: intermediate
3807: Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
3808: row is 0 (the first column).
3810: This code is only implemented for a couple of matrix formats.
3812: Concepts: matrices^getting row maximums
3814: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
3815: @*/
3816: PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
3817: {
3824: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3825: if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3826: MatPreallocated(mat);
3827: if (idx) {PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));}
3829: (*mat->ops->getrowmaxabs)(mat,v,idx);
3830: PetscObjectStateIncrease((PetscObject)v);
3831: return(0);
3832: }
3836: /*@
3837: MatGetRowSum - Gets the sum of each row of the matrix
3839: Collective on Mat and Vec
3841: Input Parameters:
3842: . mat - the matrix
3844: Output Parameter:
3845: . v - the vector for storing the maximums
3847: Level: intermediate
3849: Notes: This code is slow since it is not currently specialized for different formats
3851: Concepts: matrices^getting row sums
3853: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
3854: @*/
3855: PetscErrorCode MatGetRowSum(Mat mat, Vec v)
3856: {
3857: PetscInt start, end, row;
3858: PetscScalar *array;
3865: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3866: MatPreallocated(mat);
3867: MatGetOwnershipRange(mat, &start, &end);
3868: VecGetArray(v, &array);
3869: for(row = start; row < end; ++row) {
3870: PetscInt ncols, col;
3871: const PetscInt *cols;
3872: const PetscScalar *vals;
3874: array[row - start] = 0.0;
3875: MatGetRow(mat, row, &ncols, &cols, &vals);
3876: for(col = 0; col < ncols; col++) {
3877: array[row - start] += vals[col];
3878: }
3879: MatRestoreRow(mat, row, &ncols, &cols, &vals);
3880: }
3881: VecRestoreArray(v, &array);
3882: PetscObjectStateIncrease((PetscObject) v);
3883: return(0);
3884: }
3888: /*@
3889: MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
3891: Collective on Mat
3893: Input Parameter:
3894: + mat - the matrix to transpose
3895: - reuse - store the transpose matrix in the provided B
3897: Output Parameters:
3898: . B - the transpose
3900: Notes:
3901: If you pass in &mat for B the transpose will be done in place
3903: Level: intermediate
3905: Concepts: matrices^transposing
3907: .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose()
3908: @*/
3909: PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B)
3910: {
3916: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3917: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3918: if (!mat->ops->transpose) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3919: MatPreallocated(mat);
3921: PetscLogEventBegin(MAT_Transpose,mat,0,0,0);
3922: (*mat->ops->transpose)(mat,reuse,B);
3923: PetscLogEventEnd(MAT_Transpose,mat,0,0,0);
3924: if (B) {PetscObjectStateIncrease((PetscObject)*B);}
3925: return(0);
3926: }
3930: /*@
3931: MatIsTranspose - Test whether a matrix is another one's transpose,
3932: or its own, in which case it tests symmetry.
3934: Collective on Mat
3936: Input Parameter:
3937: + A - the matrix to test
3938: - B - the matrix to test against, this can equal the first parameter
3940: Output Parameters:
3941: . flg - the result
3943: Notes:
3944: Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
3945: has a running time of the order of the number of nonzeros; the parallel
3946: test involves parallel copies of the block-offdiagonal parts of the matrix.
3948: Level: intermediate
3950: Concepts: matrices^transposing, matrix^symmetry
3952: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
3953: @*/
3954: PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscTruth *flg)
3955: {
3956: PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscTruth*),(*g)(Mat,Mat,PetscReal,PetscTruth*);
3962: PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",(void (**)(void))&f);
3963: PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",(void (**)(void))&g);
3964: if (f && g) {
3965: if (f==g) {
3966: (*f)(A,B,tol,flg);
3967: } else {
3968: SETERRQ(PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
3969: }
3970: }
3971: return(0);
3972: }
3976: /*@
3977: MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,
3979: Collective on Mat
3981: Input Parameter:
3982: + A - the matrix to test
3983: - B - the matrix to test against, this can equal the first parameter
3985: Output Parameters:
3986: . flg - the result
3988: Notes:
3989: Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
3990: has a running time of the order of the number of nonzeros; the parallel
3991: test involves parallel copies of the block-offdiagonal parts of the matrix.
3993: Level: intermediate
3995: Concepts: matrices^transposing, matrix^symmetry
3997: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
3998: @*/
3999: PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscTruth *flg)
4000: {
4001: PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscTruth*),(*g)(Mat,Mat,PetscReal,PetscTruth*);
4007: PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",(void (**)(void))&f);
4008: PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",(void (**)(void))&g);
4009: if (f && g) {
4010: if (f==g) {
4011: (*f)(A,B,tol,flg);
4012: } else {
4013: SETERRQ(PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
4014: }
4015: }
4016: return(0);
4017: }
4021: /*@
4022: MatPermute - Creates a new matrix with rows and columns permuted from the
4023: original.
4025: Collective on Mat
4027: Input Parameters:
4028: + mat - the matrix to permute
4029: . row - row permutation, each processor supplies only the permutation for its rows
4030: - col - column permutation, each processor needs the entire column permutation, that is
4031: this is the same size as the total number of columns in the matrix
4033: Output Parameters:
4034: . B - the permuted matrix
4036: Level: advanced
4038: Concepts: matrices^permuting
4040: .seealso: MatGetOrdering()
4041: @*/
4042: PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
4043: {
4052: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4053: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4054: if (!mat->ops->permute) SETERRQ1(PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
4055: MatPreallocated(mat);
4057: (*mat->ops->permute)(mat,row,col,B);
4058: PetscObjectStateIncrease((PetscObject)*B);
4059: return(0);
4060: }
4064: /*@
4065: MatPermuteSparsify - Creates a new matrix with rows and columns permuted from the
4066: original and sparsified to the prescribed tolerance.
4068: Collective on Mat
4070: Input Parameters:
4071: + A - The matrix to permute
4072: . band - The half-bandwidth of the sparsified matrix, or PETSC_DECIDE
4073: . frac - The half-bandwidth as a fraction of the total size, or 0.0
4074: . tol - The drop tolerance
4075: . rowp - The row permutation
4076: - colp - The column permutation
4078: Output Parameter:
4079: . B - The permuted, sparsified matrix
4081: Level: advanced
4083: Note:
4084: The default behavior (band = PETSC_DECIDE and frac = 0.0) is to
4085: restrict the half-bandwidth of the resulting matrix to 5% of the
4086: total matrix size.
4088: .keywords: matrix, permute, sparsify
4090: .seealso: MatGetOrdering(), MatPermute()
4091: @*/
4092: PetscErrorCode MatPermuteSparsify(Mat A, PetscInt band, PetscReal frac, PetscReal tol, IS rowp, IS colp, Mat *B)
4093: {
4094: IS irowp, icolp;
4095: const PetscInt *rows, *cols;
4096: PetscInt M, N, locRowStart, locRowEnd;
4097: PetscInt nz, newNz;
4098: const PetscInt *cwork;
4099: PetscInt *cnew;
4100: const PetscScalar *vwork;
4101: PetscScalar *vnew;
4102: PetscInt bw, issize;
4103: PetscInt row, locRow, newRow, col, newCol;
4104: PetscErrorCode ierr;
4111: if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix");
4112: if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
4113: if (!A->ops->permutesparsify) {
4114: MatGetSize(A, &M, &N);
4115: MatGetOwnershipRange(A, &locRowStart, &locRowEnd);
4116: ISGetSize(rowp, &issize);
4117: if (issize != M) SETERRQ2(PETSC_ERR_ARG_WRONG, "Wrong size %D for row permutation, should be %D", issize, M);
4118: ISGetSize(colp, &issize);
4119: if (issize != N) SETERRQ2(PETSC_ERR_ARG_WRONG, "Wrong size %D for column permutation, should be %D", issize, N);
4120: ISInvertPermutation(rowp, 0, &irowp);
4121: ISGetIndices(irowp, &rows);
4122: ISInvertPermutation(colp, 0, &icolp);
4123: ISGetIndices(icolp, &cols);
4124: PetscMalloc(N * sizeof(PetscInt), &cnew);
4125: PetscMalloc(N * sizeof(PetscScalar), &vnew);
4127: /* Setup bandwidth to include */
4128: if (band == PETSC_DECIDE) {
4129: if (frac <= 0.0)
4130: bw = (PetscInt) (M * 0.05);
4131: else
4132: bw = (PetscInt) (M * frac);
4133: } else {
4134: if (band <= 0) SETERRQ(PETSC_ERR_ARG_WRONG, "Bandwidth must be a positive integer");
4135: bw = band;
4136: }
4138: /* Put values into new matrix */
4139: MatDuplicate(A, MAT_DO_NOT_COPY_VALUES, B);
4140: for(row = locRowStart, locRow = 0; row < locRowEnd; row++, locRow++) {
4141: MatGetRow(A, row, &nz, &cwork, &vwork);
4142: newRow = rows[locRow]+locRowStart;
4143: for(col = 0, newNz = 0; col < nz; col++) {
4144: newCol = cols[cwork[col]];
4145: if ((newCol >= newRow - bw) && (newCol < newRow + bw) && (PetscAbsScalar(vwork[col]) >= tol)) {
4146: cnew[newNz] = newCol;
4147: vnew[newNz] = vwork[col];
4148: newNz++;
4149: }
4150: }
4151: MatSetValues(*B, 1, &newRow, newNz, cnew, vnew, INSERT_VALUES);
4152: MatRestoreRow(A, row, &nz, &cwork, &vwork);
4153: }
4154: PetscFree(cnew);
4155: PetscFree(vnew);
4156: MatAssemblyBegin(*B, MAT_FINAL_ASSEMBLY);
4157: MatAssemblyEnd(*B, MAT_FINAL_ASSEMBLY);
4158: ISRestoreIndices(irowp, &rows);
4159: ISRestoreIndices(icolp, &cols);
4160: ISDestroy(irowp);
4161: ISDestroy(icolp);
4162: } else {
4163: (*A->ops->permutesparsify)(A, band, frac, tol, rowp, colp, B);
4164: }
4165: PetscObjectStateIncrease((PetscObject)*B);
4166: return(0);
4167: }
4171: /*@
4172: MatEqual - Compares two matrices.
4174: Collective on Mat
4176: Input Parameters:
4177: + A - the first matrix
4178: - B - the second matrix
4180: Output Parameter:
4181: . flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
4183: Level: intermediate
4185: Concepts: matrices^equality between
4186: @*/
4187: PetscErrorCode MatEqual(Mat A,Mat B,PetscTruth *flg)
4188: {
4198: MatPreallocated(B);
4199: if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4200: if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4201: 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);
4202: if (!A->ops->equal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4203: if (!B->ops->equal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4204: 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);
4205: MatPreallocated(A);
4207: (*A->ops->equal)(A,B,flg);
4208: return(0);
4209: }
4213: /*@
4214: MatDiagonalScale - Scales a matrix on the left and right by diagonal
4215: matrices that are stored as vectors. Either of the two scaling
4216: matrices can be PETSC_NULL.
4218: Collective on Mat
4220: Input Parameters:
4221: + mat - the matrix to be scaled
4222: . l - the left scaling vector (or PETSC_NULL)
4223: - r - the right scaling vector (or PETSC_NULL)
4225: Notes:
4226: MatDiagonalScale() computes A = LAR, where
4227: L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
4229: Level: intermediate
4231: Concepts: matrices^diagonal scaling
4232: Concepts: diagonal scaling of matrices
4234: .seealso: MatScale()
4235: @*/
4236: PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
4237: {
4243: if (!mat->ops->diagonalscale) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4246: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4247: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4248: MatPreallocated(mat);
4250: PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4251: (*mat->ops->diagonalscale)(mat,l,r);
4252: PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4253: PetscObjectStateIncrease((PetscObject)mat);
4254: return(0);
4255: }
4259: /*@
4260: MatScale - Scales all elements of a matrix by a given number.
4262: Collective on Mat
4264: Input Parameters:
4265: + mat - the matrix to be scaled
4266: - a - the scaling value
4268: Output Parameter:
4269: . mat - the scaled matrix
4271: Level: intermediate
4273: Concepts: matrices^scaling all entries
4275: .seealso: MatDiagonalScale()
4276: @*/
4277: PetscErrorCode MatScale(Mat mat,PetscScalar a)
4278: {
4284: if (a != 1.0 && !mat->ops->scale) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4285: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4286: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4287: MatPreallocated(mat);
4289: PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4290: if (a != 1.0) {
4291: (*mat->ops->scale)(mat,a);
4292: PetscObjectStateIncrease((PetscObject)mat);
4293: }
4294: PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4295: return(0);
4296: }
4300: /*@
4301: MatNorm - Calculates various norms of a matrix.
4303: Collective on Mat
4305: Input Parameters:
4306: + mat - the matrix
4307: - type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
4309: Output Parameters:
4310: . nrm - the resulting norm
4312: Level: intermediate
4314: Concepts: matrices^norm
4315: Concepts: norm^of matrix
4316: @*/
4317: PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
4318: {
4326: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4327: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4328: if (!mat->ops->norm) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4329: MatPreallocated(mat);
4331: (*mat->ops->norm)(mat,type,nrm);
4332: return(0);
4333: }
4335: /*
4336: This variable is used to prevent counting of MatAssemblyBegin() that
4337: are called from within a MatAssemblyEnd().
4338: */
4339: static PetscInt MatAssemblyEnd_InUse = 0;
4342: /*@
4343: MatAssemblyBegin - Begins assembling the matrix. This routine should
4344: be called after completing all calls to MatSetValues().
4346: Collective on Mat
4348: Input Parameters:
4349: + mat - the matrix
4350: - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
4351:
4352: Notes:
4353: MatSetValues() generally caches the values. The matrix is ready to
4354: use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4355: Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4356: in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4357: using the matrix.
4359: Level: beginner
4361: Concepts: matrices^assembling
4363: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
4364: @*/
4365: PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
4366: {
4372: MatPreallocated(mat);
4373: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
4374: if (mat->assembled) {
4375: mat->was_assembled = PETSC_TRUE;
4376: mat->assembled = PETSC_FALSE;
4377: }
4378: if (!MatAssemblyEnd_InUse) {
4379: PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);
4380: if (mat->ops->assemblybegin){(*mat->ops->assemblybegin)(mat,type);}
4381: PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);
4382: } else {
4383: if (mat->ops->assemblybegin){(*mat->ops->assemblybegin)(mat,type);}
4384: }
4385: return(0);
4386: }
4390: /*@
4391: MatAssembled - Indicates if a matrix has been assembled and is ready for
4392: use; for example, in matrix-vector product.
4394: Collective on Mat
4396: Input Parameter:
4397: . mat - the matrix
4399: Output Parameter:
4400: . assembled - PETSC_TRUE or PETSC_FALSE
4402: Level: advanced
4404: Concepts: matrices^assembled?
4406: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
4407: @*/
4408: PetscErrorCode MatAssembled(Mat mat,PetscTruth *assembled)
4409: {
4414: *assembled = mat->assembled;
4415: return(0);
4416: }
4420: /*
4421: Processes command line options to determine if/how a matrix
4422: is to be viewed. Called by MatAssemblyEnd() and MatLoad().
4423: */
4424: PetscErrorCode MatView_Private(Mat mat)
4425: {
4426: PetscErrorCode ierr;
4427: PetscTruth flg1,flg2,flg3,flg4,flg6,flg7,flg8;
4428: static PetscTruth incall = PETSC_FALSE;
4429: #if defined(PETSC_USE_SOCKET_VIEWER)
4430: PetscTruth flg5;
4431: #endif
4434: if (incall) return(0);
4435: incall = PETSC_TRUE;
4436: PetscOptionsBegin(((PetscObject)mat)->comm,((PetscObject)mat)->prefix,"Matrix Options","Mat");
4437: PetscOptionsName("-mat_view_info","Information on matrix size","MatView",&flg1);
4438: PetscOptionsName("-mat_view_info_detailed","Nonzeros in the matrix","MatView",&flg2);
4439: PetscOptionsName("-mat_view","Print matrix to stdout","MatView",&flg3);
4440: PetscOptionsName("-mat_view_matlab","Print matrix to stdout in a format Matlab can read","MatView",&flg4);
4441: #if defined(PETSC_USE_SOCKET_VIEWER)
4442: PetscOptionsName("-mat_view_socket","Send matrix to socket (can be read from matlab)","MatView",&flg5);
4443: #endif
4444: PetscOptionsName("-mat_view_binary","Save matrix to file in binary format","MatView",&flg6);
4445: PetscOptionsName("-mat_view_draw","Draw the matrix nonzero structure","MatView",&flg7);
4446: PetscOptionsEnd();
4448: if (flg1) {
4449: PetscViewer viewer;
4451: PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4452: PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO);
4453: MatView(mat,viewer);
4454: PetscViewerPopFormat(viewer);
4455: }
4456: if (flg2) {
4457: PetscViewer viewer;
4459: PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4460: PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO_DETAIL);
4461: MatView(mat,viewer);
4462: PetscViewerPopFormat(viewer);
4463: }
4464: if (flg3) {
4465: PetscViewer viewer;
4467: PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4468: MatView(mat,viewer);
4469: }
4470: if (flg4) {
4471: PetscViewer viewer;
4473: PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4474: PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);
4475: MatView(mat,viewer);
4476: PetscViewerPopFormat(viewer);
4477: }
4478: #if defined(PETSC_USE_SOCKET_VIEWER)
4479: if (flg5) {
4480: MatView(mat,PETSC_VIEWER_SOCKET_(((PetscObject)mat)->comm));
4481: PetscViewerFlush(PETSC_VIEWER_SOCKET_(((PetscObject)mat)->comm));
4482: }
4483: #endif
4484: if (flg6) {
4485: MatView(mat,PETSC_VIEWER_BINARY_(((PetscObject)mat)->comm));
4486: PetscViewerFlush(PETSC_VIEWER_BINARY_(((PetscObject)mat)->comm));
4487: }
4488: if (flg7) {
4489: PetscOptionsHasName(((PetscObject)mat)->prefix,"-mat_view_contour",&flg8);
4490: if (flg8) {
4491: PetscViewerPushFormat(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm),PETSC_VIEWER_DRAW_CONTOUR);
4492: }
4493: MatView(mat,PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));
4494: PetscViewerFlush(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));
4495: if (flg8) {
4496: PetscViewerPopFormat(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));
4497: }
4498: }
4499: incall = PETSC_FALSE;
4500: return(0);
4501: }
4505: /*@
4506: MatAssemblyEnd - Completes assembling the matrix. This routine should
4507: be called after MatAssemblyBegin().
4509: Collective on Mat
4511: Input Parameters:
4512: + mat - the matrix
4513: - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
4515: Options Database Keys:
4516: + -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly()
4517: . -mat_view_info_detailed - Prints more detailed info
4518: . -mat_view - Prints matrix in ASCII format
4519: . -mat_view_matlab - Prints matrix in Matlab format
4520: . -mat_view_draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
4521: . -display <name> - Sets display name (default is host)
4522: . -draw_pause <sec> - Sets number of seconds to pause after display
4523: . -mat_view_socket - Sends matrix to socket, can be accessed from Matlab (see users manual)
4524: . -viewer_socket_machine <machine>
4525: . -viewer_socket_port <port>
4526: . -mat_view_binary - save matrix to file in binary format
4527: - -viewer_binary_filename <name>
4529: Notes:
4530: MatSetValues() generally caches the values. The matrix is ready to
4531: use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4532: Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4533: in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4534: using the matrix.
4536: Level: beginner
4538: .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), MatView(), MatAssembled(), PetscViewerSocketOpen()
4539: @*/
4540: PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
4541: {
4542: PetscErrorCode ierr;
4543: static PetscInt inassm = 0;
4544: PetscTruth flg;
4550: inassm++;
4551: MatAssemblyEnd_InUse++;
4552: if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
4553: PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);
4554: if (mat->ops->assemblyend) {
4555: (*mat->ops->assemblyend)(mat,type);
4556: }
4557: PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);
4558: } else {
4559: if (mat->ops->assemblyend) {
4560: (*mat->ops->assemblyend)(mat,type);
4561: }
4562: }
4564: /* Flush assembly is not a true assembly */
4565: if (type != MAT_FLUSH_ASSEMBLY) {
4566: mat->assembled = PETSC_TRUE; mat->num_ass++;
4567: }
4568: mat->insertmode = NOT_SET_VALUES;
4569: MatAssemblyEnd_InUse--;
4570: PetscObjectStateIncrease((PetscObject)mat);
4571: if (!mat->symmetric_eternal) {
4572: mat->symmetric_set = PETSC_FALSE;
4573: mat->hermitian_set = PETSC_FALSE;
4574: mat->structurally_symmetric_set = PETSC_FALSE;
4575: }
4576: if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
4577: MatView_Private(mat);
4578: PetscOptionsHasName(((PetscObject)mat)->prefix,"-mat_is_symmetric",&flg);
4579: if (flg) {
4580: PetscReal tol = 0.0;
4581: PetscOptionsGetReal(((PetscObject)mat)->prefix,"-mat_is_symmetric",&tol,PETSC_NULL);
4582: MatIsSymmetric(mat,tol,&flg);
4583: if (flg) {
4584: PetscPrintf(((PetscObject)mat)->comm,"Matrix is symmetric (tolerance %G)\n",tol);
4585: } else {
4586: PetscPrintf(((PetscObject)mat)->comm,"Matrix is not symmetric (tolerance %G)\n",tol);
4587: }
4588: }
4589: }
4590: inassm--;
4591: return(0);
4592: }
4597: /*@
4598: MatCompress - Tries to store the matrix in as little space as
4599: possible. May fail if memory is already fully used, since it
4600: tries to allocate new space.
4602: Collective on Mat
4604: Input Parameters:
4605: . mat - the matrix
4607: Level: advanced
4609: @*/
4610: PetscErrorCode MatCompress(Mat mat)
4611: {
4617: MatPreallocated(mat);
4618: if (mat->ops->compress) {(*mat->ops->compress)(mat);}
4619: return(0);
4620: }
4624: /*@
4625: MatSetOption - Sets a parameter option for a matrix. Some options
4626: may be specific to certain storage formats. Some options
4627: determine how values will be inserted (or added). Sorted,
4628: row-oriented input will generally assemble the fastest. The default
4629: is row-oriented, nonsorted input.
4631: Collective on Mat
4633: Input Parameters:
4634: + mat - the matrix
4635: . option - the option, one of those listed below (and possibly others),
4636: - flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
4638: Options Describing Matrix Structure:
4639: + MAT_SYMMETRIC - symmetric in terms of both structure and value
4640: . MAT_HERMITIAN - transpose is the complex conjugation
4641: . MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
4642: - MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
4643: you set to be kept with all future use of the matrix
4644: including after MatAssemblyBegin/End() which could
4645: potentially change the symmetry structure, i.e. you
4646: KNOW the matrix will ALWAYS have the property you set.
4649: Options For Use with MatSetValues():
4650: Insert a logically dense subblock, which can be
4651: . MAT_ROW_ORIENTED - row-oriented (default)
4653: Note these options reflect the data you pass in with MatSetValues(); it has
4654: nothing to do with how the data is stored internally in the matrix
4655: data structure.
4657: When (re)assembling a matrix, we can restrict the input for
4658: efficiency/debugging purposes. These options include
4659: + MAT_NEW_NONZERO_LOCATIONS - additional insertions will be
4660: allowed if they generate a new nonzero
4661: . MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
4662: . MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
4663: . MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
4664: - MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
4666: Notes:
4667: Some options are relevant only for particular matrix types and
4668: are thus ignored by others. Other options are not supported by
4669: certain matrix types and will generate an error message if set.
4671: If using a Fortran 77 module to compute a matrix, one may need to
4672: use the column-oriented option (or convert to the row-oriented
4673: format).
4675: MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
4676: that would generate a new entry in the nonzero structure is instead
4677: ignored. Thus, if memory has not alredy been allocated for this particular
4678: data, then the insertion is ignored. For dense matrices, in which
4679: the entire array is allocated, no entries are ever ignored.
4680: Set after the first MatAssemblyEnd()
4682: MAT_NEW_NONZERO_LOCATION_ERR indicates that any add or insertion
4683: that would generate a new entry in the nonzero structure instead produces
4684: an error. (Currently supported for AIJ and BAIJ formats only.)
4685: This is a useful flag when using SAME_NONZERO_PATTERN in calling
4686: KSPSetOperators() to ensure that the nonzero pattern truely does
4687: remain unchanged. Set after the first MatAssemblyEnd()
4689: MAT_NEW_NONZERO_ALLOCATION_ERR indicates that any add or insertion
4690: that would generate a new entry that has not been preallocated will
4691: instead produce an error. (Currently supported for AIJ and BAIJ formats
4692: only.) This is a useful flag when debugging matrix memory preallocation.
4694: MAT_IGNORE_OFF_PROC_ENTRIES indicates entries destined for
4695: other processors should be dropped, rather than stashed.
4696: This is useful if you know that the "owning" processor is also
4697: always generating the correct matrix entries, so that PETSc need
4698: not transfer duplicate entries generated on another processor.
4699:
4700: MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
4701: searches during matrix assembly. When this flag is set, the hash table
4702: is created during the first Matrix Assembly. This hash table is
4703: used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
4704: to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
4705: should be used with MAT_USE_HASH_TABLE flag. This option is currently
4706: supported by MATMPIBAIJ format only.
4708: MAT_KEEP_ZEROED_ROWS indicates when MatZeroRows() is called the zeroed entries
4709: are kept in the nonzero structure
4711: MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
4712: a zero location in the matrix
4714: MAT_USE_INODES - indicates using inode version of the code - works with AIJ and
4715: ROWBS matrix types
4717: Level: intermediate
4719: Concepts: matrices^setting options
4721: @*/
4722: PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscTruth flg)
4723: {
4729: if (((int) op) < 0 || ((int) op) >= NUM_MAT_OPTIONS) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Options %d is out of range",(int)op);
4730: MatPreallocated(mat);
4731: switch (op) {
4732: case MAT_SYMMETRIC:
4733: mat->symmetric = flg;
4734: if (flg) mat->structurally_symmetric = PETSC_TRUE;
4735: mat->symmetric_set = PETSC_TRUE;
4736: mat->structurally_symmetric_set = flg;
4737: break;
4738: case MAT_HERMITIAN:
4739: mat->hermitian = flg;
4740: if (flg) mat->structurally_symmetric = PETSC_TRUE;
4741: mat->hermitian_set = PETSC_TRUE;
4742: mat->structurally_symmetric_set = flg;
4743: break;
4744: case MAT_STRUCTURALLY_SYMMETRIC:
4745: mat->structurally_symmetric = flg;
4746: mat->structurally_symmetric_set = PETSC_TRUE;
4747: break;
4748: case MAT_SYMMETRY_ETERNAL:
4749: mat->symmetric_eternal = flg;
4750: break;
4751: default:
4752: break;
4753: }
4754: if (mat->ops->setoption) {
4755: (*mat->ops->setoption)(mat,op,flg);
4756: }
4757: return(0);
4758: }
4762: /*@
4763: MatZeroEntries - Zeros all entries of a matrix. For sparse matrices
4764: this routine retains the old nonzero structure.
4766: Collective on Mat
4768: Input Parameters:
4769: . mat - the matrix
4771: Level: intermediate
4773: Concepts: matrices^zeroing
4775: .seealso: MatZeroRows()
4776: @*/
4777: PetscErrorCode MatZeroEntries(Mat mat)
4778: {
4784: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4785: if (mat->insertmode != NOT_SET_VALUES) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for matrices where you have set values but not yet assembled");
4786: if (!mat->ops->zeroentries) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4787: MatPreallocated(mat);
4789: PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);
4790: (*mat->ops->zeroentries)(mat);
4791: PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);
4792: PetscObjectStateIncrease((PetscObject)mat);
4793: return(0);
4794: }
4798: /*@C
4799: MatZeroRows - Zeros all entries (except possibly the main diagonal)
4800: of a set of rows of a matrix.
4802: Collective on Mat
4804: Input Parameters:
4805: + mat - the matrix
4806: . numRows - the number of rows to remove
4807: . rows - the global row indices
4808: - diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
4810: Notes:
4811: For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
4812: but does not release memory. For the dense and block diagonal
4813: formats this does not alter the nonzero structure.
4815: If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS,PETSC_TRUE) the nonzero structure
4816: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
4817: merely zeroed.
4819: The user can set a value in the diagonal entry (or for the AIJ and
4820: row formats can optionally remove the main diagonal entry from the
4821: nonzero structure as well, by passing 0.0 as the final argument).
4823: For the parallel case, all processes that share the matrix (i.e.,
4824: those in the communicator used for matrix creation) MUST call this
4825: routine, regardless of whether any rows being zeroed are owned by
4826: them.
4828: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
4829: list only rows local to itself).
4831: Level: intermediate
4833: Concepts: matrices^zeroing rows
4835: .seealso: MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
4836: @*/
4837: PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag)
4838: {
4845: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4846: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4847: if (!mat->ops->zerorows) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4848: MatPreallocated(mat);
4850: (*mat->ops->zerorows)(mat,numRows,rows,diag);
4851: MatView_Private(mat);
4852: PetscObjectStateIncrease((PetscObject)mat);
4853: return(0);
4854: }
4858: /*@C
4859: MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
4860: of a set of rows of a matrix.
4862: Collective on Mat
4864: Input Parameters:
4865: + mat - the matrix
4866: . is - index set of rows to remove
4867: - diag - value put in all diagonals of eliminated rows
4869: Notes:
4870: For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
4871: but does not release memory. For the dense and block diagonal
4872: formats this does not alter the nonzero structure.
4874: If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS,PETSC_TRUE) the nonzero structure
4875: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
4876: merely zeroed.
4878: The user can set a value in the diagonal entry (or for the AIJ and
4879: row formats can optionally remove the main diagonal entry from the
4880: nonzero structure as well, by passing 0.0 as the final argument).
4882: For the parallel case, all processes that share the matrix (i.e.,
4883: those in the communicator used for matrix creation) MUST call this
4884: routine, regardless of whether any rows being zeroed are owned by
4885: them.
4887: Each processor should list the rows that IT wants zeroed
4889: Level: intermediate
4891: Concepts: matrices^zeroing rows
4893: .seealso: MatZeroRows(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
4894: @*/
4895: PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag)
4896: {
4897: PetscInt numRows;
4898: const PetscInt *rows;
4905: ISGetLocalSize(is,&numRows);
4906: ISGetIndices(is,&rows);
4907: MatZeroRows(mat,numRows,rows,diag);
4908: ISRestoreIndices(is,&rows);
4909: return(0);
4910: }
4914: /*@C
4915: MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
4916: of a set of rows of a matrix; using local numbering of rows.
4918: Collective on Mat
4920: Input Parameters:
4921: + mat - the matrix
4922: . numRows - the number of rows to remove
4923: . rows - the global row indices
4924: - diag - value put in all diagonals of eliminated rows
4926: Notes:
4927: Before calling MatZeroRowsLocal(), the user must first set the
4928: local-to-global mapping by calling MatSetLocalToGlobalMapping().
4930: For the AIJ matrix formats this removes the old nonzero structure,
4931: but does not release memory. For the dense and block diagonal
4932: formats this does not alter the nonzero structure.
4934: If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS,PETSC_TRUE) the nonzero structure
4935: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
4936: merely zeroed.
4938: The user can set a value in the diagonal entry (or for the AIJ and
4939: row formats can optionally remove the main diagonal entry from the
4940: nonzero structure as well, by passing 0.0 as the final argument).
4942: Level: intermediate
4944: Concepts: matrices^zeroing
4946: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
4947: @*/
4948: PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag)
4949: {
4956: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4957: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4958: MatPreallocated(mat);
4960: if (mat->ops->zerorowslocal) {
4961: (*mat->ops->zerorowslocal)(mat,numRows,rows,diag);
4962: } else {
4963: IS is, newis;
4964: const PetscInt *newRows;
4966: if (!mat->mapping) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
4967: ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,&is);
4968: ISLocalToGlobalMappingApplyIS(mat->mapping,is,&newis);
4969: ISGetIndices(newis,&newRows);
4970: (*mat->ops->zerorows)(mat,numRows,newRows,diag);
4971: ISRestoreIndices(newis,&newRows);
4972: ISDestroy(newis);
4973: ISDestroy(is);
4974: }
4975: PetscObjectStateIncrease((PetscObject)mat);
4976: return(0);
4977: }
4981: /*@C
4982: MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
4983: of a set of rows of a matrix; using local numbering of rows.
4985: Collective on Mat
4987: Input Parameters:
4988: + mat - the matrix
4989: . is - index set of rows to remove
4990: - diag - value put in all diagonals of eliminated rows
4992: Notes:
4993: Before calling MatZeroRowsLocalIS(), the user must first set the
4994: local-to-global mapping by calling MatSetLocalToGlobalMapping().
4996: For the AIJ matrix formats this removes the old nonzero structure,
4997: but does not release memory. For the dense and block diagonal
4998: formats this does not alter the nonzero structure.
5000: If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS,PETSC_TRUE) the nonzero structure
5001: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5002: merely zeroed.
5004: The user can set a value in the diagonal entry (or for the AIJ and
5005: row formats can optionally remove the main diagonal entry from the
5006: nonzero structure as well, by passing 0.0 as the final argument).
5008: Level: intermediate
5010: Concepts: matrices^zeroing
5012: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5013: @*/
5014: PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag)
5015: {
5017: PetscInt numRows;
5018: const PetscInt *rows;
5024: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5025: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5026: MatPreallocated(mat);
5028: ISGetLocalSize(is,&numRows);
5029: ISGetIndices(is,&rows);
5030: MatZeroRowsLocal(mat,numRows,rows,diag);
5031: ISRestoreIndices(is,&rows);
5032: return(0);
5033: }
5037: /*@
5038: MatGetSize - Returns the numbers of rows and columns in a matrix.
5040: Not Collective
5042: Input Parameter:
5043: . mat - the matrix
5045: Output Parameters:
5046: + m - the number of global rows
5047: - n - the number of global columns
5049: Note: both output parameters can be PETSC_NULL on input.
5051: Level: beginner
5053: Concepts: matrices^size
5055: .seealso: MatGetLocalSize()
5056: @*/
5057: PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt* n)
5058: {
5061: if (m) *m = mat->rmap->N;
5062: if (n) *n = mat->cmap->N;
5063: return(0);
5064: }
5068: /*@
5069: MatGetLocalSize - Returns the number of rows and columns in a matrix
5070: stored locally. This information may be implementation dependent, so
5071: use with care.
5073: Not Collective
5075: Input Parameters:
5076: . mat - the matrix
5078: Output Parameters:
5079: + m - the number of local rows
5080: - n - the number of local columns
5082: Note: both output parameters can be PETSC_NULL on input.
5084: Level: beginner
5086: Concepts: matrices^local size
5088: .seealso: MatGetSize()
5089: @*/
5090: PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt* n)
5091: {
5096: if (m) *m = mat->rmap->n;
5097: if (n) *n = mat->cmap->n;
5098: return(0);
5099: }
5103: /*@
5104: MatGetOwnershipRangeColumn - Returns the range of matrix columns owned by
5105: this processor.
5107: Not Collective, unless matrix has not been allocated, then collective on Mat
5109: Input Parameters:
5110: . mat - the matrix
5112: Output Parameters:
5113: + m - the global index of the first local column
5114: - n - one more than the global index of the last local column
5116: Notes: both output parameters can be PETSC_NULL on input.
5118: Level: developer
5120: Concepts: matrices^column ownership
5122: .seealso: MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
5124: @*/
5125: PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt* n)
5126: {
5134: MatPreallocated(mat);
5135: if (m) *m = mat->cmap->rstart;
5136: if (n) *n = mat->cmap->rend;
5137: return(0);
5138: }
5142: /*@
5143: MatGetOwnershipRange - Returns the range of matrix rows owned by
5144: this processor, assuming that the matrix is laid out with the first
5145: n1 rows on the first processor, the next n2 rows on the second, etc.
5146: For certain parallel layouts this range may not be well defined.
5148: Not Collective, unless matrix has not been allocated, then collective on Mat
5150: Input Parameters:
5151: . mat - the matrix
5153: Output Parameters:
5154: + m - the global index of the first local row
5155: - n - one more than the global index of the last local row
5157: Note: both output parameters can be PETSC_NULL on input.
5159: Level: beginner
5161: Concepts: matrices^row ownership
5163: .seealso: MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
5165: @*/
5166: PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt* n)
5167: {
5175: MatPreallocated(mat);
5176: if (m) *m = mat->rmap->rstart;
5177: if (n) *n = mat->rmap->rend;
5178: return(0);
5179: }
5183: /*@C
5184: MatGetOwnershipRanges - Returns the range of matrix rows owned by
5185: each process
5187: Not Collective, unless matrix has not been allocated, then collective on Mat
5189: Input Parameters:
5190: . mat - the matrix
5192: Output Parameters:
5193: . ranges - start of each processors portion plus one more then the total length at the end
5195: Level: beginner
5197: Concepts: matrices^row ownership
5199: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
5201: @*/
5202: PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
5203: {
5209: MatPreallocated(mat);
5210: PetscMapGetRanges(mat->rmap,ranges);
5211: return(0);
5212: }
5216: /*@C
5217: MatGetOwnershipRangesColumn - Returns the range of local columns for each process
5219: Not Collective, unless matrix has not been allocated, then collective on Mat
5221: Input Parameters:
5222: . mat - the matrix
5224: Output Parameters:
5225: . ranges - start of each processors portion plus one more then the total length at the end
5227: Level: beginner
5229: Concepts: matrices^column ownership
5231: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
5233: @*/
5234: PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
5235: {
5241: MatPreallocated(mat);
5242: PetscMapGetRanges(mat->cmap,ranges);
5243: return(0);
5244: }
5248: /*@C
5249: MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
5250: Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
5251: to complete the factorization.
5253: Collective on Mat
5255: Input Parameters:
5256: + mat - the matrix
5257: . row - row permutation
5258: . column - column permutation
5259: - info - structure containing
5260: $ levels - number of levels of fill.
5261: $ expected fill - as ratio of original fill.
5262: $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices
5263: missing diagonal entries)
5265: Output Parameters:
5266: . fact - new matrix that has been symbolically factored
5268: Notes:
5269: See the users manual for additional information about
5270: choosing the fill factor for better efficiency.
5272: Most users should employ the simplified KSP interface for linear solvers
5273: instead of working directly with matrix algebra routines such as this.
5274: See, e.g., KSPCreate().
5276: Level: developer
5278: Concepts: matrices^symbolic LU factorization
5279: Concepts: matrices^factorization
5280: Concepts: LU^symbolic factorization
5282: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
5283: MatGetOrdering(), MatFactorInfo
5285: Developer Note: fortran interface is not autogenerated as the f90
5286: interface defintion cannot be generated correctly [due to MatFactorInfo]
5288: @*/
5289: PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
5290: {
5300: if (info->levels < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
5301: if (info->fill < 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
5302: if (!(fact)->ops->ilufactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s symbolic ILU",((PetscObject)mat)->type_name);
5303: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5304: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5305: MatPreallocated(mat);
5307: PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);
5308: (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);
5309: PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);
5310: return(0);
5311: }
5315: /*@C
5316: MatICCFactorSymbolic - Performs symbolic incomplete
5317: Cholesky factorization for a symmetric matrix. Use
5318: MatCholeskyFactorNumeric() to complete the factorization.
5320: Collective on Mat
5322: Input Parameters:
5323: + mat - the matrix
5324: . perm - row and column permutation
5325: - info - structure containing
5326: $ levels - number of levels of fill.
5327: $ expected fill - as ratio of original fill.
5329: Output Parameter:
5330: . fact - the factored matrix
5332: Notes:
5333: Most users should employ the KSP interface for linear solvers
5334: instead of working directly with matrix algebra routines such as this.
5335: See, e.g., KSPCreate().
5337: Level: developer
5339: Concepts: matrices^symbolic incomplete Cholesky factorization
5340: Concepts: matrices^factorization
5341: Concepts: Cholsky^symbolic factorization
5343: .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
5345: Developer Note: fortran interface is not autogenerated as the f90
5346: interface defintion cannot be generated correctly [due to MatFactorInfo]
5348: @*/
5349: PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
5350: {
5359: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5360: if (info->levels < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
5361: if (info->fill < 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
5362: if (!(fact)->ops->iccfactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s symbolic ICC",((PetscObject)mat)->type_name);
5363: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5364: MatPreallocated(mat);
5366: PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);
5367: (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);
5368: PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);
5369: return(0);
5370: }
5374: /*@C
5375: MatGetArray - Returns a pointer to the element values in the matrix.
5376: The result of this routine is dependent on the underlying matrix data
5377: structure, and may not even work for certain matrix types. You MUST
5378: call MatRestoreArray() when you no longer need to access the array.
5380: Not Collective
5382: Input Parameter:
5383: . mat - the matrix
5385: Output Parameter:
5386: . v - the location of the values
5389: Fortran Note:
5390: This routine is used differently from Fortran, e.g.,
5391: .vb
5392: Mat mat
5393: PetscScalar mat_array(1)
5394: PetscOffset i_mat
5395: PetscErrorCode ierr
5396: call MatGetArray(mat,mat_array,i_mat,ierr)
5398: C Access first local entry in matrix; note that array is
5399: C treated as one dimensional
5400: value = mat_array(i_mat + 1)
5402: [... other code ...]
5403: call MatRestoreArray(mat,mat_array,i_mat,ierr)
5404: .ve
5406: See the Fortran chapter of the users manual and
5407: petsc/src/mat/examples/tests for details.
5409: Level: advanced
5411: Concepts: matrices^access array
5413: .seealso: MatRestoreArray(), MatGetArrayF90(), MatGetRowIJ()
5414: @*/
5415: PetscErrorCode MatGetArray(Mat mat,PetscScalar *v[])
5416: {
5423: if (!mat->ops->getarray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5424: MatPreallocated(mat);
5425: (*mat->ops->getarray)(mat,v);
5426: CHKMEMQ;
5427: return(0);
5428: }
5432: /*@C
5433: MatRestoreArray - Restores the matrix after MatGetArray() has been called.
5435: Not Collective
5437: Input Parameter:
5438: + mat - the matrix
5439: - v - the location of the values
5441: Fortran Note:
5442: This routine is used differently from Fortran, e.g.,
5443: .vb
5444: Mat mat
5445: PetscScalar mat_array(1)
5446: PetscOffset i_mat
5447: PetscErrorCode ierr
5448: call MatGetArray(mat,mat_array,i_mat,ierr)
5450: C Access first local entry in matrix; note that array is
5451: C treated as one dimensional
5452: value = mat_array(i_mat + 1)
5454: [... other code ...]
5455: call MatRestoreArray(mat,mat_array,i_mat,ierr)
5456: .ve
5458: See the Fortran chapter of the users manual and
5459: petsc/src/mat/examples/tests for details
5461: Level: advanced
5463: .seealso: MatGetArray(), MatRestoreArrayF90()
5464: @*/
5465: PetscErrorCode MatRestoreArray(Mat mat,PetscScalar *v[])
5466: {
5473: #if defined(PETSC_USE_DEBUG)
5474: CHKMEMQ;
5475: #endif
5476: if (!mat->ops->restorearray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5477: (*mat->ops->restorearray)(mat,v);
5478: PetscObjectStateIncrease((PetscObject)mat);
5479: return(0);
5480: }
5484: /*@C
5485: MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
5486: points to an array of valid matrices, they may be reused to store the new
5487: submatrices.
5489: Collective on Mat
5491: Input Parameters:
5492: + mat - the matrix
5493: . n - the number of submatrixes to be extracted (on this processor, may be zero)
5494: . irow, icol - index sets of rows and columns to extract
5495: - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
5497: Output Parameter:
5498: . submat - the array of submatrices
5500: Notes:
5501: MatGetSubMatrices() can extract ONLY sequential submatrices
5502: (from both sequential and parallel matrices). Use MatGetSubMatrix()
5503: to extract a parallel submatrix.
5505: When extracting submatrices from a parallel matrix, each processor can
5506: form a different submatrix by setting the rows and columns of its
5507: individual index sets according to the local submatrix desired.
5509: When finished using the submatrices, the user should destroy
5510: them with MatDestroyMatrices().
5512: MAT_REUSE_MATRIX can only be used when the nonzero structure of the
5513: original matrix has not changed from that last call to MatGetSubMatrices().
5515: This routine creates the matrices in submat; you should NOT create them before
5516: calling it. It also allocates the array of matrix pointers submat.
5518: For BAIJ matrices the index sets must respect the block structure, that is if they
5519: request one row/column in a block, they must request all rows/columns that are in
5520: that block. For example, if the block size is 2 you cannot request just row 0 and
5521: column 0.
5523: Fortran Note:
5524: The Fortran interface is slightly different from that given below; it
5525: requires one to pass in as submat a Mat (integer) array of size at least m.
5527: Level: advanced
5529: Concepts: matrices^accessing submatrices
5530: Concepts: submatrices
5532: .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
5533: @*/
5534: PetscErrorCode MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
5535: {
5537: PetscInt i;
5538: PetscTruth eq;
5543: if (n) {
5548: }
5550: if (n && scall == MAT_REUSE_MATRIX) {
5553: }
5554: if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5555: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5556: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5557: MatPreallocated(mat);
5559: PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
5560: (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);
5561: PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
5562: for (i=0; i<n; i++) {
5563: if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
5564: ISEqual(irow[i],icol[i],&eq);
5565: if (eq) {
5566: if (mat->symmetric){
5567: MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
5568: } else if (mat->hermitian) {
5569: MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
5570: } else if (mat->structurally_symmetric) {
5571: MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
5572: }
5573: }
5574: }
5575: }
5576: return(0);
5577: }
5581: /*@C
5582: MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().
5584: Collective on Mat
5586: Input Parameters:
5587: + n - the number of local matrices
5588: - mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
5589: sequence of MatGetSubMatrices())
5591: Level: advanced
5593: Notes: Frees not only the matrices, but also the array that contains the matrices
5594: In Fortran will not free the array.
5596: .seealso: MatGetSubMatrices()
5597: @*/
5598: PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
5599: {
5601: PetscInt i;
5604: if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
5606: for (i=0; i<n; i++) {
5607: MatDestroy((*mat)[i]);
5608: }
5609: /* memory is allocated even if n = 0 */
5610: PetscFree(*mat);
5611: return(0);
5612: }
5616: /*@C
5617: MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
5619: Collective on Mat
5621: Input Parameters:
5622: . mat - the matrix
5624: Output Parameter:
5625: . matstruct - the sequential matrix with the nonzero structure of mat
5627: Level: intermediate
5629: .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
5630: @*/
5631: PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct[])
5632: {
5638:
5640: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5641: MatPreallocated(mat);
5643: PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);
5644: (*mat->ops->getseqnonzerostructure)(mat,matstruct);
5645: PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);
5646: return(0);
5647: }
5651: /*@C
5652: MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
5654: Collective on Mat
5656: Input Parameters:
5657: . mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
5658: sequence of MatGetSequentialNonzeroStructure())
5660: Level: advanced
5662: Notes: Frees not only the matrices, but also the array that contains the matrices
5664: .seealso: MatGetSeqNonzeroStructure()
5665: @*/
5666: PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat[])
5667: {
5672: MatDestroyMatrices(1,mat);
5673: return(0);
5674: }
5678: /*@
5679: MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
5680: replaces the index sets by larger ones that represent submatrices with
5681: additional overlap.
5683: Collective on Mat
5685: Input Parameters:
5686: + mat - the matrix
5687: . n - the number of index sets
5688: . is - the array of index sets (these index sets will changed during the call)
5689: - ov - the additional overlap requested
5691: Level: developer
5693: Concepts: overlap
5694: Concepts: ASM^computing overlap
5696: .seealso: MatGetSubMatrices()
5697: @*/
5698: PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
5699: {
5705: if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
5706: if (n) {
5709: }
5710: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5711: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5712: MatPreallocated(mat);
5714: if (!ov) return(0);
5715: if (!mat->ops->increaseoverlap) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5716: PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
5717: (*mat->ops->increaseoverlap)(mat,n,is,ov);
5718: PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
5719: return(0);
5720: }
5724: /*@
5725: MatGetBlockSize - Returns the matrix block size; useful especially for the
5726: block row and block diagonal formats.
5727:
5728: Not Collective
5730: Input Parameter:
5731: . mat - the matrix
5733: Output Parameter:
5734: . bs - block size
5736: Notes:
5737: Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ
5739: Level: intermediate
5741: Concepts: matrices^block size
5743: .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ()
5744: @*/
5745: PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
5746: {
5753: MatPreallocated(mat);
5754: *bs = mat->rmap->bs;
5755: return(0);
5756: }
5760: /*@
5761: MatSetBlockSize - Sets the matrix block size; for many matrix types you
5762: cannot use this and MUST set the blocksize when you preallocate the matrix
5763:
5764: Collective on Mat
5766: Input Parameters:
5767: + mat - the matrix
5768: - bs - block size
5770: Notes:
5771: Only works for shell and AIJ matrices
5773: Level: intermediate
5775: Concepts: matrices^block size
5777: .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ(), MatGetBlockSize()
5778: @*/
5779: PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
5780: {
5786: MatPreallocated(mat);
5787: if (mat->ops->setblocksize) {
5788: /* XXX should check if (bs < 1) ??? */
5789: PetscMapSetBlockSize(mat->rmap,bs);
5790: PetscMapSetBlockSize(mat->cmap,bs);
5791: (*mat->ops->setblocksize)(mat,bs);
5792: } else {
5793: SETERRQ1(PETSC_ERR_ARG_INCOMP,"Cannot set the blocksize for matrix type %s",((PetscObject)mat)->type_name);
5794: }
5795: return(0);
5796: }
5800: /*@C
5801: MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
5803: Collective on Mat
5805: Input Parameters:
5806: + mat - the matrix
5807: . shift - 0 or 1 indicating we want the indices starting at 0 or 1
5808: . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5809: symmetrized
5810: - blockcompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
5811: blockcompressed matrix is desired or not [inode, baij have blockcompressed
5812: nonzero structure which is different than the full nonzero structure]
5814: Output Parameters:
5815: + n - number of rows in the (possibly compressed) matrix
5816: . ia - the row pointers [of length n+1]
5817: . ja - the column indices
5818: - done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
5819: are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
5821: Level: developer
5823: Notes: You CANNOT change any of the ia[] or ja[] values.
5825: Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values
5827: Fortran Node
5829: In Fortran use
5830: $ PetscInt ia(1), ja(1)
5831: $ PetscOffset iia, jja
5832: $ call MatGetRowIJ(mat,shift,symmetric,blockcompressed,n,ia,iia,ja,jja,done,ierr)
5833:
5834: Acess the ith and jth entries via ia(iia + i) and ja(jja + j)
5836: .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatGetArray()
5837: @*/
5838: PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth blockcompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5839: {
5849: MatPreallocated(mat);
5850: if (!mat->ops->getrowij) *done = PETSC_FALSE;
5851: else {
5852: *done = PETSC_TRUE;
5853: PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);
5854: (*mat->ops->getrowij)(mat,shift,symmetric,blockcompressed,n,ia,ja,done);
5855: PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);
5856: }
5857: return(0);
5858: }
5862: /*@C
5863: MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
5865: Collective on Mat
5867: Input Parameters:
5868: + mat - the matrix
5869: . shift - 1 or zero indicating we want the indices starting at 0 or 1
5870: . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5871: symmetrized
5872: - blockcompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
5873: blockcompressed matrix is desired or not [inode, baij have blockcompressed
5874: nonzero structure which is different than the full nonzero structure]
5876: Output Parameters:
5877: + n - number of columns in the (possibly compressed) matrix
5878: . ia - the column pointers
5879: . ja - the row indices
5880: - done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
5882: Level: developer
5884: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
5885: @*/
5886: PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth blockcompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5887: {
5897: MatPreallocated(mat);
5898: if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
5899: else {
5900: *done = PETSC_TRUE;
5901: (*mat->ops->getcolumnij)(mat,shift,symmetric,blockcompressed,n,ia,ja,done);
5902: }
5903: return(0);
5904: }
5908: /*@C
5909: MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
5910: MatGetRowIJ().
5912: Collective on Mat
5914: Input Parameters:
5915: + mat - the matrix
5916: . shift - 1 or zero indicating we want the indices starting at 0 or 1
5917: . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5918: symmetrized
5919: - blockcompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
5920: blockcompressed matrix is desired or not [inode, baij have blockcompressed
5921: nonzero structure which is different than the full nonzero structure]
5923: Output Parameters:
5924: + n - size of (possibly compressed) matrix
5925: . ia - the row pointers
5926: . ja - the column indices
5927: - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
5929: Level: developer
5931: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
5932: @*/
5933: PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth blockcompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5934: {
5943: MatPreallocated(mat);
5945: if (!mat->ops->restorerowij) *done = PETSC_FALSE;
5946: else {
5947: *done = PETSC_TRUE;
5948: (*mat->ops->restorerowij)(mat,shift,symmetric,blockcompressed,n,ia,ja,done);
5949: }
5950: return(0);
5951: }
5955: /*@C
5956: MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
5957: MatGetColumnIJ().
5959: Collective on Mat
5961: Input Parameters:
5962: + mat - the matrix
5963: . shift - 1 or zero indicating we want the indices starting at 0 or 1
5964: - symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5965: symmetrized
5966: - blockcompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
5967: blockcompressed matrix is desired or not [inode, baij have blockcompressed
5968: nonzero structure which is different than the full nonzero structure]
5970: Output Parameters:
5971: + n - size of (possibly compressed) matrix
5972: . ia - the column pointers
5973: . ja - the row indices
5974: - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
5976: Level: developer
5978: .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
5979: @*/
5980: PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth blockcompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5981: {
5990: MatPreallocated(mat);
5992: if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
5993: else {
5994: *done = PETSC_TRUE;
5995: (*mat->ops->restorecolumnij)(mat,shift,symmetric,blockcompressed,n,ia,ja,done);
5996: }
5997: return(0);
5998: }
6002: /*@C
6003: MatColoringPatch -Used inside matrix coloring routines that
6004: use MatGetRowIJ() and/or MatGetColumnIJ().
6006: Collective on Mat
6008: Input Parameters:
6009: + mat - the matrix
6010: . ncolors - max color value
6011: . n - number of entries in colorarray
6012: - colorarray - array indicating color for each column
6014: Output Parameters:
6015: . iscoloring - coloring generated using colorarray information
6017: Level: developer
6019: .seealso: MatGetRowIJ(), MatGetColumnIJ()
6021: @*/
6022: PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
6023: {
6031: MatPreallocated(mat);
6033: if (!mat->ops->coloringpatch){
6034: ISColoringCreate(((PetscObject)mat)->comm,ncolors,n,colorarray,iscoloring);
6035: } else {
6036: (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);
6037: }
6038: return(0);
6039: }
6044: /*@
6045: MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
6047: Collective on Mat
6049: Input Parameter:
6050: . mat - the factored matrix to be reset
6052: Notes:
6053: This routine should be used only with factored matrices formed by in-place
6054: factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
6055: format). This option can save memory, for example, when solving nonlinear
6056: systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
6057: ILU(0) preconditioner.
6059: Note that one can specify in-place ILU(0) factorization by calling
6060: .vb
6061: PCType(pc,PCILU);
6062: PCFactorSeUseInPlace(pc);
6063: .ve
6064: or by using the options -pc_type ilu -pc_factor_in_place
6066: In-place factorization ILU(0) can also be used as a local
6067: solver for the blocks within the block Jacobi or additive Schwarz
6068: methods (runtime option: -sub_pc_factor_in_place). See the discussion
6069: of these preconditioners in the users manual for details on setting
6070: local solver options.
6072: Most users should employ the simplified KSP interface for linear solvers
6073: instead of working directly with matrix algebra routines such as this.
6074: See, e.g., KSPCreate().
6076: Level: developer
6078: .seealso: PCFactorSetUseInPlace()
6080: Concepts: matrices^unfactored
6082: @*/
6083: PetscErrorCode MatSetUnfactored(Mat mat)
6084: {
6090: MatPreallocated(mat);
6091: mat->factor = MAT_FACTOR_NONE;
6092: if (!mat->ops->setunfactored) return(0);
6093: (*mat->ops->setunfactored)(mat);
6094: return(0);
6095: }
6097: /*MC
6098: MatGetArrayF90 - Accesses a matrix array from Fortran90.
6100: Synopsis:
6101: MatGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
6103: Not collective
6105: Input Parameter:
6106: . x - matrix
6108: Output Parameters:
6109: + xx_v - the Fortran90 pointer to the array
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
6121: Notes:
6122: Not yet supported for all F90 compilers
6124: Level: advanced
6126: .seealso: MatRestoreArrayF90(), MatGetArray(), MatRestoreArray()
6128: Concepts: matrices^accessing array
6130: M*/
6132: /*MC
6133: MatRestoreArrayF90 - Restores a matrix array that has been
6134: accessed with MatGetArrayF90().
6136: Synopsis:
6137: MatRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
6139: Not collective
6141: Input Parameters:
6142: + x - matrix
6143: - xx_v - the Fortran90 pointer to the array
6145: Output Parameter:
6146: . ierr - error code
6148: Example of Usage:
6149: .vb
6150: PetscScalar, pointer xx_v(:)
6151: ....
6152: call MatGetArrayF90(x,xx_v,ierr)
6153: a = xx_v(3)
6154: call MatRestoreArrayF90(x,xx_v,ierr)
6155: .ve
6156:
6157: Notes:
6158: Not yet supported for all F90 compilers
6160: Level: advanced
6162: .seealso: MatGetArrayF90(), MatGetArray(), MatRestoreArray()
6164: M*/
6169: /*@
6170: MatGetSubMatrix - Gets a single submatrix on the same number of processors
6171: as the original matrix.
6173: Collective on Mat
6175: Input Parameters:
6176: + mat - the original matrix
6177: . isrow - rows this processor should obtain
6178: . iscol - columns for all processors you wish to keep
6179: . csize - number of columns "local" to this processor (does nothing for sequential
6180: matrices). This should match the result from VecGetLocalSize(x,...) if you
6181: plan to use the matrix in a A*x; alternatively, you can use PETSC_DECIDE
6182: - cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6184: Output Parameter:
6185: . newmat - the new submatrix, of the same type as the old
6187: Level: advanced
6189: Notes: the iscol argument MUST be the same on each processor. You might be
6190: able to create the iscol argument with ISAllGather(). The rows is isrow will be
6191: sorted into the same order as the original matrix.
6193: The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
6194: the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
6195: to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
6196: will reuse the matrix generated the first time. You should call MatDestroy() on newmat when
6197: you are finished using it.
6199: The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
6200: the input matrix.
6202: If iscol is PETSC_NULL then all columns are obtained (not supported in Fortran), you should
6203: use csize = PETSC_DECIDE also in this case.
6205: Concepts: matrices^submatrices
6207: .seealso: MatGetSubMatrices(), ISAllGather()
6208: @*/
6209: PetscErrorCode MatGetSubMatrix(Mat mat,IS isrow,IS iscol,PetscInt csize,MatReuse cll,Mat *newmat)
6210: {
6212: PetscMPIInt size;
6213: Mat *local;
6214: IS iscoltmp;
6223: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6224: MatPreallocated(mat);
6225: MPI_Comm_size(((PetscObject)mat)->comm,&size);
6227: if (!iscol) {
6228: if (csize == PETSC_DECIDE) csize = mat->cmap->n;
6229: ISCreateStride(((PetscObject)mat)->comm,mat->cmap->N,0,1,&iscoltmp);
6230: } else {
6231: iscoltmp = iscol;
6232: }
6234: /* if original matrix is on just one processor then use submatrix generated */
6235: if (!mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
6236: MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);
6237: if (!iscol) {ISDestroy(iscoltmp);}
6238: return(0);
6239: } else if (!mat->ops->getsubmatrix && size == 1) {
6240: MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);
6241: *newmat = *local;
6242: PetscFree(local);
6243: if (!iscol) {ISDestroy(iscoltmp);}
6244: return(0);
6245: }
6247: if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6248: (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,csize,cll,newmat);
6249: if (!iscol) {ISDestroy(iscoltmp);}
6250: PetscObjectStateIncrease((PetscObject)*newmat);
6251: return(0);
6252: }
6256: /*@
6257: MatGetSubMatrixRaw - Gets a single submatrix on the same number of processors
6258: as the original matrix.
6260: Collective on Mat
6262: Input Parameters:
6263: + mat - the original matrix
6264: . nrows - the number of rows this processor should obtain
6265: . rows - rows this processor should obtain
6266: . ncols - the number of columns for all processors you wish to keep
6267: . cols - columns for all processors you wish to keep
6268: . csize - number of columns "local" to this processor (does nothing for sequential
6269: matrices). This should match the result from VecGetLocalSize(x,...) if you
6270: plan to use the matrix in a A*x; alternatively, you can use PETSC_DECIDE
6271: - cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6273: Output Parameter:
6274: . newmat - the new submatrix, of the same type as the old
6276: Level: advanced
6278: Notes: the iscol argument MUST be the same on each processor. You might be
6279: able to create the iscol argument with ISAllGather().
6281: The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
6282: the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
6283: to this routine with a mat of the same nonzero structure and with a cll of MAT_REUSE_MATRIX
6284: will reuse the matrix generated the first time.
6286: Concepts: matrices^submatrices
6288: .seealso: MatGetSubMatrices(), ISAllGather()
6289: @*/
6290: PetscErrorCode MatGetSubMatrixRaw(Mat mat,PetscInt nrows,const PetscInt rows[],PetscInt ncols,const PetscInt cols[],PetscInt csize,MatReuse cll,Mat *newmat)
6291: {
6292: IS isrow, iscol;
6302: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6303: MatPreallocated(mat);
6304: ISCreateGeneralWithArray(PETSC_COMM_SELF, nrows, (PetscInt *) rows, &isrow);
6305: ISCreateGeneralWithArray(PETSC_COMM_SELF, ncols, (PetscInt *) cols, &iscol);
6306: MatGetSubMatrix(mat, isrow, iscol, csize, cll, newmat);
6307: ISDestroy(isrow);
6308: ISDestroy(iscol);
6309: return(0);
6310: }
6314: /*@
6315: MatStashSetInitialSize - sets the sizes of the matrix stash, that is
6316: used during the assembly process to store values that belong to
6317: other processors.
6319: Not Collective
6321: Input Parameters:
6322: + mat - the matrix
6323: . size - the initial size of the stash.
6324: - bsize - the initial size of the block-stash(if used).
6326: Options Database Keys:
6327: + -matstash_initial_size <size> or <size0,size1,...sizep-1>
6328: - -matstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1>
6330: Level: intermediate
6332: Notes:
6333: The block-stash is used for values set with MatSetValuesBlocked() while
6334: the stash is used for values set with MatSetValues()
6336: Run with the option -info and look for output of the form
6337: MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
6338: to determine the appropriate value, MM, to use for size and
6339: MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
6340: to determine the value, BMM to use for bsize
6342: Concepts: stash^setting matrix size
6343: Concepts: matrices^stash
6345: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
6347: @*/
6348: PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
6349: {
6355: MatStashSetInitialSize_Private(&mat->stash,size);
6356: MatStashSetInitialSize_Private(&mat->bstash,bsize);
6357: return(0);
6358: }
6362: /*@
6363: MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
6364: the matrix
6366: Collective on Mat
6368: Input Parameters:
6369: + mat - the matrix
6370: . x,y - the vectors
6371: - w - where the result is stored
6373: Level: intermediate
6375: Notes:
6376: w may be the same vector as y.
6378: This allows one to use either the restriction or interpolation (its transpose)
6379: matrix to do the interpolation
6381: Concepts: interpolation
6383: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
6385: @*/
6386: PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
6387: {
6389: PetscInt M,N;
6397: MatPreallocated(A);
6398: MatGetSize(A,&M,&N);
6399: if (N > M) {
6400: MatMultTransposeAdd(A,x,y,w);
6401: } else {
6402: MatMultAdd(A,x,y,w);
6403: }
6404: return(0);
6405: }
6409: /*@
6410: MatInterpolate - y = A*x or A'*x depending on the shape of
6411: the matrix
6413: Collective on Mat
6415: Input Parameters:
6416: + mat - the matrix
6417: - x,y - the vectors
6419: Level: intermediate
6421: Notes:
6422: This allows one to use either the restriction or interpolation (its transpose)
6423: matrix to do the interpolation
6425: Concepts: matrices^interpolation
6427: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
6429: @*/
6430: PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
6431: {
6433: PetscInt M,N;
6440: MatPreallocated(A);
6441: MatGetSize(A,&M,&N);
6442: if (N > M) {
6443: MatMultTranspose(A,x,y);
6444: } else {
6445: MatMult(A,x,y);
6446: }
6447: return(0);
6448: }
6452: /*@
6453: MatRestrict - y = A*x or A'*x
6455: Collective on Mat
6457: Input Parameters:
6458: + mat - the matrix
6459: - x,y - the vectors
6461: Level: intermediate
6463: Notes:
6464: This allows one to use either the restriction or interpolation (its transpose)
6465: matrix to do the restriction
6467: Concepts: matrices^restriction
6469: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
6471: @*/
6472: PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
6473: {
6475: PetscInt M,N;
6482: MatPreallocated(A);
6484: MatGetSize(A,&M,&N);
6485: if (N > M) {
6486: MatMult(A,x,y);
6487: } else {
6488: MatMultTranspose(A,x,y);
6489: }
6490: return(0);
6491: }
6495: /*@
6496: MatNullSpaceAttach - attaches a null space to a matrix.
6497: This null space will be removed from the resulting vector whenever
6498: MatMult() is called
6500: Collective on Mat
6502: Input Parameters:
6503: + mat - the matrix
6504: - nullsp - the null space object
6506: Level: developer
6508: Notes:
6509: Overwrites any previous null space that may have been attached
6511: Concepts: null space^attaching to matrix
6513: .seealso: MatCreate(), MatNullSpaceCreate()
6514: @*/
6515: PetscErrorCode MatNullSpaceAttach(Mat mat,MatNullSpace nullsp)
6516: {
6523: MatPreallocated(mat);
6524: PetscObjectReference((PetscObject)nullsp);
6525: if (mat->nullsp) { MatNullSpaceDestroy(mat->nullsp); }
6526: mat->nullsp = nullsp;
6527: return(0);
6528: }
6532: /*@C
6533: MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
6535: Collective on Mat
6537: Input Parameters:
6538: + mat - the matrix
6539: . row - row/column permutation
6540: . fill - expected fill factor >= 1.0
6541: - level - level of fill, for ICC(k)
6543: Notes:
6544: Probably really in-place only when level of fill is zero, otherwise allocates
6545: new space to store factored matrix and deletes previous memory.
6547: Most users should employ the simplified KSP interface for linear solvers
6548: instead of working directly with matrix algebra routines such as this.
6549: See, e.g., KSPCreate().
6551: Level: developer
6553: Concepts: matrices^incomplete Cholesky factorization
6554: Concepts: Cholesky factorization
6556: .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6558: Developer Note: fortran interface is not autogenerated as the f90
6559: interface defintion cannot be generated correctly [due to MatFactorInfo]
6561: @*/
6562: PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo* info)
6563: {
6571: if (mat->rmap->N != mat->cmap->N) SETERRQ(PETSC_ERR_ARG_WRONG,"matrix must be square");
6572: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6573: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6574: if (!mat->ops->iccfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6575: MatPreallocated(mat);
6576: (*mat->ops->iccfactor)(mat,row,info);
6577: PetscObjectStateIncrease((PetscObject)mat);
6578: return(0);
6579: }
6583: /*@
6584: MatSetValuesAdic - Sets values computed with ADIC automatic differentiation into a matrix.
6586: Not Collective
6588: Input Parameters:
6589: + mat - the matrix
6590: - v - the values compute with ADIC
6592: Level: developer
6594: Notes:
6595: Must call MatSetColoring() before using this routine. Also this matrix must already
6596: have its nonzero pattern determined.
6598: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
6599: MatSetValues(), MatSetColoring(), MatSetValuesAdifor()
6600: @*/
6601: PetscErrorCode MatSetValuesAdic(Mat mat,void *v)
6602: {
6610: if (!mat->assembled) {
6611: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6612: }
6613: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
6614: if (!mat->ops->setvaluesadic) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6615: (*mat->ops->setvaluesadic)(mat,v);
6616: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
6617: MatView_Private(mat);
6618: PetscObjectStateIncrease((PetscObject)mat);
6619: return(0);
6620: }
6625: /*@
6626: MatSetColoring - Sets a coloring used by calls to MatSetValuesAdic()
6628: Not Collective
6630: Input Parameters:
6631: + mat - the matrix
6632: - coloring - the coloring
6634: Level: developer
6636: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
6637: MatSetValues(), MatSetValuesAdic()
6638: @*/
6639: PetscErrorCode MatSetColoring(Mat mat,ISColoring coloring)
6640: {
6648: if (!mat->assembled) {
6649: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6650: }
6651: if (!mat->ops->setcoloring) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6652: (*mat->ops->setcoloring)(mat,coloring);
6653: return(0);
6654: }
6658: /*@
6659: MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.
6661: Not Collective
6663: Input Parameters:
6664: + mat - the matrix
6665: . nl - leading dimension of v
6666: - v - the values compute with ADIFOR
6668: Level: developer
6670: Notes:
6671: Must call MatSetColoring() before using this routine. Also this matrix must already
6672: have its nonzero pattern determined.
6674: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
6675: MatSetValues(), MatSetColoring()
6676: @*/
6677: PetscErrorCode MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
6678: {
6686: if (!mat->assembled) {
6687: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6688: }
6689: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
6690: if (!mat->ops->setvaluesadifor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6691: (*mat->ops->setvaluesadifor)(mat,nl,v);
6692: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
6693: PetscObjectStateIncrease((PetscObject)mat);
6694: return(0);
6695: }
6699: /*@
6700: MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
6701: ghosted ones.
6703: Not Collective
6705: Input Parameters:
6706: + mat - the matrix
6707: - diag = the diagonal values, including ghost ones
6709: Level: developer
6711: Notes: Works only for MPIAIJ and MPIBAIJ matrices
6712:
6713: .seealso: MatDiagonalScale()
6714: @*/
6715: PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
6716: {
6718: PetscMPIInt size;
6725: if (!mat->assembled) {
6726: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6727: }
6728: PetscLogEventBegin(MAT_Scale,mat,0,0,0);
6729: MPI_Comm_size(((PetscObject)mat)->comm,&size);
6730: if (size == 1) {
6731: PetscInt n,m;
6732: VecGetSize(diag,&n);
6733: MatGetSize(mat,0,&m);
6734: if (m == n) {
6735: MatDiagonalScale(mat,0,diag);
6736: } else {
6737: SETERRQ(PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
6738: }
6739: } else {
6740: PetscErrorCode (*f)(Mat,Vec);
6741: PetscObjectQueryFunction((PetscObject)mat,"MatDiagonalScaleLocal_C",(void (**)(void))&f);
6742: if (f) {
6743: (*f)(mat,diag);
6744: } else {
6745: SETERRQ(PETSC_ERR_SUP,"Only supported for MPIAIJ and MPIBAIJ parallel matrices");
6746: }
6747: }
6748: PetscLogEventEnd(MAT_Scale,mat,0,0,0);
6749: PetscObjectStateIncrease((PetscObject)mat);
6750: return(0);
6751: }
6755: /*@
6756: MatGetInertia - Gets the inertia from a factored matrix
6758: Collective on Mat
6760: Input Parameter:
6761: . mat - the matrix
6763: Output Parameters:
6764: + nneg - number of negative eigenvalues
6765: . nzero - number of zero eigenvalues
6766: - npos - number of positive eigenvalues
6768: Level: advanced
6770: Notes: Matrix must have been factored by MatCholeskyFactor()
6773: @*/
6774: PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
6775: {
6781: if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
6782: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
6783: if (!mat->ops->getinertia) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6784: (*mat->ops->getinertia)(mat,nneg,nzero,npos);
6785: return(0);
6786: }
6788: /* ----------------------------------------------------------------*/
6791: /*@C
6792: MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
6794: Collective on Mat and Vecs
6796: Input Parameters:
6797: + mat - the factored matrix
6798: - b - the right-hand-side vectors
6800: Output Parameter:
6801: . x - the result vectors
6803: Notes:
6804: The vectors b and x cannot be the same. I.e., one cannot
6805: call MatSolves(A,x,x).
6807: Notes:
6808: Most users should employ the simplified KSP interface for linear solvers
6809: instead of working directly with matrix algebra routines such as this.
6810: See, e.g., KSPCreate().
6812: Level: developer
6814: Concepts: matrices^triangular solves
6816: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
6817: @*/
6818: PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
6819: {
6825: if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
6826: if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
6827: if (!mat->rmap->N && !mat->cmap->N) return(0);
6829: if (!mat->ops->solves) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6830: MatPreallocated(mat);
6831: PetscLogEventBegin(MAT_Solves,mat,0,0,0);
6832: (*mat->ops->solves)(mat,b,x);
6833: PetscLogEventEnd(MAT_Solves,mat,0,0,0);
6834: return(0);
6835: }
6839: /*@
6840: MatIsSymmetric - Test whether a matrix is symmetric
6842: Collective on Mat
6844: Input Parameter:
6845: + A - the matrix to test
6846: - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
6848: Output Parameters:
6849: . flg - the result
6851: Level: intermediate
6853: Concepts: matrix^symmetry
6855: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
6856: @*/
6857: PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscTruth *flg)
6858: {
6864: if (!A->symmetric_set) {
6865: if (!A->ops->issymmetric) {
6866: const MatType mattype;
6867: MatGetType(A,&mattype);
6868: SETERRQ1(PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
6869: }
6870: (*A->ops->issymmetric)(A,tol,&A->symmetric);
6871: A->symmetric_set = PETSC_TRUE;
6872: if (A->symmetric) {
6873: A->structurally_symmetric_set = PETSC_TRUE;
6874: A->structurally_symmetric = PETSC_TRUE;
6875: }
6876: }
6877: *flg = A->symmetric;
6878: return(0);
6879: }
6883: /*@
6884: MatIsHermitian - Test whether a matrix is Hermitian
6886: Collective on Mat
6888: Input Parameter:
6889: + A - the matrix to test
6890: - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
6892: Output Parameters:
6893: . flg - the result
6895: Level: intermediate
6897: Concepts: matrix^symmetry
6899: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
6900: @*/
6901: PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscTruth *flg)
6902: {
6908: if (!A->hermitian_set) {
6909: if (!A->ops->ishermitian) {
6910: const MatType mattype;
6911: MatGetType(A,&mattype);
6912: SETERRQ1(PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for Hermitian",mattype);
6913: }
6914: (*A->ops->ishermitian)(A,tol,&A->hermitian);
6915: A->hermitian_set = PETSC_TRUE;
6916: if (A->hermitian) {
6917: A->structurally_symmetric_set = PETSC_TRUE;
6918: A->structurally_symmetric = PETSC_TRUE;
6919: }
6920: }
6921: *flg = A->hermitian;
6922: return(0);
6923: }
6927: /*@
6928: MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
6930: Collective on Mat
6932: Input Parameter:
6933: . A - the matrix to check
6935: Output Parameters:
6936: + set - if the symmetric flag is set (this tells you if the next flag is valid)
6937: - flg - the result
6939: Level: advanced
6941: Concepts: matrix^symmetry
6943: Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
6944: if you want it explicitly checked
6946: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
6947: @*/
6948: PetscErrorCode MatIsSymmetricKnown(Mat A,PetscTruth *set,PetscTruth *flg)
6949: {
6954: if (A->symmetric_set) {
6955: *set = PETSC_TRUE;
6956: *flg = A->symmetric;
6957: } else {
6958: *set = PETSC_FALSE;
6959: }
6960: return(0);
6961: }
6965: /*@
6966: MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
6968: Collective on Mat
6970: Input Parameter:
6971: . A - the matrix to check
6973: Output Parameters:
6974: + set - if the hermitian flag is set (this tells you if the next flag is valid)
6975: - flg - the result
6977: Level: advanced
6979: Concepts: matrix^symmetry
6981: Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
6982: if you want it explicitly checked
6984: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
6985: @*/
6986: PetscErrorCode MatIsHermitianKnown(Mat A,PetscTruth *set,PetscTruth *flg)
6987: {
6992: if (A->hermitian_set) {
6993: *set = PETSC_TRUE;
6994: *flg = A->hermitian;
6995: } else {
6996: *set = PETSC_FALSE;
6997: }
6998: return(0);
6999: }
7003: /*@
7004: MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
7006: Collective on Mat
7008: Input Parameter:
7009: . A - the matrix to test
7011: Output Parameters:
7012: . flg - the result
7014: Level: intermediate
7016: Concepts: matrix^symmetry
7018: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
7019: @*/
7020: PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscTruth *flg)
7021: {
7027: if (!A->structurally_symmetric_set) {
7028: if (!A->ops->isstructurallysymmetric) SETERRQ(PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
7029: (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);
7030: A->structurally_symmetric_set = PETSC_TRUE;
7031: }
7032: *flg = A->structurally_symmetric;
7033: return(0);
7034: }
7039: /*@
7040: MatStashGetInfo - Gets how many values are currently in the vector stash, i.e. need
7041: to be communicated to other processors during the MatAssemblyBegin/End() process
7043: Not collective
7045: Input Parameter:
7046: . vec - the vector
7048: Output Parameters:
7049: + nstash - the size of the stash
7050: . reallocs - the number of additional mallocs incurred.
7051: . bnstash - the size of the block stash
7052: - breallocs - the number of additional mallocs incurred.in the block stash
7053:
7054: Level: advanced
7056: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
7057:
7058: @*/
7059: PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
7060: {
7063: MatStashGetInfo_Private(&mat->stash,nstash,reallocs);
7064: MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);
7065: return(0);
7066: }
7070: /*@C
7071: MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same
7072: parallel layout
7073:
7074: Collective on Mat
7076: Input Parameter:
7077: . mat - the matrix
7079: Output Parameter:
7080: + right - (optional) vector that the matrix can be multiplied against
7081: - left - (optional) vector that the matrix vector product can be stored in
7083: Level: advanced
7085: .seealso: MatCreate()
7086: @*/
7087: PetscErrorCode MatGetVecs(Mat mat,Vec *right,Vec *left)
7088: {
7094: MatPreallocated(mat);
7095: if (mat->ops->getvecs) {
7096: (*mat->ops->getvecs)(mat,right,left);
7097: } else {
7098: PetscMPIInt size;
7099: MPI_Comm_size(((PetscObject)mat)->comm, &size);
7100: if (right) {
7101: VecCreate(((PetscObject)mat)->comm,right);
7102: VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);
7103: VecSetBlockSize(*right,mat->rmap->bs);
7104: if (size > 1) {
7105: /* New vectors uses Mat cmap and does not create a new one */
7106: PetscMapDestroy((*right)->map);
7107: (*right)->map = mat->cmap;
7108: mat->cmap->refcnt++;
7110: VecSetType(*right,VECMPI);
7111: } else {VecSetType(*right,VECSEQ);}
7112: }
7113: if (left) {
7114: VecCreate(((PetscObject)mat)->comm,left);
7115: VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);
7116: VecSetBlockSize(*left,mat->rmap->bs);
7117: if (size > 1) {
7118: /* New vectors uses Mat rmap and does not create a new one */
7119: PetscMapDestroy((*left)->map);
7120: (*left)->map = mat->rmap;
7121: mat->rmap->refcnt++;
7123: VecSetType(*left,VECMPI);
7124: } else {VecSetType(*left,VECSEQ);}
7125: }
7126: }
7127: if (mat->mapping) {
7128: if (right) {VecSetLocalToGlobalMapping(*right,mat->mapping);}
7129: if (left) {VecSetLocalToGlobalMapping(*left,mat->mapping);}
7130: }
7131: if (mat->bmapping) {
7132: if (right) {VecSetLocalToGlobalMappingBlock(*right,mat->bmapping);}
7133: if (left) {VecSetLocalToGlobalMappingBlock(*left,mat->bmapping);}
7134: }
7135: return(0);
7136: }
7140: /*@C
7141: MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
7142: with default values.
7144: Not Collective
7146: Input Parameters:
7147: . info - the MatFactorInfo data structure
7150: Notes: The solvers are generally used through the KSP and PC objects, for example
7151: PCLU, PCILU, PCCHOLESKY, PCICC
7153: Level: developer
7155: .seealso: MatFactorInfo
7157: Developer Note: fortran interface is not autogenerated as the f90
7158: interface defintion cannot be generated correctly [due to MatFactorInfo]
7160: @*/
7162: PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
7163: {
7167: PetscMemzero(info,sizeof(MatFactorInfo));
7168: return(0);
7169: }
7173: /*@
7174: MatPtAP - Creates the matrix projection C = P^T * A * P
7176: Collective on Mat
7178: Input Parameters:
7179: + A - the matrix
7180: . P - the projection matrix
7181: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7182: - fill - expected fill as ratio of nnz(C)/nnz(A)
7184: Output Parameters:
7185: . C - the product matrix
7187: Notes:
7188: C will be created and must be destroyed by the user with MatDestroy().
7190: This routine is currently only implemented for pairs of AIJ matrices and classes
7191: which inherit from AIJ.
7193: Level: intermediate
7195: .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult()
7196: @*/
7197: PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
7198: {
7204: if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7205: if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7208: MatPreallocated(P);
7209: if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7210: if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7212: if (P->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
7213: if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
7214: MatPreallocated(A);
7216: PetscLogEventBegin(MAT_PtAP,A,P,0,0);
7217: (*A->ops->ptap)(A,P,scall,fill,C);
7218: PetscLogEventEnd(MAT_PtAP,A,P,0,0);
7220: return(0);
7221: }
7225: /*@
7226: MatPtAPNumeric - Computes the matrix projection C = P^T * A * P
7228: Collective on Mat
7230: Input Parameters:
7231: + A - the matrix
7232: - P - the projection matrix
7234: Output Parameters:
7235: . C - the product matrix
7237: Notes:
7238: C must have been created by calling MatPtAPSymbolic and must be destroyed by
7239: the user using MatDeatroy().
7241: This routine is currently only implemented for pairs of AIJ matrices and classes
7242: which inherit from AIJ. C will be of type MATAIJ.
7244: Level: intermediate
7246: .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
7247: @*/
7248: PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C)
7249: {
7255: if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7256: if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7259: MatPreallocated(P);
7260: if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7261: if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7264: MatPreallocated(C);
7265: if (C->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7266: if (P->cmap->N!=C->rmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->rmap->N);
7267: if (P->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
7268: 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);
7269: if (P->cmap->N!=C->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->cmap->N);
7270: MatPreallocated(A);
7272: PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
7273: (*A->ops->ptapnumeric)(A,P,C);
7274: PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
7275: return(0);
7276: }
7280: /*@
7281: MatPtAPSymbolic - Creates the (i,j) structure of the matrix projection C = P^T * A * P
7283: Collective on Mat
7285: Input Parameters:
7286: + A - the matrix
7287: - P - the projection matrix
7289: Output Parameters:
7290: . C - the (i,j) structure of the product matrix
7292: Notes:
7293: C will be created and must be destroyed by the user with MatDestroy().
7295: This routine is currently only implemented for pairs of SeqAIJ matrices and classes
7296: which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using
7297: this (i,j) structure by calling MatPtAPNumeric().
7299: Level: intermediate
7301: .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
7302: @*/
7303: PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
7304: {
7310: if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7311: if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7312: if (fill <1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
7315: MatPreallocated(P);
7316: if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7317: if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7320: if (P->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
7321: 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);
7322: MatPreallocated(A);
7323: PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);
7324: (*A->ops->ptapsymbolic)(A,P,fill,C);
7325: PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);
7327: MatSetBlockSize(*C,A->rmap->bs);
7329: return(0);
7330: }
7334: /*@
7335: MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
7337: Collective on Mat
7339: Input Parameters:
7340: + A - the left matrix
7341: . B - the right matrix
7342: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7343: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
7344: if the result is a dense matrix this is irrelevent
7346: Output Parameters:
7347: . C - the product matrix
7349: Notes:
7350: Unless scall is MAT_REUSE_MATRIX C will be created.
7352: MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
7353:
7354: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
7355: actually needed.
7357: If you have many matrices with the same non-zero structure to multiply, you
7358: should either
7359: $ 1) use MAT_REUSE_MATRIX in all calls but the first or
7360: $ 2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
7362: Level: intermediate
7364: .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatPtAP()
7365: @*/
7366: PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
7367: {
7369: PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
7370: PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
7371: PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat *)=PETSC_NULL;
7376: if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7377: if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7380: MatPreallocated(B);
7381: if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7382: if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7384: if (B->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
7385: if (scall == MAT_REUSE_MATRIX){
7388: }
7389: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
7390: if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
7391: MatPreallocated(A);
7393: fA = A->ops->matmult;
7394: fB = B->ops->matmult;
7395: if (fB == fA) {
7396: if (!fB) SETERRQ1(PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
7397: mult = fB;
7398: } else {
7399: /* dispatch based on the type of A and B */
7400: char multname[256];
7401: PetscStrcpy(multname,"MatMatMult_");
7402: PetscStrcat(multname,((PetscObject)A)->type_name);
7403: PetscStrcat(multname,"_");
7404: PetscStrcat(multname,((PetscObject)B)->type_name);
7405: PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
7406: PetscObjectQueryFunction((PetscObject)B,multname,(void (**)(void))&mult);
7407: 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);
7408: }
7409: PetscLogEventBegin(MAT_MatMult,A,B,0,0);
7410: (*mult)(A,B,scall,fill,C);
7411: PetscLogEventEnd(MAT_MatMult,A,B,0,0);
7412: return(0);
7413: }
7417: /*@
7418: MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
7419: of the matrix-matrix product C=A*B. Call this routine before calling MatMatMultNumeric().
7421: Collective on Mat
7423: Input Parameters:
7424: + A - the left matrix
7425: . B - the right matrix
7426: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
7427: if C is a dense matrix this is irrelevent
7428:
7429: Output Parameters:
7430: . C - the product matrix
7432: Notes:
7433: Unless scall is MAT_REUSE_MATRIX C will be created.
7435: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
7436: actually needed.
7438: This routine is currently implemented for
7439: - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
7440: - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
7441: - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
7443: Level: intermediate
7445: .seealso: MatMatMult(), MatMatMultNumeric()
7446: @*/
7447: PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
7448: {
7450: PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat *);
7451: PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat *);
7452: PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat *)=PETSC_NULL;
7457: if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7458: if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7462: MatPreallocated(B);
7463: if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7464: if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7467: if (B->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
7468: if (fill == PETSC_DEFAULT) fill = 2.0;
7469: if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
7470: MatPreallocated(A);
7471:
7472: Asymbolic = A->ops->matmultsymbolic;
7473: Bsymbolic = B->ops->matmultsymbolic;
7474: if (Asymbolic == Bsymbolic){
7475: if (!Bsymbolic) SETERRQ1(PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
7476: symbolic = Bsymbolic;
7477: } else { /* dispatch based on the type of A and B */
7478: char symbolicname[256];
7479: PetscStrcpy(symbolicname,"MatMatMultSymbolic_");
7480: PetscStrcat(symbolicname,((PetscObject)A)->type_name);
7481: PetscStrcat(symbolicname,"_");
7482: PetscStrcat(symbolicname,((PetscObject)B)->type_name);
7483: PetscStrcat(symbolicname,"_C");
7484: PetscObjectQueryFunction((PetscObject)B,symbolicname,(void (**)(void))&symbolic);
7485: 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);
7486: }
7487: PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);
7488: (*symbolic)(A,B,fill,C);
7489: PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);
7490: return(0);
7491: }
7495: /*@
7496: MatMatMultNumeric - Performs the numeric matrix-matrix product.
7497: Call this routine after first calling MatMatMultSymbolic().
7499: Collective on Mat
7501: Input Parameters:
7502: + A - the left matrix
7503: - B - the right matrix
7505: Output Parameters:
7506: . C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
7508: Notes:
7509: C must have been created with MatMatMultSymbolic().
7511: This routine is currently implemented for
7512: - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
7513: - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
7514: - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
7516: Level: intermediate
7518: .seealso: MatMatMult(), MatMatMultSymbolic()
7519: @*/
7520: PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C)
7521: {
7523: PetscErrorCode (*Anumeric)(Mat,Mat,Mat);
7524: PetscErrorCode (*Bnumeric)(Mat,Mat,Mat);
7525: PetscErrorCode (*numeric)(Mat,Mat,Mat)=PETSC_NULL;
7530: if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7531: if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7535: MatPreallocated(B);
7536: if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7537: if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7541: MatPreallocated(C);
7542: if (!C->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7543: if (C->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7545: if (B->cmap->N!=C->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->cmap->N,C->cmap->N);
7546: if (B->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
7547: if (A->rmap->N!=C->rmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",A->rmap->N,C->rmap->N);
7548: MatPreallocated(A);
7550: Anumeric = A->ops->matmultnumeric;
7551: Bnumeric = B->ops->matmultnumeric;
7552: if (Anumeric == Bnumeric){
7553: if (!Bnumeric) SETERRQ1(PETSC_ERR_SUP,"MatMatMultNumeric not supported for B of type %s",((PetscObject)B)->type_name);
7554: numeric = Bnumeric;
7555: } else {
7556: char numericname[256];
7557: PetscStrcpy(numericname,"MatMatMultNumeric_");
7558: PetscStrcat(numericname,((PetscObject)A)->type_name);
7559: PetscStrcat(numericname,"_");
7560: PetscStrcat(numericname,((PetscObject)B)->type_name);
7561: PetscStrcat(numericname,"_C");
7562: PetscObjectQueryFunction((PetscObject)B,numericname,(void (**)(void))&numeric);
7563: if (!numeric)
7564: SETERRQ2(PETSC_ERR_ARG_INCOMP,"MatMatMultNumeric requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
7565: }
7566: PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);
7567: (*numeric)(A,B,C);
7568: PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);
7569: return(0);
7570: }
7574: /*@
7575: MatMatMultTranspose - Performs Matrix-Matrix Multiplication C=A^T*B.
7577: Collective on Mat
7579: Input Parameters:
7580: + A - the left matrix
7581: . B - the right matrix
7582: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7583: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
7585: Output Parameters:
7586: . C - the product matrix
7588: Notes:
7589: C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
7591: MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
7593: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
7594: actually needed.
7596: This routine is currently only implemented for pairs of SeqAIJ matrices and pairs of SeqDense matrices and classes
7597: which inherit from SeqAIJ. C will be of type MATSEQAIJ.
7599: Level: intermediate
7601: .seealso: MatMatMultTransposeSymbolic(), MatMatMultTransposeNumeric(), MatPtAP()
7602: @*/
7603: PetscErrorCode MatMatMultTranspose(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
7604: {
7606: PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
7607: PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
7612: if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7613: if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7616: MatPreallocated(B);
7617: if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7618: if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7620: if (B->rmap->N!=A->rmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->rmap->N);
7621: if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
7622: MatPreallocated(A);
7624: fA = A->ops->matmulttranspose;
7625: if (!fA) SETERRQ1(PETSC_ERR_SUP,"MatMatMultTranspose not supported for A of type %s",((PetscObject)A)->type_name);
7626: fB = B->ops->matmulttranspose;
7627: if (!fB) SETERRQ1(PETSC_ERR_SUP,"MatMatMultTranspose not supported for B of type %s",((PetscObject)B)->type_name);
7628: 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);
7630: PetscLogEventBegin(MAT_MatMultTranspose,A,B,0,0);
7631: (*A->ops->matmulttranspose)(A,B,scall,fill,C);
7632: PetscLogEventEnd(MAT_MatMultTranspose,A,B,0,0);
7633:
7634: return(0);
7635: }
7639: /*@C
7640: MatGetRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
7642: Collective on Mat
7644: Input Parameters:
7645: + mat - the matrix
7646: . nsubcomm - the number of subcommunicators (= number of redundant pareallel or sequential matrices)
7647: . subcomm - MPI communicator split from the communicator where mat resides in
7648: . mlocal_red - number of local rows of the redundant matrix
7649: - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7651: Output Parameter:
7652: . matredundant - redundant matrix
7654: Notes:
7655: MAT_REUSE_MATRIX can only be used when the nonzero structure of the
7656: original matrix has not changed from that last call to MatGetRedundantMatrix().
7658: This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
7659: calling it.
7661: Only MPIAIJ matrix is supported.
7662:
7663: Level: advanced
7665: Concepts: subcommunicator
7666: Concepts: duplicate matrix
7668: .seealso: MatDestroy()
7669: @*/
7670: PetscErrorCode MatGetRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,PetscInt mlocal_red,MatReuse reuse,Mat *matredundant)
7671: {
7676: if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
7679: }
7680: if (!mat->ops->getredundantmatrix) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7681: if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7682: if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7683: MatPreallocated(mat);
7685: PetscLogEventBegin(MAT_GetRedundantMatrix,mat,0,0,0);
7686: (*mat->ops->getredundantmatrix)(mat,nsubcomm,subcomm,mlocal_red,reuse,matredundant);
7687: PetscLogEventEnd(MAT_GetRedundantMatrix,mat,0,0,0);
7688: return(0);
7689: }