Actual source code: matrix.c
petsc-3.3-p7 2013-05-11
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: /*@
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: {
376: #ifdef PETSC_USE_COMPLEX
381: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
382: if (!mat->ops->conjugate) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Not provided for this matrix format, send email to petsc-maint@mcs.anl.gov");
383: (*mat->ops->conjugate)(mat);
384: #if defined(PETSC_HAVE_CUSP)
385: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
386: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
387: }
388: #endif
389: return(0);
390: #else
391: return 0;
392: #endif
393: }
397: /*@C
398: MatRestoreRow - Frees any temporary space allocated by MatGetRow().
400: Not Collective
402: Input Parameters:
403: + mat - the matrix
404: . row - the row to get
405: . ncols, cols - the number of nonzeros and their columns
406: - vals - if nonzero the column values
408: Notes:
409: This routine should be called after you have finished examining the entries.
411: Fortran Notes:
412: The calling sequence from Fortran is
413: .vb
414: MatRestoreRow(matrix,row,ncols,cols,values,ierr)
415: Mat matrix (input)
416: integer row (input)
417: integer ncols (output)
418: integer cols(maxcols) (output)
419: double precision (or double complex) values(maxcols) output
420: .ve
421: Where maxcols >= maximum nonzeros in any row of the matrix.
423: In Fortran MatRestoreRow() MUST be called after MatGetRow()
424: before another call to MatGetRow() can be made.
426: Level: advanced
428: .seealso: MatGetRow()
429: @*/
430: PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
431: {
437: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
438: if (!mat->ops->restorerow) return(0);
439: (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);
440: return(0);
441: }
445: /*@
446: MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format.
447: You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag.
449: Not Collective
451: Input Parameters:
452: + mat - the matrix
454: Notes:
455: 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.
457: Level: advanced
459: Concepts: matrices^row access
461: .seealso: MatRestoreRowRowUpperTriangular()
462: @*/
463: PetscErrorCode MatGetRowUpperTriangular(Mat mat)
464: {
470: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
471: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
472: if (!mat->ops->getrowuppertriangular) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
473: MatCheckPreallocated(mat,1);
474: (*mat->ops->getrowuppertriangular)(mat);
475: return(0);
476: }
480: /*@
481: MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format.
483: Not Collective
485: Input Parameters:
486: + mat - the matrix
488: Notes:
489: This routine should be called after you have finished MatGetRow/MatRestoreRow().
492: Level: advanced
494: .seealso: MatGetRowUpperTriangular()
495: @*/
496: PetscErrorCode MatRestoreRowUpperTriangular(Mat mat)
497: {
502: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
503: if (!mat->ops->restorerowuppertriangular) return(0);
504: (*mat->ops->restorerowuppertriangular)(mat);
505: return(0);
506: }
510: /*@C
511: MatSetOptionsPrefix - Sets the prefix used for searching for all
512: Mat options in the database.
514: Logically Collective on Mat
516: Input Parameter:
517: + A - the Mat context
518: - prefix - the prefix to prepend to all option names
520: Notes:
521: A hyphen (-) must NOT be given at the beginning of the prefix name.
522: The first character of all runtime options is AUTOMATICALLY the hyphen.
524: Level: advanced
526: .keywords: Mat, set, options, prefix, database
528: .seealso: MatSetFromOptions()
529: @*/
530: PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[])
531: {
536: PetscObjectSetOptionsPrefix((PetscObject)A,prefix);
537: return(0);
538: }
542: /*@C
543: MatAppendOptionsPrefix - Appends to the prefix used for searching for all
544: Mat options in the database.
546: Logically Collective on Mat
548: Input Parameters:
549: + A - the Mat context
550: - prefix - the prefix to prepend to all option names
552: Notes:
553: A hyphen (-) must NOT be given at the beginning of the prefix name.
554: The first character of all runtime options is AUTOMATICALLY the hyphen.
556: Level: advanced
558: .keywords: Mat, append, options, prefix, database
560: .seealso: MatGetOptionsPrefix()
561: @*/
562: PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[])
563: {
565:
568: PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);
569: return(0);
570: }
574: /*@C
575: MatGetOptionsPrefix - Sets the prefix used for searching for all
576: Mat options in the database.
578: Not Collective
580: Input Parameter:
581: . A - the Mat context
583: Output Parameter:
584: . prefix - pointer to the prefix string used
586: Notes: On the fortran side, the user should pass in a string 'prefix' of
587: sufficient length to hold the prefix.
589: Level: advanced
591: .keywords: Mat, get, options, prefix, database
593: .seealso: MatAppendOptionsPrefix()
594: @*/
595: PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[])
596: {
601: PetscObjectGetOptionsPrefix((PetscObject)A,prefix);
602: return(0);
603: }
607: /*@
608: MatSetUp - Sets up the internal matrix data structures for the later use.
610: Collective on Mat
612: Input Parameters:
613: . A - the Mat context
615: Notes:
616: If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used.
618: If a suitable preallocation routine is used, this function does not need to be called.
620: See the Performance chapter of the PETSc users manual for how to preallocate matrices
622: Level: beginner
624: .keywords: Mat, setup
626: .seealso: MatCreate(), MatDestroy()
627: @*/
628: PetscErrorCode MatSetUp(Mat A)
629: {
630: PetscMPIInt size;
635: if (!((PetscObject)A)->type_name) {
636: MPI_Comm_size(((PetscObject)A)->comm, &size);
637: if (size == 1) {
638: MatSetType(A, MATSEQAIJ);
639: } else {
640: MatSetType(A, MATMPIAIJ);
641: }
642: }
643: if (!A->preallocated && A->ops->setup) {
644: PetscInfo(A,"Warning not preallocating matrix storage\n");
645: (*A->ops->setup)(A);
646: }
647: A->preallocated = PETSC_TRUE;
648: return(0);
649: }
654: /*@C
655: MatView - Visualizes a matrix object.
657: Collective on Mat
659: Input Parameters:
660: + mat - the matrix
661: - viewer - visualization context
663: Notes:
664: The available visualization contexts include
665: + PETSC_VIEWER_STDOUT_SELF - standard output (default)
666: . PETSC_VIEWER_STDOUT_WORLD - synchronized standard
667: output where only the first processor opens
668: the file. All other processors send their
669: data to the first processor to print.
670: - PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure
672: The user can open alternative visualization contexts with
673: + PetscViewerASCIIOpen() - Outputs matrix to a specified file
674: . PetscViewerBinaryOpen() - Outputs matrix in binary to a
675: specified file; corresponding input uses MatLoad()
676: . PetscViewerDrawOpen() - Outputs nonzero matrix structure to
677: an X window display
678: - PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
679: Currently only the sequential dense and AIJ
680: matrix types support the Socket viewer.
682: The user can call PetscViewerSetFormat() to specify the output
683: format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
684: PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen). Available formats include
685: + PETSC_VIEWER_DEFAULT - default, prints matrix contents
686: . PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
687: . PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
688: . PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse
689: format common among all matrix types
690: . PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific
691: format (which is in many cases the same as the default)
692: . PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
693: size and structure (not the matrix entries)
694: . PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about
695: the matrix structure
697: Options Database Keys:
698: + -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly()
699: . -mat_view_info_detailed - Prints more detailed info
700: . -mat_view - Prints matrix in ASCII format
701: . -mat_view_matlab - Prints matrix in Matlab format
702: . -mat_view_draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
703: . -display <name> - Sets display name (default is host)
704: . -draw_pause <sec> - Sets number of seconds to pause after display
705: . -mat_view_socket - Sends matrix to socket, can be accessed from Matlab (see the <a href="../../docs/manual.pdf">users manual</a> for details).
706: . -viewer_socket_machine <machine>
707: . -viewer_socket_port <port>
708: . -mat_view_binary - save matrix to file in binary format
709: - -viewer_binary_filename <name>
710: Level: beginner
712: Notes: see the manual page for MatLoad() for the exact format of the binary file when the binary
713: viewer is used.
715: See bin/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary
716: viewer is used.
718: Concepts: matrices^viewing
719: Concepts: matrices^plotting
720: Concepts: matrices^printing
722: .seealso: PetscViewerSetFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(),
723: PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
724: @*/
725: PetscErrorCode MatView(Mat mat,PetscViewer viewer)
726: {
727: PetscErrorCode ierr;
728: PetscInt rows,cols,bs;
729: PetscBool iascii;
730: PetscViewerFormat format;
735: if (!viewer) {
736: PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
737: }
740: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
741: MatCheckPreallocated(mat,1);
743: PetscLogEventBegin(MAT_View,mat,viewer,0,0);
744: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
745: if (iascii) {
746: PetscViewerGetFormat(viewer,&format);
747: if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
748: PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer,"Matrix Object");
749: PetscViewerASCIIPushTab(viewer);
750: MatGetSize(mat,&rows,&cols);
751: MatGetBlockSize(mat,&bs);
752: if (bs != 1) {
753: PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,bs);
754: } else {
755: PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);
756: }
757: if (mat->factortype) {
758: const MatSolverPackage solver;
759: MatFactorGetSolverPackage(mat,&solver);
760: PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);
761: }
762: if (mat->ops->getinfo) {
763: MatInfo info;
764: MatGetInfo(mat,MAT_GLOBAL_SUM,&info);
765: PetscViewerASCIIPrintf(viewer,"total: nonzeros=%lld, allocated nonzeros=%lld\n",(Petsc64bitInt)info.nz_used,(Petsc64bitInt)info.nz_allocated);
766: PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls =%D\n",(PetscInt)info.mallocs);
767: }
768: }
769: }
770: if (mat->ops->view) {
771: PetscViewerASCIIPushTab(viewer);
772: (*mat->ops->view)(mat,viewer);
773: PetscViewerASCIIPopTab(viewer);
774: } else if (!iascii) {
775: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Viewer type %s not supported",((PetscObject)viewer)->type_name);
776: }
777: if (iascii) {
778: PetscViewerGetFormat(viewer,&format);
779: if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
780: PetscViewerASCIIPopTab(viewer);
781: }
782: }
783: PetscLogEventEnd(MAT_View,mat,viewer,0,0);
784: return(0);
785: }
787: #if defined(PETSC_USE_DEBUG)
788: #include <../src/sys/totalview/tv_data_display.h>
789: PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat)
790: {
791: TV_add_row("Local rows", "int", &mat->rmap->n);
792: TV_add_row("Local columns", "int", &mat->cmap->n);
793: TV_add_row("Global rows", "int", &mat->rmap->N);
794: TV_add_row("Global columns", "int", &mat->cmap->N);
795: TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name);
796: return TV_format_OK;
797: }
798: #endif
802: /*@C
803: MatLoad - Loads a matrix that has been stored in binary format
804: with MatView(). The matrix format is determined from the options database.
805: Generates a parallel MPI matrix if the communicator has more than one
806: processor. The default matrix type is AIJ.
808: Collective on PetscViewer
810: Input Parameters:
811: + newmat - the newly loaded matrix, this needs to have been created with MatCreate()
812: or some related function before a call to MatLoad()
813: - viewer - binary file viewer, created with PetscViewerBinaryOpen()
815: Options Database Keys:
816: Used with block matrix formats (MATSEQBAIJ, ...) to specify
817: block size
818: . -matload_block_size <bs>
820: Level: beginner
822: Notes:
823: If the Mat type has not yet been given then MATAIJ is used, call MatSetFromOptions() on the
824: Mat before calling this routine if you wish to set it from the options database.
826: MatLoad() automatically loads into the options database any options
827: given in the file filename.info where filename is the name of the file
828: that was passed to the PetscViewerBinaryOpen(). The options in the info
829: file will be ignored if you use the -viewer_binary_skip_info option.
831: If the type or size of newmat is not set before a call to MatLoad, PETSc
832: sets the default matrix type AIJ and sets the local and global sizes.
833: If type and/or size is already set, then the same are used.
835: In parallel, each processor can load a subset of rows (or the
836: entire matrix). This routine is especially useful when a large
837: matrix is stored on disk and only part of it is desired on each
838: processor. For example, a parallel solver may access only some of
839: the rows from each processor. The algorithm used here reads
840: relatively small blocks of data rather than reading the entire
841: matrix and then subsetting it.
843: Notes for advanced users:
844: Most users should not need to know the details of the binary storage
845: format, since MatLoad() and MatView() completely hide these details.
846: But for anyone who's interested, the standard binary matrix storage
847: format is
849: $ int MAT_FILE_CLASSID
850: $ int number of rows
851: $ int number of columns
852: $ int total number of nonzeros
853: $ int *number nonzeros in each row
854: $ int *column indices of all nonzeros (starting index is zero)
855: $ PetscScalar *values of all nonzeros
857: PETSc automatically does the byte swapping for
858: machines that store the bytes reversed, e.g. DEC alpha, freebsd,
859: linux, Windows and the paragon; thus if you write your own binary
860: read/write routines you have to swap the bytes; see PetscBinaryRead()
861: and PetscBinaryWrite() to see how this may be done.
863: .keywords: matrix, load, binary, input
865: .seealso: PetscViewerBinaryOpen(), MatView(), VecLoad()
867: @*/
868: PetscErrorCode MatLoad(Mat newmat,PetscViewer viewer)
869: {
871: PetscBool isbinary,flg;
876: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);
877: if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()");
879: if (!((PetscObject)newmat)->type_name) {
880: MatSetType(newmat,MATAIJ);
881: }
883: if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type");
884: PetscLogEventBegin(MAT_Load,viewer,0,0,0);
885: (*newmat->ops->load)(newmat,viewer);
886: PetscLogEventEnd(MAT_Load,viewer,0,0,0);
888: flg = PETSC_FALSE;
889: PetscOptionsGetBool(((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,PETSC_NULL);
890: if (flg) {
891: MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);
892: MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);
893: }
894: flg = PETSC_FALSE;
895: PetscOptionsGetBool(((PetscObject)newmat)->prefix,"-matload_spd",&flg,PETSC_NULL);
896: if (flg) {
897: MatSetOption(newmat,MAT_SPD,PETSC_TRUE);
898: }
899: return(0);
900: }
904: /*@
905: MatDestroy - Frees space taken by a matrix.
907: Collective on Mat
909: Input Parameter:
910: . A - the matrix
912: Level: beginner
914: @*/
915: PetscErrorCode MatDestroy(Mat *A)
916: {
920: if (!*A) return(0);
922: if (--((PetscObject)(*A))->refct > 0) {*A = PETSC_NULL; return(0);}
923: /* if memory was published with AMS then destroy it */
924: PetscObjectDepublish(*A);
925: if ((*A)->ops->destroy) {
926: (*(*A)->ops->destroy)(*A);
927: }
928: MatNullSpaceDestroy(&(*A)->nullsp);
929: MatNullSpaceDestroy(&(*A)->nearnullsp);
930: PetscLayoutDestroy(&(*A)->rmap);
931: PetscLayoutDestroy(&(*A)->cmap);
932: PetscHeaderDestroy(A);
933: return(0);
934: }
938: /*@
939: MatSetValues - Inserts or adds a block of values into a matrix.
940: These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
941: MUST be called after all calls to MatSetValues() have been completed.
943: Not Collective
945: Input Parameters:
946: + mat - the matrix
947: . v - a logically two-dimensional array of values
948: . m, idxm - the number of rows and their global indices
949: . n, idxn - the number of columns and their global indices
950: - addv - either ADD_VALUES or INSERT_VALUES, where
951: ADD_VALUES adds values to any existing entries, and
952: INSERT_VALUES replaces existing entries with new values
954: Notes:
955: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
956: MatSetUp() before using this routine
958: By default the values, v, are row-oriented. See MatSetOption() for other options.
960: Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
961: options cannot be mixed without intervening calls to the assembly
962: routines.
964: MatSetValues() uses 0-based row and column numbers in Fortran
965: as well as in C.
967: Negative indices may be passed in idxm and idxn, these rows and columns are
968: simply ignored. This allows easily inserting element stiffness matrices
969: with homogeneous Dirchlet boundary conditions that you don't want represented
970: in the matrix.
972: Efficiency Alert:
973: The routine MatSetValuesBlocked() may offer much better efficiency
974: for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
976: Level: beginner
978: Concepts: matrices^putting entries in
980: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
981: InsertMode, INSERT_VALUES, ADD_VALUES
982: @*/
983: PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
984: {
986: #if defined(PETSC_USE_DEBUG)
987: PetscInt i,j;
988: #endif
993: if (!m || !n) return(0); /* no values to insert */
997: MatCheckPreallocated(mat,1);
998: if (mat->insertmode == NOT_SET_VALUES) {
999: mat->insertmode = addv;
1000: }
1001: #if defined(PETSC_USE_DEBUG)
1002: else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1003: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1004: if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1006: if (v) {
1007: for (i=0; i<m; i++) {
1008: for (j=0; j<n; j++) {
1009: if (PetscIsInfOrNanScalar(v[i*n+j]))
1010: #if defined(PETSC_USE_COMPLEX)
1011: 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]);
1012: #else
1013: SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %G at matrix entry (%D,%D)",(PetscReal)v[i*n+j],idxm[i],idxn[j]);
1014: #endif
1015: }
1016: }
1017: }
1018: #endif
1020: if (mat->assembled) {
1021: mat->was_assembled = PETSC_TRUE;
1022: mat->assembled = PETSC_FALSE;
1023: }
1024: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1025: (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);
1026: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1027: #if defined(PETSC_HAVE_CUSP)
1028: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1029: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1030: }
1031: #endif
1032: return(0);
1033: }
1038: /*@
1039: MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
1040: values into a matrix
1042: Not Collective
1044: Input Parameters:
1045: + mat - the matrix
1046: . row - the (block) row to set
1047: - v - a logically two-dimensional array of values
1049: Notes:
1050: By the values, v, are column-oriented (for the block version) and sorted
1052: All the nonzeros in the row must be provided
1054: The matrix must have previously had its column indices set
1056: The row must belong to this process
1058: Level: intermediate
1060: Concepts: matrices^putting entries in
1062: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1063: InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping()
1064: @*/
1065: PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
1066: {
1073: MatSetValuesRow(mat, mat->rmap->mapping->indices[row],v);
1074: #if defined(PETSC_HAVE_CUSP)
1075: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1076: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1077: }
1078: #endif
1079: return(0);
1080: }
1084: /*@
1085: MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
1086: values into a matrix
1088: Not Collective
1090: Input Parameters:
1091: + mat - the matrix
1092: . row - the (block) row to set
1093: - v - a logically two-dimensional array of values
1095: Notes:
1096: The values, v, are column-oriented for the block version.
1098: All the nonzeros in the row must be provided
1100: THE MATRIX MUSAT HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually MatSetValues() is used.
1102: The row must belong to this process
1104: Level: advanced
1106: Concepts: matrices^putting entries in
1108: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1109: InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1110: @*/
1111: PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
1112: {
1118: MatCheckPreallocated(mat,1);
1120: #if defined(PETSC_USE_DEBUG)
1121: if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
1122: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1123: #endif
1124: mat->insertmode = INSERT_VALUES;
1126: if (mat->assembled) {
1127: mat->was_assembled = PETSC_TRUE;
1128: mat->assembled = PETSC_FALSE;
1129: }
1130: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1131: if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1132: (*mat->ops->setvaluesrow)(mat,row,v);
1133: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1134: #if defined(PETSC_HAVE_CUSP)
1135: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1136: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1137: }
1138: #endif
1139: return(0);
1140: }
1144: /*@
1145: MatSetValuesStencil - Inserts or adds a block of values into a matrix.
1146: Using structured grid indexing
1148: Not Collective
1150: Input Parameters:
1151: + mat - the matrix
1152: . m - number of rows being entered
1153: . idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
1154: . n - number of columns being entered
1155: . idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered
1156: . v - a logically two-dimensional array of values
1157: - addv - either ADD_VALUES or INSERT_VALUES, where
1158: ADD_VALUES adds values to any existing entries, and
1159: INSERT_VALUES replaces existing entries with new values
1161: Notes:
1162: By default the values, v, are row-oriented. See MatSetOption() for other options.
1164: Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
1165: options cannot be mixed without intervening calls to the assembly
1166: routines.
1168: The grid coordinates are across the entire grid, not just the local portion
1170: MatSetValuesStencil() uses 0-based row and column numbers in Fortran
1171: as well as in C.
1173: For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1175: In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1176: or call MatSetLocalToGlobalMapping() and MatSetStencil() first.
1178: The columns and rows in the stencil passed in MUST be contained within the
1179: ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1180: if you create a DMDA with an overlap of one grid level and on a particular process its first
1181: local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1182: first i index you can use in your column and row indices in MatSetStencil() is 5.
1184: In Fortran idxm and idxn should be declared as
1185: $ MatStencil idxm(4,m),idxn(4,n)
1186: and the values inserted using
1187: $ idxm(MatStencil_i,1) = i
1188: $ idxm(MatStencil_j,1) = j
1189: $ idxm(MatStencil_k,1) = k
1190: $ idxm(MatStencil_c,1) = c
1191: etc
1192:
1193: For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
1194: obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
1195: etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
1196: DMDA_BOUNDARY_PERIODIC boundary type.
1198: 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
1199: a single value per point) you can skip filling those indices.
1201: Inspired by the structured grid interface to the HYPRE package
1202: (http://www.llnl.gov/CASC/hypre)
1204: Efficiency Alert:
1205: The routine MatSetValuesBlockedStencil() may offer much better efficiency
1206: for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1208: Level: beginner
1210: Concepts: matrices^putting entries in
1212: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1213: MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil
1214: @*/
1215: PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1216: {
1218: PetscInt buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1219: PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1220: PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1223: if (!m || !n) return(0); /* no values to insert */
1230: if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1231: jdxm = buf; jdxn = buf+m;
1232: } else {
1233: PetscMalloc2(m,PetscInt,&bufm,n,PetscInt,&bufn);
1234: jdxm = bufm; jdxn = bufn;
1235: }
1236: for (i=0; i<m; i++) {
1237: for (j=0; j<3-sdim; j++) dxm++;
1238: tmp = *dxm++ - starts[0];
1239: for (j=0; j<dim-1; j++) {
1240: if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1241: else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1242: }
1243: if (mat->stencil.noc) dxm++;
1244: jdxm[i] = tmp;
1245: }
1246: for (i=0; i<n; i++) {
1247: for (j=0; j<3-sdim; j++) dxn++;
1248: tmp = *dxn++ - starts[0];
1249: for (j=0; j<dim-1; j++) {
1250: if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1251: else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1252: }
1253: if (mat->stencil.noc) dxn++;
1254: jdxn[i] = tmp;
1255: }
1256: MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);
1257: PetscFree2(bufm,bufn);
1258: return(0);
1259: }
1263: /*@C
1264: MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1265: Using structured grid indexing
1267: Not Collective
1269: Input Parameters:
1270: + mat - the matrix
1271: . m - number of rows being entered
1272: . idxm - grid coordinates for matrix rows being entered
1273: . n - number of columns being entered
1274: . idxn - grid coordinates for matrix columns being entered
1275: . v - a logically two-dimensional array of values
1276: - addv - either ADD_VALUES or INSERT_VALUES, where
1277: ADD_VALUES adds values to any existing entries, and
1278: INSERT_VALUES replaces existing entries with new values
1280: Notes:
1281: By default the values, v, are row-oriented and unsorted.
1282: See MatSetOption() for other options.
1284: Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
1285: options cannot be mixed without intervening calls to the assembly
1286: routines.
1288: The grid coordinates are across the entire grid, not just the local portion
1290: MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran
1291: as well as in C.
1293: For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1295: In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1296: or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first.
1298: The columns and rows in the stencil passed in MUST be contained within the
1299: ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1300: if you create a DMDA with an overlap of one grid level and on a particular process its first
1301: local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1302: first i index you can use in your column and row indices in MatSetStencil() is 5.
1304: In Fortran idxm and idxn should be declared as
1305: $ MatStencil idxm(4,m),idxn(4,n)
1306: and the values inserted using
1307: $ idxm(MatStencil_i,1) = i
1308: $ idxm(MatStencil_j,1) = j
1309: $ idxm(MatStencil_k,1) = k
1310: etc
1312: Negative indices may be passed in idxm and idxn, these rows and columns are
1313: simply ignored. This allows easily inserting element stiffness matrices
1314: with homogeneous Dirchlet boundary conditions that you don't want represented
1315: in the matrix.
1317: Inspired by the structured grid interface to the HYPRE package
1318: (http://www.llnl.gov/CASC/hypre)
1320: Level: beginner
1322: Concepts: matrices^putting entries in
1324: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1325: MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil,
1326: MatSetBlockSize(), MatSetLocalToGlobalMapping()
1327: @*/
1328: PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1329: {
1331: PetscInt buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1332: PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1333: PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1336: if (!m || !n) return(0); /* no values to insert */
1343: if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1344: jdxm = buf; jdxn = buf+m;
1345: } else {
1346: PetscMalloc2(m,PetscInt,&bufm,n,PetscInt,&bufn);
1347: jdxm = bufm; jdxn = bufn;
1348: }
1349: for (i=0; i<m; i++) {
1350: for (j=0; j<3-sdim; j++) dxm++;
1351: tmp = *dxm++ - starts[0];
1352: for (j=0; j<sdim-1; j++) {
1353: if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1354: else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1355: }
1356: dxm++;
1357: jdxm[i] = tmp;
1358: }
1359: for (i=0; i<n; i++) {
1360: for (j=0; j<3-sdim; j++) dxn++;
1361: tmp = *dxn++ - starts[0];
1362: for (j=0; j<sdim-1; j++) {
1363: if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1364: else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1365: }
1366: dxn++;
1367: jdxn[i] = tmp;
1368: }
1369: MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);
1370: PetscFree2(bufm,bufn);
1371: #if defined(PETSC_HAVE_CUSP)
1372: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1373: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1374: }
1375: #endif
1376: return(0);
1377: }
1381: /*@
1382: MatSetStencil - Sets the grid information for setting values into a matrix via
1383: MatSetValuesStencil()
1385: Not Collective
1387: Input Parameters:
1388: + mat - the matrix
1389: . dim - dimension of the grid 1, 2, or 3
1390: . dims - number of grid points in x, y, and z direction, including ghost points on your processor
1391: . starts - starting point of ghost nodes on your processor in x, y, and z direction
1392: - dof - number of degrees of freedom per node
1395: Inspired by the structured grid interface to the HYPRE package
1396: (www.llnl.gov/CASC/hyper)
1398: For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the
1399: user.
1400:
1401: Level: beginner
1403: Concepts: matrices^putting entries in
1405: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1406: MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
1407: @*/
1408: PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1409: {
1410: PetscInt i;
1417: mat->stencil.dim = dim + (dof > 1);
1418: for (i=0; i<dim; i++) {
1419: mat->stencil.dims[i] = dims[dim-i-1]; /* copy the values in backwards */
1420: mat->stencil.starts[i] = starts[dim-i-1];
1421: }
1422: mat->stencil.dims[dim] = dof;
1423: mat->stencil.starts[dim] = 0;
1424: mat->stencil.noc = (PetscBool)(dof == 1);
1425: return(0);
1426: }
1430: /*@
1431: MatSetValuesBlocked - Inserts or adds a block of values into a matrix.
1433: Not Collective
1435: Input Parameters:
1436: + mat - the matrix
1437: . v - a logically two-dimensional array of values
1438: . m, idxm - the number of block rows and their global block indices
1439: . n, idxn - the number of block columns and their global block indices
1440: - addv - either ADD_VALUES or INSERT_VALUES, where
1441: ADD_VALUES adds values to any existing entries, and
1442: INSERT_VALUES replaces existing entries with new values
1444: Notes:
1445: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call
1446: MatXXXXSetPreallocation() or MatSetUp() before using this routine.
1448: The m and n count the NUMBER of blocks in the row direction and column direction,
1449: NOT the total number of rows/columns; for example, if the block size is 2 and
1450: you are passing in values for rows 2,3,4,5 then m would be 2 (not 4).
1451: The values in idxm would be 1 2; that is the first index for each block divided by
1452: the block size.
1454: Note that you must call MatSetBlockSize() when constructing this matrix (after
1455: preallocating it).
1457: By default the values, v, are row-oriented, so the layout of
1458: v is the same as for MatSetValues(). See MatSetOption() for other options.
1460: Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
1461: options cannot be mixed without intervening calls to the assembly
1462: routines.
1464: MatSetValuesBlocked() uses 0-based row and column numbers in Fortran
1465: as well as in C.
1467: Negative indices may be passed in idxm and idxn, these rows and columns are
1468: simply ignored. This allows easily inserting element stiffness matrices
1469: with homogeneous Dirchlet boundary conditions that you don't want represented
1470: in the matrix.
1472: Each time an entry is set within a sparse matrix via MatSetValues(),
1473: internal searching must be done to determine where to place the the
1474: data in the matrix storage space. By instead inserting blocks of
1475: entries via MatSetValuesBlocked(), the overhead of matrix assembly is
1476: reduced.
1478: Example:
1479: $ Suppose m=n=2 and block size(bs) = 2 The array is
1480: $
1481: $ 1 2 | 3 4
1482: $ 5 6 | 7 8
1483: $ - - - | - - -
1484: $ 9 10 | 11 12
1485: $ 13 14 | 15 16
1486: $
1487: $ v[] should be passed in like
1488: $ v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
1489: $
1490: $ If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then
1491: $ v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16]
1493: Level: intermediate
1495: Concepts: matrices^putting entries in blocked
1497: .seealso: MatSetBlockSize(), MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal()
1498: @*/
1499: PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1500: {
1506: if (!m || !n) return(0); /* no values to insert */
1510: MatCheckPreallocated(mat,1);
1511: if (mat->insertmode == NOT_SET_VALUES) {
1512: mat->insertmode = addv;
1513: }
1514: #if defined(PETSC_USE_DEBUG)
1515: else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1516: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1517: if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1518: #endif
1520: if (mat->assembled) {
1521: mat->was_assembled = PETSC_TRUE;
1522: mat->assembled = PETSC_FALSE;
1523: }
1524: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1525: if (mat->ops->setvaluesblocked) {
1526: (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);
1527: } else {
1528: PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn;
1529: PetscInt i,j,bs=mat->rmap->bs;
1530: if ((m+n)*bs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1531: iidxm = buf; iidxn = buf + m*bs;
1532: } else {
1533: PetscMalloc2(m*bs,PetscInt,&bufr,n*bs,PetscInt,&bufc);
1534: iidxm = bufr; iidxn = bufc;
1535: }
1536: for (i=0; i<m; i++)
1537: for (j=0; j<bs; j++)
1538: iidxm[i*bs+j] = bs*idxm[i] + j;
1539: for (i=0; i<n; i++)
1540: for (j=0; j<bs; j++)
1541: iidxn[i*bs+j] = bs*idxn[i] + j;
1542: MatSetValues(mat,m*bs,iidxm,n*bs,iidxn,v,addv);
1543: PetscFree2(bufr,bufc);
1544: }
1545: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1546: #if defined(PETSC_HAVE_CUSP)
1547: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1548: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1549: }
1550: #endif
1551: return(0);
1552: }
1556: /*@
1557: MatGetValues - Gets a block of values from a matrix.
1559: Not Collective; currently only returns a local block
1561: Input Parameters:
1562: + mat - the matrix
1563: . v - a logically two-dimensional array for storing the values
1564: . m, idxm - the number of rows and their global indices
1565: - n, idxn - the number of columns and their global indices
1567: Notes:
1568: The user must allocate space (m*n PetscScalars) for the values, v.
1569: The values, v, are then returned in a row-oriented format,
1570: analogous to that used by default in MatSetValues().
1572: MatGetValues() uses 0-based row and column numbers in
1573: Fortran as well as in C.
1575: MatGetValues() requires that the matrix has been assembled
1576: with MatAssemblyBegin()/MatAssemblyEnd(). Thus, calls to
1577: MatSetValues() and MatGetValues() CANNOT be made in succession
1578: without intermediate matrix assembly.
1580: Negative row or column indices will be ignored and those locations in v[] will be
1581: left unchanged.
1583: Level: advanced
1585: Concepts: matrices^accessing values
1587: .seealso: MatGetRow(), MatGetSubMatrices(), MatSetValues()
1588: @*/
1589: PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1590: {
1596: if (!m || !n) return(0);
1600: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1601: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1602: if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1603: MatCheckPreallocated(mat,1);
1605: PetscLogEventBegin(MAT_GetValues,mat,0,0,0);
1606: (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);
1607: PetscLogEventEnd(MAT_GetValues,mat,0,0,0);
1608: return(0);
1609: }
1613: /*@
1614: MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and
1615: the same size. Currently, this can only be called once and creates the given matrix.
1617: Not Collective
1619: Input Parameters:
1620: + mat - the matrix
1621: . nb - the number of blocks
1622: . bs - the number of rows (and columns) in each block
1623: . rows - a concatenation of the rows for each block
1624: - v - a concatenation of logically two-dimensional arrays of values
1626: Notes:
1627: In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix.
1629: Level: advanced
1631: Concepts: matrices^putting entries in
1633: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1634: InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1635: @*/
1636: PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[])
1637: {
1645: #if defined(PETSC_USE_DEBUG)
1646: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1647: #endif
1649: PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);
1650: if (mat->ops->setvaluesbatch) {
1651: (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);
1652: } else {
1653: PetscInt b;
1654: for(b = 0; b < nb; ++b) {
1655: MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);
1656: }
1657: }
1658: PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);
1659: return(0);
1660: }
1664: /*@
1665: MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
1666: the routine MatSetValuesLocal() to allow users to insert matrix entries
1667: using a local (per-processor) numbering.
1669: Not Collective
1671: Input Parameters:
1672: + x - the matrix
1673: . rmapping - row mapping created with ISLocalToGlobalMappingCreate()
1674: or ISLocalToGlobalMappingCreateIS()
1675: - cmapping - column mapping
1677: Level: intermediate
1679: Concepts: matrices^local to global mapping
1680: Concepts: local to global mapping^for matrices
1682: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
1683: @*/
1684: PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
1685: {
1693: if (x->ops->setlocaltoglobalmapping) {
1694: (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);
1695: } else {
1696: PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);
1697: PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);
1698: }
1699: return(0);
1700: }
1704: /*@
1705: MatSetLocalToGlobalMappingBlock - Sets a local-to-global numbering for use
1706: by the routine MatSetValuesBlockedLocal() to allow users to insert matrix
1707: entries using a local (per-processor) numbering.
1709: Not Collective
1711: Input Parameters:
1712: + x - the matrix
1713: . rmapping - row mapping created with ISLocalToGlobalMappingCreate() or
1714: ISLocalToGlobalMappingCreateIS()
1715: - cmapping - column mapping
1717: Level: intermediate
1719: Concepts: matrices^local to global mapping blocked
1720: Concepts: local to global mapping^for matrices, blocked
1722: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal(),
1723: MatSetValuesBlocked(), MatSetValuesLocal()
1724: @*/
1725: PetscErrorCode MatSetLocalToGlobalMappingBlock(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
1726: {
1734: PetscLayoutSetISLocalToGlobalMappingBlock(x->rmap,rmapping);
1735: PetscLayoutSetISLocalToGlobalMappingBlock(x->cmap,cmapping);
1736: return(0);
1737: }
1741: /*@
1742: MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping()
1744: Not Collective
1746: Input Parameters:
1747: . A - the matrix
1749: Output Parameters:
1750: + rmapping - row mapping
1751: - cmapping - column mapping
1753: Level: advanced
1755: Concepts: matrices^local to global mapping
1756: Concepts: local to global mapping^for matrices
1758: .seealso: MatSetValuesLocal(), MatGetLocalToGlobalMappingBlock()
1759: @*/
1760: PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
1761: {
1767: if (rmapping) *rmapping = A->rmap->mapping;
1768: if (cmapping) *cmapping = A->cmap->mapping;
1769: return(0);
1770: }
1774: /*@
1775: MatGetLocalToGlobalMappingBlock - Gets the local-to-global numbering set by MatSetLocalToGlobalMappingBlock()
1777: Not Collective
1779: Input Parameters:
1780: . A - the matrix
1782: Output Parameters:
1783: + rmapping - row mapping
1784: - cmapping - column mapping
1786: Level: advanced
1788: Concepts: matrices^local to global mapping blocked
1789: Concepts: local to global mapping^for matrices, blocked
1791: .seealso: MatSetValuesBlockedLocal(), MatGetLocalToGlobalMapping()
1792: @*/
1793: PetscErrorCode MatGetLocalToGlobalMappingBlock(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
1794: {
1800: if (rmapping) *rmapping = A->rmap->bmapping;
1801: if (cmapping) *cmapping = A->cmap->bmapping;
1802: return(0);
1803: }
1807: /*@
1808: MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
1809: using a local ordering of the nodes.
1811: Not Collective
1813: Input Parameters:
1814: + x - the matrix
1815: . nrow, irow - number of rows and their local indices
1816: . ncol, icol - number of columns and their local indices
1817: . y - a logically two-dimensional array of values
1818: - addv - either INSERT_VALUES or ADD_VALUES, where
1819: ADD_VALUES adds values to any existing entries, and
1820: INSERT_VALUES replaces existing entries with new values
1822: Notes:
1823: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
1824: MatSetUp() before using this routine
1826: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine
1828: Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
1829: options cannot be mixed without intervening calls to the assembly
1830: routines.
1832: These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1833: MUST be called after all calls to MatSetValuesLocal() have been completed.
1835: Level: intermediate
1837: Concepts: matrices^putting entries in with local numbering
1839: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
1840: MatSetValueLocal()
1841: @*/
1842: PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
1843: {
1849: MatCheckPreallocated(mat,1);
1850: if (!nrow || !ncol) return(0); /* no values to insert */
1854: if (mat->insertmode == NOT_SET_VALUES) {
1855: mat->insertmode = addv;
1856: }
1857: #if defined(PETSC_USE_DEBUG)
1858: else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1859: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1860: if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1861: #endif
1863: if (mat->assembled) {
1864: mat->was_assembled = PETSC_TRUE;
1865: mat->assembled = PETSC_FALSE;
1866: }
1867: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1868: if (mat->ops->setvalueslocal) {
1869: (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);
1870: } else {
1871: PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
1872: if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1873: irowm = buf; icolm = buf+nrow;
1874: } else {
1875: PetscMalloc2(nrow,PetscInt,&bufr,ncol,PetscInt,&bufc);
1876: irowm = bufr; icolm = bufc;
1877: }
1878: ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);
1879: ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);
1880: MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);
1881: PetscFree2(bufr,bufc);
1882: }
1883: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1884: #if defined(PETSC_HAVE_CUSP)
1885: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1886: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1887: }
1888: #endif
1889: return(0);
1890: }
1894: /*@
1895: MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix,
1896: using a local ordering of the nodes a block at a time.
1898: Not Collective
1900: Input Parameters:
1901: + x - the matrix
1902: . nrow, irow - number of rows and their local indices
1903: . ncol, icol - number of columns and their local indices
1904: . y - a logically two-dimensional array of values
1905: - addv - either INSERT_VALUES or ADD_VALUES, where
1906: ADD_VALUES adds values to any existing entries, and
1907: INSERT_VALUES replaces existing entries with new values
1909: Notes:
1910: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
1911: MatSetUp() before using this routine
1913: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMappingBlock()
1914: before using this routineBefore calling MatSetValuesLocal(), the user must first set the
1916: Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
1917: options cannot be mixed without intervening calls to the assembly
1918: routines.
1920: These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1921: MUST be called after all calls to MatSetValuesBlockedLocal() have been completed.
1923: Level: intermediate
1925: Concepts: matrices^putting blocked values in with local numbering
1927: .seealso: MatSetBlockSize(), MatSetLocalToGlobalMappingBlock(), MatAssemblyBegin(), MatAssemblyEnd(),
1928: MatSetValuesLocal(), MatSetLocalToGlobalMappingBlock(), MatSetValuesBlocked()
1929: @*/
1930: PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
1931: {
1937: MatCheckPreallocated(mat,1);
1938: if (!nrow || !ncol) return(0); /* no values to insert */
1942: if (mat->insertmode == NOT_SET_VALUES) {
1943: mat->insertmode = addv;
1944: }
1945: #if defined(PETSC_USE_DEBUG)
1946: else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1947: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1948: 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);
1949: #endif
1951: if (mat->assembled) {
1952: mat->was_assembled = PETSC_TRUE;
1953: mat->assembled = PETSC_FALSE;
1954: }
1955: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1956: if (mat->ops->setvaluesblockedlocal) {
1957: (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);
1958: } else {
1959: PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
1960: if (mat->rmap->bmapping && mat->cmap->bmapping) {
1961: if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1962: irowm = buf; icolm = buf + nrow;
1963: } else {
1964: PetscMalloc2(nrow,PetscInt,&bufr,ncol,PetscInt,&bufc);
1965: irowm = bufr; icolm = bufc;
1966: }
1967: ISLocalToGlobalMappingApply(mat->rmap->bmapping,nrow,irow,irowm);
1968: ISLocalToGlobalMappingApply(mat->cmap->bmapping,ncol,icol,icolm);
1969: MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);
1970: PetscFree2(bufr,bufc);
1971: } else {
1972: PetscInt i,j,bs=mat->rmap->bs;
1973: if ((nrow+ncol)*bs <=(PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1974: irowm = buf; icolm = buf + nrow;
1975: } else {
1976: PetscMalloc2(nrow*bs,PetscInt,&bufr,ncol*bs,PetscInt,&bufc);
1977: irowm = bufr; icolm = bufc;
1978: }
1979: for (i=0; i<nrow; i++)
1980: for (j=0; j<bs; j++)
1981: irowm[i*bs+j] = irow[i]*bs+j;
1982: for (i=0; i<ncol; i++)
1983: for (j=0; j<bs; j++)
1984: icolm[i*bs+j] = icol[i]*bs+j;
1985: MatSetValuesLocal(mat,nrow*bs,irowm,ncol*bs,icolm,y,addv);
1986: PetscFree2(bufr,bufc);
1987: }
1988: }
1989: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1990: #if defined(PETSC_HAVE_CUSP)
1991: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1992: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1993: }
1994: #endif
1995: return(0);
1996: }
2000: /*@
2001: MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal
2003: Collective on Mat and Vec
2005: Input Parameters:
2006: + mat - the matrix
2007: - x - the vector to be multiplied
2009: Output Parameters:
2010: . y - the result
2012: Notes:
2013: The vectors x and y cannot be the same. I.e., one cannot
2014: call MatMult(A,y,y).
2016: Level: developer
2018: Concepts: matrix-vector product
2020: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2021: @*/
2022: PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y)
2023: {
2032: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2033: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2034: if (x == y) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2035: MatCheckPreallocated(mat,1);
2037: if (!mat->ops->multdiagonalblock) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2038: (*mat->ops->multdiagonalblock)(mat,x,y);
2039: PetscObjectStateIncrease((PetscObject)y);
2040: return(0);
2041: }
2043: /* --------------------------------------------------------*/
2046: /*@
2047: MatMult - Computes the matrix-vector product, y = Ax.
2049: Neighbor-wise Collective on Mat and Vec
2051: Input Parameters:
2052: + mat - the matrix
2053: - x - the vector to be multiplied
2055: Output Parameters:
2056: . y - the result
2058: Notes:
2059: The vectors x and y cannot be the same. I.e., one cannot
2060: call MatMult(A,y,y).
2062: Level: beginner
2064: Concepts: matrix-vector product
2066: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2067: @*/
2068: PetscErrorCode MatMult(Mat mat,Vec x,Vec y)
2069: {
2077: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2078: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2079: if (x == y) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2080: #ifndef PETSC_HAVE_CONSTRAINTS
2081: 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);
2082: 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);
2083: 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);
2084: #endif
2085: VecValidValues(x,2,PETSC_TRUE);
2086: MatCheckPreallocated(mat,1);
2088: if (!mat->ops->mult) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2089: PetscLogEventBegin(MAT_Mult,mat,x,y,0);
2090: (*mat->ops->mult)(mat,x,y);
2091: PetscLogEventEnd(MAT_Mult,mat,x,y,0);
2092: VecValidValues(y,3,PETSC_FALSE);
2093: return(0);
2094: }
2098: /*@
2099: MatMultTranspose - Computes matrix transpose times a vector.
2101: Neighbor-wise Collective on Mat and Vec
2103: Input Parameters:
2104: + mat - the matrix
2105: - x - the vector to be multilplied
2107: Output Parameters:
2108: . y - the result
2110: Notes:
2111: The vectors x and y cannot be the same. I.e., one cannot
2112: call MatMultTranspose(A,y,y).
2114: For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple,
2115: use MatMultHermitianTranspose()
2117: Level: beginner
2119: Concepts: matrix vector product^transpose
2121: .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose()
2122: @*/
2123: PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y)
2124: {
2133: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2134: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2135: if (x == y) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2136: #ifndef PETSC_HAVE_CONSTRAINTS
2137: 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);
2138: 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);
2139: #endif
2140: VecValidValues(x,2,PETSC_TRUE);
2141: MatCheckPreallocated(mat,1);
2143: if (!mat->ops->multtranspose) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"This matrix type does not have a multiply tranpose defined");
2144: PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);
2145: (*mat->ops->multtranspose)(mat,x,y);
2146: PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);
2147: PetscObjectStateIncrease((PetscObject)y);
2148: VecValidValues(y,3,PETSC_FALSE);
2149: return(0);
2150: }
2154: /*@
2155: MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.
2157: Neighbor-wise Collective on Mat and Vec
2159: Input Parameters:
2160: + mat - the matrix
2161: - x - the vector to be multilplied
2163: Output Parameters:
2164: . y - the result
2166: Notes:
2167: The vectors x and y cannot be the same. I.e., one cannot
2168: call MatMultHermitianTranspose(A,y,y).
2170: Also called the conjugate transpose, complex conjugate transpose, or adjoint.
2172: For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical.
2174: Level: beginner
2176: Concepts: matrix vector product^transpose
2178: .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose()
2179: @*/
2180: PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y)
2181: {
2183: Vec w;
2191: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2192: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2193: if (x == y) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2194: #ifndef PETSC_HAVE_CONSTRAINTS
2195: 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);
2196: 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);
2197: #endif
2198: MatCheckPreallocated(mat,1);
2200: PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);
2201: if (mat->ops->multhermitiantranspose) {
2202: (*mat->ops->multhermitiantranspose)(mat,x,y);
2203: } else {
2204: VecDuplicate(x,&w);
2205: VecCopy(x,w);
2206: VecConjugate(w);
2207: MatMultTranspose(mat,w,y);
2208: VecDestroy(&w);
2209: VecConjugate(y);
2210: }
2211: PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);
2212: PetscObjectStateIncrease((PetscObject)y);
2213: return(0);
2214: }
2218: /*@
2219: MatMultAdd - Computes v3 = v2 + A * v1.
2221: Neighbor-wise Collective on Mat and Vec
2223: Input Parameters:
2224: + mat - the matrix
2225: - v1, v2 - the vectors
2227: Output Parameters:
2228: . v3 - the result
2230: Notes:
2231: The vectors v1 and v3 cannot be the same. I.e., one cannot
2232: call MatMultAdd(A,v1,v2,v1).
2234: Level: beginner
2236: Concepts: matrix vector product^addition
2238: .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
2239: @*/
2240: PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2241: {
2251: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2252: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2253: 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);
2254: /* 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);
2255: 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); */
2256: 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);
2257: 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);
2258: if (v1 == v3) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2259: MatCheckPreallocated(mat,1);
2261: if (!mat->ops->multadd) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name);
2262: PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);
2263: (*mat->ops->multadd)(mat,v1,v2,v3);
2264: PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);
2265: PetscObjectStateIncrease((PetscObject)v3);
2266: return(0);
2267: }
2271: /*@
2272: MatMultTransposeAdd - Computes v3 = v2 + A' * v1.
2274: Neighbor-wise Collective on Mat and Vec
2276: Input Parameters:
2277: + mat - the matrix
2278: - v1, v2 - the vectors
2280: Output Parameters:
2281: . v3 - the result
2283: Notes:
2284: The vectors v1 and v3 cannot be the same. I.e., one cannot
2285: call MatMultTransposeAdd(A,v1,v2,v1).
2287: Level: beginner
2289: Concepts: matrix vector product^transpose and addition
2291: .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
2292: @*/
2293: PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2294: {
2304: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2305: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2306: if (!mat->ops->multtransposeadd) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2307: if (v1 == v3) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2308: 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);
2309: 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);
2310: 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);
2311: MatCheckPreallocated(mat,1);
2313: PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);
2314: (*mat->ops->multtransposeadd)(mat,v1,v2,v3);
2315: PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);
2316: PetscObjectStateIncrease((PetscObject)v3);
2317: return(0);
2318: }
2322: /*@
2323: MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1.
2325: Neighbor-wise Collective on Mat and Vec
2327: Input Parameters:
2328: + mat - the matrix
2329: - v1, v2 - the vectors
2331: Output Parameters:
2332: . v3 - the result
2334: Notes:
2335: The vectors v1 and v3 cannot be the same. I.e., one cannot
2336: call MatMultHermitianTransposeAdd(A,v1,v2,v1).
2338: Level: beginner
2340: Concepts: matrix vector product^transpose and addition
2342: .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult()
2343: @*/
2344: PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2345: {
2355: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2356: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2357: if (!mat->ops->multhermitiantransposeadd) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2358: if (v1 == v3) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2359: 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);
2360: 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);
2361: 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);
2362: MatCheckPreallocated(mat,1);
2364: PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2365: (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);
2366: PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2367: PetscObjectStateIncrease((PetscObject)v3);
2368: return(0);
2369: }
2373: /*@
2374: MatMultConstrained - The inner multiplication routine for a
2375: constrained matrix P^T A P.
2377: Neighbor-wise Collective on Mat and Vec
2379: Input Parameters:
2380: + mat - the matrix
2381: - x - the vector to be multilplied
2383: Output Parameters:
2384: . y - the result
2386: Notes:
2387: The vectors x and y cannot be the same. I.e., one cannot
2388: call MatMult(A,y,y).
2390: Level: beginner
2392: .keywords: matrix, multiply, matrix-vector product, constraint
2393: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2394: @*/
2395: PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y)
2396: {
2403: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2404: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2405: if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2406: 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);
2407: 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);
2408: 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);
2410: PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2411: (*mat->ops->multconstrained)(mat,x,y);
2412: PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2413: PetscObjectStateIncrease((PetscObject)y);
2415: return(0);
2416: }
2420: /*@
2421: MatMultTransposeConstrained - The inner multiplication routine for a
2422: constrained matrix P^T A^T P.
2424: Neighbor-wise Collective on Mat and Vec
2426: Input Parameters:
2427: + mat - the matrix
2428: - x - the vector to be multilplied
2430: Output Parameters:
2431: . y - the result
2433: Notes:
2434: The vectors x and y cannot be the same. I.e., one cannot
2435: call MatMult(A,y,y).
2437: Level: beginner
2439: .keywords: matrix, multiply, matrix-vector product, constraint
2440: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2441: @*/
2442: PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2443: {
2450: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2451: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2452: if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2453: 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);
2454: 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);
2456: PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2457: (*mat->ops->multtransposeconstrained)(mat,x,y);
2458: PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2459: PetscObjectStateIncrease((PetscObject)y);
2461: return(0);
2462: }
2466: /*@C
2467: MatGetFactorType - gets the type of factorization it is
2469: Note Collective
2470: as the flag
2472: Input Parameters:
2473: . mat - the matrix
2475: Output Parameters:
2476: . t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT
2478: Level: intermediate
2480: .seealso: MatFactorType, MatGetFactor()
2481: @*/
2482: PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t)
2483: {
2487: *t = mat->factortype;
2488: return(0);
2489: }
2491: /* ------------------------------------------------------------*/
2494: /*@C
2495: MatGetInfo - Returns information about matrix storage (number of
2496: nonzeros, memory, etc.).
2498: Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag
2500: Input Parameters:
2501: . mat - the matrix
2503: Output Parameters:
2504: + flag - flag indicating the type of parameters to be returned
2505: (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2506: MAT_GLOBAL_SUM - sum over all processors)
2507: - info - matrix information context
2509: Notes:
2510: The MatInfo context contains a variety of matrix data, including
2511: number of nonzeros allocated and used, number of mallocs during
2512: matrix assembly, etc. Additional information for factored matrices
2513: is provided (such as the fill ratio, number of mallocs during
2514: factorization, etc.). Much of this info is printed to PETSC_STDOUT
2515: when using the runtime options
2516: $ -info -mat_view_info
2518: Example for C/C++ Users:
2519: See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2520: data within the MatInfo context. For example,
2521: .vb
2522: MatInfo info;
2523: Mat A;
2524: double mal, nz_a, nz_u;
2526: MatGetInfo(A,MAT_LOCAL,&info);
2527: mal = info.mallocs;
2528: nz_a = info.nz_allocated;
2529: .ve
2531: Example for Fortran Users:
2532: Fortran users should declare info as a double precision
2533: array of dimension MAT_INFO_SIZE, and then extract the parameters
2534: of interest. See the file ${PETSC_DIR}/include/finclude/petscmat.h
2535: a complete list of parameter names.
2536: .vb
2537: double precision info(MAT_INFO_SIZE)
2538: double precision mal, nz_a
2539: Mat A
2540: integer ierr
2542: call MatGetInfo(A,MAT_LOCAL,info,ierr)
2543: mal = info(MAT_INFO_MALLOCS)
2544: nz_a = info(MAT_INFO_NZ_ALLOCATED)
2545: .ve
2547: Level: intermediate
2549: Concepts: matrices^getting information on
2550:
2551: Developer Note: fortran interface is not autogenerated as the f90
2552: interface defintion cannot be generated correctly [due to MatInfo]
2554: .seealso: MatStashGetInfo()
2555:
2556: @*/
2557: PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2558: {
2565: if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2566: MatCheckPreallocated(mat,1);
2567: (*mat->ops->getinfo)(mat,flag,info);
2568: return(0);
2569: }
2571: /* ----------------------------------------------------------*/
2575: /*@C
2576: MatLUFactor - Performs in-place LU factorization of matrix.
2578: Collective on Mat
2580: Input Parameters:
2581: + mat - the matrix
2582: . row - row permutation
2583: . col - column permutation
2584: - info - options for factorization, includes
2585: $ fill - expected fill as ratio of original fill.
2586: $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2587: $ Run with the option -info to determine an optimal value to use
2589: Notes:
2590: Most users should employ the simplified KSP interface for linear solvers
2591: instead of working directly with matrix algebra routines such as this.
2592: See, e.g., KSPCreate().
2594: This changes the state of the matrix to a factored matrix; it cannot be used
2595: for example with MatSetValues() unless one first calls MatSetUnfactored().
2597: Level: developer
2599: Concepts: matrices^LU factorization
2601: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2602: MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor()
2604: Developer Note: fortran interface is not autogenerated as the f90
2605: interface defintion cannot be generated correctly [due to MatFactorInfo]
2607: @*/
2608: PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2609: {
2611: MatFactorInfo tinfo;
2619: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2620: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2621: if (!mat->ops->lufactor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2622: MatCheckPreallocated(mat,1);
2623: if (!info) {
2624: MatFactorInfoInitialize(&tinfo);
2625: info = &tinfo;
2626: }
2628: PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);
2629: (*mat->ops->lufactor)(mat,row,col,info);
2630: PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);
2631: PetscObjectStateIncrease((PetscObject)mat);
2632: return(0);
2633: }
2637: /*@C
2638: MatILUFactor - Performs in-place ILU factorization of matrix.
2640: Collective on Mat
2642: Input Parameters:
2643: + mat - the matrix
2644: . row - row permutation
2645: . col - column permutation
2646: - info - structure containing
2647: $ levels - number of levels of fill.
2648: $ expected fill - as ratio of original fill.
2649: $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2650: missing diagonal entries)
2652: Notes:
2653: Probably really in-place only when level of fill is zero, otherwise allocates
2654: new space to store factored matrix and deletes previous memory.
2656: Most users should employ the simplified KSP interface for linear solvers
2657: instead of working directly with matrix algebra routines such as this.
2658: See, e.g., KSPCreate().
2660: Level: developer
2662: Concepts: matrices^ILU factorization
2664: .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
2666: Developer Note: fortran interface is not autogenerated as the f90
2667: interface defintion cannot be generated correctly [due to MatFactorInfo]
2669: @*/
2670: PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2671: {
2680: if (mat->rmap->N != mat->cmap->N) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONG,"matrix must be square");
2681: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2682: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2683: if (!mat->ops->ilufactor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2684: MatCheckPreallocated(mat,1);
2686: PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);
2687: (*mat->ops->ilufactor)(mat,row,col,info);
2688: PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);
2689: PetscObjectStateIncrease((PetscObject)mat);
2690: return(0);
2691: }
2695: /*@C
2696: MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
2697: Call this routine before calling MatLUFactorNumeric().
2699: Collective on Mat
2701: Input Parameters:
2702: + fact - the factor matrix obtained with MatGetFactor()
2703: . mat - the matrix
2704: . row, col - row and column permutations
2705: - info - options for factorization, includes
2706: $ fill - expected fill as ratio of original fill.
2707: $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2708: $ Run with the option -info to determine an optimal value to use
2711: Notes:
2712: See the <a href="../../docs/manual.pdf">users manual</a> for additional information about
2713: choosing the fill factor for better efficiency.
2715: Most users should employ the simplified KSP interface for linear solvers
2716: instead of working directly with matrix algebra routines such as this.
2717: See, e.g., KSPCreate().
2719: Level: developer
2721: Concepts: matrices^LU symbolic factorization
2723: .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
2725: Developer Note: fortran interface is not autogenerated as the f90
2726: interface defintion cannot be generated correctly [due to MatFactorInfo]
2728: @*/
2729: PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
2730: {
2740: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2741: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2742: if (!(fact)->ops->lufactorsymbolic) {
2743: const MatSolverPackage spackage;
2744: MatFactorGetSolverPackage(fact,&spackage);
2745: SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage);
2746: }
2747: MatCheckPreallocated(mat,2);
2749: PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);
2750: (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);
2751: PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);
2752: PetscObjectStateIncrease((PetscObject)fact);
2753: return(0);
2754: }
2758: /*@C
2759: MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
2760: Call this routine after first calling MatLUFactorSymbolic().
2762: Collective on Mat
2764: Input Parameters:
2765: + fact - the factor matrix obtained with MatGetFactor()
2766: . mat - the matrix
2767: - info - options for factorization
2769: Notes:
2770: See MatLUFactor() for in-place factorization. See
2771: MatCholeskyFactorNumeric() for the symmetric, positive definite case.
2773: Most users should employ the simplified KSP interface for linear solvers
2774: instead of working directly with matrix algebra routines such as this.
2775: See, e.g., KSPCreate().
2777: Level: developer
2779: Concepts: matrices^LU numeric factorization
2781: .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()
2783: Developer Note: fortran interface is not autogenerated as the f90
2784: interface defintion cannot be generated correctly [due to MatFactorInfo]
2786: @*/
2787: PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
2788: {
2796: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2797: if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) {
2798: 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);
2799: }
2800: if (!(fact)->ops->lufactornumeric) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name);
2801: MatCheckPreallocated(mat,2);
2802: PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);
2803: (fact->ops->lufactornumeric)(fact,mat,info);
2804: PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);
2806: MatView_Private(fact);
2807: PetscObjectStateIncrease((PetscObject)fact);
2808: return(0);
2809: }
2813: /*@C
2814: MatCholeskyFactor - Performs in-place Cholesky factorization of a
2815: symmetric matrix.
2817: Collective on Mat
2819: Input Parameters:
2820: + mat - the matrix
2821: . perm - row and column permutations
2822: - f - expected fill as ratio of original fill
2824: Notes:
2825: See MatLUFactor() for the nonsymmetric case. See also
2826: MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().
2828: Most users should employ the simplified KSP interface for linear solvers
2829: instead of working directly with matrix algebra routines such as this.
2830: See, e.g., KSPCreate().
2832: Level: developer
2834: Concepts: matrices^Cholesky factorization
2836: .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
2837: MatGetOrdering()
2839: Developer Note: fortran interface is not autogenerated as the f90
2840: interface defintion cannot be generated correctly [due to MatFactorInfo]
2842: @*/
2843: PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
2844: {
2852: if (mat->rmap->N != mat->cmap->N) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONG,"Matrix must be square");
2853: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2854: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2855: if (!mat->ops->choleskyfactor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2856: MatCheckPreallocated(mat,1);
2858: PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);
2859: (*mat->ops->choleskyfactor)(mat,perm,info);
2860: PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);
2861: PetscObjectStateIncrease((PetscObject)mat);
2862: return(0);
2863: }
2867: /*@C
2868: MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
2869: of a symmetric matrix.
2871: Collective on Mat
2873: Input Parameters:
2874: + fact - the factor matrix obtained with MatGetFactor()
2875: . mat - the matrix
2876: . perm - row and column permutations
2877: - info - options for factorization, includes
2878: $ fill - expected fill as ratio of original fill.
2879: $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2880: $ Run with the option -info to determine an optimal value to use
2882: Notes:
2883: See MatLUFactorSymbolic() for the nonsymmetric case. See also
2884: MatCholeskyFactor() and MatCholeskyFactorNumeric().
2886: Most users should employ the simplified KSP interface for linear solvers
2887: instead of working directly with matrix algebra routines such as this.
2888: See, e.g., KSPCreate().
2890: Level: developer
2892: Concepts: matrices^Cholesky symbolic factorization
2894: .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
2895: MatGetOrdering()
2897: Developer Note: fortran interface is not autogenerated as the f90
2898: interface defintion cannot be generated correctly [due to MatFactorInfo]
2900: @*/
2901: PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
2902: {
2911: if (mat->rmap->N != mat->cmap->N) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONG,"Matrix must be square");
2912: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2913: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2914: if (!(fact)->ops->choleskyfactorsymbolic) {
2915: const MatSolverPackage spackage;
2916: MatFactorGetSolverPackage(fact,&spackage);
2917: SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage);
2918: }
2919: MatCheckPreallocated(mat,2);
2921: PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
2922: (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);
2923: PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
2924: PetscObjectStateIncrease((PetscObject)fact);
2925: return(0);
2926: }
2930: /*@C
2931: MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
2932: of a symmetric matrix. Call this routine after first calling
2933: MatCholeskyFactorSymbolic().
2935: Collective on Mat
2937: Input Parameters:
2938: + fact - the factor matrix obtained with MatGetFactor()
2939: . mat - the initial matrix
2940: . info - options for factorization
2941: - fact - the symbolic factor of mat
2944: Notes:
2945: Most users should employ the simplified KSP interface for linear solvers
2946: instead of working directly with matrix algebra routines such as this.
2947: See, e.g., KSPCreate().
2949: Level: developer
2951: Concepts: matrices^Cholesky numeric factorization
2953: .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
2955: Developer Note: fortran interface is not autogenerated as the f90
2956: interface defintion cannot be generated correctly [due to MatFactorInfo]
2958: @*/
2959: PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
2960: {
2968: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2969: if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name);
2970: if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) {
2971: 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);
2972: }
2973: MatCheckPreallocated(mat,2);
2975: PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);
2976: (fact->ops->choleskyfactornumeric)(fact,mat,info);
2977: PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);
2979: MatView_Private(fact);
2980: PetscObjectStateIncrease((PetscObject)fact);
2981: return(0);
2982: }
2984: /* ----------------------------------------------------------------*/
2987: /*@
2988: MatSolve - Solves A x = b, given a factored matrix.
2990: Neighbor-wise Collective on Mat and Vec
2992: Input Parameters:
2993: + mat - the factored matrix
2994: - b - the right-hand-side vector
2996: Output Parameter:
2997: . x - the result vector
2999: Notes:
3000: The vectors b and x cannot be the same. I.e., one cannot
3001: call MatSolve(A,x,x).
3003: Notes:
3004: Most users should employ the simplified KSP interface for linear solvers
3005: instead of working directly with matrix algebra routines such as this.
3006: See, e.g., KSPCreate().
3008: Level: developer
3010: Concepts: matrices^triangular solves
3012: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
3013: @*/
3014: PetscErrorCode MatSolve(Mat mat,Vec b,Vec x)
3015: {
3025: if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3026: if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3027: 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);
3028: 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);
3029: 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);
3030: if (!mat->rmap->N && !mat->cmap->N) return(0);
3031: if (!mat->ops->solve) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3032: MatCheckPreallocated(mat,1);
3034: PetscLogEventBegin(MAT_Solve,mat,b,x,0);
3035: (*mat->ops->solve)(mat,b,x);
3036: PetscLogEventEnd(MAT_Solve,mat,b,x,0);
3037: PetscObjectStateIncrease((PetscObject)x);
3038: return(0);
3039: }
3043: PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X)
3044: {
3046: Vec b,x;
3047: PetscInt m,N,i;
3048: PetscScalar *bb,*xx;
3049: PetscBool flg;
3052: PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,PETSC_NULL);
3053: if (!flg) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
3054: PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,PETSC_NULL);
3055: if (!flg) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");
3057: MatGetArray(B,&bb);
3058: MatGetArray(X,&xx);
3059: MatGetLocalSize(B,&m,PETSC_NULL); /* number local rows */
3060: MatGetSize(B,PETSC_NULL,&N); /* total columns in dense matrix */
3061: MatGetVecs(A,&x,&b);
3062: for (i=0; i<N; i++) {
3063: VecPlaceArray(b,bb + i*m);
3064: VecPlaceArray(x,xx + i*m);
3065: MatSolve(A,b,x);
3066: VecResetArray(x);
3067: VecResetArray(b);
3068: }
3069: VecDestroy(&b);
3070: VecDestroy(&x);
3071: MatRestoreArray(B,&bb);
3072: MatRestoreArray(X,&xx);
3073: return(0);
3074: }
3078: /*@
3079: MatMatSolve - Solves A X = B, given a factored matrix.
3081: Neighbor-wise Collective on Mat
3083: Input Parameters:
3084: + mat - the factored matrix
3085: - B - the right-hand-side matrix (dense matrix)
3087: Output Parameter:
3088: . X - the result matrix (dense matrix)
3090: Notes:
3091: The matrices b and x cannot be the same. I.e., one cannot
3092: call MatMatSolve(A,x,x).
3094: Notes:
3095: Most users should usually employ the simplified KSP interface for linear solvers
3096: instead of working directly with matrix algebra routines such as this.
3097: See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3098: at a time.
3100: When using SuperLU_Dist as a parallel solver PETSc will use the SuperLU_Dist functionality to solve multiple right hand sides simultaneously. For MUMPS
3101: it calls a separate solve for each right hand side since MUMPS does not yet support distributed right hand sides.
3103: Since the resulting matrix X must always be dense we do not support sparse representation of the matrix B.
3105: Level: developer
3107: Concepts: matrices^triangular solves
3109: .seealso: MatMatSolveAdd(), MatMatSolveTranspose(), MatMatSolveTransposeAdd(), MatLUFactor(), MatCholeskyFactor()
3110: @*/
3111: PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X)
3112: {
3122: if (X == B) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3123: if (!A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3124: 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);
3125: 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);
3126: 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);
3127: if (!A->rmap->N && !A->cmap->N) return(0);
3128: MatCheckPreallocated(A,1);
3130: PetscLogEventBegin(MAT_MatSolve,A,B,X,0);
3131: if (!A->ops->matsolve) {
3132: PetscInfo1(A,"Mat type %s using basic MatMatSolve",((PetscObject)A)->type_name);
3133: MatMatSolve_Basic(A,B,X);
3134: } else {
3135: (*A->ops->matsolve)(A,B,X);
3136: }
3137: PetscLogEventEnd(MAT_MatSolve,A,B,X,0);
3138: PetscObjectStateIncrease((PetscObject)X);
3139: return(0);
3140: }
3145: /*@
3146: MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or
3147: U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U,
3149: Neighbor-wise Collective on Mat and Vec
3151: Input Parameters:
3152: + mat - the factored matrix
3153: - b - the right-hand-side vector
3155: Output Parameter:
3156: . x - the result vector
3158: Notes:
3159: MatSolve() should be used for most applications, as it performs
3160: a forward solve followed by a backward solve.
3162: The vectors b and x cannot be the same, i.e., one cannot
3163: call MatForwardSolve(A,x,x).
3165: For matrix in seqsbaij format with block size larger than 1,
3166: the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3167: MatForwardSolve() solves U^T*D y = b, and
3168: MatBackwardSolve() solves U x = y.
3169: Thus they do not provide a symmetric preconditioner.
3171: Most users should employ the simplified KSP interface for linear solvers
3172: instead of working directly with matrix algebra routines such as this.
3173: See, e.g., KSPCreate().
3175: Level: developer
3177: Concepts: matrices^forward solves
3179: .seealso: MatSolve(), MatBackwardSolve()
3180: @*/
3181: PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x)
3182: {
3192: if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3193: if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3194: if (!mat->ops->forwardsolve) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3195: 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);
3196: 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);
3197: 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);
3198: MatCheckPreallocated(mat,1);
3199: PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);
3200: (*mat->ops->forwardsolve)(mat,b,x);
3201: PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);
3202: PetscObjectStateIncrease((PetscObject)x);
3203: return(0);
3204: }
3208: /*@
3209: MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
3210: D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U,
3212: Neighbor-wise Collective on Mat and Vec
3214: Input Parameters:
3215: + mat - the factored matrix
3216: - b - the right-hand-side vector
3218: Output Parameter:
3219: . x - the result vector
3221: Notes:
3222: MatSolve() should be used for most applications, as it performs
3223: a forward solve followed by a backward solve.
3225: The vectors b and x cannot be the same. I.e., one cannot
3226: call MatBackwardSolve(A,x,x).
3228: For matrix in seqsbaij format with block size larger than 1,
3229: the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3230: MatForwardSolve() solves U^T*D y = b, and
3231: MatBackwardSolve() solves U x = y.
3232: Thus they do not provide a symmetric preconditioner.
3234: Most users should employ the simplified KSP interface for linear solvers
3235: instead of working directly with matrix algebra routines such as this.
3236: See, e.g., KSPCreate().
3238: Level: developer
3240: Concepts: matrices^backward solves
3242: .seealso: MatSolve(), MatForwardSolve()
3243: @*/
3244: PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x)
3245: {
3255: if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3256: if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3257: if (!mat->ops->backwardsolve) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3258: 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);
3259: 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);
3260: 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);
3261: MatCheckPreallocated(mat,1);
3263: PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);
3264: (*mat->ops->backwardsolve)(mat,b,x);
3265: PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);
3266: PetscObjectStateIncrease((PetscObject)x);
3267: return(0);
3268: }
3272: /*@
3273: MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
3275: Neighbor-wise Collective on Mat and Vec
3277: Input Parameters:
3278: + mat - the factored matrix
3279: . b - the right-hand-side vector
3280: - y - the vector to be added to
3282: Output Parameter:
3283: . x - the result vector
3285: Notes:
3286: The vectors b and x cannot be the same. I.e., one cannot
3287: call MatSolveAdd(A,x,y,x).
3289: Most users should employ the simplified KSP interface for linear solvers
3290: instead of working directly with matrix algebra routines such as this.
3291: See, e.g., KSPCreate().
3293: Level: developer
3295: Concepts: matrices^triangular solves
3297: .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3298: @*/
3299: PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3300: {
3301: PetscScalar one = 1.0;
3302: Vec tmp;
3314: if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3315: if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3316: 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);
3317: 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);
3318: 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);
3319: 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);
3320: 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);
3321: MatCheckPreallocated(mat,1);
3323: PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);
3324: if (mat->ops->solveadd) {
3325: (*mat->ops->solveadd)(mat,b,y,x);
3326: } else {
3327: /* do the solve then the add manually */
3328: if (x != y) {
3329: MatSolve(mat,b,x);
3330: VecAXPY(x,one,y);
3331: } else {
3332: VecDuplicate(x,&tmp);
3333: PetscLogObjectParent(mat,tmp);
3334: VecCopy(x,tmp);
3335: MatSolve(mat,b,x);
3336: VecAXPY(x,one,tmp);
3337: VecDestroy(&tmp);
3338: }
3339: }
3340: PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);
3341: PetscObjectStateIncrease((PetscObject)x);
3342: return(0);
3343: }
3347: /*@
3348: MatSolveTranspose - Solves A' x = b, given a factored matrix.
3350: Neighbor-wise Collective on Mat and Vec
3352: Input Parameters:
3353: + mat - the factored matrix
3354: - b - the right-hand-side vector
3356: Output Parameter:
3357: . x - the result vector
3359: Notes:
3360: The vectors b and x cannot be the same. I.e., one cannot
3361: call MatSolveTranspose(A,x,x).
3363: Most users should employ the simplified KSP interface for linear solvers
3364: instead of working directly with matrix algebra routines such as this.
3365: See, e.g., KSPCreate().
3367: Level: developer
3369: Concepts: matrices^triangular solves
3371: .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
3372: @*/
3373: PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x)
3374: {
3384: if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3385: if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3386: if (!mat->ops->solvetranspose) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3387: 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);
3388: 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);
3389: MatCheckPreallocated(mat,1);
3390: PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);
3391: (*mat->ops->solvetranspose)(mat,b,x);
3392: PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);
3393: PetscObjectStateIncrease((PetscObject)x);
3394: return(0);
3395: }
3399: /*@
3400: MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
3401: factored matrix.
3403: Neighbor-wise Collective on Mat and Vec
3405: Input Parameters:
3406: + mat - the factored matrix
3407: . b - the right-hand-side vector
3408: - y - the vector to be added to
3410: Output Parameter:
3411: . x - the result vector
3413: Notes:
3414: The vectors b and x cannot be the same. I.e., one cannot
3415: call MatSolveTransposeAdd(A,x,y,x).
3417: Most users should employ the simplified KSP interface for linear solvers
3418: instead of working directly with matrix algebra routines such as this.
3419: See, e.g., KSPCreate().
3421: Level: developer
3423: Concepts: matrices^triangular solves
3425: .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3426: @*/
3427: PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3428: {
3429: PetscScalar one = 1.0;
3431: Vec tmp;
3442: if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3443: if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3444: 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);
3445: 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);
3446: 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);
3447: 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);
3448: MatCheckPreallocated(mat,1);
3450: PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);
3451: if (mat->ops->solvetransposeadd) {
3452: (*mat->ops->solvetransposeadd)(mat,b,y,x);
3453: } else {
3454: /* do the solve then the add manually */
3455: if (x != y) {
3456: MatSolveTranspose(mat,b,x);
3457: VecAXPY(x,one,y);
3458: } else {
3459: VecDuplicate(x,&tmp);
3460: PetscLogObjectParent(mat,tmp);
3461: VecCopy(x,tmp);
3462: MatSolveTranspose(mat,b,x);
3463: VecAXPY(x,one,tmp);
3464: VecDestroy(&tmp);
3465: }
3466: }
3467: PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);
3468: PetscObjectStateIncrease((PetscObject)x);
3469: return(0);
3470: }
3471: /* ----------------------------------------------------------------*/
3475: /*@
3476: MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps.
3478: Neighbor-wise Collective on Mat and Vec
3480: Input Parameters:
3481: + mat - the matrix
3482: . b - the right hand side
3483: . omega - the relaxation factor
3484: . flag - flag indicating the type of SOR (see below)
3485: . shift - diagonal shift
3486: . its - the number of iterations
3487: - lits - the number of local iterations
3489: Output Parameters:
3490: . x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess)
3492: SOR Flags:
3493: . SOR_FORWARD_SWEEP - forward SOR
3494: . SOR_BACKWARD_SWEEP - backward SOR
3495: . SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3496: . SOR_LOCAL_FORWARD_SWEEP - local forward SOR
3497: . SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
3498: . SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3499: . SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
3500: upper/lower triangular part of matrix to
3501: vector (with omega)
3502: . SOR_ZERO_INITIAL_GUESS - zero initial guess
3504: Notes:
3505: SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3506: SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3507: on each processor.
3509: Application programmers will not generally use MatSOR() directly,
3510: but instead will employ the KSP/PC interface.
3512: Notes: for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing
3514: Notes for Advanced Users:
3515: The flags are implemented as bitwise inclusive or operations.
3516: For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3517: to specify a zero initial guess for SSOR.
3519: Most users should employ the simplified KSP interface for linear solvers
3520: instead of working directly with matrix algebra routines such as this.
3521: See, e.g., KSPCreate().
3523: Vectors x and b CANNOT be the same
3525: Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes
3527: Level: developer
3529: Concepts: matrices^relaxation
3530: Concepts: matrices^SOR
3531: Concepts: matrices^Gauss-Seidel
3533: @*/
3534: PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3535: {
3545: if (!mat->ops->sor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3546: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3547: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3548: 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);
3549: 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);
3550: 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);
3551: if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
3552: if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
3553: if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");
3555: MatCheckPreallocated(mat,1);
3556: PetscLogEventBegin(MAT_SOR,mat,b,x,0);
3557: ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);
3558: PetscLogEventEnd(MAT_SOR,mat,b,x,0);
3559: PetscObjectStateIncrease((PetscObject)x);
3560: return(0);
3561: }
3565: /*
3566: Default matrix copy routine.
3567: */
3568: PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
3569: {
3570: PetscErrorCode ierr;
3571: PetscInt i,rstart = 0,rend = 0,nz;
3572: const PetscInt *cwork;
3573: const PetscScalar *vwork;
3576: if (B->assembled) {
3577: MatZeroEntries(B);
3578: }
3579: MatGetOwnershipRange(A,&rstart,&rend);
3580: for (i=rstart; i<rend; i++) {
3581: MatGetRow(A,i,&nz,&cwork,&vwork);
3582: MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);
3583: MatRestoreRow(A,i,&nz,&cwork,&vwork);
3584: }
3585: MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
3586: MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);
3587: PetscObjectStateIncrease((PetscObject)B);
3588: return(0);
3589: }
3593: /*@
3594: MatCopy - Copys a matrix to another matrix.
3596: Collective on Mat
3598: Input Parameters:
3599: + A - the matrix
3600: - str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
3602: Output Parameter:
3603: . B - where the copy is put
3605: Notes:
3606: If you use SAME_NONZERO_PATTERN then the two matrices had better have the
3607: same nonzero pattern or the routine will crash.
3609: MatCopy() copies the matrix entries of a matrix to another existing
3610: matrix (after first zeroing the second matrix). A related routine is
3611: MatConvert(), which first creates a new matrix and then copies the data.
3613: Level: intermediate
3614:
3615: Concepts: matrices^copying
3617: .seealso: MatConvert(), MatDuplicate()
3619: @*/
3620: PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str)
3621: {
3623: PetscInt i;
3631: MatCheckPreallocated(B,2);
3632: if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3633: if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3634: 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);
3635: MatCheckPreallocated(A,1);
3637: PetscLogEventBegin(MAT_Copy,A,B,0,0);
3638: if (A->ops->copy) {
3639: (*A->ops->copy)(A,B,str);
3640: } else { /* generic conversion */
3641: MatCopy_Basic(A,B,str);
3642: }
3644: B->stencil.dim = A->stencil.dim;
3645: B->stencil.noc = A->stencil.noc;
3646: for (i=0; i<=A->stencil.dim; i++) {
3647: B->stencil.dims[i] = A->stencil.dims[i];
3648: B->stencil.starts[i] = A->stencil.starts[i];
3649: }
3651: PetscLogEventEnd(MAT_Copy,A,B,0,0);
3652: PetscObjectStateIncrease((PetscObject)B);
3653: return(0);
3654: }
3658: /*@C
3659: MatConvert - Converts a matrix to another matrix, either of the same
3660: or different type.
3662: Collective on Mat
3664: Input Parameters:
3665: + mat - the matrix
3666: . newtype - new matrix type. Use MATSAME to create a new matrix of the
3667: same type as the original matrix.
3668: - reuse - denotes if the destination matrix is to be created or reused. Currently
3669: MAT_REUSE_MATRIX is only supported for inplace conversion, otherwise use
3670: MAT_INITIAL_MATRIX.
3672: Output Parameter:
3673: . M - pointer to place new matrix
3675: Notes:
3676: MatConvert() first creates a new matrix and then copies the data from
3677: the first matrix. A related routine is MatCopy(), which copies the matrix
3678: entries of one matrix to another already existing matrix context.
3680: Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
3681: the MPI communicator of the generated matrix is always the same as the communicator
3682: of the input matrix.
3684: Level: intermediate
3686: Concepts: matrices^converting between storage formats
3688: .seealso: MatCopy(), MatDuplicate()
3689: @*/
3690: PetscErrorCode MatConvert(Mat mat, const MatType newtype,MatReuse reuse,Mat *M)
3691: {
3692: PetscErrorCode ierr;
3693: PetscBool sametype,issame,flg;
3694: char convname[256],mtype[256];
3695: Mat B;
3701: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3702: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3703: MatCheckPreallocated(mat,1);
3704: MatSetOption(mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);
3706: PetscOptionsGetString(((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);
3707: if (flg) {
3708: newtype = mtype;
3709: }
3710: PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);
3711: PetscStrcmp(newtype,"same",&issame);
3712: if ((reuse == MAT_REUSE_MATRIX) && (mat != *M)) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"MAT_REUSE_MATRIX only supported for in-place conversion currently");
3714: if ((reuse == MAT_REUSE_MATRIX) && (issame || sametype)) return(0);
3715:
3716: if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
3717: (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);
3718: } else {
3719: PetscErrorCode (*conv)(Mat, const MatType,MatReuse,Mat*)=PETSC_NULL;
3720: const char *prefix[3] = {"seq","mpi",""};
3721: PetscInt i;
3722: /*
3723: Order of precedence:
3724: 1) See if a specialized converter is known to the current matrix.
3725: 2) See if a specialized converter is known to the desired matrix class.
3726: 3) See if a good general converter is registered for the desired class
3727: (as of 6/27/03 only MATMPIADJ falls into this category).
3728: 4) See if a good general converter is known for the current matrix.
3729: 5) Use a really basic converter.
3730: */
3731:
3732: /* 1) See if a specialized converter is known to the current matrix and the desired class */
3733: for (i=0; i<3; i++) {
3734: PetscStrcpy(convname,"MatConvert_");
3735: PetscStrcat(convname,((PetscObject)mat)->type_name);
3736: PetscStrcat(convname,"_");
3737: PetscStrcat(convname,prefix[i]);
3738: PetscStrcat(convname,issame?((PetscObject)mat)->type_name:newtype);
3739: PetscStrcat(convname,"_C");
3740: PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);
3741: if (conv) goto foundconv;
3742: }
3744: /* 2) See if a specialized converter is known to the desired matrix class. */
3745: MatCreate(((PetscObject)mat)->comm,&B);
3746: MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);
3747: MatSetType(B,newtype);
3748: for (i=0; i<3; i++) {
3749: PetscStrcpy(convname,"MatConvert_");
3750: PetscStrcat(convname,((PetscObject)mat)->type_name);
3751: PetscStrcat(convname,"_");
3752: PetscStrcat(convname,prefix[i]);
3753: PetscStrcat(convname,newtype);
3754: PetscStrcat(convname,"_C");
3755: PetscObjectQueryFunction((PetscObject)B,convname,(void (**)(void))&conv);
3756: if (conv) {
3757: MatDestroy(&B);
3758: goto foundconv;
3759: }
3760: }
3762: /* 3) See if a good general converter is registered for the desired class */
3763: conv = B->ops->convertfrom;
3764: MatDestroy(&B);
3765: if (conv) goto foundconv;
3767: /* 4) See if a good general converter is known for the current matrix */
3768: if (mat->ops->convert) {
3769: conv = mat->ops->convert;
3770: }
3771: if (conv) goto foundconv;
3773: /* 5) Use a really basic converter. */
3774: conv = MatConvert_Basic;
3776: foundconv:
3777: PetscLogEventBegin(MAT_Convert,mat,0,0,0);
3778: (*conv)(mat,newtype,reuse,M);
3779: PetscLogEventEnd(MAT_Convert,mat,0,0,0);
3780: }
3781: PetscObjectStateIncrease((PetscObject)*M);
3783: /* Copy Mat options */
3784: if (mat->symmetric){MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);}
3785: if (mat->hermitian){MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);}
3786: return(0);
3787: }
3791: /*@C
3792: MatFactorGetSolverPackage - Returns name of the package providing the factorization routines
3794: Not Collective
3796: Input Parameter:
3797: . mat - the matrix, must be a factored matrix
3799: Output Parameter:
3800: . type - the string name of the package (do not free this string)
3802: Notes:
3803: In Fortran you pass in a empty string and the package name will be copied into it.
3804: (Make sure the string is long enough)
3806: Level: intermediate
3808: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
3809: @*/
3810: PetscErrorCode MatFactorGetSolverPackage(Mat mat, const MatSolverPackage *type)
3811: {
3812: PetscErrorCode ierr;
3813: PetscErrorCode (*conv)(Mat,const MatSolverPackage*);
3818: if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
3819: PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverPackage_C",(void (**)(void))&conv);
3820: if (!conv) {
3821: *type = MATSOLVERPETSC;
3822: } else {
3823: (*conv)(mat,type);
3824: }
3825: return(0);
3826: }
3830: /*@C
3831: MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic()
3833: Collective on Mat
3835: Input Parameters:
3836: + mat - the matrix
3837: . type - name of solver type, for example, spooles, superlu, plapack, petsc (to use PETSc's default)
3838: - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
3840: Output Parameters:
3841: . f - the factor matrix used with MatXXFactorSymbolic() calls
3843: Notes:
3844: Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
3845: such as pastix, superlu, mumps, spooles etc.
3847: PETSc must have been ./configure to use the external solver, using the option --download-package
3849: Level: intermediate
3851: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
3852: @*/
3853: PetscErrorCode MatGetFactor(Mat mat, const MatSolverPackage type,MatFactorType ftype,Mat *f)
3854: {
3855: PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
3856: char convname[256];
3862: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3863: MatCheckPreallocated(mat,1);
3865: PetscStrcpy(convname,"MatGetFactor_");
3866: PetscStrcat(convname,type);
3867: PetscStrcat(convname,"_C");
3868: PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);
3869: if (!conv) {
3870: PetscBool flag;
3871: MPI_Comm comm;
3873: PetscObjectGetComm((PetscObject)mat,&comm);
3874: PetscStrcasecmp(MATSOLVERPETSC,type,&flag);
3875: if (flag) {
3876: SETERRQ2(comm,PETSC_ERR_SUP,"Matrix format %s does not have a built-in PETSc %s",((PetscObject)mat)->type_name,MatFactorTypes[ftype]);
3877: } else {
3878: 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);
3879: }
3880: }
3881: (*conv)(mat,ftype,f);
3882: return(0);
3883: }
3887: /*@C
3888: MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type
3890: Not Collective
3892: Input Parameters:
3893: + mat - the matrix
3894: . type - name of solver type, for example, spooles, superlu, plapack, petsc (to use PETSc's default)
3895: - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
3897: Output Parameter:
3898: . flg - PETSC_TRUE if the factorization is available
3900: Notes:
3901: Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
3902: such as pastix, superlu, mumps, spooles etc.
3904: PETSc must have been ./configure to use the external solver, using the option --download-package
3906: Level: intermediate
3908: .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
3909: @*/
3910: PetscErrorCode MatGetFactorAvailable(Mat mat, const MatSolverPackage type,MatFactorType ftype,PetscBool *flg)
3911: {
3912: PetscErrorCode ierr;
3913: char convname[256];
3914: PetscErrorCode (*conv)(Mat,MatFactorType,PetscBool *);
3920: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3921: MatCheckPreallocated(mat,1);
3923: PetscStrcpy(convname,"MatGetFactorAvailable_");
3924: PetscStrcat(convname,type);
3925: PetscStrcat(convname,"_C");
3926: PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);
3927: if (!conv) {
3928: *flg = PETSC_FALSE;
3929: } else {
3930: (*conv)(mat,ftype,flg);
3931: }
3932: return(0);
3933: }
3938: /*@
3939: MatDuplicate - Duplicates a matrix including the non-zero structure.
3941: Collective on Mat
3943: Input Parameters:
3944: + mat - the matrix
3945: - op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy the numerical values in the matrix
3946: MAT_SHARE_NONZERO_PATTERN to share the nonzero patterns with the previous matrix and not copy them.
3948: Output Parameter:
3949: . M - pointer to place new matrix
3951: Level: intermediate
3953: Concepts: matrices^duplicating
3955: Notes: You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN.
3957: .seealso: MatCopy(), MatConvert()
3958: @*/
3959: PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
3960: {
3962: Mat B;
3963: PetscInt i;
3969: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3970: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3971: MatCheckPreallocated(mat,1);
3973: *M = 0;
3974: if (!mat->ops->duplicate) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Not written for this matrix type");
3975: PetscLogEventBegin(MAT_Convert,mat,0,0,0);
3976: (*mat->ops->duplicate)(mat,op,M);
3977: B = *M;
3978:
3979: B->stencil.dim = mat->stencil.dim;
3980: B->stencil.noc = mat->stencil.noc;
3981: for (i=0; i<=mat->stencil.dim; i++) {
3982: B->stencil.dims[i] = mat->stencil.dims[i];
3983: B->stencil.starts[i] = mat->stencil.starts[i];
3984: }
3986: B->nooffproczerorows = mat->nooffproczerorows;
3987: B->nooffprocentries = mat->nooffprocentries;
3988: PetscLogEventEnd(MAT_Convert,mat,0,0,0);
3989: PetscObjectStateIncrease((PetscObject)B);
3990: return(0);
3991: }
3995: /*@
3996: MatGetDiagonal - Gets the diagonal of a matrix.
3998: Logically Collective on Mat and Vec
4000: Input Parameters:
4001: + mat - the matrix
4002: - v - the vector for storing the diagonal
4004: Output Parameter:
4005: . v - the diagonal of the matrix
4007: Level: intermediate
4009: Note:
4010: Currently only correct in parallel for square matrices.
4012: Concepts: matrices^accessing diagonals
4014: .seealso: MatGetRow(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs()
4015: @*/
4016: PetscErrorCode MatGetDiagonal(Mat mat,Vec v)
4017: {
4024: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4025: if (!mat->ops->getdiagonal) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4026: MatCheckPreallocated(mat,1);
4028: (*mat->ops->getdiagonal)(mat,v);
4029: PetscObjectStateIncrease((PetscObject)v);
4030: return(0);
4031: }
4035: /*@
4036: MatGetRowMin - Gets the minimum value (of the real part) of each
4037: row of the matrix
4039: Logically Collective on Mat and Vec
4041: Input Parameters:
4042: . mat - the matrix
4044: Output Parameter:
4045: + v - the vector for storing the maximums
4046: - idx - the indices of the column found for each row (optional)
4048: Level: intermediate
4050: Notes: The result of this call are the same as if one converted the matrix to dense format
4051: and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4053: This code is only implemented for a couple of matrix formats.
4055: Concepts: matrices^getting row maximums
4057: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(),
4058: MatGetRowMax()
4059: @*/
4060: PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4061: {
4068: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4069: if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4070: MatCheckPreallocated(mat,1);
4072: (*mat->ops->getrowmin)(mat,v,idx);
4073: PetscObjectStateIncrease((PetscObject)v);
4074: return(0);
4075: }
4079: /*@
4080: MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4081: row of the matrix
4083: Logically Collective on Mat and Vec
4085: Input Parameters:
4086: . mat - the matrix
4088: Output Parameter:
4089: + v - the vector for storing the minimums
4090: - idx - the indices of the column found for each row (or PETSC_NULL if not needed)
4092: Level: intermediate
4094: Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
4095: row is 0 (the first column).
4097: This code is only implemented for a couple of matrix formats.
4099: Concepts: matrices^getting row maximums
4101: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4102: @*/
4103: PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4104: {
4111: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4112: if (!mat->ops->getrowminabs) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4113: MatCheckPreallocated(mat,1);
4114: if (idx) {PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));}
4116: (*mat->ops->getrowminabs)(mat,v,idx);
4117: PetscObjectStateIncrease((PetscObject)v);
4118: return(0);
4119: }
4123: /*@
4124: MatGetRowMax - Gets the maximum value (of the real part) of each
4125: row of the matrix
4127: Logically Collective on Mat and Vec
4129: Input Parameters:
4130: . mat - the matrix
4132: Output Parameter:
4133: + v - the vector for storing the maximums
4134: - idx - the indices of the column found for each row (optional)
4136: Level: intermediate
4138: Notes: The result of this call are the same as if one converted the matrix to dense format
4139: and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4141: This code is only implemented for a couple of matrix formats.
4143: Concepts: matrices^getting row maximums
4145: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4146: @*/
4147: PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4148: {
4155: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4156: if (!mat->ops->getrowmax) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4157: MatCheckPreallocated(mat,1);
4159: (*mat->ops->getrowmax)(mat,v,idx);
4160: PetscObjectStateIncrease((PetscObject)v);
4161: return(0);
4162: }
4166: /*@
4167: MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4168: row of the matrix
4170: Logically Collective on Mat and Vec
4172: Input Parameters:
4173: . mat - the matrix
4175: Output Parameter:
4176: + v - the vector for storing the maximums
4177: - idx - the indices of the column found for each row (or PETSC_NULL if not needed)
4179: Level: intermediate
4181: Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
4182: row is 0 (the first column).
4184: This code is only implemented for a couple of matrix formats.
4186: Concepts: matrices^getting row maximums
4188: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4189: @*/
4190: PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4191: {
4198: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4199: if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4200: MatCheckPreallocated(mat,1);
4201: if (idx) {PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));}
4203: (*mat->ops->getrowmaxabs)(mat,v,idx);
4204: PetscObjectStateIncrease((PetscObject)v);
4205: return(0);
4206: }
4210: /*@
4211: MatGetRowSum - Gets the sum of each row of the matrix
4213: Logically Collective on Mat and Vec
4215: Input Parameters:
4216: . mat - the matrix
4218: Output Parameter:
4219: . v - the vector for storing the sum of rows
4221: Level: intermediate
4223: Notes: This code is slow since it is not currently specialized for different formats
4225: Concepts: matrices^getting row sums
4227: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4228: @*/
4229: PetscErrorCode MatGetRowSum(Mat mat, Vec v)
4230: {
4231: PetscInt start = 0, end = 0, row;
4232: PetscScalar *array;
4239: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4240: MatCheckPreallocated(mat,1);
4241: MatGetOwnershipRange(mat, &start, &end);
4242: VecGetArray(v, &array);
4243: for(row = start; row < end; ++row) {
4244: PetscInt ncols, col;
4245: const PetscInt *cols;
4246: const PetscScalar *vals;
4248: array[row - start] = 0.0;
4249: MatGetRow(mat, row, &ncols, &cols, &vals);
4250: for(col = 0; col < ncols; col++) {
4251: array[row - start] += vals[col];
4252: }
4253: MatRestoreRow(mat, row, &ncols, &cols, &vals);
4254: }
4255: VecRestoreArray(v, &array);
4256: PetscObjectStateIncrease((PetscObject) v);
4257: return(0);
4258: }
4262: /*@
4263: MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
4265: Collective on Mat
4267: Input Parameter:
4268: + mat - the matrix to transpose
4269: - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
4271: Output Parameters:
4272: . B - the transpose
4274: Notes:
4275: If you pass in &mat for B the transpose will be done in place, for example MatTranspose(mat,MAT_REUSE_MATRIX,&mat);
4277: Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed.
4279: Level: intermediate
4281: Concepts: matrices^transposing
4283: .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4284: @*/
4285: PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4286: {
4292: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4293: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4294: if (!mat->ops->transpose) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4295: MatCheckPreallocated(mat,1);
4297: PetscLogEventBegin(MAT_Transpose,mat,0,0,0);
4298: (*mat->ops->transpose)(mat,reuse,B);
4299: PetscLogEventEnd(MAT_Transpose,mat,0,0,0);
4300: if (B) {PetscObjectStateIncrease((PetscObject)*B);}
4301: return(0);
4302: }
4306: /*@
4307: MatIsTranspose - Test whether a matrix is another one's transpose,
4308: or its own, in which case it tests symmetry.
4310: Collective on Mat
4312: Input Parameter:
4313: + A - the matrix to test
4314: - B - the matrix to test against, this can equal the first parameter
4316: Output Parameters:
4317: . flg - the result
4319: Notes:
4320: Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4321: has a running time of the order of the number of nonzeros; the parallel
4322: test involves parallel copies of the block-offdiagonal parts of the matrix.
4324: Level: intermediate
4326: Concepts: matrices^transposing, matrix^symmetry
4328: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4329: @*/
4330: PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg)
4331: {
4332: PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool *),(*g)(Mat,Mat,PetscReal,PetscBool *);
4338: PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",(void (**)(void))&f);
4339: PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",(void (**)(void))&g);
4340: *flg = PETSC_FALSE;
4341: if (f && g) {
4342: if (f == g) {
4343: (*f)(A,B,tol,flg);
4344: } else {
4345: SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4346: }
4347: } else {
4348: const MatType mattype;
4349: if (!f) {MatGetType(A,&mattype);}
4350: else {MatGetType(B,&mattype);}
4351: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
4352: }
4353: return(0);
4354: }
4358: /*@
4359: MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate.
4361: Collective on Mat
4363: Input Parameter:
4364: + mat - the matrix to transpose and complex conjugate
4365: - reuse - store the transpose matrix in the provided B
4367: Output Parameters:
4368: . B - the Hermitian
4370: Notes:
4371: If you pass in &mat for B the Hermitian will be done in place
4373: Level: intermediate
4375: Concepts: matrices^transposing, complex conjugatex
4377: .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4378: @*/
4379: PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
4380: {
4384: MatTranspose(mat,reuse,B);
4385: #if defined(PETSC_USE_COMPLEX)
4386: MatConjugate(*B);
4387: #endif
4388: return(0);
4389: }
4393: /*@
4394: MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,
4396: Collective on Mat
4398: Input Parameter:
4399: + A - the matrix to test
4400: - B - the matrix to test against, this can equal the first parameter
4402: Output Parameters:
4403: . flg - the result
4405: Notes:
4406: Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4407: has a running time of the order of the number of nonzeros; the parallel
4408: test involves parallel copies of the block-offdiagonal parts of the matrix.
4410: Level: intermediate
4412: Concepts: matrices^transposing, matrix^symmetry
4414: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
4415: @*/
4416: PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg)
4417: {
4418: PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool *),(*g)(Mat,Mat,PetscReal,PetscBool *);
4424: PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",(void (**)(void))&f);
4425: PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",(void (**)(void))&g);
4426: if (f && g) {
4427: if (f==g) {
4428: (*f)(A,B,tol,flg);
4429: } else {
4430: SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
4431: }
4432: }
4433: return(0);
4434: }
4438: /*@
4439: MatPermute - Creates a new matrix with rows and columns permuted from the
4440: original.
4442: Collective on Mat
4444: Input Parameters:
4445: + mat - the matrix to permute
4446: . row - row permutation, each processor supplies only the permutation for its rows
4447: - col - column permutation, each processor needs the entire column permutation, that is
4448: this is the same size as the total number of columns in the matrix. It can often
4449: be obtained with ISAllGather() on the row permutation
4451: Output Parameters:
4452: . B - the permuted matrix
4454: Level: advanced
4456: Concepts: matrices^permuting
4458: .seealso: MatGetOrdering(), ISAllGather()
4460: @*/
4461: PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
4462: {
4471: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4472: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4473: if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
4474: MatCheckPreallocated(mat,1);
4476: (*mat->ops->permute)(mat,row,col,B);
4477: PetscObjectStateIncrease((PetscObject)*B);
4478: return(0);
4479: }
4483: /*@
4484: MatEqual - Compares two matrices.
4486: Collective on Mat
4488: Input Parameters:
4489: + A - the first matrix
4490: - B - the second matrix
4492: Output Parameter:
4493: . flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
4495: Level: intermediate
4497: Concepts: matrices^equality between
4498: @*/
4499: PetscErrorCode MatEqual(Mat A,Mat B,PetscBool *flg)
4500: {
4510: MatCheckPreallocated(B,2);
4511: if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4512: if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4513: 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);
4514: if (!A->ops->equal) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4515: if (!B->ops->equal) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4516: 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);
4517: MatCheckPreallocated(A,1);
4519: (*A->ops->equal)(A,B,flg);
4520: return(0);
4521: }
4525: /*@
4526: MatDiagonalScale - Scales a matrix on the left and right by diagonal
4527: matrices that are stored as vectors. Either of the two scaling
4528: matrices can be PETSC_NULL.
4530: Collective on Mat
4532: Input Parameters:
4533: + mat - the matrix to be scaled
4534: . l - the left scaling vector (or PETSC_NULL)
4535: - r - the right scaling vector (or PETSC_NULL)
4537: Notes:
4538: MatDiagonalScale() computes A = LAR, where
4539: L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
4540: The L scales the rows of the matrix, the R scales the columns of the matrix.
4542: Level: intermediate
4544: Concepts: matrices^diagonal scaling
4545: Concepts: diagonal scaling of matrices
4547: .seealso: MatScale()
4548: @*/
4549: PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
4550: {
4556: if (!mat->ops->diagonalscale) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4559: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4560: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4561: MatCheckPreallocated(mat,1);
4563: PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4564: (*mat->ops->diagonalscale)(mat,l,r);
4565: PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4566: PetscObjectStateIncrease((PetscObject)mat);
4567: #if defined(PETSC_HAVE_CUSP)
4568: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4569: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4570: }
4571: #endif
4572: return(0);
4573: }
4577: /*@
4578: MatScale - Scales all elements of a matrix by a given number.
4580: Logically Collective on Mat
4582: Input Parameters:
4583: + mat - the matrix to be scaled
4584: - a - the scaling value
4586: Output Parameter:
4587: . mat - the scaled matrix
4589: Level: intermediate
4591: Concepts: matrices^scaling all entries
4593: .seealso: MatDiagonalScale()
4594: @*/
4595: PetscErrorCode MatScale(Mat mat,PetscScalar a)
4596: {
4602: if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4603: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4604: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4606: MatCheckPreallocated(mat,1);
4608: PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4609: if (a != (PetscScalar)1.0) {
4610: (*mat->ops->scale)(mat,a);
4611: PetscObjectStateIncrease((PetscObject)mat);
4612: }
4613: PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4614: #if defined(PETSC_HAVE_CUSP)
4615: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4616: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4617: }
4618: #endif
4619: return(0);
4620: }
4624: /*@
4625: MatNorm - Calculates various norms of a matrix.
4627: Collective on Mat
4629: Input Parameters:
4630: + mat - the matrix
4631: - type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
4633: Output Parameters:
4634: . nrm - the resulting norm
4636: Level: intermediate
4638: Concepts: matrices^norm
4639: Concepts: norm^of matrix
4640: @*/
4641: PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
4642: {
4650: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4651: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4652: if (!mat->ops->norm) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4653: MatCheckPreallocated(mat,1);
4655: (*mat->ops->norm)(mat,type,nrm);
4656: return(0);
4657: }
4659: /*
4660: This variable is used to prevent counting of MatAssemblyBegin() that
4661: are called from within a MatAssemblyEnd().
4662: */
4663: static PetscInt MatAssemblyEnd_InUse = 0;
4666: /*@
4667: MatAssemblyBegin - Begins assembling the matrix. This routine should
4668: be called after completing all calls to MatSetValues().
4670: Collective on Mat
4672: Input Parameters:
4673: + mat - the matrix
4674: - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
4675:
4676: Notes:
4677: MatSetValues() generally caches the values. The matrix is ready to
4678: use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4679: Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4680: in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4681: using the matrix.
4683: Level: beginner
4685: Concepts: matrices^assembling
4687: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
4688: @*/
4689: PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
4690: {
4696: MatCheckPreallocated(mat,1);
4697: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
4698: if (mat->assembled) {
4699: mat->was_assembled = PETSC_TRUE;
4700: mat->assembled = PETSC_FALSE;
4701: }
4702: if (!MatAssemblyEnd_InUse) {
4703: PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);
4704: if (mat->ops->assemblybegin){(*mat->ops->assemblybegin)(mat,type);}
4705: PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);
4706: } else {
4707: if (mat->ops->assemblybegin){(*mat->ops->assemblybegin)(mat,type);}
4708: }
4709: return(0);
4710: }
4714: /*@
4715: MatAssembled - Indicates if a matrix has been assembled and is ready for
4716: use; for example, in matrix-vector product.
4718: Not Collective
4720: Input Parameter:
4721: . mat - the matrix
4723: Output Parameter:
4724: . assembled - PETSC_TRUE or PETSC_FALSE
4726: Level: advanced
4728: Concepts: matrices^assembled?
4730: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
4731: @*/
4732: PetscErrorCode MatAssembled(Mat mat,PetscBool *assembled)
4733: {
4738: *assembled = mat->assembled;
4739: return(0);
4740: }
4744: /*
4745: Processes command line options to determine if/how a matrix
4746: is to be viewed. Called by MatAssemblyEnd() and MatLoad().
4747: */
4748: PetscErrorCode MatView_Private(Mat mat)
4749: {
4750: PetscErrorCode ierr;
4751: PetscBool flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE,flg4 = PETSC_FALSE,flg6 = PETSC_FALSE,flg7 = PETSC_FALSE,flg8 = PETSC_FALSE;
4752: static PetscBool incall = PETSC_FALSE;
4753: #if defined(PETSC_USE_SOCKET_VIEWER)
4754: PetscBool flg5 = PETSC_FALSE;
4755: #endif
4758: if (incall) return(0);
4759: incall = PETSC_TRUE;
4760: PetscObjectOptionsBegin((PetscObject)mat);
4761: PetscOptionsBool("-mat_view_info","Information on matrix size","MatView",flg1,&flg1,PETSC_NULL);
4762: PetscOptionsBool("-mat_view_info_detailed","Nonzeros in the matrix","MatView",flg2,&flg2,PETSC_NULL);
4763: PetscOptionsBool("-mat_view","Print matrix to stdout","MatView",flg3,&flg3,PETSC_NULL);
4764: PetscOptionsBool("-mat_view_matlab","Print matrix to stdout in a format Matlab can read","MatView",flg4,&flg4,PETSC_NULL);
4765: #if defined(PETSC_USE_SOCKET_VIEWER)
4766: PetscOptionsBool("-mat_view_socket","Send matrix to socket (can be read from matlab)","MatView",flg5,&flg5,PETSC_NULL);
4767: #endif
4768: PetscOptionsBool("-mat_view_binary","Save matrix to file in binary format","MatView",flg6,&flg6,PETSC_NULL);
4769: PetscOptionsBool("-mat_view_draw","Draw the matrix nonzero structure","MatView",flg7,&flg7,PETSC_NULL);
4770: PetscOptionsEnd();
4772: if (flg1) {
4773: PetscViewer viewer;
4775: PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4776: PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO);
4777: MatView(mat,viewer);
4778: PetscViewerPopFormat(viewer);
4779: }
4780: if (flg2) {
4781: PetscViewer viewer;
4783: PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4784: PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO_DETAIL);
4785: MatView(mat,viewer);
4786: PetscViewerPopFormat(viewer);
4787: }
4788: if (flg3) {
4789: PetscViewer viewer;
4791: PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4792: MatView(mat,viewer);
4793: }
4794: if (flg4) {
4795: PetscViewer viewer;
4797: PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4798: PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);
4799: MatView(mat,viewer);
4800: PetscViewerPopFormat(viewer);
4801: }
4802: #if defined(PETSC_USE_SOCKET_VIEWER)
4803: if (flg5) {
4804: MatView(mat,PETSC_VIEWER_SOCKET_(((PetscObject)mat)->comm));
4805: PetscViewerFlush(PETSC_VIEWER_SOCKET_(((PetscObject)mat)->comm));
4806: }
4807: #endif
4808: if (flg6) {
4809: MatView(mat,PETSC_VIEWER_BINARY_(((PetscObject)mat)->comm));
4810: PetscViewerFlush(PETSC_VIEWER_BINARY_(((PetscObject)mat)->comm));
4811: }
4812: if (flg7) {
4813: PetscOptionsGetBool(((PetscObject)mat)->prefix,"-mat_view_contour",&flg8,PETSC_NULL);
4814: if (flg8) {
4815: PetscViewerPushFormat(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm),PETSC_VIEWER_DRAW_CONTOUR);
4816: }
4817: MatView(mat,PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));
4818: PetscViewerFlush(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));
4819: if (flg8) {
4820: PetscViewerPopFormat(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));
4821: }
4822: }
4823: incall = PETSC_FALSE;
4824: return(0);
4825: }
4829: /*@
4830: MatAssemblyEnd - Completes assembling the matrix. This routine should
4831: be called after MatAssemblyBegin().
4833: Collective on Mat
4835: Input Parameters:
4836: + mat - the matrix
4837: - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
4839: Options Database Keys:
4840: + -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly()
4841: . -mat_view_info_detailed - Prints more detailed info
4842: . -mat_view - Prints matrix in ASCII format
4843: . -mat_view_matlab - Prints matrix in Matlab format
4844: . -mat_view_draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
4845: . -display <name> - Sets display name (default is host)
4846: . -draw_pause <sec> - Sets number of seconds to pause after display
4847: . -mat_view_socket - Sends matrix to socket, can be accessed from Matlab (See the <a href="../../docs/manual.pdf">users manual</a>)
4848: . -viewer_socket_machine <machine>
4849: . -viewer_socket_port <port>
4850: . -mat_view_binary - save matrix to file in binary format
4851: - -viewer_binary_filename <name>
4853: Notes:
4854: MatSetValues() generally caches the values. The matrix is ready to
4855: use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4856: Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4857: in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4858: using the matrix.
4860: Level: beginner
4862: .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), MatView(), MatAssembled(), PetscViewerSocketOpen()
4863: @*/
4864: PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
4865: {
4866: PetscErrorCode ierr;
4867: static PetscInt inassm = 0;
4868: PetscBool flg = PETSC_FALSE;
4874: inassm++;
4875: MatAssemblyEnd_InUse++;
4876: if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
4877: PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);
4878: if (mat->ops->assemblyend) {
4879: (*mat->ops->assemblyend)(mat,type);
4880: }
4881: PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);
4882: } else {
4883: if (mat->ops->assemblyend) {
4884: (*mat->ops->assemblyend)(mat,type);
4885: }
4886: }
4888: /* Flush assembly is not a true assembly */
4889: if (type != MAT_FLUSH_ASSEMBLY) {
4890: mat->assembled = PETSC_TRUE; mat->num_ass++;
4891: }
4892: mat->insertmode = NOT_SET_VALUES;
4893: MatAssemblyEnd_InUse--;
4894: PetscObjectStateIncrease((PetscObject)mat);
4895: if (!mat->symmetric_eternal) {
4896: mat->symmetric_set = PETSC_FALSE;
4897: mat->hermitian_set = PETSC_FALSE;
4898: mat->structurally_symmetric_set = PETSC_FALSE;
4899: }
4900: #if defined(PETSC_HAVE_CUSP)
4901: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4902: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4903: }
4904: #endif
4905: if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
4906: MatView_Private(mat);
4907: PetscOptionsHasName(((PetscObject)mat)->prefix,"-mat_is_symmetric",&flg);
4908: if (flg) {
4909: PetscReal tol = 0.0;
4910: PetscOptionsGetReal(((PetscObject)mat)->prefix,"-mat_is_symmetric",&tol,PETSC_NULL);
4911: MatIsSymmetric(mat,tol,&flg);
4912: if (flg) {
4913: PetscPrintf(((PetscObject)mat)->comm,"Matrix is symmetric (tolerance %G)\n",tol);
4914: } else {
4915: PetscPrintf(((PetscObject)mat)->comm,"Matrix is not symmetric (tolerance %G)\n",tol);
4916: }
4917: }
4918: }
4919: inassm--;
4920: return(0);
4921: }
4925: /*@
4926: MatSetOption - Sets a parameter option for a matrix. Some options
4927: may be specific to certain storage formats. Some options
4928: determine how values will be inserted (or added). Sorted,
4929: row-oriented input will generally assemble the fastest. The default
4930: is row-oriented.
4932: Logically Collective on Mat
4934: Input Parameters:
4935: + mat - the matrix
4936: . option - the option, one of those listed below (and possibly others),
4937: - flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
4939: Options Describing Matrix Structure:
4940: + MAT_SPD - symmetric positive definite
4941: - MAT_SYMMETRIC - symmetric in terms of both structure and value
4942: . MAT_HERMITIAN - transpose is the complex conjugation
4943: . MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
4944: - MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
4945: you set to be kept with all future use of the matrix
4946: including after MatAssemblyBegin/End() which could
4947: potentially change the symmetry structure, i.e. you
4948: KNOW the matrix will ALWAYS have the property you set.
4951: Options For Use with MatSetValues():
4952: Insert a logically dense subblock, which can be
4953: . MAT_ROW_ORIENTED - row-oriented (default)
4955: Note these options reflect the data you pass in with MatSetValues(); it has
4956: nothing to do with how the data is stored internally in the matrix
4957: data structure.
4959: When (re)assembling a matrix, we can restrict the input for
4960: efficiency/debugging purposes. These options include
4961: + MAT_NEW_NONZERO_LOCATIONS - additional insertions will be
4962: allowed if they generate a new nonzero
4963: . MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
4964: . MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
4965: . MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
4966: . MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
4967: + MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
4968: any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
4969: performance for very large process counts.
4971: Notes:
4972: Some options are relevant only for particular matrix types and
4973: are thus ignored by others. Other options are not supported by
4974: certain matrix types and will generate an error message if set.
4976: If using a Fortran 77 module to compute a matrix, one may need to
4977: use the column-oriented option (or convert to the row-oriented
4978: format).
4980: MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
4981: that would generate a new entry in the nonzero structure is instead
4982: ignored. Thus, if memory has not alredy been allocated for this particular
4983: data, then the insertion is ignored. For dense matrices, in which
4984: the entire array is allocated, no entries are ever ignored.
4985: Set after the first MatAssemblyEnd()
4987: MAT_NEW_NONZERO_LOCATION_ERR indicates that any add or insertion
4988: that would generate a new entry in the nonzero structure instead produces
4989: an error. (Currently supported for AIJ and BAIJ formats only.)
4990: This is a useful flag when using SAME_NONZERO_PATTERN in calling
4991: KSPSetOperators() to ensure that the nonzero pattern truely does
4992: remain unchanged. Set after the first MatAssemblyEnd()
4994: MAT_NEW_NONZERO_ALLOCATION_ERR indicates that any add or insertion
4995: that would generate a new entry that has not been preallocated will
4996: instead produce an error. (Currently supported for AIJ and BAIJ formats
4997: only.) This is a useful flag when debugging matrix memory preallocation.
4999: MAT_IGNORE_OFF_PROC_ENTRIES indicates entries destined for
5000: other processors should be dropped, rather than stashed.
5001: This is useful if you know that the "owning" processor is also
5002: always generating the correct matrix entries, so that PETSc need
5003: not transfer duplicate entries generated on another processor.
5004:
5005: MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5006: searches during matrix assembly. When this flag is set, the hash table
5007: is created during the first Matrix Assembly. This hash table is
5008: used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5009: to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5010: should be used with MAT_USE_HASH_TABLE flag. This option is currently
5011: supported by MATMPIBAIJ format only.
5013: MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries
5014: are kept in the nonzero structure
5016: MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
5017: a zero location in the matrix
5019: MAT_USE_INODES - indicates using inode version of the code - works with AIJ and
5020: ROWBS matrix types
5022: MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the
5023: zero row routines and thus improves performance for very large process counts.
5025: MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular
5026: part of the matrix (since they should match the upper triangular part).
5028: Notes: Can only be called after MatSetSizes() and MatSetType() have been set.
5030: Level: intermediate
5032: Concepts: matrices^setting options
5034: @*/
5035: PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg)
5036: {
5045: 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);
5046: 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()");
5048: switch (op) {
5049: case MAT_NO_OFF_PROC_ENTRIES:
5050: mat->nooffprocentries = flg;
5051: return(0);
5052: break;
5053: case MAT_NO_OFF_PROC_ZERO_ROWS:
5054: mat->nooffproczerorows = flg;
5055: return(0);
5056: break;
5057: case MAT_SPD:
5058: mat->spd_set = PETSC_TRUE;
5059: mat->spd = flg;
5060: if (flg) {
5061: mat->symmetric = PETSC_TRUE;
5062: mat->structurally_symmetric = PETSC_TRUE;
5063: mat->symmetric_set = PETSC_TRUE;
5064: mat->structurally_symmetric_set = PETSC_TRUE;
5065: }
5066: break;
5067: case MAT_SYMMETRIC:
5068: mat->symmetric = flg;
5069: if (flg) mat->structurally_symmetric = PETSC_TRUE;
5070: mat->symmetric_set = PETSC_TRUE;
5071: mat->structurally_symmetric_set = flg;
5072: break;
5073: case MAT_HERMITIAN:
5074: mat->hermitian = flg;
5075: if (flg) mat->structurally_symmetric = PETSC_TRUE;
5076: mat->hermitian_set = PETSC_TRUE;
5077: mat->structurally_symmetric_set = flg;
5078: break;
5079: case MAT_STRUCTURALLY_SYMMETRIC:
5080: mat->structurally_symmetric = flg;
5081: mat->structurally_symmetric_set = PETSC_TRUE;
5082: break;
5083: case MAT_SYMMETRY_ETERNAL:
5084: mat->symmetric_eternal = flg;
5085: break;
5086: default:
5087: break;
5088: }
5089: if (mat->ops->setoption) {
5090: (*mat->ops->setoption)(mat,op,flg);
5091: }
5092: return(0);
5093: }
5097: /*@
5098: MatZeroEntries - Zeros all entries of a matrix. For sparse matrices
5099: this routine retains the old nonzero structure.
5101: Logically Collective on Mat
5103: Input Parameters:
5104: . mat - the matrix
5106: Level: intermediate
5108: 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.
5109: See the Performance chapter of the users manual for information on preallocating matrices.
5111: Concepts: matrices^zeroing
5113: .seealso: MatZeroRows()
5114: @*/
5115: PetscErrorCode MatZeroEntries(Mat mat)
5116: {
5122: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5123: 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");
5124: if (!mat->ops->zeroentries) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5125: MatCheckPreallocated(mat,1);
5127: PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);
5128: (*mat->ops->zeroentries)(mat);
5129: PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);
5130: PetscObjectStateIncrease((PetscObject)mat);
5131: #if defined(PETSC_HAVE_CUSP)
5132: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5133: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5134: }
5135: #endif
5136: return(0);
5137: }
5141: /*@C
5142: MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal)
5143: of a set of rows and columns of a matrix.
5145: Collective on Mat
5147: Input Parameters:
5148: + mat - the matrix
5149: . numRows - the number of rows to remove
5150: . rows - the global row indices
5151: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5152: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5153: - b - optional vector of right hand side, that will be adjusted by provided solution
5155: Notes:
5156: This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5158: The user can set a value in the diagonal entry (or for the AIJ and
5159: row formats can optionally remove the main diagonal entry from the
5160: nonzero structure as well, by passing 0.0 as the final argument).
5162: For the parallel case, all processes that share the matrix (i.e.,
5163: those in the communicator used for matrix creation) MUST call this
5164: routine, regardless of whether any rows being zeroed are owned by
5165: them.
5167: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5168: list only rows local to itself).
5170: The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5172: Level: intermediate
5174: Concepts: matrices^zeroing rows
5176: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumnsIS()
5177: @*/
5178: PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5179: {
5186: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5187: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5188: if (!mat->ops->zerorowscolumns) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5189: MatCheckPreallocated(mat,1);
5191: (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);
5192: MatView_Private(mat);
5193: PetscObjectStateIncrease((PetscObject)mat);
5194: #if defined(PETSC_HAVE_CUSP)
5195: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5196: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5197: }
5198: #endif
5199: return(0);
5200: }
5204: /*@C
5205: MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
5206: of a set of rows and columns of a matrix.
5208: Collective on Mat
5210: Input Parameters:
5211: + mat - the matrix
5212: . is - the rows to zero
5213: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5214: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5215: - b - optional vector of right hand side, that will be adjusted by provided solution
5217: Notes:
5218: This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5220: The user can set a value in the diagonal entry (or for the AIJ and
5221: row formats can optionally remove the main diagonal entry from the
5222: nonzero structure as well, by passing 0.0 as the final argument).
5224: For the parallel case, all processes that share the matrix (i.e.,
5225: those in the communicator used for matrix creation) MUST call this
5226: routine, regardless of whether any rows being zeroed are owned by
5227: them.
5229: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5230: list only rows local to itself).
5232: The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5234: Level: intermediate
5236: Concepts: matrices^zeroing rows
5238: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumns()
5239: @*/
5240: PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5241: {
5243: PetscInt numRows;
5244: const PetscInt *rows;
5251: ISGetLocalSize(is,&numRows);
5252: ISGetIndices(is,&rows);
5253: MatZeroRowsColumns(mat,numRows,rows,diag,x,b);
5254: ISRestoreIndices(is,&rows);
5255: return(0);
5256: }
5260: /*@C
5261: MatZeroRows - Zeros all entries (except possibly the main diagonal)
5262: of a set of rows of a matrix.
5264: Collective on Mat
5266: Input Parameters:
5267: + mat - the matrix
5268: . numRows - the number of rows to remove
5269: . rows - the global row indices
5270: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5271: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5272: - b - optional vector of right hand side, that will be adjusted by provided solution
5274: Notes:
5275: For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5276: but does not release memory. For the dense and block diagonal
5277: formats this does not alter the nonzero structure.
5279: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5280: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5281: merely zeroed.
5283: The user can set a value in the diagonal entry (or for the AIJ and
5284: row formats can optionally remove the main diagonal entry from the
5285: nonzero structure as well, by passing 0.0 as the final argument).
5287: For the parallel case, all processes that share the matrix (i.e.,
5288: those in the communicator used for matrix creation) MUST call this
5289: routine, regardless of whether any rows being zeroed are owned by
5290: them.
5292: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5293: list only rows local to itself).
5295: You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5296: owns that are to be zeroed. This saves a global synchronization in the implementation.
5298: Level: intermediate
5300: Concepts: matrices^zeroing rows
5302: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5303: @*/
5304: PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5305: {
5312: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5313: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5314: if (!mat->ops->zerorows) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5315: MatCheckPreallocated(mat,1);
5317: (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);
5318: MatView_Private(mat);
5319: PetscObjectStateIncrease((PetscObject)mat);
5320: #if defined(PETSC_HAVE_CUSP)
5321: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5322: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5323: }
5324: #endif
5325: return(0);
5326: }
5330: /*@C
5331: MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5332: of a set of rows of a matrix.
5334: Collective on Mat
5336: Input Parameters:
5337: + mat - the matrix
5338: . is - index set of rows to remove
5339: . diag - value put in all diagonals of eliminated rows
5340: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5341: - b - optional vector of right hand side, that will be adjusted by provided solution
5343: Notes:
5344: For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5345: but does not release memory. For the dense and block diagonal
5346: formats this does not alter the nonzero structure.
5348: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5349: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5350: merely zeroed.
5352: The user can set a value in the diagonal entry (or for the AIJ and
5353: row formats can optionally remove the main diagonal entry from the
5354: nonzero structure as well, by passing 0.0 as the final argument).
5356: For the parallel case, all processes that share the matrix (i.e.,
5357: those in the communicator used for matrix creation) MUST call this
5358: routine, regardless of whether any rows being zeroed are owned by
5359: them.
5361: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5362: list only rows local to itself).
5364: You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5365: owns that are to be zeroed. This saves a global synchronization in the implementation.
5367: Level: intermediate
5369: Concepts: matrices^zeroing rows
5371: .seealso: MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5372: @*/
5373: PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5374: {
5375: PetscInt numRows;
5376: const PetscInt *rows;
5383: ISGetLocalSize(is,&numRows);
5384: ISGetIndices(is,&rows);
5385: MatZeroRows(mat,numRows,rows,diag,x,b);
5386: ISRestoreIndices(is,&rows);
5387: return(0);
5388: }
5392: /*@C
5393: MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
5394: of a set of rows of a matrix. These rows must be local to the process.
5396: Collective on Mat
5398: Input Parameters:
5399: + mat - the matrix
5400: . numRows - the number of rows to remove
5401: . rows - the grid coordinates (and component number when dof > 1) for matrix rows
5402: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5403: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5404: - b - optional vector of right hand side, that will be adjusted by provided solution
5406: Notes:
5407: For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5408: but does not release memory. For the dense and block diagonal
5409: formats this does not alter the nonzero structure.
5411: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5412: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5413: merely zeroed.
5415: The user can set a value in the diagonal entry (or for the AIJ and
5416: row formats can optionally remove the main diagonal entry from the
5417: nonzero structure as well, by passing 0.0 as the final argument).
5419: For the parallel case, all processes that share the matrix (i.e.,
5420: those in the communicator used for matrix creation) MUST call this
5421: routine, regardless of whether any rows being zeroed are owned by
5422: them.
5424: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5425: list only rows local to itself).
5427: The grid coordinates are across the entire grid, not just the local portion
5429: In Fortran idxm and idxn should be declared as
5430: $ MatStencil idxm(4,m)
5431: and the values inserted using
5432: $ idxm(MatStencil_i,1) = i
5433: $ idxm(MatStencil_j,1) = j
5434: $ idxm(MatStencil_k,1) = k
5435: $ idxm(MatStencil_c,1) = c
5436: etc
5438: For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5439: obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5440: etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5441: DMDA_BOUNDARY_PERIODIC boundary type.
5443: 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
5444: a single value per point) you can skip filling those indices.
5446: Level: intermediate
5448: Concepts: matrices^zeroing rows
5450: .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5451: @*/
5452: PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5453: {
5454: PetscInt dim = mat->stencil.dim;
5455: PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc);
5456: PetscInt *dims = mat->stencil.dims+1;
5457: PetscInt *starts = mat->stencil.starts;
5458: PetscInt *dxm = (PetscInt *) rows;
5459: PetscInt *jdxm, i, j, tmp, numNewRows = 0;
5467: PetscMalloc(numRows*sizeof(PetscInt), &jdxm);
5468: for(i = 0; i < numRows; ++i) {
5469: /* Skip unused dimensions (they are ordered k, j, i, c) */
5470: for(j = 0; j < 3-sdim; ++j) dxm++;
5471: /* Local index in X dir */
5472: tmp = *dxm++ - starts[0];
5473: /* Loop over remaining dimensions */
5474: for(j = 0; j < dim-1; ++j) {
5475: /* If nonlocal, set index to be negative */
5476: if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5477: /* Update local index */
5478: else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5479: }
5480: /* Skip component slot if necessary */
5481: if (mat->stencil.noc) dxm++;
5482: /* Local row number */
5483: if (tmp >= 0) {
5484: jdxm[numNewRows++] = tmp;
5485: }
5486: }
5487: MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);
5488: PetscFree(jdxm);
5489: return(0);
5490: }
5494: /*@C
5495: MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal)
5496: of a set of rows and columns of a matrix.
5498: Collective on Mat
5500: Input Parameters:
5501: + mat - the matrix
5502: . numRows - the number of rows/columns to remove
5503: . rows - the grid coordinates (and component number when dof > 1) for matrix rows
5504: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5505: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5506: - b - optional vector of right hand side, that will be adjusted by provided solution
5508: Notes:
5509: For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5510: but does not release memory. For the dense and block diagonal
5511: formats this does not alter the nonzero structure.
5513: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5514: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5515: merely zeroed.
5517: The user can set a value in the diagonal entry (or for the AIJ and
5518: row formats can optionally remove the main diagonal entry from the
5519: nonzero structure as well, by passing 0.0 as the final argument).
5521: For the parallel case, all processes that share the matrix (i.e.,
5522: those in the communicator used for matrix creation) MUST call this
5523: routine, regardless of whether any rows being zeroed are owned by
5524: them.
5526: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5527: list only rows local to itself, but the row/column numbers are given in local numbering).
5529: The grid coordinates are across the entire grid, not just the local portion
5531: In Fortran idxm and idxn should be declared as
5532: $ MatStencil idxm(4,m)
5533: and the values inserted using
5534: $ idxm(MatStencil_i,1) = i
5535: $ idxm(MatStencil_j,1) = j
5536: $ idxm(MatStencil_k,1) = k
5537: $ idxm(MatStencil_c,1) = c
5538: etc
5540: For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5541: obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5542: etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5543: DMDA_BOUNDARY_PERIODIC boundary type.
5545: 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
5546: a single value per point) you can skip filling those indices.
5548: Level: intermediate
5550: Concepts: matrices^zeroing rows
5552: .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5553: @*/
5554: PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5555: {
5556: PetscInt dim = mat->stencil.dim;
5557: PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc);
5558: PetscInt *dims = mat->stencil.dims+1;
5559: PetscInt *starts = mat->stencil.starts;
5560: PetscInt *dxm = (PetscInt *) rows;
5561: PetscInt *jdxm, i, j, tmp, numNewRows = 0;
5569: PetscMalloc(numRows*sizeof(PetscInt), &jdxm);
5570: for(i = 0; i < numRows; ++i) {
5571: /* Skip unused dimensions (they are ordered k, j, i, c) */
5572: for(j = 0; j < 3-sdim; ++j) dxm++;
5573: /* Local index in X dir */
5574: tmp = *dxm++ - starts[0];
5575: /* Loop over remaining dimensions */
5576: for(j = 0; j < dim-1; ++j) {
5577: /* If nonlocal, set index to be negative */
5578: if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5579: /* Update local index */
5580: else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5581: }
5582: /* Skip component slot if necessary */
5583: if (mat->stencil.noc) dxm++;
5584: /* Local row number */
5585: if (tmp >= 0) {
5586: jdxm[numNewRows++] = tmp;
5587: }
5588: }
5589: MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);
5590: PetscFree(jdxm);
5591: return(0);
5592: }
5596: /*@C
5597: MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
5598: of a set of rows of a matrix; using local numbering of rows.
5600: Collective on Mat
5602: Input Parameters:
5603: + mat - the matrix
5604: . numRows - the number of rows to remove
5605: . rows - the global row indices
5606: . diag - value put in all diagonals of eliminated rows
5607: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5608: - b - optional vector of right hand side, that will be adjusted by provided solution
5610: Notes:
5611: Before calling MatZeroRowsLocal(), the user must first set the
5612: local-to-global mapping by calling MatSetLocalToGlobalMapping().
5614: For the AIJ matrix formats this removes the old nonzero structure,
5615: but does not release memory. For the dense and block diagonal
5616: formats this does not alter the nonzero structure.
5618: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5619: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5620: merely zeroed.
5622: The user can set a value in the diagonal entry (or for the AIJ and
5623: row formats can optionally remove the main diagonal entry from the
5624: nonzero structure as well, by passing 0.0 as the final argument).
5626: You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5627: owns that are to be zeroed. This saves a global synchronization in the implementation.
5629: Level: intermediate
5631: Concepts: matrices^zeroing
5633: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5634: @*/
5635: PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5636: {
5638: PetscMPIInt size;
5644: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5645: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5646: MatCheckPreallocated(mat,1);
5648: MPI_Comm_size(((PetscObject)mat)->comm,&size);
5649: if (mat->ops->zerorowslocal) {
5650: (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);
5651: } else if (size == 1) {
5652: (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);
5653: } else {
5654: IS is, newis;
5655: const PetscInt *newRows;
5657: if (!mat->rmap->mapping) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5658: ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
5659: ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);
5660: ISGetIndices(newis,&newRows);
5661: (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);
5662: ISRestoreIndices(newis,&newRows);
5663: ISDestroy(&newis);
5664: ISDestroy(&is);
5665: }
5666: PetscObjectStateIncrease((PetscObject)mat);
5667: #if defined(PETSC_HAVE_CUSP)
5668: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5669: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5670: }
5671: #endif
5672: return(0);
5673: }
5677: /*@C
5678: MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
5679: of a set of rows of a matrix; using local numbering of rows.
5681: Collective on Mat
5683: Input Parameters:
5684: + mat - the matrix
5685: . is - index set of rows to remove
5686: . diag - value put in all diagonals of eliminated rows
5687: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5688: - b - optional vector of right hand side, that will be adjusted by provided solution
5690: Notes:
5691: Before calling MatZeroRowsLocalIS(), the user must first set the
5692: local-to-global mapping by calling MatSetLocalToGlobalMapping().
5694: For the AIJ matrix formats this removes the old nonzero structure,
5695: but does not release memory. For the dense and block diagonal
5696: formats this does not alter the nonzero structure.
5698: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5699: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5700: merely zeroed.
5702: The user can set a value in the diagonal entry (or for the AIJ and
5703: row formats can optionally remove the main diagonal entry from the
5704: nonzero structure as well, by passing 0.0 as the final argument).
5706: You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5707: owns that are to be zeroed. This saves a global synchronization in the implementation.
5709: Level: intermediate
5711: Concepts: matrices^zeroing
5713: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5714: @*/
5715: PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5716: {
5718: PetscInt numRows;
5719: const PetscInt *rows;
5725: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5726: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5727: MatCheckPreallocated(mat,1);
5729: ISGetLocalSize(is,&numRows);
5730: ISGetIndices(is,&rows);
5731: MatZeroRowsLocal(mat,numRows,rows,diag,x,b);
5732: ISRestoreIndices(is,&rows);
5733: return(0);
5734: }
5738: /*@C
5739: MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
5740: of a set of rows and columns of a matrix; using local numbering of rows.
5742: Collective on Mat
5744: Input Parameters:
5745: + mat - the matrix
5746: . numRows - the number of rows to remove
5747: . rows - the global row indices
5748: . diag - value put in all diagonals of eliminated rows
5749: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5750: - b - optional vector of right hand side, that will be adjusted by provided solution
5752: Notes:
5753: Before calling MatZeroRowsColumnsLocal(), the user must first set the
5754: local-to-global mapping by calling MatSetLocalToGlobalMapping().
5756: The user can set a value in the diagonal entry (or for the AIJ and
5757: row formats can optionally remove the main diagonal entry from the
5758: nonzero structure as well, by passing 0.0 as the final argument).
5760: Level: intermediate
5762: Concepts: matrices^zeroing
5764: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5765: @*/
5766: PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5767: {
5769: PetscMPIInt size;
5775: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5776: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5777: MatCheckPreallocated(mat,1);
5779: MPI_Comm_size(((PetscObject)mat)->comm,&size);
5780: if (size == 1) {
5781: (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);
5782: } else {
5783: IS is, newis;
5784: const PetscInt *newRows;
5786: if (!mat->cmap->mapping) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5787: ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
5788: ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);
5789: ISGetIndices(newis,&newRows);
5790: (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);
5791: ISRestoreIndices(newis,&newRows);
5792: ISDestroy(&newis);
5793: ISDestroy(&is);
5794: }
5795: PetscObjectStateIncrease((PetscObject)mat);
5796: #if defined(PETSC_HAVE_CUSP)
5797: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5798: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5799: }
5800: #endif
5801: return(0);
5802: }
5806: /*@C
5807: MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
5808: of a set of rows and columns of a matrix; using local numbering of rows.
5810: Collective on Mat
5812: Input Parameters:
5813: + mat - the matrix
5814: . is - index set of rows to remove
5815: . diag - value put in all diagonals of eliminated rows
5816: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5817: - b - optional vector of right hand side, that will be adjusted by provided solution
5819: Notes:
5820: Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
5821: local-to-global mapping by calling MatSetLocalToGlobalMapping().
5823: The user can set a value in the diagonal entry (or for the AIJ and
5824: row formats can optionally remove the main diagonal entry from the
5825: nonzero structure as well, by passing 0.0 as the final argument).
5827: Level: intermediate
5829: Concepts: matrices^zeroing
5831: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5832: @*/
5833: PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5834: {
5836: PetscInt numRows;
5837: const PetscInt *rows;
5843: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5844: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5845: MatCheckPreallocated(mat,1);
5847: ISGetLocalSize(is,&numRows);
5848: ISGetIndices(is,&rows);
5849: MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);
5850: ISRestoreIndices(is,&rows);
5851: return(0);
5852: }
5856: /*@
5857: MatGetSize - Returns the numbers of rows and columns in a matrix.
5859: Not Collective
5861: Input Parameter:
5862: . mat - the matrix
5864: Output Parameters:
5865: + m - the number of global rows
5866: - n - the number of global columns
5868: Note: both output parameters can be PETSC_NULL on input.
5870: Level: beginner
5872: Concepts: matrices^size
5874: .seealso: MatGetLocalSize()
5875: @*/
5876: PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt* n)
5877: {
5880: if (m) *m = mat->rmap->N;
5881: if (n) *n = mat->cmap->N;
5882: return(0);
5883: }
5887: /*@
5888: MatGetLocalSize - Returns the number of rows and columns in a matrix
5889: stored locally. This information may be implementation dependent, so
5890: use with care.
5892: Not Collective
5894: Input Parameters:
5895: . mat - the matrix
5897: Output Parameters:
5898: + m - the number of local rows
5899: - n - the number of local columns
5901: Note: both output parameters can be PETSC_NULL on input.
5903: Level: beginner
5905: Concepts: matrices^local size
5907: .seealso: MatGetSize()
5908: @*/
5909: PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt* n)
5910: {
5915: if (m) *m = mat->rmap->n;
5916: if (n) *n = mat->cmap->n;
5917: return(0);
5918: }
5922: /*@
5923: MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
5924: this processor. (The columns of the "diagonal block")
5926: Not Collective, unless matrix has not been allocated, then collective on Mat
5928: Input Parameters:
5929: . mat - the matrix
5931: Output Parameters:
5932: + m - the global index of the first local column
5933: - n - one more than the global index of the last local column
5935: Notes: both output parameters can be PETSC_NULL on input.
5937: Level: developer
5939: Concepts: matrices^column ownership
5941: .seealso: MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
5943: @*/
5944: PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt* n)
5945: {
5952: MatCheckPreallocated(mat,1);
5953: if (m) *m = mat->cmap->rstart;
5954: if (n) *n = mat->cmap->rend;
5955: return(0);
5956: }
5960: /*@
5961: MatGetOwnershipRange - Returns the range of matrix rows owned by
5962: this processor, assuming that the matrix is laid out with the first
5963: n1 rows on the first processor, the next n2 rows on the second, etc.
5964: For certain parallel layouts this range may not be well defined.
5966: Not Collective
5968: Input Parameters:
5969: . mat - the matrix
5971: Output Parameters:
5972: + m - the global index of the first local row
5973: - n - one more than the global index of the last local row
5975: Note: Both output parameters can be PETSC_NULL on input.
5976: $ This function requires that the matrix be preallocated. If you have not preallocated, consider using
5977: $ PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
5978: $ and then MPI_Scan() to calculate prefix sums of the local sizes.
5980: Level: beginner
5982: Concepts: matrices^row ownership
5984: .seealso: MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()
5986: @*/
5987: PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt* n)
5988: {
5995: MatCheckPreallocated(mat,1);
5996: if (m) *m = mat->rmap->rstart;
5997: if (n) *n = mat->rmap->rend;
5998: return(0);
5999: }
6003: /*@C
6004: MatGetOwnershipRanges - Returns the range of matrix rows owned by
6005: each process
6007: Not Collective, unless matrix has not been allocated, then collective on Mat
6009: Input Parameters:
6010: . mat - the matrix
6012: Output Parameters:
6013: . ranges - start of each processors portion plus one more then the total length at the end
6015: Level: beginner
6017: Concepts: matrices^row ownership
6019: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
6021: @*/
6022: PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6023: {
6029: MatCheckPreallocated(mat,1);
6030: PetscLayoutGetRanges(mat->rmap,ranges);
6031: return(0);
6032: }
6036: /*@C
6037: MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6038: this processor. (The columns of the "diagonal blocks" for each process)
6040: Not Collective, unless matrix has not been allocated, then collective on Mat
6042: Input Parameters:
6043: . mat - the matrix
6045: Output Parameters:
6046: . ranges - start of each processors portion plus one more then the total length at the end
6048: Level: beginner
6050: Concepts: matrices^column ownership
6052: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
6054: @*/
6055: PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6056: {
6062: MatCheckPreallocated(mat,1);
6063: PetscLayoutGetRanges(mat->cmap,ranges);
6064: return(0);
6065: }
6069: /*@C
6070: MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6071: Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6072: to complete the factorization.
6074: Collective on Mat
6076: Input Parameters:
6077: + mat - the matrix
6078: . row - row permutation
6079: . column - column permutation
6080: - info - structure containing
6081: $ levels - number of levels of fill.
6082: $ expected fill - as ratio of original fill.
6083: $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6084: missing diagonal entries)
6086: Output Parameters:
6087: . fact - new matrix that has been symbolically factored
6089: Notes:
6090: See the <a href="../../docs/manual.pdf">users manual</a> for additional information about
6091: choosing the fill factor for better efficiency.
6093: Most users should employ the simplified KSP interface for linear solvers
6094: instead of working directly with matrix algebra routines such as this.
6095: See, e.g., KSPCreate().
6097: Level: developer
6099: Concepts: matrices^symbolic LU factorization
6100: Concepts: matrices^factorization
6101: Concepts: LU^symbolic factorization
6103: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6104: MatGetOrdering(), MatFactorInfo
6106: Developer Note: fortran interface is not autogenerated as the f90
6107: interface defintion cannot be generated correctly [due to MatFactorInfo]
6109: @*/
6110: PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6111: {
6121: if (info->levels < 0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6122: if (info->fill < 1.0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
6123: if (!(fact)->ops->ilufactorsymbolic) {
6124: const MatSolverPackage spackage;
6125: MatFactorGetSolverPackage(fact,&spackage);
6126: SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6127: }
6128: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6129: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6130: MatCheckPreallocated(mat,2);
6132: PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);
6133: (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);
6134: PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);
6135: return(0);
6136: }
6140: /*@C
6141: MatICCFactorSymbolic - Performs symbolic incomplete
6142: Cholesky factorization for a symmetric matrix. Use
6143: MatCholeskyFactorNumeric() to complete the factorization.
6145: Collective on Mat
6147: Input Parameters:
6148: + mat - the matrix
6149: . perm - row and column permutation
6150: - info - structure containing
6151: $ levels - number of levels of fill.
6152: $ expected fill - as ratio of original fill.
6154: Output Parameter:
6155: . fact - the factored matrix
6157: Notes:
6158: Most users should employ the KSP interface for linear solvers
6159: instead of working directly with matrix algebra routines such as this.
6160: See, e.g., KSPCreate().
6162: Level: developer
6164: Concepts: matrices^symbolic incomplete Cholesky factorization
6165: Concepts: matrices^factorization
6166: Concepts: Cholsky^symbolic factorization
6168: .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
6170: Developer Note: fortran interface is not autogenerated as the f90
6171: interface defintion cannot be generated correctly [due to MatFactorInfo]
6173: @*/
6174: PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6175: {
6184: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6185: if (info->levels < 0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6186: if (info->fill < 1.0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
6187: if (!(fact)->ops->iccfactorsymbolic) {
6188: const MatSolverPackage spackage;
6189: MatFactorGetSolverPackage(fact,&spackage);
6190: SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6191: }
6192: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6193: MatCheckPreallocated(mat,2);
6195: PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);
6196: (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);
6197: PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);
6198: return(0);
6199: }
6203: /*@C
6204: MatGetArray - Returns a pointer to the element values in the matrix.
6205: The result of this routine is dependent on the underlying matrix data
6206: structure, and may not even work for certain matrix types. You MUST
6207: call MatRestoreArray() when you no longer need to access the array.
6209: Not Collective
6211: Input Parameter:
6212: . mat - the matrix
6214: Output Parameter:
6215: . v - the location of the values
6218: Fortran Note:
6219: This routine is used differently from Fortran, e.g.,
6220: .vb
6221: Mat mat
6222: PetscScalar mat_array(1)
6223: PetscOffset i_mat
6224: PetscErrorCode ierr
6225: call MatGetArray(mat,mat_array,i_mat,ierr)
6227: C Access first local entry in matrix; note that array is
6228: C treated as one dimensional
6229: value = mat_array(i_mat + 1)
6231: [... other code ...]
6232: call MatRestoreArray(mat,mat_array,i_mat,ierr)
6233: .ve
6235: See the <a href="../../docs/manual.pdf#Chapter 9 PETSc for Fortran Users">Fortran chapter of the users manual</a> and
6236: src/mat/examples/tests for details.
6238: Level: advanced
6240: Concepts: matrices^access array
6242: .seealso: MatRestoreArray(), MatGetArrayF90(), MatGetRowIJ()
6243: @*/
6244: PetscErrorCode MatGetArray(Mat mat,PetscScalar *v[])
6245: {
6252: if (!mat->ops->getarray) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6253: MatCheckPreallocated(mat,1);
6254: (*mat->ops->getarray)(mat,v);
6255: CHKMEMQ;
6256: return(0);
6257: }
6261: /*@C
6262: MatRestoreArray - Restores the matrix after MatGetArray() has been called.
6264: Not Collective
6266: Input Parameter:
6267: + mat - the matrix
6268: - v - the location of the values
6270: Fortran Note:
6271: This routine is used differently from Fortran, e.g.,
6272: .vb
6273: Mat mat
6274: PetscScalar mat_array(1)
6275: PetscOffset i_mat
6276: PetscErrorCode ierr
6277: call MatGetArray(mat,mat_array,i_mat,ierr)
6279: C Access first local entry in matrix; note that array is
6280: C treated as one dimensional
6281: value = mat_array(i_mat + 1)
6283: [... other code ...]
6284: call MatRestoreArray(mat,mat_array,i_mat,ierr)
6285: .ve
6287: See the <a href="../../docs/manual.pdf#Chapter 9 PETSc for Fortran Users">Fortran chapter of the users manual</a>
6288: src/mat/examples/tests for details
6290: Level: advanced
6292: .seealso: MatGetArray(), MatRestoreArrayF90()
6293: @*/
6294: PetscErrorCode MatRestoreArray(Mat mat,PetscScalar *v[])
6295: {
6302: CHKMEMQ;
6303: if (!mat->ops->restorearray) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6304: (*mat->ops->restorearray)(mat,v);
6305: PetscObjectStateIncrease((PetscObject)mat);
6306: #if defined(PETSC_HAVE_CUSP)
6307: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
6308: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
6309: }
6310: #endif
6311: return(0);
6312: }
6316: /*@C
6317: MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
6318: points to an array of valid matrices, they may be reused to store the new
6319: submatrices.
6321: Collective on Mat
6323: Input Parameters:
6324: + mat - the matrix
6325: . n - the number of submatrixes to be extracted (on this processor, may be zero)
6326: . irow, icol - index sets of rows and columns to extract (must be sorted)
6327: - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6329: Output Parameter:
6330: . submat - the array of submatrices
6332: Notes:
6333: MatGetSubMatrices() can extract ONLY sequential submatrices
6334: (from both sequential and parallel matrices). Use MatGetSubMatrix()
6335: to extract a parallel submatrix.
6337: Currently both row and column indices must be sorted to guarantee
6338: correctness with all matrix types.
6340: When extracting submatrices from a parallel matrix, each processor can
6341: form a different submatrix by setting the rows and columns of its
6342: individual index sets according to the local submatrix desired.
6344: When finished using the submatrices, the user should destroy
6345: them with MatDestroyMatrices().
6347: MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6348: original matrix has not changed from that last call to MatGetSubMatrices().
6350: This routine creates the matrices in submat; you should NOT create them before
6351: calling it. It also allocates the array of matrix pointers submat.
6353: For BAIJ matrices the index sets must respect the block structure, that is if they
6354: request one row/column in a block, they must request all rows/columns that are in
6355: that block. For example, if the block size is 2 you cannot request just row 0 and
6356: column 0.
6358: Fortran Note:
6359: The Fortran interface is slightly different from that given below; it
6360: requires one to pass in as submat a Mat (integer) array of size at least m.
6362: Level: advanced
6364: Concepts: matrices^accessing submatrices
6365: Concepts: submatrices
6367: .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6368: @*/
6369: PetscErrorCode MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6370: {
6372: PetscInt i;
6373: PetscBool eq;
6378: if (n) {
6383: }
6385: if (n && scall == MAT_REUSE_MATRIX) {
6388: }
6389: if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6390: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6391: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6392: MatCheckPreallocated(mat,1);
6394: PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6395: (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);
6396: PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6397: for (i=0; i<n; i++) {
6398: if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6399: ISEqual(irow[i],icol[i],&eq);
6400: if (eq) {
6401: if (mat->symmetric){
6402: MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6403: } else if (mat->hermitian) {
6404: MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6405: } else if (mat->structurally_symmetric) {
6406: MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6407: }
6408: }
6409: }
6410: }
6411: return(0);
6412: }
6416: PetscErrorCode MatGetSubMatricesParallel(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6417: {
6419: PetscInt i;
6420: PetscBool eq;
6425: if (n) {
6430: }
6432: if (n && scall == MAT_REUSE_MATRIX) {
6435: }
6436: if (!mat->ops->getsubmatricesparallel) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6437: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6438: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6439: MatCheckPreallocated(mat,1);
6441: PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6442: (*mat->ops->getsubmatricesparallel)(mat,n,irow,icol,scall,submat);
6443: PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6444: for (i=0; i<n; i++) {
6445: if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6446: ISEqual(irow[i],icol[i],&eq);
6447: if (eq) {
6448: if (mat->symmetric){
6449: MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6450: } else if (mat->hermitian) {
6451: MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6452: } else if (mat->structurally_symmetric) {
6453: MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6454: }
6455: }
6456: }
6457: }
6458: return(0);
6459: }
6463: /*@C
6464: MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().
6466: Collective on Mat
6468: Input Parameters:
6469: + n - the number of local matrices
6470: - mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6471: sequence of MatGetSubMatrices())
6473: Level: advanced
6475: Notes: Frees not only the matrices, but also the array that contains the matrices
6476: In Fortran will not free the array.
6478: .seealso: MatGetSubMatrices()
6479: @*/
6480: PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
6481: {
6483: PetscInt i;
6486: if (!*mat) return(0);
6487: if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6489: for (i=0; i<n; i++) {
6490: MatDestroy(&(*mat)[i]);
6491: }
6492: /* memory is allocated even if n = 0 */
6493: PetscFree(*mat);
6494: *mat = PETSC_NULL;
6495: return(0);
6496: }
6500: /*@C
6501: MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
6503: Collective on Mat
6505: Input Parameters:
6506: . mat - the matrix
6508: Output Parameter:
6509: . matstruct - the sequential matrix with the nonzero structure of mat
6511: Level: intermediate
6513: .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
6514: @*/
6515: PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6516: {
6522:
6524: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6525: MatCheckPreallocated(mat,1);
6527: if (!mat->ops->getseqnonzerostructure) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6528: PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6529: (*mat->ops->getseqnonzerostructure)(mat,matstruct);
6530: PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6531: return(0);
6532: }
6536: /*@C
6537: MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
6539: Collective on Mat
6541: Input Parameters:
6542: . mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
6543: sequence of MatGetSequentialNonzeroStructure())
6545: Level: advanced
6547: Notes: Frees not only the matrices, but also the array that contains the matrices
6549: .seealso: MatGetSeqNonzeroStructure()
6550: @*/
6551: PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
6552: {
6557: MatDestroy(mat);
6558: return(0);
6559: }
6563: /*@
6564: MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6565: replaces the index sets by larger ones that represent submatrices with
6566: additional overlap.
6568: Collective on Mat
6570: Input Parameters:
6571: + mat - the matrix
6572: . n - the number of index sets
6573: . is - the array of index sets (these index sets will changed during the call)
6574: - ov - the additional overlap requested
6576: Level: developer
6578: Concepts: overlap
6579: Concepts: ASM^computing overlap
6581: .seealso: MatGetSubMatrices()
6582: @*/
6583: PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6584: {
6590: if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6591: if (n) {
6594: }
6595: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6596: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6597: MatCheckPreallocated(mat,1);
6599: if (!ov) return(0);
6600: if (!mat->ops->increaseoverlap) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6601: PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
6602: (*mat->ops->increaseoverlap)(mat,n,is,ov);
6603: PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
6604: return(0);
6605: }
6609: /*@
6610: MatGetBlockSize - Returns the matrix block size; useful especially for the
6611: block row and block diagonal formats.
6612:
6613: Not Collective
6615: Input Parameter:
6616: . mat - the matrix
6618: Output Parameter:
6619: . bs - block size
6621: Notes:
6622: Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ
6624: Level: intermediate
6626: Concepts: matrices^block size
6628: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
6629: @*/
6630: PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
6631: {
6637: MatCheckPreallocated(mat,1);
6638: *bs = mat->rmap->bs;
6639: return(0);
6640: }
6644: /*@
6645: MatGetBlockSizes - Returns the matrix block row and column sizes;
6646: useful especially for the block row and block diagonal formats.
6647:
6648: Not Collective
6650: Input Parameter:
6651: . mat - the matrix
6653: Output Parameter:
6654: . rbs - row block size
6655: . cbs - coumn block size
6657: Notes:
6658: Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ
6660: Level: intermediate
6662: Concepts: matrices^block size
6664: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
6665: @*/
6666: PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
6667: {
6674: MatCheckPreallocated(mat,1);
6675: if(rbs) *rbs = mat->rmap->bs;
6676: if(cbs) *cbs = mat->cmap->bs;
6677: return(0);
6678: }
6682: /*@
6683: MatSetBlockSize - Sets the matrix block size.
6684:
6685: Logically Collective on Mat
6687: Input Parameters:
6688: + mat - the matrix
6689: - bs - block size
6691: Notes:
6692: This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later
6694: Level: intermediate
6696: Concepts: matrices^block size
6698: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
6699: @*/
6700: PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
6701: {
6707: PetscLayoutSetBlockSize(mat->rmap,bs);
6708: PetscLayoutSetBlockSize(mat->cmap,bs);
6709: return(0);
6710: }
6714: /*@
6715: MatSetBlockSizes - Sets the matrix block row and column sizes.
6716:
6717: Logically Collective on Mat
6719: Input Parameters:
6720: + mat - the matrix
6721: - rbs - row block size
6722: - cbs - column block size
6724: Notes:
6725: This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later
6727: Level: intermediate
6729: Concepts: matrices^block size
6731: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
6732: @*/
6733: PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
6734: {
6740: PetscLayoutSetBlockSize(mat->rmap,rbs);
6741: PetscLayoutSetBlockSize(mat->cmap,cbs);
6742: return(0);
6743: }
6747: /*@C
6748: MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
6750: Collective on Mat
6752: Input Parameters:
6753: + mat - the matrix
6754: . shift - 0 or 1 indicating we want the indices starting at 0 or 1
6755: . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be symmetrized
6756: - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6757: inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6758: always used.
6760: Output Parameters:
6761: + n - number of rows in the (possibly compressed) matrix
6762: . ia - the row pointers [of length n+1]
6763: . ja - the column indices
6764: - done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
6765: are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
6767: Level: developer
6769: Notes: You CANNOT change any of the ia[] or ja[] values.
6771: Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values
6773: Fortran Node
6775: In Fortran use
6776: $ PetscInt ia(1), ja(1)
6777: $ PetscOffset iia, jja
6778: $ call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
6779: $
6780: $ or
6781: $
6782: $ PetscScalar, pointer :: xx_v(:)
6783: $ call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
6784:
6785:
6786: Acess the ith and jth entries via ia(iia + i) and ja(jja + j)
6788: .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatGetArray()
6789: @*/
6790: PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool *done)
6791: {
6801: MatCheckPreallocated(mat,1);
6802: if (!mat->ops->getrowij) *done = PETSC_FALSE;
6803: else {
6804: *done = PETSC_TRUE;
6805: PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);
6806: (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6807: PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);
6808: }
6809: return(0);
6810: }
6814: /*@C
6815: MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
6817: Collective on Mat
6819: Input Parameters:
6820: + mat - the matrix
6821: . shift - 1 or zero indicating we want the indices starting at 0 or 1
6822: . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6823: symmetrized
6824: - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6825: inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6826: always used.
6828: Output Parameters:
6829: + n - number of columns in the (possibly compressed) matrix
6830: . ia - the column pointers
6831: . ja - the row indices
6832: - done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
6834: Level: developer
6836: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6837: @*/
6838: PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool *done)
6839: {
6849: MatCheckPreallocated(mat,1);
6850: if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
6851: else {
6852: *done = PETSC_TRUE;
6853: (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6854: }
6855: return(0);
6856: }
6860: /*@C
6861: MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
6862: MatGetRowIJ().
6864: Collective on Mat
6866: Input Parameters:
6867: + mat - the matrix
6868: . shift - 1 or zero indicating we want the indices starting at 0 or 1
6869: . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6870: symmetrized
6871: - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6872: inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6873: always used.
6875: Output Parameters:
6876: + n - size of (possibly compressed) matrix
6877: . ia - the row pointers
6878: . ja - the column indices
6879: - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
6881: Level: developer
6883: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6884: @*/
6885: PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool *done)
6886: {
6895: MatCheckPreallocated(mat,1);
6897: if (!mat->ops->restorerowij) *done = PETSC_FALSE;
6898: else {
6899: *done = PETSC_TRUE;
6900: (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6901: }
6902: return(0);
6903: }
6907: /*@C
6908: MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
6909: MatGetColumnIJ().
6911: Collective on Mat
6913: Input Parameters:
6914: + mat - the matrix
6915: . shift - 1 or zero indicating we want the indices starting at 0 or 1
6916: - symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6917: symmetrized
6918: - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6919: inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6920: always used.
6922: Output Parameters:
6923: + n - size of (possibly compressed) matrix
6924: . ia - the column pointers
6925: . ja - the row indices
6926: - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
6928: Level: developer
6930: .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
6931: @*/
6932: PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool *done)
6933: {
6942: MatCheckPreallocated(mat,1);
6944: if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
6945: else {
6946: *done = PETSC_TRUE;
6947: (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6948: }
6949: return(0);
6950: }
6954: /*@C
6955: MatColoringPatch -Used inside matrix coloring routines that
6956: use MatGetRowIJ() and/or MatGetColumnIJ().
6958: Collective on Mat
6960: Input Parameters:
6961: + mat - the matrix
6962: . ncolors - max color value
6963: . n - number of entries in colorarray
6964: - colorarray - array indicating color for each column
6966: Output Parameters:
6967: . iscoloring - coloring generated using colorarray information
6969: Level: developer
6971: .seealso: MatGetRowIJ(), MatGetColumnIJ()
6973: @*/
6974: PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
6975: {
6983: MatCheckPreallocated(mat,1);
6985: if (!mat->ops->coloringpatch){
6986: ISColoringCreate(((PetscObject)mat)->comm,ncolors,n,colorarray,iscoloring);
6987: } else {
6988: (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);
6989: }
6990: return(0);
6991: }
6996: /*@
6997: MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
6999: Logically Collective on Mat
7001: Input Parameter:
7002: . mat - the factored matrix to be reset
7004: Notes:
7005: This routine should be used only with factored matrices formed by in-place
7006: factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7007: format). This option can save memory, for example, when solving nonlinear
7008: systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7009: ILU(0) preconditioner.
7011: Note that one can specify in-place ILU(0) factorization by calling
7012: .vb
7013: PCType(pc,PCILU);
7014: PCFactorSeUseInPlace(pc);
7015: .ve
7016: or by using the options -pc_type ilu -pc_factor_in_place
7018: In-place factorization ILU(0) can also be used as a local
7019: solver for the blocks within the block Jacobi or additive Schwarz
7020: methods (runtime option: -sub_pc_factor_in_place). See the discussion
7021: of these preconditioners in the <a href="../../docs/manual.pdf#ch_pc">PC chapter of the users manual</a> for details on setting
7022: local solver options.
7024: Most users should employ the simplified KSP interface for linear solvers
7025: instead of working directly with matrix algebra routines such as this.
7026: See, e.g., KSPCreate().
7028: Level: developer
7030: .seealso: PCFactorSetUseInPlace()
7032: Concepts: matrices^unfactored
7034: @*/
7035: PetscErrorCode MatSetUnfactored(Mat mat)
7036: {
7042: MatCheckPreallocated(mat,1);
7043: mat->factortype = MAT_FACTOR_NONE;
7044: if (!mat->ops->setunfactored) return(0);
7045: (*mat->ops->setunfactored)(mat);
7046: return(0);
7047: }
7049: /*MC
7050: MatGetArrayF90 - Accesses a matrix array from Fortran90.
7052: Synopsis:
7053: MatGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7055: Not collective
7057: Input Parameter:
7058: . x - matrix
7060: Output Parameters:
7061: + xx_v - the Fortran90 pointer to the array
7062: - ierr - error code
7064: Example of Usage:
7065: .vb
7066: PetscScalar, pointer xx_v(:,:)
7067: ....
7068: call MatGetArrayF90(x,xx_v,ierr)
7069: a = xx_v(3)
7070: call MatRestoreArrayF90(x,xx_v,ierr)
7071: .ve
7073: Notes:
7074: Not yet supported for all F90 compilers
7076: Level: advanced
7078: .seealso: MatRestoreArrayF90(), MatGetArray(), MatRestoreArray()
7080: Concepts: matrices^accessing array
7082: M*/
7084: /*MC
7085: MatRestoreArrayF90 - Restores a matrix array that has been
7086: accessed with MatGetArrayF90().
7088: Synopsis:
7089: MatRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7091: Not collective
7093: Input Parameters:
7094: + x - matrix
7095: - xx_v - the Fortran90 pointer to the array
7097: Output Parameter:
7098: . ierr - error code
7100: Example of Usage:
7101: .vb
7102: PetscScalar, pointer xx_v(:)
7103: ....
7104: call MatGetArrayF90(x,xx_v,ierr)
7105: a = xx_v(3)
7106: call MatRestoreArrayF90(x,xx_v,ierr)
7107: .ve
7108:
7109: Notes:
7110: Not yet supported for all F90 compilers
7112: Level: advanced
7114: .seealso: MatGetArrayF90(), MatGetArray(), MatRestoreArray()
7116: M*/
7121: /*@
7122: MatGetSubMatrix - Gets a single submatrix on the same number of processors
7123: as the original matrix.
7125: Collective on Mat
7127: Input Parameters:
7128: + mat - the original matrix
7129: . isrow - parallel IS containing the rows this processor should obtain
7130: . 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.
7131: - cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7133: Output Parameter:
7134: . newmat - the new submatrix, of the same type as the old
7136: Level: advanced
7138: Notes:
7139: The submatrix will be able to be multiplied with vectors using the same layout as iscol.
7141: The rows in isrow will be sorted into the same order as the original matrix on each process.
7143: The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7144: the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
7145: to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7146: will reuse the matrix generated the first time. You should call MatDestroy() on newmat when
7147: you are finished using it.
7149: The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7150: the input matrix.
7152: If iscol is PETSC_NULL then all columns are obtained (not supported in Fortran).
7154: Example usage:
7155: Consider the following 8x8 matrix with 34 non-zero values, that is
7156: assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7157: proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7158: as follows:
7160: .vb
7161: 1 2 0 | 0 3 0 | 0 4
7162: Proc0 0 5 6 | 7 0 0 | 8 0
7163: 9 0 10 | 11 0 0 | 12 0
7164: -------------------------------------
7165: 13 0 14 | 15 16 17 | 0 0
7166: Proc1 0 18 0 | 19 20 21 | 0 0
7167: 0 0 0 | 22 23 0 | 24 0
7168: -------------------------------------
7169: Proc2 25 26 27 | 0 0 28 | 29 0
7170: 30 0 0 | 31 32 33 | 0 34
7171: .ve
7173: Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6]. The resulting submatrix is
7175: .vb
7176: 2 0 | 0 3 0 | 0
7177: Proc0 5 6 | 7 0 0 | 8
7178: -------------------------------
7179: Proc1 18 0 | 19 20 21 | 0
7180: -------------------------------
7181: Proc2 26 27 | 0 0 28 | 29
7182: 0 0 | 31 32 33 | 0
7183: .ve
7186: Concepts: matrices^submatrices
7188: .seealso: MatGetSubMatrices()
7189: @*/
7190: PetscErrorCode MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7191: {
7193: PetscMPIInt size;
7194: Mat *local;
7195: IS iscoltmp;
7204: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7205: MatCheckPreallocated(mat,1);
7206: MPI_Comm_size(((PetscObject)mat)->comm,&size);
7208: if (!iscol) {
7209: ISCreateStride(((PetscObject)mat)->comm,mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);
7210: } else {
7211: iscoltmp = iscol;
7212: }
7214: /* if original matrix is on just one processor then use submatrix generated */
7215: if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7216: MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);
7217: if (!iscol) {ISDestroy(&iscoltmp);}
7218: return(0);
7219: } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) {
7220: MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);
7221: *newmat = *local;
7222: PetscFree(local);
7223: if (!iscol) {ISDestroy(&iscoltmp);}
7224: return(0);
7225: } else if (!mat->ops->getsubmatrix) {
7226: /* Create a new matrix type that implements the operation using the full matrix */
7227: switch (cll) {
7228: case MAT_INITIAL_MATRIX:
7229: MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);
7230: break;
7231: case MAT_REUSE_MATRIX:
7232: MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);
7233: break;
7234: default: SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7235: }
7236: if (!iscol) {ISDestroy(&iscoltmp);}
7237: return(0);
7238: }
7240: if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7241: (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);
7242: if (!iscol) {ISDestroy(&iscoltmp);}
7243: if (*newmat && cll == MAT_INITIAL_MATRIX) {PetscObjectStateIncrease((PetscObject)*newmat);}
7244: return(0);
7245: }
7249: /*@
7250: MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7251: used during the assembly process to store values that belong to
7252: other processors.
7254: Not Collective
7256: Input Parameters:
7257: + mat - the matrix
7258: . size - the initial size of the stash.
7259: - bsize - the initial size of the block-stash(if used).
7261: Options Database Keys:
7262: + -matstash_initial_size <size> or <size0,size1,...sizep-1>
7263: - -matstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1>
7265: Level: intermediate
7267: Notes:
7268: The block-stash is used for values set with MatSetValuesBlocked() while
7269: the stash is used for values set with MatSetValues()
7271: Run with the option -info and look for output of the form
7272: MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7273: to determine the appropriate value, MM, to use for size and
7274: MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7275: to determine the value, BMM to use for bsize
7277: Concepts: stash^setting matrix size
7278: Concepts: matrices^stash
7280: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
7282: @*/
7283: PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7284: {
7290: MatStashSetInitialSize_Private(&mat->stash,size);
7291: MatStashSetInitialSize_Private(&mat->bstash,bsize);
7292: return(0);
7293: }
7297: /*@
7298: MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
7299: the matrix
7301: Neighbor-wise Collective on Mat
7303: Input Parameters:
7304: + mat - the matrix
7305: . x,y - the vectors
7306: - w - where the result is stored
7308: Level: intermediate
7310: Notes:
7311: w may be the same vector as y.
7313: This allows one to use either the restriction or interpolation (its transpose)
7314: matrix to do the interpolation
7316: Concepts: interpolation
7318: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7320: @*/
7321: PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7322: {
7324: PetscInt M,N,Ny;
7332: MatCheckPreallocated(A,1);
7333: MatGetSize(A,&M,&N);
7334: VecGetSize(y,&Ny);
7335: if (M == Ny) {
7336: MatMultAdd(A,x,y,w);
7337: } else {
7338: MatMultTransposeAdd(A,x,y,w);
7339: }
7340: return(0);
7341: }
7345: /*@
7346: MatInterpolate - y = A*x or A'*x depending on the shape of
7347: the matrix
7349: Neighbor-wise Collective on Mat
7351: Input Parameters:
7352: + mat - the matrix
7353: - x,y - the vectors
7355: Level: intermediate
7357: Notes:
7358: This allows one to use either the restriction or interpolation (its transpose)
7359: matrix to do the interpolation
7361: Concepts: matrices^interpolation
7363: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7365: @*/
7366: PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
7367: {
7369: PetscInt M,N,Ny;
7376: MatCheckPreallocated(A,1);
7377: MatGetSize(A,&M,&N);
7378: VecGetSize(y,&Ny);
7379: if (M == Ny) {
7380: MatMult(A,x,y);
7381: } else {
7382: MatMultTranspose(A,x,y);
7383: }
7384: return(0);
7385: }
7389: /*@
7390: MatRestrict - y = A*x or A'*x
7392: Neighbor-wise Collective on Mat
7394: Input Parameters:
7395: + mat - the matrix
7396: - x,y - the vectors
7398: Level: intermediate
7400: Notes:
7401: This allows one to use either the restriction or interpolation (its transpose)
7402: matrix to do the restriction
7404: Concepts: matrices^restriction
7406: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
7408: @*/
7409: PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
7410: {
7412: PetscInt M,N,Ny;
7419: MatCheckPreallocated(A,1);
7421: MatGetSize(A,&M,&N);
7422: VecGetSize(y,&Ny);
7423: if (M == Ny) {
7424: MatMult(A,x,y);
7425: } else {
7426: MatMultTranspose(A,x,y);
7427: }
7428: return(0);
7429: }
7433: /*@
7434: MatGetNullSpace - retrieves the null space to a matrix.
7436: Logically Collective on Mat and MatNullSpace
7438: Input Parameters:
7439: + mat - the matrix
7440: - nullsp - the null space object
7442: Level: developer
7444: Notes:
7445: This null space is used by solvers. Overwrites any previous null space that may have been attached
7447: Concepts: null space^attaching to matrix
7449: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace()
7450: @*/
7451: PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
7452: {
7457: *nullsp = mat->nullsp;
7458: return(0);
7459: }
7463: /*@
7464: MatSetNullSpace - attaches a null space to a matrix.
7465: This null space will be removed from the resulting vector whenever
7466: MatMult() is called
7468: Logically Collective on Mat and MatNullSpace
7470: Input Parameters:
7471: + mat - the matrix
7472: - nullsp - the null space object
7474: Level: advanced
7476: Notes:
7477: This null space is used by solvers. Overwrites any previous null space that may have been attached
7479: Concepts: null space^attaching to matrix
7481: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace()
7482: @*/
7483: PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp)
7484: {
7491: MatCheckPreallocated(mat,1);
7492: PetscObjectReference((PetscObject)nullsp);
7493: MatNullSpaceDestroy(&mat->nullsp);
7494: mat->nullsp = nullsp;
7495: return(0);
7496: }
7500: /*@
7501: MatSetNearNullSpace - attaches a null space to a matrix.
7502: This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.
7504: Logically Collective on Mat and MatNullSpace
7506: Input Parameters:
7507: + mat - the matrix
7508: - nullsp - the null space object
7510: Level: advanced
7512: Notes:
7513: Overwrites any previous near null space that may have been attached
7515: Concepts: null space^attaching to matrix
7517: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace()
7518: @*/
7519: PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
7520: {
7527: MatCheckPreallocated(mat,1);
7528: PetscObjectReference((PetscObject)nullsp);
7529: MatNullSpaceDestroy(&mat->nearnullsp);
7530: mat->nearnullsp = nullsp;
7531: return(0);
7532: }
7536: /*@
7537: MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()
7539: Not Collective
7541: Input Parameters:
7542: . mat - the matrix
7544: Output Parameters:
7545: . nullsp - the null space object, PETSC_NULL if not set
7547: Level: developer
7549: Concepts: null space^attaching to matrix
7551: .seealso: MatSetNearNullSpace(), MatGetNullSpace()
7552: @*/
7553: PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
7554: {
7560: MatCheckPreallocated(mat,1);
7561: *nullsp = mat->nearnullsp;
7562: return(0);
7563: }
7567: /*@C
7568: MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
7570: Collective on Mat
7572: Input Parameters:
7573: + mat - the matrix
7574: . row - row/column permutation
7575: . fill - expected fill factor >= 1.0
7576: - level - level of fill, for ICC(k)
7578: Notes:
7579: Probably really in-place only when level of fill is zero, otherwise allocates
7580: new space to store factored matrix and deletes previous memory.
7582: Most users should employ the simplified KSP interface for linear solvers
7583: instead of working directly with matrix algebra routines such as this.
7584: See, e.g., KSPCreate().
7586: Level: developer
7588: Concepts: matrices^incomplete Cholesky factorization
7589: Concepts: Cholesky factorization
7591: .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
7593: Developer Note: fortran interface is not autogenerated as the f90
7594: interface defintion cannot be generated correctly [due to MatFactorInfo]
7596: @*/
7597: PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo* info)
7598: {
7606: if (mat->rmap->N != mat->cmap->N) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONG,"matrix must be square");
7607: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7608: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7609: if (!mat->ops->iccfactor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7610: MatCheckPreallocated(mat,1);
7611: (*mat->ops->iccfactor)(mat,row,info);
7612: PetscObjectStateIncrease((PetscObject)mat);
7613: return(0);
7614: }
7618: /*@
7619: MatSetValuesAdic - Sets values computed with ADIC automatic differentiation into a matrix.
7621: Not Collective
7623: Input Parameters:
7624: + mat - the matrix
7625: - v - the values compute with ADIC
7627: Level: developer
7629: Notes:
7630: Must call MatSetColoring() before using this routine. Also this matrix must already
7631: have its nonzero pattern determined.
7633: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7634: MatSetValues(), MatSetColoring(), MatSetValuesAdifor()
7635: @*/
7636: PetscErrorCode MatSetValuesAdic(Mat mat,void *v)
7637: {
7645: if (!mat->assembled) {
7646: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7647: }
7648: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
7649: if (!mat->ops->setvaluesadic) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7650: (*mat->ops->setvaluesadic)(mat,v);
7651: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
7652: MatView_Private(mat);
7653: PetscObjectStateIncrease((PetscObject)mat);
7654: return(0);
7655: }
7660: /*@
7661: MatSetColoring - Sets a coloring used by calls to MatSetValuesAdic()
7663: Not Collective
7665: Input Parameters:
7666: + mat - the matrix
7667: - coloring - the coloring
7669: Level: developer
7671: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7672: MatSetValues(), MatSetValuesAdic()
7673: @*/
7674: PetscErrorCode MatSetColoring(Mat mat,ISColoring coloring)
7675: {
7683: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7684: if (!mat->ops->setcoloring) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7685: (*mat->ops->setcoloring)(mat,coloring);
7686: return(0);
7687: }
7691: /*@
7692: MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.
7694: Not Collective
7696: Input Parameters:
7697: + mat - the matrix
7698: . nl - leading dimension of v
7699: - v - the values compute with ADIFOR
7701: Level: developer
7703: Notes:
7704: Must call MatSetColoring() before using this routine. Also this matrix must already
7705: have its nonzero pattern determined.
7707: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7708: MatSetValues(), MatSetColoring()
7709: @*/
7710: PetscErrorCode MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
7711: {
7719: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7720: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
7721: if (!mat->ops->setvaluesadifor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7722: (*mat->ops->setvaluesadifor)(mat,nl,v);
7723: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
7724: PetscObjectStateIncrease((PetscObject)mat);
7725: return(0);
7726: }
7730: /*@
7731: MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
7732: ghosted ones.
7734: Not Collective
7736: Input Parameters:
7737: + mat - the matrix
7738: - diag = the diagonal values, including ghost ones
7740: Level: developer
7742: Notes: Works only for MPIAIJ and MPIBAIJ matrices
7743:
7744: .seealso: MatDiagonalScale()
7745: @*/
7746: PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
7747: {
7749: PetscMPIInt size;
7756: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7757: PetscLogEventBegin(MAT_Scale,mat,0,0,0);
7758: MPI_Comm_size(((PetscObject)mat)->comm,&size);
7759: if (size == 1) {
7760: PetscInt n,m;
7761: VecGetSize(diag,&n);
7762: MatGetSize(mat,0,&m);
7763: if (m == n) {
7764: MatDiagonalScale(mat,0,diag);
7765: } else {
7766: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
7767: }
7768: } else {
7769: PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));
7770: }
7771: PetscLogEventEnd(MAT_Scale,mat,0,0,0);
7772: PetscObjectStateIncrease((PetscObject)mat);
7773: return(0);
7774: }
7778: /*@
7779: MatGetInertia - Gets the inertia from a factored matrix
7781: Collective on Mat
7783: Input Parameter:
7784: . mat - the matrix
7786: Output Parameters:
7787: + nneg - number of negative eigenvalues
7788: . nzero - number of zero eigenvalues
7789: - npos - number of positive eigenvalues
7791: Level: advanced
7793: Notes: Matrix must have been factored by MatCholeskyFactor()
7796: @*/
7797: PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
7798: {
7804: if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7805: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
7806: if (!mat->ops->getinertia) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7807: (*mat->ops->getinertia)(mat,nneg,nzero,npos);
7808: return(0);
7809: }
7811: /* ----------------------------------------------------------------*/
7814: /*@C
7815: MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
7817: Neighbor-wise Collective on Mat and Vecs
7819: Input Parameters:
7820: + mat - the factored matrix
7821: - b - the right-hand-side vectors
7823: Output Parameter:
7824: . x - the result vectors
7826: Notes:
7827: The vectors b and x cannot be the same. I.e., one cannot
7828: call MatSolves(A,x,x).
7830: Notes:
7831: Most users should employ the simplified KSP interface for linear solvers
7832: instead of working directly with matrix algebra routines such as this.
7833: See, e.g., KSPCreate().
7835: Level: developer
7837: Concepts: matrices^triangular solves
7839: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
7840: @*/
7841: PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
7842: {
7848: if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
7849: if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7850: if (!mat->rmap->N && !mat->cmap->N) return(0);
7852: if (!mat->ops->solves) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7853: MatCheckPreallocated(mat,1);
7854: PetscLogEventBegin(MAT_Solves,mat,0,0,0);
7855: (*mat->ops->solves)(mat,b,x);
7856: PetscLogEventEnd(MAT_Solves,mat,0,0,0);
7857: return(0);
7858: }
7862: /*@
7863: MatIsSymmetric - Test whether a matrix is symmetric
7865: Collective on Mat
7867: Input Parameter:
7868: + A - the matrix to test
7869: - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
7871: Output Parameters:
7872: . flg - the result
7874: Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
7876: Level: intermediate
7878: Concepts: matrix^symmetry
7880: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
7881: @*/
7882: PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool *flg)
7883: {
7890: if (!A->symmetric_set) {
7891: if (!A->ops->issymmetric) {
7892: const MatType mattype;
7893: MatGetType(A,&mattype);
7894: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7895: }
7896: (*A->ops->issymmetric)(A,tol,flg);
7897: if (!tol) {
7898: A->symmetric_set = PETSC_TRUE;
7899: A->symmetric = *flg;
7900: if (A->symmetric) {
7901: A->structurally_symmetric_set = PETSC_TRUE;
7902: A->structurally_symmetric = PETSC_TRUE;
7903: }
7904: }
7905: } else if (A->symmetric) {
7906: *flg = PETSC_TRUE;
7907: } else if (!tol) {
7908: *flg = PETSC_FALSE;
7909: } else {
7910: if (!A->ops->issymmetric) {
7911: const MatType mattype;
7912: MatGetType(A,&mattype);
7913: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7914: }
7915: (*A->ops->issymmetric)(A,tol,flg);
7916: }
7917: return(0);
7918: }
7922: /*@
7923: MatIsHermitian - Test whether a matrix is Hermitian
7925: Collective on Mat
7927: Input Parameter:
7928: + A - the matrix to test
7929: - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
7931: Output Parameters:
7932: . flg - the result
7934: Level: intermediate
7936: Concepts: matrix^symmetry
7938: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
7939: MatIsSymmetricKnown(), MatIsSymmetric()
7940: @*/
7941: PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool *flg)
7942: {
7949: if (!A->hermitian_set) {
7950: if (!A->ops->ishermitian) {
7951: const MatType mattype;
7952: MatGetType(A,&mattype);
7953: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7954: }
7955: (*A->ops->ishermitian)(A,tol,flg);
7956: if (!tol) {
7957: A->hermitian_set = PETSC_TRUE;
7958: A->hermitian = *flg;
7959: if (A->hermitian) {
7960: A->structurally_symmetric_set = PETSC_TRUE;
7961: A->structurally_symmetric = PETSC_TRUE;
7962: }
7963: }
7964: } else if (A->hermitian) {
7965: *flg = PETSC_TRUE;
7966: } else if (!tol) {
7967: *flg = PETSC_FALSE;
7968: } else {
7969: if (!A->ops->ishermitian) {
7970: const MatType mattype;
7971: MatGetType(A,&mattype);
7972: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7973: }
7974: (*A->ops->ishermitian)(A,tol,flg);
7975: }
7976: return(0);
7977: }
7981: /*@
7982: MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
7984: Not Collective
7986: Input Parameter:
7987: . A - the matrix to check
7989: Output Parameters:
7990: + set - if the symmetric flag is set (this tells you if the next flag is valid)
7991: - flg - the result
7993: Level: advanced
7995: Concepts: matrix^symmetry
7997: Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
7998: if you want it explicitly checked
8000: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8001: @*/
8002: PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool *set,PetscBool *flg)
8003: {
8008: if (A->symmetric_set) {
8009: *set = PETSC_TRUE;
8010: *flg = A->symmetric;
8011: } else {
8012: *set = PETSC_FALSE;
8013: }
8014: return(0);
8015: }
8019: /*@
8020: MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
8022: Not Collective
8024: Input Parameter:
8025: . A - the matrix to check
8027: Output Parameters:
8028: + set - if the hermitian flag is set (this tells you if the next flag is valid)
8029: - flg - the result
8031: Level: advanced
8033: Concepts: matrix^symmetry
8035: Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8036: if you want it explicitly checked
8038: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8039: @*/
8040: PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg)
8041: {
8046: if (A->hermitian_set) {
8047: *set = PETSC_TRUE;
8048: *flg = A->hermitian;
8049: } else {
8050: *set = PETSC_FALSE;
8051: }
8052: return(0);
8053: }
8057: /*@
8058: MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
8060: Collective on Mat
8062: Input Parameter:
8063: . A - the matrix to test
8065: Output Parameters:
8066: . flg - the result
8068: Level: intermediate
8070: Concepts: matrix^symmetry
8072: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8073: @*/
8074: PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg)
8075: {
8081: if (!A->structurally_symmetric_set) {
8082: if (!A->ops->isstructurallysymmetric) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8083: (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);
8084: A->structurally_symmetric_set = PETSC_TRUE;
8085: }
8086: *flg = A->structurally_symmetric;
8087: return(0);
8088: }
8092: extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
8093: /*@
8094: MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8095: to be communicated to other processors during the MatAssemblyBegin/End() process
8097: Not collective
8099: Input Parameter:
8100: . vec - the vector
8102: Output Parameters:
8103: + nstash - the size of the stash
8104: . reallocs - the number of additional mallocs incurred.
8105: . bnstash - the size of the block stash
8106: - breallocs - the number of additional mallocs incurred.in the block stash
8107:
8108: Level: advanced
8110: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
8111:
8112: @*/
8113: PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8114: {
8117: MatStashGetInfo_Private(&mat->stash,nstash,reallocs);
8118: MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);
8119: return(0);
8120: }
8124: /*@C
8125: MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same
8126: parallel layout
8127:
8128: Collective on Mat
8130: Input Parameter:
8131: . mat - the matrix
8133: Output Parameter:
8134: + right - (optional) vector that the matrix can be multiplied against
8135: - left - (optional) vector that the matrix vector product can be stored in
8137: Level: advanced
8139: .seealso: MatCreate()
8140: @*/
8141: PetscErrorCode MatGetVecs(Mat mat,Vec *right,Vec *left)
8142: {
8148: MatCheckPreallocated(mat,1);
8149: if (mat->ops->getvecs) {
8150: (*mat->ops->getvecs)(mat,right,left);
8151: } else {
8152: PetscMPIInt size;
8153: MPI_Comm_size(((PetscObject)mat)->comm, &size);
8154: if (right) {
8155: VecCreate(((PetscObject)mat)->comm,right);
8156: VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);
8157: VecSetBlockSize(*right,mat->rmap->bs);
8158: VecSetType(*right,VECSTANDARD);
8159: PetscLayoutReference(mat->cmap,&(*right)->map);
8160: }
8161: if (left) {
8162: VecCreate(((PetscObject)mat)->comm,left);
8163: VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);
8164: VecSetBlockSize(*left,mat->rmap->bs);
8165: VecSetType(*left,VECSTANDARD);
8166: PetscLayoutReference(mat->rmap,&(*left)->map);
8167: }
8168: }
8169: return(0);
8170: }
8174: /*@C
8175: MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8176: with default values.
8178: Not Collective
8180: Input Parameters:
8181: . info - the MatFactorInfo data structure
8184: Notes: The solvers are generally used through the KSP and PC objects, for example
8185: PCLU, PCILU, PCCHOLESKY, PCICC
8187: Level: developer
8189: .seealso: MatFactorInfo
8191: Developer Note: fortran interface is not autogenerated as the f90
8192: interface defintion cannot be generated correctly [due to MatFactorInfo]
8194: @*/
8196: PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
8197: {
8201: PetscMemzero(info,sizeof(MatFactorInfo));
8202: return(0);
8203: }
8207: /*@
8208: MatPtAP - Creates the matrix product C = P^T * A * P
8210: Neighbor-wise Collective on Mat
8212: Input Parameters:
8213: + A - the matrix
8214: . P - the projection matrix
8215: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8216: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P))
8218: Output Parameters:
8219: . C - the product matrix
8221: Notes:
8222: C will be created and must be destroyed by the user with MatDestroy().
8224: This routine is currently only implemented for pairs of AIJ matrices and classes
8225: which inherit from AIJ.
8227: Level: intermediate
8229: .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
8230: @*/
8231: PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
8232: {
8238: if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8239: if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8242: MatCheckPreallocated(P,2);
8243: if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8244: if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8246: 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);
8247: if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8248: MatCheckPreallocated(A,1);
8250: if (!A->ops->ptap) {
8251: const MatType mattype;
8252: MatGetType(A,&mattype);
8253: SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix of type <%s> does not support PtAP",mattype);
8254: }
8255: PetscLogEventBegin(MAT_PtAP,A,P,0,0);
8256: (*A->ops->ptap)(A,P,scall,fill,C);
8257: PetscLogEventEnd(MAT_PtAP,A,P,0,0);
8258: return(0);
8259: }
8263: /*@
8264: MatPtAPNumeric - Computes the matrix product C = P^T * A * P
8266: Neighbor-wise Collective on Mat
8268: Input Parameters:
8269: + A - the matrix
8270: - P - the projection matrix
8272: Output Parameters:
8273: . C - the product matrix
8275: Notes:
8276: C must have been created by calling MatPtAPSymbolic and must be destroyed by
8277: the user using MatDeatroy().
8279: This routine is currently only implemented for pairs of AIJ matrices and classes
8280: which inherit from AIJ. C will be of type MATAIJ.
8282: Level: intermediate
8284: .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
8285: @*/
8286: PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C)
8287: {
8293: if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8294: if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8297: MatCheckPreallocated(P,2);
8298: if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8299: if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8302: MatCheckPreallocated(C,3);
8303: if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8304: 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);
8305: 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);
8306: 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);
8307: 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);
8308: MatCheckPreallocated(A,1);
8310: PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
8311: (*A->ops->ptapnumeric)(A,P,C);
8312: PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
8313: return(0);
8314: }
8318: /*@
8319: MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P
8321: Neighbor-wise Collective on Mat
8323: Input Parameters:
8324: + A - the matrix
8325: - P - the projection matrix
8327: Output Parameters:
8328: . C - the (i,j) structure of the product matrix
8330: Notes:
8331: C will be created and must be destroyed by the user with MatDestroy().
8333: This routine is currently only implemented for pairs of SeqAIJ matrices and classes
8334: which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using
8335: this (i,j) structure by calling MatPtAPNumeric().
8337: Level: intermediate
8339: .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
8340: @*/
8341: PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
8342: {
8348: if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8349: if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8350: if (fill <1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8353: MatCheckPreallocated(P,2);
8354: if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8355: if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8358: 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);
8359: 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);
8360: MatCheckPreallocated(A,1);
8361: PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);
8362: (*A->ops->ptapsymbolic)(A,P,fill,C);
8363: PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);
8365: /* MatSetBlockSize(*C,A->rmap->bs); NO! this is not always true -ma */
8367: return(0);
8368: }
8372: /*@
8373: MatRARt - Creates the matrix product C = R * A * R^T
8375: Neighbor-wise Collective on Mat
8377: Input Parameters:
8378: + A - the matrix
8379: . R - the projection matrix
8380: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8381: - fill - expected fill as ratio of nnz(C)/nnz(A)
8383: Output Parameters:
8384: . C - the product matrix
8386: Notes:
8387: C will be created and must be destroyed by the user with MatDestroy().
8389: This routine is currently only implemented for pairs of AIJ matrices and classes
8390: which inherit from AIJ.
8392: Level: intermediate
8394: .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
8395: @*/
8396: PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
8397: {
8403: if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8404: if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8407: MatCheckPreallocated(R,2);
8408: if (!R->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8409: if (R->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8411: 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);
8412: if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8413: MatCheckPreallocated(A,1);
8415: if (!A->ops->rart) {
8416: const MatType mattype;
8417: MatGetType(A,&mattype);
8418: SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix of type <%s> does not support RARt",mattype);
8419: }
8420: PetscLogEventBegin(MAT_RARt,A,R,0,0);
8421: (*A->ops->rart)(A,R,scall,fill,C);
8422: PetscLogEventEnd(MAT_RARt,A,R,0,0);
8423: return(0);
8424: }
8428: /*@
8429: MatRARtNumeric - Computes the matrix product C = R * A * R^T
8431: Neighbor-wise Collective on Mat
8433: Input Parameters:
8434: + A - the matrix
8435: - R - the projection matrix
8437: Output Parameters:
8438: . C - the product matrix
8440: Notes:
8441: C must have been created by calling MatRARtSymbolic and must be destroyed by
8442: the user using MatDeatroy().
8444: This routine is currently only implemented for pairs of AIJ matrices and classes
8445: which inherit from AIJ. C will be of type MATAIJ.
8447: Level: intermediate
8449: .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
8450: @*/
8451: PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C)
8452: {
8458: if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8459: if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8462: MatCheckPreallocated(R,2);
8463: if (!R->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8464: if (R->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8467: MatCheckPreallocated(C,3);
8468: if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8469: 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);
8470: 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);
8471: 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);
8472: 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);
8473: MatCheckPreallocated(A,1);
8475: PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);
8476: (*A->ops->rartnumeric)(A,R,C);
8477: PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);
8478: return(0);
8479: }
8483: /*@
8484: MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T
8486: Neighbor-wise Collective on Mat
8488: Input Parameters:
8489: + A - the matrix
8490: - R - the projection matrix
8492: Output Parameters:
8493: . C - the (i,j) structure of the product matrix
8495: Notes:
8496: C will be created and must be destroyed by the user with MatDestroy().
8498: This routine is currently only implemented for pairs of SeqAIJ matrices and classes
8499: which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using
8500: this (i,j) structure by calling MatRARtNumeric().
8502: Level: intermediate
8504: .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
8505: @*/
8506: PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
8507: {
8513: if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8514: if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8515: if (fill <1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8518: MatCheckPreallocated(R,2);
8519: if (!R->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8520: if (R->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8523: 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);
8524: 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);
8525: MatCheckPreallocated(A,1);
8526: PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);
8527: (*A->ops->rartsymbolic)(A,R,fill,C);
8528: PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);
8530: MatSetBlockSize(*C,A->rmap->bs);
8531: return(0);
8532: }
8534: extern PetscErrorCode MatQueryOp(MPI_Comm comm, void (**function)(void), const char op[], PetscInt numArgs, ...);
8538: /*@
8539: MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
8541: Neighbor-wise Collective on Mat
8543: Input Parameters:
8544: + A - the left matrix
8545: . B - the right matrix
8546: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8547: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
8548: if the result is a dense matrix this is irrelevent
8550: Output Parameters:
8551: . C - the product matrix
8553: Notes:
8554: Unless scall is MAT_REUSE_MATRIX C will be created.
8556: MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8557:
8558: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8559: actually needed.
8561: If you have many matrices with the same non-zero structure to multiply, you
8562: should either
8563: $ 1) use MAT_REUSE_MATRIX in all calls but the first or
8564: $ 2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
8566: Level: intermediate
8568: .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(), MatMatTransposeMult(), MatPtAP()
8569: @*/
8570: PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8571: {
8573: PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8574: PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8575: PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat *)=PETSC_NULL;
8580: if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8581: if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8584: MatCheckPreallocated(B,2);
8585: if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8586: if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8588: 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);
8589: if (scall == MAT_REUSE_MATRIX){
8592: PetscLogEventBegin(MAT_MatMult,A,B,0,0);
8593: (*(*C)->ops->matmult)(A,B,scall,fill,C);
8594: PetscLogEventEnd(MAT_MatMult,A,B,0,0);
8595: }
8596: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8597: if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8598: MatCheckPreallocated(A,1);
8600: fA = A->ops->matmult;
8601: fB = B->ops->matmult;
8602: if (fB == fA) {
8603: if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
8604: mult = fB;
8605: } else {
8606: /* dispatch based on the type of A and B from their PetscObject's PetscFLists. */
8607: char multname[256];
8608: PetscStrcpy(multname,"MatMatMult_");
8609: PetscStrcat(multname,((PetscObject)A)->type_name);
8610: PetscStrcat(multname,"_");
8611: PetscStrcat(multname,((PetscObject)B)->type_name);
8612: PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
8613: PetscObjectQueryFunction((PetscObject)B,multname,(void (**)(void))&mult);
8614: if(!mult){
8615: /* dual dispatch using MatQueryOp */
8616: MatQueryOp(((PetscObject)A)->comm, (PetscVoidFunction*)(&mult), "MatMatMult",2,((PetscObject)A)->type_name,((PetscObject)B)->type_name);
8617: 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);
8618: }
8619: }
8620: PetscLogEventBegin(MAT_MatMult,A,B,0,0);
8621: (*mult)(A,B,scall,fill,C);
8622: PetscLogEventEnd(MAT_MatMult,A,B,0,0);
8623: return(0);
8624: }
8628: /*@
8629: MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
8630: of the matrix-matrix product C=A*B. Call this routine before calling MatMatMultNumeric().
8632: Neighbor-wise Collective on Mat
8634: Input Parameters:
8635: + A - the left matrix
8636: . B - the right matrix
8637: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
8638: if C is a dense matrix this is irrelevent
8639:
8640: Output Parameters:
8641: . C - the product matrix
8643: Notes:
8644: Unless scall is MAT_REUSE_MATRIX C will be created.
8646: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8647: actually needed.
8649: This routine is currently implemented for
8650: - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
8651: - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8652: - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
8654: Level: intermediate
8656: Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
8657: We should incorporate them into PETSc.
8659: .seealso: MatMatMult(), MatMatMultNumeric()
8660: @*/
8661: PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
8662: {
8664: PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat *);
8665: PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat *);
8666: PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat *)=PETSC_NULL;
8671: if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8672: if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8676: MatCheckPreallocated(B,2);
8677: if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8678: if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8681: 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);
8682: if (fill == PETSC_DEFAULT) fill = 2.0;
8683: if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8684: MatCheckPreallocated(A,1);
8685:
8686: Asymbolic = A->ops->matmultsymbolic;
8687: Bsymbolic = B->ops->matmultsymbolic;
8688: if (Asymbolic == Bsymbolic){
8689: if (!Bsymbolic) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
8690: symbolic = Bsymbolic;
8691: } else { /* dispatch based on the type of A and B */
8692: char symbolicname[256];
8693: PetscStrcpy(symbolicname,"MatMatMultSymbolic_");
8694: PetscStrcat(symbolicname,((PetscObject)A)->type_name);
8695: PetscStrcat(symbolicname,"_");
8696: PetscStrcat(symbolicname,((PetscObject)B)->type_name);
8697: PetscStrcat(symbolicname,"_C");
8698: PetscObjectQueryFunction((PetscObject)B,symbolicname,(void (**)(void))&symbolic);
8699: 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);
8700: }
8701: PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);
8702: (*symbolic)(A,B,fill,C);
8703: PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);
8704: return(0);
8705: }
8709: /*@
8710: MatMatMultNumeric - Performs the numeric matrix-matrix product.
8711: Call this routine after first calling MatMatMultSymbolic().
8713: Neighbor-wise Collective on Mat
8715: Input Parameters:
8716: + A - the left matrix
8717: - B - the right matrix
8719: Output Parameters:
8720: . C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
8722: Notes:
8723: C must have been created with MatMatMultSymbolic().
8725: This routine is currently implemented for
8726: - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
8727: - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8728: - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
8730: Level: intermediate
8732: .seealso: MatMatMult(), MatMatMultSymbolic()
8733: @*/
8734: PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C)
8735: {
8737: PetscErrorCode (*Anumeric)(Mat,Mat,Mat);
8738: PetscErrorCode (*Bnumeric)(Mat,Mat,Mat);
8739: PetscErrorCode (*numeric)(Mat,Mat,Mat)=PETSC_NULL;
8744: if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8745: if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8749: MatCheckPreallocated(B,2);
8750: if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8751: if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8755: MatCheckPreallocated(C,3);
8756: if (!C->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8757: if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8759: 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);
8760: 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);
8761: 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);
8762: MatCheckPreallocated(A,1);
8764: Anumeric = A->ops->matmultnumeric;
8765: Bnumeric = B->ops->matmultnumeric;
8766: if (Anumeric == Bnumeric){
8767: if (!Bnumeric) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMultNumeric not supported for B of type %s",((PetscObject)B)->type_name);
8768: numeric = Bnumeric;
8769: } else {
8770: char numericname[256];
8771: PetscStrcpy(numericname,"MatMatMultNumeric_");
8772: PetscStrcat(numericname,((PetscObject)A)->type_name);
8773: PetscStrcat(numericname,"_");
8774: PetscStrcat(numericname,((PetscObject)B)->type_name);
8775: PetscStrcat(numericname,"_C");
8776: PetscObjectQueryFunction((PetscObject)B,numericname,(void (**)(void))&numeric);
8777: if (!numeric)
8778: 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);
8779: }
8780: PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);
8781: (*numeric)(A,B,C);
8782: PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);
8783: return(0);
8784: }
8788: /*@
8789: MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.
8791: Neighbor-wise Collective on Mat
8793: Input Parameters:
8794: + A - the left matrix
8795: . B - the right matrix
8796: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8797: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
8799: Output Parameters:
8800: . C - the product matrix
8802: Notes:
8803: C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
8805: MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8807: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8808: actually needed.
8810: This routine is currently only implemented for pairs of SeqAIJ matrices. C will be of type MATSEQAIJ.
8812: Level: intermediate
8814: .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
8815: @*/
8816: PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8817: {
8819: PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8820: PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8825: if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8826: if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8829: MatCheckPreallocated(B,2);
8830: if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8831: if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8833: 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);
8834: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8835: if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8836: MatCheckPreallocated(A,1);
8838: fA = A->ops->mattransposemult;
8839: if (!fA) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
8840: fB = B->ops->mattransposemult;
8841: if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
8842: 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);
8844: if (scall == MAT_INITIAL_MATRIX){
8845: PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);
8846: (*A->ops->mattransposemultsymbolic)(A,B,fill,C);
8847: PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);
8848: }
8849: PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);
8850: (*A->ops->mattransposemultnumeric)(A,B,*C);
8851: PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);
8852: return(0);
8853: }
8857: /*@
8858: MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.
8860: Neighbor-wise Collective on Mat
8862: Input Parameters:
8863: + A - the left matrix
8864: . B - the right matrix
8865: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8866: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
8868: Output Parameters:
8869: . C - the product matrix
8871: Notes:
8872: C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
8874: MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8876: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8877: actually needed.
8879: This routine is currently only implemented for pairs of SeqAIJ matrices and pairs of SeqDense matrices and classes
8880: which inherit from SeqAIJ. C will be of type MATSEQAIJ.
8882: Level: intermediate
8884: .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
8885: @*/
8886: PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8887: {
8889: PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8890: PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8891: PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*);
8896: if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8897: if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8900: MatCheckPreallocated(B,2);
8901: if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8902: if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8904: 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);
8905: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8906: if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8907: MatCheckPreallocated(A,1);
8909: fA = A->ops->transposematmult;
8910: if (!fA) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
8911: fB = B->ops->transposematmult;
8912: if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatTransposeMatMult not supported for B of type %s",((PetscObject)B)->type_name);
8913: if (fB==fA) {
8914: transposematmult = fA;
8915: }
8916: else {
8917: /* dual dispatch using MatQueryOp */
8918: MatQueryOp(((PetscObject)A)->comm, (PetscVoidFunction*)(&transposematmult), "MatTansposeMatMult",2,((PetscObject)A)->type_name,((PetscObject)B)->type_name);
8919: if(!transposematmult)
8920: 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);
8921: }
8922: PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);
8923: (*transposematmult)(A,B,scall,fill,C);
8924: PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);
8925: return(0);
8926: }
8930: /*@C
8931: MatGetRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
8933: Collective on Mat
8935: Input Parameters:
8936: + mat - the matrix
8937: . nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
8938: . subcomm - MPI communicator split from the communicator where mat resides in
8939: . mlocal_red - number of local rows of the redundant matrix
8940: - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8942: Output Parameter:
8943: . matredundant - redundant matrix
8945: Notes:
8946: MAT_REUSE_MATRIX can only be used when the nonzero structure of the
8947: original matrix has not changed from that last call to MatGetRedundantMatrix().
8949: This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
8950: calling it.
8952: Only MPIAIJ matrix is supported.
8953:
8954: Level: advanced
8956: Concepts: subcommunicator
8957: Concepts: duplicate matrix
8959: .seealso: MatDestroy()
8960: @*/
8961: PetscErrorCode MatGetRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,PetscInt mlocal_red,MatReuse reuse,Mat *matredundant)
8962: {
8967: if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
8970: }
8971: if (!mat->ops->getredundantmatrix) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8972: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8973: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8974: MatCheckPreallocated(mat,1);
8976: PetscLogEventBegin(MAT_GetRedundantMatrix,mat,0,0,0);
8977: (*mat->ops->getredundantmatrix)(mat,nsubcomm,subcomm,mlocal_red,reuse,matredundant);
8978: PetscLogEventEnd(MAT_GetRedundantMatrix,mat,0,0,0);
8979: return(0);
8980: }
8984: /*@C
8985: MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
8986: a given 'mat' object. Each submatrix can span multiple procs.
8988: Collective on Mat
8990: Input Parameters:
8991: + mat - the matrix
8992: . subcomm - the subcommunicator obtained by com_split(comm)
8993: - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8995: Output Parameter:
8996: . subMat - 'parallel submatrices each spans a given subcomm
8998: Notes:
8999: The submatrix partition across processors is dicated by 'subComm' a
9000: communicator obtained by com_split(comm). The comm_split
9001: is not restriced to be grouped with consequitive original ranks.
9003: Due the comm_split() usage, the parallel layout of the submatrices
9004: map directly to the layout of the original matrix [wrt the local
9005: row,col partitioning]. So the original 'DiagonalMat' naturally maps
9006: into the 'DiagonalMat' of the subMat, hence it is used directly from
9007: the subMat. However the offDiagMat looses some columns - and this is
9008: reconstructed with MatSetValues()
9010: Level: advanced
9012: Concepts: subcommunicator
9013: Concepts: submatrices
9015: .seealso: MatGetSubMatrices()
9016: @*/
9017: PetscErrorCode MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat* subMat)
9018: {
9020: PetscMPIInt commsize,subCommSize;
9023: MPI_Comm_size(((PetscObject)mat)->comm,&commsize);
9024: MPI_Comm_size(subComm,&subCommSize);
9025: if (subCommSize > commsize) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
9026:
9027: PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);
9028: (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);
9029: PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);
9030: return(0);
9031: }
9035: /*@
9036: MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
9038: Not Collective
9040: Input Arguments:
9041: mat - matrix to extract local submatrix from
9042: isrow - local row indices for submatrix
9043: iscol - local column indices for submatrix
9045: Output Arguments:
9046: submat - the submatrix
9048: Level: intermediate
9050: Notes:
9051: The submat should be returned with MatRestoreLocalSubMatrix().
9053: Depending on the format of mat, the returned submat may not implement MatMult(). Its communicator may be
9054: the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
9056: The submat always implements MatSetValuesLocal(). If isrow and iscol have the same block size, then
9057: MatSetValuesBlockedLocal() will also be implemented.
9059: .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef()
9060: @*/
9061: PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9062: {
9072: if (mat->ops->getlocalsubmatrix) {
9073: (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);
9074: } else {
9075: MatCreateLocalRef(mat,isrow,iscol,submat);
9076: }
9077: return(0);
9078: }
9082: /*@
9083: MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
9085: Not Collective
9087: Input Arguments:
9088: mat - matrix to extract local submatrix from
9089: isrow - local row indices for submatrix
9090: iscol - local column indices for submatrix
9091: submat - the submatrix
9093: Level: intermediate
9095: .seealso: MatGetLocalSubMatrix()
9096: @*/
9097: PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9098: {
9109: if (mat->ops->restorelocalsubmatrix) {
9110: (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);
9111: } else {
9112: MatDestroy(submat);
9113: }
9114: *submat = PETSC_NULL;
9115: return(0);
9116: }
9118: /* --------------------------------------------------------*/
9121: /*@
9122: MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no entry in the matrix
9124: Collective on Mat
9126: Input Parameter:
9127: . mat - the matrix
9129: Output Parameter:
9130: . is - if any rows have zero diagonals this contains the list of them
9132: Level: developer
9134: Concepts: matrix-vector product
9136: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
9137: @*/
9138: PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is)
9139: {
9145: if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9146: if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9148: if (!mat->ops->findzerodiagonals) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"This matrix type does not have a find zero diagonals defined");
9149: (*mat->ops->findzerodiagonals)(mat,is);
9150: return(0);
9151: }
9155: /*@C
9156: MatInvertBlockDiagonal - Inverts the block diagonal entries.
9158: Collective on Mat
9160: Input Parameters:
9161: . mat - the matrix
9163: Output Parameters:
9164: . values - the block inverses in column major order (FORTRAN-like)
9166: Note:
9167: This routine is not available from Fortran.
9169: Level: advanced
9170: @*/
9171: PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
9172: {
9177: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9178: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9179: if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
9180: (*mat->ops->invertblockdiagonal)(mat,values);
9181: return(0);
9182: }
9186: /*@C
9187: MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
9188: via MatTransposeColoringCreate().
9190: Collective on MatTransposeColoring
9192: Input Parameter:
9193: . c - coloring context
9195: Level: intermediate
9197: .seealso: MatTransposeColoringCreate()
9198: @*/
9199: PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c)
9200: {
9201: PetscErrorCode ierr;
9202: MatTransposeColoring matcolor=*c;
9205: if (!matcolor) return(0);
9206: if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; return(0);}
9208: PetscFree(matcolor->ncolumns);
9209: PetscFree(matcolor->nrows);
9210: PetscFree(matcolor->colorforrow);
9211: PetscFree2(matcolor->rows,matcolor->columnsforspidx);
9212: PetscFree(matcolor->colorforcol);
9213: PetscFree(matcolor->columns);
9214: PetscHeaderDestroy(c);
9215: return(0);
9216: }
9220: /*@C
9221: MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
9222: a MatTransposeColoring context has been created, computes a dense B^T by Apply
9223: MatTransposeColoring to sparse B.
9225: Collective on MatTransposeColoring
9227: Input Parameters:
9228: + B - sparse matrix B
9229: . Btdense - symbolic dense matrix B^T
9230: - coloring - coloring context created with MatTransposeColoringCreate()
9232: Output Parameter:
9233: . Btdense - dense matrix B^T
9235: Options Database Keys:
9236: + -mat_transpose_coloring_view - Activates basic viewing or coloring
9237: . -mat_transpose_coloring_view_draw - Activates drawing of coloring
9238: - -mat_transpose_coloring_view_info - Activates viewing of coloring info
9240: Level: intermediate
9242: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy()
9244: .keywords: coloring
9245: @*/
9246: PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
9247: {
9254:
9255: if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
9256: (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);
9257: return(0);
9258: }
9262: /*@C
9263: MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
9264: a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
9265: in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
9266: Csp from Cden.
9268: Collective on MatTransposeColoring
9270: Input Parameters:
9271: + coloring - coloring context created with MatTransposeColoringCreate()
9272: - Cden - matrix product of a sparse matrix and a dense matrix Btdense
9274: Output Parameter:
9275: . Csp - sparse matrix
9277: Options Database Keys:
9278: + -mat_multtranspose_coloring_view - Activates basic viewing or coloring
9279: . -mat_multtranspose_coloring_view_draw - Activates drawing of coloring
9280: - -mat_multtranspose_coloring_view_info - Activates viewing of coloring info
9282: Level: intermediate
9284: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()
9286: .keywords: coloring
9287: @*/
9288: PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
9289: {
9296:
9297: if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
9298: (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);
9299: return(0);
9300: }
9304: /*@C
9305: MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.
9307: Collective on Mat
9309: Input Parameters:
9310: + mat - the matrix product C
9311: - iscoloring - the coloring of the matrix; usually obtained with MatGetColoring() or DMCreateColoring()
9313: Output Parameter:
9314: . color - the new coloring context
9315:
9316: Level: intermediate
9318: .seealso: MatTransposeColoringDestroy(), MatTransposeColoringSetFromOptions(), MatTransColoringApplySpToDen(),
9319: MatTransColoringApplyDen()ToSp, MatTransposeColoringView(),
9320: @*/
9321: PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
9322: {
9323: MatTransposeColoring c;
9324: MPI_Comm comm;
9325: PetscErrorCode ierr;
9328: PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);
9329: PetscObjectGetComm((PetscObject)mat,&comm);
9330: PetscHeaderCreate(c,_p_MatTransposeColoring,int,MAT_TRANSPOSECOLORING_CLASSID,0,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,0);
9332: c->ctype = iscoloring->ctype;
9333: if (mat->ops->transposecoloringcreate) {
9334: (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);
9335: } else SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Code not yet written for this matrix type");
9337: *color = c;
9338: PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);
9339: return(0);
9340: }