Actual source code: matrix.c
2: /*
3: This is where the abstract matrix operations are defined
4: */
6: #include <private/matimpl.h> /*I "petscmat.h" I*/
7: #include <private/vecimpl.h>
9: /* Logging support */
10: PetscClassId MAT_CLASSID;
11: PetscClassId MAT_FDCOLORING_CLASSID;
13: PetscLogEvent MAT_Mult, MAT_Mults, MAT_MultConstrained, MAT_MultAdd, MAT_MultTranspose;
14: PetscLogEvent MAT_MultTransposeConstrained, MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve;
15: PetscLogEvent MAT_SolveTransposeAdd, MAT_SOR, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic;
16: PetscLogEvent MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor;
17: PetscLogEvent MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin;
18: PetscLogEvent MAT_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetRowIJ, MAT_GetSubMatrices, MAT_GetColoring, MAT_GetOrdering, MAT_GetRedundantMatrix, MAT_GetSeqNonzeroStructure;
19: PetscLogEvent MAT_IncreaseOverlap, MAT_Partitioning, MAT_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate;
20: PetscLogEvent MAT_FDColoringApply,MAT_Transpose,MAT_FDColoringFunction;
21: PetscLogEvent MAT_MatMult, MAT_MatMultSymbolic, MAT_MatMultNumeric;
22: PetscLogEvent MAT_PtAP, MAT_PtAPSymbolic, MAT_PtAPNumeric;
23: PetscLogEvent MAT_MatMultTranspose, MAT_MatMultTransposeSymbolic, MAT_MatMultTransposeNumeric;
24: PetscLogEvent MAT_MultHermitianTranspose,MAT_MultHermitianTransposeAdd;
25: PetscLogEvent MAT_Getsymtranspose, MAT_Getsymtransreduced, MAT_Transpose_SeqAIJ, MAT_GetBrowsOfAcols;
26: PetscLogEvent MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym;
27: PetscLogEvent MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure;
28: PetscLogEvent MAT_GetMultiProcBlock;
29: PetscLogEvent MAT_CUSPCopyToGPU, MAT_SetValuesBatch, MAT_SetValuesBatchI, MAT_SetValuesBatchII, MAT_SetValuesBatchIII, MAT_SetValuesBatchIV;
31: /* nasty global values for MatSetValue() */
32: PetscInt MatSetValue_Row = 0;
33: PetscInt MatSetValue_Column = 0;
34: PetscScalar MatSetValue_Value = 0.0;
36: const char *const MatFactorTypes[] = {"NONE","LU","CHOLESKY","ILU","ICC","ILUDT","MatFactorType","MAT_FACTOR_",0};
40: /*@C
41: MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix
43: Input Parameter:
44: . A - the matrix
46: Output Parameter:
47: . keptrows - the rows that are not completely zero
49: Level: intermediate
51: @*/
52: PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows)
53: {
54: PetscErrorCode ierr;
58: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
59: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
60: if (!mat->ops->findnonzerorows) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Not coded for this matrix type");
61: (*mat->ops->findnonzerorows)(mat,keptrows);
62: return(0);
63: }
67: /*@
68: MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling
70: Not Collective
72: Input Parameters:
73: . A - the matrix
75: Output Parameters:
76: . a - the diagonal part (which is a SEQUENTIAL matrix)
78: Notes: see the manual page for MatCreateMPIAIJ() for more information on the "diagonal part" of the matrix.
80: Level: advanced
82: @*/
83: PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a)
84: {
85: PetscErrorCode ierr,(*f)(Mat,Mat*);
86: PetscMPIInt size;
92: if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
93: if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
94: MPI_Comm_size(((PetscObject)A)->comm,&size);
95: PetscObjectQueryFunction((PetscObject)A,"MatGetDiagonalBlock_C",(void (**)(void))&f);
96: if (f) {
97: (*f)(A,a);
98: return(0);
99: } else if (size == 1) {
100: *a = A;
101: } else {
102: const MatType mattype;
103: MatGetType(A,&mattype);
104: SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix type %s does not support getting diagonal block",mattype);
105: }
106: return(0);
107: }
111: /*@
112: MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries.
114: Collective on Mat
116: Input Parameters:
117: . mat - the matrix
119: Output Parameter:
120: . trace - the sum of the diagonal entries
122: Level: advanced
124: @*/
125: PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace)
126: {
128: Vec diag;
131: MatGetVecs(mat,&diag,PETSC_NULL);
132: MatGetDiagonal(mat,diag);
133: VecSum(diag,trace);
134: VecDestroy(&diag);
135: return(0);
136: }
140: /*@
141: MatRealPart - Zeros out the imaginary part of the matrix
143: Logically Collective on Mat
145: Input Parameters:
146: . mat - the matrix
148: Level: advanced
151: .seealso: MatImaginaryPart()
152: @*/
153: PetscErrorCode MatRealPart(Mat mat)
154: {
160: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
161: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
162: if (!mat->ops->realpart) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
163: MatPreallocated(mat);
164: (*mat->ops->realpart)(mat);
165: #if defined(PETSC_HAVE_CUSP)
166: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
167: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
168: }
169: #endif
170: return(0);
171: }
175: /*@C
176: MatGetGhosts - Get the global index of all ghost nodes defined by the sparse matrix
178: Collective on Mat
180: Input Parameter:
181: . mat - the matrix
183: Output Parameters:
184: + nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block)
185: - ghosts - the global indices of the ghost points
187: Notes: the nghosts and ghosts are suitable to pass into VecCreateGhost()
189: Level: advanced
191: @*/
192: PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[])
193: {
199: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
200: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
201: if (!mat->ops->getghosts) {
202: if (nghosts) *nghosts = 0;
203: if (ghosts) *ghosts = 0;
204: } else {
205: (*mat->ops->getghosts)(mat,nghosts,ghosts);
206: }
207: return(0);
208: }
213: /*@
214: MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part
216: Logically Collective on Mat
218: Input Parameters:
219: . mat - the matrix
221: Level: advanced
224: .seealso: MatRealPart()
225: @*/
226: PetscErrorCode MatImaginaryPart(Mat mat)
227: {
233: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
234: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
235: if (!mat->ops->imaginarypart) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
236: MatPreallocated(mat);
237: (*mat->ops->imaginarypart)(mat);
238: #if defined(PETSC_HAVE_CUSP)
239: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
240: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
241: }
242: #endif
243: return(0);
244: }
248: /*@
249: MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices)
251: Collective on Mat
253: Input Parameter:
254: . mat - the matrix
256: Output Parameters:
257: + missing - is any diagonal missing
258: - dd - first diagonal entry that is missing (optional)
260: Level: advanced
263: .seealso: MatRealPart()
264: @*/
265: PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd)
266: {
272: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
273: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
274: if (!mat->ops->missingdiagonal) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
275: (*mat->ops->missingdiagonal)(mat,missing,dd);
276: return(0);
277: }
281: /*@C
282: MatGetRow - Gets a row of a matrix. You MUST call MatRestoreRow()
283: for each row that you get to ensure that your application does
284: not bleed memory.
286: Not Collective
288: Input Parameters:
289: + mat - the matrix
290: - row - the row to get
292: Output Parameters:
293: + ncols - if not NULL, the number of nonzeros in the row
294: . cols - if not NULL, the column numbers
295: - vals - if not NULL, the values
297: Notes:
298: This routine is provided for people who need to have direct access
299: to the structure of a matrix. We hope that we provide enough
300: high-level matrix routines that few users will need it.
302: MatGetRow() always returns 0-based column indices, regardless of
303: whether the internal representation is 0-based (default) or 1-based.
305: For better efficiency, set cols and/or vals to PETSC_NULL if you do
306: not wish to extract these quantities.
308: The user can only examine the values extracted with MatGetRow();
309: the values cannot be altered. To change the matrix entries, one
310: must use MatSetValues().
312: You can only have one call to MatGetRow() outstanding for a particular
313: matrix at a time, per processor. MatGetRow() can only obtain rows
314: associated with the given processor, it cannot get rows from the
315: other processors; for that we suggest using MatGetSubMatrices(), then
316: MatGetRow() on the submatrix. The row indix passed to MatGetRows()
317: is in the global number of rows.
319: Fortran Notes:
320: The calling sequence from Fortran is
321: .vb
322: MatGetRow(matrix,row,ncols,cols,values,ierr)
323: Mat matrix (input)
324: integer row (input)
325: integer ncols (output)
326: integer cols(maxcols) (output)
327: double precision (or double complex) values(maxcols) output
328: .ve
329: where maxcols >= maximum nonzeros in any row of the matrix.
332: Caution:
333: Do not try to change the contents of the output arrays (cols and vals).
334: In some cases, this may corrupt the matrix.
336: Level: advanced
338: Concepts: matrices^row access
340: .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatGetSubMatrices(), MatGetDiagonal()
341: @*/
342: PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
343: {
345: PetscInt incols;
350: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
351: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
352: if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
353: MatPreallocated(mat);
354: PetscLogEventBegin(MAT_GetRow,mat,0,0,0);
355: (*mat->ops->getrow)(mat,row,&incols,(PetscInt **)cols,(PetscScalar **)vals);
356: if (ncols) *ncols = incols;
357: PetscLogEventEnd(MAT_GetRow,mat,0,0,0);
358: return(0);
359: }
363: /*@
364: MatConjugate - replaces the matrix values with their complex conjugates
366: Logically Collective on Mat
368: Input Parameters:
369: . mat - the matrix
371: Level: advanced
373: .seealso: VecConjugate()
374: @*/
375: PetscErrorCode MatConjugate(Mat mat)
376: {
381: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
382: if (!mat->ops->conjugate) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Not provided for this matrix format, send email to petsc-maint@mcs.anl.gov");
383: (*mat->ops->conjugate)(mat);
384: #if defined(PETSC_HAVE_CUSP)
385: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
386: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
387: }
388: #endif
389: return(0);
390: }
394: /*@C
395: MatRestoreRow - Frees any temporary space allocated by MatGetRow().
397: Not Collective
399: Input Parameters:
400: + mat - the matrix
401: . row - the row to get
402: . ncols, cols - the number of nonzeros and their columns
403: - vals - if nonzero the column values
405: Notes:
406: This routine should be called after you have finished examining the entries.
408: Fortran Notes:
409: The calling sequence from Fortran is
410: .vb
411: MatRestoreRow(matrix,row,ncols,cols,values,ierr)
412: Mat matrix (input)
413: integer row (input)
414: integer ncols (output)
415: integer cols(maxcols) (output)
416: double precision (or double complex) values(maxcols) output
417: .ve
418: Where maxcols >= maximum nonzeros in any row of the matrix.
420: In Fortran MatRestoreRow() MUST be called after MatGetRow()
421: before another call to MatGetRow() can be made.
423: Level: advanced
425: .seealso: MatGetRow()
426: @*/
427: PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
428: {
434: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
435: if (!mat->ops->restorerow) return(0);
436: (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);
437: return(0);
438: }
442: /*@
443: MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format.
444: You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag.
446: Not Collective
448: Input Parameters:
449: + mat - the matrix
451: Notes:
452: The flag is to ensure that users are aware of MatGetRow() only provides the upper trianglular part of the row for the matrices in MATSBAIJ format.
454: Level: advanced
456: Concepts: matrices^row access
458: .seealso: MatRestoreRowRowUpperTriangular()
459: @*/
460: PetscErrorCode MatGetRowUpperTriangular(Mat mat)
461: {
467: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
468: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
469: if (!mat->ops->getrowuppertriangular) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
470: MatPreallocated(mat);
471: (*mat->ops->getrowuppertriangular)(mat);
472: return(0);
473: }
477: /*@
478: MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format.
480: Not Collective
482: Input Parameters:
483: + mat - the matrix
485: Notes:
486: This routine should be called after you have finished MatGetRow/MatRestoreRow().
489: Level: advanced
491: .seealso: MatGetRowUpperTriangular()
492: @*/
493: PetscErrorCode MatRestoreRowUpperTriangular(Mat mat)
494: {
499: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
500: if (!mat->ops->restorerowuppertriangular) return(0);
501: (*mat->ops->restorerowuppertriangular)(mat);
502: return(0);
503: }
507: /*@C
508: MatSetOptionsPrefix - Sets the prefix used for searching for all
509: Mat options in the database.
511: Logically Collective on Mat
513: Input Parameter:
514: + A - the Mat context
515: - prefix - the prefix to prepend to all option names
517: Notes:
518: A hyphen (-) must NOT be given at the beginning of the prefix name.
519: The first character of all runtime options is AUTOMATICALLY the hyphen.
521: Level: advanced
523: .keywords: Mat, set, options, prefix, database
525: .seealso: MatSetFromOptions()
526: @*/
527: PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[])
528: {
533: PetscObjectSetOptionsPrefix((PetscObject)A,prefix);
534: return(0);
535: }
539: /*@C
540: MatAppendOptionsPrefix - Appends to the prefix used for searching for all
541: Mat options in the database.
543: Logically Collective on Mat
545: Input Parameters:
546: + A - the Mat context
547: - prefix - the prefix to prepend to all option names
549: Notes:
550: A hyphen (-) must NOT be given at the beginning of the prefix name.
551: The first character of all runtime options is AUTOMATICALLY the hyphen.
553: Level: advanced
555: .keywords: Mat, append, options, prefix, database
557: .seealso: MatGetOptionsPrefix()
558: @*/
559: PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[])
560: {
562:
565: PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);
566: return(0);
567: }
571: /*@C
572: MatGetOptionsPrefix - Sets the prefix used for searching for all
573: Mat options in the database.
575: Not Collective
577: Input Parameter:
578: . A - the Mat context
580: Output Parameter:
581: . prefix - pointer to the prefix string used
583: Notes: On the fortran side, the user should pass in a string 'prefix' of
584: sufficient length to hold the prefix.
586: Level: advanced
588: .keywords: Mat, get, options, prefix, database
590: .seealso: MatAppendOptionsPrefix()
591: @*/
592: PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[])
593: {
598: PetscObjectGetOptionsPrefix((PetscObject)A,prefix);
599: return(0);
600: }
604: /*@
605: MatSetUp - Sets up the internal matrix data structures for the later use.
607: Collective on Mat
609: Input Parameters:
610: . A - the Mat context
612: Notes:
613: For basic use of the Mat classes the user need not explicitly call
614: MatSetUp(), since these actions will happen automatically.
616: Level: advanced
618: .keywords: Mat, setup
620: .seealso: MatCreate(), MatDestroy()
621: @*/
622: PetscErrorCode MatSetUp(Mat A)
623: {
624: PetscMPIInt size;
629: if (!((PetscObject)A)->type_name) {
630: MPI_Comm_size(((PetscObject)A)->comm, &size);
631: if (size == 1) {
632: MatSetType(A, MATSEQAIJ);
633: } else {
634: MatSetType(A, MATMPIAIJ);
635: }
636: }
637: MatSetUpPreallocation(A);
638: return(0);
639: }
644: /*@C
645: MatView - Visualizes a matrix object.
647: Collective on Mat
649: Input Parameters:
650: + mat - the matrix
651: - viewer - visualization context
653: Notes:
654: The available visualization contexts include
655: + PETSC_VIEWER_STDOUT_SELF - standard output (default)
656: . PETSC_VIEWER_STDOUT_WORLD - synchronized standard
657: output where only the first processor opens
658: the file. All other processors send their
659: data to the first processor to print.
660: - PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure
662: The user can open alternative visualization contexts with
663: + PetscViewerASCIIOpen() - Outputs matrix to a specified file
664: . PetscViewerBinaryOpen() - Outputs matrix in binary to a
665: specified file; corresponding input uses MatLoad()
666: . PetscViewerDrawOpen() - Outputs nonzero matrix structure to
667: an X window display
668: - PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
669: Currently only the sequential dense and AIJ
670: matrix types support the Socket viewer.
672: The user can call PetscViewerSetFormat() to specify the output
673: format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
674: PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen). Available formats include
675: + PETSC_VIEWER_DEFAULT - default, prints matrix contents
676: . PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
677: . PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
678: . PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse
679: format common among all matrix types
680: . PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific
681: format (which is in many cases the same as the default)
682: . PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
683: size and structure (not the matrix entries)
684: . PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about
685: the matrix structure
687: Options Database Keys:
688: + -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly()
689: . -mat_view_info_detailed - Prints more detailed info
690: . -mat_view - Prints matrix in ASCII format
691: . -mat_view_matlab - Prints matrix in Matlab format
692: . -mat_view_draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
693: . -display <name> - Sets display name (default is host)
694: . -draw_pause <sec> - Sets number of seconds to pause after display
695: . -mat_view_socket - Sends matrix to socket, can be accessed from Matlab (see the <a href="../../docs/manual.pdf">users manual</a> for details).
696: . -viewer_socket_machine <machine>
697: . -viewer_socket_port <port>
698: . -mat_view_binary - save matrix to file in binary format
699: - -viewer_binary_filename <name>
700: Level: beginner
702: Notes: see the manual page for MatLoad() for the exact format of the binary file when the binary
703: viewer is used.
705: See bin/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary
706: viewer is used.
708: Concepts: matrices^viewing
709: Concepts: matrices^plotting
710: Concepts: matrices^printing
712: .seealso: PetscViewerSetFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(),
713: PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
714: @*/
715: PetscErrorCode MatView(Mat mat,PetscViewer viewer)
716: {
717: PetscErrorCode ierr;
718: PetscInt rows,cols;
719: PetscBool iascii;
720: PetscViewerFormat format;
725: if (!viewer) {
726: PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
727: }
730: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
731: MatPreallocated(mat);
733: PetscLogEventBegin(MAT_View,mat,viewer,0,0);
734: PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
735: if (iascii) {
736: PetscViewerGetFormat(viewer,&format);
737: if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
738: PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer,"Matrix Object");
739: PetscViewerASCIIPushTab(viewer);
740: MatGetSize(mat,&rows,&cols);
741: PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);
742: if (mat->factortype) {
743: const MatSolverPackage solver;
744: MatFactorGetSolverPackage(mat,&solver);
745: PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);
746: }
747: if (mat->ops->getinfo) {
748: MatInfo info;
749: MatGetInfo(mat,MAT_GLOBAL_SUM,&info);
750: PetscViewerASCIIPrintf(viewer,"total: nonzeros=%D, allocated nonzeros=%D\n",(PetscInt)info.nz_used,(PetscInt)info.nz_allocated);
751: PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls =%D\n",(PetscInt)info.mallocs);
752: }
753: }
754: }
755: if (mat->ops->view) {
756: PetscViewerASCIIPushTab(viewer);
757: (*mat->ops->view)(mat,viewer);
758: PetscViewerASCIIPopTab(viewer);
759: } else if (!iascii) {
760: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Viewer type %s not supported",((PetscObject)viewer)->type_name);
761: }
762: if (iascii) {
763: PetscViewerGetFormat(viewer,&format);
764: if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
765: PetscViewerASCIIPopTab(viewer);
766: }
767: }
768: PetscLogEventEnd(MAT_View,mat,viewer,0,0);
769: return(0);
770: }
772: #if defined(PETSC_USE_DEBUG)
773: #include <../src/sys/totalview/tv_data_display.h>
774: PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat)
775: {
776: TV_add_row("Local rows", "int", &mat->rmap->n);
777: TV_add_row("Local columns", "int", &mat->cmap->n);
778: TV_add_row("Global rows", "int", &mat->rmap->N);
779: TV_add_row("Global columns", "int", &mat->cmap->N);
780: TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name);
781: return TV_format_OK;
782: }
783: #endif
787: /*@C
788: MatLoad - Loads a matrix that has been stored in binary format
789: with MatView(). The matrix format is determined from the options database.
790: Generates a parallel MPI matrix if the communicator has more than one
791: processor. The default matrix type is AIJ.
793: Collective on PetscViewer
795: Input Parameters:
796: + newmat - the newly loaded matrix, this needs to have been created with MatCreate()
797: or some related function before a call to MatLoad()
798: - viewer - binary file viewer, created with PetscViewerBinaryOpen()
800: Options Database Keys:
801: Used with block matrix formats (MATSEQBAIJ, ...) to specify
802: block size
803: . -matload_block_size <bs>
805: Level: beginner
807: Notes:
808: If the Mat type has not yet been given then MATAIJ is used, call MatSetFromOptions() on the
809: Mat before calling this routine if you wish to set it from the options database.
811: MatLoad() automatically loads into the options database any options
812: given in the file filename.info where filename is the name of the file
813: that was passed to the PetscViewerBinaryOpen(). The options in the info
814: file will be ignored if you use the -viewer_binary_skip_info option.
816: If the type or size of newmat is not set before a call to MatLoad, PETSc
817: sets the default matrix type AIJ and sets the local and global sizes.
818: If type and/or size is already set, then the same are used.
820: In parallel, each processor can load a subset of rows (or the
821: entire matrix). This routine is especially useful when a large
822: matrix is stored on disk and only part of it is desired on each
823: processor. For example, a parallel solver may access only some of
824: the rows from each processor. The algorithm used here reads
825: relatively small blocks of data rather than reading the entire
826: matrix and then subsetting it.
828: Notes for advanced users:
829: Most users should not need to know the details of the binary storage
830: format, since MatLoad() and MatView() completely hide these details.
831: But for anyone who's interested, the standard binary matrix storage
832: format is
834: $ int MAT_FILE_CLASSID
835: $ int number of rows
836: $ int number of columns
837: $ int total number of nonzeros
838: $ int *number nonzeros in each row
839: $ int *column indices of all nonzeros (starting index is zero)
840: $ PetscScalar *values of all nonzeros
842: PETSc automatically does the byte swapping for
843: machines that store the bytes reversed, e.g. DEC alpha, freebsd,
844: linux, Windows and the paragon; thus if you write your own binary
845: read/write routines you have to swap the bytes; see PetscBinaryRead()
846: and PetscBinaryWrite() to see how this may be done.
848: .keywords: matrix, load, binary, input
850: .seealso: PetscViewerBinaryOpen(), MatView(), VecLoad()
852: @*/
853: PetscErrorCode MatLoad(Mat newmat,PetscViewer viewer)
854: {
856: PetscBool isbinary,flg;
861: PetscTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);
862: if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()");
864: if (!((PetscObject)newmat)->type_name) {
865: MatSetType(newmat,MATAIJ);
866: }
868: if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type");
869: PetscLogEventBegin(MAT_Load,viewer,0,0,0);
870: (*newmat->ops->load)(newmat,viewer);
871: PetscLogEventEnd(MAT_Load,viewer,0,0,0);
873: flg = PETSC_FALSE;
874: PetscOptionsGetBool(((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,PETSC_NULL);
875: if (flg) {
876: MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);
877: MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);
878: }
879: flg = PETSC_FALSE;
880: PetscOptionsGetBool(((PetscObject)newmat)->prefix,"-matload_spd",&flg,PETSC_NULL);
881: if (flg) {
882: MatSetOption(newmat,MAT_SPD,PETSC_TRUE);
883: }
884: return(0);
885: }
889: /*@
890: MatScaleSystem - Scale a vector solution and right hand side to
891: match the scaling of a scaled matrix.
892:
893: Collective on Mat
895: Input Parameter:
896: + mat - the matrix
897: . b - right hand side vector (or PETSC_NULL)
898: - x - solution vector (or PETSC_NULL)
901: Notes:
902: For AIJ, and BAIJ matrix formats, the matrices are not
903: internally scaled, so this does nothing.
905: The KSP methods automatically call this routine when required
906: (via PCPreSolve()) so it is rarely used directly.
908: Level: Developer
910: Concepts: matrices^scaling
912: .seealso: MatUseScaledForm(), MatUnScaleSystem()
913: @*/
914: PetscErrorCode MatScaleSystem(Mat mat,Vec b,Vec x)
915: {
921: MatPreallocated(mat);
925: if (mat->ops->scalesystem) {
926: (*mat->ops->scalesystem)(mat,b,x);
927: }
928: return(0);
929: }
933: /*@
934: MatUnScaleSystem - Unscales a vector solution and right hand side to
935: match the original scaling of a scaled matrix.
936:
937: Collective on Mat
939: Input Parameter:
940: + mat - the matrix
941: . b - right hand side vector (or PETSC_NULL)
942: - x - solution vector (or PETSC_NULL)
945: Notes:
946: For AIJ and BAIJ matrix formats, the matrices are not
947: internally scaled, so this does nothing.
949: The KSP methods automatically call this routine when required
950: (via PCPreSolve()) so it is rarely used directly.
952: Level: Developer
954: .seealso: MatUseScaledForm(), MatScaleSystem()
955: @*/
956: PetscErrorCode MatUnScaleSystem(Mat mat,Vec b,Vec x)
957: {
963: MatPreallocated(mat);
966: if (mat->ops->unscalesystem) {
967: (*mat->ops->unscalesystem)(mat,b,x);
968: }
969: return(0);
970: }
974: /*@
975: MatUseScaledForm - For matrix storage formats that scale the
976: matrix indicates matrix operations (MatMult() etc) are
977: applied using the scaled matrix.
978:
979: Logically Collective on Mat
981: Input Parameter:
982: + mat - the matrix
983: - scaled - PETSC_TRUE for applying the scaled, PETSC_FALSE for
984: applying the original matrix
986: Notes:
987: For scaled matrix formats, applying the original, unscaled matrix
988: will be slightly more expensive
990: Level: Developer
992: .seealso: MatScaleSystem(), MatUnScaleSystem()
993: @*/
994: PetscErrorCode MatUseScaledForm(Mat mat,PetscBool scaled)
995: {
1002: MatPreallocated(mat);
1003: if (mat->ops->usescaledform) {
1004: (*mat->ops->usescaledform)(mat,scaled);
1005: }
1006: return(0);
1007: }
1011: /*@
1012: MatDestroy - Frees space taken by a matrix.
1014: Collective on Mat
1016: Input Parameter:
1017: . A - the matrix
1019: Level: beginner
1021: @*/
1022: PetscErrorCode MatDestroy(Mat *A)
1023: {
1027: if (!*A) return(0);
1029: if (--((PetscObject)(*A))->refct > 0) {*A = PETSC_NULL; return(0);}
1031: /* if memory was published with AMS then destroy it */
1032: PetscObjectDepublish(*A);
1034: if ((*A)->ops->destroy) {
1035: (*(*A)->ops->destroy)(*A);
1036: }
1038: MatNullSpaceDestroy(&(*A)->nullsp);
1039: PetscLayoutDestroy(&(*A)->rmap);
1040: PetscLayoutDestroy(&(*A)->cmap);
1041: PetscHeaderDestroy(A);
1042: return(0);
1043: }
1047: /*@
1048: MatSetValues - Inserts or adds a block of values into a matrix.
1049: These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1050: MUST be called after all calls to MatSetValues() have been completed.
1052: Not Collective
1054: Input Parameters:
1055: + mat - the matrix
1056: . v - a logically two-dimensional array of values
1057: . m, idxm - the number of rows and their global indices
1058: . n, idxn - the number of columns and their global indices
1059: - addv - either ADD_VALUES or INSERT_VALUES, where
1060: ADD_VALUES adds values to any existing entries, and
1061: INSERT_VALUES replaces existing entries with new values
1063: Notes:
1064: By default the values, v, are row-oriented. See MatSetOption() for other options.
1066: Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
1067: options cannot be mixed without intervening calls to the assembly
1068: routines.
1070: MatSetValues() uses 0-based row and column numbers in Fortran
1071: as well as in C.
1073: Negative indices may be passed in idxm and idxn, these rows and columns are
1074: simply ignored. This allows easily inserting element stiffness matrices
1075: with homogeneous Dirchlet boundary conditions that you don't want represented
1076: in the matrix.
1078: Efficiency Alert:
1079: The routine MatSetValuesBlocked() may offer much better efficiency
1080: for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1082: Level: beginner
1084: Concepts: matrices^putting entries in
1086: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1087: InsertMode, INSERT_VALUES, ADD_VALUES
1088: @*/
1089: PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1090: {
1096: if (!m || !n) return(0); /* no values to insert */
1100: MatPreallocated(mat);
1101: if (mat->insertmode == NOT_SET_VALUES) {
1102: mat->insertmode = addv;
1103: }
1104: #if defined(PETSC_USE_DEBUG)
1105: else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1106: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1107: if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1108: #endif
1110: if (mat->assembled) {
1111: mat->was_assembled = PETSC_TRUE;
1112: mat->assembled = PETSC_FALSE;
1113: }
1114: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1115: (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);
1116: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1117: #if defined(PETSC_HAVE_CUSP)
1118: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1119: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1120: }
1121: #endif
1122: return(0);
1123: }
1128: /*@
1129: MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
1130: values into a matrix
1132: Not Collective
1134: Input Parameters:
1135: + mat - the matrix
1136: . row - the (block) row to set
1137: - v - a logically two-dimensional array of values
1139: Notes:
1140: By the values, v, are column-oriented (for the block version) and sorted
1142: All the nonzeros in the row must be provided
1144: The matrix must have previously had its column indices set
1146: The row must belong to this process
1148: Level: intermediate
1150: Concepts: matrices^putting entries in
1152: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1153: InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping()
1154: @*/
1155: PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
1156: {
1163: MatSetValuesRow(mat, mat->rmap->mapping->indices[row],v);
1164: #if defined(PETSC_HAVE_CUSP)
1165: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1166: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1167: }
1168: #endif
1169: return(0);
1170: }
1174: /*@
1175: MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
1176: values into a matrix
1178: Not Collective
1180: Input Parameters:
1181: + mat - the matrix
1182: . row - the (block) row to set
1183: - v - a logically two-dimensional array of values
1185: Notes:
1186: The values, v, are column-oriented for the block version.
1188: All the nonzeros in the row must be provided
1190: THE MATRIX MUSAT HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually MatSetValues() is used.
1192: The row must belong to this process
1194: Level: advanced
1196: Concepts: matrices^putting entries in
1198: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1199: InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1200: @*/
1201: PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
1202: {
1209: #if defined(PETSC_USE_DEBUG)
1210: if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
1211: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1212: #endif
1213: mat->insertmode = INSERT_VALUES;
1215: if (mat->assembled) {
1216: mat->was_assembled = PETSC_TRUE;
1217: mat->assembled = PETSC_FALSE;
1218: }
1219: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1220: if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1221: (*mat->ops->setvaluesrow)(mat,row,v);
1222: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1223: #if defined(PETSC_HAVE_CUSP)
1224: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1225: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1226: }
1227: #endif
1228: return(0);
1229: }
1233: /*@
1234: MatSetValuesStencil - Inserts or adds a block of values into a matrix.
1235: Using structured grid indexing
1237: Not Collective
1239: Input Parameters:
1240: + mat - the matrix
1241: . m - number of rows being entered
1242: . idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
1243: . n - number of columns being entered
1244: . idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered
1245: . v - a logically two-dimensional array of values
1246: - addv - either ADD_VALUES or INSERT_VALUES, where
1247: ADD_VALUES adds values to any existing entries, and
1248: INSERT_VALUES replaces existing entries with new values
1250: Notes:
1251: By default the values, v, are row-oriented. See MatSetOption() for other options.
1253: Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
1254: options cannot be mixed without intervening calls to the assembly
1255: routines.
1257: The grid coordinates are across the entire grid, not just the local portion
1259: MatSetValuesStencil() uses 0-based row and column numbers in Fortran
1260: as well as in C.
1262: For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1264: In order to use this routine you must either obtain the matrix with DMGetMatrix()
1265: or call MatSetLocalToGlobalMapping() and MatSetStencil() first.
1267: The columns and rows in the stencil passed in MUST be contained within the
1268: ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1269: if you create a DMDA with an overlap of one grid level and on a particular process its first
1270: local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1271: first i index you can use in your column and row indices in MatSetStencil() is 5.
1273: In Fortran idxm and idxn should be declared as
1274: $ MatStencil idxm(4,m),idxn(4,n)
1275: and the values inserted using
1276: $ idxm(MatStencil_i,1) = i
1277: $ idxm(MatStencil_j,1) = j
1278: $ idxm(MatStencil_k,1) = k
1279: $ idxm(MatStencil_c,1) = c
1280: etc
1281:
1282: For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
1283: obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
1284: etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
1285: DMDA_BOUNDARY_PERIODIC boundary type.
1287: For indices that don't mean anything for your case (like the k index when working in 2d) or the c index when you have
1288: a single value per point) you can skip filling those indices.
1290: Inspired by the structured grid interface to the HYPRE package
1291: (http://www.llnl.gov/CASC/hypre)
1293: Efficiency Alert:
1294: The routine MatSetValuesBlockedStencil() may offer much better efficiency
1295: for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1297: Level: beginner
1299: Concepts: matrices^putting entries in
1301: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1302: MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMGetMatrix(), DMDAVecGetArray(), MatStencil
1303: @*/
1304: PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1305: {
1307: PetscInt buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1308: PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1309: PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1312: if (!m || !n) return(0); /* no values to insert */
1319: if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1320: jdxm = buf; jdxn = buf+m;
1321: } else {
1322: PetscMalloc2(m,PetscInt,&bufm,n,PetscInt,&bufn);
1323: jdxm = bufm; jdxn = bufn;
1324: }
1325: for (i=0; i<m; i++) {
1326: for (j=0; j<3-sdim; j++) dxm++;
1327: tmp = *dxm++ - starts[0];
1328: for (j=0; j<dim-1; j++) {
1329: if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1330: else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1331: }
1332: if (mat->stencil.noc) dxm++;
1333: jdxm[i] = tmp;
1334: }
1335: for (i=0; i<n; i++) {
1336: for (j=0; j<3-sdim; j++) dxn++;
1337: tmp = *dxn++ - starts[0];
1338: for (j=0; j<dim-1; j++) {
1339: if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1340: else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1341: }
1342: if (mat->stencil.noc) dxn++;
1343: jdxn[i] = tmp;
1344: }
1345: MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);
1346: PetscFree2(bufm,bufn);
1347: return(0);
1348: }
1352: /*@C
1353: MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1354: Using structured grid indexing
1356: Not Collective
1358: Input Parameters:
1359: + mat - the matrix
1360: . m - number of rows being entered
1361: . idxm - grid coordinates for matrix rows being entered
1362: . n - number of columns being entered
1363: . idxn - grid coordinates for matrix columns being entered
1364: . v - a logically two-dimensional array of values
1365: - addv - either ADD_VALUES or INSERT_VALUES, where
1366: ADD_VALUES adds values to any existing entries, and
1367: INSERT_VALUES replaces existing entries with new values
1369: Notes:
1370: By default the values, v, are row-oriented and unsorted.
1371: See MatSetOption() for other options.
1373: Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
1374: options cannot be mixed without intervening calls to the assembly
1375: routines.
1377: The grid coordinates are across the entire grid, not just the local portion
1379: MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran
1380: as well as in C.
1382: For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1384: In order to use this routine you must either obtain the matrix with DMGetMatrix()
1385: or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first.
1387: The columns and rows in the stencil passed in MUST be contained within the
1388: ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1389: if you create a DMDA with an overlap of one grid level and on a particular process its first
1390: local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1391: first i index you can use in your column and row indices in MatSetStencil() is 5.
1393: In Fortran idxm and idxn should be declared as
1394: $ MatStencil idxm(4,m),idxn(4,n)
1395: and the values inserted using
1396: $ idxm(MatStencil_i,1) = i
1397: $ idxm(MatStencil_j,1) = j
1398: $ idxm(MatStencil_k,1) = k
1399: etc
1401: Negative indices may be passed in idxm and idxn, these rows and columns are
1402: simply ignored. This allows easily inserting element stiffness matrices
1403: with homogeneous Dirchlet boundary conditions that you don't want represented
1404: in the matrix.
1406: Inspired by the structured grid interface to the HYPRE package
1407: (http://www.llnl.gov/CASC/hypre)
1409: Level: beginner
1411: Concepts: matrices^putting entries in
1413: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1414: MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMGetMatrix(), DMDAVecGetArray(), MatStencil,
1415: MatSetBlockSize(), MatSetLocalToGlobalMapping()
1416: @*/
1417: PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1418: {
1420: PetscInt buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1421: PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1422: PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1425: if (!m || !n) return(0); /* no values to insert */
1432: if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1433: jdxm = buf; jdxn = buf+m;
1434: } else {
1435: PetscMalloc2(m,PetscInt,&bufm,n,PetscInt,&bufn);
1436: jdxm = bufm; jdxn = bufn;
1437: }
1438: for (i=0; i<m; i++) {
1439: for (j=0; j<3-sdim; j++) dxm++;
1440: tmp = *dxm++ - starts[0];
1441: for (j=0; j<sdim-1; j++) {
1442: if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1443: else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1444: }
1445: dxm++;
1446: jdxm[i] = tmp;
1447: }
1448: for (i=0; i<n; i++) {
1449: for (j=0; j<3-sdim; j++) dxn++;
1450: tmp = *dxn++ - starts[0];
1451: for (j=0; j<sdim-1; j++) {
1452: if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1453: else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1454: }
1455: dxn++;
1456: jdxn[i] = tmp;
1457: }
1458: MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);
1459: PetscFree2(bufm,bufn);
1460: #if defined(PETSC_HAVE_CUSP)
1461: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1462: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1463: }
1464: #endif
1465: return(0);
1466: }
1470: /*@
1471: MatSetStencil - Sets the grid information for setting values into a matrix via
1472: MatSetValuesStencil()
1474: Not Collective
1476: Input Parameters:
1477: + mat - the matrix
1478: . dim - dimension of the grid 1, 2, or 3
1479: . dims - number of grid points in x, y, and z direction, including ghost points on your processor
1480: . starts - starting point of ghost nodes on your processor in x, y, and z direction
1481: - dof - number of degrees of freedom per node
1484: Inspired by the structured grid interface to the HYPRE package
1485: (www.llnl.gov/CASC/hyper)
1487: For matrices generated with DMGetMatrix() this routine is automatically called and so not needed by the
1488: user.
1489:
1490: Level: beginner
1492: Concepts: matrices^putting entries in
1494: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1495: MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
1496: @*/
1497: PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1498: {
1499: PetscInt i;
1506: mat->stencil.dim = dim + (dof > 1);
1507: for (i=0; i<dim; i++) {
1508: mat->stencil.dims[i] = dims[dim-i-1]; /* copy the values in backwards */
1509: mat->stencil.starts[i] = starts[dim-i-1];
1510: }
1511: mat->stencil.dims[dim] = dof;
1512: mat->stencil.starts[dim] = 0;
1513: mat->stencil.noc = (PetscBool)(dof == 1);
1514: return(0);
1515: }
1519: /*@
1520: MatSetValuesBlocked - Inserts or adds a block of values into a matrix.
1522: Not Collective
1524: Input Parameters:
1525: + mat - the matrix
1526: . v - a logically two-dimensional array of values
1527: . m, idxm - the number of block rows and their global block indices
1528: . n, idxn - the number of block columns and their global block indices
1529: - addv - either ADD_VALUES or INSERT_VALUES, where
1530: ADD_VALUES adds values to any existing entries, and
1531: INSERT_VALUES replaces existing entries with new values
1533: Notes:
1534: The m and n count the NUMBER of blocks in the row direction and column direction,
1535: NOT the total number of rows/columns; for example, if the block size is 2 and
1536: you are passing in values for rows 2,3,4,5 then m would be 2 (not 4).
1537: The values in idxm would be 1 2; that is the first index for each block divided by
1538: the block size.
1540: Note that you must call MatSetBlockSize() when constructing this matrix (after
1541: preallocating it).
1543: By default the values, v, are row-oriented, so the layout of
1544: v is the same as for MatSetValues(). See MatSetOption() for other options.
1546: Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
1547: options cannot be mixed without intervening calls to the assembly
1548: routines.
1550: MatSetValuesBlocked() uses 0-based row and column numbers in Fortran
1551: as well as in C.
1553: Negative indices may be passed in idxm and idxn, these rows and columns are
1554: simply ignored. This allows easily inserting element stiffness matrices
1555: with homogeneous Dirchlet boundary conditions that you don't want represented
1556: in the matrix.
1558: Each time an entry is set within a sparse matrix via MatSetValues(),
1559: internal searching must be done to determine where to place the the
1560: data in the matrix storage space. By instead inserting blocks of
1561: entries via MatSetValuesBlocked(), the overhead of matrix assembly is
1562: reduced.
1564: Example:
1565: $ Suppose m=n=2 and block size(bs) = 2 The array is
1566: $
1567: $ 1 2 | 3 4
1568: $ 5 6 | 7 8
1569: $ - - - | - - -
1570: $ 9 10 | 11 12
1571: $ 13 14 | 15 16
1572: $
1573: $ v[] should be passed in like
1574: $ v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
1575: $
1576: $ If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then
1577: $ v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16]
1579: Level: intermediate
1581: Concepts: matrices^putting entries in blocked
1583: .seealso: MatSetBlockSize(), MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal()
1584: @*/
1585: PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1586: {
1592: if (!m || !n) return(0); /* no values to insert */
1596: MatPreallocated(mat);
1597: if (mat->insertmode == NOT_SET_VALUES) {
1598: mat->insertmode = addv;
1599: }
1600: #if defined(PETSC_USE_DEBUG)
1601: else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1602: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1603: if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1604: #endif
1606: if (mat->assembled) {
1607: mat->was_assembled = PETSC_TRUE;
1608: mat->assembled = PETSC_FALSE;
1609: }
1610: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1611: if (mat->ops->setvaluesblocked) {
1612: (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);
1613: } else {
1614: PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn;
1615: PetscInt i,j,bs=mat->rmap->bs;
1616: if ((m+n)*bs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1617: iidxm = buf; iidxn = buf + m*bs;
1618: } else {
1619: PetscMalloc2(m*bs,PetscInt,&bufr,n*bs,PetscInt,&bufc);
1620: iidxm = bufr; iidxn = bufc;
1621: }
1622: for (i=0; i<m; i++)
1623: for (j=0; j<bs; j++)
1624: iidxm[i*bs+j] = bs*idxm[i] + j;
1625: for (i=0; i<n; i++)
1626: for (j=0; j<bs; j++)
1627: iidxn[i*bs+j] = bs*idxn[i] + j;
1628: MatSetValues(mat,m*bs,iidxm,n*bs,iidxn,v,addv);
1629: PetscFree2(bufr,bufc);
1630: }
1631: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1632: #if defined(PETSC_HAVE_CUSP)
1633: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1634: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1635: }
1636: #endif
1637: return(0);
1638: }
1642: /*@
1643: MatGetValues - Gets a block of values from a matrix.
1645: Not Collective; currently only returns a local block
1647: Input Parameters:
1648: + mat - the matrix
1649: . v - a logically two-dimensional array for storing the values
1650: . m, idxm - the number of rows and their global indices
1651: - n, idxn - the number of columns and their global indices
1653: Notes:
1654: The user must allocate space (m*n PetscScalars) for the values, v.
1655: The values, v, are then returned in a row-oriented format,
1656: analogous to that used by default in MatSetValues().
1658: MatGetValues() uses 0-based row and column numbers in
1659: Fortran as well as in C.
1661: MatGetValues() requires that the matrix has been assembled
1662: with MatAssemblyBegin()/MatAssemblyEnd(). Thus, calls to
1663: MatSetValues() and MatGetValues() CANNOT be made in succession
1664: without intermediate matrix assembly.
1666: Negative row or column indices will be ignored and those locations in v[] will be
1667: left unchanged.
1669: Level: advanced
1671: Concepts: matrices^accessing values
1673: .seealso: MatGetRow(), MatGetSubMatrices(), MatSetValues()
1674: @*/
1675: PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1676: {
1682: if (!m || !n) return(0);
1686: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1687: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1688: if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1689: MatPreallocated(mat);
1691: PetscLogEventBegin(MAT_GetValues,mat,0,0,0);
1692: (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);
1693: PetscLogEventEnd(MAT_GetValues,mat,0,0,0);
1694: return(0);
1695: }
1699: /*@
1700: MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and
1701: the same size. Currently, this can only be called once and creates the given matrix.
1703: Not Collective
1705: Input Parameters:
1706: + mat - the matrix
1707: . nb - the number of blocks
1708: . bs - the number of rows (and columns) in each block
1709: . rows - a concatenation of the rows for each block
1710: - v - a concatenation of logically two-dimensional arrays of values
1712: Notes:
1713: In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix.
1715: Level: advanced
1717: Concepts: matrices^putting entries in
1719: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1720: InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1721: @*/
1722: PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[])
1723: {
1731: #if defined(PETSC_USE_DEBUG)
1732: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1733: #endif
1735: if (mat->ops->setvaluesbatch) {
1736: PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);
1737: (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);
1738: PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);
1739: } else {
1740: PetscInt b;
1741: for(b = 0; b < nb; ++b) {
1742: MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);
1743: }
1744: }
1745: return(0);
1746: }
1750: /*@
1751: MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
1752: the routine MatSetValuesLocal() to allow users to insert matrix entries
1753: using a local (per-processor) numbering.
1755: Not Collective
1757: Input Parameters:
1758: + x - the matrix
1759: . rmapping - row mapping created with ISLocalToGlobalMappingCreate()
1760: or ISLocalToGlobalMappingCreateIS()
1761: - cmapping - column mapping
1763: Level: intermediate
1765: Concepts: matrices^local to global mapping
1766: Concepts: local to global mapping^for matrices
1768: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
1769: @*/
1770: PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
1771: {
1778: MatPreallocated(x);
1780: if (x->ops->setlocaltoglobalmapping) {
1781: (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);
1782: } else {
1783: PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);
1784: PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);
1785: }
1786: return(0);
1787: }
1791: /*@
1792: MatSetLocalToGlobalMappingBlock - Sets a local-to-global numbering for use
1793: by the routine MatSetValuesBlockedLocal() to allow users to insert matrix
1794: entries using a local (per-processor) numbering.
1796: Not Collective
1798: Input Parameters:
1799: + x - the matrix
1800: . rmapping - row mapping created with ISLocalToGlobalMappingCreate() or
1801: ISLocalToGlobalMappingCreateIS()
1802: - cmapping - column mapping
1804: Level: intermediate
1806: Concepts: matrices^local to global mapping blocked
1807: Concepts: local to global mapping^for matrices, blocked
1809: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal(),
1810: MatSetValuesBlocked(), MatSetValuesLocal()
1811: @*/
1812: PetscErrorCode MatSetLocalToGlobalMappingBlock(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
1813: {
1820: MatPreallocated(x);
1822: PetscLayoutSetISLocalToGlobalMappingBlock(x->rmap,rmapping);
1823: PetscLayoutSetISLocalToGlobalMappingBlock(x->cmap,cmapping);
1824: return(0);
1825: }
1829: /*@
1830: MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping()
1832: Not Collective
1834: Input Parameters:
1835: . A - the matrix
1837: Output Parameters:
1838: + rmapping - row mapping
1839: - cmapping - column mapping
1841: Level: advanced
1843: Concepts: matrices^local to global mapping
1844: Concepts: local to global mapping^for matrices
1846: .seealso: MatSetValuesLocal(), MatGetLocalToGlobalMappingBlock()
1847: @*/
1848: PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
1849: {
1855: if (rmapping) *rmapping = A->rmap->mapping;
1856: if (cmapping) *cmapping = A->cmap->mapping;
1857: return(0);
1858: }
1862: /*@
1863: MatGetLocalToGlobalMappingBlock - Gets the local-to-global numbering set by MatSetLocalToGlobalMappingBlock()
1865: Not Collective
1867: Input Parameters:
1868: . A - the matrix
1870: Output Parameters:
1871: + rmapping - row mapping
1872: - cmapping - column mapping
1874: Level: advanced
1876: Concepts: matrices^local to global mapping blocked
1877: Concepts: local to global mapping^for matrices, blocked
1879: .seealso: MatSetValuesBlockedLocal(), MatGetLocalToGlobalMapping()
1880: @*/
1881: PetscErrorCode MatGetLocalToGlobalMappingBlock(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
1882: {
1888: if (rmapping) *rmapping = A->rmap->bmapping;
1889: if (cmapping) *cmapping = A->cmap->bmapping;
1890: return(0);
1891: }
1895: /*@
1896: MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
1897: using a local ordering of the nodes.
1899: Not Collective
1901: Input Parameters:
1902: + x - the matrix
1903: . nrow, irow - number of rows and their local indices
1904: . ncol, icol - number of columns and their local indices
1905: . y - a logically two-dimensional array of values
1906: - addv - either INSERT_VALUES or ADD_VALUES, where
1907: ADD_VALUES adds values to any existing entries, and
1908: INSERT_VALUES replaces existing entries with new values
1910: Notes:
1911: Before calling MatSetValuesLocal(), the user must first set the
1912: local-to-global mapping by calling MatSetLocalToGlobalMapping().
1914: Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
1915: options cannot be mixed without intervening calls to the assembly
1916: routines.
1918: These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1919: MUST be called after all calls to MatSetValuesLocal() have been completed.
1921: Level: intermediate
1923: Concepts: matrices^putting entries in with local numbering
1925: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
1926: MatSetValueLocal()
1927: @*/
1928: PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
1929: {
1935: if (!nrow || !ncol) return(0); /* no values to insert */
1939: MatPreallocated(mat);
1940: if (mat->insertmode == NOT_SET_VALUES) {
1941: mat->insertmode = addv;
1942: }
1943: #if defined(PETSC_USE_DEBUG)
1944: else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1945: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1946: if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1947: #endif
1949: if (mat->assembled) {
1950: mat->was_assembled = PETSC_TRUE;
1951: mat->assembled = PETSC_FALSE;
1952: }
1953: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1954: if (mat->ops->setvalueslocal) {
1955: (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);
1956: } else {
1957: PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
1958: if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1959: irowm = buf; icolm = buf+nrow;
1960: } else {
1961: PetscMalloc2(nrow,PetscInt,&bufr,ncol,PetscInt,&bufc);
1962: irowm = bufr; icolm = bufc;
1963: }
1964: ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);
1965: ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);
1966: MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);
1967: PetscFree2(bufr,bufc);
1968: }
1969: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1970: #if defined(PETSC_HAVE_CUSP)
1971: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1972: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1973: }
1974: #endif
1975: return(0);
1976: }
1980: /*@
1981: MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix,
1982: using a local ordering of the nodes a block at a time.
1984: Not Collective
1986: Input Parameters:
1987: + x - the matrix
1988: . nrow, irow - number of rows and their local indices
1989: . ncol, icol - number of columns and their local indices
1990: . y - a logically two-dimensional array of values
1991: - addv - either INSERT_VALUES or ADD_VALUES, where
1992: ADD_VALUES adds values to any existing entries, and
1993: INSERT_VALUES replaces existing entries with new values
1995: Notes:
1996: Before calling MatSetValuesBlockedLocal(), the user must first set the
1997: block size using MatSetBlockSize(), and the local-to-global mapping by
1998: calling MatSetLocalToGlobalMappingBlock(), where the mapping MUST be
1999: set for matrix blocks, not for matrix elements.
2001: Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
2002: options cannot be mixed without intervening calls to the assembly
2003: routines.
2005: These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2006: MUST be called after all calls to MatSetValuesBlockedLocal() have been completed.
2008: Level: intermediate
2010: Concepts: matrices^putting blocked values in with local numbering
2012: .seealso: MatSetBlockSize(), MatSetLocalToGlobalMappingBlock(), MatAssemblyBegin(), MatAssemblyEnd(),
2013: MatSetValuesLocal(), MatSetLocalToGlobalMappingBlock(), MatSetValuesBlocked()
2014: @*/
2015: PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2016: {
2022: if (!nrow || !ncol) return(0); /* no values to insert */
2026: MatPreallocated(mat);
2027: if (mat->insertmode == NOT_SET_VALUES) {
2028: mat->insertmode = addv;
2029: }
2030: #if defined(PETSC_USE_DEBUG)
2031: else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2032: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2033: if (!mat->ops->setvaluesblockedlocal && !mat->ops->setvaluesblocked && !mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2034: #endif
2036: if (mat->assembled) {
2037: mat->was_assembled = PETSC_TRUE;
2038: mat->assembled = PETSC_FALSE;
2039: }
2040: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
2041: if (mat->ops->setvaluesblockedlocal) {
2042: (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);
2043: } else {
2044: PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2045: if (mat->rmap->bmapping && mat->cmap->bmapping) {
2046: if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2047: irowm = buf; icolm = buf + nrow;
2048: } else {
2049: PetscMalloc2(nrow,PetscInt,&bufr,ncol,PetscInt,&bufc);
2050: irowm = bufr; icolm = bufc;
2051: }
2052: ISLocalToGlobalMappingApply(mat->rmap->bmapping,nrow,irow,irowm);
2053: ISLocalToGlobalMappingApply(mat->cmap->bmapping,ncol,icol,icolm);
2054: MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);
2055: PetscFree2(bufr,bufc);
2056: } else {
2057: PetscInt i,j,bs=mat->rmap->bs;
2058: if ((nrow+ncol)*bs <=(PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2059: irowm = buf; icolm = buf + nrow;
2060: } else {
2061: PetscMalloc2(nrow*bs,PetscInt,&bufr,ncol*bs,PetscInt,&bufc);
2062: irowm = bufr; icolm = bufc;
2063: }
2064: for (i=0; i<nrow; i++)
2065: for (j=0; j<bs; j++)
2066: irowm[i*bs+j] = irow[i]*bs+j;
2067: for (i=0; i<ncol; i++)
2068: for (j=0; j<bs; j++)
2069: icolm[i*bs+j] = icol[i]*bs+j;
2070: MatSetValuesLocal(mat,nrow*bs,irowm,ncol*bs,icolm,y,addv);
2071: PetscFree2(bufr,bufc);
2072: }
2073: }
2074: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
2075: #if defined(PETSC_HAVE_CUSP)
2076: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
2077: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
2078: }
2079: #endif
2080: return(0);
2081: }
2085: /*@
2086: MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal
2088: Collective on Mat and Vec
2090: Input Parameters:
2091: + mat - the matrix
2092: - x - the vector to be multiplied
2094: Output Parameters:
2095: . y - the result
2097: Notes:
2098: The vectors x and y cannot be the same. I.e., one cannot
2099: call MatMult(A,y,y).
2101: Level: developer
2103: Concepts: matrix-vector product
2105: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2106: @*/
2107: PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y)
2108: {
2117: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2118: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2119: if (x == y) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2120: MatPreallocated(mat);
2122: if (!mat->ops->multdiagonalblock) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2123: (*mat->ops->multdiagonalblock)(mat,x,y);
2124: PetscObjectStateIncrease((PetscObject)y);
2125: return(0);
2126: }
2128: /* --------------------------------------------------------*/
2131: /*@
2132: MatMult - Computes the matrix-vector product, y = Ax.
2134: Neighbor-wise Collective on Mat and Vec
2136: Input Parameters:
2137: + mat - the matrix
2138: - x - the vector to be multiplied
2140: Output Parameters:
2141: . y - the result
2143: Notes:
2144: The vectors x and y cannot be the same. I.e., one cannot
2145: call MatMult(A,y,y).
2147: Level: beginner
2149: Concepts: matrix-vector product
2151: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2152: @*/
2153: PetscErrorCode MatMult(Mat mat,Vec x,Vec y)
2154: {
2162: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2163: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2164: if (x == y) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2165: #ifndef PETSC_HAVE_CONSTRAINTS
2166: if (mat->cmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
2167: if (mat->rmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
2168: if (mat->rmap->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %D %D",mat->rmap->n,y->map->n);
2169: #endif
2170: MatPreallocated(mat);
2172: if (mat->nullsp) {
2173: MatNullSpaceRemove(mat->nullsp,x,&x);
2174: }
2176: if (!mat->ops->mult) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2177: PetscLogEventBegin(MAT_Mult,mat,x,y,0);
2178: (*mat->ops->mult)(mat,x,y);
2179: PetscLogEventEnd(MAT_Mult,mat,x,y,0);
2181: if (mat->nullsp) {
2182: MatNullSpaceRemove(mat->nullsp,y,PETSC_NULL);
2183: }
2184: PetscObjectStateIncrease((PetscObject)y);
2185: return(0);
2186: }
2190: /*@
2191: MatMultTranspose - Computes matrix transpose times a vector.
2193: Neighbor-wise Collective on Mat and Vec
2195: Input Parameters:
2196: + mat - the matrix
2197: - x - the vector to be multilplied
2199: Output Parameters:
2200: . y - the result
2202: Notes:
2203: The vectors x and y cannot be the same. I.e., one cannot
2204: call MatMultTranspose(A,y,y).
2206: For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple,
2207: use MatMultHermitianTranspose()
2209: Level: beginner
2211: Concepts: matrix vector product^transpose
2213: .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose()
2214: @*/
2215: PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y)
2216: {
2225: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2226: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2227: if (x == y) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2228: #ifndef PETSC_HAVE_CONSTRAINTS
2229: if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
2230: if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N);
2231: #endif
2232: MatPreallocated(mat);
2234: if (!mat->ops->multtranspose) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"This matrix type does not have a multiply tranpose defined");
2235: PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);
2236: (*mat->ops->multtranspose)(mat,x,y);
2237: PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);
2238: PetscObjectStateIncrease((PetscObject)y);
2239: return(0);
2240: }
2244: /*@
2245: MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.
2247: Neighbor-wise Collective on Mat and Vec
2249: Input Parameters:
2250: + mat - the matrix
2251: - x - the vector to be multilplied
2253: Output Parameters:
2254: . y - the result
2256: Notes:
2257: The vectors x and y cannot be the same. I.e., one cannot
2258: call MatMultHermitianTranspose(A,y,y).
2260: Also called the conjugate transpose, complex conjugate transpose, or adjoint.
2262: For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical.
2264: Level: beginner
2266: Concepts: matrix vector product^transpose
2268: .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose()
2269: @*/
2270: PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y)
2271: {
2280: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2281: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2282: if (x == y) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2283: #ifndef PETSC_HAVE_CONSTRAINTS
2284: if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
2285: if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N);
2286: #endif
2287: MatPreallocated(mat);
2289: if (!mat->ops->multhermitiantranspose) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2290: PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);
2291: (*mat->ops->multhermitiantranspose)(mat,x,y);
2292: PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);
2293: PetscObjectStateIncrease((PetscObject)y);
2294: return(0);
2295: }
2299: /*@
2300: MatMultAdd - Computes v3 = v2 + A * v1.
2302: Neighbor-wise Collective on Mat and Vec
2304: Input Parameters:
2305: + mat - the matrix
2306: - v1, v2 - the vectors
2308: Output Parameters:
2309: . v3 - the result
2311: Notes:
2312: The vectors v1 and v3 cannot be the same. I.e., one cannot
2313: call MatMultAdd(A,v1,v2,v1).
2315: Level: beginner
2317: Concepts: matrix vector product^addition
2319: .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
2320: @*/
2321: PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2322: {
2332: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2333: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2334: if (mat->cmap->N != v1->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->cmap->N,v1->map->N);
2335: /* if (mat->rmap->N != v2->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->rmap->N,v2->map->N);
2336: if (mat->rmap->N != v3->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->rmap->N,v3->map->N); */
2337: if (mat->rmap->n != v3->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: local dim %D %D",mat->rmap->n,v3->map->n);
2338: if (mat->rmap->n != v2->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: local dim %D %D",mat->rmap->n,v2->map->n);
2339: if (v1 == v3) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2340: MatPreallocated(mat);
2342: if (!mat->ops->multadd) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name);
2343: PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);
2344: (*mat->ops->multadd)(mat,v1,v2,v3);
2345: PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);
2346: PetscObjectStateIncrease((PetscObject)v3);
2347: return(0);
2348: }
2352: /*@
2353: MatMultTransposeAdd - Computes v3 = v2 + A' * v1.
2355: Neighbor-wise Collective on Mat and Vec
2357: Input Parameters:
2358: + mat - the matrix
2359: - v1, v2 - the vectors
2361: Output Parameters:
2362: . v3 - the result
2364: Notes:
2365: The vectors v1 and v3 cannot be the same. I.e., one cannot
2366: call MatMultTransposeAdd(A,v1,v2,v1).
2368: Level: beginner
2370: Concepts: matrix vector product^transpose and addition
2372: .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
2373: @*/
2374: PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2375: {
2385: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2386: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2387: if (!mat->ops->multtransposeadd) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2388: if (v1 == v3) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2389: if (mat->rmap->N != v1->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->rmap->N,v1->map->N);
2390: if (mat->cmap->N != v2->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->cmap->N,v2->map->N);
2391: if (mat->cmap->N != v3->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->cmap->N,v3->map->N);
2392: MatPreallocated(mat);
2394: PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);
2395: (*mat->ops->multtransposeadd)(mat,v1,v2,v3);
2396: PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);
2397: PetscObjectStateIncrease((PetscObject)v3);
2398: return(0);
2399: }
2403: /*@
2404: MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1.
2406: Neighbor-wise Collective on Mat and Vec
2408: Input Parameters:
2409: + mat - the matrix
2410: - v1, v2 - the vectors
2412: Output Parameters:
2413: . v3 - the result
2415: Notes:
2416: The vectors v1 and v3 cannot be the same. I.e., one cannot
2417: call MatMultHermitianTransposeAdd(A,v1,v2,v1).
2419: Level: beginner
2421: Concepts: matrix vector product^transpose and addition
2423: .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult()
2424: @*/
2425: PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2426: {
2436: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2437: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2438: if (!mat->ops->multhermitiantransposeadd) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2439: if (v1 == v3) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2440: if (mat->rmap->N != v1->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->rmap->N,v1->map->N);
2441: if (mat->cmap->N != v2->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->cmap->N,v2->map->N);
2442: if (mat->cmap->N != v3->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->cmap->N,v3->map->N);
2443: MatPreallocated(mat);
2445: PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2446: (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);
2447: PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2448: PetscObjectStateIncrease((PetscObject)v3);
2449: return(0);
2450: }
2454: /*@
2455: MatMultConstrained - The inner multiplication routine for a
2456: constrained matrix P^T A P.
2458: Neighbor-wise Collective on Mat and Vec
2460: Input Parameters:
2461: + mat - the matrix
2462: - x - the vector to be multilplied
2464: Output Parameters:
2465: . y - the result
2467: Notes:
2468: The vectors x and y cannot be the same. I.e., one cannot
2469: call MatMult(A,y,y).
2471: Level: beginner
2473: .keywords: matrix, multiply, matrix-vector product, constraint
2474: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2475: @*/
2476: PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y)
2477: {
2484: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2485: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2486: if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2487: if (mat->cmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
2488: if (mat->rmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
2489: if (mat->rmap->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %D %D",mat->rmap->n,y->map->n);
2491: PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2492: (*mat->ops->multconstrained)(mat,x,y);
2493: PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2494: PetscObjectStateIncrease((PetscObject)y);
2496: return(0);
2497: }
2501: /*@
2502: MatMultTransposeConstrained - The inner multiplication routine for a
2503: constrained matrix P^T A^T P.
2505: Neighbor-wise Collective on Mat and Vec
2507: Input Parameters:
2508: + mat - the matrix
2509: - x - the vector to be multilplied
2511: Output Parameters:
2512: . y - the result
2514: Notes:
2515: The vectors x and y cannot be the same. I.e., one cannot
2516: call MatMult(A,y,y).
2518: Level: beginner
2520: .keywords: matrix, multiply, matrix-vector product, constraint
2521: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2522: @*/
2523: PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2524: {
2531: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2532: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2533: if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2534: if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
2535: if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
2537: PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2538: (*mat->ops->multtransposeconstrained)(mat,x,y);
2539: PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2540: PetscObjectStateIncrease((PetscObject)y);
2542: return(0);
2543: }
2547: /*@C
2548: MatGetFactorType - gets the type of factorization it is
2550: Note Collective
2551: as the flag
2553: Input Parameters:
2554: . mat - the matrix
2556: Output Parameters:
2557: . t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT
2559: Level: intermediate
2561: .seealso: MatFactorType, MatGetFactor()
2562: @*/
2563: PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t)
2564: {
2568: *t = mat->factortype;
2569: return(0);
2570: }
2572: /* ------------------------------------------------------------*/
2575: /*@C
2576: MatGetInfo - Returns information about matrix storage (number of
2577: nonzeros, memory, etc.).
2579: Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag
2581: Input Parameters:
2582: . mat - the matrix
2584: Output Parameters:
2585: + flag - flag indicating the type of parameters to be returned
2586: (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2587: MAT_GLOBAL_SUM - sum over all processors)
2588: - info - matrix information context
2590: Notes:
2591: The MatInfo context contains a variety of matrix data, including
2592: number of nonzeros allocated and used, number of mallocs during
2593: matrix assembly, etc. Additional information for factored matrices
2594: is provided (such as the fill ratio, number of mallocs during
2595: factorization, etc.). Much of this info is printed to PETSC_STDOUT
2596: when using the runtime options
2597: $ -info -mat_view_info
2599: Example for C/C++ Users:
2600: See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2601: data within the MatInfo context. For example,
2602: .vb
2603: MatInfo info;
2604: Mat A;
2605: double mal, nz_a, nz_u;
2607: MatGetInfo(A,MAT_LOCAL,&info);
2608: mal = info.mallocs;
2609: nz_a = info.nz_allocated;
2610: .ve
2612: Example for Fortran Users:
2613: Fortran users should declare info as a double precision
2614: array of dimension MAT_INFO_SIZE, and then extract the parameters
2615: of interest. See the file ${PETSC_DIR}/include/finclude/petscmat.h
2616: a complete list of parameter names.
2617: .vb
2618: double precision info(MAT_INFO_SIZE)
2619: double precision mal, nz_a
2620: Mat A
2621: integer ierr
2623: call MatGetInfo(A,MAT_LOCAL,info,ierr)
2624: mal = info(MAT_INFO_MALLOCS)
2625: nz_a = info(MAT_INFO_NZ_ALLOCATED)
2626: .ve
2628: Level: intermediate
2630: Concepts: matrices^getting information on
2631:
2632: Developer Note: fortran interface is not autogenerated as the f90
2633: interface defintion cannot be generated correctly [due to MatInfo]
2634:
2635: @*/
2636: PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2637: {
2644: if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2645: MatPreallocated(mat);
2646: (*mat->ops->getinfo)(mat,flag,info);
2647: return(0);
2648: }
2650: /* ----------------------------------------------------------*/
2654: /*@C
2655: MatLUFactor - Performs in-place LU factorization of matrix.
2657: Collective on Mat
2659: Input Parameters:
2660: + mat - the matrix
2661: . row - row permutation
2662: . col - column permutation
2663: - info - options for factorization, includes
2664: $ fill - expected fill as ratio of original fill.
2665: $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2666: $ Run with the option -info to determine an optimal value to use
2668: Notes:
2669: Most users should employ the simplified KSP interface for linear solvers
2670: instead of working directly with matrix algebra routines such as this.
2671: See, e.g., KSPCreate().
2673: This changes the state of the matrix to a factored matrix; it cannot be used
2674: for example with MatSetValues() unless one first calls MatSetUnfactored().
2676: Level: developer
2678: Concepts: matrices^LU factorization
2680: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2681: MatGetOrdering(), MatSetUnfactored(), MatFactorInfo
2683: Developer Note: fortran interface is not autogenerated as the f90
2684: interface defintion cannot be generated correctly [due to MatFactorInfo]
2686: @*/
2687: PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2688: {
2697: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2698: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2699: if (!mat->ops->lufactor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2700: MatPreallocated(mat);
2702: PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);
2703: (*mat->ops->lufactor)(mat,row,col,info);
2704: PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);
2705: PetscObjectStateIncrease((PetscObject)mat);
2706: return(0);
2707: }
2711: /*@C
2712: MatILUFactor - Performs in-place ILU factorization of matrix.
2714: Collective on Mat
2716: Input Parameters:
2717: + mat - the matrix
2718: . row - row permutation
2719: . col - column permutation
2720: - info - structure containing
2721: $ levels - number of levels of fill.
2722: $ expected fill - as ratio of original fill.
2723: $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2724: missing diagonal entries)
2726: Notes:
2727: Probably really in-place only when level of fill is zero, otherwise allocates
2728: new space to store factored matrix and deletes previous memory.
2730: Most users should employ the simplified KSP interface for linear solvers
2731: instead of working directly with matrix algebra routines such as this.
2732: See, e.g., KSPCreate().
2734: Level: developer
2736: Concepts: matrices^ILU factorization
2738: .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
2740: Developer Note: fortran interface is not autogenerated as the f90
2741: interface defintion cannot be generated correctly [due to MatFactorInfo]
2743: @*/
2744: PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2745: {
2754: if (mat->rmap->N != mat->cmap->N) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONG,"matrix must be square");
2755: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2756: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2757: if (!mat->ops->ilufactor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2758: MatPreallocated(mat);
2760: PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);
2761: (*mat->ops->ilufactor)(mat,row,col,info);
2762: PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);
2763: PetscObjectStateIncrease((PetscObject)mat);
2764: return(0);
2765: }
2769: /*@C
2770: MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
2771: Call this routine before calling MatLUFactorNumeric().
2773: Collective on Mat
2775: Input Parameters:
2776: + fact - the factor matrix obtained with MatGetFactor()
2777: . mat - the matrix
2778: . row, col - row and column permutations
2779: - info - options for factorization, includes
2780: $ fill - expected fill as ratio of original fill.
2781: $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2782: $ Run with the option -info to determine an optimal value to use
2785: Notes:
2786: See the <a href="../../docs/manual.pdf">users manual</a> for additional information about
2787: choosing the fill factor for better efficiency.
2789: Most users should employ the simplified KSP interface for linear solvers
2790: instead of working directly with matrix algebra routines such as this.
2791: See, e.g., KSPCreate().
2793: Level: developer
2795: Concepts: matrices^LU symbolic factorization
2797: .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
2799: Developer Note: fortran interface is not autogenerated as the f90
2800: interface defintion cannot be generated correctly [due to MatFactorInfo]
2802: @*/
2803: PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
2804: {
2814: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2815: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2816: if (!(fact)->ops->lufactorsymbolic) {
2817: const MatSolverPackage spackage;
2818: MatFactorGetSolverPackage(fact,&spackage);
2819: SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage);
2820: }
2821: MatPreallocated(mat);
2823: PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);
2824: (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);
2825: PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);
2826: PetscObjectStateIncrease((PetscObject)fact);
2827: return(0);
2828: }
2832: /*@C
2833: MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
2834: Call this routine after first calling MatLUFactorSymbolic().
2836: Collective on Mat
2838: Input Parameters:
2839: + fact - the factor matrix obtained with MatGetFactor()
2840: . mat - the matrix
2841: - info - options for factorization
2843: Notes:
2844: See MatLUFactor() for in-place factorization. See
2845: MatCholeskyFactorNumeric() for the symmetric, positive definite case.
2847: Most users should employ the simplified KSP interface for linear solvers
2848: instead of working directly with matrix algebra routines such as this.
2849: See, e.g., KSPCreate().
2851: Level: developer
2853: Concepts: matrices^LU numeric factorization
2855: .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()
2857: Developer Note: fortran interface is not autogenerated as the f90
2858: interface defintion cannot be generated correctly [due to MatFactorInfo]
2860: @*/
2861: PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
2862: {
2870: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2871: if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) {
2872: SETERRQ4(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dimensions are different %D should = %D %D should = %D",mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N);
2873: }
2874: if (!(fact)->ops->lufactornumeric) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name);
2875: MatPreallocated(mat);
2876: PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);
2877: (fact->ops->lufactornumeric)(fact,mat,info);
2878: PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);
2880: MatView_Private(fact);
2881: PetscObjectStateIncrease((PetscObject)fact);
2882: return(0);
2883: }
2887: /*@C
2888: MatCholeskyFactor - Performs in-place Cholesky factorization of a
2889: symmetric matrix.
2891: Collective on Mat
2893: Input Parameters:
2894: + mat - the matrix
2895: . perm - row and column permutations
2896: - f - expected fill as ratio of original fill
2898: Notes:
2899: See MatLUFactor() for the nonsymmetric case. See also
2900: MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().
2902: Most users should employ the simplified KSP interface for linear solvers
2903: instead of working directly with matrix algebra routines such as this.
2904: See, e.g., KSPCreate().
2906: Level: developer
2908: Concepts: matrices^Cholesky factorization
2910: .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
2911: MatGetOrdering()
2913: Developer Note: fortran interface is not autogenerated as the f90
2914: interface defintion cannot be generated correctly [due to MatFactorInfo]
2916: @*/
2917: PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
2918: {
2926: if (mat->rmap->N != mat->cmap->N) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONG,"Matrix must be square");
2927: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2928: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2929: if (!mat->ops->choleskyfactor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2930: MatPreallocated(mat);
2932: PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);
2933: (*mat->ops->choleskyfactor)(mat,perm,info);
2934: PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);
2935: PetscObjectStateIncrease((PetscObject)mat);
2936: return(0);
2937: }
2941: /*@C
2942: MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
2943: of a symmetric matrix.
2945: Collective on Mat
2947: Input Parameters:
2948: + fact - the factor matrix obtained with MatGetFactor()
2949: . mat - the matrix
2950: . perm - row and column permutations
2951: - info - options for factorization, includes
2952: $ fill - expected fill as ratio of original fill.
2953: $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2954: $ Run with the option -info to determine an optimal value to use
2956: Notes:
2957: See MatLUFactorSymbolic() for the nonsymmetric case. See also
2958: MatCholeskyFactor() and MatCholeskyFactorNumeric().
2960: Most users should employ the simplified KSP interface for linear solvers
2961: instead of working directly with matrix algebra routines such as this.
2962: See, e.g., KSPCreate().
2964: Level: developer
2966: Concepts: matrices^Cholesky symbolic factorization
2968: .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
2969: MatGetOrdering()
2971: Developer Note: fortran interface is not autogenerated as the f90
2972: interface defintion cannot be generated correctly [due to MatFactorInfo]
2974: @*/
2975: PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
2976: {
2985: if (mat->rmap->N != mat->cmap->N) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONG,"Matrix must be square");
2986: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2987: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2988: if (!(fact)->ops->choleskyfactorsymbolic) {
2989: const MatSolverPackage spackage;
2990: MatFactorGetSolverPackage(fact,&spackage);
2991: SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage);
2992: }
2993: MatPreallocated(mat);
2995: PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
2996: (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);
2997: PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
2998: PetscObjectStateIncrease((PetscObject)fact);
2999: return(0);
3000: }
3004: /*@C
3005: MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
3006: of a symmetric matrix. Call this routine after first calling
3007: MatCholeskyFactorSymbolic().
3009: Collective on Mat
3011: Input Parameters:
3012: + fact - the factor matrix obtained with MatGetFactor()
3013: . mat - the initial matrix
3014: . info - options for factorization
3015: - fact - the symbolic factor of mat
3018: Notes:
3019: Most users should employ the simplified KSP interface for linear solvers
3020: instead of working directly with matrix algebra routines such as this.
3021: See, e.g., KSPCreate().
3023: Level: developer
3025: Concepts: matrices^Cholesky numeric factorization
3027: .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
3029: Developer Note: fortran interface is not autogenerated as the f90
3030: interface defintion cannot be generated correctly [due to MatFactorInfo]
3032: @*/
3033: PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3034: {
3042: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3043: if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name);
3044: if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) {
3045: SETERRQ4(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dim %D should = %D %D should = %D",mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N);
3046: }
3047: MatPreallocated(mat);
3049: PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);
3050: (fact->ops->choleskyfactornumeric)(fact,mat,info);
3051: PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);
3053: MatView_Private(fact);
3054: PetscObjectStateIncrease((PetscObject)fact);
3055: return(0);
3056: }
3058: /* ----------------------------------------------------------------*/
3061: /*@
3062: MatSolve - Solves A x = b, given a factored matrix.
3064: Neighbor-wise Collective on Mat and Vec
3066: Input Parameters:
3067: + mat - the factored matrix
3068: - b - the right-hand-side vector
3070: Output Parameter:
3071: . x - the result vector
3073: Notes:
3074: The vectors b and x cannot be the same. I.e., one cannot
3075: call MatSolve(A,x,x).
3077: Notes:
3078: Most users should employ the simplified KSP interface for linear solvers
3079: instead of working directly with matrix algebra routines such as this.
3080: See, e.g., KSPCreate().
3082: Level: developer
3084: Concepts: matrices^triangular solves
3086: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
3087: @*/
3088: PetscErrorCode MatSolve(Mat mat,Vec b,Vec x)
3089: {
3099: if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3100: if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3101: if (mat->cmap->N != x->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3102: if (mat->rmap->N != b->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3103: if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3104: if (!mat->rmap->N && !mat->cmap->N) return(0);
3105: if (!mat->ops->solve) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3106: MatPreallocated(mat);
3108: PetscLogEventBegin(MAT_Solve,mat,b,x,0);
3109: (*mat->ops->solve)(mat,b,x);
3110: PetscLogEventEnd(MAT_Solve,mat,b,x,0);
3111: PetscObjectStateIncrease((PetscObject)x);
3112: return(0);
3113: }
3117: PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X)
3118: {
3120: Vec b,x;
3121: PetscInt m,N,i;
3122: PetscScalar *bb,*xx;
3123: PetscBool flg;
3126: PetscTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,PETSC_NULL);
3127: if (!flg) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
3128: PetscTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,PETSC_NULL);
3129: if (!flg) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");
3131: MatGetArray(B,&bb);
3132: MatGetArray(X,&xx);
3133: MatGetLocalSize(B,&m,PETSC_NULL); /* number local rows */
3134: MatGetSize(B,PETSC_NULL,&N); /* total columns in dense matrix */
3135: MatGetVecs(A,&x,&b);
3136: for (i=0; i<N; i++) {
3137: VecPlaceArray(b,bb + i*m);
3138: VecPlaceArray(x,xx + i*m);
3139: MatSolve(A,b,x);
3140: VecResetArray(x);
3141: VecResetArray(b);
3142: }
3143: VecDestroy(&b);
3144: VecDestroy(&x);
3145: MatRestoreArray(B,&bb);
3146: MatRestoreArray(X,&xx);
3147: return(0);
3148: }
3152: /*@
3153: MatMatSolve - Solves A X = B, given a factored matrix.
3155: Neighbor-wise Collective on Mat
3157: Input Parameters:
3158: + mat - the factored matrix
3159: - B - the right-hand-side matrix (dense matrix)
3161: Output Parameter:
3162: . X - the result matrix (dense matrix)
3164: Notes:
3165: The matrices b and x cannot be the same. I.e., one cannot
3166: call MatMatSolve(A,x,x).
3168: Notes:
3169: Most users should usually employ the simplified KSP interface for linear solvers
3170: instead of working directly with matrix algebra routines such as this.
3171: See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3172: at a time.
3174: Level: developer
3176: Concepts: matrices^triangular solves
3178: .seealso: MatMatSolveAdd(), MatMatSolveTranspose(), MatMatSolveTransposeAdd(), MatLUFactor(), MatCholeskyFactor()
3179: @*/
3180: PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X)
3181: {
3191: if (X == B) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3192: if (!A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3193: if (A->cmap->N != X->rmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %D %D",A->cmap->N,X->rmap->N);
3194: if (A->rmap->N != B->rmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %D %D",A->rmap->N,B->rmap->N);
3195: if (A->rmap->n != B->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat A,Mat B: local dim %D %D",A->rmap->n,B->rmap->n);
3196: if (!A->rmap->N && !A->cmap->N) return(0);
3197: MatPreallocated(A);
3199: PetscLogEventBegin(MAT_MatSolve,A,B,X,0);
3200: if (!A->ops->matsolve) {
3201: PetscInfo1(A,"Mat type %s using basic MatMatSolve",((PetscObject)A)->type_name);
3202: MatMatSolve_Basic(A,B,X);
3203: } else {
3204: (*A->ops->matsolve)(A,B,X);
3205: }
3206: PetscLogEventEnd(MAT_MatSolve,A,B,X,0);
3207: PetscObjectStateIncrease((PetscObject)X);
3208: return(0);
3209: }
3214: /*@
3215: MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or
3216: U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U,
3218: Neighbor-wise Collective on Mat and Vec
3220: Input Parameters:
3221: + mat - the factored matrix
3222: - b - the right-hand-side vector
3224: Output Parameter:
3225: . x - the result vector
3227: Notes:
3228: MatSolve() should be used for most applications, as it performs
3229: a forward solve followed by a backward solve.
3231: The vectors b and x cannot be the same, i.e., one cannot
3232: call MatForwardSolve(A,x,x).
3234: For matrix in seqsbaij format with block size larger than 1,
3235: the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3236: MatForwardSolve() solves U^T*D y = b, and
3237: MatBackwardSolve() solves U x = y.
3238: Thus they do not provide a symmetric preconditioner.
3240: Most users should employ the simplified KSP interface for linear solvers
3241: instead of working directly with matrix algebra routines such as this.
3242: See, e.g., KSPCreate().
3244: Level: developer
3246: Concepts: matrices^forward solves
3248: .seealso: MatSolve(), MatBackwardSolve()
3249: @*/
3250: PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x)
3251: {
3261: if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3262: if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3263: if (!mat->ops->forwardsolve) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3264: if (mat->cmap->N != x->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3265: if (mat->rmap->N != b->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3266: if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3267: MatPreallocated(mat);
3268: PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);
3269: (*mat->ops->forwardsolve)(mat,b,x);
3270: PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);
3271: PetscObjectStateIncrease((PetscObject)x);
3272: return(0);
3273: }
3277: /*@
3278: MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
3279: D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U,
3281: Neighbor-wise Collective on Mat and Vec
3283: Input Parameters:
3284: + mat - the factored matrix
3285: - b - the right-hand-side vector
3287: Output Parameter:
3288: . x - the result vector
3290: Notes:
3291: MatSolve() should be used for most applications, as it performs
3292: a forward solve followed by a backward solve.
3294: The vectors b and x cannot be the same. I.e., one cannot
3295: call MatBackwardSolve(A,x,x).
3297: For matrix in seqsbaij format with block size larger than 1,
3298: the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3299: MatForwardSolve() solves U^T*D y = b, and
3300: MatBackwardSolve() solves U x = y.
3301: Thus they do not provide a symmetric preconditioner.
3303: Most users should employ the simplified KSP interface for linear solvers
3304: instead of working directly with matrix algebra routines such as this.
3305: See, e.g., KSPCreate().
3307: Level: developer
3309: Concepts: matrices^backward solves
3311: .seealso: MatSolve(), MatForwardSolve()
3312: @*/
3313: PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x)
3314: {
3324: if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3325: if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3326: if (!mat->ops->backwardsolve) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3327: if (mat->cmap->N != x->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3328: if (mat->rmap->N != b->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3329: if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3330: MatPreallocated(mat);
3332: PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);
3333: (*mat->ops->backwardsolve)(mat,b,x);
3334: PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);
3335: PetscObjectStateIncrease((PetscObject)x);
3336: return(0);
3337: }
3341: /*@
3342: MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
3344: Neighbor-wise Collective on Mat and Vec
3346: Input Parameters:
3347: + mat - the factored matrix
3348: . b - the right-hand-side vector
3349: - y - the vector to be added to
3351: Output Parameter:
3352: . x - the result vector
3354: Notes:
3355: The vectors b and x cannot be the same. I.e., one cannot
3356: call MatSolveAdd(A,x,y,x).
3358: Most users should employ the simplified KSP interface for linear solvers
3359: instead of working directly with matrix algebra routines such as this.
3360: See, e.g., KSPCreate().
3362: Level: developer
3364: Concepts: matrices^triangular solves
3366: .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3367: @*/
3368: PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3369: {
3370: PetscScalar one = 1.0;
3371: Vec tmp;
3383: if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3384: if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3385: if (mat->cmap->N != x->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3386: if (mat->rmap->N != b->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3387: if (mat->rmap->N != y->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
3388: if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3389: if (x->map->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %D %D",x->map->n,y->map->n);
3390: MatPreallocated(mat);
3392: PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);
3393: if (mat->ops->solveadd) {
3394: (*mat->ops->solveadd)(mat,b,y,x);
3395: } else {
3396: /* do the solve then the add manually */
3397: if (x != y) {
3398: MatSolve(mat,b,x);
3399: VecAXPY(x,one,y);
3400: } else {
3401: VecDuplicate(x,&tmp);
3402: PetscLogObjectParent(mat,tmp);
3403: VecCopy(x,tmp);
3404: MatSolve(mat,b,x);
3405: VecAXPY(x,one,tmp);
3406: VecDestroy(&tmp);
3407: }
3408: }
3409: PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);
3410: PetscObjectStateIncrease((PetscObject)x);
3411: return(0);
3412: }
3416: /*@
3417: MatSolveTranspose - Solves A' x = b, given a factored matrix.
3419: Neighbor-wise Collective on Mat and Vec
3421: Input Parameters:
3422: + mat - the factored matrix
3423: - b - the right-hand-side vector
3425: Output Parameter:
3426: . x - the result vector
3428: Notes:
3429: The vectors b and x cannot be the same. I.e., one cannot
3430: call MatSolveTranspose(A,x,x).
3432: Most users should employ the simplified KSP interface for linear solvers
3433: instead of working directly with matrix algebra routines such as this.
3434: See, e.g., KSPCreate().
3436: Level: developer
3438: Concepts: matrices^triangular solves
3440: .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
3441: @*/
3442: PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x)
3443: {
3453: if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3454: if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3455: if (!mat->ops->solvetranspose) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3456: if (mat->rmap->N != x->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
3457: if (mat->cmap->N != b->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->cmap->N,b->map->N);
3458: MatPreallocated(mat);
3459: PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);
3460: (*mat->ops->solvetranspose)(mat,b,x);
3461: PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);
3462: PetscObjectStateIncrease((PetscObject)x);
3463: return(0);
3464: }
3468: /*@
3469: MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
3470: factored matrix.
3472: Neighbor-wise Collective on Mat and Vec
3474: Input Parameters:
3475: + mat - the factored matrix
3476: . b - the right-hand-side vector
3477: - y - the vector to be added to
3479: Output Parameter:
3480: . x - the result vector
3482: Notes:
3483: The vectors b and x cannot be the same. I.e., one cannot
3484: call MatSolveTransposeAdd(A,x,y,x).
3486: Most users should employ the simplified KSP interface for linear solvers
3487: instead of working directly with matrix algebra routines such as this.
3488: See, e.g., KSPCreate().
3490: Level: developer
3492: Concepts: matrices^triangular solves
3494: .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3495: @*/
3496: PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3497: {
3498: PetscScalar one = 1.0;
3500: Vec tmp;
3511: if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3512: if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3513: if (mat->rmap->N != x->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
3514: if (mat->cmap->N != b->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->cmap->N,b->map->N);
3515: if (mat->cmap->N != y->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N);
3516: if (x->map->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %D %D",x->map->n,y->map->n);
3517: MatPreallocated(mat);
3519: PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);
3520: if (mat->ops->solvetransposeadd) {
3521: (*mat->ops->solvetransposeadd)(mat,b,y,x);
3522: } else {
3523: /* do the solve then the add manually */
3524: if (x != y) {
3525: MatSolveTranspose(mat,b,x);
3526: VecAXPY(x,one,y);
3527: } else {
3528: VecDuplicate(x,&tmp);
3529: PetscLogObjectParent(mat,tmp);
3530: VecCopy(x,tmp);
3531: MatSolveTranspose(mat,b,x);
3532: VecAXPY(x,one,tmp);
3533: VecDestroy(&tmp);
3534: }
3535: }
3536: PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);
3537: PetscObjectStateIncrease((PetscObject)x);
3538: return(0);
3539: }
3540: /* ----------------------------------------------------------------*/
3544: /*@
3545: MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps.
3547: Neighbor-wise Collective on Mat and Vec
3549: Input Parameters:
3550: + mat - the matrix
3551: . b - the right hand side
3552: . omega - the relaxation factor
3553: . flag - flag indicating the type of SOR (see below)
3554: . shift - diagonal shift
3555: . its - the number of iterations
3556: - lits - the number of local iterations
3558: Output Parameters:
3559: . x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess)
3561: SOR Flags:
3562: . SOR_FORWARD_SWEEP - forward SOR
3563: . SOR_BACKWARD_SWEEP - backward SOR
3564: . SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3565: . SOR_LOCAL_FORWARD_SWEEP - local forward SOR
3566: . SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
3567: . SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3568: . SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
3569: upper/lower triangular part of matrix to
3570: vector (with omega)
3571: . SOR_ZERO_INITIAL_GUESS - zero initial guess
3573: Notes:
3574: SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3575: SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3576: on each processor.
3578: Application programmers will not generally use MatSOR() directly,
3579: but instead will employ the KSP/PC interface.
3581: Notes: for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing
3583: Notes for Advanced Users:
3584: The flags are implemented as bitwise inclusive or operations.
3585: For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3586: to specify a zero initial guess for SSOR.
3588: Most users should employ the simplified KSP interface for linear solvers
3589: instead of working directly with matrix algebra routines such as this.
3590: See, e.g., KSPCreate().
3592: Vectors x and b CANNOT be the same
3594: Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes
3596: Level: developer
3598: Concepts: matrices^relaxation
3599: Concepts: matrices^SOR
3600: Concepts: matrices^Gauss-Seidel
3602: @*/
3603: PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3604: {
3614: if (!mat->ops->sor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3615: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3616: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3617: if (mat->cmap->N != x->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3618: if (mat->rmap->N != b->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3619: if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3620: if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
3621: if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
3622: if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");
3624: MatPreallocated(mat);
3625: PetscLogEventBegin(MAT_SOR,mat,b,x,0);
3626: ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);
3627: PetscLogEventEnd(MAT_SOR,mat,b,x,0);
3628: PetscObjectStateIncrease((PetscObject)x);
3629: return(0);
3630: }
3634: /*
3635: Default matrix copy routine.
3636: */
3637: PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
3638: {
3639: PetscErrorCode ierr;
3640: PetscInt i,rstart = 0,rend = 0,nz;
3641: const PetscInt *cwork;
3642: const PetscScalar *vwork;
3645: if (B->assembled) {
3646: MatZeroEntries(B);
3647: }
3648: MatGetOwnershipRange(A,&rstart,&rend);
3649: for (i=rstart; i<rend; i++) {
3650: MatGetRow(A,i,&nz,&cwork,&vwork);
3651: MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);
3652: MatRestoreRow(A,i,&nz,&cwork,&vwork);
3653: }
3654: MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
3655: MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);
3656: PetscObjectStateIncrease((PetscObject)B);
3657: return(0);
3658: }
3662: /*@
3663: MatCopy - Copys a matrix to another matrix.
3665: Collective on Mat
3667: Input Parameters:
3668: + A - the matrix
3669: - str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
3671: Output Parameter:
3672: . B - where the copy is put
3674: Notes:
3675: If you use SAME_NONZERO_PATTERN then the two matrices had better have the
3676: same nonzero pattern or the routine will crash.
3678: MatCopy() copies the matrix entries of a matrix to another existing
3679: matrix (after first zeroing the second matrix). A related routine is
3680: MatConvert(), which first creates a new matrix and then copies the data.
3682: Level: intermediate
3683:
3684: Concepts: matrices^copying
3686: .seealso: MatConvert(), MatDuplicate()
3688: @*/
3689: PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str)
3690: {
3692: PetscInt i;
3700: MatPreallocated(B);
3701: if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3702: if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3703: if (A->rmap->N != B->rmap->N || A->cmap->N != B->cmap->N) SETERRQ4(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim (%D,%D) (%D,%D)",A->rmap->N,B->rmap->N,A->cmap->N,B->cmap->N);
3704: MatPreallocated(A);
3706: PetscLogEventBegin(MAT_Copy,A,B,0,0);
3707: if (A->ops->copy) {
3708: (*A->ops->copy)(A,B,str);
3709: } else { /* generic conversion */
3710: MatCopy_Basic(A,B,str);
3711: }
3713: B->stencil.dim = A->stencil.dim;
3714: B->stencil.noc = A->stencil.noc;
3715: for (i=0; i<=A->stencil.dim; i++) {
3716: B->stencil.dims[i] = A->stencil.dims[i];
3717: B->stencil.starts[i] = A->stencil.starts[i];
3718: }
3720: PetscLogEventEnd(MAT_Copy,A,B,0,0);
3721: PetscObjectStateIncrease((PetscObject)B);
3722: return(0);
3723: }
3727: /*@C
3728: MatConvert - Converts a matrix to another matrix, either of the same
3729: or different type.
3731: Collective on Mat
3733: Input Parameters:
3734: + mat - the matrix
3735: . newtype - new matrix type. Use MATSAME to create a new matrix of the
3736: same type as the original matrix.
3737: - reuse - denotes if the destination matrix is to be created or reused. Currently
3738: MAT_REUSE_MATRIX is only supported for inplace conversion, otherwise use
3739: MAT_INITIAL_MATRIX.
3741: Output Parameter:
3742: . M - pointer to place new matrix
3744: Notes:
3745: MatConvert() first creates a new matrix and then copies the data from
3746: the first matrix. A related routine is MatCopy(), which copies the matrix
3747: entries of one matrix to another already existing matrix context.
3749: Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
3750: the MPI communicator of the generated matrix is always the same as the communicator
3751: of the input matrix.
3753: Level: intermediate
3755: Concepts: matrices^converting between storage formats
3757: .seealso: MatCopy(), MatDuplicate()
3758: @*/
3759: PetscErrorCode MatConvert(Mat mat, const MatType newtype,MatReuse reuse,Mat *M)
3760: {
3761: PetscErrorCode ierr;
3762: PetscBool sametype,issame,flg;
3763: char convname[256],mtype[256];
3764: Mat B;
3770: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3771: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3772: MatPreallocated(mat);
3774: PetscOptionsGetString(((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);
3775: if (flg) {
3776: newtype = mtype;
3777: }
3778: PetscTypeCompare((PetscObject)mat,newtype,&sametype);
3779: PetscStrcmp(newtype,"same",&issame);
3780: if ((reuse == MAT_REUSE_MATRIX) && (mat != *M)) {
3781: SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"MAT_REUSE_MATRIX only supported for in-place conversion currently");
3782: }
3784: if ((reuse == MAT_REUSE_MATRIX) && (issame || sametype)) return(0);
3785:
3786: if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
3787: (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);
3788: } else {
3789: PetscErrorCode (*conv)(Mat, const MatType,MatReuse,Mat*)=PETSC_NULL;
3790: const char *prefix[3] = {"seq","mpi",""};
3791: PetscInt i;
3792: /*
3793: Order of precedence:
3794: 1) See if a specialized converter is known to the current matrix.
3795: 2) See if a specialized converter is known to the desired matrix class.
3796: 3) See if a good general converter is registered for the desired class
3797: (as of 6/27/03 only MATMPIADJ falls into this category).
3798: 4) See if a good general converter is known for the current matrix.
3799: 5) Use a really basic converter.
3800: */
3801:
3802: /* 1) See if a specialized converter is known to the current matrix and the desired class */
3803: for (i=0; i<3; i++) {
3804: PetscStrcpy(convname,"MatConvert_");
3805: PetscStrcat(convname,((PetscObject)mat)->type_name);
3806: PetscStrcat(convname,"_");
3807: PetscStrcat(convname,prefix[i]);
3808: PetscStrcat(convname,issame?((PetscObject)mat)->type_name:newtype);
3809: PetscStrcat(convname,"_C");
3810: PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);
3811: if (conv) goto foundconv;
3812: }
3814: /* 2) See if a specialized converter is known to the desired matrix class. */
3815: MatCreate(((PetscObject)mat)->comm,&B);
3816: MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);
3817: MatSetType(B,newtype);
3818: for (i=0; i<3; i++) {
3819: PetscStrcpy(convname,"MatConvert_");
3820: PetscStrcat(convname,((PetscObject)mat)->type_name);
3821: PetscStrcat(convname,"_");
3822: PetscStrcat(convname,prefix[i]);
3823: PetscStrcat(convname,newtype);
3824: PetscStrcat(convname,"_C");
3825: PetscObjectQueryFunction((PetscObject)B,convname,(void (**)(void))&conv);
3826: if (conv) {
3827: MatDestroy(&B);
3828: goto foundconv;
3829: }
3830: }
3832: /* 3) See if a good general converter is registered for the desired class */
3833: conv = B->ops->convertfrom;
3834: MatDestroy(&B);
3835: if (conv) goto foundconv;
3837: /* 4) See if a good general converter is known for the current matrix */
3838: if (mat->ops->convert) {
3839: conv = mat->ops->convert;
3840: }
3841: if (conv) goto foundconv;
3843: /* 5) Use a really basic converter. */
3844: conv = MatConvert_Basic;
3846: foundconv:
3847: PetscLogEventBegin(MAT_Convert,mat,0,0,0);
3848: (*conv)(mat,newtype,reuse,M);
3849: PetscLogEventEnd(MAT_Convert,mat,0,0,0);
3850: }
3851: PetscObjectStateIncrease((PetscObject)*M);
3853: /* Copy Mat options */
3854: if (mat->symmetric){MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);}
3855: if (mat->hermitian){MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);}
3856: return(0);
3857: }
3861: /*@C
3862: MatFactorGetSolverPackage - Returns name of the package providing the factorization routines
3864: Not Collective
3866: Input Parameter:
3867: . mat - the matrix, must be a factored matrix
3869: Output Parameter:
3870: . type - the string name of the package (do not free this string)
3872: Notes:
3873: In Fortran you pass in a empty string and the package name will be copied into it.
3874: (Make sure the string is long enough)
3876: Level: intermediate
3878: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
3879: @*/
3880: PetscErrorCode MatFactorGetSolverPackage(Mat mat, const MatSolverPackage *type)
3881: {
3882: PetscErrorCode ierr;
3883: PetscErrorCode (*conv)(Mat,const MatSolverPackage*);
3888: if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
3889: PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverPackage_C",(void (**)(void))&conv);
3890: if (!conv) {
3891: *type = MATSOLVERPETSC;
3892: } else {
3893: (*conv)(mat,type);
3894: }
3895: return(0);
3896: }
3900: /*@C
3901: MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic()
3903: Collective on Mat
3905: Input Parameters:
3906: + mat - the matrix
3907: . type - name of solver type, for example, spooles, superlu, plapack, petsc (to use PETSc's default)
3908: - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
3910: Output Parameters:
3911: . f - the factor matrix used with MatXXFactorSymbolic() calls
3913: Notes:
3914: Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
3915: such as pastix, superlu, mumps, spooles etc.
3917: PETSc must have been ./configure to use the external solver, using the option --download-package
3919: Level: intermediate
3921: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
3922: @*/
3923: PetscErrorCode MatGetFactor(Mat mat, const MatSolverPackage type,MatFactorType ftype,Mat *f)
3924: {
3925: PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
3926: char convname[256];
3932: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3933: MatPreallocated(mat);
3935: PetscStrcpy(convname,"MatGetFactor_");
3936: PetscStrcat(convname,type);
3937: PetscStrcat(convname,"_C");
3938: PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);
3939: if (!conv) {
3940: PetscBool flag;
3941: MPI_Comm comm;
3943: PetscObjectGetComm((PetscObject)mat,&comm);
3944: PetscStrcasecmp(MATSOLVERPETSC,type,&flag);
3945: if (flag) {
3946: SETERRQ2(comm,PETSC_ERR_SUP,"Matrix format %s does not have a built-in PETSc %s",((PetscObject)mat)->type_name,MatFactorTypes[ftype]);
3947: } else {
3948: SETERRQ4(comm,PETSC_ERR_SUP,"Matrix format %s does not have a solver package %s for %s. Perhaps you must ./configure with --download-%s",((PetscObject)mat)->type_name,type,MatFactorTypes[ftype],type);
3949: }
3950: }
3951: (*conv)(mat,ftype,f);
3952: return(0);
3953: }
3957: /*@C
3958: MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type
3960: Not Collective
3962: Input Parameters:
3963: + mat - the matrix
3964: . type - name of solver type, for example, spooles, superlu, plapack, petsc (to use PETSc's default)
3965: - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
3967: Output Parameter:
3968: . flg - PETSC_TRUE if the factorization is available
3970: Notes:
3971: Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
3972: such as pastix, superlu, mumps, spooles etc.
3974: PETSc must have been ./configure to use the external solver, using the option --download-package
3976: Level: intermediate
3978: .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
3979: @*/
3980: PetscErrorCode MatGetFactorAvailable(Mat mat, const MatSolverPackage type,MatFactorType ftype,PetscBool *flg)
3981: {
3982: PetscErrorCode ierr;
3983: char convname[256];
3984: PetscErrorCode (*conv)(Mat,MatFactorType,PetscBool *);
3990: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3991: MatPreallocated(mat);
3993: PetscStrcpy(convname,"MatGetFactorAvailable_");
3994: PetscStrcat(convname,type);
3995: PetscStrcat(convname,"_C");
3996: PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);
3997: if (!conv) {
3998: *flg = PETSC_FALSE;
3999: } else {
4000: (*conv)(mat,ftype,flg);
4001: }
4002: return(0);
4003: }
4008: /*@
4009: MatDuplicate - Duplicates a matrix including the non-zero structure.
4011: Collective on Mat
4013: Input Parameters:
4014: + mat - the matrix
4015: - op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy the numerical values in the matrix
4016: MAT_SHARE_NONZERO_PATTERN to share the nonzero patterns with the previous matrix and not copy them.
4018: Output Parameter:
4019: . M - pointer to place new matrix
4021: Level: intermediate
4023: Concepts: matrices^duplicating
4025: Notes: You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN.
4027: .seealso: MatCopy(), MatConvert()
4028: @*/
4029: PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4030: {
4032: Mat B;
4033: PetscInt i;
4039: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4040: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4041: MatPreallocated(mat);
4043: *M = 0;
4044: if (!mat->ops->duplicate) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Not written for this matrix type");
4045: PetscLogEventBegin(MAT_Convert,mat,0,0,0);
4046: (*mat->ops->duplicate)(mat,op,M);
4047: B = *M;
4048:
4049: B->stencil.dim = mat->stencil.dim;
4050: B->stencil.noc = mat->stencil.noc;
4051: for (i=0; i<=mat->stencil.dim; i++) {
4052: B->stencil.dims[i] = mat->stencil.dims[i];
4053: B->stencil.starts[i] = mat->stencil.starts[i];
4054: }
4056: B->nooffproczerorows = mat->nooffproczerorows;
4057: B->nooffprocentries = mat->nooffprocentries;
4058: PetscLogEventEnd(MAT_Convert,mat,0,0,0);
4059: PetscObjectStateIncrease((PetscObject)B);
4060: return(0);
4061: }
4065: /*@
4066: MatGetDiagonal - Gets the diagonal of a matrix.
4068: Logically Collective on Mat and Vec
4070: Input Parameters:
4071: + mat - the matrix
4072: - v - the vector for storing the diagonal
4074: Output Parameter:
4075: . v - the diagonal of the matrix
4077: Level: intermediate
4079: Concepts: matrices^accessing diagonals
4081: .seealso: MatGetRow(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs()
4082: @*/
4083: PetscErrorCode MatGetDiagonal(Mat mat,Vec v)
4084: {
4091: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4092: if (!mat->ops->getdiagonal) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4093: MatPreallocated(mat);
4095: (*mat->ops->getdiagonal)(mat,v);
4096: PetscObjectStateIncrease((PetscObject)v);
4097: return(0);
4098: }
4102: /*@
4103: MatGetRowMin - Gets the minimum value (of the real part) of each
4104: row of the matrix
4106: Logically Collective on Mat and Vec
4108: Input Parameters:
4109: . mat - the matrix
4111: Output Parameter:
4112: + v - the vector for storing the maximums
4113: - idx - the indices of the column found for each row (optional)
4115: Level: intermediate
4117: Notes: The result of this call are the same as if one converted the matrix to dense format
4118: and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4120: This code is only implemented for a couple of matrix formats.
4122: Concepts: matrices^getting row maximums
4124: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(),
4125: MatGetRowMax()
4126: @*/
4127: PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4128: {
4135: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4136: if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4137: MatPreallocated(mat);
4139: (*mat->ops->getrowmin)(mat,v,idx);
4140: PetscObjectStateIncrease((PetscObject)v);
4141: return(0);
4142: }
4146: /*@
4147: MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4148: row of the matrix
4150: Logically Collective on Mat and Vec
4152: Input Parameters:
4153: . mat - the matrix
4155: Output Parameter:
4156: + v - the vector for storing the minimums
4157: - idx - the indices of the column found for each row (optional)
4159: Level: intermediate
4161: Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
4162: row is 0 (the first column).
4164: This code is only implemented for a couple of matrix formats.
4166: Concepts: matrices^getting row maximums
4168: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4169: @*/
4170: PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4171: {
4178: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4179: if (!mat->ops->getrowminabs) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4180: MatPreallocated(mat);
4181: if (idx) {PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));}
4183: (*mat->ops->getrowminabs)(mat,v,idx);
4184: PetscObjectStateIncrease((PetscObject)v);
4185: return(0);
4186: }
4190: /*@
4191: MatGetRowMax - Gets the maximum value (of the real part) of each
4192: row of the matrix
4194: Logically Collective on Mat and Vec
4196: Input Parameters:
4197: . mat - the matrix
4199: Output Parameter:
4200: + v - the vector for storing the maximums
4201: - idx - the indices of the column found for each row (optional)
4203: Level: intermediate
4205: Notes: The result of this call are the same as if one converted the matrix to dense format
4206: and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4208: This code is only implemented for a couple of matrix formats.
4210: Concepts: matrices^getting row maximums
4212: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4213: @*/
4214: PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4215: {
4222: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4223: if (!mat->ops->getrowmax) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4224: MatPreallocated(mat);
4226: (*mat->ops->getrowmax)(mat,v,idx);
4227: PetscObjectStateIncrease((PetscObject)v);
4228: return(0);
4229: }
4233: /*@
4234: MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4235: row of the matrix
4237: Logically Collective on Mat and Vec
4239: Input Parameters:
4240: . mat - the matrix
4242: Output Parameter:
4243: + v - the vector for storing the maximums
4244: - idx - the indices of the column found for each row (optional)
4246: Level: intermediate
4248: Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
4249: row is 0 (the first column).
4251: This code is only implemented for a couple of matrix formats.
4253: Concepts: matrices^getting row maximums
4255: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4256: @*/
4257: PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4258: {
4265: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4266: if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4267: MatPreallocated(mat);
4268: if (idx) {PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));}
4270: (*mat->ops->getrowmaxabs)(mat,v,idx);
4271: PetscObjectStateIncrease((PetscObject)v);
4272: return(0);
4273: }
4277: /*@
4278: MatGetRowSum - Gets the sum of each row of the matrix
4280: Logically Collective on Mat and Vec
4282: Input Parameters:
4283: . mat - the matrix
4285: Output Parameter:
4286: . v - the vector for storing the sum of rows
4288: Level: intermediate
4290: Notes: This code is slow since it is not currently specialized for different formats
4292: Concepts: matrices^getting row sums
4294: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4295: @*/
4296: PetscErrorCode MatGetRowSum(Mat mat, Vec v)
4297: {
4298: PetscInt start = 0, end = 0, row;
4299: PetscScalar *array;
4306: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4307: MatPreallocated(mat);
4308: MatGetOwnershipRange(mat, &start, &end);
4309: VecGetArray(v, &array);
4310: for(row = start; row < end; ++row) {
4311: PetscInt ncols, col;
4312: const PetscInt *cols;
4313: const PetscScalar *vals;
4315: array[row - start] = 0.0;
4316: MatGetRow(mat, row, &ncols, &cols, &vals);
4317: for(col = 0; col < ncols; col++) {
4318: array[row - start] += vals[col];
4319: }
4320: MatRestoreRow(mat, row, &ncols, &cols, &vals);
4321: }
4322: VecRestoreArray(v, &array);
4323: PetscObjectStateIncrease((PetscObject) v);
4324: return(0);
4325: }
4329: /*@
4330: MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
4332: Collective on Mat
4334: Input Parameter:
4335: + mat - the matrix to transpose
4336: - reuse - store the transpose matrix in the provided B
4338: Output Parameters:
4339: . B - the transpose
4341: Notes:
4342: If you pass in &mat for B the transpose will be done in place, for example MatTranspose(mat,MAT_REUSE_MATRIX,&mat);
4344: Level: intermediate
4346: Concepts: matrices^transposing
4348: .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4349: @*/
4350: PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4351: {
4357: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4358: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4359: if (!mat->ops->transpose) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4360: MatPreallocated(mat);
4362: PetscLogEventBegin(MAT_Transpose,mat,0,0,0);
4363: (*mat->ops->transpose)(mat,reuse,B);
4364: PetscLogEventEnd(MAT_Transpose,mat,0,0,0);
4365: if (B) {PetscObjectStateIncrease((PetscObject)*B);}
4366: return(0);
4367: }
4371: /*@
4372: MatIsTranspose - Test whether a matrix is another one's transpose,
4373: or its own, in which case it tests symmetry.
4375: Collective on Mat
4377: Input Parameter:
4378: + A - the matrix to test
4379: - B - the matrix to test against, this can equal the first parameter
4381: Output Parameters:
4382: . flg - the result
4384: Notes:
4385: Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4386: has a running time of the order of the number of nonzeros; the parallel
4387: test involves parallel copies of the block-offdiagonal parts of the matrix.
4389: Level: intermediate
4391: Concepts: matrices^transposing, matrix^symmetry
4393: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4394: @*/
4395: PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg)
4396: {
4397: PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool *),(*g)(Mat,Mat,PetscReal,PetscBool *);
4403: PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",(void (**)(void))&f);
4404: PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",(void (**)(void))&g);
4405: *flg = PETSC_FALSE;
4406: if (f && g) {
4407: if (f == g) {
4408: (*f)(A,B,tol,flg);
4409: } else {
4410: SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4411: }
4412: } else {
4413: const MatType mattype;
4414: if (!f) {MatGetType(A,&mattype);}
4415: else {MatGetType(B,&mattype);}
4416: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
4417: }
4418: return(0);
4419: }
4423: /*@
4424: MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate.
4426: Collective on Mat
4428: Input Parameter:
4429: + mat - the matrix to transpose and complex conjugate
4430: - reuse - store the transpose matrix in the provided B
4432: Output Parameters:
4433: . B - the Hermitian
4435: Notes:
4436: If you pass in &mat for B the Hermitian will be done in place
4438: Level: intermediate
4440: Concepts: matrices^transposing, complex conjugatex
4442: .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4443: @*/
4444: PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
4445: {
4449: MatTranspose(mat,reuse,B);
4450: #if defined(PETSC_USE_COMPLEX)
4451: MatConjugate(*B);
4452: #endif
4453: return(0);
4454: }
4458: /*@
4459: MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,
4461: Collective on Mat
4463: Input Parameter:
4464: + A - the matrix to test
4465: - B - the matrix to test against, this can equal the first parameter
4467: Output Parameters:
4468: . flg - the result
4470: Notes:
4471: Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4472: has a running time of the order of the number of nonzeros; the parallel
4473: test involves parallel copies of the block-offdiagonal parts of the matrix.
4475: Level: intermediate
4477: Concepts: matrices^transposing, matrix^symmetry
4479: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
4480: @*/
4481: PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg)
4482: {
4483: PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool *),(*g)(Mat,Mat,PetscReal,PetscBool *);
4489: PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",(void (**)(void))&f);
4490: PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",(void (**)(void))&g);
4491: if (f && g) {
4492: if (f==g) {
4493: (*f)(A,B,tol,flg);
4494: } else {
4495: SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
4496: }
4497: }
4498: return(0);
4499: }
4503: /*@
4504: MatPermute - Creates a new matrix with rows and columns permuted from the
4505: original.
4507: Collective on Mat
4509: Input Parameters:
4510: + mat - the matrix to permute
4511: . row - row permutation, each processor supplies only the permutation for its rows
4512: - col - column permutation, each processor needs the entire column permutation, that is
4513: this is the same size as the total number of columns in the matrix. It can often
4514: be obtained with ISAllGather() on the row permutation
4516: Output Parameters:
4517: . B - the permuted matrix
4519: Level: advanced
4521: Concepts: matrices^permuting
4523: .seealso: MatGetOrdering(), ISAllGather()
4525: @*/
4526: PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
4527: {
4536: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4537: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4538: if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
4539: MatPreallocated(mat);
4541: (*mat->ops->permute)(mat,row,col,B);
4542: PetscObjectStateIncrease((PetscObject)*B);
4543: return(0);
4544: }
4548: /*@
4549: MatEqual - Compares two matrices.
4551: Collective on Mat
4553: Input Parameters:
4554: + A - the first matrix
4555: - B - the second matrix
4557: Output Parameter:
4558: . flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
4560: Level: intermediate
4562: Concepts: matrices^equality between
4563: @*/
4564: PetscErrorCode MatEqual(Mat A,Mat B,PetscBool *flg)
4565: {
4575: MatPreallocated(B);
4576: if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4577: if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4578: if (A->rmap->N != B->rmap->N || A->cmap->N != B->cmap->N) SETERRQ4(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %D %D %D %D",A->rmap->N,B->rmap->N,A->cmap->N,B->cmap->N);
4579: if (!A->ops->equal) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4580: if (!B->ops->equal) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4581: if (A->ops->equal != B->ops->equal) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_INCOMP,"A is type: %s\nB is type: %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
4582: MatPreallocated(A);
4584: (*A->ops->equal)(A,B,flg);
4585: return(0);
4586: }
4590: /*@
4591: MatDiagonalScale - Scales a matrix on the left and right by diagonal
4592: matrices that are stored as vectors. Either of the two scaling
4593: matrices can be PETSC_NULL.
4595: Collective on Mat
4597: Input Parameters:
4598: + mat - the matrix to be scaled
4599: . l - the left scaling vector (or PETSC_NULL)
4600: - r - the right scaling vector (or PETSC_NULL)
4602: Notes:
4603: MatDiagonalScale() computes A = LAR, where
4604: L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
4605: The L scales the rows of the matrix, the R scales the columns of the matrix.
4607: Level: intermediate
4609: Concepts: matrices^diagonal scaling
4610: Concepts: diagonal scaling of matrices
4612: .seealso: MatScale()
4613: @*/
4614: PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
4615: {
4621: if (!mat->ops->diagonalscale) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4624: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4625: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4626: MatPreallocated(mat);
4628: PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4629: (*mat->ops->diagonalscale)(mat,l,r);
4630: PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4631: PetscObjectStateIncrease((PetscObject)mat);
4632: #if defined(PETSC_HAVE_CUSP)
4633: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4634: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4635: }
4636: #endif
4637: return(0);
4638: }
4642: /*@
4643: MatScale - Scales all elements of a matrix by a given number.
4645: Logically Collective on Mat
4647: Input Parameters:
4648: + mat - the matrix to be scaled
4649: - a - the scaling value
4651: Output Parameter:
4652: . mat - the scaled matrix
4654: Level: intermediate
4656: Concepts: matrices^scaling all entries
4658: .seealso: MatDiagonalScale()
4659: @*/
4660: PetscErrorCode MatScale(Mat mat,PetscScalar a)
4661: {
4667: if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4668: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4669: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4671: MatPreallocated(mat);
4673: PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4674: if (a != (PetscScalar)1.0) {
4675: (*mat->ops->scale)(mat,a);
4676: PetscObjectStateIncrease((PetscObject)mat);
4677: }
4678: PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4679: #if defined(PETSC_HAVE_CUSP)
4680: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4681: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4682: }
4683: #endif
4684: return(0);
4685: }
4689: /*@
4690: MatNorm - Calculates various norms of a matrix.
4692: Collective on Mat
4694: Input Parameters:
4695: + mat - the matrix
4696: - type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
4698: Output Parameters:
4699: . nrm - the resulting norm
4701: Level: intermediate
4703: Concepts: matrices^norm
4704: Concepts: norm^of matrix
4705: @*/
4706: PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
4707: {
4715: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4716: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4717: if (!mat->ops->norm) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4718: MatPreallocated(mat);
4720: (*mat->ops->norm)(mat,type,nrm);
4721: return(0);
4722: }
4724: /*
4725: This variable is used to prevent counting of MatAssemblyBegin() that
4726: are called from within a MatAssemblyEnd().
4727: */
4728: static PetscInt MatAssemblyEnd_InUse = 0;
4731: /*@
4732: MatAssemblyBegin - Begins assembling the matrix. This routine should
4733: be called after completing all calls to MatSetValues().
4735: Collective on Mat
4737: Input Parameters:
4738: + mat - the matrix
4739: - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
4740:
4741: Notes:
4742: MatSetValues() generally caches the values. The matrix is ready to
4743: use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4744: Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4745: in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4746: using the matrix.
4748: Level: beginner
4750: Concepts: matrices^assembling
4752: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
4753: @*/
4754: PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
4755: {
4761: MatPreallocated(mat);
4762: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
4763: if (mat->assembled) {
4764: mat->was_assembled = PETSC_TRUE;
4765: mat->assembled = PETSC_FALSE;
4766: }
4767: if (!MatAssemblyEnd_InUse) {
4768: PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);
4769: if (mat->ops->assemblybegin){(*mat->ops->assemblybegin)(mat,type);}
4770: PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);
4771: } else {
4772: if (mat->ops->assemblybegin){(*mat->ops->assemblybegin)(mat,type);}
4773: }
4774: return(0);
4775: }
4779: /*@
4780: MatAssembled - Indicates if a matrix has been assembled and is ready for
4781: use; for example, in matrix-vector product.
4783: Not Collective
4785: Input Parameter:
4786: . mat - the matrix
4788: Output Parameter:
4789: . assembled - PETSC_TRUE or PETSC_FALSE
4791: Level: advanced
4793: Concepts: matrices^assembled?
4795: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
4796: @*/
4797: PetscErrorCode MatAssembled(Mat mat,PetscBool *assembled)
4798: {
4803: *assembled = mat->assembled;
4804: return(0);
4805: }
4809: /*
4810: Processes command line options to determine if/how a matrix
4811: is to be viewed. Called by MatAssemblyEnd() and MatLoad().
4812: */
4813: PetscErrorCode MatView_Private(Mat mat)
4814: {
4815: PetscErrorCode ierr;
4816: PetscBool flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE,flg4 = PETSC_FALSE,flg6 = PETSC_FALSE,flg7 = PETSC_FALSE,flg8 = PETSC_FALSE;
4817: static PetscBool incall = PETSC_FALSE;
4818: #if defined(PETSC_USE_SOCKET_VIEWER)
4819: PetscBool flg5 = PETSC_FALSE;
4820: #endif
4823: if (incall) return(0);
4824: incall = PETSC_TRUE;
4825: PetscObjectOptionsBegin((PetscObject)mat);
4826: PetscOptionsBool("-mat_view_info","Information on matrix size","MatView",flg1,&flg1,PETSC_NULL);
4827: PetscOptionsBool("-mat_view_info_detailed","Nonzeros in the matrix","MatView",flg2,&flg2,PETSC_NULL);
4828: PetscOptionsBool("-mat_view","Print matrix to stdout","MatView",flg3,&flg3,PETSC_NULL);
4829: PetscOptionsBool("-mat_view_matlab","Print matrix to stdout in a format Matlab can read","MatView",flg4,&flg4,PETSC_NULL);
4830: #if defined(PETSC_USE_SOCKET_VIEWER)
4831: PetscOptionsBool("-mat_view_socket","Send matrix to socket (can be read from matlab)","MatView",flg5,&flg5,PETSC_NULL);
4832: #endif
4833: PetscOptionsBool("-mat_view_binary","Save matrix to file in binary format","MatView",flg6,&flg6,PETSC_NULL);
4834: PetscOptionsBool("-mat_view_draw","Draw the matrix nonzero structure","MatView",flg7,&flg7,PETSC_NULL);
4835: PetscOptionsEnd();
4837: if (flg1) {
4838: PetscViewer viewer;
4840: PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4841: PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO);
4842: MatView(mat,viewer);
4843: PetscViewerPopFormat(viewer);
4844: }
4845: if (flg2) {
4846: PetscViewer viewer;
4848: PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4849: PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO_DETAIL);
4850: MatView(mat,viewer);
4851: PetscViewerPopFormat(viewer);
4852: }
4853: if (flg3) {
4854: PetscViewer viewer;
4856: PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4857: MatView(mat,viewer);
4858: }
4859: if (flg4) {
4860: PetscViewer viewer;
4862: PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4863: PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);
4864: MatView(mat,viewer);
4865: PetscViewerPopFormat(viewer);
4866: }
4867: #if defined(PETSC_USE_SOCKET_VIEWER)
4868: if (flg5) {
4869: MatView(mat,PETSC_VIEWER_SOCKET_(((PetscObject)mat)->comm));
4870: PetscViewerFlush(PETSC_VIEWER_SOCKET_(((PetscObject)mat)->comm));
4871: }
4872: #endif
4873: if (flg6) {
4874: MatView(mat,PETSC_VIEWER_BINARY_(((PetscObject)mat)->comm));
4875: PetscViewerFlush(PETSC_VIEWER_BINARY_(((PetscObject)mat)->comm));
4876: }
4877: if (flg7) {
4878: PetscOptionsGetBool(((PetscObject)mat)->prefix,"-mat_view_contour",&flg8,PETSC_NULL);
4879: if (flg8) {
4880: PetscViewerPushFormat(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm),PETSC_VIEWER_DRAW_CONTOUR);
4881: }
4882: MatView(mat,PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));
4883: PetscViewerFlush(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));
4884: if (flg8) {
4885: PetscViewerPopFormat(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));
4886: }
4887: }
4888: incall = PETSC_FALSE;
4889: return(0);
4890: }
4894: /*@
4895: MatAssemblyEnd - Completes assembling the matrix. This routine should
4896: be called after MatAssemblyBegin().
4898: Collective on Mat
4900: Input Parameters:
4901: + mat - the matrix
4902: - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
4904: Options Database Keys:
4905: + -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly()
4906: . -mat_view_info_detailed - Prints more detailed info
4907: . -mat_view - Prints matrix in ASCII format
4908: . -mat_view_matlab - Prints matrix in Matlab format
4909: . -mat_view_draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
4910: . -display <name> - Sets display name (default is host)
4911: . -draw_pause <sec> - Sets number of seconds to pause after display
4912: . -mat_view_socket - Sends matrix to socket, can be accessed from Matlab (See the <a href="../../docs/manual.pdf">users manual</a>)
4913: . -viewer_socket_machine <machine>
4914: . -viewer_socket_port <port>
4915: . -mat_view_binary - save matrix to file in binary format
4916: - -viewer_binary_filename <name>
4918: Notes:
4919: MatSetValues() generally caches the values. The matrix is ready to
4920: use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4921: Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4922: in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4923: using the matrix.
4925: Level: beginner
4927: .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), MatView(), MatAssembled(), PetscViewerSocketOpen()
4928: @*/
4929: PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
4930: {
4931: PetscErrorCode ierr;
4932: static PetscInt inassm = 0;
4933: PetscBool flg = PETSC_FALSE;
4939: inassm++;
4940: MatAssemblyEnd_InUse++;
4941: if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
4942: PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);
4943: if (mat->ops->assemblyend) {
4944: (*mat->ops->assemblyend)(mat,type);
4945: }
4946: PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);
4947: } else {
4948: if (mat->ops->assemblyend) {
4949: (*mat->ops->assemblyend)(mat,type);
4950: }
4951: }
4953: /* Flush assembly is not a true assembly */
4954: if (type != MAT_FLUSH_ASSEMBLY) {
4955: mat->assembled = PETSC_TRUE; mat->num_ass++;
4956: }
4957: mat->insertmode = NOT_SET_VALUES;
4958: MatAssemblyEnd_InUse--;
4959: PetscObjectStateIncrease((PetscObject)mat);
4960: if (!mat->symmetric_eternal) {
4961: mat->symmetric_set = PETSC_FALSE;
4962: mat->hermitian_set = PETSC_FALSE;
4963: mat->structurally_symmetric_set = PETSC_FALSE;
4964: }
4965: if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
4966: MatView_Private(mat);
4967: PetscOptionsGetBool(((PetscObject)mat)->prefix,"-mat_is_symmetric",&flg,PETSC_NULL);
4968: if (flg) {
4969: PetscReal tol = 0.0;
4970: PetscOptionsGetReal(((PetscObject)mat)->prefix,"-mat_is_symmetric",&tol,PETSC_NULL);
4971: MatIsSymmetric(mat,tol,&flg);
4972: if (flg) {
4973: PetscPrintf(((PetscObject)mat)->comm,"Matrix is symmetric (tolerance %G)\n",tol);
4974: } else {
4975: PetscPrintf(((PetscObject)mat)->comm,"Matrix is not symmetric (tolerance %G)\n",tol);
4976: }
4977: }
4978: }
4979: inassm--;
4980: #if defined(PETSC_HAVE_CUSP)
4981: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4982: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4983: }
4984: #endif
4985: return(0);
4986: }
4990: /*@
4991: MatSetOption - Sets a parameter option for a matrix. Some options
4992: may be specific to certain storage formats. Some options
4993: determine how values will be inserted (or added). Sorted,
4994: row-oriented input will generally assemble the fastest. The default
4995: is row-oriented, nonsorted input.
4997: Logically Collective on Mat
4999: Input Parameters:
5000: + mat - the matrix
5001: . option - the option, one of those listed below (and possibly others),
5002: - flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5004: Options Describing Matrix Structure:
5005: + MAT_SPD - symmetric positive definite
5006: - MAT_SYMMETRIC - symmetric in terms of both structure and value
5007: . MAT_HERMITIAN - transpose is the complex conjugation
5008: . MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5009: - MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5010: you set to be kept with all future use of the matrix
5011: including after MatAssemblyBegin/End() which could
5012: potentially change the symmetry structure, i.e. you
5013: KNOW the matrix will ALWAYS have the property you set.
5016: Options For Use with MatSetValues():
5017: Insert a logically dense subblock, which can be
5018: . MAT_ROW_ORIENTED - row-oriented (default)
5020: Note these options reflect the data you pass in with MatSetValues(); it has
5021: nothing to do with how the data is stored internally in the matrix
5022: data structure.
5024: When (re)assembling a matrix, we can restrict the input for
5025: efficiency/debugging purposes. These options include
5026: + MAT_NEW_NONZERO_LOCATIONS - additional insertions will be
5027: allowed if they generate a new nonzero
5028: . MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
5029: . MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
5030: . MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
5031: . MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
5032: + MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
5033: any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
5034: performance for very large process counts.
5036: Notes:
5037: Some options are relevant only for particular matrix types and
5038: are thus ignored by others. Other options are not supported by
5039: certain matrix types and will generate an error message if set.
5041: If using a Fortran 77 module to compute a matrix, one may need to
5042: use the column-oriented option (or convert to the row-oriented
5043: format).
5045: MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
5046: that would generate a new entry in the nonzero structure is instead
5047: ignored. Thus, if memory has not alredy been allocated for this particular
5048: data, then the insertion is ignored. For dense matrices, in which
5049: the entire array is allocated, no entries are ever ignored.
5050: Set after the first MatAssemblyEnd()
5052: MAT_NEW_NONZERO_LOCATION_ERR indicates that any add or insertion
5053: that would generate a new entry in the nonzero structure instead produces
5054: an error. (Currently supported for AIJ and BAIJ formats only.)
5055: This is a useful flag when using SAME_NONZERO_PATTERN in calling
5056: KSPSetOperators() to ensure that the nonzero pattern truely does
5057: remain unchanged. Set after the first MatAssemblyEnd()
5059: MAT_NEW_NONZERO_ALLOCATION_ERR indicates that any add or insertion
5060: that would generate a new entry that has not been preallocated will
5061: instead produce an error. (Currently supported for AIJ and BAIJ formats
5062: only.) This is a useful flag when debugging matrix memory preallocation.
5064: MAT_IGNORE_OFF_PROC_ENTRIES indicates entries destined for
5065: other processors should be dropped, rather than stashed.
5066: This is useful if you know that the "owning" processor is also
5067: always generating the correct matrix entries, so that PETSc need
5068: not transfer duplicate entries generated on another processor.
5069:
5070: MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5071: searches during matrix assembly. When this flag is set, the hash table
5072: is created during the first Matrix Assembly. This hash table is
5073: used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5074: to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5075: should be used with MAT_USE_HASH_TABLE flag. This option is currently
5076: supported by MATMPIBAIJ format only.
5078: MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries
5079: are kept in the nonzero structure
5081: MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
5082: a zero location in the matrix
5084: MAT_USE_INODES - indicates using inode version of the code - works with AIJ and
5085: ROWBS matrix types
5087: MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the
5088: zero row routines and thus improves performance for very large process counts.
5090: MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular
5091: part of the matrix (since they should match the upper triangular part).
5093: Level: intermediate
5095: Concepts: matrices^setting options
5097: @*/
5098: PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg)
5099: {
5108: if (((int) op) < 0 || ((int) op) >= NUM_MAT_OPTIONS) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Options %d is out of range",(int)op);
5109: if (!((PetscObject)mat)->type_name) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_TYPENOTSET,"Cannot set options until type and size have been set, see MatSetType() and MatSetSizes()");
5110: MatPreallocated(mat);
5111: switch (op) {
5112: case MAT_NO_OFF_PROC_ENTRIES:
5113: mat->nooffprocentries = flg;
5114: return(0);
5115: break;
5116: case MAT_NO_OFF_PROC_ZERO_ROWS:
5117: mat->nooffproczerorows = flg;
5118: return(0);
5119: break;
5120: case MAT_SPD:
5121: mat->spd_set = PETSC_TRUE;
5122: mat->spd = flg;
5123: if (flg) {
5124: mat->symmetric = PETSC_TRUE;
5125: mat->structurally_symmetric = PETSC_TRUE;
5126: mat->symmetric_set = PETSC_TRUE;
5127: mat->structurally_symmetric_set = PETSC_TRUE;
5128: }
5129: break;
5130: case MAT_SYMMETRIC:
5131: mat->symmetric = flg;
5132: if (flg) mat->structurally_symmetric = PETSC_TRUE;
5133: mat->symmetric_set = PETSC_TRUE;
5134: mat->structurally_symmetric_set = flg;
5135: break;
5136: case MAT_HERMITIAN:
5137: mat->hermitian = flg;
5138: if (flg) mat->structurally_symmetric = PETSC_TRUE;
5139: mat->hermitian_set = PETSC_TRUE;
5140: mat->structurally_symmetric_set = flg;
5141: break;
5142: case MAT_STRUCTURALLY_SYMMETRIC:
5143: mat->structurally_symmetric = flg;
5144: mat->structurally_symmetric_set = PETSC_TRUE;
5145: break;
5146: case MAT_SYMMETRY_ETERNAL:
5147: mat->symmetric_eternal = flg;
5148: break;
5149: default:
5150: break;
5151: }
5152: if (mat->ops->setoption) {
5153: (*mat->ops->setoption)(mat,op,flg);
5154: }
5155: return(0);
5156: }
5160: /*@
5161: MatZeroEntries - Zeros all entries of a matrix. For sparse matrices
5162: this routine retains the old nonzero structure.
5164: Logically Collective on Mat
5166: Input Parameters:
5167: . mat - the matrix
5169: Level: intermediate
5171: Notes: If the matrix was not preallocated then a default, likely poor preallocation will be set in the matrix, so this should be called after the preallocation phase.
5172: See the Performance chapter of the users manual for information on preallocating matrices.
5174: Concepts: matrices^zeroing
5176: .seealso: MatZeroRows()
5177: @*/
5178: PetscErrorCode MatZeroEntries(Mat mat)
5179: {
5185: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5186: if (mat->insertmode != NOT_SET_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for matrices where you have set values but not yet assembled");
5187: if (!mat->ops->zeroentries) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5188: MatPreallocated(mat);
5190: PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);
5191: (*mat->ops->zeroentries)(mat);
5192: PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);
5193: PetscObjectStateIncrease((PetscObject)mat);
5194: #if defined(PETSC_HAVE_CUSP)
5195: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5196: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5197: }
5198: #endif
5199: return(0);
5200: }
5204: /*@C
5205: MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal)
5206: of a set of rows and columns of a matrix.
5208: Collective on Mat
5210: Input Parameters:
5211: + mat - the matrix
5212: . numRows - the number of rows to remove
5213: . rows - the global row indices
5214: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5215: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5216: - b - optional vector of right hand side, that will be adjusted by provided solution
5218: Notes:
5219: This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5221: The user can set a value in the diagonal entry (or for the AIJ and
5222: row formats can optionally remove the main diagonal entry from the
5223: nonzero structure as well, by passing 0.0 as the final argument).
5225: For the parallel case, all processes that share the matrix (i.e.,
5226: those in the communicator used for matrix creation) MUST call this
5227: routine, regardless of whether any rows being zeroed are owned by
5228: them.
5230: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5231: list only rows local to itself).
5233: The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5235: Level: intermediate
5237: Concepts: matrices^zeroing rows
5239: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumnsIS()
5240: @*/
5241: PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5242: {
5249: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5250: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5251: if (!mat->ops->zerorowscolumns) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5252: MatPreallocated(mat);
5254: (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);
5255: MatView_Private(mat);
5256: PetscObjectStateIncrease((PetscObject)mat);
5257: #if defined(PETSC_HAVE_CUSP)
5258: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5259: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5260: }
5261: #endif
5262: return(0);
5263: }
5267: /*@C
5268: MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
5269: of a set of rows and columns of a matrix.
5271: Collective on Mat
5273: Input Parameters:
5274: + mat - the matrix
5275: . is - the rows to zero
5276: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5277: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5278: - b - optional vector of right hand side, that will be adjusted by provided solution
5280: Notes:
5281: This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5283: The user can set a value in the diagonal entry (or for the AIJ and
5284: row formats can optionally remove the main diagonal entry from the
5285: nonzero structure as well, by passing 0.0 as the final argument).
5287: For the parallel case, all processes that share the matrix (i.e.,
5288: those in the communicator used for matrix creation) MUST call this
5289: routine, regardless of whether any rows being zeroed are owned by
5290: them.
5292: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5293: list only rows local to itself).
5295: The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5297: Level: intermediate
5299: Concepts: matrices^zeroing rows
5301: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumns()
5302: @*/
5303: PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5304: {
5306: PetscInt numRows;
5307: const PetscInt *rows;
5314: ISGetLocalSize(is,&numRows);
5315: ISGetIndices(is,&rows);
5316: MatZeroRowsColumns(mat,numRows,rows,diag,x,b);
5317: ISRestoreIndices(is,&rows);
5318: return(0);
5319: }
5323: /*@C
5324: MatZeroRows - Zeros all entries (except possibly the main diagonal)
5325: of a set of rows of a matrix.
5327: Collective on Mat
5329: Input Parameters:
5330: + mat - the matrix
5331: . numRows - the number of rows to remove
5332: . rows - the global row indices
5333: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5334: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5335: - b - optional vector of right hand side, that will be adjusted by provided solution
5337: Notes:
5338: For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5339: but does not release memory. For the dense and block diagonal
5340: formats this does not alter the nonzero structure.
5342: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5343: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5344: merely zeroed.
5346: The user can set a value in the diagonal entry (or for the AIJ and
5347: row formats can optionally remove the main diagonal entry from the
5348: nonzero structure as well, by passing 0.0 as the final argument).
5350: For the parallel case, all processes that share the matrix (i.e.,
5351: those in the communicator used for matrix creation) MUST call this
5352: routine, regardless of whether any rows being zeroed are owned by
5353: them.
5355: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5356: list only rows local to itself).
5358: You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5359: owns that are to be zeroed. This saves a global synchronization in the implementation.
5361: Level: intermediate
5363: Concepts: matrices^zeroing rows
5365: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5366: @*/
5367: PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5368: {
5375: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5376: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5377: if (!mat->ops->zerorows) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5378: MatPreallocated(mat);
5380: (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);
5381: MatView_Private(mat);
5382: PetscObjectStateIncrease((PetscObject)mat);
5383: #if defined(PETSC_HAVE_CUSP)
5384: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5385: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5386: }
5387: #endif
5388: return(0);
5389: }
5393: /*@C
5394: MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5395: of a set of rows of a matrix.
5397: Collective on Mat
5399: Input Parameters:
5400: + mat - the matrix
5401: . is - index set of rows to remove
5402: . diag - value put in all diagonals of eliminated rows
5403: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5404: - b - optional vector of right hand side, that will be adjusted by provided solution
5406: Notes:
5407: For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5408: but does not release memory. For the dense and block diagonal
5409: formats this does not alter the nonzero structure.
5411: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5412: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5413: merely zeroed.
5415: The user can set a value in the diagonal entry (or for the AIJ and
5416: row formats can optionally remove the main diagonal entry from the
5417: nonzero structure as well, by passing 0.0 as the final argument).
5419: For the parallel case, all processes that share the matrix (i.e.,
5420: those in the communicator used for matrix creation) MUST call this
5421: routine, regardless of whether any rows being zeroed are owned by
5422: them.
5424: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5425: list only rows local to itself).
5427: You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5428: owns that are to be zeroed. This saves a global synchronization in the implementation.
5430: Level: intermediate
5432: Concepts: matrices^zeroing rows
5434: .seealso: MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5435: @*/
5436: PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5437: {
5438: PetscInt numRows;
5439: const PetscInt *rows;
5446: ISGetLocalSize(is,&numRows);
5447: ISGetIndices(is,&rows);
5448: MatZeroRows(mat,numRows,rows,diag,x,b);
5449: ISRestoreIndices(is,&rows);
5450: return(0);
5451: }
5455: /*@C
5456: MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
5457: of a set of rows of a matrix. These rows must be local to the process.
5459: Collective on Mat
5461: Input Parameters:
5462: + mat - the matrix
5463: . numRows - the number of rows to remove
5464: . rows - the grid coordinates (and component number when dof > 1) for matrix rows
5465: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5466: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5467: - b - optional vector of right hand side, that will be adjusted by provided solution
5469: Notes:
5470: For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5471: but does not release memory. For the dense and block diagonal
5472: formats this does not alter the nonzero structure.
5474: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5475: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5476: merely zeroed.
5478: The user can set a value in the diagonal entry (or for the AIJ and
5479: row formats can optionally remove the main diagonal entry from the
5480: nonzero structure as well, by passing 0.0 as the final argument).
5482: For the parallel case, all processes that share the matrix (i.e.,
5483: those in the communicator used for matrix creation) MUST call this
5484: routine, regardless of whether any rows being zeroed are owned by
5485: them.
5487: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5488: list only rows local to itself).
5490: The grid coordinates are across the entire grid, not just the local portion
5492: In Fortran idxm and idxn should be declared as
5493: $ MatStencil idxm(4,m)
5494: and the values inserted using
5495: $ idxm(MatStencil_i,1) = i
5496: $ idxm(MatStencil_j,1) = j
5497: $ idxm(MatStencil_k,1) = k
5498: $ idxm(MatStencil_c,1) = c
5499: etc
5501: For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5502: obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5503: etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5504: DMDA_BOUNDARY_PERIODIC boundary type.
5506: 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
5507: a single value per point) you can skip filling those indices.
5509: Level: intermediate
5511: Concepts: matrices^zeroing rows
5513: .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5514: @*/
5515: PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5516: {
5517: PetscInt dim = mat->stencil.dim;
5518: PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc);
5519: PetscInt *dims = mat->stencil.dims+1;
5520: PetscInt *starts = mat->stencil.starts;
5521: PetscInt *dxm = (PetscInt *) rows;
5522: PetscInt *jdxm, i, j, tmp, numNewRows = 0;
5530: PetscMalloc(numRows*sizeof(PetscInt), &jdxm);
5531: for(i = 0; i < numRows; ++i) {
5532: /* Skip unused dimensions (they are ordered k, j, i, c) */
5533: for(j = 0; j < 3-sdim; ++j) dxm++;
5534: /* Local index in X dir */
5535: tmp = *dxm++ - starts[0];
5536: /* Loop over remaining dimensions */
5537: for(j = 0; j < dim-1; ++j) {
5538: /* If nonlocal, set index to be negative */
5539: if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5540: /* Update local index */
5541: else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5542: }
5543: /* Skip component slot if necessary */
5544: if (mat->stencil.noc) dxm++;
5545: /* Local row number */
5546: if (tmp >= 0) {
5547: jdxm[numNewRows++] = tmp;
5548: }
5549: }
5550: MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);
5551: PetscFree(jdxm);
5552: return(0);
5553: }
5557: /*@C
5558: MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
5559: of a set of rows of a matrix; using local numbering of rows.
5561: Collective on Mat
5563: Input Parameters:
5564: + mat - the matrix
5565: . numRows - the number of rows to remove
5566: . rows - the global row indices
5567: . diag - value put in all diagonals of eliminated rows
5568: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5569: - b - optional vector of right hand side, that will be adjusted by provided solution
5571: Notes:
5572: Before calling MatZeroRowsLocal(), the user must first set the
5573: local-to-global mapping by calling MatSetLocalToGlobalMapping().
5575: For the AIJ matrix formats this removes the old nonzero structure,
5576: but does not release memory. For the dense and block diagonal
5577: formats this does not alter the nonzero structure.
5579: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5580: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5581: merely zeroed.
5583: The user can set a value in the diagonal entry (or for the AIJ and
5584: row formats can optionally remove the main diagonal entry from the
5585: nonzero structure as well, by passing 0.0 as the final argument).
5587: You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5588: owns that are to be zeroed. This saves a global synchronization in the implementation.
5590: Level: intermediate
5592: Concepts: matrices^zeroing
5594: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5595: @*/
5596: PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5597: {
5599: PetscMPIInt size;
5605: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5606: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5607: MatPreallocated(mat);
5609: MPI_Comm_size(((PetscObject)mat)->comm,&size);
5610: if (mat->ops->zerorowslocal) {
5611: (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);
5612: } else if (size == 1) {
5613: (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);
5614: } else {
5615: IS is, newis;
5616: const PetscInt *newRows;
5618: if (!mat->rmap->mapping) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5619: ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
5620: ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);
5621: ISGetIndices(newis,&newRows);
5622: (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);
5623: ISRestoreIndices(newis,&newRows);
5624: ISDestroy(&newis);
5625: ISDestroy(&is);
5626: }
5627: PetscObjectStateIncrease((PetscObject)mat);
5628: #if defined(PETSC_HAVE_CUSP)
5629: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5630: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5631: }
5632: #endif
5633: return(0);
5634: }
5638: /*@C
5639: MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
5640: of a set of rows of a matrix; using local numbering of rows.
5642: Collective on Mat
5644: Input Parameters:
5645: + mat - the matrix
5646: . is - index set of rows to remove
5647: . diag - value put in all diagonals of eliminated rows
5648: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5649: - b - optional vector of right hand side, that will be adjusted by provided solution
5651: Notes:
5652: Before calling MatZeroRowsLocalIS(), the user must first set the
5653: local-to-global mapping by calling MatSetLocalToGlobalMapping().
5655: For the AIJ matrix formats this removes the old nonzero structure,
5656: but does not release memory. For the dense and block diagonal
5657: formats this does not alter the nonzero structure.
5659: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5660: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5661: merely zeroed.
5663: The user can set a value in the diagonal entry (or for the AIJ and
5664: row formats can optionally remove the main diagonal entry from the
5665: nonzero structure as well, by passing 0.0 as the final argument).
5667: You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5668: owns that are to be zeroed. This saves a global synchronization in the implementation.
5670: Level: intermediate
5672: Concepts: matrices^zeroing
5674: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5675: @*/
5676: PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5677: {
5679: PetscInt numRows;
5680: const PetscInt *rows;
5686: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5687: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5688: MatPreallocated(mat);
5690: ISGetLocalSize(is,&numRows);
5691: ISGetIndices(is,&rows);
5692: MatZeroRowsLocal(mat,numRows,rows,diag,x,b);
5693: ISRestoreIndices(is,&rows);
5694: return(0);
5695: }
5699: /*@C
5700: MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
5701: of a set of rows and columns of a matrix; using local numbering of rows.
5703: Collective on Mat
5705: Input Parameters:
5706: + mat - the matrix
5707: . numRows - the number of rows to remove
5708: . rows - the global row indices
5709: . diag - value put in all diagonals of eliminated rows
5710: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5711: - b - optional vector of right hand side, that will be adjusted by provided solution
5713: Notes:
5714: Before calling MatZeroRowsColumnsLocal(), the user must first set the
5715: local-to-global mapping by calling MatSetLocalToGlobalMapping().
5717: The user can set a value in the diagonal entry (or for the AIJ and
5718: row formats can optionally remove the main diagonal entry from the
5719: nonzero structure as well, by passing 0.0 as the final argument).
5721: Level: intermediate
5723: Concepts: matrices^zeroing
5725: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5726: @*/
5727: PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5728: {
5730: PetscMPIInt size;
5736: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5737: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5738: MatPreallocated(mat);
5740: MPI_Comm_size(((PetscObject)mat)->comm,&size);
5741: if (size == 1) {
5742: (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);
5743: } else {
5744: IS is, newis;
5745: const PetscInt *newRows;
5747: if (!mat->cmap->mapping) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5748: ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
5749: ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);
5750: ISGetIndices(newis,&newRows);
5751: (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);
5752: ISRestoreIndices(newis,&newRows);
5753: ISDestroy(&newis);
5754: ISDestroy(&is);
5755: }
5756: PetscObjectStateIncrease((PetscObject)mat);
5757: #if defined(PETSC_HAVE_CUSP)
5758: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5759: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5760: }
5761: #endif
5762: return(0);
5763: }
5767: /*@C
5768: MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
5769: of a set of rows and columns of a matrix; using local numbering of rows.
5771: Collective on Mat
5773: Input Parameters:
5774: + mat - the matrix
5775: . is - index set of rows to remove
5776: . diag - value put in all diagonals of eliminated rows
5777: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5778: - b - optional vector of right hand side, that will be adjusted by provided solution
5780: Notes:
5781: Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
5782: local-to-global mapping by calling MatSetLocalToGlobalMapping().
5784: The user can set a value in the diagonal entry (or for the AIJ and
5785: row formats can optionally remove the main diagonal entry from the
5786: nonzero structure as well, by passing 0.0 as the final argument).
5788: Level: intermediate
5790: Concepts: matrices^zeroing
5792: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5793: @*/
5794: PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5795: {
5797: PetscInt numRows;
5798: const PetscInt *rows;
5804: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5805: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5806: MatPreallocated(mat);
5808: ISGetLocalSize(is,&numRows);
5809: ISGetIndices(is,&rows);
5810: MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);
5811: ISRestoreIndices(is,&rows);
5812: return(0);
5813: }
5817: /*@
5818: MatGetSize - Returns the numbers of rows and columns in a matrix.
5820: Not Collective
5822: Input Parameter:
5823: . mat - the matrix
5825: Output Parameters:
5826: + m - the number of global rows
5827: - n - the number of global columns
5829: Note: both output parameters can be PETSC_NULL on input.
5831: Level: beginner
5833: Concepts: matrices^size
5835: .seealso: MatGetLocalSize()
5836: @*/
5837: PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt* n)
5838: {
5841: if (m) *m = mat->rmap->N;
5842: if (n) *n = mat->cmap->N;
5843: return(0);
5844: }
5848: /*@
5849: MatGetLocalSize - Returns the number of rows and columns in a matrix
5850: stored locally. This information may be implementation dependent, so
5851: use with care.
5853: Not Collective
5855: Input Parameters:
5856: . mat - the matrix
5858: Output Parameters:
5859: + m - the number of local rows
5860: - n - the number of local columns
5862: Note: both output parameters can be PETSC_NULL on input.
5864: Level: beginner
5866: Concepts: matrices^local size
5868: .seealso: MatGetSize()
5869: @*/
5870: PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt* n)
5871: {
5876: if (m) *m = mat->rmap->n;
5877: if (n) *n = mat->cmap->n;
5878: return(0);
5879: }
5883: /*@
5884: MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
5885: this processor. (The columns of the "diagonal block")
5887: Not Collective, unless matrix has not been allocated, then collective on Mat
5889: Input Parameters:
5890: . mat - the matrix
5892: Output Parameters:
5893: + m - the global index of the first local column
5894: - n - one more than the global index of the last local column
5896: Notes: both output parameters can be PETSC_NULL on input.
5898: Level: developer
5900: Concepts: matrices^column ownership
5902: .seealso: MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
5904: @*/
5905: PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt* n)
5906: {
5914: MatPreallocated(mat);
5915: if (m) *m = mat->cmap->rstart;
5916: if (n) *n = mat->cmap->rend;
5917: return(0);
5918: }
5922: /*@
5923: MatGetOwnershipRange - Returns the range of matrix rows owned by
5924: this processor, assuming that the matrix is laid out with the first
5925: n1 rows on the first processor, the next n2 rows on the second, etc.
5926: For certain parallel layouts this range may not be well defined.
5928: Not Collective, unless matrix has not been allocated, then collective on Mat
5930: Input Parameters:
5931: . mat - the matrix
5933: Output Parameters:
5934: + m - the global index of the first local row
5935: - n - one more than the global index of the last local row
5937: Note: both output parameters can be PETSC_NULL on input.
5939: Level: beginner
5941: Concepts: matrices^row ownership
5943: .seealso: MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
5945: @*/
5946: PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt* n)
5947: {
5955: MatPreallocated(mat);
5956: if (m) *m = mat->rmap->rstart;
5957: if (n) *n = mat->rmap->rend;
5958: return(0);
5959: }
5963: /*@C
5964: MatGetOwnershipRanges - Returns the range of matrix rows owned by
5965: each process
5967: Not Collective, unless matrix has not been allocated, then collective on Mat
5969: Input Parameters:
5970: . mat - the matrix
5972: Output Parameters:
5973: . ranges - start of each processors portion plus one more then the total length at the end
5975: Level: beginner
5977: Concepts: matrices^row ownership
5979: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
5981: @*/
5982: PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
5983: {
5989: MatPreallocated(mat);
5990: PetscLayoutGetRanges(mat->rmap,ranges);
5991: return(0);
5992: }
5996: /*@C
5997: MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
5998: this processor. (The columns of the "diagonal blocks" for each process)
6000: Not Collective, unless matrix has not been allocated, then collective on Mat
6002: Input Parameters:
6003: . mat - the matrix
6005: Output Parameters:
6006: . ranges - start of each processors portion plus one more then the total length at the end
6008: Level: beginner
6010: Concepts: matrices^column ownership
6012: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
6014: @*/
6015: PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6016: {
6022: MatPreallocated(mat);
6023: PetscLayoutGetRanges(mat->cmap,ranges);
6024: return(0);
6025: }
6029: /*@C
6030: MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6031: Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6032: to complete the factorization.
6034: Collective on Mat
6036: Input Parameters:
6037: + mat - the matrix
6038: . row - row permutation
6039: . column - column permutation
6040: - info - structure containing
6041: $ levels - number of levels of fill.
6042: $ expected fill - as ratio of original fill.
6043: $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6044: missing diagonal entries)
6046: Output Parameters:
6047: . fact - new matrix that has been symbolically factored
6049: Notes:
6050: See the <a href="../../docs/manual.pdf">users manual</a> for additional information about
6051: choosing the fill factor for better efficiency.
6053: Most users should employ the simplified KSP interface for linear solvers
6054: instead of working directly with matrix algebra routines such as this.
6055: See, e.g., KSPCreate().
6057: Level: developer
6059: Concepts: matrices^symbolic LU factorization
6060: Concepts: matrices^factorization
6061: Concepts: LU^symbolic factorization
6063: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6064: MatGetOrdering(), MatFactorInfo
6066: Developer Note: fortran interface is not autogenerated as the f90
6067: interface defintion cannot be generated correctly [due to MatFactorInfo]
6069: @*/
6070: PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6071: {
6081: if (info->levels < 0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6082: if (info->fill < 1.0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
6083: if (!(fact)->ops->ilufactorsymbolic) {
6084: const MatSolverPackage spackage;
6085: MatFactorGetSolverPackage(fact,&spackage);
6086: SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6087: }
6088: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6089: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6090: MatPreallocated(mat);
6092: PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);
6093: (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);
6094: PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);
6095: return(0);
6096: }
6100: /*@C
6101: MatICCFactorSymbolic - Performs symbolic incomplete
6102: Cholesky factorization for a symmetric matrix. Use
6103: MatCholeskyFactorNumeric() to complete the factorization.
6105: Collective on Mat
6107: Input Parameters:
6108: + mat - the matrix
6109: . perm - row and column permutation
6110: - info - structure containing
6111: $ levels - number of levels of fill.
6112: $ expected fill - as ratio of original fill.
6114: Output Parameter:
6115: . fact - the factored matrix
6117: Notes:
6118: Most users should employ the KSP interface for linear solvers
6119: instead of working directly with matrix algebra routines such as this.
6120: See, e.g., KSPCreate().
6122: Level: developer
6124: Concepts: matrices^symbolic incomplete Cholesky factorization
6125: Concepts: matrices^factorization
6126: Concepts: Cholsky^symbolic factorization
6128: .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
6130: Developer Note: fortran interface is not autogenerated as the f90
6131: interface defintion cannot be generated correctly [due to MatFactorInfo]
6133: @*/
6134: PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6135: {
6144: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6145: if (info->levels < 0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6146: if (info->fill < 1.0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
6147: if (!(fact)->ops->iccfactorsymbolic) {
6148: const MatSolverPackage spackage;
6149: MatFactorGetSolverPackage(fact,&spackage);
6150: SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6151: }
6152: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6153: MatPreallocated(mat);
6155: PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);
6156: (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);
6157: PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);
6158: return(0);
6159: }
6163: /*@C
6164: MatGetArray - Returns a pointer to the element values in the matrix.
6165: The result of this routine is dependent on the underlying matrix data
6166: structure, and may not even work for certain matrix types. You MUST
6167: call MatRestoreArray() when you no longer need to access the array.
6169: Not Collective
6171: Input Parameter:
6172: . mat - the matrix
6174: Output Parameter:
6175: . v - the location of the values
6178: Fortran Note:
6179: This routine is used differently from Fortran, e.g.,
6180: .vb
6181: Mat mat
6182: PetscScalar mat_array(1)
6183: PetscOffset i_mat
6184: PetscErrorCode ierr
6185: call MatGetArray(mat,mat_array,i_mat,ierr)
6187: C Access first local entry in matrix; note that array is
6188: C treated as one dimensional
6189: value = mat_array(i_mat + 1)
6191: [... other code ...]
6192: call MatRestoreArray(mat,mat_array,i_mat,ierr)
6193: .ve
6195: See the <a href="../../docs/manual.pdf#Chapter 10 PETSc for Fortran Users">Fortran chapter of the users manual</a> and
6196: src/mat/examples/tests for details.
6198: Level: advanced
6200: Concepts: matrices^access array
6202: .seealso: MatRestoreArray(), MatGetArrayF90(), MatGetRowIJ()
6203: @*/
6204: PetscErrorCode MatGetArray(Mat mat,PetscScalar *v[])
6205: {
6212: if (!mat->ops->getarray) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6213: MatPreallocated(mat);
6214: (*mat->ops->getarray)(mat,v);
6215: CHKMEMQ;
6216: return(0);
6217: }
6221: /*@C
6222: MatRestoreArray - Restores the matrix after MatGetArray() has been called.
6224: Not Collective
6226: Input Parameter:
6227: + mat - the matrix
6228: - v - the location of the values
6230: Fortran Note:
6231: This routine is used differently from Fortran, e.g.,
6232: .vb
6233: Mat mat
6234: PetscScalar mat_array(1)
6235: PetscOffset i_mat
6236: PetscErrorCode ierr
6237: call MatGetArray(mat,mat_array,i_mat,ierr)
6239: C Access first local entry in matrix; note that array is
6240: C treated as one dimensional
6241: value = mat_array(i_mat + 1)
6243: [... other code ...]
6244: call MatRestoreArray(mat,mat_array,i_mat,ierr)
6245: .ve
6247: See the <a href="../../docs/manual.pdf#Chapter 10 PETSc for Fortran Users">Fortran chapter of the users manual</a>
6248: src/mat/examples/tests for details
6250: Level: advanced
6252: .seealso: MatGetArray(), MatRestoreArrayF90()
6253: @*/
6254: PetscErrorCode MatRestoreArray(Mat mat,PetscScalar *v[])
6255: {
6262: CHKMEMQ;
6263: if (!mat->ops->restorearray) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6264: (*mat->ops->restorearray)(mat,v);
6265: PetscObjectStateIncrease((PetscObject)mat);
6266: #if defined(PETSC_HAVE_CUSP)
6267: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
6268: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
6269: }
6270: #endif
6271: return(0);
6272: }
6276: /*@C
6277: MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
6278: points to an array of valid matrices, they may be reused to store the new
6279: submatrices.
6281: Collective on Mat
6283: Input Parameters:
6284: + mat - the matrix
6285: . n - the number of submatrixes to be extracted (on this processor, may be zero)
6286: . irow, icol - index sets of rows and columns to extract
6287: - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6289: Output Parameter:
6290: . submat - the array of submatrices
6292: Notes:
6293: MatGetSubMatrices() can extract ONLY sequential submatrices
6294: (from both sequential and parallel matrices). Use MatGetSubMatrix()
6295: to extract a parallel submatrix.
6297: When extracting submatrices from a parallel matrix, each processor can
6298: form a different submatrix by setting the rows and columns of its
6299: individual index sets according to the local submatrix desired.
6301: When finished using the submatrices, the user should destroy
6302: them with MatDestroyMatrices().
6304: MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6305: original matrix has not changed from that last call to MatGetSubMatrices().
6307: This routine creates the matrices in submat; you should NOT create them before
6308: calling it. It also allocates the array of matrix pointers submat.
6310: For BAIJ matrices the index sets must respect the block structure, that is if they
6311: request one row/column in a block, they must request all rows/columns that are in
6312: that block. For example, if the block size is 2 you cannot request just row 0 and
6313: column 0.
6315: Fortran Note:
6316: The Fortran interface is slightly different from that given below; it
6317: requires one to pass in as submat a Mat (integer) array of size at least m.
6319: Level: advanced
6321: Concepts: matrices^accessing submatrices
6322: Concepts: submatrices
6324: .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6325: @*/
6326: PetscErrorCode MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6327: {
6329: PetscInt i;
6330: PetscBool eq;
6335: if (n) {
6340: }
6342: if (n && scall == MAT_REUSE_MATRIX) {
6345: }
6346: if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6347: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6348: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6349: MatPreallocated(mat);
6351: PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6352: (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);
6353: PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6354: for (i=0; i<n; i++) {
6355: if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6356: ISEqual(irow[i],icol[i],&eq);
6357: if (eq) {
6358: if (mat->symmetric){
6359: MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6360: } else if (mat->hermitian) {
6361: MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6362: } else if (mat->structurally_symmetric) {
6363: MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6364: }
6365: }
6366: }
6367: }
6368: return(0);
6369: }
6373: PetscErrorCode MatGetSubMatricesParallel(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6374: {
6376: PetscInt i;
6377: PetscBool eq;
6382: if (n) {
6387: }
6389: if (n && scall == MAT_REUSE_MATRIX) {
6392: }
6393: if (!mat->ops->getsubmatricesparallel) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6394: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6395: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6396: MatPreallocated(mat);
6398: PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6399: (*mat->ops->getsubmatricesparallel)(mat,n,irow,icol,scall,submat);
6400: PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6401: for (i=0; i<n; i++) {
6402: if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6403: ISEqual(irow[i],icol[i],&eq);
6404: if (eq) {
6405: if (mat->symmetric){
6406: MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6407: } else if (mat->hermitian) {
6408: MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6409: } else if (mat->structurally_symmetric) {
6410: MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6411: }
6412: }
6413: }
6414: }
6415: return(0);
6416: }
6420: /*@C
6421: MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().
6423: Collective on Mat
6425: Input Parameters:
6426: + n - the number of local matrices
6427: - mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6428: sequence of MatGetSubMatrices())
6430: Level: advanced
6432: Notes: Frees not only the matrices, but also the array that contains the matrices
6433: In Fortran will not free the array.
6435: .seealso: MatGetSubMatrices()
6436: @*/
6437: PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
6438: {
6440: PetscInt i;
6443: if (!*mat) return(0);
6444: if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6446: for (i=0; i<n; i++) {
6447: MatDestroy(&(*mat)[i]);
6448: }
6449: /* memory is allocated even if n = 0 */
6450: PetscFree(*mat);
6451: *mat = PETSC_NULL;
6452: return(0);
6453: }
6457: /*@C
6458: MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
6460: Collective on Mat
6462: Input Parameters:
6463: . mat - the matrix
6465: Output Parameter:
6466: . matstruct - the sequential matrix with the nonzero structure of mat
6468: Level: intermediate
6470: .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
6471: @*/
6472: PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6473: {
6479:
6481: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6482: MatPreallocated(mat);
6484: if (!mat->ops->getseqnonzerostructure) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6485: PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6486: (*mat->ops->getseqnonzerostructure)(mat,matstruct);
6487: PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6488: return(0);
6489: }
6493: /*@C
6494: MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
6496: Collective on Mat
6498: Input Parameters:
6499: . mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
6500: sequence of MatGetSequentialNonzeroStructure())
6502: Level: advanced
6504: Notes: Frees not only the matrices, but also the array that contains the matrices
6506: .seealso: MatGetSeqNonzeroStructure()
6507: @*/
6508: PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
6509: {
6514: MatDestroy(mat);
6515: return(0);
6516: }
6520: /*@
6521: MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6522: replaces the index sets by larger ones that represent submatrices with
6523: additional overlap.
6525: Collective on Mat
6527: Input Parameters:
6528: + mat - the matrix
6529: . n - the number of index sets
6530: . is - the array of index sets (these index sets will changed during the call)
6531: - ov - the additional overlap requested
6533: Level: developer
6535: Concepts: overlap
6536: Concepts: ASM^computing overlap
6538: .seealso: MatGetSubMatrices()
6539: @*/
6540: PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6541: {
6547: if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6548: if (n) {
6551: }
6552: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6553: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6554: MatPreallocated(mat);
6556: if (!ov) return(0);
6557: if (!mat->ops->increaseoverlap) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6558: PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
6559: (*mat->ops->increaseoverlap)(mat,n,is,ov);
6560: PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
6561: return(0);
6562: }
6566: /*@
6567: MatGetBlockSize - Returns the matrix block size; useful especially for the
6568: block row and block diagonal formats.
6569:
6570: Not Collective
6572: Input Parameter:
6573: . mat - the matrix
6575: Output Parameter:
6576: . bs - block size
6578: Notes:
6579: Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ
6581: Level: intermediate
6583: Concepts: matrices^block size
6585: .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ()
6586: @*/
6587: PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
6588: {
6595: MatPreallocated(mat);
6596: *bs = mat->rmap->bs;
6597: return(0);
6598: }
6602: /*@
6603: MatSetBlockSize - Sets the matrix block size; for many matrix types you
6604: cannot use this and MUST set the blocksize when you preallocate the matrix
6605:
6606: Logically Collective on Mat
6608: Input Parameters:
6609: + mat - the matrix
6610: - bs - block size
6612: Notes:
6613: For BAIJ matrices, this just checks that the block size agrees with the BAIJ size,
6614: it is not possible to change BAIJ block sizes after preallocation.
6616: Level: intermediate
6618: Concepts: matrices^block size
6620: .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ(), MatGetBlockSize()
6621: @*/
6622: PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
6623: {
6630: MatPreallocated(mat);
6631: if (bs < 1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Block size %D, must be positive",bs);
6632: if (mat->ops->setblocksize) {
6633: (*mat->ops->setblocksize)(mat,bs);
6634: } else {
6635: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Cannot set the blocksize for matrix type %s",((PetscObject)mat)->type_name);
6636: }
6637: return(0);
6638: }
6642: /*@C
6643: MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
6645: Collective on Mat
6647: Input Parameters:
6648: + mat - the matrix
6649: . shift - 0 or 1 indicating we want the indices starting at 0 or 1
6650: . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be symmetrized
6651: - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6652: inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6653: always used.
6655: Output Parameters:
6656: + n - number of rows in the (possibly compressed) matrix
6657: . ia - the row pointers [of length n+1]
6658: . ja - the column indices
6659: - done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
6660: are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
6662: Level: developer
6664: Notes: You CANNOT change any of the ia[] or ja[] values.
6666: Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values
6668: Fortran Node
6670: In Fortran use
6671: $ PetscInt ia(1), ja(1)
6672: $ PetscOffset iia, jja
6673: $ call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
6674: $
6675: $ or
6676: $
6677: $ PetscScalar, pointer :: xx_v(:)
6678: $ call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
6679:
6680:
6681: Acess the ith and jth entries via ia(iia + i) and ja(jja + j)
6683: .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatGetArray()
6684: @*/
6685: PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool *done)
6686: {
6696: MatPreallocated(mat);
6697: if (!mat->ops->getrowij) *done = PETSC_FALSE;
6698: else {
6699: *done = PETSC_TRUE;
6700: PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);
6701: (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6702: PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);
6703: }
6704: return(0);
6705: }
6709: /*@C
6710: MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
6712: Collective on Mat
6714: Input Parameters:
6715: + mat - the matrix
6716: . shift - 1 or zero indicating we want the indices starting at 0 or 1
6717: . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6718: symmetrized
6719: - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6720: inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6721: always used.
6723: Output Parameters:
6724: + n - number of columns in the (possibly compressed) matrix
6725: . ia - the column pointers
6726: . ja - the row indices
6727: - done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
6729: Level: developer
6731: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6732: @*/
6733: PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool *done)
6734: {
6744: MatPreallocated(mat);
6745: if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
6746: else {
6747: *done = PETSC_TRUE;
6748: (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6749: }
6750: return(0);
6751: }
6755: /*@C
6756: MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
6757: MatGetRowIJ().
6759: Collective on Mat
6761: Input Parameters:
6762: + mat - the matrix
6763: . shift - 1 or zero indicating we want the indices starting at 0 or 1
6764: . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6765: symmetrized
6766: - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6767: inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6768: always used.
6770: Output Parameters:
6771: + n - size of (possibly compressed) matrix
6772: . ia - the row pointers
6773: . ja - the column indices
6774: - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
6776: Level: developer
6778: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6779: @*/
6780: PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool *done)
6781: {
6790: MatPreallocated(mat);
6792: if (!mat->ops->restorerowij) *done = PETSC_FALSE;
6793: else {
6794: *done = PETSC_TRUE;
6795: (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6796: }
6797: return(0);
6798: }
6802: /*@C
6803: MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
6804: MatGetColumnIJ().
6806: Collective on Mat
6808: Input Parameters:
6809: + mat - the matrix
6810: . shift - 1 or zero indicating we want the indices starting at 0 or 1
6811: - symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6812: symmetrized
6813: - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6814: inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6815: always used.
6817: Output Parameters:
6818: + n - size of (possibly compressed) matrix
6819: . ia - the column pointers
6820: . ja - the row indices
6821: - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
6823: Level: developer
6825: .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
6826: @*/
6827: PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool *done)
6828: {
6837: MatPreallocated(mat);
6839: if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
6840: else {
6841: *done = PETSC_TRUE;
6842: (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6843: }
6844: return(0);
6845: }
6849: /*@C
6850: MatColoringPatch -Used inside matrix coloring routines that
6851: use MatGetRowIJ() and/or MatGetColumnIJ().
6853: Collective on Mat
6855: Input Parameters:
6856: + mat - the matrix
6857: . ncolors - max color value
6858: . n - number of entries in colorarray
6859: - colorarray - array indicating color for each column
6861: Output Parameters:
6862: . iscoloring - coloring generated using colorarray information
6864: Level: developer
6866: .seealso: MatGetRowIJ(), MatGetColumnIJ()
6868: @*/
6869: PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
6870: {
6878: MatPreallocated(mat);
6880: if (!mat->ops->coloringpatch){
6881: ISColoringCreate(((PetscObject)mat)->comm,ncolors,n,colorarray,iscoloring);
6882: } else {
6883: (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);
6884: }
6885: return(0);
6886: }
6891: /*@
6892: MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
6894: Logically Collective on Mat
6896: Input Parameter:
6897: . mat - the factored matrix to be reset
6899: Notes:
6900: This routine should be used only with factored matrices formed by in-place
6901: factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
6902: format). This option can save memory, for example, when solving nonlinear
6903: systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
6904: ILU(0) preconditioner.
6906: Note that one can specify in-place ILU(0) factorization by calling
6907: .vb
6908: PCType(pc,PCILU);
6909: PCFactorSeUseInPlace(pc);
6910: .ve
6911: or by using the options -pc_type ilu -pc_factor_in_place
6913: In-place factorization ILU(0) can also be used as a local
6914: solver for the blocks within the block Jacobi or additive Schwarz
6915: methods (runtime option: -sub_pc_factor_in_place). See the discussion
6916: of these preconditioners in the <a href="../../docs/manual.pdf#ch_pc">PC chapter of the users manual</a> for details on setting
6917: local solver options.
6919: Most users should employ the simplified KSP interface for linear solvers
6920: instead of working directly with matrix algebra routines such as this.
6921: See, e.g., KSPCreate().
6923: Level: developer
6925: .seealso: PCFactorSetUseInPlace()
6927: Concepts: matrices^unfactored
6929: @*/
6930: PetscErrorCode MatSetUnfactored(Mat mat)
6931: {
6937: MatPreallocated(mat);
6938: mat->factortype = MAT_FACTOR_NONE;
6939: if (!mat->ops->setunfactored) return(0);
6940: (*mat->ops->setunfactored)(mat);
6941: return(0);
6942: }
6944: /*MC
6945: MatGetArrayF90 - Accesses a matrix array from Fortran90.
6947: Synopsis:
6948: MatGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
6950: Not collective
6952: Input Parameter:
6953: . x - matrix
6955: Output Parameters:
6956: + xx_v - the Fortran90 pointer to the array
6957: - ierr - error code
6959: Example of Usage:
6960: .vb
6961: PetscScalar, pointer xx_v(:,:)
6962: ....
6963: call MatGetArrayF90(x,xx_v,ierr)
6964: a = xx_v(3)
6965: call MatRestoreArrayF90(x,xx_v,ierr)
6966: .ve
6968: Notes:
6969: Not yet supported for all F90 compilers
6971: Level: advanced
6973: .seealso: MatRestoreArrayF90(), MatGetArray(), MatRestoreArray()
6975: Concepts: matrices^accessing array
6977: M*/
6979: /*MC
6980: MatRestoreArrayF90 - Restores a matrix array that has been
6981: accessed with MatGetArrayF90().
6983: Synopsis:
6984: MatRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
6986: Not collective
6988: Input Parameters:
6989: + x - matrix
6990: - xx_v - the Fortran90 pointer to the array
6992: Output Parameter:
6993: . ierr - error code
6995: Example of Usage:
6996: .vb
6997: PetscScalar, pointer xx_v(:)
6998: ....
6999: call MatGetArrayF90(x,xx_v,ierr)
7000: a = xx_v(3)
7001: call MatRestoreArrayF90(x,xx_v,ierr)
7002: .ve
7003:
7004: Notes:
7005: Not yet supported for all F90 compilers
7007: Level: advanced
7009: .seealso: MatGetArrayF90(), MatGetArray(), MatRestoreArray()
7011: M*/
7016: /*@
7017: MatGetSubMatrix - Gets a single submatrix on the same number of processors
7018: as the original matrix.
7020: Collective on Mat
7022: Input Parameters:
7023: + mat - the original matrix
7024: . isrow - parallel IS containing the rows this processor should obtain
7025: . iscol - parallel IS containing all columns you wish to keep. Each process should list the columns that will be in IT's "diagonal part" in the new matrix.
7026: - cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7028: Output Parameter:
7029: . newmat - the new submatrix, of the same type as the old
7031: Level: advanced
7033: Notes:
7034: The submatrix will be able to be multiplied with vectors using the same layout as iscol.
7036: The rows in isrow will be sorted into the same order as the original matrix on each process.
7038: The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7039: the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
7040: to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7041: will reuse the matrix generated the first time. You should call MatDestroy() on newmat when
7042: you are finished using it.
7044: The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7045: the input matrix.
7047: If iscol is PETSC_NULL then all columns are obtained (not supported in Fortran).
7049: Example usage:
7050: Consider the following 8x8 matrix with 34 non-zero values, that is
7051: assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7052: proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7053: as follows:
7055: .vb
7056: 1 2 0 | 0 3 0 | 0 4
7057: Proc0 0 5 6 | 7 0 0 | 8 0
7058: 9 0 10 | 11 0 0 | 12 0
7059: -------------------------------------
7060: 13 0 14 | 15 16 17 | 0 0
7061: Proc1 0 18 0 | 19 20 21 | 0 0
7062: 0 0 0 | 22 23 0 | 24 0
7063: -------------------------------------
7064: Proc2 25 26 27 | 0 0 28 | 29 0
7065: 30 0 0 | 31 32 33 | 0 34
7066: .ve
7068: Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6]. The resulting submatrix is
7070: .vb
7071: 2 0 | 0 3 0 | 0
7072: Proc0 5 6 | 7 0 0 | 8
7073: -------------------------------
7074: Proc1 18 0 | 19 20 21 | 0
7075: -------------------------------
7076: Proc2 26 27 | 0 0 28 | 29
7077: 0 0 | 31 32 33 | 0
7078: .ve
7081: Concepts: matrices^submatrices
7083: .seealso: MatGetSubMatrices()
7084: @*/
7085: PetscErrorCode MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7086: {
7088: PetscMPIInt size;
7089: Mat *local;
7090: IS iscoltmp;
7099: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7100: MatPreallocated(mat);
7101: MPI_Comm_size(((PetscObject)mat)->comm,&size);
7103: if (!iscol) {
7104: ISCreateStride(((PetscObject)mat)->comm,mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);
7105: } else {
7106: iscoltmp = iscol;
7107: }
7109: /* if original matrix is on just one processor then use submatrix generated */
7110: if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7111: MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);
7112: if (!iscol) {ISDestroy(&iscoltmp);}
7113: return(0);
7114: } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) {
7115: MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);
7116: *newmat = *local;
7117: PetscFree(local);
7118: if (!iscol) {ISDestroy(&iscoltmp);}
7119: return(0);
7120: } else if (!mat->ops->getsubmatrix) {
7121: /* Create a new matrix type that implements the operation using the full matrix */
7122: switch (cll) {
7123: case MAT_INITIAL_MATRIX:
7124: MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);
7125: break;
7126: case MAT_REUSE_MATRIX:
7127: MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);
7128: break;
7129: default: SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7130: }
7131: if (!iscol) {ISDestroy(&iscoltmp);}
7132: return(0);
7133: }
7135: if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7136: (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);
7137: if (!iscol) {ISDestroy(&iscoltmp);}
7138: if (*newmat && cll == MAT_INITIAL_MATRIX) {PetscObjectStateIncrease((PetscObject)*newmat);}
7139: return(0);
7140: }
7144: /*@
7145: MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7146: used during the assembly process to store values that belong to
7147: other processors.
7149: Not Collective
7151: Input Parameters:
7152: + mat - the matrix
7153: . size - the initial size of the stash.
7154: - bsize - the initial size of the block-stash(if used).
7156: Options Database Keys:
7157: + -matstash_initial_size <size> or <size0,size1,...sizep-1>
7158: - -matstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1>
7160: Level: intermediate
7162: Notes:
7163: The block-stash is used for values set with MatSetValuesBlocked() while
7164: the stash is used for values set with MatSetValues()
7166: Run with the option -info and look for output of the form
7167: MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7168: to determine the appropriate value, MM, to use for size and
7169: MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7170: to determine the value, BMM to use for bsize
7172: Concepts: stash^setting matrix size
7173: Concepts: matrices^stash
7175: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
7177: @*/
7178: PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7179: {
7185: MatStashSetInitialSize_Private(&mat->stash,size);
7186: MatStashSetInitialSize_Private(&mat->bstash,bsize);
7187: return(0);
7188: }
7192: /*@
7193: MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
7194: the matrix
7196: Neighbor-wise Collective on Mat
7198: Input Parameters:
7199: + mat - the matrix
7200: . x,y - the vectors
7201: - w - where the result is stored
7203: Level: intermediate
7205: Notes:
7206: w may be the same vector as y.
7208: This allows one to use either the restriction or interpolation (its transpose)
7209: matrix to do the interpolation
7211: Concepts: interpolation
7213: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7215: @*/
7216: PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7217: {
7219: PetscInt M,N,Ny;
7227: MatPreallocated(A);
7228: MatGetSize(A,&M,&N);
7229: VecGetSize(y,&Ny);
7230: if (M == Ny) {
7231: MatMultAdd(A,x,y,w);
7232: } else {
7233: MatMultTransposeAdd(A,x,y,w);
7234: }
7235: return(0);
7236: }
7240: /*@
7241: MatInterpolate - y = A*x or A'*x depending on the shape of
7242: the matrix
7244: Neighbor-wise Collective on Mat
7246: Input Parameters:
7247: + mat - the matrix
7248: - x,y - the vectors
7250: Level: intermediate
7252: Notes:
7253: This allows one to use either the restriction or interpolation (its transpose)
7254: matrix to do the interpolation
7256: Concepts: matrices^interpolation
7258: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7260: @*/
7261: PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
7262: {
7264: PetscInt M,N,Ny;
7271: MatPreallocated(A);
7272: MatGetSize(A,&M,&N);
7273: VecGetSize(y,&Ny);
7274: if (M == Ny) {
7275: MatMult(A,x,y);
7276: } else {
7277: MatMultTranspose(A,x,y);
7278: }
7279: return(0);
7280: }
7284: /*@
7285: MatRestrict - y = A*x or A'*x
7287: Neighbor-wise Collective on Mat
7289: Input Parameters:
7290: + mat - the matrix
7291: - x,y - the vectors
7293: Level: intermediate
7295: Notes:
7296: This allows one to use either the restriction or interpolation (its transpose)
7297: matrix to do the restriction
7299: Concepts: matrices^restriction
7301: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
7303: @*/
7304: PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
7305: {
7307: PetscInt M,N,Ny;
7314: MatPreallocated(A);
7316: MatGetSize(A,&M,&N);
7317: VecGetSize(y,&Ny);
7318: if (M == Ny) {
7319: MatMult(A,x,y);
7320: } else {
7321: MatMultTranspose(A,x,y);
7322: }
7323: return(0);
7324: }
7328: /*@
7329: MatNullSpaceAttach - attaches a null space to a matrix.
7330: This null space will be removed from the resulting vector whenever
7331: MatMult() is called
7333: Logically Collective on Mat and MatNullSpace
7335: Input Parameters:
7336: + mat - the matrix
7337: - nullsp - the null space object
7339: Level: developer
7341: Notes:
7342: Overwrites any previous null space that may have been attached
7344: Concepts: null space^attaching to matrix
7346: .seealso: MatCreate(), MatNullSpaceCreate()
7347: @*/
7348: PetscErrorCode MatNullSpaceAttach(Mat mat,MatNullSpace nullsp)
7349: {
7356: MatPreallocated(mat);
7357: PetscObjectReference((PetscObject)nullsp);
7358: if (mat->nullsp) { MatNullSpaceDestroy(&mat->nullsp); }
7359: mat->nullsp = nullsp;
7360: return(0);
7361: }
7365: /*@C
7366: MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
7368: Collective on Mat
7370: Input Parameters:
7371: + mat - the matrix
7372: . row - row/column permutation
7373: . fill - expected fill factor >= 1.0
7374: - level - level of fill, for ICC(k)
7376: Notes:
7377: Probably really in-place only when level of fill is zero, otherwise allocates
7378: new space to store factored matrix and deletes previous memory.
7380: Most users should employ the simplified KSP interface for linear solvers
7381: instead of working directly with matrix algebra routines such as this.
7382: See, e.g., KSPCreate().
7384: Level: developer
7386: Concepts: matrices^incomplete Cholesky factorization
7387: Concepts: Cholesky factorization
7389: .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
7391: Developer Note: fortran interface is not autogenerated as the f90
7392: interface defintion cannot be generated correctly [due to MatFactorInfo]
7394: @*/
7395: PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo* info)
7396: {
7404: if (mat->rmap->N != mat->cmap->N) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONG,"matrix must be square");
7405: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7406: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7407: if (!mat->ops->iccfactor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7408: MatPreallocated(mat);
7409: (*mat->ops->iccfactor)(mat,row,info);
7410: PetscObjectStateIncrease((PetscObject)mat);
7411: return(0);
7412: }
7416: /*@
7417: MatSetValuesAdic - Sets values computed with ADIC automatic differentiation into a matrix.
7419: Not Collective
7421: Input Parameters:
7422: + mat - the matrix
7423: - v - the values compute with ADIC
7425: Level: developer
7427: Notes:
7428: Must call MatSetColoring() before using this routine. Also this matrix must already
7429: have its nonzero pattern determined.
7431: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7432: MatSetValues(), MatSetColoring(), MatSetValuesAdifor()
7433: @*/
7434: PetscErrorCode MatSetValuesAdic(Mat mat,void *v)
7435: {
7443: if (!mat->assembled) {
7444: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7445: }
7446: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
7447: if (!mat->ops->setvaluesadic) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7448: (*mat->ops->setvaluesadic)(mat,v);
7449: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
7450: MatView_Private(mat);
7451: PetscObjectStateIncrease((PetscObject)mat);
7452: return(0);
7453: }
7458: /*@
7459: MatSetColoring - Sets a coloring used by calls to MatSetValuesAdic()
7461: Not Collective
7463: Input Parameters:
7464: + mat - the matrix
7465: - coloring - the coloring
7467: Level: developer
7469: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7470: MatSetValues(), MatSetValuesAdic()
7471: @*/
7472: PetscErrorCode MatSetColoring(Mat mat,ISColoring coloring)
7473: {
7481: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7482: if (!mat->ops->setcoloring) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7483: (*mat->ops->setcoloring)(mat,coloring);
7484: return(0);
7485: }
7489: /*@
7490: MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.
7492: Not Collective
7494: Input Parameters:
7495: + mat - the matrix
7496: . nl - leading dimension of v
7497: - v - the values compute with ADIFOR
7499: Level: developer
7501: Notes:
7502: Must call MatSetColoring() before using this routine. Also this matrix must already
7503: have its nonzero pattern determined.
7505: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7506: MatSetValues(), MatSetColoring()
7507: @*/
7508: PetscErrorCode MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
7509: {
7517: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7518: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
7519: if (!mat->ops->setvaluesadifor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7520: (*mat->ops->setvaluesadifor)(mat,nl,v);
7521: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
7522: PetscObjectStateIncrease((PetscObject)mat);
7523: return(0);
7524: }
7528: /*@
7529: MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
7530: ghosted ones.
7532: Not Collective
7534: Input Parameters:
7535: + mat - the matrix
7536: - diag = the diagonal values, including ghost ones
7538: Level: developer
7540: Notes: Works only for MPIAIJ and MPIBAIJ matrices
7541:
7542: .seealso: MatDiagonalScale()
7543: @*/
7544: PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
7545: {
7547: PetscMPIInt size;
7554: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7555: PetscLogEventBegin(MAT_Scale,mat,0,0,0);
7556: MPI_Comm_size(((PetscObject)mat)->comm,&size);
7557: if (size == 1) {
7558: PetscInt n,m;
7559: VecGetSize(diag,&n);
7560: MatGetSize(mat,0,&m);
7561: if (m == n) {
7562: MatDiagonalScale(mat,0,diag);
7563: } else {
7564: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
7565: }
7566: } else {
7567: PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));
7568: }
7569: PetscLogEventEnd(MAT_Scale,mat,0,0,0);
7570: PetscObjectStateIncrease((PetscObject)mat);
7571: return(0);
7572: }
7576: /*@
7577: MatGetInertia - Gets the inertia from a factored matrix
7579: Collective on Mat
7581: Input Parameter:
7582: . mat - the matrix
7584: Output Parameters:
7585: + nneg - number of negative eigenvalues
7586: . nzero - number of zero eigenvalues
7587: - npos - number of positive eigenvalues
7589: Level: advanced
7591: Notes: Matrix must have been factored by MatCholeskyFactor()
7594: @*/
7595: PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
7596: {
7602: if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7603: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
7604: if (!mat->ops->getinertia) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7605: (*mat->ops->getinertia)(mat,nneg,nzero,npos);
7606: return(0);
7607: }
7609: /* ----------------------------------------------------------------*/
7612: /*@C
7613: MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
7615: Neighbor-wise Collective on Mat and Vecs
7617: Input Parameters:
7618: + mat - the factored matrix
7619: - b - the right-hand-side vectors
7621: Output Parameter:
7622: . x - the result vectors
7624: Notes:
7625: The vectors b and x cannot be the same. I.e., one cannot
7626: call MatSolves(A,x,x).
7628: Notes:
7629: Most users should employ the simplified KSP interface for linear solvers
7630: instead of working directly with matrix algebra routines such as this.
7631: See, e.g., KSPCreate().
7633: Level: developer
7635: Concepts: matrices^triangular solves
7637: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
7638: @*/
7639: PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
7640: {
7646: if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
7647: if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7648: if (!mat->rmap->N && !mat->cmap->N) return(0);
7650: if (!mat->ops->solves) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7651: MatPreallocated(mat);
7652: PetscLogEventBegin(MAT_Solves,mat,0,0,0);
7653: (*mat->ops->solves)(mat,b,x);
7654: PetscLogEventEnd(MAT_Solves,mat,0,0,0);
7655: return(0);
7656: }
7660: /*@
7661: MatIsSymmetric - Test whether a matrix is symmetric
7663: Collective on Mat
7665: Input Parameter:
7666: + A - the matrix to test
7667: - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
7669: Output Parameters:
7670: . flg - the result
7672: Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
7674: Level: intermediate
7676: Concepts: matrix^symmetry
7678: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
7679: @*/
7680: PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool *flg)
7681: {
7688: if (!A->symmetric_set) {
7689: if (!A->ops->issymmetric) {
7690: const MatType mattype;
7691: MatGetType(A,&mattype);
7692: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7693: }
7694: (*A->ops->issymmetric)(A,tol,flg);
7695: if (!tol) {
7696: A->symmetric_set = PETSC_TRUE;
7697: A->symmetric = *flg;
7698: if (A->symmetric) {
7699: A->structurally_symmetric_set = PETSC_TRUE;
7700: A->structurally_symmetric = PETSC_TRUE;
7701: }
7702: }
7703: } else if (A->symmetric) {
7704: *flg = PETSC_TRUE;
7705: } else if (!tol) {
7706: *flg = PETSC_FALSE;
7707: } else {
7708: if (!A->ops->issymmetric) {
7709: const MatType mattype;
7710: MatGetType(A,&mattype);
7711: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7712: }
7713: (*A->ops->issymmetric)(A,tol,flg);
7714: }
7715: return(0);
7716: }
7720: /*@
7721: MatIsHermitian - Test whether a matrix is Hermitian
7723: Collective on Mat
7725: Input Parameter:
7726: + A - the matrix to test
7727: - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
7729: Output Parameters:
7730: . flg - the result
7732: Level: intermediate
7734: Concepts: matrix^symmetry
7736: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
7737: MatIsSymmetricKnown(), MatIsSymmetric()
7738: @*/
7739: PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool *flg)
7740: {
7747: if (!A->hermitian_set) {
7748: if (!A->ops->ishermitian) {
7749: const MatType mattype;
7750: MatGetType(A,&mattype);
7751: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7752: }
7753: (*A->ops->ishermitian)(A,tol,flg);
7754: if (!tol) {
7755: A->hermitian_set = PETSC_TRUE;
7756: A->hermitian = *flg;
7757: if (A->hermitian) {
7758: A->structurally_symmetric_set = PETSC_TRUE;
7759: A->structurally_symmetric = PETSC_TRUE;
7760: }
7761: }
7762: } else if (A->hermitian) {
7763: *flg = PETSC_TRUE;
7764: } else if (!tol) {
7765: *flg = PETSC_FALSE;
7766: } else {
7767: if (!A->ops->ishermitian) {
7768: const MatType mattype;
7769: MatGetType(A,&mattype);
7770: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7771: }
7772: (*A->ops->ishermitian)(A,tol,flg);
7773: }
7774: return(0);
7775: }
7779: /*@
7780: MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
7782: Not Collective
7784: Input Parameter:
7785: . A - the matrix to check
7787: Output Parameters:
7788: + set - if the symmetric flag is set (this tells you if the next flag is valid)
7789: - flg - the result
7791: Level: advanced
7793: Concepts: matrix^symmetry
7795: Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
7796: if you want it explicitly checked
7798: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
7799: @*/
7800: PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool *set,PetscBool *flg)
7801: {
7806: if (A->symmetric_set) {
7807: *set = PETSC_TRUE;
7808: *flg = A->symmetric;
7809: } else {
7810: *set = PETSC_FALSE;
7811: }
7812: return(0);
7813: }
7817: /*@
7818: MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
7820: Not Collective
7822: Input Parameter:
7823: . A - the matrix to check
7825: Output Parameters:
7826: + set - if the hermitian flag is set (this tells you if the next flag is valid)
7827: - flg - the result
7829: Level: advanced
7831: Concepts: matrix^symmetry
7833: Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
7834: if you want it explicitly checked
7836: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
7837: @*/
7838: PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg)
7839: {
7844: if (A->hermitian_set) {
7845: *set = PETSC_TRUE;
7846: *flg = A->hermitian;
7847: } else {
7848: *set = PETSC_FALSE;
7849: }
7850: return(0);
7851: }
7855: /*@
7856: MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
7858: Collective on Mat
7860: Input Parameter:
7861: . A - the matrix to test
7863: Output Parameters:
7864: . flg - the result
7866: Level: intermediate
7868: Concepts: matrix^symmetry
7870: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
7871: @*/
7872: PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg)
7873: {
7879: if (!A->structurally_symmetric_set) {
7880: if (!A->ops->isstructurallysymmetric) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
7881: (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);
7882: A->structurally_symmetric_set = PETSC_TRUE;
7883: }
7884: *flg = A->structurally_symmetric;
7885: return(0);
7886: }
7890: extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
7891: /*@
7892: MatStashGetInfo - Gets how many values are currently in the vector stash, i.e. need
7893: to be communicated to other processors during the MatAssemblyBegin/End() process
7895: Not collective
7897: Input Parameter:
7898: . vec - the vector
7900: Output Parameters:
7901: + nstash - the size of the stash
7902: . reallocs - the number of additional mallocs incurred.
7903: . bnstash - the size of the block stash
7904: - breallocs - the number of additional mallocs incurred.in the block stash
7905:
7906: Level: advanced
7908: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
7909:
7910: @*/
7911: PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
7912: {
7915: MatStashGetInfo_Private(&mat->stash,nstash,reallocs);
7916: MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);
7917: return(0);
7918: }
7922: /*@C
7923: MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same
7924: parallel layout
7925:
7926: Collective on Mat
7928: Input Parameter:
7929: . mat - the matrix
7931: Output Parameter:
7932: + right - (optional) vector that the matrix can be multiplied against
7933: - left - (optional) vector that the matrix vector product can be stored in
7935: Level: advanced
7937: .seealso: MatCreate()
7938: @*/
7939: PetscErrorCode MatGetVecs(Mat mat,Vec *right,Vec *left)
7940: {
7946: MatPreallocated(mat);
7947: if (mat->ops->getvecs) {
7948: (*mat->ops->getvecs)(mat,right,left);
7949: } else {
7950: PetscMPIInt size;
7951: MPI_Comm_size(((PetscObject)mat)->comm, &size);
7952: if (right) {
7953: VecCreate(((PetscObject)mat)->comm,right);
7954: VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);
7955: VecSetBlockSize(*right,mat->rmap->bs);
7956: VecSetType(*right,VECSTANDARD);
7957: PetscLayoutReference(mat->cmap,&(*right)->map);
7958: }
7959: if (left) {
7960: VecCreate(((PetscObject)mat)->comm,left);
7961: VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);
7962: VecSetBlockSize(*left,mat->rmap->bs);
7963: VecSetType(*left,VECSTANDARD);
7964: PetscLayoutReference(mat->rmap,&(*left)->map);
7965: }
7966: }
7967: return(0);
7968: }
7972: /*@C
7973: MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
7974: with default values.
7976: Not Collective
7978: Input Parameters:
7979: . info - the MatFactorInfo data structure
7982: Notes: The solvers are generally used through the KSP and PC objects, for example
7983: PCLU, PCILU, PCCHOLESKY, PCICC
7985: Level: developer
7987: .seealso: MatFactorInfo
7989: Developer Note: fortran interface is not autogenerated as the f90
7990: interface defintion cannot be generated correctly [due to MatFactorInfo]
7992: @*/
7994: PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
7995: {
7999: PetscMemzero(info,sizeof(MatFactorInfo));
8000: return(0);
8001: }
8005: /*@
8006: MatPtAP - Creates the matrix product C = P^T * A * P
8008: Neighbor-wise Collective on Mat
8010: Input Parameters:
8011: + A - the matrix
8012: . P - the projection matrix
8013: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8014: - fill - expected fill as ratio of nnz(C)/nnz(A)
8016: Output Parameters:
8017: . C - the product matrix
8019: Notes:
8020: C will be created and must be destroyed by the user with MatDestroy().
8022: This routine is currently only implemented for pairs of AIJ matrices and classes
8023: which inherit from AIJ.
8025: Level: intermediate
8027: .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult()
8028: @*/
8029: PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
8030: {
8036: if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8037: if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8040: MatPreallocated(P);
8041: if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8042: if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8044: if (P->rmap->N!=A->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
8045: if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8046: MatPreallocated(A);
8048: if (!A->ops->ptap) {
8049: const MatType mattype;
8050: MatGetType(A,&mattype);
8051: SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix of type <%s> does not support PtAP",mattype);
8052: }
8053: PetscLogEventBegin(MAT_PtAP,A,P,0,0);
8054: (*A->ops->ptap)(A,P,scall,fill,C);
8055: PetscLogEventEnd(MAT_PtAP,A,P,0,0);
8057: return(0);
8058: }
8062: /*@
8063: MatPtAPNumeric - Computes the matrix product C = P^T * A * P
8065: Neighbor-wise Collective on Mat
8067: Input Parameters:
8068: + A - the matrix
8069: - P - the projection matrix
8071: Output Parameters:
8072: . C - the product matrix
8074: Notes:
8075: C must have been created by calling MatPtAPSymbolic and must be destroyed by
8076: the user using MatDeatroy().
8078: This routine is currently only implemented for pairs of AIJ matrices and classes
8079: which inherit from AIJ. C will be of type MATAIJ.
8081: Level: intermediate
8083: .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
8084: @*/
8085: PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C)
8086: {
8092: if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8093: if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8096: MatPreallocated(P);
8097: if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8098: if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8101: MatPreallocated(C);
8102: if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8103: if (P->cmap->N!=C->rmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->rmap->N);
8104: if (P->rmap->N!=A->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
8105: if (A->rmap->N!=A->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
8106: if (P->cmap->N!=C->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->cmap->N);
8107: MatPreallocated(A);
8109: PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
8110: (*A->ops->ptapnumeric)(A,P,C);
8111: PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
8112: return(0);
8113: }
8117: /*@
8118: MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P
8120: Neighbor-wise Collective on Mat
8122: Input Parameters:
8123: + A - the matrix
8124: - P - the projection matrix
8126: Output Parameters:
8127: . C - the (i,j) structure of the product matrix
8129: Notes:
8130: C will be created and must be destroyed by the user with MatDestroy().
8132: This routine is currently only implemented for pairs of SeqAIJ matrices and classes
8133: which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using
8134: this (i,j) structure by calling MatPtAPNumeric().
8136: Level: intermediate
8138: .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
8139: @*/
8140: PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
8141: {
8147: if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8148: if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8149: if (fill <1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8152: MatPreallocated(P);
8153: if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8154: if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8157: if (P->rmap->N!=A->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
8158: if (A->rmap->N!=A->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
8159: MatPreallocated(A);
8160: PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);
8161: (*A->ops->ptapsymbolic)(A,P,fill,C);
8162: PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);
8164: MatSetBlockSize(*C,A->rmap->bs);
8166: return(0);
8167: }
8171: /*@
8172: MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
8174: Neighbor-wise Collective on Mat
8176: Input Parameters:
8177: + A - the left matrix
8178: . B - the right matrix
8179: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8180: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
8181: if the result is a dense matrix this is irrelevent
8183: Output Parameters:
8184: . C - the product matrix
8186: Notes:
8187: Unless scall is MAT_REUSE_MATRIX C will be created.
8189: MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8190:
8191: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8192: actually needed.
8194: If you have many matrices with the same non-zero structure to multiply, you
8195: should either
8196: $ 1) use MAT_REUSE_MATRIX in all calls but the first or
8197: $ 2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
8199: Level: intermediate
8201: .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatPtAP()
8202: @*/
8203: PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8204: {
8206: PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8207: PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8208: PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat *)=PETSC_NULL;
8213: if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8214: if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8217: MatPreallocated(B);
8218: if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8219: if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8221: if (B->rmap->N!=A->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
8222: if (scall == MAT_REUSE_MATRIX){
8225: }
8226: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8227: if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8228: MatPreallocated(A);
8230: fA = A->ops->matmult;
8231: fB = B->ops->matmult;
8232: if (fB == fA) {
8233: if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
8234: mult = fB;
8235: } else {
8236: /* dispatch based on the type of A and B */
8237: char multname[256];
8238: PetscStrcpy(multname,"MatMatMult_");
8239: PetscStrcat(multname,((PetscObject)A)->type_name);
8240: PetscStrcat(multname,"_");
8241: PetscStrcat(multname,((PetscObject)B)->type_name);
8242: PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
8243: PetscObjectQueryFunction((PetscObject)B,multname,(void (**)(void))&mult);
8244: if (!mult) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_INCOMP,"MatMatMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
8245: }
8246: PetscLogEventBegin(MAT_MatMult,A,B,0,0);
8247: (*mult)(A,B,scall,fill,C);
8248: PetscLogEventEnd(MAT_MatMult,A,B,0,0);
8249: return(0);
8250: }
8254: /*@
8255: MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
8256: of the matrix-matrix product C=A*B. Call this routine before calling MatMatMultNumeric().
8258: Neighbor-wise Collective on Mat
8260: Input Parameters:
8261: + A - the left matrix
8262: . B - the right matrix
8263: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
8264: if C is a dense matrix this is irrelevent
8265:
8266: Output Parameters:
8267: . C - the product matrix
8269: Notes:
8270: Unless scall is MAT_REUSE_MATRIX C will be created.
8272: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8273: actually needed.
8275: This routine is currently implemented for
8276: - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
8277: - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8278: - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
8280: Level: intermediate
8282: Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
8283: We should incorporate them into PETSc.
8285: .seealso: MatMatMult(), MatMatMultNumeric()
8286: @*/
8287: PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
8288: {
8290: PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat *);
8291: PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat *);
8292: PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat *)=PETSC_NULL;
8297: if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8298: if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8302: MatPreallocated(B);
8303: if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8304: if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8307: if (B->rmap->N!=A->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
8308: if (fill == PETSC_DEFAULT) fill = 2.0;
8309: if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8310: MatPreallocated(A);
8311:
8312: Asymbolic = A->ops->matmultsymbolic;
8313: Bsymbolic = B->ops->matmultsymbolic;
8314: if (Asymbolic == Bsymbolic){
8315: if (!Bsymbolic) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
8316: symbolic = Bsymbolic;
8317: } else { /* dispatch based on the type of A and B */
8318: char symbolicname[256];
8319: PetscStrcpy(symbolicname,"MatMatMultSymbolic_");
8320: PetscStrcat(symbolicname,((PetscObject)A)->type_name);
8321: PetscStrcat(symbolicname,"_");
8322: PetscStrcat(symbolicname,((PetscObject)B)->type_name);
8323: PetscStrcat(symbolicname,"_C");
8324: PetscObjectQueryFunction((PetscObject)B,symbolicname,(void (**)(void))&symbolic);
8325: if (!symbolic) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_INCOMP,"MatMatMultSymbolic requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
8326: }
8327: PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);
8328: (*symbolic)(A,B,fill,C);
8329: PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);
8330: return(0);
8331: }
8335: /*@
8336: MatMatMultNumeric - Performs the numeric matrix-matrix product.
8337: Call this routine after first calling MatMatMultSymbolic().
8339: Neighbor-wise Collective on Mat
8341: Input Parameters:
8342: + A - the left matrix
8343: - B - the right matrix
8345: Output Parameters:
8346: . C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
8348: Notes:
8349: C must have been created with MatMatMultSymbolic().
8351: This routine is currently implemented for
8352: - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
8353: - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8354: - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
8356: Level: intermediate
8358: .seealso: MatMatMult(), MatMatMultSymbolic()
8359: @*/
8360: PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C)
8361: {
8363: PetscErrorCode (*Anumeric)(Mat,Mat,Mat);
8364: PetscErrorCode (*Bnumeric)(Mat,Mat,Mat);
8365: PetscErrorCode (*numeric)(Mat,Mat,Mat)=PETSC_NULL;
8370: if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8371: if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8375: MatPreallocated(B);
8376: if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8377: if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8381: MatPreallocated(C);
8382: if (!C->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8383: if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8385: if (B->cmap->N!=C->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->cmap->N,C->cmap->N);
8386: if (B->rmap->N!=A->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
8387: if (A->rmap->N!=C->rmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",A->rmap->N,C->rmap->N);
8388: MatPreallocated(A);
8390: Anumeric = A->ops->matmultnumeric;
8391: Bnumeric = B->ops->matmultnumeric;
8392: if (Anumeric == Bnumeric){
8393: if (!Bnumeric) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMultNumeric not supported for B of type %s",((PetscObject)B)->type_name);
8394: numeric = Bnumeric;
8395: } else {
8396: char numericname[256];
8397: PetscStrcpy(numericname,"MatMatMultNumeric_");
8398: PetscStrcat(numericname,((PetscObject)A)->type_name);
8399: PetscStrcat(numericname,"_");
8400: PetscStrcat(numericname,((PetscObject)B)->type_name);
8401: PetscStrcat(numericname,"_C");
8402: PetscObjectQueryFunction((PetscObject)B,numericname,(void (**)(void))&numeric);
8403: if (!numeric)
8404: SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_INCOMP,"MatMatMultNumeric requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
8405: }
8406: PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);
8407: (*numeric)(A,B,C);
8408: PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);
8409: return(0);
8410: }
8414: /*@
8415: MatMatMultTranspose - Performs Matrix-Matrix Multiplication C=A^T*B.
8417: Neighbor-wise Collective on Mat
8419: Input Parameters:
8420: + A - the left matrix
8421: . B - the right matrix
8422: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8423: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
8425: Output Parameters:
8426: . C - the product matrix
8428: Notes:
8429: C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
8431: MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8433: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8434: actually needed.
8436: This routine is currently only implemented for pairs of SeqAIJ matrices and pairs of SeqDense matrices and classes
8437: which inherit from SeqAIJ. C will be of type MATSEQAIJ.
8439: Level: intermediate
8441: .seealso: MatMatMultTransposeSymbolic(), MatMatMultTransposeNumeric(), MatPtAP()
8442: @*/
8443: PetscErrorCode MatMatMultTranspose(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8444: {
8446: PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8447: PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8452: if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8453: if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8456: MatPreallocated(B);
8457: if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8458: if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8460: if (B->rmap->N!=A->rmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->rmap->N);
8461: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8462: if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8463: MatPreallocated(A);
8465: fA = A->ops->matmulttranspose;
8466: if (!fA) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMultTranspose not supported for A of type %s",((PetscObject)A)->type_name);
8467: fB = B->ops->matmulttranspose;
8468: if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMultTranspose not supported for B of type %s",((PetscObject)B)->type_name);
8469: if (fB!=fA) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_INCOMP,"MatMatMultTranspose requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
8471: PetscLogEventBegin(MAT_MatMultTranspose,A,B,0,0);
8472: (*A->ops->matmulttranspose)(A,B,scall,fill,C);
8473: PetscLogEventEnd(MAT_MatMultTranspose,A,B,0,0);
8474:
8475: return(0);
8476: }
8480: /*@C
8481: MatGetRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
8483: Collective on Mat
8485: Input Parameters:
8486: + mat - the matrix
8487: . nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
8488: . subcomm - MPI communicator split from the communicator where mat resides in
8489: . mlocal_red - number of local rows of the redundant matrix
8490: - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8492: Output Parameter:
8493: . matredundant - redundant matrix
8495: Notes:
8496: MAT_REUSE_MATRIX can only be used when the nonzero structure of the
8497: original matrix has not changed from that last call to MatGetRedundantMatrix().
8499: This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
8500: calling it.
8502: Only MPIAIJ matrix is supported.
8503:
8504: Level: advanced
8506: Concepts: subcommunicator
8507: Concepts: duplicate matrix
8509: .seealso: MatDestroy()
8510: @*/
8511: PetscErrorCode MatGetRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,PetscInt mlocal_red,MatReuse reuse,Mat *matredundant)
8512: {
8517: if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
8520: }
8521: if (!mat->ops->getredundantmatrix) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8522: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8523: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8524: MatPreallocated(mat);
8526: PetscLogEventBegin(MAT_GetRedundantMatrix,mat,0,0,0);
8527: (*mat->ops->getredundantmatrix)(mat,nsubcomm,subcomm,mlocal_red,reuse,matredundant);
8528: PetscLogEventEnd(MAT_GetRedundantMatrix,mat,0,0,0);
8529: return(0);
8530: }
8534: /*@C
8535: MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
8536: a given 'mat' object. Each submatrix can span multiple procs.
8538: Collective on Mat
8540: Input Parameters:
8541: + mat - the matrix
8542: - subcomm - the subcommunicator obtained by com_split(comm)
8544: Output Parameter:
8545: . subMat - 'parallel submatrices each spans a given subcomm
8547: Notes:
8548: The submatrix partition across processors is dicated by 'subComm' a
8549: communicator obtained by com_split(comm). The comm_split
8550: is not restriced to be grouped with consequitive original ranks.
8552: Due the comm_split() usage, the parallel layout of the submatrices
8553: map directly to the layout of the original matrix [wrt the local
8554: row,col partitioning]. So the original 'DiagonalMat' naturally maps
8555: into the 'DiagonalMat' of the subMat, hence it is used directly from
8556: the subMat. However the offDiagMat looses some columns - and this is
8557: reconstructed with MatSetValues()
8559: Level: advanced
8561: Concepts: subcommunicator
8562: Concepts: submatrices
8564: .seealso: MatGetSubMatrices()
8565: @*/
8566: PetscErrorCode MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, Mat* subMat)
8567: {
8569: PetscMPIInt commsize,subCommSize;
8572: MPI_Comm_size(((PetscObject)mat)->comm,&commsize);
8573: MPI_Comm_size(subComm,&subCommSize);
8574: if (subCommSize > commsize) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
8575:
8576: PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);
8577: (*mat->ops->getmultiprocblock)(mat,subComm,subMat);
8578: PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);
8579: return(0);
8580: }
8584: /*@
8585: MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
8587: Not Collective
8589: Input Arguments:
8590: mat - matrix to extract local submatrix from
8591: isrow - local row indices for submatrix
8592: iscol - local column indices for submatrix
8594: Output Arguments:
8595: submat - the submatrix
8597: Level: intermediate
8599: Notes:
8600: The submat should be returned with MatRestoreLocalSubMatrix().
8602: Depending on the format of mat, the returned submat may not implement MatMult(). Its communicator may be
8603: the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
8605: The submat always implements MatSetValuesLocal(). If isrow and iscol have the same block size, then
8606: MatSetValuesBlockedLocal() will also be implemented.
8608: .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef()
8609: @*/
8610: PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
8611: {
8621: if (mat->ops->getlocalsubmatrix) {
8622: (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);
8623: } else {
8624: MatCreateLocalRef(mat,isrow,iscol,submat);
8625: }
8626: return(0);
8627: }
8631: /*@
8632: MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
8634: Not Collective
8636: Input Arguments:
8637: mat - matrix to extract local submatrix from
8638: isrow - local row indices for submatrix
8639: iscol - local column indices for submatrix
8640: submat - the submatrix
8642: Level: intermediate
8644: .seealso: MatGetLocalSubMatrix()
8645: @*/
8646: PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
8647: {
8658: if (mat->ops->restorelocalsubmatrix) {
8659: (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);
8660: } else {
8661: MatDestroy(submat);
8662: }
8663: *submat = PETSC_NULL;
8664: return(0);
8665: }
8667: /* --------------------------------------------------------*/
8670: /*@
8671: MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no entry in the matrix
8673: Collective on Mat
8675: Input Parameter:
8676: . mat - the matrix
8678: Output Parameter:
8679: . is - if any rows have zero diagonals this contains the list of them
8681: Level: developer
8683: Concepts: matrix-vector product
8685: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
8686: @*/
8687: PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is)
8688: {
8694: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8695: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8697: if (!mat->ops->findzerodiagonals) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"This matrix type does not have a find zero diagonals defined");
8698: (*mat->ops->findzerodiagonals)(mat,is);
8699: return(0);
8700: }
8704: /*@
8705: MatInvertBlockDiagonal - Inverts the block diagonal entries.
8707: Collective on Mat
8709: Input Parameters:
8710: . mat - the matrix
8712: Output Parameters:
8713: . values - the block inverses in column major order (FORTRAN-like)
8715: Level: advanced
8716: @*/
8717: PetscErrorCode MatInvertBlockDiagonal(Mat mat,PetscScalar **values)
8718: {
8723: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8724: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8725: if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
8726: (*mat->ops->invertblockdiagonal)(mat,values);
8727: return(0);
8728: }