Actual source code: matrix.c
petsc-3.3-p0 2012-06-05
2: /*
3: This is where the abstract matrix operations are defined
4: */
6: #include <petsc-private/matimpl.h> /*I "petscmat.h" I*/
7: #include <petsc-private/vecimpl.h>
9: /* Logging support */
10: PetscClassId MAT_CLASSID;
11: PetscClassId MAT_FDCOLORING_CLASSID;
12: PetscClassId MAT_TRANSPOSECOLORING_CLASSID;
14: PetscLogEvent MAT_Mult, MAT_Mults, MAT_MultConstrained, MAT_MultAdd, MAT_MultTranspose;
15: PetscLogEvent MAT_MultTransposeConstrained, MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve;
16: PetscLogEvent MAT_SolveTransposeAdd, MAT_SOR, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic;
17: PetscLogEvent MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor;
18: PetscLogEvent MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin;
19: PetscLogEvent MAT_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetRowIJ, MAT_GetSubMatrices, MAT_GetColoring, MAT_GetOrdering, MAT_GetRedundantMatrix, MAT_GetSeqNonzeroStructure;
20: PetscLogEvent MAT_IncreaseOverlap, MAT_Partitioning, MAT_Coarsen, MAT_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate;
21: PetscLogEvent MAT_FDColoringApply,MAT_Transpose,MAT_FDColoringFunction;
22: PetscLogEvent MAT_TransposeColoringCreate;
23: PetscLogEvent MAT_MatMult, MAT_MatMultSymbolic, MAT_MatMultNumeric;
24: PetscLogEvent MAT_PtAP, MAT_PtAPSymbolic, MAT_PtAPNumeric,MAT_RARt, MAT_RARtSymbolic, MAT_RARtNumeric;
25: PetscLogEvent MAT_MatTransposeMult, MAT_MatTransposeMultSymbolic, MAT_MatTransposeMultNumeric;
26: PetscLogEvent MAT_TransposeMatMult, MAT_TransposeMatMultSymbolic, MAT_TransposeMatMultNumeric;
27: PetscLogEvent MAT_MultHermitianTranspose,MAT_MultHermitianTransposeAdd;
28: PetscLogEvent MAT_Getsymtranspose, MAT_Getsymtransreduced, MAT_Transpose_SeqAIJ, MAT_GetBrowsOfAcols;
29: PetscLogEvent MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym;
30: PetscLogEvent MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure;
31: PetscLogEvent MAT_GetMultiProcBlock;
32: PetscLogEvent MAT_CUSPCopyToGPU, MAT_SetValuesBatch, MAT_SetValuesBatchI, MAT_SetValuesBatchII, MAT_SetValuesBatchIII, MAT_SetValuesBatchIV;
33: PetscLogEvent MAT_Merge;
35: const char *const MatFactorTypes[] = {"NONE","LU","CHOLESKY","ILU","ICC","ILUDT","MatFactorType","MAT_FACTOR_",0};
39: /*@C
40: MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix
42: Input Parameter:
43: . A - the matrix
45: Output Parameter:
46: . keptrows - the rows that are not completely zero
48: Level: intermediate
50: @*/
51: PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows)
52: {
53: PetscErrorCode ierr;
57: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
58: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
59: if (!mat->ops->findnonzerorows) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Not coded for this matrix type");
60: (*mat->ops->findnonzerorows)(mat,keptrows);
61: return(0);
62: }
66: /*@
67: MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling
69: Not Collective
71: Input Parameters:
72: . A - the matrix
74: Output Parameters:
75: . a - the diagonal part (which is a SEQUENTIAL matrix)
77: Notes: see the manual page for MatCreateAIJ() for more information on the "diagonal part" of the matrix.
79: Level: advanced
81: @*/
82: PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a)
83: {
84: PetscErrorCode ierr,(*f)(Mat,Mat*);
85: PetscMPIInt size;
91: if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
92: if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
93: MPI_Comm_size(((PetscObject)A)->comm,&size);
94: PetscObjectQueryFunction((PetscObject)A,"MatGetDiagonalBlock_C",(void (**)(void))&f);
95: if (f) {
96: (*f)(A,a);
97: return(0);
98: } else if (size == 1) {
99: *a = A;
100: } else {
101: const MatType mattype;
102: MatGetType(A,&mattype);
103: SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix type %s does not support getting diagonal block",mattype);
104: }
105: return(0);
106: }
110: /*@
111: MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries.
113: Collective on Mat
115: Input Parameters:
116: . mat - the matrix
118: Output Parameter:
119: . trace - the sum of the diagonal entries
121: Level: advanced
123: @*/
124: PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace)
125: {
127: Vec diag;
130: MatGetVecs(mat,&diag,PETSC_NULL);
131: MatGetDiagonal(mat,diag);
132: VecSum(diag,trace);
133: VecDestroy(&diag);
134: return(0);
135: }
139: /*@
140: MatRealPart - Zeros out the imaginary part of the matrix
142: Logically Collective on Mat
144: Input Parameters:
145: . mat - the matrix
147: Level: advanced
150: .seealso: MatImaginaryPart()
151: @*/
152: PetscErrorCode MatRealPart(Mat mat)
153: {
159: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
160: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
161: if (!mat->ops->realpart) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
162: MatCheckPreallocated(mat,1);
163: (*mat->ops->realpart)(mat);
164: #if defined(PETSC_HAVE_CUSP)
165: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
166: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
167: }
168: #endif
169: return(0);
170: }
174: /*@C
175: MatGetGhosts - Get the global index of all ghost nodes defined by the sparse matrix
177: Collective on Mat
179: Input Parameter:
180: . mat - the matrix
182: Output Parameters:
183: + nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block)
184: - ghosts - the global indices of the ghost points
186: Notes: the nghosts and ghosts are suitable to pass into VecCreateGhost()
188: Level: advanced
190: @*/
191: PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[])
192: {
198: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
199: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
200: if (!mat->ops->getghosts) {
201: if (nghosts) *nghosts = 0;
202: if (ghosts) *ghosts = 0;
203: } else {
204: (*mat->ops->getghosts)(mat,nghosts,ghosts);
205: }
206: return(0);
207: }
212: /*@
213: MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part
215: Logically Collective on Mat
217: Input Parameters:
218: . mat - the matrix
220: Level: advanced
223: .seealso: MatRealPart()
224: @*/
225: PetscErrorCode MatImaginaryPart(Mat mat)
226: {
232: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
233: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
234: if (!mat->ops->imaginarypart) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
235: MatCheckPreallocated(mat,1);
236: (*mat->ops->imaginarypart)(mat);
237: #if defined(PETSC_HAVE_CUSP)
238: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
239: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
240: }
241: #endif
242: return(0);
243: }
247: /*@
248: MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices)
250: Collective on Mat
252: Input Parameter:
253: . mat - the matrix
255: Output Parameters:
256: + missing - is any diagonal missing
257: - dd - first diagonal entry that is missing (optional)
259: Level: advanced
262: .seealso: MatRealPart()
263: @*/
264: PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd)
265: {
271: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
272: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
273: if (!mat->ops->missingdiagonal) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
274: (*mat->ops->missingdiagonal)(mat,missing,dd);
275: return(0);
276: }
280: /*@C
281: MatGetRow - Gets a row of a matrix. You MUST call MatRestoreRow()
282: for each row that you get to ensure that your application does
283: not bleed memory.
285: Not Collective
287: Input Parameters:
288: + mat - the matrix
289: - row - the row to get
291: Output Parameters:
292: + ncols - if not NULL, the number of nonzeros in the row
293: . cols - if not NULL, the column numbers
294: - vals - if not NULL, the values
296: Notes:
297: This routine is provided for people who need to have direct access
298: to the structure of a matrix. We hope that we provide enough
299: high-level matrix routines that few users will need it.
301: MatGetRow() always returns 0-based column indices, regardless of
302: whether the internal representation is 0-based (default) or 1-based.
304: For better efficiency, set cols and/or vals to PETSC_NULL if you do
305: not wish to extract these quantities.
307: The user can only examine the values extracted with MatGetRow();
308: the values cannot be altered. To change the matrix entries, one
309: must use MatSetValues().
311: You can only have one call to MatGetRow() outstanding for a particular
312: matrix at a time, per processor. MatGetRow() can only obtain rows
313: associated with the given processor, it cannot get rows from the
314: other processors; for that we suggest using MatGetSubMatrices(), then
315: MatGetRow() on the submatrix. The row indix passed to MatGetRows()
316: is in the global number of rows.
318: Fortran Notes:
319: The calling sequence from Fortran is
320: .vb
321: MatGetRow(matrix,row,ncols,cols,values,ierr)
322: Mat matrix (input)
323: integer row (input)
324: integer ncols (output)
325: integer cols(maxcols) (output)
326: double precision (or double complex) values(maxcols) output
327: .ve
328: where maxcols >= maximum nonzeros in any row of the matrix.
331: Caution:
332: Do not try to change the contents of the output arrays (cols and vals).
333: In some cases, this may corrupt the matrix.
335: Level: advanced
337: Concepts: matrices^row access
339: .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatGetSubMatrices(), MatGetDiagonal()
340: @*/
341: PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
342: {
344: PetscInt incols;
349: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
350: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
351: if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
352: MatCheckPreallocated(mat,1);
353: PetscLogEventBegin(MAT_GetRow,mat,0,0,0);
354: (*mat->ops->getrow)(mat,row,&incols,(PetscInt **)cols,(PetscScalar **)vals);
355: if (ncols) *ncols = incols;
356: PetscLogEventEnd(MAT_GetRow,mat,0,0,0);
357: return(0);
358: }
362: /*@
363: MatConjugate - replaces the matrix values with their complex conjugates
365: Logically Collective on Mat
367: Input Parameters:
368: . mat - the matrix
370: Level: advanced
372: .seealso: VecConjugate()
373: @*/
374: PetscErrorCode MatConjugate(Mat mat)
375: {
380: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
381: 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");
382: (*mat->ops->conjugate)(mat);
383: #if defined(PETSC_HAVE_CUSP)
384: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
385: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
386: }
387: #endif
388: return(0);
389: }
393: /*@C
394: MatRestoreRow - Frees any temporary space allocated by MatGetRow().
396: Not Collective
398: Input Parameters:
399: + mat - the matrix
400: . row - the row to get
401: . ncols, cols - the number of nonzeros and their columns
402: - vals - if nonzero the column values
404: Notes:
405: This routine should be called after you have finished examining the entries.
407: Fortran Notes:
408: The calling sequence from Fortran is
409: .vb
410: MatRestoreRow(matrix,row,ncols,cols,values,ierr)
411: Mat matrix (input)
412: integer row (input)
413: integer ncols (output)
414: integer cols(maxcols) (output)
415: double precision (or double complex) values(maxcols) output
416: .ve
417: Where maxcols >= maximum nonzeros in any row of the matrix.
419: In Fortran MatRestoreRow() MUST be called after MatGetRow()
420: before another call to MatGetRow() can be made.
422: Level: advanced
424: .seealso: MatGetRow()
425: @*/
426: PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
427: {
433: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
434: if (!mat->ops->restorerow) return(0);
435: (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);
436: return(0);
437: }
441: /*@
442: MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format.
443: You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag.
445: Not Collective
447: Input Parameters:
448: + mat - the matrix
450: Notes:
451: 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.
453: Level: advanced
455: Concepts: matrices^row access
457: .seealso: MatRestoreRowRowUpperTriangular()
458: @*/
459: PetscErrorCode MatGetRowUpperTriangular(Mat mat)
460: {
466: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
467: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
468: if (!mat->ops->getrowuppertriangular) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
469: MatCheckPreallocated(mat,1);
470: (*mat->ops->getrowuppertriangular)(mat);
471: return(0);
472: }
476: /*@
477: MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format.
479: Not Collective
481: Input Parameters:
482: + mat - the matrix
484: Notes:
485: This routine should be called after you have finished MatGetRow/MatRestoreRow().
488: Level: advanced
490: .seealso: MatGetRowUpperTriangular()
491: @*/
492: PetscErrorCode MatRestoreRowUpperTriangular(Mat mat)
493: {
498: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
499: if (!mat->ops->restorerowuppertriangular) return(0);
500: (*mat->ops->restorerowuppertriangular)(mat);
501: return(0);
502: }
506: /*@C
507: MatSetOptionsPrefix - Sets the prefix used for searching for all
508: Mat options in the database.
510: Logically Collective on Mat
512: Input Parameter:
513: + A - the Mat context
514: - prefix - the prefix to prepend to all option names
516: Notes:
517: A hyphen (-) must NOT be given at the beginning of the prefix name.
518: The first character of all runtime options is AUTOMATICALLY the hyphen.
520: Level: advanced
522: .keywords: Mat, set, options, prefix, database
524: .seealso: MatSetFromOptions()
525: @*/
526: PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[])
527: {
532: PetscObjectSetOptionsPrefix((PetscObject)A,prefix);
533: return(0);
534: }
538: /*@C
539: MatAppendOptionsPrefix - Appends to the prefix used for searching for all
540: Mat options in the database.
542: Logically Collective on Mat
544: Input Parameters:
545: + A - the Mat context
546: - prefix - the prefix to prepend to all option names
548: Notes:
549: A hyphen (-) must NOT be given at the beginning of the prefix name.
550: The first character of all runtime options is AUTOMATICALLY the hyphen.
552: Level: advanced
554: .keywords: Mat, append, options, prefix, database
556: .seealso: MatGetOptionsPrefix()
557: @*/
558: PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[])
559: {
561:
564: PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);
565: return(0);
566: }
570: /*@C
571: MatGetOptionsPrefix - Sets the prefix used for searching for all
572: Mat options in the database.
574: Not Collective
576: Input Parameter:
577: . A - the Mat context
579: Output Parameter:
580: . prefix - pointer to the prefix string used
582: Notes: On the fortran side, the user should pass in a string 'prefix' of
583: sufficient length to hold the prefix.
585: Level: advanced
587: .keywords: Mat, get, options, prefix, database
589: .seealso: MatAppendOptionsPrefix()
590: @*/
591: PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[])
592: {
597: PetscObjectGetOptionsPrefix((PetscObject)A,prefix);
598: return(0);
599: }
603: /*@
604: MatSetUp - Sets up the internal matrix data structures for the later use.
606: Collective on Mat
608: Input Parameters:
609: . A - the Mat context
611: Notes:
612: If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used.
614: If a suitable preallocation routine is used, this function does not need to be called.
616: See the Performance chapter of the PETSc users manual for how to preallocate matrices
618: Level: beginner
620: .keywords: Mat, setup
622: .seealso: MatCreate(), MatDestroy()
623: @*/
624: PetscErrorCode MatSetUp(Mat A)
625: {
626: PetscMPIInt size;
631: if (!((PetscObject)A)->type_name) {
632: MPI_Comm_size(((PetscObject)A)->comm, &size);
633: if (size == 1) {
634: MatSetType(A, MATSEQAIJ);
635: } else {
636: MatSetType(A, MATMPIAIJ);
637: }
638: }
639: if (!A->preallocated && A->ops->setup) {
640: PetscInfo(A,"Warning not preallocating matrix storage\n");
641: (*A->ops->setup)(A);
642: }
643: A->preallocated = PETSC_TRUE;
644: return(0);
645: }
650: /*@C
651: MatView - Visualizes a matrix object.
653: Collective on Mat
655: Input Parameters:
656: + mat - the matrix
657: - viewer - visualization context
659: Notes:
660: The available visualization contexts include
661: + PETSC_VIEWER_STDOUT_SELF - standard output (default)
662: . PETSC_VIEWER_STDOUT_WORLD - synchronized standard
663: output where only the first processor opens
664: the file. All other processors send their
665: data to the first processor to print.
666: - PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure
668: The user can open alternative visualization contexts with
669: + PetscViewerASCIIOpen() - Outputs matrix to a specified file
670: . PetscViewerBinaryOpen() - Outputs matrix in binary to a
671: specified file; corresponding input uses MatLoad()
672: . PetscViewerDrawOpen() - Outputs nonzero matrix structure to
673: an X window display
674: - PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
675: Currently only the sequential dense and AIJ
676: matrix types support the Socket viewer.
678: The user can call PetscViewerSetFormat() to specify the output
679: format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
680: PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen). Available formats include
681: + PETSC_VIEWER_DEFAULT - default, prints matrix contents
682: . PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
683: . PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
684: . PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse
685: format common among all matrix types
686: . PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific
687: format (which is in many cases the same as the default)
688: . PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
689: size and structure (not the matrix entries)
690: . PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about
691: the matrix structure
693: Options Database Keys:
694: + -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly()
695: . -mat_view_info_detailed - Prints more detailed info
696: . -mat_view - Prints matrix in ASCII format
697: . -mat_view_matlab - Prints matrix in Matlab format
698: . -mat_view_draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
699: . -display <name> - Sets display name (default is host)
700: . -draw_pause <sec> - Sets number of seconds to pause after display
701: . -mat_view_socket - Sends matrix to socket, can be accessed from Matlab (see the <a href="../../docs/manual.pdf">users manual</a> for details).
702: . -viewer_socket_machine <machine>
703: . -viewer_socket_port <port>
704: . -mat_view_binary - save matrix to file in binary format
705: - -viewer_binary_filename <name>
706: Level: beginner
708: Notes: see the manual page for MatLoad() for the exact format of the binary file when the binary
709: viewer is used.
711: See bin/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary
712: viewer is used.
714: Concepts: matrices^viewing
715: Concepts: matrices^plotting
716: Concepts: matrices^printing
718: .seealso: PetscViewerSetFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(),
719: PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
720: @*/
721: PetscErrorCode MatView(Mat mat,PetscViewer viewer)
722: {
723: PetscErrorCode ierr;
724: PetscInt rows,cols,bs;
725: PetscBool iascii;
726: PetscViewerFormat format;
731: if (!viewer) {
732: PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
733: }
736: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
737: MatCheckPreallocated(mat,1);
739: PetscLogEventBegin(MAT_View,mat,viewer,0,0);
740: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
741: if (iascii) {
742: PetscViewerGetFormat(viewer,&format);
743: if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
744: PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer,"Matrix Object");
745: PetscViewerASCIIPushTab(viewer);
746: MatGetSize(mat,&rows,&cols);
747: MatGetBlockSize(mat,&bs);
748: if (bs != 1) {
749: PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,bs);
750: } else {
751: PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);
752: }
753: if (mat->factortype) {
754: const MatSolverPackage solver;
755: MatFactorGetSolverPackage(mat,&solver);
756: PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);
757: }
758: if (mat->ops->getinfo) {
759: MatInfo info;
760: MatGetInfo(mat,MAT_GLOBAL_SUM,&info);
761: PetscViewerASCIIPrintf(viewer,"total: nonzeros=%D, allocated nonzeros=%D\n",(PetscInt)info.nz_used,(PetscInt)info.nz_allocated);
762: PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls =%D\n",(PetscInt)info.mallocs);
763: }
764: }
765: }
766: if (mat->ops->view) {
767: PetscViewerASCIIPushTab(viewer);
768: (*mat->ops->view)(mat,viewer);
769: PetscViewerASCIIPopTab(viewer);
770: } else if (!iascii) {
771: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Viewer type %s not supported",((PetscObject)viewer)->type_name);
772: }
773: if (iascii) {
774: PetscViewerGetFormat(viewer,&format);
775: if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
776: PetscViewerASCIIPopTab(viewer);
777: }
778: }
779: PetscLogEventEnd(MAT_View,mat,viewer,0,0);
780: return(0);
781: }
783: #if defined(PETSC_USE_DEBUG)
784: #include <../src/sys/totalview/tv_data_display.h>
785: PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat)
786: {
787: TV_add_row("Local rows", "int", &mat->rmap->n);
788: TV_add_row("Local columns", "int", &mat->cmap->n);
789: TV_add_row("Global rows", "int", &mat->rmap->N);
790: TV_add_row("Global columns", "int", &mat->cmap->N);
791: TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name);
792: return TV_format_OK;
793: }
794: #endif
798: /*@C
799: MatLoad - Loads a matrix that has been stored in binary format
800: with MatView(). The matrix format is determined from the options database.
801: Generates a parallel MPI matrix if the communicator has more than one
802: processor. The default matrix type is AIJ.
804: Collective on PetscViewer
806: Input Parameters:
807: + newmat - the newly loaded matrix, this needs to have been created with MatCreate()
808: or some related function before a call to MatLoad()
809: - viewer - binary file viewer, created with PetscViewerBinaryOpen()
811: Options Database Keys:
812: Used with block matrix formats (MATSEQBAIJ, ...) to specify
813: block size
814: . -matload_block_size <bs>
816: Level: beginner
818: Notes:
819: If the Mat type has not yet been given then MATAIJ is used, call MatSetFromOptions() on the
820: Mat before calling this routine if you wish to set it from the options database.
822: MatLoad() automatically loads into the options database any options
823: given in the file filename.info where filename is the name of the file
824: that was passed to the PetscViewerBinaryOpen(). The options in the info
825: file will be ignored if you use the -viewer_binary_skip_info option.
827: If the type or size of newmat is not set before a call to MatLoad, PETSc
828: sets the default matrix type AIJ and sets the local and global sizes.
829: If type and/or size is already set, then the same are used.
831: In parallel, each processor can load a subset of rows (or the
832: entire matrix). This routine is especially useful when a large
833: matrix is stored on disk and only part of it is desired on each
834: processor. For example, a parallel solver may access only some of
835: the rows from each processor. The algorithm used here reads
836: relatively small blocks of data rather than reading the entire
837: matrix and then subsetting it.
839: Notes for advanced users:
840: Most users should not need to know the details of the binary storage
841: format, since MatLoad() and MatView() completely hide these details.
842: But for anyone who's interested, the standard binary matrix storage
843: format is
845: $ int MAT_FILE_CLASSID
846: $ int number of rows
847: $ int number of columns
848: $ int total number of nonzeros
849: $ int *number nonzeros in each row
850: $ int *column indices of all nonzeros (starting index is zero)
851: $ PetscScalar *values of all nonzeros
853: PETSc automatically does the byte swapping for
854: machines that store the bytes reversed, e.g. DEC alpha, freebsd,
855: linux, Windows and the paragon; thus if you write your own binary
856: read/write routines you have to swap the bytes; see PetscBinaryRead()
857: and PetscBinaryWrite() to see how this may be done.
859: .keywords: matrix, load, binary, input
861: .seealso: PetscViewerBinaryOpen(), MatView(), VecLoad()
863: @*/
864: PetscErrorCode MatLoad(Mat newmat,PetscViewer viewer)
865: {
867: PetscBool isbinary,flg;
872: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);
873: if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()");
875: if (!((PetscObject)newmat)->type_name) {
876: MatSetType(newmat,MATAIJ);
877: }
879: if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type");
880: PetscLogEventBegin(MAT_Load,viewer,0,0,0);
881: (*newmat->ops->load)(newmat,viewer);
882: PetscLogEventEnd(MAT_Load,viewer,0,0,0);
884: flg = PETSC_FALSE;
885: PetscOptionsGetBool(((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,PETSC_NULL);
886: if (flg) {
887: MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);
888: MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);
889: }
890: flg = PETSC_FALSE;
891: PetscOptionsGetBool(((PetscObject)newmat)->prefix,"-matload_spd",&flg,PETSC_NULL);
892: if (flg) {
893: MatSetOption(newmat,MAT_SPD,PETSC_TRUE);
894: }
895: return(0);
896: }
900: /*@
901: MatDestroy - Frees space taken by a matrix.
903: Collective on Mat
905: Input Parameter:
906: . A - the matrix
908: Level: beginner
910: @*/
911: PetscErrorCode MatDestroy(Mat *A)
912: {
916: if (!*A) return(0);
918: if (--((PetscObject)(*A))->refct > 0) {*A = PETSC_NULL; return(0);}
919: /* if memory was published with AMS then destroy it */
920: PetscObjectDepublish(*A);
921: if ((*A)->ops->destroy) {
922: (*(*A)->ops->destroy)(*A);
923: }
924: MatNullSpaceDestroy(&(*A)->nullsp);
925: MatNullSpaceDestroy(&(*A)->nearnullsp);
926: PetscLayoutDestroy(&(*A)->rmap);
927: PetscLayoutDestroy(&(*A)->cmap);
928: PetscHeaderDestroy(A);
929: return(0);
930: }
934: /*@
935: MatSetValues - Inserts or adds a block of values into a matrix.
936: These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
937: MUST be called after all calls to MatSetValues() have been completed.
939: Not Collective
941: Input Parameters:
942: + mat - the matrix
943: . v - a logically two-dimensional array of values
944: . m, idxm - the number of rows and their global indices
945: . n, idxn - the number of columns and their global indices
946: - addv - either ADD_VALUES or INSERT_VALUES, where
947: ADD_VALUES adds values to any existing entries, and
948: INSERT_VALUES replaces existing entries with new values
950: Notes:
951: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
952: MatSetUp() before using this routine
954: By default the values, v, are row-oriented. See MatSetOption() for other options.
956: Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
957: options cannot be mixed without intervening calls to the assembly
958: routines.
960: MatSetValues() uses 0-based row and column numbers in Fortran
961: as well as in C.
963: Negative indices may be passed in idxm and idxn, these rows and columns are
964: simply ignored. This allows easily inserting element stiffness matrices
965: with homogeneous Dirchlet boundary conditions that you don't want represented
966: in the matrix.
968: Efficiency Alert:
969: The routine MatSetValuesBlocked() may offer much better efficiency
970: for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
972: Level: beginner
974: Concepts: matrices^putting entries in
976: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
977: InsertMode, INSERT_VALUES, ADD_VALUES
978: @*/
979: PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
980: {
982: #if defined(PETSC_USE_DEBUG)
983: PetscInt i,j;
984: #endif
989: if (!m || !n) return(0); /* no values to insert */
993: MatCheckPreallocated(mat,1);
994: if (mat->insertmode == NOT_SET_VALUES) {
995: mat->insertmode = addv;
996: }
997: #if defined(PETSC_USE_DEBUG)
998: else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
999: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1000: if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1002: if (v) {
1003: for (i=0; i<m; i++) {
1004: for (j=0; j<n; j++) {
1005: if (PetscIsInfOrNanScalar(v[i*n+j]))
1006: #if defined(PETSC_USE_COMPLEX)
1007: SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %G+iG at matrix entry (%D,%D)",PetscRealPart(v[i*n+j]),PetscImaginaryPart(v[i*n+j]),idxm[i],idxn[j]);
1008: #else
1009: SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %G at matrix entry (%D,%D)",(PetscReal)v[i*n+j],idxm[i],idxn[j]);
1010: #endif
1011: }
1012: }
1013: }
1014: #endif
1016: if (mat->assembled) {
1017: mat->was_assembled = PETSC_TRUE;
1018: mat->assembled = PETSC_FALSE;
1019: }
1020: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1021: (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);
1022: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1023: #if defined(PETSC_HAVE_CUSP)
1024: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1025: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1026: }
1027: #endif
1028: return(0);
1029: }
1034: /*@
1035: MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
1036: values into a matrix
1038: Not Collective
1040: Input Parameters:
1041: + mat - the matrix
1042: . row - the (block) row to set
1043: - v - a logically two-dimensional array of values
1045: Notes:
1046: By the values, v, are column-oriented (for the block version) and sorted
1048: All the nonzeros in the row must be provided
1050: The matrix must have previously had its column indices set
1052: The row must belong to this process
1054: Level: intermediate
1056: Concepts: matrices^putting entries in
1058: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1059: InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping()
1060: @*/
1061: PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
1062: {
1069: MatSetValuesRow(mat, mat->rmap->mapping->indices[row],v);
1070: #if defined(PETSC_HAVE_CUSP)
1071: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1072: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1073: }
1074: #endif
1075: return(0);
1076: }
1080: /*@
1081: MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
1082: values into a matrix
1084: Not Collective
1086: Input Parameters:
1087: + mat - the matrix
1088: . row - the (block) row to set
1089: - v - a logically two-dimensional array of values
1091: Notes:
1092: The values, v, are column-oriented for the block version.
1094: All the nonzeros in the row must be provided
1096: THE MATRIX MUSAT HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually MatSetValues() is used.
1098: The row must belong to this process
1100: Level: advanced
1102: Concepts: matrices^putting entries in
1104: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1105: InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1106: @*/
1107: PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
1108: {
1114: MatCheckPreallocated(mat,1);
1116: #if defined(PETSC_USE_DEBUG)
1117: if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
1118: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1119: #endif
1120: mat->insertmode = INSERT_VALUES;
1122: if (mat->assembled) {
1123: mat->was_assembled = PETSC_TRUE;
1124: mat->assembled = PETSC_FALSE;
1125: }
1126: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1127: if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1128: (*mat->ops->setvaluesrow)(mat,row,v);
1129: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1130: #if defined(PETSC_HAVE_CUSP)
1131: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1132: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1133: }
1134: #endif
1135: return(0);
1136: }
1140: /*@
1141: MatSetValuesStencil - Inserts or adds a block of values into a matrix.
1142: Using structured grid indexing
1144: Not Collective
1146: Input Parameters:
1147: + mat - the matrix
1148: . m - number of rows being entered
1149: . idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
1150: . n - number of columns being entered
1151: . idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered
1152: . v - a logically two-dimensional array of values
1153: - addv - either ADD_VALUES or INSERT_VALUES, where
1154: ADD_VALUES adds values to any existing entries, and
1155: INSERT_VALUES replaces existing entries with new values
1157: Notes:
1158: By default the values, v, are row-oriented. See MatSetOption() for other options.
1160: Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
1161: options cannot be mixed without intervening calls to the assembly
1162: routines.
1164: The grid coordinates are across the entire grid, not just the local portion
1166: MatSetValuesStencil() uses 0-based row and column numbers in Fortran
1167: as well as in C.
1169: For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1171: In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1172: or call MatSetLocalToGlobalMapping() and MatSetStencil() first.
1174: The columns and rows in the stencil passed in MUST be contained within the
1175: ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1176: if you create a DMDA with an overlap of one grid level and on a particular process its first
1177: local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1178: first i index you can use in your column and row indices in MatSetStencil() is 5.
1180: In Fortran idxm and idxn should be declared as
1181: $ MatStencil idxm(4,m),idxn(4,n)
1182: and the values inserted using
1183: $ idxm(MatStencil_i,1) = i
1184: $ idxm(MatStencil_j,1) = j
1185: $ idxm(MatStencil_k,1) = k
1186: $ idxm(MatStencil_c,1) = c
1187: etc
1188:
1189: For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
1190: obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
1191: etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
1192: DMDA_BOUNDARY_PERIODIC boundary type.
1194: 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
1195: a single value per point) you can skip filling those indices.
1197: Inspired by the structured grid interface to the HYPRE package
1198: (http://www.llnl.gov/CASC/hypre)
1200: Efficiency Alert:
1201: The routine MatSetValuesBlockedStencil() may offer much better efficiency
1202: for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1204: Level: beginner
1206: Concepts: matrices^putting entries in
1208: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1209: MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil
1210: @*/
1211: PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1212: {
1214: PetscInt buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1215: PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1216: PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1219: if (!m || !n) return(0); /* no values to insert */
1226: if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1227: jdxm = buf; jdxn = buf+m;
1228: } else {
1229: PetscMalloc2(m,PetscInt,&bufm,n,PetscInt,&bufn);
1230: jdxm = bufm; jdxn = bufn;
1231: }
1232: for (i=0; i<m; i++) {
1233: for (j=0; j<3-sdim; j++) dxm++;
1234: tmp = *dxm++ - starts[0];
1235: for (j=0; j<dim-1; j++) {
1236: if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1237: else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1238: }
1239: if (mat->stencil.noc) dxm++;
1240: jdxm[i] = tmp;
1241: }
1242: for (i=0; i<n; i++) {
1243: for (j=0; j<3-sdim; j++) dxn++;
1244: tmp = *dxn++ - starts[0];
1245: for (j=0; j<dim-1; j++) {
1246: if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1247: else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1248: }
1249: if (mat->stencil.noc) dxn++;
1250: jdxn[i] = tmp;
1251: }
1252: MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);
1253: PetscFree2(bufm,bufn);
1254: return(0);
1255: }
1259: /*@C
1260: MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1261: Using structured grid indexing
1263: Not Collective
1265: Input Parameters:
1266: + mat - the matrix
1267: . m - number of rows being entered
1268: . idxm - grid coordinates for matrix rows being entered
1269: . n - number of columns being entered
1270: . idxn - grid coordinates for matrix columns being entered
1271: . v - a logically two-dimensional array of values
1272: - addv - either ADD_VALUES or INSERT_VALUES, where
1273: ADD_VALUES adds values to any existing entries, and
1274: INSERT_VALUES replaces existing entries with new values
1276: Notes:
1277: By default the values, v, are row-oriented and unsorted.
1278: See MatSetOption() for other options.
1280: Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
1281: options cannot be mixed without intervening calls to the assembly
1282: routines.
1284: The grid coordinates are across the entire grid, not just the local portion
1286: MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran
1287: as well as in C.
1289: For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1291: In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1292: or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first.
1294: The columns and rows in the stencil passed in MUST be contained within the
1295: ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1296: if you create a DMDA with an overlap of one grid level and on a particular process its first
1297: local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1298: first i index you can use in your column and row indices in MatSetStencil() is 5.
1300: In Fortran idxm and idxn should be declared as
1301: $ MatStencil idxm(4,m),idxn(4,n)
1302: and the values inserted using
1303: $ idxm(MatStencil_i,1) = i
1304: $ idxm(MatStencil_j,1) = j
1305: $ idxm(MatStencil_k,1) = k
1306: etc
1308: Negative indices may be passed in idxm and idxn, these rows and columns are
1309: simply ignored. This allows easily inserting element stiffness matrices
1310: with homogeneous Dirchlet boundary conditions that you don't want represented
1311: in the matrix.
1313: Inspired by the structured grid interface to the HYPRE package
1314: (http://www.llnl.gov/CASC/hypre)
1316: Level: beginner
1318: Concepts: matrices^putting entries in
1320: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1321: MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil,
1322: MatSetBlockSize(), MatSetLocalToGlobalMapping()
1323: @*/
1324: PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1325: {
1327: PetscInt buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1328: PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1329: PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1332: if (!m || !n) return(0); /* no values to insert */
1339: if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1340: jdxm = buf; jdxn = buf+m;
1341: } else {
1342: PetscMalloc2(m,PetscInt,&bufm,n,PetscInt,&bufn);
1343: jdxm = bufm; jdxn = bufn;
1344: }
1345: for (i=0; i<m; i++) {
1346: for (j=0; j<3-sdim; j++) dxm++;
1347: tmp = *dxm++ - starts[0];
1348: for (j=0; j<sdim-1; j++) {
1349: if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1350: else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1351: }
1352: dxm++;
1353: jdxm[i] = tmp;
1354: }
1355: for (i=0; i<n; i++) {
1356: for (j=0; j<3-sdim; j++) dxn++;
1357: tmp = *dxn++ - starts[0];
1358: for (j=0; j<sdim-1; j++) {
1359: if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1360: else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1361: }
1362: dxn++;
1363: jdxn[i] = tmp;
1364: }
1365: MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);
1366: PetscFree2(bufm,bufn);
1367: #if defined(PETSC_HAVE_CUSP)
1368: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1369: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1370: }
1371: #endif
1372: return(0);
1373: }
1377: /*@
1378: MatSetStencil - Sets the grid information for setting values into a matrix via
1379: MatSetValuesStencil()
1381: Not Collective
1383: Input Parameters:
1384: + mat - the matrix
1385: . dim - dimension of the grid 1, 2, or 3
1386: . dims - number of grid points in x, y, and z direction, including ghost points on your processor
1387: . starts - starting point of ghost nodes on your processor in x, y, and z direction
1388: - dof - number of degrees of freedom per node
1391: Inspired by the structured grid interface to the HYPRE package
1392: (www.llnl.gov/CASC/hyper)
1394: For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the
1395: user.
1396:
1397: Level: beginner
1399: Concepts: matrices^putting entries in
1401: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1402: MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
1403: @*/
1404: PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1405: {
1406: PetscInt i;
1413: mat->stencil.dim = dim + (dof > 1);
1414: for (i=0; i<dim; i++) {
1415: mat->stencil.dims[i] = dims[dim-i-1]; /* copy the values in backwards */
1416: mat->stencil.starts[i] = starts[dim-i-1];
1417: }
1418: mat->stencil.dims[dim] = dof;
1419: mat->stencil.starts[dim] = 0;
1420: mat->stencil.noc = (PetscBool)(dof == 1);
1421: return(0);
1422: }
1426: /*@
1427: MatSetValuesBlocked - Inserts or adds a block of values into a matrix.
1429: Not Collective
1431: Input Parameters:
1432: + mat - the matrix
1433: . v - a logically two-dimensional array of values
1434: . m, idxm - the number of block rows and their global block indices
1435: . n, idxn - the number of block columns and their global block indices
1436: - addv - either ADD_VALUES or INSERT_VALUES, where
1437: ADD_VALUES adds values to any existing entries, and
1438: INSERT_VALUES replaces existing entries with new values
1440: Notes:
1441: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call
1442: MatXXXXSetPreallocation() or MatSetUp() before using this routine.
1444: The m and n count the NUMBER of blocks in the row direction and column direction,
1445: NOT the total number of rows/columns; for example, if the block size is 2 and
1446: you are passing in values for rows 2,3,4,5 then m would be 2 (not 4).
1447: The values in idxm would be 1 2; that is the first index for each block divided by
1448: the block size.
1450: Note that you must call MatSetBlockSize() when constructing this matrix (after
1451: preallocating it).
1453: By default the values, v, are row-oriented, so the layout of
1454: v is the same as for MatSetValues(). See MatSetOption() for other options.
1456: Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
1457: options cannot be mixed without intervening calls to the assembly
1458: routines.
1460: MatSetValuesBlocked() uses 0-based row and column numbers in Fortran
1461: as well as in C.
1463: Negative indices may be passed in idxm and idxn, these rows and columns are
1464: simply ignored. This allows easily inserting element stiffness matrices
1465: with homogeneous Dirchlet boundary conditions that you don't want represented
1466: in the matrix.
1468: Each time an entry is set within a sparse matrix via MatSetValues(),
1469: internal searching must be done to determine where to place the the
1470: data in the matrix storage space. By instead inserting blocks of
1471: entries via MatSetValuesBlocked(), the overhead of matrix assembly is
1472: reduced.
1474: Example:
1475: $ Suppose m=n=2 and block size(bs) = 2 The array is
1476: $
1477: $ 1 2 | 3 4
1478: $ 5 6 | 7 8
1479: $ - - - | - - -
1480: $ 9 10 | 11 12
1481: $ 13 14 | 15 16
1482: $
1483: $ v[] should be passed in like
1484: $ v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
1485: $
1486: $ If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then
1487: $ v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16]
1489: Level: intermediate
1491: Concepts: matrices^putting entries in blocked
1493: .seealso: MatSetBlockSize(), MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal()
1494: @*/
1495: PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1496: {
1502: if (!m || !n) return(0); /* no values to insert */
1506: MatCheckPreallocated(mat,1);
1507: if (mat->insertmode == NOT_SET_VALUES) {
1508: mat->insertmode = addv;
1509: }
1510: #if defined(PETSC_USE_DEBUG)
1511: else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1512: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1513: if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1514: #endif
1516: if (mat->assembled) {
1517: mat->was_assembled = PETSC_TRUE;
1518: mat->assembled = PETSC_FALSE;
1519: }
1520: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1521: if (mat->ops->setvaluesblocked) {
1522: (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);
1523: } else {
1524: PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn;
1525: PetscInt i,j,bs=mat->rmap->bs;
1526: if ((m+n)*bs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1527: iidxm = buf; iidxn = buf + m*bs;
1528: } else {
1529: PetscMalloc2(m*bs,PetscInt,&bufr,n*bs,PetscInt,&bufc);
1530: iidxm = bufr; iidxn = bufc;
1531: }
1532: for (i=0; i<m; i++)
1533: for (j=0; j<bs; j++)
1534: iidxm[i*bs+j] = bs*idxm[i] + j;
1535: for (i=0; i<n; i++)
1536: for (j=0; j<bs; j++)
1537: iidxn[i*bs+j] = bs*idxn[i] + j;
1538: MatSetValues(mat,m*bs,iidxm,n*bs,iidxn,v,addv);
1539: PetscFree2(bufr,bufc);
1540: }
1541: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1542: #if defined(PETSC_HAVE_CUSP)
1543: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1544: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1545: }
1546: #endif
1547: return(0);
1548: }
1552: /*@
1553: MatGetValues - Gets a block of values from a matrix.
1555: Not Collective; currently only returns a local block
1557: Input Parameters:
1558: + mat - the matrix
1559: . v - a logically two-dimensional array for storing the values
1560: . m, idxm - the number of rows and their global indices
1561: - n, idxn - the number of columns and their global indices
1563: Notes:
1564: The user must allocate space (m*n PetscScalars) for the values, v.
1565: The values, v, are then returned in a row-oriented format,
1566: analogous to that used by default in MatSetValues().
1568: MatGetValues() uses 0-based row and column numbers in
1569: Fortran as well as in C.
1571: MatGetValues() requires that the matrix has been assembled
1572: with MatAssemblyBegin()/MatAssemblyEnd(). Thus, calls to
1573: MatSetValues() and MatGetValues() CANNOT be made in succession
1574: without intermediate matrix assembly.
1576: Negative row or column indices will be ignored and those locations in v[] will be
1577: left unchanged.
1579: Level: advanced
1581: Concepts: matrices^accessing values
1583: .seealso: MatGetRow(), MatGetSubMatrices(), MatSetValues()
1584: @*/
1585: PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1586: {
1592: if (!m || !n) return(0);
1596: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1597: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1598: if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1599: MatCheckPreallocated(mat,1);
1601: PetscLogEventBegin(MAT_GetValues,mat,0,0,0);
1602: (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);
1603: PetscLogEventEnd(MAT_GetValues,mat,0,0,0);
1604: return(0);
1605: }
1609: /*@
1610: MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and
1611: the same size. Currently, this can only be called once and creates the given matrix.
1613: Not Collective
1615: Input Parameters:
1616: + mat - the matrix
1617: . nb - the number of blocks
1618: . bs - the number of rows (and columns) in each block
1619: . rows - a concatenation of the rows for each block
1620: - v - a concatenation of logically two-dimensional arrays of values
1622: Notes:
1623: In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix.
1625: Level: advanced
1627: Concepts: matrices^putting entries in
1629: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1630: InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1631: @*/
1632: PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[])
1633: {
1641: #if defined(PETSC_USE_DEBUG)
1642: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1643: #endif
1645: PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);
1646: if (mat->ops->setvaluesbatch) {
1647: (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);
1648: } else {
1649: PetscInt b;
1650: for(b = 0; b < nb; ++b) {
1651: MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);
1652: }
1653: }
1654: PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);
1655: return(0);
1656: }
1660: /*@
1661: MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
1662: the routine MatSetValuesLocal() to allow users to insert matrix entries
1663: using a local (per-processor) numbering.
1665: Not Collective
1667: Input Parameters:
1668: + x - the matrix
1669: . rmapping - row mapping created with ISLocalToGlobalMappingCreate()
1670: or ISLocalToGlobalMappingCreateIS()
1671: - cmapping - column mapping
1673: Level: intermediate
1675: Concepts: matrices^local to global mapping
1676: Concepts: local to global mapping^for matrices
1678: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
1679: @*/
1680: PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
1681: {
1689: if (x->ops->setlocaltoglobalmapping) {
1690: (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);
1691: } else {
1692: PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);
1693: PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);
1694: }
1695: return(0);
1696: }
1700: /*@
1701: MatSetLocalToGlobalMappingBlock - Sets a local-to-global numbering for use
1702: by the routine MatSetValuesBlockedLocal() to allow users to insert matrix
1703: entries using a local (per-processor) numbering.
1705: Not Collective
1707: Input Parameters:
1708: + x - the matrix
1709: . rmapping - row mapping created with ISLocalToGlobalMappingCreate() or
1710: ISLocalToGlobalMappingCreateIS()
1711: - cmapping - column mapping
1713: Level: intermediate
1715: Concepts: matrices^local to global mapping blocked
1716: Concepts: local to global mapping^for matrices, blocked
1718: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal(),
1719: MatSetValuesBlocked(), MatSetValuesLocal()
1720: @*/
1721: PetscErrorCode MatSetLocalToGlobalMappingBlock(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
1722: {
1730: PetscLayoutSetISLocalToGlobalMappingBlock(x->rmap,rmapping);
1731: PetscLayoutSetISLocalToGlobalMappingBlock(x->cmap,cmapping);
1732: return(0);
1733: }
1737: /*@
1738: MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping()
1740: Not Collective
1742: Input Parameters:
1743: . A - the matrix
1745: Output Parameters:
1746: + rmapping - row mapping
1747: - cmapping - column mapping
1749: Level: advanced
1751: Concepts: matrices^local to global mapping
1752: Concepts: local to global mapping^for matrices
1754: .seealso: MatSetValuesLocal(), MatGetLocalToGlobalMappingBlock()
1755: @*/
1756: PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
1757: {
1763: if (rmapping) *rmapping = A->rmap->mapping;
1764: if (cmapping) *cmapping = A->cmap->mapping;
1765: return(0);
1766: }
1770: /*@
1771: MatGetLocalToGlobalMappingBlock - Gets the local-to-global numbering set by MatSetLocalToGlobalMappingBlock()
1773: Not Collective
1775: Input Parameters:
1776: . A - the matrix
1778: Output Parameters:
1779: + rmapping - row mapping
1780: - cmapping - column mapping
1782: Level: advanced
1784: Concepts: matrices^local to global mapping blocked
1785: Concepts: local to global mapping^for matrices, blocked
1787: .seealso: MatSetValuesBlockedLocal(), MatGetLocalToGlobalMapping()
1788: @*/
1789: PetscErrorCode MatGetLocalToGlobalMappingBlock(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
1790: {
1796: if (rmapping) *rmapping = A->rmap->bmapping;
1797: if (cmapping) *cmapping = A->cmap->bmapping;
1798: return(0);
1799: }
1803: /*@
1804: MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
1805: using a local ordering of the nodes.
1807: Not Collective
1809: Input Parameters:
1810: + x - the matrix
1811: . nrow, irow - number of rows and their local indices
1812: . ncol, icol - number of columns and their local indices
1813: . y - a logically two-dimensional array of values
1814: - addv - either INSERT_VALUES or ADD_VALUES, where
1815: ADD_VALUES adds values to any existing entries, and
1816: INSERT_VALUES replaces existing entries with new values
1818: Notes:
1819: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
1820: MatSetUp() before using this routine
1822: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine
1824: Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
1825: options cannot be mixed without intervening calls to the assembly
1826: routines.
1828: These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1829: MUST be called after all calls to MatSetValuesLocal() have been completed.
1831: Level: intermediate
1833: Concepts: matrices^putting entries in with local numbering
1835: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
1836: MatSetValueLocal()
1837: @*/
1838: PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
1839: {
1845: MatCheckPreallocated(mat,1);
1846: if (!nrow || !ncol) return(0); /* no values to insert */
1850: if (mat->insertmode == NOT_SET_VALUES) {
1851: mat->insertmode = addv;
1852: }
1853: #if defined(PETSC_USE_DEBUG)
1854: else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1855: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1856: if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1857: #endif
1859: if (mat->assembled) {
1860: mat->was_assembled = PETSC_TRUE;
1861: mat->assembled = PETSC_FALSE;
1862: }
1863: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1864: if (mat->ops->setvalueslocal) {
1865: (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);
1866: } else {
1867: PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
1868: if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1869: irowm = buf; icolm = buf+nrow;
1870: } else {
1871: PetscMalloc2(nrow,PetscInt,&bufr,ncol,PetscInt,&bufc);
1872: irowm = bufr; icolm = bufc;
1873: }
1874: ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);
1875: ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);
1876: MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);
1877: PetscFree2(bufr,bufc);
1878: }
1879: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1880: #if defined(PETSC_HAVE_CUSP)
1881: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1882: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1883: }
1884: #endif
1885: return(0);
1886: }
1890: /*@
1891: MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix,
1892: using a local ordering of the nodes a block at a time.
1894: Not Collective
1896: Input Parameters:
1897: + x - the matrix
1898: . nrow, irow - number of rows and their local indices
1899: . ncol, icol - number of columns and their local indices
1900: . y - a logically two-dimensional array of values
1901: - addv - either INSERT_VALUES or ADD_VALUES, where
1902: ADD_VALUES adds values to any existing entries, and
1903: INSERT_VALUES replaces existing entries with new values
1905: Notes:
1906: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
1907: MatSetUp() before using this routine
1909: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMappingBlock()
1910: before using this routineBefore calling MatSetValuesLocal(), the user must first set the
1912: Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
1913: options cannot be mixed without intervening calls to the assembly
1914: routines.
1916: These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1917: MUST be called after all calls to MatSetValuesBlockedLocal() have been completed.
1919: Level: intermediate
1921: Concepts: matrices^putting blocked values in with local numbering
1923: .seealso: MatSetBlockSize(), MatSetLocalToGlobalMappingBlock(), MatAssemblyBegin(), MatAssemblyEnd(),
1924: MatSetValuesLocal(), MatSetLocalToGlobalMappingBlock(), MatSetValuesBlocked()
1925: @*/
1926: PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
1927: {
1933: MatCheckPreallocated(mat,1);
1934: if (!nrow || !ncol) return(0); /* no values to insert */
1938: if (mat->insertmode == NOT_SET_VALUES) {
1939: mat->insertmode = addv;
1940: }
1941: #if defined(PETSC_USE_DEBUG)
1942: else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1943: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1944: 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);
1945: #endif
1947: if (mat->assembled) {
1948: mat->was_assembled = PETSC_TRUE;
1949: mat->assembled = PETSC_FALSE;
1950: }
1951: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1952: if (mat->ops->setvaluesblockedlocal) {
1953: (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);
1954: } else {
1955: PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
1956: if (mat->rmap->bmapping && mat->cmap->bmapping) {
1957: if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1958: irowm = buf; icolm = buf + nrow;
1959: } else {
1960: PetscMalloc2(nrow,PetscInt,&bufr,ncol,PetscInt,&bufc);
1961: irowm = bufr; icolm = bufc;
1962: }
1963: ISLocalToGlobalMappingApply(mat->rmap->bmapping,nrow,irow,irowm);
1964: ISLocalToGlobalMappingApply(mat->cmap->bmapping,ncol,icol,icolm);
1965: MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);
1966: PetscFree2(bufr,bufc);
1967: } else {
1968: PetscInt i,j,bs=mat->rmap->bs;
1969: if ((nrow+ncol)*bs <=(PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1970: irowm = buf; icolm = buf + nrow;
1971: } else {
1972: PetscMalloc2(nrow*bs,PetscInt,&bufr,ncol*bs,PetscInt,&bufc);
1973: irowm = bufr; icolm = bufc;
1974: }
1975: for (i=0; i<nrow; i++)
1976: for (j=0; j<bs; j++)
1977: irowm[i*bs+j] = irow[i]*bs+j;
1978: for (i=0; i<ncol; i++)
1979: for (j=0; j<bs; j++)
1980: icolm[i*bs+j] = icol[i]*bs+j;
1981: MatSetValuesLocal(mat,nrow*bs,irowm,ncol*bs,icolm,y,addv);
1982: PetscFree2(bufr,bufc);
1983: }
1984: }
1985: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1986: #if defined(PETSC_HAVE_CUSP)
1987: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1988: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1989: }
1990: #endif
1991: return(0);
1992: }
1996: /*@
1997: MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal
1999: Collective on Mat and Vec
2001: Input Parameters:
2002: + mat - the matrix
2003: - x - the vector to be multiplied
2005: Output Parameters:
2006: . y - the result
2008: Notes:
2009: The vectors x and y cannot be the same. I.e., one cannot
2010: call MatMult(A,y,y).
2012: Level: developer
2014: Concepts: matrix-vector product
2016: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2017: @*/
2018: PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y)
2019: {
2028: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2029: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2030: if (x == y) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2031: MatCheckPreallocated(mat,1);
2033: if (!mat->ops->multdiagonalblock) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2034: (*mat->ops->multdiagonalblock)(mat,x,y);
2035: PetscObjectStateIncrease((PetscObject)y);
2036: return(0);
2037: }
2039: /* --------------------------------------------------------*/
2042: /*@
2043: MatMult - Computes the matrix-vector product, y = Ax.
2045: Neighbor-wise Collective on Mat and Vec
2047: Input Parameters:
2048: + mat - the matrix
2049: - x - the vector to be multiplied
2051: Output Parameters:
2052: . y - the result
2054: Notes:
2055: The vectors x and y cannot be the same. I.e., one cannot
2056: call MatMult(A,y,y).
2058: Level: beginner
2060: Concepts: matrix-vector product
2062: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2063: @*/
2064: PetscErrorCode MatMult(Mat mat,Vec x,Vec y)
2065: {
2073: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2074: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2075: if (x == y) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2076: #ifndef PETSC_HAVE_CONSTRAINTS
2077: 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);
2078: 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);
2079: 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);
2080: #endif
2081: VecValidValues(x,2,PETSC_TRUE);
2082: MatCheckPreallocated(mat,1);
2084: if (!mat->ops->mult) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2085: PetscLogEventBegin(MAT_Mult,mat,x,y,0);
2086: (*mat->ops->mult)(mat,x,y);
2087: PetscLogEventEnd(MAT_Mult,mat,x,y,0);
2088: VecValidValues(y,3,PETSC_FALSE);
2089: return(0);
2090: }
2094: /*@
2095: MatMultTranspose - Computes matrix transpose times a vector.
2097: Neighbor-wise Collective on Mat and Vec
2099: Input Parameters:
2100: + mat - the matrix
2101: - x - the vector to be multilplied
2103: Output Parameters:
2104: . y - the result
2106: Notes:
2107: The vectors x and y cannot be the same. I.e., one cannot
2108: call MatMultTranspose(A,y,y).
2110: For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple,
2111: use MatMultHermitianTranspose()
2113: Level: beginner
2115: Concepts: matrix vector product^transpose
2117: .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose()
2118: @*/
2119: PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y)
2120: {
2129: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2130: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2131: if (x == y) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2132: #ifndef PETSC_HAVE_CONSTRAINTS
2133: 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);
2134: 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);
2135: #endif
2136: VecValidValues(x,2,PETSC_TRUE);
2137: MatCheckPreallocated(mat,1);
2139: if (!mat->ops->multtranspose) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"This matrix type does not have a multiply tranpose defined");
2140: PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);
2141: (*mat->ops->multtranspose)(mat,x,y);
2142: PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);
2143: PetscObjectStateIncrease((PetscObject)y);
2144: VecValidValues(y,3,PETSC_FALSE);
2145: return(0);
2146: }
2150: /*@
2151: MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.
2153: Neighbor-wise Collective on Mat and Vec
2155: Input Parameters:
2156: + mat - the matrix
2157: - x - the vector to be multilplied
2159: Output Parameters:
2160: . y - the result
2162: Notes:
2163: The vectors x and y cannot be the same. I.e., one cannot
2164: call MatMultHermitianTranspose(A,y,y).
2166: Also called the conjugate transpose, complex conjugate transpose, or adjoint.
2168: For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical.
2170: Level: beginner
2172: Concepts: matrix vector product^transpose
2174: .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose()
2175: @*/
2176: PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y)
2177: {
2186: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2187: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2188: if (x == y) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2189: #ifndef PETSC_HAVE_CONSTRAINTS
2190: 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);
2191: 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);
2192: #endif
2193: MatCheckPreallocated(mat,1);
2195: if (!mat->ops->multhermitiantranspose) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2196: PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);
2197: (*mat->ops->multhermitiantranspose)(mat,x,y);
2198: PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);
2199: PetscObjectStateIncrease((PetscObject)y);
2200: return(0);
2201: }
2205: /*@
2206: MatMultAdd - Computes v3 = v2 + A * v1.
2208: Neighbor-wise Collective on Mat and Vec
2210: Input Parameters:
2211: + mat - the matrix
2212: - v1, v2 - the vectors
2214: Output Parameters:
2215: . v3 - the result
2217: Notes:
2218: The vectors v1 and v3 cannot be the same. I.e., one cannot
2219: call MatMultAdd(A,v1,v2,v1).
2221: Level: beginner
2223: Concepts: matrix vector product^addition
2225: .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
2226: @*/
2227: PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2228: {
2238: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2239: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2240: 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);
2241: /* 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);
2242: 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); */
2243: 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);
2244: 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);
2245: if (v1 == v3) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2246: MatCheckPreallocated(mat,1);
2248: if (!mat->ops->multadd) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name);
2249: PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);
2250: (*mat->ops->multadd)(mat,v1,v2,v3);
2251: PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);
2252: PetscObjectStateIncrease((PetscObject)v3);
2253: return(0);
2254: }
2258: /*@
2259: MatMultTransposeAdd - Computes v3 = v2 + A' * v1.
2261: Neighbor-wise Collective on Mat and Vec
2263: Input Parameters:
2264: + mat - the matrix
2265: - v1, v2 - the vectors
2267: Output Parameters:
2268: . v3 - the result
2270: Notes:
2271: The vectors v1 and v3 cannot be the same. I.e., one cannot
2272: call MatMultTransposeAdd(A,v1,v2,v1).
2274: Level: beginner
2276: Concepts: matrix vector product^transpose and addition
2278: .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
2279: @*/
2280: PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2281: {
2291: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2292: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2293: if (!mat->ops->multtransposeadd) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2294: if (v1 == v3) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2295: 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);
2296: 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);
2297: 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);
2298: MatCheckPreallocated(mat,1);
2300: PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);
2301: (*mat->ops->multtransposeadd)(mat,v1,v2,v3);
2302: PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);
2303: PetscObjectStateIncrease((PetscObject)v3);
2304: return(0);
2305: }
2309: /*@
2310: MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1.
2312: Neighbor-wise Collective on Mat and Vec
2314: Input Parameters:
2315: + mat - the matrix
2316: - v1, v2 - the vectors
2318: Output Parameters:
2319: . v3 - the result
2321: Notes:
2322: The vectors v1 and v3 cannot be the same. I.e., one cannot
2323: call MatMultHermitianTransposeAdd(A,v1,v2,v1).
2325: Level: beginner
2327: Concepts: matrix vector product^transpose and addition
2329: .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult()
2330: @*/
2331: PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2332: {
2342: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2343: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2344: if (!mat->ops->multhermitiantransposeadd) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2345: if (v1 == v3) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2346: 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);
2347: 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);
2348: 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);
2349: MatCheckPreallocated(mat,1);
2351: PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2352: (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);
2353: PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2354: PetscObjectStateIncrease((PetscObject)v3);
2355: return(0);
2356: }
2360: /*@
2361: MatMultConstrained - The inner multiplication routine for a
2362: constrained matrix P^T A P.
2364: Neighbor-wise Collective on Mat and Vec
2366: Input Parameters:
2367: + mat - the matrix
2368: - x - the vector to be multilplied
2370: Output Parameters:
2371: . y - the result
2373: Notes:
2374: The vectors x and y cannot be the same. I.e., one cannot
2375: call MatMult(A,y,y).
2377: Level: beginner
2379: .keywords: matrix, multiply, matrix-vector product, constraint
2380: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2381: @*/
2382: PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y)
2383: {
2390: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2391: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2392: if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2393: 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);
2394: 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);
2395: 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);
2397: PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2398: (*mat->ops->multconstrained)(mat,x,y);
2399: PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2400: PetscObjectStateIncrease((PetscObject)y);
2402: return(0);
2403: }
2407: /*@
2408: MatMultTransposeConstrained - The inner multiplication routine for a
2409: constrained matrix P^T A^T P.
2411: Neighbor-wise Collective on Mat and Vec
2413: Input Parameters:
2414: + mat - the matrix
2415: - x - the vector to be multilplied
2417: Output Parameters:
2418: . y - the result
2420: Notes:
2421: The vectors x and y cannot be the same. I.e., one cannot
2422: call MatMult(A,y,y).
2424: Level: beginner
2426: .keywords: matrix, multiply, matrix-vector product, constraint
2427: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2428: @*/
2429: PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2430: {
2437: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2438: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2439: if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2440: 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);
2441: 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);
2443: PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2444: (*mat->ops->multtransposeconstrained)(mat,x,y);
2445: PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2446: PetscObjectStateIncrease((PetscObject)y);
2448: return(0);
2449: }
2453: /*@C
2454: MatGetFactorType - gets the type of factorization it is
2456: Note Collective
2457: as the flag
2459: Input Parameters:
2460: . mat - the matrix
2462: Output Parameters:
2463: . t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT
2465: Level: intermediate
2467: .seealso: MatFactorType, MatGetFactor()
2468: @*/
2469: PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t)
2470: {
2474: *t = mat->factortype;
2475: return(0);
2476: }
2478: /* ------------------------------------------------------------*/
2481: /*@C
2482: MatGetInfo - Returns information about matrix storage (number of
2483: nonzeros, memory, etc.).
2485: Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag
2487: Input Parameters:
2488: . mat - the matrix
2490: Output Parameters:
2491: + flag - flag indicating the type of parameters to be returned
2492: (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2493: MAT_GLOBAL_SUM - sum over all processors)
2494: - info - matrix information context
2496: Notes:
2497: The MatInfo context contains a variety of matrix data, including
2498: number of nonzeros allocated and used, number of mallocs during
2499: matrix assembly, etc. Additional information for factored matrices
2500: is provided (such as the fill ratio, number of mallocs during
2501: factorization, etc.). Much of this info is printed to PETSC_STDOUT
2502: when using the runtime options
2503: $ -info -mat_view_info
2505: Example for C/C++ Users:
2506: See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2507: data within the MatInfo context. For example,
2508: .vb
2509: MatInfo info;
2510: Mat A;
2511: double mal, nz_a, nz_u;
2513: MatGetInfo(A,MAT_LOCAL,&info);
2514: mal = info.mallocs;
2515: nz_a = info.nz_allocated;
2516: .ve
2518: Example for Fortran Users:
2519: Fortran users should declare info as a double precision
2520: array of dimension MAT_INFO_SIZE, and then extract the parameters
2521: of interest. See the file ${PETSC_DIR}/include/finclude/petscmat.h
2522: a complete list of parameter names.
2523: .vb
2524: double precision info(MAT_INFO_SIZE)
2525: double precision mal, nz_a
2526: Mat A
2527: integer ierr
2529: call MatGetInfo(A,MAT_LOCAL,info,ierr)
2530: mal = info(MAT_INFO_MALLOCS)
2531: nz_a = info(MAT_INFO_NZ_ALLOCATED)
2532: .ve
2534: Level: intermediate
2536: Concepts: matrices^getting information on
2537:
2538: Developer Note: fortran interface is not autogenerated as the f90
2539: interface defintion cannot be generated correctly [due to MatInfo]
2541: .seealso: MatStashGetInfo()
2542:
2543: @*/
2544: PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2545: {
2552: if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2553: MatCheckPreallocated(mat,1);
2554: (*mat->ops->getinfo)(mat,flag,info);
2555: return(0);
2556: }
2558: /* ----------------------------------------------------------*/
2562: /*@C
2563: MatLUFactor - Performs in-place LU factorization of matrix.
2565: Collective on Mat
2567: Input Parameters:
2568: + mat - the matrix
2569: . row - row permutation
2570: . col - column permutation
2571: - info - options for factorization, includes
2572: $ fill - expected fill as ratio of original fill.
2573: $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2574: $ Run with the option -info to determine an optimal value to use
2576: Notes:
2577: Most users should employ the simplified KSP interface for linear solvers
2578: instead of working directly with matrix algebra routines such as this.
2579: See, e.g., KSPCreate().
2581: This changes the state of the matrix to a factored matrix; it cannot be used
2582: for example with MatSetValues() unless one first calls MatSetUnfactored().
2584: Level: developer
2586: Concepts: matrices^LU factorization
2588: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2589: MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor()
2591: Developer Note: fortran interface is not autogenerated as the f90
2592: interface defintion cannot be generated correctly [due to MatFactorInfo]
2594: @*/
2595: PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2596: {
2598: MatFactorInfo tinfo;
2606: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2607: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2608: if (!mat->ops->lufactor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2609: MatCheckPreallocated(mat,1);
2610: if (!info) {
2611: MatFactorInfoInitialize(&tinfo);
2612: info = &tinfo;
2613: }
2615: PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);
2616: (*mat->ops->lufactor)(mat,row,col,info);
2617: PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);
2618: PetscObjectStateIncrease((PetscObject)mat);
2619: return(0);
2620: }
2624: /*@C
2625: MatILUFactor - Performs in-place ILU factorization of matrix.
2627: Collective on Mat
2629: Input Parameters:
2630: + mat - the matrix
2631: . row - row permutation
2632: . col - column permutation
2633: - info - structure containing
2634: $ levels - number of levels of fill.
2635: $ expected fill - as ratio of original fill.
2636: $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2637: missing diagonal entries)
2639: Notes:
2640: Probably really in-place only when level of fill is zero, otherwise allocates
2641: new space to store factored matrix and deletes previous memory.
2643: Most users should employ the simplified KSP interface for linear solvers
2644: instead of working directly with matrix algebra routines such as this.
2645: See, e.g., KSPCreate().
2647: Level: developer
2649: Concepts: matrices^ILU factorization
2651: .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
2653: Developer Note: fortran interface is not autogenerated as the f90
2654: interface defintion cannot be generated correctly [due to MatFactorInfo]
2656: @*/
2657: PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2658: {
2667: if (mat->rmap->N != mat->cmap->N) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONG,"matrix must be square");
2668: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2669: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2670: if (!mat->ops->ilufactor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2671: MatCheckPreallocated(mat,1);
2673: PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);
2674: (*mat->ops->ilufactor)(mat,row,col,info);
2675: PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);
2676: PetscObjectStateIncrease((PetscObject)mat);
2677: return(0);
2678: }
2682: /*@C
2683: MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
2684: Call this routine before calling MatLUFactorNumeric().
2686: Collective on Mat
2688: Input Parameters:
2689: + fact - the factor matrix obtained with MatGetFactor()
2690: . mat - the matrix
2691: . row, col - row and column permutations
2692: - info - options for factorization, includes
2693: $ fill - expected fill as ratio of original fill.
2694: $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2695: $ Run with the option -info to determine an optimal value to use
2698: Notes:
2699: See the <a href="../../docs/manual.pdf">users manual</a> for additional information about
2700: choosing the fill factor for better efficiency.
2702: Most users should employ the simplified KSP interface for linear solvers
2703: instead of working directly with matrix algebra routines such as this.
2704: See, e.g., KSPCreate().
2706: Level: developer
2708: Concepts: matrices^LU symbolic factorization
2710: .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
2712: Developer Note: fortran interface is not autogenerated as the f90
2713: interface defintion cannot be generated correctly [due to MatFactorInfo]
2715: @*/
2716: PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
2717: {
2727: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2728: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2729: if (!(fact)->ops->lufactorsymbolic) {
2730: const MatSolverPackage spackage;
2731: MatFactorGetSolverPackage(fact,&spackage);
2732: SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage);
2733: }
2734: MatCheckPreallocated(mat,2);
2736: PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);
2737: (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);
2738: PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);
2739: PetscObjectStateIncrease((PetscObject)fact);
2740: return(0);
2741: }
2745: /*@C
2746: MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
2747: Call this routine after first calling MatLUFactorSymbolic().
2749: Collective on Mat
2751: Input Parameters:
2752: + fact - the factor matrix obtained with MatGetFactor()
2753: . mat - the matrix
2754: - info - options for factorization
2756: Notes:
2757: See MatLUFactor() for in-place factorization. See
2758: MatCholeskyFactorNumeric() for the symmetric, positive definite case.
2760: Most users should employ the simplified KSP interface for linear solvers
2761: instead of working directly with matrix algebra routines such as this.
2762: See, e.g., KSPCreate().
2764: Level: developer
2766: Concepts: matrices^LU numeric factorization
2768: .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()
2770: Developer Note: fortran interface is not autogenerated as the f90
2771: interface defintion cannot be generated correctly [due to MatFactorInfo]
2773: @*/
2774: PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
2775: {
2783: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2784: if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) {
2785: 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);
2786: }
2787: if (!(fact)->ops->lufactornumeric) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name);
2788: MatCheckPreallocated(mat,2);
2789: PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);
2790: (fact->ops->lufactornumeric)(fact,mat,info);
2791: PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);
2793: MatView_Private(fact);
2794: PetscObjectStateIncrease((PetscObject)fact);
2795: return(0);
2796: }
2800: /*@C
2801: MatCholeskyFactor - Performs in-place Cholesky factorization of a
2802: symmetric matrix.
2804: Collective on Mat
2806: Input Parameters:
2807: + mat - the matrix
2808: . perm - row and column permutations
2809: - f - expected fill as ratio of original fill
2811: Notes:
2812: See MatLUFactor() for the nonsymmetric case. See also
2813: MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().
2815: Most users should employ the simplified KSP interface for linear solvers
2816: instead of working directly with matrix algebra routines such as this.
2817: See, e.g., KSPCreate().
2819: Level: developer
2821: Concepts: matrices^Cholesky factorization
2823: .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
2824: MatGetOrdering()
2826: Developer Note: fortran interface is not autogenerated as the f90
2827: interface defintion cannot be generated correctly [due to MatFactorInfo]
2829: @*/
2830: PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
2831: {
2839: if (mat->rmap->N != mat->cmap->N) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONG,"Matrix must be square");
2840: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2841: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2842: if (!mat->ops->choleskyfactor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2843: MatCheckPreallocated(mat,1);
2845: PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);
2846: (*mat->ops->choleskyfactor)(mat,perm,info);
2847: PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);
2848: PetscObjectStateIncrease((PetscObject)mat);
2849: return(0);
2850: }
2854: /*@C
2855: MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
2856: of a symmetric matrix.
2858: Collective on Mat
2860: Input Parameters:
2861: + fact - the factor matrix obtained with MatGetFactor()
2862: . mat - the matrix
2863: . perm - row and column permutations
2864: - info - options for factorization, includes
2865: $ fill - expected fill as ratio of original fill.
2866: $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2867: $ Run with the option -info to determine an optimal value to use
2869: Notes:
2870: See MatLUFactorSymbolic() for the nonsymmetric case. See also
2871: MatCholeskyFactor() and MatCholeskyFactorNumeric().
2873: Most users should employ the simplified KSP interface for linear solvers
2874: instead of working directly with matrix algebra routines such as this.
2875: See, e.g., KSPCreate().
2877: Level: developer
2879: Concepts: matrices^Cholesky symbolic factorization
2881: .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
2882: MatGetOrdering()
2884: Developer Note: fortran interface is not autogenerated as the f90
2885: interface defintion cannot be generated correctly [due to MatFactorInfo]
2887: @*/
2888: PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
2889: {
2898: if (mat->rmap->N != mat->cmap->N) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONG,"Matrix must be square");
2899: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2900: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2901: if (!(fact)->ops->choleskyfactorsymbolic) {
2902: const MatSolverPackage spackage;
2903: MatFactorGetSolverPackage(fact,&spackage);
2904: SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage);
2905: }
2906: MatCheckPreallocated(mat,2);
2908: PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
2909: (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);
2910: PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
2911: PetscObjectStateIncrease((PetscObject)fact);
2912: return(0);
2913: }
2917: /*@C
2918: MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
2919: of a symmetric matrix. Call this routine after first calling
2920: MatCholeskyFactorSymbolic().
2922: Collective on Mat
2924: Input Parameters:
2925: + fact - the factor matrix obtained with MatGetFactor()
2926: . mat - the initial matrix
2927: . info - options for factorization
2928: - fact - the symbolic factor of mat
2931: Notes:
2932: Most users should employ the simplified KSP interface for linear solvers
2933: instead of working directly with matrix algebra routines such as this.
2934: See, e.g., KSPCreate().
2936: Level: developer
2938: Concepts: matrices^Cholesky numeric factorization
2940: .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
2942: Developer Note: fortran interface is not autogenerated as the f90
2943: interface defintion cannot be generated correctly [due to MatFactorInfo]
2945: @*/
2946: PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
2947: {
2955: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2956: if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name);
2957: if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) {
2958: 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);
2959: }
2960: MatCheckPreallocated(mat,2);
2962: PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);
2963: (fact->ops->choleskyfactornumeric)(fact,mat,info);
2964: PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);
2966: MatView_Private(fact);
2967: PetscObjectStateIncrease((PetscObject)fact);
2968: return(0);
2969: }
2971: /* ----------------------------------------------------------------*/
2974: /*@
2975: MatSolve - Solves A x = b, given a factored matrix.
2977: Neighbor-wise Collective on Mat and Vec
2979: Input Parameters:
2980: + mat - the factored matrix
2981: - b - the right-hand-side vector
2983: Output Parameter:
2984: . x - the result vector
2986: Notes:
2987: The vectors b and x cannot be the same. I.e., one cannot
2988: call MatSolve(A,x,x).
2990: Notes:
2991: Most users should employ the simplified KSP interface for linear solvers
2992: instead of working directly with matrix algebra routines such as this.
2993: See, e.g., KSPCreate().
2995: Level: developer
2997: Concepts: matrices^triangular solves
2999: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
3000: @*/
3001: PetscErrorCode MatSolve(Mat mat,Vec b,Vec x)
3002: {
3012: if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3013: if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3014: 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);
3015: 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);
3016: 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);
3017: if (!mat->rmap->N && !mat->cmap->N) return(0);
3018: if (!mat->ops->solve) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3019: MatCheckPreallocated(mat,1);
3021: PetscLogEventBegin(MAT_Solve,mat,b,x,0);
3022: (*mat->ops->solve)(mat,b,x);
3023: PetscLogEventEnd(MAT_Solve,mat,b,x,0);
3024: PetscObjectStateIncrease((PetscObject)x);
3025: return(0);
3026: }
3030: PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X)
3031: {
3033: Vec b,x;
3034: PetscInt m,N,i;
3035: PetscScalar *bb,*xx;
3036: PetscBool flg;
3039: PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,PETSC_NULL);
3040: if (!flg) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
3041: PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,PETSC_NULL);
3042: if (!flg) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");
3044: MatGetArray(B,&bb);
3045: MatGetArray(X,&xx);
3046: MatGetLocalSize(B,&m,PETSC_NULL); /* number local rows */
3047: MatGetSize(B,PETSC_NULL,&N); /* total columns in dense matrix */
3048: MatGetVecs(A,&x,&b);
3049: for (i=0; i<N; i++) {
3050: VecPlaceArray(b,bb + i*m);
3051: VecPlaceArray(x,xx + i*m);
3052: MatSolve(A,b,x);
3053: VecResetArray(x);
3054: VecResetArray(b);
3055: }
3056: VecDestroy(&b);
3057: VecDestroy(&x);
3058: MatRestoreArray(B,&bb);
3059: MatRestoreArray(X,&xx);
3060: return(0);
3061: }
3065: /*@
3066: MatMatSolve - Solves A X = B, given a factored matrix.
3068: Neighbor-wise Collective on Mat
3070: Input Parameters:
3071: + mat - the factored matrix
3072: - B - the right-hand-side matrix (dense matrix)
3074: Output Parameter:
3075: . X - the result matrix (dense matrix)
3077: Notes:
3078: The matrices b and x cannot be the same. I.e., one cannot
3079: call MatMatSolve(A,x,x).
3081: Notes:
3082: Most users should usually employ the simplified KSP interface for linear solvers
3083: instead of working directly with matrix algebra routines such as this.
3084: See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3085: at a time.
3087: When using SuperLU_Dist as a parallel solver PETSc will use the SuperLU_Dist functionality to solve multiple right hand sides simultaneously. For MUMPS
3088: it calls a separate solve for each right hand side since MUMPS does not yet support distributed right hand sides.
3090: Since the resulting matrix X must always be dense we do not support sparse representation of the matrix B.
3092: Level: developer
3094: Concepts: matrices^triangular solves
3096: .seealso: MatMatSolveAdd(), MatMatSolveTranspose(), MatMatSolveTransposeAdd(), MatLUFactor(), MatCholeskyFactor()
3097: @*/
3098: PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X)
3099: {
3109: if (X == B) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3110: if (!A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3111: 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);
3112: 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);
3113: 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);
3114: if (!A->rmap->N && !A->cmap->N) return(0);
3115: MatCheckPreallocated(A,1);
3117: PetscLogEventBegin(MAT_MatSolve,A,B,X,0);
3118: if (!A->ops->matsolve) {
3119: PetscInfo1(A,"Mat type %s using basic MatMatSolve",((PetscObject)A)->type_name);
3120: MatMatSolve_Basic(A,B,X);
3121: } else {
3122: (*A->ops->matsolve)(A,B,X);
3123: }
3124: PetscLogEventEnd(MAT_MatSolve,A,B,X,0);
3125: PetscObjectStateIncrease((PetscObject)X);
3126: return(0);
3127: }
3132: /*@
3133: MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or
3134: U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U,
3136: Neighbor-wise Collective on Mat and Vec
3138: Input Parameters:
3139: + mat - the factored matrix
3140: - b - the right-hand-side vector
3142: Output Parameter:
3143: . x - the result vector
3145: Notes:
3146: MatSolve() should be used for most applications, as it performs
3147: a forward solve followed by a backward solve.
3149: The vectors b and x cannot be the same, i.e., one cannot
3150: call MatForwardSolve(A,x,x).
3152: For matrix in seqsbaij format with block size larger than 1,
3153: the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3154: MatForwardSolve() solves U^T*D y = b, and
3155: MatBackwardSolve() solves U x = y.
3156: Thus they do not provide a symmetric preconditioner.
3158: Most users should employ the simplified KSP interface for linear solvers
3159: instead of working directly with matrix algebra routines such as this.
3160: See, e.g., KSPCreate().
3162: Level: developer
3164: Concepts: matrices^forward solves
3166: .seealso: MatSolve(), MatBackwardSolve()
3167: @*/
3168: PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x)
3169: {
3179: if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3180: if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3181: if (!mat->ops->forwardsolve) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3182: 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);
3183: 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);
3184: 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);
3185: MatCheckPreallocated(mat,1);
3186: PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);
3187: (*mat->ops->forwardsolve)(mat,b,x);
3188: PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);
3189: PetscObjectStateIncrease((PetscObject)x);
3190: return(0);
3191: }
3195: /*@
3196: MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
3197: D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U,
3199: Neighbor-wise Collective on Mat and Vec
3201: Input Parameters:
3202: + mat - the factored matrix
3203: - b - the right-hand-side vector
3205: Output Parameter:
3206: . x - the result vector
3208: Notes:
3209: MatSolve() should be used for most applications, as it performs
3210: a forward solve followed by a backward solve.
3212: The vectors b and x cannot be the same. I.e., one cannot
3213: call MatBackwardSolve(A,x,x).
3215: For matrix in seqsbaij format with block size larger than 1,
3216: the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3217: MatForwardSolve() solves U^T*D y = b, and
3218: MatBackwardSolve() solves U x = y.
3219: Thus they do not provide a symmetric preconditioner.
3221: Most users should employ the simplified KSP interface for linear solvers
3222: instead of working directly with matrix algebra routines such as this.
3223: See, e.g., KSPCreate().
3225: Level: developer
3227: Concepts: matrices^backward solves
3229: .seealso: MatSolve(), MatForwardSolve()
3230: @*/
3231: PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x)
3232: {
3242: if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3243: if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3244: if (!mat->ops->backwardsolve) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3245: 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);
3246: 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);
3247: 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);
3248: MatCheckPreallocated(mat,1);
3250: PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);
3251: (*mat->ops->backwardsolve)(mat,b,x);
3252: PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);
3253: PetscObjectStateIncrease((PetscObject)x);
3254: return(0);
3255: }
3259: /*@
3260: MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
3262: Neighbor-wise Collective on Mat and Vec
3264: Input Parameters:
3265: + mat - the factored matrix
3266: . b - the right-hand-side vector
3267: - y - the vector to be added to
3269: Output Parameter:
3270: . x - the result vector
3272: Notes:
3273: The vectors b and x cannot be the same. I.e., one cannot
3274: call MatSolveAdd(A,x,y,x).
3276: Most users should employ the simplified KSP interface for linear solvers
3277: instead of working directly with matrix algebra routines such as this.
3278: See, e.g., KSPCreate().
3280: Level: developer
3282: Concepts: matrices^triangular solves
3284: .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3285: @*/
3286: PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3287: {
3288: PetscScalar one = 1.0;
3289: Vec tmp;
3301: if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3302: if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3303: 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);
3304: 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);
3305: 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);
3306: 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);
3307: 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);
3308: MatCheckPreallocated(mat,1);
3310: PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);
3311: if (mat->ops->solveadd) {
3312: (*mat->ops->solveadd)(mat,b,y,x);
3313: } else {
3314: /* do the solve then the add manually */
3315: if (x != y) {
3316: MatSolve(mat,b,x);
3317: VecAXPY(x,one,y);
3318: } else {
3319: VecDuplicate(x,&tmp);
3320: PetscLogObjectParent(mat,tmp);
3321: VecCopy(x,tmp);
3322: MatSolve(mat,b,x);
3323: VecAXPY(x,one,tmp);
3324: VecDestroy(&tmp);
3325: }
3326: }
3327: PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);
3328: PetscObjectStateIncrease((PetscObject)x);
3329: return(0);
3330: }
3334: /*@
3335: MatSolveTranspose - Solves A' x = b, given a factored matrix.
3337: Neighbor-wise Collective on Mat and Vec
3339: Input Parameters:
3340: + mat - the factored matrix
3341: - b - the right-hand-side vector
3343: Output Parameter:
3344: . x - the result vector
3346: Notes:
3347: The vectors b and x cannot be the same. I.e., one cannot
3348: call MatSolveTranspose(A,x,x).
3350: Most users should employ the simplified KSP interface for linear solvers
3351: instead of working directly with matrix algebra routines such as this.
3352: See, e.g., KSPCreate().
3354: Level: developer
3356: Concepts: matrices^triangular solves
3358: .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
3359: @*/
3360: PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x)
3361: {
3371: if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3372: if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3373: if (!mat->ops->solvetranspose) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3374: 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);
3375: 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);
3376: MatCheckPreallocated(mat,1);
3377: PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);
3378: (*mat->ops->solvetranspose)(mat,b,x);
3379: PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);
3380: PetscObjectStateIncrease((PetscObject)x);
3381: return(0);
3382: }
3386: /*@
3387: MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
3388: factored matrix.
3390: Neighbor-wise Collective on Mat and Vec
3392: Input Parameters:
3393: + mat - the factored matrix
3394: . b - the right-hand-side vector
3395: - y - the vector to be added to
3397: Output Parameter:
3398: . x - the result vector
3400: Notes:
3401: The vectors b and x cannot be the same. I.e., one cannot
3402: call MatSolveTransposeAdd(A,x,y,x).
3404: Most users should employ the simplified KSP interface for linear solvers
3405: instead of working directly with matrix algebra routines such as this.
3406: See, e.g., KSPCreate().
3408: Level: developer
3410: Concepts: matrices^triangular solves
3412: .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3413: @*/
3414: PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3415: {
3416: PetscScalar one = 1.0;
3418: Vec tmp;
3429: if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3430: if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3431: 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);
3432: 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);
3433: 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);
3434: 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);
3435: MatCheckPreallocated(mat,1);
3437: PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);
3438: if (mat->ops->solvetransposeadd) {
3439: (*mat->ops->solvetransposeadd)(mat,b,y,x);
3440: } else {
3441: /* do the solve then the add manually */
3442: if (x != y) {
3443: MatSolveTranspose(mat,b,x);
3444: VecAXPY(x,one,y);
3445: } else {
3446: VecDuplicate(x,&tmp);
3447: PetscLogObjectParent(mat,tmp);
3448: VecCopy(x,tmp);
3449: MatSolveTranspose(mat,b,x);
3450: VecAXPY(x,one,tmp);
3451: VecDestroy(&tmp);
3452: }
3453: }
3454: PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);
3455: PetscObjectStateIncrease((PetscObject)x);
3456: return(0);
3457: }
3458: /* ----------------------------------------------------------------*/
3462: /*@
3463: MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps.
3465: Neighbor-wise Collective on Mat and Vec
3467: Input Parameters:
3468: + mat - the matrix
3469: . b - the right hand side
3470: . omega - the relaxation factor
3471: . flag - flag indicating the type of SOR (see below)
3472: . shift - diagonal shift
3473: . its - the number of iterations
3474: - lits - the number of local iterations
3476: Output Parameters:
3477: . x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess)
3479: SOR Flags:
3480: . SOR_FORWARD_SWEEP - forward SOR
3481: . SOR_BACKWARD_SWEEP - backward SOR
3482: . SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3483: . SOR_LOCAL_FORWARD_SWEEP - local forward SOR
3484: . SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
3485: . SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3486: . SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
3487: upper/lower triangular part of matrix to
3488: vector (with omega)
3489: . SOR_ZERO_INITIAL_GUESS - zero initial guess
3491: Notes:
3492: SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3493: SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3494: on each processor.
3496: Application programmers will not generally use MatSOR() directly,
3497: but instead will employ the KSP/PC interface.
3499: Notes: for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing
3501: Notes for Advanced Users:
3502: The flags are implemented as bitwise inclusive or operations.
3503: For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3504: to specify a zero initial guess for SSOR.
3506: Most users should employ the simplified KSP interface for linear solvers
3507: instead of working directly with matrix algebra routines such as this.
3508: See, e.g., KSPCreate().
3510: Vectors x and b CANNOT be the same
3512: Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes
3514: Level: developer
3516: Concepts: matrices^relaxation
3517: Concepts: matrices^SOR
3518: Concepts: matrices^Gauss-Seidel
3520: @*/
3521: PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3522: {
3532: if (!mat->ops->sor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3533: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3534: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3535: 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);
3536: 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);
3537: 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);
3538: if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
3539: if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
3540: if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");
3542: MatCheckPreallocated(mat,1);
3543: PetscLogEventBegin(MAT_SOR,mat,b,x,0);
3544: ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);
3545: PetscLogEventEnd(MAT_SOR,mat,b,x,0);
3546: PetscObjectStateIncrease((PetscObject)x);
3547: return(0);
3548: }
3552: /*
3553: Default matrix copy routine.
3554: */
3555: PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
3556: {
3557: PetscErrorCode ierr;
3558: PetscInt i,rstart = 0,rend = 0,nz;
3559: const PetscInt *cwork;
3560: const PetscScalar *vwork;
3563: if (B->assembled) {
3564: MatZeroEntries(B);
3565: }
3566: MatGetOwnershipRange(A,&rstart,&rend);
3567: for (i=rstart; i<rend; i++) {
3568: MatGetRow(A,i,&nz,&cwork,&vwork);
3569: MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);
3570: MatRestoreRow(A,i,&nz,&cwork,&vwork);
3571: }
3572: MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
3573: MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);
3574: PetscObjectStateIncrease((PetscObject)B);
3575: return(0);
3576: }
3580: /*@
3581: MatCopy - Copys a matrix to another matrix.
3583: Collective on Mat
3585: Input Parameters:
3586: + A - the matrix
3587: - str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
3589: Output Parameter:
3590: . B - where the copy is put
3592: Notes:
3593: If you use SAME_NONZERO_PATTERN then the two matrices had better have the
3594: same nonzero pattern or the routine will crash.
3596: MatCopy() copies the matrix entries of a matrix to another existing
3597: matrix (after first zeroing the second matrix). A related routine is
3598: MatConvert(), which first creates a new matrix and then copies the data.
3600: Level: intermediate
3601:
3602: Concepts: matrices^copying
3604: .seealso: MatConvert(), MatDuplicate()
3606: @*/
3607: PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str)
3608: {
3610: PetscInt i;
3618: MatCheckPreallocated(B,2);
3619: if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3620: if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3621: 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);
3622: MatCheckPreallocated(A,1);
3624: PetscLogEventBegin(MAT_Copy,A,B,0,0);
3625: if (A->ops->copy) {
3626: (*A->ops->copy)(A,B,str);
3627: } else { /* generic conversion */
3628: MatCopy_Basic(A,B,str);
3629: }
3631: B->stencil.dim = A->stencil.dim;
3632: B->stencil.noc = A->stencil.noc;
3633: for (i=0; i<=A->stencil.dim; i++) {
3634: B->stencil.dims[i] = A->stencil.dims[i];
3635: B->stencil.starts[i] = A->stencil.starts[i];
3636: }
3638: PetscLogEventEnd(MAT_Copy,A,B,0,0);
3639: PetscObjectStateIncrease((PetscObject)B);
3640: return(0);
3641: }
3645: /*@C
3646: MatConvert - Converts a matrix to another matrix, either of the same
3647: or different type.
3649: Collective on Mat
3651: Input Parameters:
3652: + mat - the matrix
3653: . newtype - new matrix type. Use MATSAME to create a new matrix of the
3654: same type as the original matrix.
3655: - reuse - denotes if the destination matrix is to be created or reused. Currently
3656: MAT_REUSE_MATRIX is only supported for inplace conversion, otherwise use
3657: MAT_INITIAL_MATRIX.
3659: Output Parameter:
3660: . M - pointer to place new matrix
3662: Notes:
3663: MatConvert() first creates a new matrix and then copies the data from
3664: the first matrix. A related routine is MatCopy(), which copies the matrix
3665: entries of one matrix to another already existing matrix context.
3667: Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
3668: the MPI communicator of the generated matrix is always the same as the communicator
3669: of the input matrix.
3671: Level: intermediate
3673: Concepts: matrices^converting between storage formats
3675: .seealso: MatCopy(), MatDuplicate()
3676: @*/
3677: PetscErrorCode MatConvert(Mat mat, const MatType newtype,MatReuse reuse,Mat *M)
3678: {
3679: PetscErrorCode ierr;
3680: PetscBool sametype,issame,flg;
3681: char convname[256],mtype[256];
3682: Mat B;
3688: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3689: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3690: MatCheckPreallocated(mat,1);
3691: MatSetOption(mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);
3693: PetscOptionsGetString(((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);
3694: if (flg) {
3695: newtype = mtype;
3696: }
3697: PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);
3698: PetscStrcmp(newtype,"same",&issame);
3699: if ((reuse == MAT_REUSE_MATRIX) && (mat != *M)) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"MAT_REUSE_MATRIX only supported for in-place conversion currently");
3701: if ((reuse == MAT_REUSE_MATRIX) && (issame || sametype)) return(0);
3702:
3703: if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
3704: (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);
3705: } else {
3706: PetscErrorCode (*conv)(Mat, const MatType,MatReuse,Mat*)=PETSC_NULL;
3707: const char *prefix[3] = {"seq","mpi",""};
3708: PetscInt i;
3709: /*
3710: Order of precedence:
3711: 1) See if a specialized converter is known to the current matrix.
3712: 2) See if a specialized converter is known to the desired matrix class.
3713: 3) See if a good general converter is registered for the desired class
3714: (as of 6/27/03 only MATMPIADJ falls into this category).
3715: 4) See if a good general converter is known for the current matrix.
3716: 5) Use a really basic converter.
3717: */
3718:
3719: /* 1) See if a specialized converter is known to the current matrix and the desired class */
3720: for (i=0; i<3; i++) {
3721: PetscStrcpy(convname,"MatConvert_");
3722: PetscStrcat(convname,((PetscObject)mat)->type_name);
3723: PetscStrcat(convname,"_");
3724: PetscStrcat(convname,prefix[i]);
3725: PetscStrcat(convname,issame?((PetscObject)mat)->type_name:newtype);
3726: PetscStrcat(convname,"_C");
3727: PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);
3728: if (conv) goto foundconv;
3729: }
3731: /* 2) See if a specialized converter is known to the desired matrix class. */
3732: MatCreate(((PetscObject)mat)->comm,&B);
3733: MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);
3734: MatSetType(B,newtype);
3735: for (i=0; i<3; i++) {
3736: PetscStrcpy(convname,"MatConvert_");
3737: PetscStrcat(convname,((PetscObject)mat)->type_name);
3738: PetscStrcat(convname,"_");
3739: PetscStrcat(convname,prefix[i]);
3740: PetscStrcat(convname,newtype);
3741: PetscStrcat(convname,"_C");
3742: PetscObjectQueryFunction((PetscObject)B,convname,(void (**)(void))&conv);
3743: if (conv) {
3744: MatDestroy(&B);
3745: goto foundconv;
3746: }
3747: }
3749: /* 3) See if a good general converter is registered for the desired class */
3750: conv = B->ops->convertfrom;
3751: MatDestroy(&B);
3752: if (conv) goto foundconv;
3754: /* 4) See if a good general converter is known for the current matrix */
3755: if (mat->ops->convert) {
3756: conv = mat->ops->convert;
3757: }
3758: if (conv) goto foundconv;
3760: /* 5) Use a really basic converter. */
3761: conv = MatConvert_Basic;
3763: foundconv:
3764: PetscLogEventBegin(MAT_Convert,mat,0,0,0);
3765: (*conv)(mat,newtype,reuse,M);
3766: PetscLogEventEnd(MAT_Convert,mat,0,0,0);
3767: }
3768: PetscObjectStateIncrease((PetscObject)*M);
3770: /* Copy Mat options */
3771: if (mat->symmetric){MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);}
3772: if (mat->hermitian){MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);}
3773: return(0);
3774: }
3778: /*@C
3779: MatFactorGetSolverPackage - Returns name of the package providing the factorization routines
3781: Not Collective
3783: Input Parameter:
3784: . mat - the matrix, must be a factored matrix
3786: Output Parameter:
3787: . type - the string name of the package (do not free this string)
3789: Notes:
3790: In Fortran you pass in a empty string and the package name will be copied into it.
3791: (Make sure the string is long enough)
3793: Level: intermediate
3795: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
3796: @*/
3797: PetscErrorCode MatFactorGetSolverPackage(Mat mat, const MatSolverPackage *type)
3798: {
3799: PetscErrorCode ierr;
3800: PetscErrorCode (*conv)(Mat,const MatSolverPackage*);
3805: if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
3806: PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverPackage_C",(void (**)(void))&conv);
3807: if (!conv) {
3808: *type = MATSOLVERPETSC;
3809: } else {
3810: (*conv)(mat,type);
3811: }
3812: return(0);
3813: }
3817: /*@C
3818: MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic()
3820: Collective on Mat
3822: Input Parameters:
3823: + mat - the matrix
3824: . type - name of solver type, for example, spooles, superlu, plapack, petsc (to use PETSc's default)
3825: - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
3827: Output Parameters:
3828: . f - the factor matrix used with MatXXFactorSymbolic() calls
3830: Notes:
3831: Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
3832: such as pastix, superlu, mumps, spooles etc.
3834: PETSc must have been ./configure to use the external solver, using the option --download-package
3836: Level: intermediate
3838: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
3839: @*/
3840: PetscErrorCode MatGetFactor(Mat mat, const MatSolverPackage type,MatFactorType ftype,Mat *f)
3841: {
3842: PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
3843: char convname[256];
3849: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3850: MatCheckPreallocated(mat,1);
3852: PetscStrcpy(convname,"MatGetFactor_");
3853: PetscStrcat(convname,type);
3854: PetscStrcat(convname,"_C");
3855: PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);
3856: if (!conv) {
3857: PetscBool flag;
3858: MPI_Comm comm;
3860: PetscObjectGetComm((PetscObject)mat,&comm);
3861: PetscStrcasecmp(MATSOLVERPETSC,type,&flag);
3862: if (flag) {
3863: SETERRQ2(comm,PETSC_ERR_SUP,"Matrix format %s does not have a built-in PETSc %s",((PetscObject)mat)->type_name,MatFactorTypes[ftype]);
3864: } else {
3865: 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);
3866: }
3867: }
3868: (*conv)(mat,ftype,f);
3869: return(0);
3870: }
3874: /*@C
3875: MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type
3877: Not Collective
3879: Input Parameters:
3880: + mat - the matrix
3881: . type - name of solver type, for example, spooles, superlu, plapack, petsc (to use PETSc's default)
3882: - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
3884: Output Parameter:
3885: . flg - PETSC_TRUE if the factorization is available
3887: Notes:
3888: Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
3889: such as pastix, superlu, mumps, spooles etc.
3891: PETSc must have been ./configure to use the external solver, using the option --download-package
3893: Level: intermediate
3895: .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
3896: @*/
3897: PetscErrorCode MatGetFactorAvailable(Mat mat, const MatSolverPackage type,MatFactorType ftype,PetscBool *flg)
3898: {
3899: PetscErrorCode ierr;
3900: char convname[256];
3901: PetscErrorCode (*conv)(Mat,MatFactorType,PetscBool *);
3907: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3908: MatCheckPreallocated(mat,1);
3910: PetscStrcpy(convname,"MatGetFactorAvailable_");
3911: PetscStrcat(convname,type);
3912: PetscStrcat(convname,"_C");
3913: PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);
3914: if (!conv) {
3915: *flg = PETSC_FALSE;
3916: } else {
3917: (*conv)(mat,ftype,flg);
3918: }
3919: return(0);
3920: }
3925: /*@
3926: MatDuplicate - Duplicates a matrix including the non-zero structure.
3928: Collective on Mat
3930: Input Parameters:
3931: + mat - the matrix
3932: - op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy the numerical values in the matrix
3933: MAT_SHARE_NONZERO_PATTERN to share the nonzero patterns with the previous matrix and not copy them.
3935: Output Parameter:
3936: . M - pointer to place new matrix
3938: Level: intermediate
3940: Concepts: matrices^duplicating
3942: Notes: You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN.
3944: .seealso: MatCopy(), MatConvert()
3945: @*/
3946: PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
3947: {
3949: Mat B;
3950: PetscInt i;
3956: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3957: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3958: MatCheckPreallocated(mat,1);
3960: *M = 0;
3961: if (!mat->ops->duplicate) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Not written for this matrix type");
3962: PetscLogEventBegin(MAT_Convert,mat,0,0,0);
3963: (*mat->ops->duplicate)(mat,op,M);
3964: B = *M;
3965:
3966: B->stencil.dim = mat->stencil.dim;
3967: B->stencil.noc = mat->stencil.noc;
3968: for (i=0; i<=mat->stencil.dim; i++) {
3969: B->stencil.dims[i] = mat->stencil.dims[i];
3970: B->stencil.starts[i] = mat->stencil.starts[i];
3971: }
3973: B->nooffproczerorows = mat->nooffproczerorows;
3974: B->nooffprocentries = mat->nooffprocentries;
3975: PetscLogEventEnd(MAT_Convert,mat,0,0,0);
3976: PetscObjectStateIncrease((PetscObject)B);
3977: return(0);
3978: }
3982: /*@
3983: MatGetDiagonal - Gets the diagonal of a matrix.
3985: Logically Collective on Mat and Vec
3987: Input Parameters:
3988: + mat - the matrix
3989: - v - the vector for storing the diagonal
3991: Output Parameter:
3992: . v - the diagonal of the matrix
3994: Level: intermediate
3996: Note:
3997: Currently only correct in parallel for square matrices.
3999: Concepts: matrices^accessing diagonals
4001: .seealso: MatGetRow(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs()
4002: @*/
4003: PetscErrorCode MatGetDiagonal(Mat mat,Vec v)
4004: {
4011: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4012: if (!mat->ops->getdiagonal) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4013: MatCheckPreallocated(mat,1);
4015: (*mat->ops->getdiagonal)(mat,v);
4016: PetscObjectStateIncrease((PetscObject)v);
4017: return(0);
4018: }
4022: /*@
4023: MatGetRowMin - Gets the minimum value (of the real part) of each
4024: row of the matrix
4026: Logically Collective on Mat and Vec
4028: Input Parameters:
4029: . mat - the matrix
4031: Output Parameter:
4032: + v - the vector for storing the maximums
4033: - idx - the indices of the column found for each row (optional)
4035: Level: intermediate
4037: Notes: The result of this call are the same as if one converted the matrix to dense format
4038: and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4040: This code is only implemented for a couple of matrix formats.
4042: Concepts: matrices^getting row maximums
4044: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(),
4045: MatGetRowMax()
4046: @*/
4047: PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4048: {
4055: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4056: if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4057: MatCheckPreallocated(mat,1);
4059: (*mat->ops->getrowmin)(mat,v,idx);
4060: PetscObjectStateIncrease((PetscObject)v);
4061: return(0);
4062: }
4066: /*@
4067: MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4068: row of the matrix
4070: Logically Collective on Mat and Vec
4072: Input Parameters:
4073: . mat - the matrix
4075: Output Parameter:
4076: + v - the vector for storing the minimums
4077: - idx - the indices of the column found for each row (or PETSC_NULL if not needed)
4079: Level: intermediate
4081: Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
4082: row is 0 (the first column).
4084: This code is only implemented for a couple of matrix formats.
4086: Concepts: matrices^getting row maximums
4088: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4089: @*/
4090: PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4091: {
4098: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4099: if (!mat->ops->getrowminabs) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4100: MatCheckPreallocated(mat,1);
4101: if (idx) {PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));}
4103: (*mat->ops->getrowminabs)(mat,v,idx);
4104: PetscObjectStateIncrease((PetscObject)v);
4105: return(0);
4106: }
4110: /*@
4111: MatGetRowMax - Gets the maximum value (of the real part) of each
4112: row of the matrix
4114: Logically Collective on Mat and Vec
4116: Input Parameters:
4117: . mat - the matrix
4119: Output Parameter:
4120: + v - the vector for storing the maximums
4121: - idx - the indices of the column found for each row (optional)
4123: Level: intermediate
4125: Notes: The result of this call are the same as if one converted the matrix to dense format
4126: and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4128: This code is only implemented for a couple of matrix formats.
4130: Concepts: matrices^getting row maximums
4132: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4133: @*/
4134: PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4135: {
4142: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4143: if (!mat->ops->getrowmax) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4144: MatCheckPreallocated(mat,1);
4146: (*mat->ops->getrowmax)(mat,v,idx);
4147: PetscObjectStateIncrease((PetscObject)v);
4148: return(0);
4149: }
4153: /*@
4154: MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4155: row of the matrix
4157: Logically Collective on Mat and Vec
4159: Input Parameters:
4160: . mat - the matrix
4162: Output Parameter:
4163: + v - the vector for storing the maximums
4164: - idx - the indices of the column found for each row (or PETSC_NULL if not needed)
4166: Level: intermediate
4168: Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
4169: row is 0 (the first column).
4171: This code is only implemented for a couple of matrix formats.
4173: Concepts: matrices^getting row maximums
4175: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4176: @*/
4177: PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4178: {
4185: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4186: if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4187: MatCheckPreallocated(mat,1);
4188: if (idx) {PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));}
4190: (*mat->ops->getrowmaxabs)(mat,v,idx);
4191: PetscObjectStateIncrease((PetscObject)v);
4192: return(0);
4193: }
4197: /*@
4198: MatGetRowSum - Gets the sum of each row of the matrix
4200: Logically Collective on Mat and Vec
4202: Input Parameters:
4203: . mat - the matrix
4205: Output Parameter:
4206: . v - the vector for storing the sum of rows
4208: Level: intermediate
4210: Notes: This code is slow since it is not currently specialized for different formats
4212: Concepts: matrices^getting row sums
4214: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4215: @*/
4216: PetscErrorCode MatGetRowSum(Mat mat, Vec v)
4217: {
4218: PetscInt start = 0, end = 0, row;
4219: PetscScalar *array;
4226: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4227: MatCheckPreallocated(mat,1);
4228: MatGetOwnershipRange(mat, &start, &end);
4229: VecGetArray(v, &array);
4230: for(row = start; row < end; ++row) {
4231: PetscInt ncols, col;
4232: const PetscInt *cols;
4233: const PetscScalar *vals;
4235: array[row - start] = 0.0;
4236: MatGetRow(mat, row, &ncols, &cols, &vals);
4237: for(col = 0; col < ncols; col++) {
4238: array[row - start] += vals[col];
4239: }
4240: MatRestoreRow(mat, row, &ncols, &cols, &vals);
4241: }
4242: VecRestoreArray(v, &array);
4243: PetscObjectStateIncrease((PetscObject) v);
4244: return(0);
4245: }
4249: /*@
4250: MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
4252: Collective on Mat
4254: Input Parameter:
4255: + mat - the matrix to transpose
4256: - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
4258: Output Parameters:
4259: . B - the transpose
4261: Notes:
4262: If you pass in &mat for B the transpose will be done in place, for example MatTranspose(mat,MAT_REUSE_MATRIX,&mat);
4264: Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed.
4266: Level: intermediate
4268: Concepts: matrices^transposing
4270: .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4271: @*/
4272: PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4273: {
4279: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4280: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4281: if (!mat->ops->transpose) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4282: MatCheckPreallocated(mat,1);
4284: PetscLogEventBegin(MAT_Transpose,mat,0,0,0);
4285: (*mat->ops->transpose)(mat,reuse,B);
4286: PetscLogEventEnd(MAT_Transpose,mat,0,0,0);
4287: if (B) {PetscObjectStateIncrease((PetscObject)*B);}
4288: return(0);
4289: }
4293: /*@
4294: MatIsTranspose - Test whether a matrix is another one's transpose,
4295: or its own, in which case it tests symmetry.
4297: Collective on Mat
4299: Input Parameter:
4300: + A - the matrix to test
4301: - B - the matrix to test against, this can equal the first parameter
4303: Output Parameters:
4304: . flg - the result
4306: Notes:
4307: Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4308: has a running time of the order of the number of nonzeros; the parallel
4309: test involves parallel copies of the block-offdiagonal parts of the matrix.
4311: Level: intermediate
4313: Concepts: matrices^transposing, matrix^symmetry
4315: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4316: @*/
4317: PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg)
4318: {
4319: PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool *),(*g)(Mat,Mat,PetscReal,PetscBool *);
4325: PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",(void (**)(void))&f);
4326: PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",(void (**)(void))&g);
4327: *flg = PETSC_FALSE;
4328: if (f && g) {
4329: if (f == g) {
4330: (*f)(A,B,tol,flg);
4331: } else {
4332: SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4333: }
4334: } else {
4335: const MatType mattype;
4336: if (!f) {MatGetType(A,&mattype);}
4337: else {MatGetType(B,&mattype);}
4338: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
4339: }
4340: return(0);
4341: }
4345: /*@
4346: MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate.
4348: Collective on Mat
4350: Input Parameter:
4351: + mat - the matrix to transpose and complex conjugate
4352: - reuse - store the transpose matrix in the provided B
4354: Output Parameters:
4355: . B - the Hermitian
4357: Notes:
4358: If you pass in &mat for B the Hermitian will be done in place
4360: Level: intermediate
4362: Concepts: matrices^transposing, complex conjugatex
4364: .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4365: @*/
4366: PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
4367: {
4371: MatTranspose(mat,reuse,B);
4372: #if defined(PETSC_USE_COMPLEX)
4373: MatConjugate(*B);
4374: #endif
4375: return(0);
4376: }
4380: /*@
4381: MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,
4383: Collective on Mat
4385: Input Parameter:
4386: + A - the matrix to test
4387: - B - the matrix to test against, this can equal the first parameter
4389: Output Parameters:
4390: . flg - the result
4392: Notes:
4393: Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4394: has a running time of the order of the number of nonzeros; the parallel
4395: test involves parallel copies of the block-offdiagonal parts of the matrix.
4397: Level: intermediate
4399: Concepts: matrices^transposing, matrix^symmetry
4401: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
4402: @*/
4403: PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg)
4404: {
4405: PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool *),(*g)(Mat,Mat,PetscReal,PetscBool *);
4411: PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",(void (**)(void))&f);
4412: PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",(void (**)(void))&g);
4413: if (f && g) {
4414: if (f==g) {
4415: (*f)(A,B,tol,flg);
4416: } else {
4417: SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
4418: }
4419: }
4420: return(0);
4421: }
4425: /*@
4426: MatPermute - Creates a new matrix with rows and columns permuted from the
4427: original.
4429: Collective on Mat
4431: Input Parameters:
4432: + mat - the matrix to permute
4433: . row - row permutation, each processor supplies only the permutation for its rows
4434: - col - column permutation, each processor needs the entire column permutation, that is
4435: this is the same size as the total number of columns in the matrix. It can often
4436: be obtained with ISAllGather() on the row permutation
4438: Output Parameters:
4439: . B - the permuted matrix
4441: Level: advanced
4443: Concepts: matrices^permuting
4445: .seealso: MatGetOrdering(), ISAllGather()
4447: @*/
4448: PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
4449: {
4458: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4459: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4460: if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
4461: MatCheckPreallocated(mat,1);
4463: (*mat->ops->permute)(mat,row,col,B);
4464: PetscObjectStateIncrease((PetscObject)*B);
4465: return(0);
4466: }
4470: /*@
4471: MatEqual - Compares two matrices.
4473: Collective on Mat
4475: Input Parameters:
4476: + A - the first matrix
4477: - B - the second matrix
4479: Output Parameter:
4480: . flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
4482: Level: intermediate
4484: Concepts: matrices^equality between
4485: @*/
4486: PetscErrorCode MatEqual(Mat A,Mat B,PetscBool *flg)
4487: {
4497: MatCheckPreallocated(B,2);
4498: if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4499: if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4500: 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);
4501: if (!A->ops->equal) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4502: if (!B->ops->equal) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4503: 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);
4504: MatCheckPreallocated(A,1);
4506: (*A->ops->equal)(A,B,flg);
4507: return(0);
4508: }
4512: /*@
4513: MatDiagonalScale - Scales a matrix on the left and right by diagonal
4514: matrices that are stored as vectors. Either of the two scaling
4515: matrices can be PETSC_NULL.
4517: Collective on Mat
4519: Input Parameters:
4520: + mat - the matrix to be scaled
4521: . l - the left scaling vector (or PETSC_NULL)
4522: - r - the right scaling vector (or PETSC_NULL)
4524: Notes:
4525: MatDiagonalScale() computes A = LAR, where
4526: L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
4527: The L scales the rows of the matrix, the R scales the columns of the matrix.
4529: Level: intermediate
4531: Concepts: matrices^diagonal scaling
4532: Concepts: diagonal scaling of matrices
4534: .seealso: MatScale()
4535: @*/
4536: PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
4537: {
4543: if (!mat->ops->diagonalscale) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4546: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4547: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4548: MatCheckPreallocated(mat,1);
4550: PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4551: (*mat->ops->diagonalscale)(mat,l,r);
4552: PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4553: PetscObjectStateIncrease((PetscObject)mat);
4554: #if defined(PETSC_HAVE_CUSP)
4555: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4556: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4557: }
4558: #endif
4559: return(0);
4560: }
4564: /*@
4565: MatScale - Scales all elements of a matrix by a given number.
4567: Logically Collective on Mat
4569: Input Parameters:
4570: + mat - the matrix to be scaled
4571: - a - the scaling value
4573: Output Parameter:
4574: . mat - the scaled matrix
4576: Level: intermediate
4578: Concepts: matrices^scaling all entries
4580: .seealso: MatDiagonalScale()
4581: @*/
4582: PetscErrorCode MatScale(Mat mat,PetscScalar a)
4583: {
4589: if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4590: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4591: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4593: MatCheckPreallocated(mat,1);
4595: PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4596: if (a != (PetscScalar)1.0) {
4597: (*mat->ops->scale)(mat,a);
4598: PetscObjectStateIncrease((PetscObject)mat);
4599: }
4600: PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4601: #if defined(PETSC_HAVE_CUSP)
4602: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4603: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4604: }
4605: #endif
4606: return(0);
4607: }
4611: /*@
4612: MatNorm - Calculates various norms of a matrix.
4614: Collective on Mat
4616: Input Parameters:
4617: + mat - the matrix
4618: - type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
4620: Output Parameters:
4621: . nrm - the resulting norm
4623: Level: intermediate
4625: Concepts: matrices^norm
4626: Concepts: norm^of matrix
4627: @*/
4628: PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
4629: {
4637: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4638: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4639: if (!mat->ops->norm) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4640: MatCheckPreallocated(mat,1);
4642: (*mat->ops->norm)(mat,type,nrm);
4643: return(0);
4644: }
4646: /*
4647: This variable is used to prevent counting of MatAssemblyBegin() that
4648: are called from within a MatAssemblyEnd().
4649: */
4650: static PetscInt MatAssemblyEnd_InUse = 0;
4653: /*@
4654: MatAssemblyBegin - Begins assembling the matrix. This routine should
4655: be called after completing all calls to MatSetValues().
4657: Collective on Mat
4659: Input Parameters:
4660: + mat - the matrix
4661: - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
4662:
4663: Notes:
4664: MatSetValues() generally caches the values. The matrix is ready to
4665: use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4666: Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4667: in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4668: using the matrix.
4670: Level: beginner
4672: Concepts: matrices^assembling
4674: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
4675: @*/
4676: PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
4677: {
4683: MatCheckPreallocated(mat,1);
4684: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
4685: if (mat->assembled) {
4686: mat->was_assembled = PETSC_TRUE;
4687: mat->assembled = PETSC_FALSE;
4688: }
4689: if (!MatAssemblyEnd_InUse) {
4690: PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);
4691: if (mat->ops->assemblybegin){(*mat->ops->assemblybegin)(mat,type);}
4692: PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);
4693: } else {
4694: if (mat->ops->assemblybegin){(*mat->ops->assemblybegin)(mat,type);}
4695: }
4696: return(0);
4697: }
4701: /*@
4702: MatAssembled - Indicates if a matrix has been assembled and is ready for
4703: use; for example, in matrix-vector product.
4705: Not Collective
4707: Input Parameter:
4708: . mat - the matrix
4710: Output Parameter:
4711: . assembled - PETSC_TRUE or PETSC_FALSE
4713: Level: advanced
4715: Concepts: matrices^assembled?
4717: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
4718: @*/
4719: PetscErrorCode MatAssembled(Mat mat,PetscBool *assembled)
4720: {
4725: *assembled = mat->assembled;
4726: return(0);
4727: }
4731: /*
4732: Processes command line options to determine if/how a matrix
4733: is to be viewed. Called by MatAssemblyEnd() and MatLoad().
4734: */
4735: PetscErrorCode MatView_Private(Mat mat)
4736: {
4737: PetscErrorCode ierr;
4738: PetscBool flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE,flg4 = PETSC_FALSE,flg6 = PETSC_FALSE,flg7 = PETSC_FALSE,flg8 = PETSC_FALSE;
4739: static PetscBool incall = PETSC_FALSE;
4740: #if defined(PETSC_USE_SOCKET_VIEWER)
4741: PetscBool flg5 = PETSC_FALSE;
4742: #endif
4745: if (incall) return(0);
4746: incall = PETSC_TRUE;
4747: PetscObjectOptionsBegin((PetscObject)mat);
4748: PetscOptionsBool("-mat_view_info","Information on matrix size","MatView",flg1,&flg1,PETSC_NULL);
4749: PetscOptionsBool("-mat_view_info_detailed","Nonzeros in the matrix","MatView",flg2,&flg2,PETSC_NULL);
4750: PetscOptionsBool("-mat_view","Print matrix to stdout","MatView",flg3,&flg3,PETSC_NULL);
4751: PetscOptionsBool("-mat_view_matlab","Print matrix to stdout in a format Matlab can read","MatView",flg4,&flg4,PETSC_NULL);
4752: #if defined(PETSC_USE_SOCKET_VIEWER)
4753: PetscOptionsBool("-mat_view_socket","Send matrix to socket (can be read from matlab)","MatView",flg5,&flg5,PETSC_NULL);
4754: #endif
4755: PetscOptionsBool("-mat_view_binary","Save matrix to file in binary format","MatView",flg6,&flg6,PETSC_NULL);
4756: PetscOptionsBool("-mat_view_draw","Draw the matrix nonzero structure","MatView",flg7,&flg7,PETSC_NULL);
4757: PetscOptionsEnd();
4759: if (flg1) {
4760: PetscViewer viewer;
4762: PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4763: PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO);
4764: MatView(mat,viewer);
4765: PetscViewerPopFormat(viewer);
4766: }
4767: if (flg2) {
4768: PetscViewer viewer;
4770: PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4771: PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO_DETAIL);
4772: MatView(mat,viewer);
4773: PetscViewerPopFormat(viewer);
4774: }
4775: if (flg3) {
4776: PetscViewer viewer;
4778: PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4779: MatView(mat,viewer);
4780: }
4781: if (flg4) {
4782: PetscViewer viewer;
4784: PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4785: PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);
4786: MatView(mat,viewer);
4787: PetscViewerPopFormat(viewer);
4788: }
4789: #if defined(PETSC_USE_SOCKET_VIEWER)
4790: if (flg5) {
4791: MatView(mat,PETSC_VIEWER_SOCKET_(((PetscObject)mat)->comm));
4792: PetscViewerFlush(PETSC_VIEWER_SOCKET_(((PetscObject)mat)->comm));
4793: }
4794: #endif
4795: if (flg6) {
4796: MatView(mat,PETSC_VIEWER_BINARY_(((PetscObject)mat)->comm));
4797: PetscViewerFlush(PETSC_VIEWER_BINARY_(((PetscObject)mat)->comm));
4798: }
4799: if (flg7) {
4800: PetscOptionsGetBool(((PetscObject)mat)->prefix,"-mat_view_contour",&flg8,PETSC_NULL);
4801: if (flg8) {
4802: PetscViewerPushFormat(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm),PETSC_VIEWER_DRAW_CONTOUR);
4803: }
4804: MatView(mat,PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));
4805: PetscViewerFlush(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));
4806: if (flg8) {
4807: PetscViewerPopFormat(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));
4808: }
4809: }
4810: incall = PETSC_FALSE;
4811: return(0);
4812: }
4816: /*@
4817: MatAssemblyEnd - Completes assembling the matrix. This routine should
4818: be called after MatAssemblyBegin().
4820: Collective on Mat
4822: Input Parameters:
4823: + mat - the matrix
4824: - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
4826: Options Database Keys:
4827: + -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly()
4828: . -mat_view_info_detailed - Prints more detailed info
4829: . -mat_view - Prints matrix in ASCII format
4830: . -mat_view_matlab - Prints matrix in Matlab format
4831: . -mat_view_draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
4832: . -display <name> - Sets display name (default is host)
4833: . -draw_pause <sec> - Sets number of seconds to pause after display
4834: . -mat_view_socket - Sends matrix to socket, can be accessed from Matlab (See the <a href="../../docs/manual.pdf">users manual</a>)
4835: . -viewer_socket_machine <machine>
4836: . -viewer_socket_port <port>
4837: . -mat_view_binary - save matrix to file in binary format
4838: - -viewer_binary_filename <name>
4840: Notes:
4841: MatSetValues() generally caches the values. The matrix is ready to
4842: use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4843: Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4844: in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4845: using the matrix.
4847: Level: beginner
4849: .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), MatView(), MatAssembled(), PetscViewerSocketOpen()
4850: @*/
4851: PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
4852: {
4853: PetscErrorCode ierr;
4854: static PetscInt inassm = 0;
4855: PetscBool flg = PETSC_FALSE;
4861: inassm++;
4862: MatAssemblyEnd_InUse++;
4863: if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
4864: PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);
4865: if (mat->ops->assemblyend) {
4866: (*mat->ops->assemblyend)(mat,type);
4867: }
4868: PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);
4869: } else {
4870: if (mat->ops->assemblyend) {
4871: (*mat->ops->assemblyend)(mat,type);
4872: }
4873: }
4875: /* Flush assembly is not a true assembly */
4876: if (type != MAT_FLUSH_ASSEMBLY) {
4877: mat->assembled = PETSC_TRUE; mat->num_ass++;
4878: }
4879: mat->insertmode = NOT_SET_VALUES;
4880: MatAssemblyEnd_InUse--;
4881: PetscObjectStateIncrease((PetscObject)mat);
4882: if (!mat->symmetric_eternal) {
4883: mat->symmetric_set = PETSC_FALSE;
4884: mat->hermitian_set = PETSC_FALSE;
4885: mat->structurally_symmetric_set = PETSC_FALSE;
4886: }
4887: #if defined(PETSC_HAVE_CUSP)
4888: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4889: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4890: }
4891: #endif
4892: if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
4893: MatView_Private(mat);
4894: PetscOptionsHasName(((PetscObject)mat)->prefix,"-mat_is_symmetric",&flg);
4895: if (flg) {
4896: PetscReal tol = 0.0;
4897: PetscOptionsGetReal(((PetscObject)mat)->prefix,"-mat_is_symmetric",&tol,PETSC_NULL);
4898: MatIsSymmetric(mat,tol,&flg);
4899: if (flg) {
4900: PetscPrintf(((PetscObject)mat)->comm,"Matrix is symmetric (tolerance %G)\n",tol);
4901: } else {
4902: PetscPrintf(((PetscObject)mat)->comm,"Matrix is not symmetric (tolerance %G)\n",tol);
4903: }
4904: }
4905: }
4906: inassm--;
4907: return(0);
4908: }
4912: /*@
4913: MatSetOption - Sets a parameter option for a matrix. Some options
4914: may be specific to certain storage formats. Some options
4915: determine how values will be inserted (or added). Sorted,
4916: row-oriented input will generally assemble the fastest. The default
4917: is row-oriented.
4919: Logically Collective on Mat
4921: Input Parameters:
4922: + mat - the matrix
4923: . option - the option, one of those listed below (and possibly others),
4924: - flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
4926: Options Describing Matrix Structure:
4927: + MAT_SPD - symmetric positive definite
4928: - MAT_SYMMETRIC - symmetric in terms of both structure and value
4929: . MAT_HERMITIAN - transpose is the complex conjugation
4930: . MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
4931: - MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
4932: you set to be kept with all future use of the matrix
4933: including after MatAssemblyBegin/End() which could
4934: potentially change the symmetry structure, i.e. you
4935: KNOW the matrix will ALWAYS have the property you set.
4938: Options For Use with MatSetValues():
4939: Insert a logically dense subblock, which can be
4940: . MAT_ROW_ORIENTED - row-oriented (default)
4942: Note these options reflect the data you pass in with MatSetValues(); it has
4943: nothing to do with how the data is stored internally in the matrix
4944: data structure.
4946: When (re)assembling a matrix, we can restrict the input for
4947: efficiency/debugging purposes. These options include
4948: + MAT_NEW_NONZERO_LOCATIONS - additional insertions will be
4949: allowed if they generate a new nonzero
4950: . MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
4951: . MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
4952: . MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
4953: . MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
4954: + MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
4955: any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
4956: performance for very large process counts.
4958: Notes:
4959: Some options are relevant only for particular matrix types and
4960: are thus ignored by others. Other options are not supported by
4961: certain matrix types and will generate an error message if set.
4963: If using a Fortran 77 module to compute a matrix, one may need to
4964: use the column-oriented option (or convert to the row-oriented
4965: format).
4967: MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
4968: that would generate a new entry in the nonzero structure is instead
4969: ignored. Thus, if memory has not alredy been allocated for this particular
4970: data, then the insertion is ignored. For dense matrices, in which
4971: the entire array is allocated, no entries are ever ignored.
4972: Set after the first MatAssemblyEnd()
4974: MAT_NEW_NONZERO_LOCATION_ERR indicates that any add or insertion
4975: that would generate a new entry in the nonzero structure instead produces
4976: an error. (Currently supported for AIJ and BAIJ formats only.)
4977: This is a useful flag when using SAME_NONZERO_PATTERN in calling
4978: KSPSetOperators() to ensure that the nonzero pattern truely does
4979: remain unchanged. Set after the first MatAssemblyEnd()
4981: MAT_NEW_NONZERO_ALLOCATION_ERR indicates that any add or insertion
4982: that would generate a new entry that has not been preallocated will
4983: instead produce an error. (Currently supported for AIJ and BAIJ formats
4984: only.) This is a useful flag when debugging matrix memory preallocation.
4986: MAT_IGNORE_OFF_PROC_ENTRIES indicates entries destined for
4987: other processors should be dropped, rather than stashed.
4988: This is useful if you know that the "owning" processor is also
4989: always generating the correct matrix entries, so that PETSc need
4990: not transfer duplicate entries generated on another processor.
4991:
4992: MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
4993: searches during matrix assembly. When this flag is set, the hash table
4994: is created during the first Matrix Assembly. This hash table is
4995: used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
4996: to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
4997: should be used with MAT_USE_HASH_TABLE flag. This option is currently
4998: supported by MATMPIBAIJ format only.
5000: MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries
5001: are kept in the nonzero structure
5003: MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
5004: a zero location in the matrix
5006: MAT_USE_INODES - indicates using inode version of the code - works with AIJ and
5007: ROWBS matrix types
5009: MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the
5010: zero row routines and thus improves performance for very large process counts.
5012: MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular
5013: part of the matrix (since they should match the upper triangular part).
5015: Notes: Can only be called after MatSetSizes() and MatSetType() have been set.
5017: Level: intermediate
5019: Concepts: matrices^setting options
5021: @*/
5022: PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg)
5023: {
5032: 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);
5033: 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()");
5035: switch (op) {
5036: case MAT_NO_OFF_PROC_ENTRIES:
5037: mat->nooffprocentries = flg;
5038: return(0);
5039: break;
5040: case MAT_NO_OFF_PROC_ZERO_ROWS:
5041: mat->nooffproczerorows = flg;
5042: return(0);
5043: break;
5044: case MAT_SPD:
5045: mat->spd_set = PETSC_TRUE;
5046: mat->spd = flg;
5047: if (flg) {
5048: mat->symmetric = PETSC_TRUE;
5049: mat->structurally_symmetric = PETSC_TRUE;
5050: mat->symmetric_set = PETSC_TRUE;
5051: mat->structurally_symmetric_set = PETSC_TRUE;
5052: }
5053: break;
5054: case MAT_SYMMETRIC:
5055: mat->symmetric = flg;
5056: if (flg) mat->structurally_symmetric = PETSC_TRUE;
5057: mat->symmetric_set = PETSC_TRUE;
5058: mat->structurally_symmetric_set = flg;
5059: break;
5060: case MAT_HERMITIAN:
5061: mat->hermitian = flg;
5062: if (flg) mat->structurally_symmetric = PETSC_TRUE;
5063: mat->hermitian_set = PETSC_TRUE;
5064: mat->structurally_symmetric_set = flg;
5065: break;
5066: case MAT_STRUCTURALLY_SYMMETRIC:
5067: mat->structurally_symmetric = flg;
5068: mat->structurally_symmetric_set = PETSC_TRUE;
5069: break;
5070: case MAT_SYMMETRY_ETERNAL:
5071: mat->symmetric_eternal = flg;
5072: break;
5073: default:
5074: break;
5075: }
5076: if (mat->ops->setoption) {
5077: (*mat->ops->setoption)(mat,op,flg);
5078: }
5079: return(0);
5080: }
5084: /*@
5085: MatZeroEntries - Zeros all entries of a matrix. For sparse matrices
5086: this routine retains the old nonzero structure.
5088: Logically Collective on Mat
5090: Input Parameters:
5091: . mat - the matrix
5093: Level: intermediate
5095: 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.
5096: See the Performance chapter of the users manual for information on preallocating matrices.
5098: Concepts: matrices^zeroing
5100: .seealso: MatZeroRows()
5101: @*/
5102: PetscErrorCode MatZeroEntries(Mat mat)
5103: {
5109: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5110: 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");
5111: if (!mat->ops->zeroentries) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5112: MatCheckPreallocated(mat,1);
5114: PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);
5115: (*mat->ops->zeroentries)(mat);
5116: PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);
5117: PetscObjectStateIncrease((PetscObject)mat);
5118: #if defined(PETSC_HAVE_CUSP)
5119: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5120: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5121: }
5122: #endif
5123: return(0);
5124: }
5128: /*@C
5129: MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal)
5130: of a set of rows and columns of a matrix.
5132: Collective on Mat
5134: Input Parameters:
5135: + mat - the matrix
5136: . numRows - the number of rows to remove
5137: . rows - the global row indices
5138: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5139: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5140: - b - optional vector of right hand side, that will be adjusted by provided solution
5142: Notes:
5143: This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5145: The user can set a value in the diagonal entry (or for the AIJ and
5146: row formats can optionally remove the main diagonal entry from the
5147: nonzero structure as well, by passing 0.0 as the final argument).
5149: For the parallel case, all processes that share the matrix (i.e.,
5150: those in the communicator used for matrix creation) MUST call this
5151: routine, regardless of whether any rows being zeroed are owned by
5152: them.
5154: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5155: list only rows local to itself).
5157: The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5159: Level: intermediate
5161: Concepts: matrices^zeroing rows
5163: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumnsIS()
5164: @*/
5165: PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5166: {
5173: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5174: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5175: if (!mat->ops->zerorowscolumns) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5176: MatCheckPreallocated(mat,1);
5178: (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);
5179: MatView_Private(mat);
5180: PetscObjectStateIncrease((PetscObject)mat);
5181: #if defined(PETSC_HAVE_CUSP)
5182: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5183: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5184: }
5185: #endif
5186: return(0);
5187: }
5191: /*@C
5192: MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
5193: of a set of rows and columns of a matrix.
5195: Collective on Mat
5197: Input Parameters:
5198: + mat - the matrix
5199: . is - the rows to zero
5200: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5201: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5202: - b - optional vector of right hand side, that will be adjusted by provided solution
5204: Notes:
5205: This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5207: The user can set a value in the diagonal entry (or for the AIJ and
5208: row formats can optionally remove the main diagonal entry from the
5209: nonzero structure as well, by passing 0.0 as the final argument).
5211: For the parallel case, all processes that share the matrix (i.e.,
5212: those in the communicator used for matrix creation) MUST call this
5213: routine, regardless of whether any rows being zeroed are owned by
5214: them.
5216: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5217: list only rows local to itself).
5219: The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5221: Level: intermediate
5223: Concepts: matrices^zeroing rows
5225: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumns()
5226: @*/
5227: PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5228: {
5230: PetscInt numRows;
5231: const PetscInt *rows;
5238: ISGetLocalSize(is,&numRows);
5239: ISGetIndices(is,&rows);
5240: MatZeroRowsColumns(mat,numRows,rows,diag,x,b);
5241: ISRestoreIndices(is,&rows);
5242: return(0);
5243: }
5247: /*@C
5248: MatZeroRows - Zeros all entries (except possibly the main diagonal)
5249: of a set of rows of a matrix.
5251: Collective on Mat
5253: Input Parameters:
5254: + mat - the matrix
5255: . numRows - the number of rows to remove
5256: . rows - the global row indices
5257: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5258: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5259: - b - optional vector of right hand side, that will be adjusted by provided solution
5261: Notes:
5262: For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5263: but does not release memory. For the dense and block diagonal
5264: formats this does not alter the nonzero structure.
5266: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5267: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5268: merely zeroed.
5270: The user can set a value in the diagonal entry (or for the AIJ and
5271: row formats can optionally remove the main diagonal entry from the
5272: nonzero structure as well, by passing 0.0 as the final argument).
5274: For the parallel case, all processes that share the matrix (i.e.,
5275: those in the communicator used for matrix creation) MUST call this
5276: routine, regardless of whether any rows being zeroed are owned by
5277: them.
5279: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5280: list only rows local to itself).
5282: You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5283: owns that are to be zeroed. This saves a global synchronization in the implementation.
5285: Level: intermediate
5287: Concepts: matrices^zeroing rows
5289: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5290: @*/
5291: PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5292: {
5299: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5300: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5301: if (!mat->ops->zerorows) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5302: MatCheckPreallocated(mat,1);
5304: (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);
5305: MatView_Private(mat);
5306: PetscObjectStateIncrease((PetscObject)mat);
5307: #if defined(PETSC_HAVE_CUSP)
5308: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5309: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5310: }
5311: #endif
5312: return(0);
5313: }
5317: /*@C
5318: MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5319: of a set of rows of a matrix.
5321: Collective on Mat
5323: Input Parameters:
5324: + mat - the matrix
5325: . is - index set of rows to remove
5326: . diag - value put in all diagonals of eliminated rows
5327: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5328: - b - optional vector of right hand side, that will be adjusted by provided solution
5330: Notes:
5331: For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5332: but does not release memory. For the dense and block diagonal
5333: formats this does not alter the nonzero structure.
5335: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5336: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5337: merely zeroed.
5339: The user can set a value in the diagonal entry (or for the AIJ and
5340: row formats can optionally remove the main diagonal entry from the
5341: nonzero structure as well, by passing 0.0 as the final argument).
5343: For the parallel case, all processes that share the matrix (i.e.,
5344: those in the communicator used for matrix creation) MUST call this
5345: routine, regardless of whether any rows being zeroed are owned by
5346: them.
5348: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5349: list only rows local to itself).
5351: You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5352: owns that are to be zeroed. This saves a global synchronization in the implementation.
5354: Level: intermediate
5356: Concepts: matrices^zeroing rows
5358: .seealso: MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5359: @*/
5360: PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5361: {
5362: PetscInt numRows;
5363: const PetscInt *rows;
5370: ISGetLocalSize(is,&numRows);
5371: ISGetIndices(is,&rows);
5372: MatZeroRows(mat,numRows,rows,diag,x,b);
5373: ISRestoreIndices(is,&rows);
5374: return(0);
5375: }
5379: /*@C
5380: MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
5381: of a set of rows of a matrix. These rows must be local to the process.
5383: Collective on Mat
5385: Input Parameters:
5386: + mat - the matrix
5387: . numRows - the number of rows to remove
5388: . rows - the grid coordinates (and component number when dof > 1) for matrix rows
5389: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5390: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5391: - b - optional vector of right hand side, that will be adjusted by provided solution
5393: Notes:
5394: For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5395: but does not release memory. For the dense and block diagonal
5396: formats this does not alter the nonzero structure.
5398: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5399: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5400: merely zeroed.
5402: The user can set a value in the diagonal entry (or for the AIJ and
5403: row formats can optionally remove the main diagonal entry from the
5404: nonzero structure as well, by passing 0.0 as the final argument).
5406: For the parallel case, all processes that share the matrix (i.e.,
5407: those in the communicator used for matrix creation) MUST call this
5408: routine, regardless of whether any rows being zeroed are owned by
5409: them.
5411: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5412: list only rows local to itself).
5414: The grid coordinates are across the entire grid, not just the local portion
5416: In Fortran idxm and idxn should be declared as
5417: $ MatStencil idxm(4,m)
5418: and the values inserted using
5419: $ idxm(MatStencil_i,1) = i
5420: $ idxm(MatStencil_j,1) = j
5421: $ idxm(MatStencil_k,1) = k
5422: $ idxm(MatStencil_c,1) = c
5423: etc
5425: For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5426: obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5427: etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5428: DMDA_BOUNDARY_PERIODIC boundary type.
5430: 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
5431: a single value per point) you can skip filling those indices.
5433: Level: intermediate
5435: Concepts: matrices^zeroing rows
5437: .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5438: @*/
5439: PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5440: {
5441: PetscInt dim = mat->stencil.dim;
5442: PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc);
5443: PetscInt *dims = mat->stencil.dims+1;
5444: PetscInt *starts = mat->stencil.starts;
5445: PetscInt *dxm = (PetscInt *) rows;
5446: PetscInt *jdxm, i, j, tmp, numNewRows = 0;
5454: PetscMalloc(numRows*sizeof(PetscInt), &jdxm);
5455: for(i = 0; i < numRows; ++i) {
5456: /* Skip unused dimensions (they are ordered k, j, i, c) */
5457: for(j = 0; j < 3-sdim; ++j) dxm++;
5458: /* Local index in X dir */
5459: tmp = *dxm++ - starts[0];
5460: /* Loop over remaining dimensions */
5461: for(j = 0; j < dim-1; ++j) {
5462: /* If nonlocal, set index to be negative */
5463: if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5464: /* Update local index */
5465: else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5466: }
5467: /* Skip component slot if necessary */
5468: if (mat->stencil.noc) dxm++;
5469: /* Local row number */
5470: if (tmp >= 0) {
5471: jdxm[numNewRows++] = tmp;
5472: }
5473: }
5474: MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);
5475: PetscFree(jdxm);
5476: return(0);
5477: }
5481: /*@C
5482: MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal)
5483: of a set of rows and columns of a matrix.
5485: Collective on Mat
5487: Input Parameters:
5488: + mat - the matrix
5489: . numRows - the number of rows/columns to remove
5490: . rows - the grid coordinates (and component number when dof > 1) for matrix rows
5491: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5492: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5493: - b - optional vector of right hand side, that will be adjusted by provided solution
5495: Notes:
5496: For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5497: but does not release memory. For the dense and block diagonal
5498: formats this does not alter the nonzero structure.
5500: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5501: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5502: merely zeroed.
5504: The user can set a value in the diagonal entry (or for the AIJ and
5505: row formats can optionally remove the main diagonal entry from the
5506: nonzero structure as well, by passing 0.0 as the final argument).
5508: For the parallel case, all processes that share the matrix (i.e.,
5509: those in the communicator used for matrix creation) MUST call this
5510: routine, regardless of whether any rows being zeroed are owned by
5511: them.
5513: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5514: list only rows local to itself, but the row/column numbers are given in local numbering).
5516: The grid coordinates are across the entire grid, not just the local portion
5518: In Fortran idxm and idxn should be declared as
5519: $ MatStencil idxm(4,m)
5520: and the values inserted using
5521: $ idxm(MatStencil_i,1) = i
5522: $ idxm(MatStencil_j,1) = j
5523: $ idxm(MatStencil_k,1) = k
5524: $ idxm(MatStencil_c,1) = c
5525: etc
5527: For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5528: obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5529: etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5530: DMDA_BOUNDARY_PERIODIC boundary type.
5532: 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
5533: a single value per point) you can skip filling those indices.
5535: Level: intermediate
5537: Concepts: matrices^zeroing rows
5539: .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5540: @*/
5541: PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5542: {
5543: PetscInt dim = mat->stencil.dim;
5544: PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc);
5545: PetscInt *dims = mat->stencil.dims+1;
5546: PetscInt *starts = mat->stencil.starts;
5547: PetscInt *dxm = (PetscInt *) rows;
5548: PetscInt *jdxm, i, j, tmp, numNewRows = 0;
5556: PetscMalloc(numRows*sizeof(PetscInt), &jdxm);
5557: for(i = 0; i < numRows; ++i) {
5558: /* Skip unused dimensions (they are ordered k, j, i, c) */
5559: for(j = 0; j < 3-sdim; ++j) dxm++;
5560: /* Local index in X dir */
5561: tmp = *dxm++ - starts[0];
5562: /* Loop over remaining dimensions */
5563: for(j = 0; j < dim-1; ++j) {
5564: /* If nonlocal, set index to be negative */
5565: if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5566: /* Update local index */
5567: else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5568: }
5569: /* Skip component slot if necessary */
5570: if (mat->stencil.noc) dxm++;
5571: /* Local row number */
5572: if (tmp >= 0) {
5573: jdxm[numNewRows++] = tmp;
5574: }
5575: }
5576: MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);
5577: PetscFree(jdxm);
5578: return(0);
5579: }
5583: /*@C
5584: MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
5585: of a set of rows of a matrix; using local numbering of rows.
5587: Collective on Mat
5589: Input Parameters:
5590: + mat - the matrix
5591: . numRows - the number of rows to remove
5592: . rows - the global row indices
5593: . diag - value put in all diagonals of eliminated rows
5594: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5595: - b - optional vector of right hand side, that will be adjusted by provided solution
5597: Notes:
5598: Before calling MatZeroRowsLocal(), the user must first set the
5599: local-to-global mapping by calling MatSetLocalToGlobalMapping().
5601: For the AIJ matrix formats this removes the old nonzero structure,
5602: but does not release memory. For the dense and block diagonal
5603: formats this does not alter the nonzero structure.
5605: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5606: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5607: merely zeroed.
5609: The user can set a value in the diagonal entry (or for the AIJ and
5610: row formats can optionally remove the main diagonal entry from the
5611: nonzero structure as well, by passing 0.0 as the final argument).
5613: You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5614: owns that are to be zeroed. This saves a global synchronization in the implementation.
5616: Level: intermediate
5618: Concepts: matrices^zeroing
5620: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5621: @*/
5622: PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5623: {
5625: PetscMPIInt size;
5631: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5632: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5633: MatCheckPreallocated(mat,1);
5635: MPI_Comm_size(((PetscObject)mat)->comm,&size);
5636: if (mat->ops->zerorowslocal) {
5637: (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);
5638: } else if (size == 1) {
5639: (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);
5640: } else {
5641: IS is, newis;
5642: const PetscInt *newRows;
5644: if (!mat->rmap->mapping) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5645: ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
5646: ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);
5647: ISGetIndices(newis,&newRows);
5648: (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);
5649: ISRestoreIndices(newis,&newRows);
5650: ISDestroy(&newis);
5651: ISDestroy(&is);
5652: }
5653: PetscObjectStateIncrease((PetscObject)mat);
5654: #if defined(PETSC_HAVE_CUSP)
5655: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5656: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5657: }
5658: #endif
5659: return(0);
5660: }
5664: /*@C
5665: MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
5666: of a set of rows of a matrix; using local numbering of rows.
5668: Collective on Mat
5670: Input Parameters:
5671: + mat - the matrix
5672: . is - index set of rows to remove
5673: . diag - value put in all diagonals of eliminated rows
5674: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5675: - b - optional vector of right hand side, that will be adjusted by provided solution
5677: Notes:
5678: Before calling MatZeroRowsLocalIS(), the user must first set the
5679: local-to-global mapping by calling MatSetLocalToGlobalMapping().
5681: For the AIJ matrix formats this removes the old nonzero structure,
5682: but does not release memory. For the dense and block diagonal
5683: formats this does not alter the nonzero structure.
5685: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5686: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5687: merely zeroed.
5689: The user can set a value in the diagonal entry (or for the AIJ and
5690: row formats can optionally remove the main diagonal entry from the
5691: nonzero structure as well, by passing 0.0 as the final argument).
5693: You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5694: owns that are to be zeroed. This saves a global synchronization in the implementation.
5696: Level: intermediate
5698: Concepts: matrices^zeroing
5700: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5701: @*/
5702: PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5703: {
5705: PetscInt numRows;
5706: const PetscInt *rows;
5712: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5713: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5714: MatCheckPreallocated(mat,1);
5716: ISGetLocalSize(is,&numRows);
5717: ISGetIndices(is,&rows);
5718: MatZeroRowsLocal(mat,numRows,rows,diag,x,b);
5719: ISRestoreIndices(is,&rows);
5720: return(0);
5721: }
5725: /*@C
5726: MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
5727: of a set of rows and columns of a matrix; using local numbering of rows.
5729: Collective on Mat
5731: Input Parameters:
5732: + mat - the matrix
5733: . numRows - the number of rows to remove
5734: . rows - the global row indices
5735: . diag - value put in all diagonals of eliminated rows
5736: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5737: - b - optional vector of right hand side, that will be adjusted by provided solution
5739: Notes:
5740: Before calling MatZeroRowsColumnsLocal(), the user must first set the
5741: local-to-global mapping by calling MatSetLocalToGlobalMapping().
5743: The user can set a value in the diagonal entry (or for the AIJ and
5744: row formats can optionally remove the main diagonal entry from the
5745: nonzero structure as well, by passing 0.0 as the final argument).
5747: Level: intermediate
5749: Concepts: matrices^zeroing
5751: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5752: @*/
5753: PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5754: {
5756: PetscMPIInt size;
5762: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5763: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5764: MatCheckPreallocated(mat,1);
5766: MPI_Comm_size(((PetscObject)mat)->comm,&size);
5767: if (size == 1) {
5768: (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);
5769: } else {
5770: IS is, newis;
5771: const PetscInt *newRows;
5773: if (!mat->cmap->mapping) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5774: ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
5775: ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);
5776: ISGetIndices(newis,&newRows);
5777: (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);
5778: ISRestoreIndices(newis,&newRows);
5779: ISDestroy(&newis);
5780: ISDestroy(&is);
5781: }
5782: PetscObjectStateIncrease((PetscObject)mat);
5783: #if defined(PETSC_HAVE_CUSP)
5784: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5785: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5786: }
5787: #endif
5788: return(0);
5789: }
5793: /*@C
5794: MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
5795: of a set of rows and columns of a matrix; using local numbering of rows.
5797: Collective on Mat
5799: Input Parameters:
5800: + mat - the matrix
5801: . is - index set of rows to remove
5802: . diag - value put in all diagonals of eliminated rows
5803: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5804: - b - optional vector of right hand side, that will be adjusted by provided solution
5806: Notes:
5807: Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
5808: local-to-global mapping by calling MatSetLocalToGlobalMapping().
5810: The user can set a value in the diagonal entry (or for the AIJ and
5811: row formats can optionally remove the main diagonal entry from the
5812: nonzero structure as well, by passing 0.0 as the final argument).
5814: Level: intermediate
5816: Concepts: matrices^zeroing
5818: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5819: @*/
5820: PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5821: {
5823: PetscInt numRows;
5824: const PetscInt *rows;
5830: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5831: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5832: MatCheckPreallocated(mat,1);
5834: ISGetLocalSize(is,&numRows);
5835: ISGetIndices(is,&rows);
5836: MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);
5837: ISRestoreIndices(is,&rows);
5838: return(0);
5839: }
5843: /*@
5844: MatGetSize - Returns the numbers of rows and columns in a matrix.
5846: Not Collective
5848: Input Parameter:
5849: . mat - the matrix
5851: Output Parameters:
5852: + m - the number of global rows
5853: - n - the number of global columns
5855: Note: both output parameters can be PETSC_NULL on input.
5857: Level: beginner
5859: Concepts: matrices^size
5861: .seealso: MatGetLocalSize()
5862: @*/
5863: PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt* n)
5864: {
5867: if (m) *m = mat->rmap->N;
5868: if (n) *n = mat->cmap->N;
5869: return(0);
5870: }
5874: /*@
5875: MatGetLocalSize - Returns the number of rows and columns in a matrix
5876: stored locally. This information may be implementation dependent, so
5877: use with care.
5879: Not Collective
5881: Input Parameters:
5882: . mat - the matrix
5884: Output Parameters:
5885: + m - the number of local rows
5886: - n - the number of local columns
5888: Note: both output parameters can be PETSC_NULL on input.
5890: Level: beginner
5892: Concepts: matrices^local size
5894: .seealso: MatGetSize()
5895: @*/
5896: PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt* n)
5897: {
5902: if (m) *m = mat->rmap->n;
5903: if (n) *n = mat->cmap->n;
5904: return(0);
5905: }
5909: /*@
5910: MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
5911: this processor. (The columns of the "diagonal block")
5913: Not Collective, unless matrix has not been allocated, then collective on Mat
5915: Input Parameters:
5916: . mat - the matrix
5918: Output Parameters:
5919: + m - the global index of the first local column
5920: - n - one more than the global index of the last local column
5922: Notes: both output parameters can be PETSC_NULL on input.
5924: Level: developer
5926: Concepts: matrices^column ownership
5928: .seealso: MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
5930: @*/
5931: PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt* n)
5932: {
5939: MatCheckPreallocated(mat,1);
5940: if (m) *m = mat->cmap->rstart;
5941: if (n) *n = mat->cmap->rend;
5942: return(0);
5943: }
5947: /*@
5948: MatGetOwnershipRange - Returns the range of matrix rows owned by
5949: this processor, assuming that the matrix is laid out with the first
5950: n1 rows on the first processor, the next n2 rows on the second, etc.
5951: For certain parallel layouts this range may not be well defined.
5953: Not Collective, unless matrix has not been allocated, then collective on Mat
5955: Input Parameters:
5956: . mat - the matrix
5958: Output Parameters:
5959: + m - the global index of the first local row
5960: - n - one more than the global index of the last local row
5962: Note: both output parameters can be PETSC_NULL on input.
5964: Level: beginner
5966: Concepts: matrices^row ownership
5968: .seealso: MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
5970: @*/
5971: PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt* n)
5972: {
5979: MatCheckPreallocated(mat,1);
5980: if (m) *m = mat->rmap->rstart;
5981: if (n) *n = mat->rmap->rend;
5982: return(0);
5983: }
5987: /*@C
5988: MatGetOwnershipRanges - Returns the range of matrix rows owned by
5989: each process
5991: Not Collective, unless matrix has not been allocated, then collective on Mat
5993: Input Parameters:
5994: . mat - the matrix
5996: Output Parameters:
5997: . ranges - start of each processors portion plus one more then the total length at the end
5999: Level: beginner
6001: Concepts: matrices^row ownership
6003: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
6005: @*/
6006: PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6007: {
6013: MatCheckPreallocated(mat,1);
6014: PetscLayoutGetRanges(mat->rmap,ranges);
6015: return(0);
6016: }
6020: /*@C
6021: MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6022: this processor. (The columns of the "diagonal blocks" for each process)
6024: Not Collective, unless matrix has not been allocated, then collective on Mat
6026: Input Parameters:
6027: . mat - the matrix
6029: Output Parameters:
6030: . ranges - start of each processors portion plus one more then the total length at the end
6032: Level: beginner
6034: Concepts: matrices^column ownership
6036: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
6038: @*/
6039: PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6040: {
6046: MatCheckPreallocated(mat,1);
6047: PetscLayoutGetRanges(mat->cmap,ranges);
6048: return(0);
6049: }
6053: /*@C
6054: MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6055: Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6056: to complete the factorization.
6058: Collective on Mat
6060: Input Parameters:
6061: + mat - the matrix
6062: . row - row permutation
6063: . column - column permutation
6064: - info - structure containing
6065: $ levels - number of levels of fill.
6066: $ expected fill - as ratio of original fill.
6067: $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6068: missing diagonal entries)
6070: Output Parameters:
6071: . fact - new matrix that has been symbolically factored
6073: Notes:
6074: See the <a href="../../docs/manual.pdf">users manual</a> for additional information about
6075: choosing the fill factor for better efficiency.
6077: Most users should employ the simplified KSP interface for linear solvers
6078: instead of working directly with matrix algebra routines such as this.
6079: See, e.g., KSPCreate().
6081: Level: developer
6083: Concepts: matrices^symbolic LU factorization
6084: Concepts: matrices^factorization
6085: Concepts: LU^symbolic factorization
6087: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6088: MatGetOrdering(), MatFactorInfo
6090: Developer Note: fortran interface is not autogenerated as the f90
6091: interface defintion cannot be generated correctly [due to MatFactorInfo]
6093: @*/
6094: PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6095: {
6105: if (info->levels < 0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6106: if (info->fill < 1.0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
6107: if (!(fact)->ops->ilufactorsymbolic) {
6108: const MatSolverPackage spackage;
6109: MatFactorGetSolverPackage(fact,&spackage);
6110: SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6111: }
6112: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6113: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6114: MatCheckPreallocated(mat,2);
6116: PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);
6117: (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);
6118: PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);
6119: return(0);
6120: }
6124: /*@C
6125: MatICCFactorSymbolic - Performs symbolic incomplete
6126: Cholesky factorization for a symmetric matrix. Use
6127: MatCholeskyFactorNumeric() to complete the factorization.
6129: Collective on Mat
6131: Input Parameters:
6132: + mat - the matrix
6133: . perm - row and column permutation
6134: - info - structure containing
6135: $ levels - number of levels of fill.
6136: $ expected fill - as ratio of original fill.
6138: Output Parameter:
6139: . fact - the factored matrix
6141: Notes:
6142: Most users should employ the KSP interface for linear solvers
6143: instead of working directly with matrix algebra routines such as this.
6144: See, e.g., KSPCreate().
6146: Level: developer
6148: Concepts: matrices^symbolic incomplete Cholesky factorization
6149: Concepts: matrices^factorization
6150: Concepts: Cholsky^symbolic factorization
6152: .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
6154: Developer Note: fortran interface is not autogenerated as the f90
6155: interface defintion cannot be generated correctly [due to MatFactorInfo]
6157: @*/
6158: PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6159: {
6168: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6169: if (info->levels < 0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6170: if (info->fill < 1.0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
6171: if (!(fact)->ops->iccfactorsymbolic) {
6172: const MatSolverPackage spackage;
6173: MatFactorGetSolverPackage(fact,&spackage);
6174: SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6175: }
6176: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6177: MatCheckPreallocated(mat,2);
6179: PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);
6180: (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);
6181: PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);
6182: return(0);
6183: }
6187: /*@C
6188: MatGetArray - Returns a pointer to the element values in the matrix.
6189: The result of this routine is dependent on the underlying matrix data
6190: structure, and may not even work for certain matrix types. You MUST
6191: call MatRestoreArray() when you no longer need to access the array.
6193: Not Collective
6195: Input Parameter:
6196: . mat - the matrix
6198: Output Parameter:
6199: . v - the location of the values
6202: Fortran Note:
6203: This routine is used differently from Fortran, e.g.,
6204: .vb
6205: Mat mat
6206: PetscScalar mat_array(1)
6207: PetscOffset i_mat
6208: PetscErrorCode ierr
6209: call MatGetArray(mat,mat_array,i_mat,ierr)
6211: C Access first local entry in matrix; note that array is
6212: C treated as one dimensional
6213: value = mat_array(i_mat + 1)
6215: [... other code ...]
6216: call MatRestoreArray(mat,mat_array,i_mat,ierr)
6217: .ve
6219: See the <a href="../../docs/manual.pdf#Chapter 9 PETSc for Fortran Users">Fortran chapter of the users manual</a> and
6220: src/mat/examples/tests for details.
6222: Level: advanced
6224: Concepts: matrices^access array
6226: .seealso: MatRestoreArray(), MatGetArrayF90(), MatGetRowIJ()
6227: @*/
6228: PetscErrorCode MatGetArray(Mat mat,PetscScalar *v[])
6229: {
6236: if (!mat->ops->getarray) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6237: MatCheckPreallocated(mat,1);
6238: (*mat->ops->getarray)(mat,v);
6239: CHKMEMQ;
6240: return(0);
6241: }
6245: /*@C
6246: MatRestoreArray - Restores the matrix after MatGetArray() has been called.
6248: Not Collective
6250: Input Parameter:
6251: + mat - the matrix
6252: - v - the location of the values
6254: Fortran Note:
6255: This routine is used differently from Fortran, e.g.,
6256: .vb
6257: Mat mat
6258: PetscScalar mat_array(1)
6259: PetscOffset i_mat
6260: PetscErrorCode ierr
6261: call MatGetArray(mat,mat_array,i_mat,ierr)
6263: C Access first local entry in matrix; note that array is
6264: C treated as one dimensional
6265: value = mat_array(i_mat + 1)
6267: [... other code ...]
6268: call MatRestoreArray(mat,mat_array,i_mat,ierr)
6269: .ve
6271: See the <a href="../../docs/manual.pdf#Chapter 9 PETSc for Fortran Users">Fortran chapter of the users manual</a>
6272: src/mat/examples/tests for details
6274: Level: advanced
6276: .seealso: MatGetArray(), MatRestoreArrayF90()
6277: @*/
6278: PetscErrorCode MatRestoreArray(Mat mat,PetscScalar *v[])
6279: {
6286: CHKMEMQ;
6287: if (!mat->ops->restorearray) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6288: (*mat->ops->restorearray)(mat,v);
6289: PetscObjectStateIncrease((PetscObject)mat);
6290: #if defined(PETSC_HAVE_CUSP)
6291: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
6292: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
6293: }
6294: #endif
6295: return(0);
6296: }
6300: /*@C
6301: MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
6302: points to an array of valid matrices, they may be reused to store the new
6303: submatrices.
6305: Collective on Mat
6307: Input Parameters:
6308: + mat - the matrix
6309: . n - the number of submatrixes to be extracted (on this processor, may be zero)
6310: . irow, icol - index sets of rows and columns to extract (must be sorted)
6311: - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6313: Output Parameter:
6314: . submat - the array of submatrices
6316: Notes:
6317: MatGetSubMatrices() can extract ONLY sequential submatrices
6318: (from both sequential and parallel matrices). Use MatGetSubMatrix()
6319: to extract a parallel submatrix.
6321: Currently both row and column indices must be sorted to guarantee
6322: correctness with all matrix types.
6324: When extracting submatrices from a parallel matrix, each processor can
6325: form a different submatrix by setting the rows and columns of its
6326: individual index sets according to the local submatrix desired.
6328: When finished using the submatrices, the user should destroy
6329: them with MatDestroyMatrices().
6331: MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6332: original matrix has not changed from that last call to MatGetSubMatrices().
6334: This routine creates the matrices in submat; you should NOT create them before
6335: calling it. It also allocates the array of matrix pointers submat.
6337: For BAIJ matrices the index sets must respect the block structure, that is if they
6338: request one row/column in a block, they must request all rows/columns that are in
6339: that block. For example, if the block size is 2 you cannot request just row 0 and
6340: column 0.
6342: Fortran Note:
6343: The Fortran interface is slightly different from that given below; it
6344: requires one to pass in as submat a Mat (integer) array of size at least m.
6346: Level: advanced
6348: Concepts: matrices^accessing submatrices
6349: Concepts: submatrices
6351: .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6352: @*/
6353: PetscErrorCode MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6354: {
6356: PetscInt i;
6357: PetscBool eq;
6362: if (n) {
6367: }
6369: if (n && scall == MAT_REUSE_MATRIX) {
6372: }
6373: if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6374: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6375: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6376: MatCheckPreallocated(mat,1);
6378: PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6379: (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);
6380: PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6381: for (i=0; i<n; i++) {
6382: if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6383: ISEqual(irow[i],icol[i],&eq);
6384: if (eq) {
6385: if (mat->symmetric){
6386: MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6387: } else if (mat->hermitian) {
6388: MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6389: } else if (mat->structurally_symmetric) {
6390: MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6391: }
6392: }
6393: }
6394: }
6395: return(0);
6396: }
6400: PetscErrorCode MatGetSubMatricesParallel(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6401: {
6403: PetscInt i;
6404: PetscBool eq;
6409: if (n) {
6414: }
6416: if (n && scall == MAT_REUSE_MATRIX) {
6419: }
6420: if (!mat->ops->getsubmatricesparallel) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6421: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6422: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6423: MatCheckPreallocated(mat,1);
6425: PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6426: (*mat->ops->getsubmatricesparallel)(mat,n,irow,icol,scall,submat);
6427: PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6428: for (i=0; i<n; i++) {
6429: if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6430: ISEqual(irow[i],icol[i],&eq);
6431: if (eq) {
6432: if (mat->symmetric){
6433: MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6434: } else if (mat->hermitian) {
6435: MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6436: } else if (mat->structurally_symmetric) {
6437: MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6438: }
6439: }
6440: }
6441: }
6442: return(0);
6443: }
6447: /*@C
6448: MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().
6450: Collective on Mat
6452: Input Parameters:
6453: + n - the number of local matrices
6454: - mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6455: sequence of MatGetSubMatrices())
6457: Level: advanced
6459: Notes: Frees not only the matrices, but also the array that contains the matrices
6460: In Fortran will not free the array.
6462: .seealso: MatGetSubMatrices()
6463: @*/
6464: PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
6465: {
6467: PetscInt i;
6470: if (!*mat) return(0);
6471: if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6473: for (i=0; i<n; i++) {
6474: MatDestroy(&(*mat)[i]);
6475: }
6476: /* memory is allocated even if n = 0 */
6477: PetscFree(*mat);
6478: *mat = PETSC_NULL;
6479: return(0);
6480: }
6484: /*@C
6485: MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
6487: Collective on Mat
6489: Input Parameters:
6490: . mat - the matrix
6492: Output Parameter:
6493: . matstruct - the sequential matrix with the nonzero structure of mat
6495: Level: intermediate
6497: .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
6498: @*/
6499: PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6500: {
6506:
6508: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6509: MatCheckPreallocated(mat,1);
6511: if (!mat->ops->getseqnonzerostructure) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6512: PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6513: (*mat->ops->getseqnonzerostructure)(mat,matstruct);
6514: PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6515: return(0);
6516: }
6520: /*@C
6521: MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
6523: Collective on Mat
6525: Input Parameters:
6526: . mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
6527: sequence of MatGetSequentialNonzeroStructure())
6529: Level: advanced
6531: Notes: Frees not only the matrices, but also the array that contains the matrices
6533: .seealso: MatGetSeqNonzeroStructure()
6534: @*/
6535: PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
6536: {
6541: MatDestroy(mat);
6542: return(0);
6543: }
6547: /*@
6548: MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6549: replaces the index sets by larger ones that represent submatrices with
6550: additional overlap.
6552: Collective on Mat
6554: Input Parameters:
6555: + mat - the matrix
6556: . n - the number of index sets
6557: . is - the array of index sets (these index sets will changed during the call)
6558: - ov - the additional overlap requested
6560: Level: developer
6562: Concepts: overlap
6563: Concepts: ASM^computing overlap
6565: .seealso: MatGetSubMatrices()
6566: @*/
6567: PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6568: {
6574: if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6575: if (n) {
6578: }
6579: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6580: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6581: MatCheckPreallocated(mat,1);
6583: if (!ov) return(0);
6584: if (!mat->ops->increaseoverlap) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6585: PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
6586: (*mat->ops->increaseoverlap)(mat,n,is,ov);
6587: PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
6588: return(0);
6589: }
6593: /*@
6594: MatGetBlockSize - Returns the matrix block size; useful especially for the
6595: block row and block diagonal formats.
6596:
6597: Not Collective
6599: Input Parameter:
6600: . mat - the matrix
6602: Output Parameter:
6603: . bs - block size
6605: Notes:
6606: Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ
6608: Level: intermediate
6610: Concepts: matrices^block size
6612: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
6613: @*/
6614: PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
6615: {
6621: MatCheckPreallocated(mat,1);
6622: *bs = mat->rmap->bs;
6623: return(0);
6624: }
6628: /*@
6629: MatGetBlockSizes - Returns the matrix block row and column sizes;
6630: useful especially for the block row and block diagonal formats.
6631:
6632: Not Collective
6634: Input Parameter:
6635: . mat - the matrix
6637: Output Parameter:
6638: . rbs - row block size
6639: . cbs - coumn block size
6641: Notes:
6642: Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ
6644: Level: intermediate
6646: Concepts: matrices^block size
6648: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
6649: @*/
6650: PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
6651: {
6658: MatCheckPreallocated(mat,1);
6659: if(rbs) *rbs = mat->rmap->bs;
6660: if(cbs) *cbs = mat->cmap->bs;
6661: return(0);
6662: }
6666: /*@
6667: MatSetBlockSize - Sets the matrix block size.
6668:
6669: Logically Collective on Mat
6671: Input Parameters:
6672: + mat - the matrix
6673: - bs - block size
6675: Notes:
6676: This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later
6678: Level: intermediate
6680: Concepts: matrices^block size
6682: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
6683: @*/
6684: PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
6685: {
6691: PetscLayoutSetBlockSize(mat->rmap,bs);
6692: PetscLayoutSetBlockSize(mat->cmap,bs);
6693: return(0);
6694: }
6698: /*@
6699: MatSetBlockSizes - Sets the matrix block row and column sizes.
6700:
6701: Logically Collective on Mat
6703: Input Parameters:
6704: + mat - the matrix
6705: - rbs - row block size
6706: - cbs - column block size
6708: Notes:
6709: This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later
6711: Level: intermediate
6713: Concepts: matrices^block size
6715: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
6716: @*/
6717: PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
6718: {
6724: PetscLayoutSetBlockSize(mat->rmap,rbs);
6725: PetscLayoutSetBlockSize(mat->cmap,cbs);
6726: return(0);
6727: }
6731: /*@C
6732: MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
6734: Collective on Mat
6736: Input Parameters:
6737: + mat - the matrix
6738: . shift - 0 or 1 indicating we want the indices starting at 0 or 1
6739: . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be symmetrized
6740: - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6741: inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6742: always used.
6744: Output Parameters:
6745: + n - number of rows in the (possibly compressed) matrix
6746: . ia - the row pointers [of length n+1]
6747: . ja - the column indices
6748: - done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
6749: are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
6751: Level: developer
6753: Notes: You CANNOT change any of the ia[] or ja[] values.
6755: Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values
6757: Fortran Node
6759: In Fortran use
6760: $ PetscInt ia(1), ja(1)
6761: $ PetscOffset iia, jja
6762: $ call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
6763: $
6764: $ or
6765: $
6766: $ PetscScalar, pointer :: xx_v(:)
6767: $ call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
6768:
6769:
6770: Acess the ith and jth entries via ia(iia + i) and ja(jja + j)
6772: .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatGetArray()
6773: @*/
6774: PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool *done)
6775: {
6785: MatCheckPreallocated(mat,1);
6786: if (!mat->ops->getrowij) *done = PETSC_FALSE;
6787: else {
6788: *done = PETSC_TRUE;
6789: PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);
6790: (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6791: PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);
6792: }
6793: return(0);
6794: }
6798: /*@C
6799: MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
6801: Collective on Mat
6803: Input Parameters:
6804: + mat - the matrix
6805: . shift - 1 or zero indicating we want the indices starting at 0 or 1
6806: . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6807: symmetrized
6808: - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6809: inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6810: always used.
6812: Output Parameters:
6813: + n - number of columns in the (possibly compressed) matrix
6814: . ia - the column pointers
6815: . ja - the row indices
6816: - done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
6818: Level: developer
6820: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6821: @*/
6822: PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool *done)
6823: {
6833: MatCheckPreallocated(mat,1);
6834: if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
6835: else {
6836: *done = PETSC_TRUE;
6837: (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6838: }
6839: return(0);
6840: }
6844: /*@C
6845: MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
6846: MatGetRowIJ().
6848: Collective on Mat
6850: Input Parameters:
6851: + mat - the matrix
6852: . shift - 1 or zero indicating we want the indices starting at 0 or 1
6853: . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6854: symmetrized
6855: - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6856: inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6857: always used.
6859: Output Parameters:
6860: + n - size of (possibly compressed) matrix
6861: . ia - the row pointers
6862: . ja - the column indices
6863: - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
6865: Level: developer
6867: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6868: @*/
6869: PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool *done)
6870: {
6879: MatCheckPreallocated(mat,1);
6881: if (!mat->ops->restorerowij) *done = PETSC_FALSE;
6882: else {
6883: *done = PETSC_TRUE;
6884: (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6885: }
6886: return(0);
6887: }
6891: /*@C
6892: MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
6893: MatGetColumnIJ().
6895: Collective on Mat
6897: Input Parameters:
6898: + mat - the matrix
6899: . shift - 1 or zero indicating we want the indices starting at 0 or 1
6900: - symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6901: symmetrized
6902: - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6903: inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6904: always used.
6906: Output Parameters:
6907: + n - size of (possibly compressed) matrix
6908: . ia - the column pointers
6909: . ja - the row indices
6910: - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
6912: Level: developer
6914: .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
6915: @*/
6916: PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool *done)
6917: {
6926: MatCheckPreallocated(mat,1);
6928: if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
6929: else {
6930: *done = PETSC_TRUE;
6931: (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6932: }
6933: return(0);
6934: }
6938: /*@C
6939: MatColoringPatch -Used inside matrix coloring routines that
6940: use MatGetRowIJ() and/or MatGetColumnIJ().
6942: Collective on Mat
6944: Input Parameters:
6945: + mat - the matrix
6946: . ncolors - max color value
6947: . n - number of entries in colorarray
6948: - colorarray - array indicating color for each column
6950: Output Parameters:
6951: . iscoloring - coloring generated using colorarray information
6953: Level: developer
6955: .seealso: MatGetRowIJ(), MatGetColumnIJ()
6957: @*/
6958: PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
6959: {
6967: MatCheckPreallocated(mat,1);
6969: if (!mat->ops->coloringpatch){
6970: ISColoringCreate(((PetscObject)mat)->comm,ncolors,n,colorarray,iscoloring);
6971: } else {
6972: (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);
6973: }
6974: return(0);
6975: }
6980: /*@
6981: MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
6983: Logically Collective on Mat
6985: Input Parameter:
6986: . mat - the factored matrix to be reset
6988: Notes:
6989: This routine should be used only with factored matrices formed by in-place
6990: factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
6991: format). This option can save memory, for example, when solving nonlinear
6992: systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
6993: ILU(0) preconditioner.
6995: Note that one can specify in-place ILU(0) factorization by calling
6996: .vb
6997: PCType(pc,PCILU);
6998: PCFactorSeUseInPlace(pc);
6999: .ve
7000: or by using the options -pc_type ilu -pc_factor_in_place
7002: In-place factorization ILU(0) can also be used as a local
7003: solver for the blocks within the block Jacobi or additive Schwarz
7004: methods (runtime option: -sub_pc_factor_in_place). See the discussion
7005: of these preconditioners in the <a href="../../docs/manual.pdf#ch_pc">PC chapter of the users manual</a> for details on setting
7006: local solver options.
7008: Most users should employ the simplified KSP interface for linear solvers
7009: instead of working directly with matrix algebra routines such as this.
7010: See, e.g., KSPCreate().
7012: Level: developer
7014: .seealso: PCFactorSetUseInPlace()
7016: Concepts: matrices^unfactored
7018: @*/
7019: PetscErrorCode MatSetUnfactored(Mat mat)
7020: {
7026: MatCheckPreallocated(mat,1);
7027: mat->factortype = MAT_FACTOR_NONE;
7028: if (!mat->ops->setunfactored) return(0);
7029: (*mat->ops->setunfactored)(mat);
7030: return(0);
7031: }
7033: /*MC
7034: MatGetArrayF90 - Accesses a matrix array from Fortran90.
7036: Synopsis:
7037: MatGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7039: Not collective
7041: Input Parameter:
7042: . x - matrix
7044: Output Parameters:
7045: + xx_v - the Fortran90 pointer to the array
7046: - ierr - error code
7048: Example of Usage:
7049: .vb
7050: PetscScalar, pointer xx_v(:,:)
7051: ....
7052: call MatGetArrayF90(x,xx_v,ierr)
7053: a = xx_v(3)
7054: call MatRestoreArrayF90(x,xx_v,ierr)
7055: .ve
7057: Notes:
7058: Not yet supported for all F90 compilers
7060: Level: advanced
7062: .seealso: MatRestoreArrayF90(), MatGetArray(), MatRestoreArray()
7064: Concepts: matrices^accessing array
7066: M*/
7068: /*MC
7069: MatRestoreArrayF90 - Restores a matrix array that has been
7070: accessed with MatGetArrayF90().
7072: Synopsis:
7073: MatRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7075: Not collective
7077: Input Parameters:
7078: + x - matrix
7079: - xx_v - the Fortran90 pointer to the array
7081: Output Parameter:
7082: . ierr - error code
7084: Example of Usage:
7085: .vb
7086: PetscScalar, pointer xx_v(:)
7087: ....
7088: call MatGetArrayF90(x,xx_v,ierr)
7089: a = xx_v(3)
7090: call MatRestoreArrayF90(x,xx_v,ierr)
7091: .ve
7092:
7093: Notes:
7094: Not yet supported for all F90 compilers
7096: Level: advanced
7098: .seealso: MatGetArrayF90(), MatGetArray(), MatRestoreArray()
7100: M*/
7105: /*@
7106: MatGetSubMatrix - Gets a single submatrix on the same number of processors
7107: as the original matrix.
7109: Collective on Mat
7111: Input Parameters:
7112: + mat - the original matrix
7113: . isrow - parallel IS containing the rows this processor should obtain
7114: . 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.
7115: - cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7117: Output Parameter:
7118: . newmat - the new submatrix, of the same type as the old
7120: Level: advanced
7122: Notes:
7123: The submatrix will be able to be multiplied with vectors using the same layout as iscol.
7125: The rows in isrow will be sorted into the same order as the original matrix on each process.
7127: The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7128: the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
7129: to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7130: will reuse the matrix generated the first time. You should call MatDestroy() on newmat when
7131: you are finished using it.
7133: The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7134: the input matrix.
7136: If iscol is PETSC_NULL then all columns are obtained (not supported in Fortran).
7138: Example usage:
7139: Consider the following 8x8 matrix with 34 non-zero values, that is
7140: assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7141: proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7142: as follows:
7144: .vb
7145: 1 2 0 | 0 3 0 | 0 4
7146: Proc0 0 5 6 | 7 0 0 | 8 0
7147: 9 0 10 | 11 0 0 | 12 0
7148: -------------------------------------
7149: 13 0 14 | 15 16 17 | 0 0
7150: Proc1 0 18 0 | 19 20 21 | 0 0
7151: 0 0 0 | 22 23 0 | 24 0
7152: -------------------------------------
7153: Proc2 25 26 27 | 0 0 28 | 29 0
7154: 30 0 0 | 31 32 33 | 0 34
7155: .ve
7157: Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6]. The resulting submatrix is
7159: .vb
7160: 2 0 | 0 3 0 | 0
7161: Proc0 5 6 | 7 0 0 | 8
7162: -------------------------------
7163: Proc1 18 0 | 19 20 21 | 0
7164: -------------------------------
7165: Proc2 26 27 | 0 0 28 | 29
7166: 0 0 | 31 32 33 | 0
7167: .ve
7170: Concepts: matrices^submatrices
7172: .seealso: MatGetSubMatrices()
7173: @*/
7174: PetscErrorCode MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7175: {
7177: PetscMPIInt size;
7178: Mat *local;
7179: IS iscoltmp;
7188: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7189: MatCheckPreallocated(mat,1);
7190: MPI_Comm_size(((PetscObject)mat)->comm,&size);
7192: if (!iscol) {
7193: ISCreateStride(((PetscObject)mat)->comm,mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);
7194: } else {
7195: iscoltmp = iscol;
7196: }
7198: /* if original matrix is on just one processor then use submatrix generated */
7199: if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7200: MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);
7201: if (!iscol) {ISDestroy(&iscoltmp);}
7202: return(0);
7203: } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) {
7204: MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);
7205: *newmat = *local;
7206: PetscFree(local);
7207: if (!iscol) {ISDestroy(&iscoltmp);}
7208: return(0);
7209: } else if (!mat->ops->getsubmatrix) {
7210: /* Create a new matrix type that implements the operation using the full matrix */
7211: switch (cll) {
7212: case MAT_INITIAL_MATRIX:
7213: MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);
7214: break;
7215: case MAT_REUSE_MATRIX:
7216: MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);
7217: break;
7218: default: SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7219: }
7220: if (!iscol) {ISDestroy(&iscoltmp);}
7221: return(0);
7222: }
7224: if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7225: (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);
7226: if (!iscol) {ISDestroy(&iscoltmp);}
7227: if (*newmat && cll == MAT_INITIAL_MATRIX) {PetscObjectStateIncrease((PetscObject)*newmat);}
7228: return(0);
7229: }
7233: /*@
7234: MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7235: used during the assembly process to store values that belong to
7236: other processors.
7238: Not Collective
7240: Input Parameters:
7241: + mat - the matrix
7242: . size - the initial size of the stash.
7243: - bsize - the initial size of the block-stash(if used).
7245: Options Database Keys:
7246: + -matstash_initial_size <size> or <size0,size1,...sizep-1>
7247: - -matstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1>
7249: Level: intermediate
7251: Notes:
7252: The block-stash is used for values set with MatSetValuesBlocked() while
7253: the stash is used for values set with MatSetValues()
7255: Run with the option -info and look for output of the form
7256: MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7257: to determine the appropriate value, MM, to use for size and
7258: MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7259: to determine the value, BMM to use for bsize
7261: Concepts: stash^setting matrix size
7262: Concepts: matrices^stash
7264: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
7266: @*/
7267: PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7268: {
7274: MatStashSetInitialSize_Private(&mat->stash,size);
7275: MatStashSetInitialSize_Private(&mat->bstash,bsize);
7276: return(0);
7277: }
7281: /*@
7282: MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
7283: the matrix
7285: Neighbor-wise Collective on Mat
7287: Input Parameters:
7288: + mat - the matrix
7289: . x,y - the vectors
7290: - w - where the result is stored
7292: Level: intermediate
7294: Notes:
7295: w may be the same vector as y.
7297: This allows one to use either the restriction or interpolation (its transpose)
7298: matrix to do the interpolation
7300: Concepts: interpolation
7302: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7304: @*/
7305: PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7306: {
7308: PetscInt M,N,Ny;
7316: MatCheckPreallocated(A,1);
7317: MatGetSize(A,&M,&N);
7318: VecGetSize(y,&Ny);
7319: if (M == Ny) {
7320: MatMultAdd(A,x,y,w);
7321: } else {
7322: MatMultTransposeAdd(A,x,y,w);
7323: }
7324: return(0);
7325: }
7329: /*@
7330: MatInterpolate - y = A*x or A'*x depending on the shape of
7331: the matrix
7333: Neighbor-wise Collective on Mat
7335: Input Parameters:
7336: + mat - the matrix
7337: - x,y - the vectors
7339: Level: intermediate
7341: Notes:
7342: This allows one to use either the restriction or interpolation (its transpose)
7343: matrix to do the interpolation
7345: Concepts: matrices^interpolation
7347: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7349: @*/
7350: PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
7351: {
7353: PetscInt M,N,Ny;
7360: MatCheckPreallocated(A,1);
7361: MatGetSize(A,&M,&N);
7362: VecGetSize(y,&Ny);
7363: if (M == Ny) {
7364: MatMult(A,x,y);
7365: } else {
7366: MatMultTranspose(A,x,y);
7367: }
7368: return(0);
7369: }
7373: /*@
7374: MatRestrict - y = A*x or A'*x
7376: Neighbor-wise Collective on Mat
7378: Input Parameters:
7379: + mat - the matrix
7380: - x,y - the vectors
7382: Level: intermediate
7384: Notes:
7385: This allows one to use either the restriction or interpolation (its transpose)
7386: matrix to do the restriction
7388: Concepts: matrices^restriction
7390: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
7392: @*/
7393: PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
7394: {
7396: PetscInt M,N,Ny;
7403: MatCheckPreallocated(A,1);
7405: MatGetSize(A,&M,&N);
7406: VecGetSize(y,&Ny);
7407: if (M == Ny) {
7408: MatMult(A,x,y);
7409: } else {
7410: MatMultTranspose(A,x,y);
7411: }
7412: return(0);
7413: }
7417: /*@
7418: MatGetNullSpace - retrieves the null space to a matrix.
7420: Logically Collective on Mat and MatNullSpace
7422: Input Parameters:
7423: + mat - the matrix
7424: - nullsp - the null space object
7426: Level: developer
7428: Notes:
7429: This null space is used by solvers. Overwrites any previous null space that may have been attached
7431: Concepts: null space^attaching to matrix
7433: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace()
7434: @*/
7435: PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
7436: {
7441: *nullsp = mat->nullsp;
7442: return(0);
7443: }
7447: /*@
7448: MatSetNullSpace - attaches a null space to a matrix.
7449: This null space will be removed from the resulting vector whenever
7450: MatMult() is called
7452: Logically Collective on Mat and MatNullSpace
7454: Input Parameters:
7455: + mat - the matrix
7456: - nullsp - the null space object
7458: Level: advanced
7460: Notes:
7461: This null space is used by solvers. Overwrites any previous null space that may have been attached
7463: Concepts: null space^attaching to matrix
7465: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace()
7466: @*/
7467: PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp)
7468: {
7475: MatCheckPreallocated(mat,1);
7476: PetscObjectReference((PetscObject)nullsp);
7477: MatNullSpaceDestroy(&mat->nullsp);
7478: mat->nullsp = nullsp;
7479: return(0);
7480: }
7484: /*@
7485: MatSetNearNullSpace - attaches a null space to a matrix.
7486: This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.
7488: Logically Collective on Mat and MatNullSpace
7490: Input Parameters:
7491: + mat - the matrix
7492: - nullsp - the null space object
7494: Level: advanced
7496: Notes:
7497: Overwrites any previous near null space that may have been attached
7499: Concepts: null space^attaching to matrix
7501: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace()
7502: @*/
7503: PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
7504: {
7511: MatCheckPreallocated(mat,1);
7512: PetscObjectReference((PetscObject)nullsp);
7513: MatNullSpaceDestroy(&mat->nearnullsp);
7514: mat->nearnullsp = nullsp;
7515: return(0);
7516: }
7520: /*@
7521: MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()
7523: Not Collective
7525: Input Parameters:
7526: . mat - the matrix
7528: Output Parameters:
7529: . nullsp - the null space object, PETSC_NULL if not set
7531: Level: developer
7533: Concepts: null space^attaching to matrix
7535: .seealso: MatSetNearNullSpace(), MatGetNullSpace()
7536: @*/
7537: PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
7538: {
7544: MatCheckPreallocated(mat,1);
7545: *nullsp = mat->nearnullsp;
7546: return(0);
7547: }
7551: /*@C
7552: MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
7554: Collective on Mat
7556: Input Parameters:
7557: + mat - the matrix
7558: . row - row/column permutation
7559: . fill - expected fill factor >= 1.0
7560: - level - level of fill, for ICC(k)
7562: Notes:
7563: Probably really in-place only when level of fill is zero, otherwise allocates
7564: new space to store factored matrix and deletes previous memory.
7566: Most users should employ the simplified KSP interface for linear solvers
7567: instead of working directly with matrix algebra routines such as this.
7568: See, e.g., KSPCreate().
7570: Level: developer
7572: Concepts: matrices^incomplete Cholesky factorization
7573: Concepts: Cholesky factorization
7575: .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
7577: Developer Note: fortran interface is not autogenerated as the f90
7578: interface defintion cannot be generated correctly [due to MatFactorInfo]
7580: @*/
7581: PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo* info)
7582: {
7590: if (mat->rmap->N != mat->cmap->N) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONG,"matrix must be square");
7591: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7592: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7593: if (!mat->ops->iccfactor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7594: MatCheckPreallocated(mat,1);
7595: (*mat->ops->iccfactor)(mat,row,info);
7596: PetscObjectStateIncrease((PetscObject)mat);
7597: return(0);
7598: }
7602: /*@
7603: MatSetValuesAdic - Sets values computed with ADIC automatic differentiation into a matrix.
7605: Not Collective
7607: Input Parameters:
7608: + mat - the matrix
7609: - v - the values compute with ADIC
7611: Level: developer
7613: Notes:
7614: Must call MatSetColoring() before using this routine. Also this matrix must already
7615: have its nonzero pattern determined.
7617: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7618: MatSetValues(), MatSetColoring(), MatSetValuesAdifor()
7619: @*/
7620: PetscErrorCode MatSetValuesAdic(Mat mat,void *v)
7621: {
7629: if (!mat->assembled) {
7630: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7631: }
7632: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
7633: if (!mat->ops->setvaluesadic) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7634: (*mat->ops->setvaluesadic)(mat,v);
7635: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
7636: MatView_Private(mat);
7637: PetscObjectStateIncrease((PetscObject)mat);
7638: return(0);
7639: }
7644: /*@
7645: MatSetColoring - Sets a coloring used by calls to MatSetValuesAdic()
7647: Not Collective
7649: Input Parameters:
7650: + mat - the matrix
7651: - coloring - the coloring
7653: Level: developer
7655: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7656: MatSetValues(), MatSetValuesAdic()
7657: @*/
7658: PetscErrorCode MatSetColoring(Mat mat,ISColoring coloring)
7659: {
7667: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7668: if (!mat->ops->setcoloring) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7669: (*mat->ops->setcoloring)(mat,coloring);
7670: return(0);
7671: }
7675: /*@
7676: MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.
7678: Not Collective
7680: Input Parameters:
7681: + mat - the matrix
7682: . nl - leading dimension of v
7683: - v - the values compute with ADIFOR
7685: Level: developer
7687: Notes:
7688: Must call MatSetColoring() before using this routine. Also this matrix must already
7689: have its nonzero pattern determined.
7691: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7692: MatSetValues(), MatSetColoring()
7693: @*/
7694: PetscErrorCode MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
7695: {
7703: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7704: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
7705: if (!mat->ops->setvaluesadifor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7706: (*mat->ops->setvaluesadifor)(mat,nl,v);
7707: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
7708: PetscObjectStateIncrease((PetscObject)mat);
7709: return(0);
7710: }
7714: /*@
7715: MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
7716: ghosted ones.
7718: Not Collective
7720: Input Parameters:
7721: + mat - the matrix
7722: - diag = the diagonal values, including ghost ones
7724: Level: developer
7726: Notes: Works only for MPIAIJ and MPIBAIJ matrices
7727:
7728: .seealso: MatDiagonalScale()
7729: @*/
7730: PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
7731: {
7733: PetscMPIInt size;
7740: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7741: PetscLogEventBegin(MAT_Scale,mat,0,0,0);
7742: MPI_Comm_size(((PetscObject)mat)->comm,&size);
7743: if (size == 1) {
7744: PetscInt n,m;
7745: VecGetSize(diag,&n);
7746: MatGetSize(mat,0,&m);
7747: if (m == n) {
7748: MatDiagonalScale(mat,0,diag);
7749: } else {
7750: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
7751: }
7752: } else {
7753: PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));
7754: }
7755: PetscLogEventEnd(MAT_Scale,mat,0,0,0);
7756: PetscObjectStateIncrease((PetscObject)mat);
7757: return(0);
7758: }
7762: /*@
7763: MatGetInertia - Gets the inertia from a factored matrix
7765: Collective on Mat
7767: Input Parameter:
7768: . mat - the matrix
7770: Output Parameters:
7771: + nneg - number of negative eigenvalues
7772: . nzero - number of zero eigenvalues
7773: - npos - number of positive eigenvalues
7775: Level: advanced
7777: Notes: Matrix must have been factored by MatCholeskyFactor()
7780: @*/
7781: PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
7782: {
7788: if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7789: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
7790: if (!mat->ops->getinertia) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7791: (*mat->ops->getinertia)(mat,nneg,nzero,npos);
7792: return(0);
7793: }
7795: /* ----------------------------------------------------------------*/
7798: /*@C
7799: MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
7801: Neighbor-wise Collective on Mat and Vecs
7803: Input Parameters:
7804: + mat - the factored matrix
7805: - b - the right-hand-side vectors
7807: Output Parameter:
7808: . x - the result vectors
7810: Notes:
7811: The vectors b and x cannot be the same. I.e., one cannot
7812: call MatSolves(A,x,x).
7814: Notes:
7815: Most users should employ the simplified KSP interface for linear solvers
7816: instead of working directly with matrix algebra routines such as this.
7817: See, e.g., KSPCreate().
7819: Level: developer
7821: Concepts: matrices^triangular solves
7823: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
7824: @*/
7825: PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
7826: {
7832: if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
7833: if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7834: if (!mat->rmap->N && !mat->cmap->N) return(0);
7836: if (!mat->ops->solves) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7837: MatCheckPreallocated(mat,1);
7838: PetscLogEventBegin(MAT_Solves,mat,0,0,0);
7839: (*mat->ops->solves)(mat,b,x);
7840: PetscLogEventEnd(MAT_Solves,mat,0,0,0);
7841: return(0);
7842: }
7846: /*@
7847: MatIsSymmetric - Test whether a matrix is symmetric
7849: Collective on Mat
7851: Input Parameter:
7852: + A - the matrix to test
7853: - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
7855: Output Parameters:
7856: . flg - the result
7858: Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
7860: Level: intermediate
7862: Concepts: matrix^symmetry
7864: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
7865: @*/
7866: PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool *flg)
7867: {
7874: if (!A->symmetric_set) {
7875: if (!A->ops->issymmetric) {
7876: const MatType mattype;
7877: MatGetType(A,&mattype);
7878: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7879: }
7880: (*A->ops->issymmetric)(A,tol,flg);
7881: if (!tol) {
7882: A->symmetric_set = PETSC_TRUE;
7883: A->symmetric = *flg;
7884: if (A->symmetric) {
7885: A->structurally_symmetric_set = PETSC_TRUE;
7886: A->structurally_symmetric = PETSC_TRUE;
7887: }
7888: }
7889: } else if (A->symmetric) {
7890: *flg = PETSC_TRUE;
7891: } else if (!tol) {
7892: *flg = PETSC_FALSE;
7893: } else {
7894: if (!A->ops->issymmetric) {
7895: const MatType mattype;
7896: MatGetType(A,&mattype);
7897: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7898: }
7899: (*A->ops->issymmetric)(A,tol,flg);
7900: }
7901: return(0);
7902: }
7906: /*@
7907: MatIsHermitian - Test whether a matrix is Hermitian
7909: Collective on Mat
7911: Input Parameter:
7912: + A - the matrix to test
7913: - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
7915: Output Parameters:
7916: . flg - the result
7918: Level: intermediate
7920: Concepts: matrix^symmetry
7922: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
7923: MatIsSymmetricKnown(), MatIsSymmetric()
7924: @*/
7925: PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool *flg)
7926: {
7933: if (!A->hermitian_set) {
7934: if (!A->ops->ishermitian) {
7935: const MatType mattype;
7936: MatGetType(A,&mattype);
7937: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7938: }
7939: (*A->ops->ishermitian)(A,tol,flg);
7940: if (!tol) {
7941: A->hermitian_set = PETSC_TRUE;
7942: A->hermitian = *flg;
7943: if (A->hermitian) {
7944: A->structurally_symmetric_set = PETSC_TRUE;
7945: A->structurally_symmetric = PETSC_TRUE;
7946: }
7947: }
7948: } else if (A->hermitian) {
7949: *flg = PETSC_TRUE;
7950: } else if (!tol) {
7951: *flg = PETSC_FALSE;
7952: } else {
7953: if (!A->ops->ishermitian) {
7954: const MatType mattype;
7955: MatGetType(A,&mattype);
7956: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7957: }
7958: (*A->ops->ishermitian)(A,tol,flg);
7959: }
7960: return(0);
7961: }
7965: /*@
7966: MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
7968: Not Collective
7970: Input Parameter:
7971: . A - the matrix to check
7973: Output Parameters:
7974: + set - if the symmetric flag is set (this tells you if the next flag is valid)
7975: - flg - the result
7977: Level: advanced
7979: Concepts: matrix^symmetry
7981: Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
7982: if you want it explicitly checked
7984: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
7985: @*/
7986: PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool *set,PetscBool *flg)
7987: {
7992: if (A->symmetric_set) {
7993: *set = PETSC_TRUE;
7994: *flg = A->symmetric;
7995: } else {
7996: *set = PETSC_FALSE;
7997: }
7998: return(0);
7999: }
8003: /*@
8004: MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
8006: Not Collective
8008: Input Parameter:
8009: . A - the matrix to check
8011: Output Parameters:
8012: + set - if the hermitian flag is set (this tells you if the next flag is valid)
8013: - flg - the result
8015: Level: advanced
8017: Concepts: matrix^symmetry
8019: Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8020: if you want it explicitly checked
8022: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8023: @*/
8024: PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg)
8025: {
8030: if (A->hermitian_set) {
8031: *set = PETSC_TRUE;
8032: *flg = A->hermitian;
8033: } else {
8034: *set = PETSC_FALSE;
8035: }
8036: return(0);
8037: }
8041: /*@
8042: MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
8044: Collective on Mat
8046: Input Parameter:
8047: . A - the matrix to test
8049: Output Parameters:
8050: . flg - the result
8052: Level: intermediate
8054: Concepts: matrix^symmetry
8056: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8057: @*/
8058: PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg)
8059: {
8065: if (!A->structurally_symmetric_set) {
8066: if (!A->ops->isstructurallysymmetric) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8067: (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);
8068: A->structurally_symmetric_set = PETSC_TRUE;
8069: }
8070: *flg = A->structurally_symmetric;
8071: return(0);
8072: }
8076: extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
8077: /*@
8078: MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8079: to be communicated to other processors during the MatAssemblyBegin/End() process
8081: Not collective
8083: Input Parameter:
8084: . vec - the vector
8086: Output Parameters:
8087: + nstash - the size of the stash
8088: . reallocs - the number of additional mallocs incurred.
8089: . bnstash - the size of the block stash
8090: - breallocs - the number of additional mallocs incurred.in the block stash
8091:
8092: Level: advanced
8094: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
8095:
8096: @*/
8097: PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8098: {
8101: MatStashGetInfo_Private(&mat->stash,nstash,reallocs);
8102: MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);
8103: return(0);
8104: }
8108: /*@C
8109: MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same
8110: parallel layout
8111:
8112: Collective on Mat
8114: Input Parameter:
8115: . mat - the matrix
8117: Output Parameter:
8118: + right - (optional) vector that the matrix can be multiplied against
8119: - left - (optional) vector that the matrix vector product can be stored in
8121: Level: advanced
8123: .seealso: MatCreate()
8124: @*/
8125: PetscErrorCode MatGetVecs(Mat mat,Vec *right,Vec *left)
8126: {
8132: MatCheckPreallocated(mat,1);
8133: if (mat->ops->getvecs) {
8134: (*mat->ops->getvecs)(mat,right,left);
8135: } else {
8136: PetscMPIInt size;
8137: MPI_Comm_size(((PetscObject)mat)->comm, &size);
8138: if (right) {
8139: VecCreate(((PetscObject)mat)->comm,right);
8140: VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);
8141: VecSetBlockSize(*right,mat->rmap->bs);
8142: VecSetType(*right,VECSTANDARD);
8143: PetscLayoutReference(mat->cmap,&(*right)->map);
8144: }
8145: if (left) {
8146: VecCreate(((PetscObject)mat)->comm,left);
8147: VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);
8148: VecSetBlockSize(*left,mat->rmap->bs);
8149: VecSetType(*left,VECSTANDARD);
8150: PetscLayoutReference(mat->rmap,&(*left)->map);
8151: }
8152: }
8153: return(0);
8154: }
8158: /*@C
8159: MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8160: with default values.
8162: Not Collective
8164: Input Parameters:
8165: . info - the MatFactorInfo data structure
8168: Notes: The solvers are generally used through the KSP and PC objects, for example
8169: PCLU, PCILU, PCCHOLESKY, PCICC
8171: Level: developer
8173: .seealso: MatFactorInfo
8175: Developer Note: fortran interface is not autogenerated as the f90
8176: interface defintion cannot be generated correctly [due to MatFactorInfo]
8178: @*/
8180: PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
8181: {
8185: PetscMemzero(info,sizeof(MatFactorInfo));
8186: return(0);
8187: }
8191: /*@
8192: MatPtAP - Creates the matrix product C = P^T * A * P
8194: Neighbor-wise Collective on Mat
8196: Input Parameters:
8197: + A - the matrix
8198: . P - the projection matrix
8199: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8200: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P))
8202: Output Parameters:
8203: . C - the product matrix
8205: Notes:
8206: C will be created and must be destroyed by the user with MatDestroy().
8208: This routine is currently only implemented for pairs of AIJ matrices and classes
8209: which inherit from AIJ.
8211: Level: intermediate
8213: .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
8214: @*/
8215: PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
8216: {
8222: if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8223: if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8226: MatCheckPreallocated(P,2);
8227: if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8228: if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8230: 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);
8231: if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8232: MatCheckPreallocated(A,1);
8234: if (!A->ops->ptap) {
8235: const MatType mattype;
8236: MatGetType(A,&mattype);
8237: SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix of type <%s> does not support PtAP",mattype);
8238: }
8239: PetscLogEventBegin(MAT_PtAP,A,P,0,0);
8240: (*A->ops->ptap)(A,P,scall,fill,C);
8241: PetscLogEventEnd(MAT_PtAP,A,P,0,0);
8242: return(0);
8243: }
8247: /*@
8248: MatPtAPNumeric - Computes the matrix product C = P^T * A * P
8250: Neighbor-wise Collective on Mat
8252: Input Parameters:
8253: + A - the matrix
8254: - P - the projection matrix
8256: Output Parameters:
8257: . C - the product matrix
8259: Notes:
8260: C must have been created by calling MatPtAPSymbolic and must be destroyed by
8261: the user using MatDeatroy().
8263: This routine is currently only implemented for pairs of AIJ matrices and classes
8264: which inherit from AIJ. C will be of type MATAIJ.
8266: Level: intermediate
8268: .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
8269: @*/
8270: PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C)
8271: {
8277: if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8278: if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8281: MatCheckPreallocated(P,2);
8282: if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8283: if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8286: MatCheckPreallocated(C,3);
8287: if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8288: 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);
8289: 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);
8290: 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);
8291: 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);
8292: MatCheckPreallocated(A,1);
8294: PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
8295: (*A->ops->ptapnumeric)(A,P,C);
8296: PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
8297: return(0);
8298: }
8302: /*@
8303: MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P
8305: Neighbor-wise Collective on Mat
8307: Input Parameters:
8308: + A - the matrix
8309: - P - the projection matrix
8311: Output Parameters:
8312: . C - the (i,j) structure of the product matrix
8314: Notes:
8315: C will be created and must be destroyed by the user with MatDestroy().
8317: This routine is currently only implemented for pairs of SeqAIJ matrices and classes
8318: which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using
8319: this (i,j) structure by calling MatPtAPNumeric().
8321: Level: intermediate
8323: .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
8324: @*/
8325: PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
8326: {
8332: if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8333: if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8334: if (fill <1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8337: MatCheckPreallocated(P,2);
8338: if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8339: if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8342: 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);
8343: 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);
8344: MatCheckPreallocated(A,1);
8345: PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);
8346: (*A->ops->ptapsymbolic)(A,P,fill,C);
8347: PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);
8349: /* MatSetBlockSize(*C,A->rmap->bs); NO! this is not always true -ma */
8351: return(0);
8352: }
8356: /*@
8357: MatRARt - Creates the matrix product C = R * A * R^T
8359: Neighbor-wise Collective on Mat
8361: Input Parameters:
8362: + A - the matrix
8363: . R - the projection matrix
8364: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8365: - fill - expected fill as ratio of nnz(C)/nnz(A)
8367: Output Parameters:
8368: . C - the product matrix
8370: Notes:
8371: C will be created and must be destroyed by the user with MatDestroy().
8373: This routine is currently only implemented for pairs of AIJ matrices and classes
8374: which inherit from AIJ.
8376: Level: intermediate
8378: .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
8379: @*/
8380: PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
8381: {
8387: if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8388: if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8391: MatCheckPreallocated(R,2);
8392: if (!R->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8393: if (R->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8395: if (R->cmap->N!=A->rmap->N) SETERRQ2(((PetscObject)R)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N);
8396: if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8397: MatCheckPreallocated(A,1);
8399: if (!A->ops->rart) {
8400: const MatType mattype;
8401: MatGetType(A,&mattype);
8402: SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix of type <%s> does not support RARt",mattype);
8403: }
8404: PetscLogEventBegin(MAT_RARt,A,R,0,0);
8405: (*A->ops->rart)(A,R,scall,fill,C);
8406: PetscLogEventEnd(MAT_RARt,A,R,0,0);
8407: return(0);
8408: }
8412: /*@
8413: MatRARtNumeric - Computes the matrix product C = R * A * R^T
8415: Neighbor-wise Collective on Mat
8417: Input Parameters:
8418: + A - the matrix
8419: - R - the projection matrix
8421: Output Parameters:
8422: . C - the product matrix
8424: Notes:
8425: C must have been created by calling MatRARtSymbolic and must be destroyed by
8426: the user using MatDeatroy().
8428: This routine is currently only implemented for pairs of AIJ matrices and classes
8429: which inherit from AIJ. C will be of type MATAIJ.
8431: Level: intermediate
8433: .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
8434: @*/
8435: PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C)
8436: {
8442: if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8443: if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8446: MatCheckPreallocated(R,2);
8447: if (!R->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8448: if (R->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8451: MatCheckPreallocated(C,3);
8452: if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8453: if (R->rmap->N!=C->rmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->rmap->N,C->rmap->N);
8454: if (R->cmap->N!=A->rmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N);
8455: 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);
8456: if (R->rmap->N!=C->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->rmap->N,C->cmap->N);
8457: MatCheckPreallocated(A,1);
8459: PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);
8460: (*A->ops->rartnumeric)(A,R,C);
8461: PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);
8462: return(0);
8463: }
8467: /*@
8468: MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T
8470: Neighbor-wise Collective on Mat
8472: Input Parameters:
8473: + A - the matrix
8474: - R - the projection matrix
8476: Output Parameters:
8477: . C - the (i,j) structure of the product matrix
8479: Notes:
8480: C will be created and must be destroyed by the user with MatDestroy().
8482: This routine is currently only implemented for pairs of SeqAIJ matrices and classes
8483: which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using
8484: this (i,j) structure by calling MatRARtNumeric().
8486: Level: intermediate
8488: .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
8489: @*/
8490: PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
8491: {
8497: if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8498: if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8499: if (fill <1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8502: MatCheckPreallocated(R,2);
8503: if (!R->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8504: if (R->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8507: if (R->cmap->N!=A->rmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N);
8508: 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);
8509: MatCheckPreallocated(A,1);
8510: PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);
8511: (*A->ops->rartsymbolic)(A,R,fill,C);
8512: PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);
8514: MatSetBlockSize(*C,A->rmap->bs);
8515: return(0);
8516: }
8518: extern PetscErrorCode MatQueryOp(MPI_Comm comm, void (**function)(void), const char op[], PetscInt numArgs, ...);
8522: /*@
8523: MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
8525: Neighbor-wise Collective on Mat
8527: Input Parameters:
8528: + A - the left matrix
8529: . B - the right matrix
8530: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8531: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
8532: if the result is a dense matrix this is irrelevent
8534: Output Parameters:
8535: . C - the product matrix
8537: Notes:
8538: Unless scall is MAT_REUSE_MATRIX C will be created.
8540: MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8541:
8542: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8543: actually needed.
8545: If you have many matrices with the same non-zero structure to multiply, you
8546: should either
8547: $ 1) use MAT_REUSE_MATRIX in all calls but the first or
8548: $ 2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
8550: Level: intermediate
8552: .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(), MatMatTransposeMult(), MatPtAP()
8553: @*/
8554: PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8555: {
8557: PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8558: PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8559: PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat *)=PETSC_NULL;
8564: if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8565: if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8568: MatCheckPreallocated(B,2);
8569: if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8570: if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8572: 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);
8573: if (scall == MAT_REUSE_MATRIX){
8576: PetscLogEventBegin(MAT_MatMult,A,B,0,0);
8577: (*(*C)->ops->matmult)(A,B,scall,fill,C);
8578: PetscLogEventEnd(MAT_MatMult,A,B,0,0);
8579: }
8580: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8581: if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8582: MatCheckPreallocated(A,1);
8584: fA = A->ops->matmult;
8585: fB = B->ops->matmult;
8586: if (fB == fA) {
8587: if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
8588: mult = fB;
8589: } else {
8590: /* dispatch based on the type of A and B from their PetscObject's PetscFLists. */
8591: char multname[256];
8592: PetscStrcpy(multname,"MatMatMult_");
8593: PetscStrcat(multname,((PetscObject)A)->type_name);
8594: PetscStrcat(multname,"_");
8595: PetscStrcat(multname,((PetscObject)B)->type_name);
8596: PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
8597: PetscObjectQueryFunction((PetscObject)B,multname,(void (**)(void))&mult);
8598: if(!mult){
8599: /* dual dispatch using MatQueryOp */
8600: MatQueryOp(((PetscObject)A)->comm, (PetscVoidFunction*)(&mult), "MatMatMult",2,((PetscObject)A)->type_name,((PetscObject)B)->type_name);
8601: 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);
8602: }
8603: }
8604: PetscLogEventBegin(MAT_MatMult,A,B,0,0);
8605: (*mult)(A,B,scall,fill,C);
8606: PetscLogEventEnd(MAT_MatMult,A,B,0,0);
8607: return(0);
8608: }
8612: /*@
8613: MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
8614: of the matrix-matrix product C=A*B. Call this routine before calling MatMatMultNumeric().
8616: Neighbor-wise Collective on Mat
8618: Input Parameters:
8619: + A - the left matrix
8620: . B - the right matrix
8621: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
8622: if C is a dense matrix this is irrelevent
8623:
8624: Output Parameters:
8625: . C - the product matrix
8627: Notes:
8628: Unless scall is MAT_REUSE_MATRIX C will be created.
8630: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8631: actually needed.
8633: This routine is currently implemented for
8634: - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
8635: - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8636: - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
8638: Level: intermediate
8640: Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
8641: We should incorporate them into PETSc.
8643: .seealso: MatMatMult(), MatMatMultNumeric()
8644: @*/
8645: PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
8646: {
8648: PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat *);
8649: PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat *);
8650: PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat *)=PETSC_NULL;
8655: if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8656: if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8660: MatCheckPreallocated(B,2);
8661: if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8662: if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8665: 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);
8666: if (fill == PETSC_DEFAULT) fill = 2.0;
8667: if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8668: MatCheckPreallocated(A,1);
8669:
8670: Asymbolic = A->ops->matmultsymbolic;
8671: Bsymbolic = B->ops->matmultsymbolic;
8672: if (Asymbolic == Bsymbolic){
8673: if (!Bsymbolic) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
8674: symbolic = Bsymbolic;
8675: } else { /* dispatch based on the type of A and B */
8676: char symbolicname[256];
8677: PetscStrcpy(symbolicname,"MatMatMultSymbolic_");
8678: PetscStrcat(symbolicname,((PetscObject)A)->type_name);
8679: PetscStrcat(symbolicname,"_");
8680: PetscStrcat(symbolicname,((PetscObject)B)->type_name);
8681: PetscStrcat(symbolicname,"_C");
8682: PetscObjectQueryFunction((PetscObject)B,symbolicname,(void (**)(void))&symbolic);
8683: 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);
8684: }
8685: PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);
8686: (*symbolic)(A,B,fill,C);
8687: PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);
8688: return(0);
8689: }
8693: /*@
8694: MatMatMultNumeric - Performs the numeric matrix-matrix product.
8695: Call this routine after first calling MatMatMultSymbolic().
8697: Neighbor-wise Collective on Mat
8699: Input Parameters:
8700: + A - the left matrix
8701: - B - the right matrix
8703: Output Parameters:
8704: . C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
8706: Notes:
8707: C must have been created with MatMatMultSymbolic().
8709: This routine is currently implemented for
8710: - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
8711: - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8712: - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
8714: Level: intermediate
8716: .seealso: MatMatMult(), MatMatMultSymbolic()
8717: @*/
8718: PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C)
8719: {
8721: PetscErrorCode (*Anumeric)(Mat,Mat,Mat);
8722: PetscErrorCode (*Bnumeric)(Mat,Mat,Mat);
8723: PetscErrorCode (*numeric)(Mat,Mat,Mat)=PETSC_NULL;
8728: if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8729: if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8733: MatCheckPreallocated(B,2);
8734: if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8735: if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8739: MatCheckPreallocated(C,3);
8740: if (!C->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8741: if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8743: 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);
8744: 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);
8745: 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);
8746: MatCheckPreallocated(A,1);
8748: Anumeric = A->ops->matmultnumeric;
8749: Bnumeric = B->ops->matmultnumeric;
8750: if (Anumeric == Bnumeric){
8751: if (!Bnumeric) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMultNumeric not supported for B of type %s",((PetscObject)B)->type_name);
8752: numeric = Bnumeric;
8753: } else {
8754: char numericname[256];
8755: PetscStrcpy(numericname,"MatMatMultNumeric_");
8756: PetscStrcat(numericname,((PetscObject)A)->type_name);
8757: PetscStrcat(numericname,"_");
8758: PetscStrcat(numericname,((PetscObject)B)->type_name);
8759: PetscStrcat(numericname,"_C");
8760: PetscObjectQueryFunction((PetscObject)B,numericname,(void (**)(void))&numeric);
8761: if (!numeric)
8762: 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);
8763: }
8764: PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);
8765: (*numeric)(A,B,C);
8766: PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);
8767: return(0);
8768: }
8772: /*@
8773: MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.
8775: Neighbor-wise Collective on Mat
8777: Input Parameters:
8778: + A - the left matrix
8779: . B - the right matrix
8780: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8781: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
8783: Output Parameters:
8784: . C - the product matrix
8786: Notes:
8787: C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
8789: MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8791: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8792: actually needed.
8794: This routine is currently only implemented for pairs of SeqAIJ matrices. C will be of type MATSEQAIJ.
8796: Level: intermediate
8798: .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
8799: @*/
8800: PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8801: {
8803: PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8804: PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8809: if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8810: if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8813: MatCheckPreallocated(B,2);
8814: if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8815: if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8817: if (B->cmap->N!=A->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, AN %D != BN %D",A->cmap->N,B->cmap->N);
8818: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8819: if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8820: MatCheckPreallocated(A,1);
8822: fA = A->ops->mattransposemult;
8823: if (!fA) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
8824: fB = B->ops->mattransposemult;
8825: if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
8826: if (fB!=fA) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_INCOMP,"MatMatTransposeMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
8828: if (scall == MAT_INITIAL_MATRIX){
8829: PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);
8830: (*A->ops->mattransposemultsymbolic)(A,B,fill,C);
8831: PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);
8832: }
8833: PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);
8834: (*A->ops->mattransposemultnumeric)(A,B,*C);
8835: PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);
8836: return(0);
8837: }
8841: /*@
8842: MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.
8844: Neighbor-wise Collective on Mat
8846: Input Parameters:
8847: + A - the left matrix
8848: . B - the right matrix
8849: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8850: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
8852: Output Parameters:
8853: . C - the product matrix
8855: Notes:
8856: C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
8858: MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8860: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8861: actually needed.
8863: This routine is currently only implemented for pairs of SeqAIJ matrices and pairs of SeqDense matrices and classes
8864: which inherit from SeqAIJ. C will be of type MATSEQAIJ.
8866: Level: intermediate
8868: .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
8869: @*/
8870: PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8871: {
8873: PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8874: PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8875: PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*);
8880: if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8881: if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8884: MatCheckPreallocated(B,2);
8885: if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8886: if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8888: 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);
8889: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8890: if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8891: MatCheckPreallocated(A,1);
8893: fA = A->ops->transposematmult;
8894: if (!fA) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
8895: fB = B->ops->transposematmult;
8896: if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatTransposeMatMult not supported for B of type %s",((PetscObject)B)->type_name);
8897: if (fB==fA) {
8898: transposematmult = fA;
8899: }
8900: else {
8901: /* dual dispatch using MatQueryOp */
8902: MatQueryOp(((PetscObject)A)->comm, (PetscVoidFunction*)(&transposematmult), "MatTansposeMatMult",2,((PetscObject)A)->type_name,((PetscObject)B)->type_name);
8903: if(!transposematmult)
8904: SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_INCOMP,"MatTransposeMatMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
8905: }
8906: PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);
8907: (*transposematmult)(A,B,scall,fill,C);
8908: PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);
8909: return(0);
8910: }
8914: /*@C
8915: MatGetRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
8917: Collective on Mat
8919: Input Parameters:
8920: + mat - the matrix
8921: . nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
8922: . subcomm - MPI communicator split from the communicator where mat resides in
8923: . mlocal_red - number of local rows of the redundant matrix
8924: - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8926: Output Parameter:
8927: . matredundant - redundant matrix
8929: Notes:
8930: MAT_REUSE_MATRIX can only be used when the nonzero structure of the
8931: original matrix has not changed from that last call to MatGetRedundantMatrix().
8933: This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
8934: calling it.
8936: Only MPIAIJ matrix is supported.
8937:
8938: Level: advanced
8940: Concepts: subcommunicator
8941: Concepts: duplicate matrix
8943: .seealso: MatDestroy()
8944: @*/
8945: PetscErrorCode MatGetRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,PetscInt mlocal_red,MatReuse reuse,Mat *matredundant)
8946: {
8951: if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
8954: }
8955: if (!mat->ops->getredundantmatrix) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8956: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8957: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8958: MatCheckPreallocated(mat,1);
8960: PetscLogEventBegin(MAT_GetRedundantMatrix,mat,0,0,0);
8961: (*mat->ops->getredundantmatrix)(mat,nsubcomm,subcomm,mlocal_red,reuse,matredundant);
8962: PetscLogEventEnd(MAT_GetRedundantMatrix,mat,0,0,0);
8963: return(0);
8964: }
8968: /*@C
8969: MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
8970: a given 'mat' object. Each submatrix can span multiple procs.
8972: Collective on Mat
8974: Input Parameters:
8975: + mat - the matrix
8976: . subcomm - the subcommunicator obtained by com_split(comm)
8977: - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8979: Output Parameter:
8980: . subMat - 'parallel submatrices each spans a given subcomm
8982: Notes:
8983: The submatrix partition across processors is dicated by 'subComm' a
8984: communicator obtained by com_split(comm). The comm_split
8985: is not restriced to be grouped with consequitive original ranks.
8987: Due the comm_split() usage, the parallel layout of the submatrices
8988: map directly to the layout of the original matrix [wrt the local
8989: row,col partitioning]. So the original 'DiagonalMat' naturally maps
8990: into the 'DiagonalMat' of the subMat, hence it is used directly from
8991: the subMat. However the offDiagMat looses some columns - and this is
8992: reconstructed with MatSetValues()
8994: Level: advanced
8996: Concepts: subcommunicator
8997: Concepts: submatrices
8999: .seealso: MatGetSubMatrices()
9000: @*/
9001: PetscErrorCode MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat* subMat)
9002: {
9004: PetscMPIInt commsize,subCommSize;
9007: MPI_Comm_size(((PetscObject)mat)->comm,&commsize);
9008: MPI_Comm_size(subComm,&subCommSize);
9009: if (subCommSize > commsize) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
9010:
9011: PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);
9012: (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);
9013: PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);
9014: return(0);
9015: }
9019: /*@
9020: MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
9022: Not Collective
9024: Input Arguments:
9025: mat - matrix to extract local submatrix from
9026: isrow - local row indices for submatrix
9027: iscol - local column indices for submatrix
9029: Output Arguments:
9030: submat - the submatrix
9032: Level: intermediate
9034: Notes:
9035: The submat should be returned with MatRestoreLocalSubMatrix().
9037: Depending on the format of mat, the returned submat may not implement MatMult(). Its communicator may be
9038: the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
9040: The submat always implements MatSetValuesLocal(). If isrow and iscol have the same block size, then
9041: MatSetValuesBlockedLocal() will also be implemented.
9043: .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef()
9044: @*/
9045: PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9046: {
9056: if (mat->ops->getlocalsubmatrix) {
9057: (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);
9058: } else {
9059: MatCreateLocalRef(mat,isrow,iscol,submat);
9060: }
9061: return(0);
9062: }
9066: /*@
9067: MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
9069: Not Collective
9071: Input Arguments:
9072: mat - matrix to extract local submatrix from
9073: isrow - local row indices for submatrix
9074: iscol - local column indices for submatrix
9075: submat - the submatrix
9077: Level: intermediate
9079: .seealso: MatGetLocalSubMatrix()
9080: @*/
9081: PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9082: {
9093: if (mat->ops->restorelocalsubmatrix) {
9094: (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);
9095: } else {
9096: MatDestroy(submat);
9097: }
9098: *submat = PETSC_NULL;
9099: return(0);
9100: }
9102: /* --------------------------------------------------------*/
9105: /*@
9106: MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no entry in the matrix
9108: Collective on Mat
9110: Input Parameter:
9111: . mat - the matrix
9113: Output Parameter:
9114: . is - if any rows have zero diagonals this contains the list of them
9116: Level: developer
9118: Concepts: matrix-vector product
9120: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
9121: @*/
9122: PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is)
9123: {
9129: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9130: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9132: if (!mat->ops->findzerodiagonals) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"This matrix type does not have a find zero diagonals defined");
9133: (*mat->ops->findzerodiagonals)(mat,is);
9134: return(0);
9135: }
9139: /*@C
9140: MatInvertBlockDiagonal - Inverts the block diagonal entries.
9142: Collective on Mat
9144: Input Parameters:
9145: . mat - the matrix
9147: Output Parameters:
9148: . values - the block inverses in column major order (FORTRAN-like)
9150: Note:
9151: This routine is not available from Fortran.
9153: Level: advanced
9154: @*/
9155: PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
9156: {
9161: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9162: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9163: if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
9164: (*mat->ops->invertblockdiagonal)(mat,values);
9165: return(0);
9166: }
9170: /*@C
9171: MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
9172: via MatTransposeColoringCreate().
9174: Collective on MatTransposeColoring
9176: Input Parameter:
9177: . c - coloring context
9179: Level: intermediate
9181: .seealso: MatTransposeColoringCreate()
9182: @*/
9183: PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c)
9184: {
9185: PetscErrorCode ierr;
9186: MatTransposeColoring matcolor=*c;
9189: if (!matcolor) return(0);
9190: if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; return(0);}
9192: PetscFree(matcolor->ncolumns);
9193: PetscFree(matcolor->nrows);
9194: PetscFree(matcolor->colorforrow);
9195: PetscFree2(matcolor->rows,matcolor->columnsforspidx);
9196: PetscFree(matcolor->colorforcol);
9197: PetscFree(matcolor->columns);
9198: PetscHeaderDestroy(c);
9199: return(0);
9200: }
9204: /*@C
9205: MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
9206: a MatTransposeColoring context has been created, computes a dense B^T by Apply
9207: MatTransposeColoring to sparse B.
9209: Collective on MatTransposeColoring
9211: Input Parameters:
9212: + B - sparse matrix B
9213: . Btdense - symbolic dense matrix B^T
9214: - coloring - coloring context created with MatTransposeColoringCreate()
9216: Output Parameter:
9217: . Btdense - dense matrix B^T
9219: Options Database Keys:
9220: + -mat_transpose_coloring_view - Activates basic viewing or coloring
9221: . -mat_transpose_coloring_view_draw - Activates drawing of coloring
9222: - -mat_transpose_coloring_view_info - Activates viewing of coloring info
9224: Level: intermediate
9226: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy()
9228: .keywords: coloring
9229: @*/
9230: PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
9231: {
9238:
9239: if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
9240: (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);
9241: return(0);
9242: }
9246: /*@C
9247: MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
9248: a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
9249: in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
9250: Csp from Cden.
9252: Collective on MatTransposeColoring
9254: Input Parameters:
9255: + coloring - coloring context created with MatTransposeColoringCreate()
9256: - Cden - matrix product of a sparse matrix and a dense matrix Btdense
9258: Output Parameter:
9259: . Csp - sparse matrix
9261: Options Database Keys:
9262: + -mat_multtranspose_coloring_view - Activates basic viewing or coloring
9263: . -mat_multtranspose_coloring_view_draw - Activates drawing of coloring
9264: - -mat_multtranspose_coloring_view_info - Activates viewing of coloring info
9266: Level: intermediate
9268: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()
9270: .keywords: coloring
9271: @*/
9272: PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
9273: {
9280:
9281: if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
9282: (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);
9283: return(0);
9284: }
9288: /*@C
9289: MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.
9291: Collective on Mat
9293: Input Parameters:
9294: + mat - the matrix product C
9295: - iscoloring - the coloring of the matrix; usually obtained with MatGetColoring() or DMCreateColoring()
9297: Output Parameter:
9298: . color - the new coloring context
9299:
9300: Level: intermediate
9302: .seealso: MatTransposeColoringDestroy(), MatTransposeColoringSetFromOptions(), MatTransColoringApplySpToDen(),
9303: MatTransColoringApplyDen()ToSp, MatTransposeColoringView(),
9304: @*/
9305: PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
9306: {
9307: MatTransposeColoring c;
9308: MPI_Comm comm;
9309: PetscErrorCode ierr;
9312: PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);
9313: PetscObjectGetComm((PetscObject)mat,&comm);
9314: PetscHeaderCreate(c,_p_MatTransposeColoring,int,MAT_TRANSPOSECOLORING_CLASSID,0,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,0);
9316: c->ctype = iscoloring->ctype;
9317: if (mat->ops->transposecoloringcreate) {
9318: (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);
9319: } else SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Code not yet written for this matrix type");
9321: *color = c;
9322: PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);
9323: return(0);
9324: }