Actual source code: matrix.c
petsc-3.5.4 2015-05-23
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_COLORING_CLASSID;
12: PetscClassId MAT_FDCOLORING_CLASSID;
13: PetscClassId MAT_TRANSPOSECOLORING_CLASSID;
15: PetscLogEvent MAT_Mult, MAT_Mults, MAT_MultConstrained, MAT_MultAdd, MAT_MultTranspose;
16: PetscLogEvent MAT_MultTransposeConstrained, MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve;
17: PetscLogEvent MAT_SolveTransposeAdd, MAT_SOR, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic;
18: PetscLogEvent MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor;
19: PetscLogEvent MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin;
20: PetscLogEvent MAT_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetRowIJ, MAT_GetSubMatrices, MAT_GetOrdering, MAT_GetRedundantMatrix, MAT_GetSeqNonzeroStructure;
21: PetscLogEvent MAT_IncreaseOverlap, MAT_Partitioning, MAT_Coarsen, MAT_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate;
22: PetscLogEvent MAT_FDColoringSetUp, MAT_FDColoringApply,MAT_Transpose,MAT_FDColoringFunction;
23: PetscLogEvent MAT_TransposeColoringCreate;
24: PetscLogEvent MAT_MatMult, MAT_MatMultSymbolic, MAT_MatMultNumeric;
25: PetscLogEvent MAT_PtAP, MAT_PtAPSymbolic, MAT_PtAPNumeric,MAT_RARt, MAT_RARtSymbolic, MAT_RARtNumeric;
26: PetscLogEvent MAT_MatTransposeMult, MAT_MatTransposeMultSymbolic, MAT_MatTransposeMultNumeric;
27: PetscLogEvent MAT_TransposeMatMult, MAT_TransposeMatMultSymbolic, MAT_TransposeMatMultNumeric;
28: PetscLogEvent MAT_MatMatMult, MAT_MatMatMultSymbolic, MAT_MatMatMultNumeric;
29: PetscLogEvent MAT_MultHermitianTranspose,MAT_MultHermitianTransposeAdd;
30: PetscLogEvent MAT_Getsymtranspose, MAT_Getsymtransreduced, MAT_Transpose_SeqAIJ, MAT_GetBrowsOfAcols;
31: PetscLogEvent MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym;
32: PetscLogEvent MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure;
33: PetscLogEvent MAT_GetMultiProcBlock;
34: PetscLogEvent MAT_CUSPCopyToGPU, MAT_CUSPARSECopyToGPU, MAT_SetValuesBatch, MAT_SetValuesBatchI, MAT_SetValuesBatchII, MAT_SetValuesBatchIII, MAT_SetValuesBatchIV;
35: PetscLogEvent MAT_ViennaCLCopyToGPU;
36: PetscLogEvent MAT_Merge,MAT_Residual;
37: PetscLogEvent Mat_Coloring_Apply,Mat_Coloring_Comm,Mat_Coloring_Local,Mat_Coloring_ISCreate,Mat_Coloring_SetUp,Mat_Coloring_Weights;
39: const char *const MatFactorTypes[] = {"NONE","LU","CHOLESKY","ILU","ICC","ILUDT","MatFactorType","MAT_FACTOR_",0};
43: /*@
44: MatSetRandom - Sets all components of a matrix to random numbers. For sparse matrices that have been preallocated it randomly selects appropriate locations
46: Logically Collective on Vec
48: Input Parameters:
49: + x - the vector
50: - rctx - the random number context, formed by PetscRandomCreate(), or NULL and
51: it will create one internally.
53: Output Parameter:
54: . x - the vector
56: Example of Usage:
57: .vb
58: PetscRandomCreate(PETSC_COMM_WORLD,&rctx);
59: VecSetRandom(x,rctx);
60: PetscRandomDestroy(rctx);
61: .ve
63: Level: intermediate
65: Concepts: vector^setting to random
66: Concepts: random^vector
68: .seealso: MatZeroEntries(), MatSetValues(), PetscRandomCreate(), PetscRandomDestroy()
69: @*/
70: PetscErrorCode MatSetRandom(Mat x,PetscRandom rctx)
71: {
73: PetscRandom randObj = NULL;
80: if (!rctx) {
81: MPI_Comm comm;
82: PetscObjectGetComm((PetscObject)x,&comm);
83: PetscRandomCreate(comm,&randObj);
84: PetscRandomSetFromOptions(randObj);
85: rctx = randObj;
86: }
88: PetscLogEventBegin(VEC_SetRandom,x,rctx,0,0);
89: (*x->ops->setrandom)(x,rctx);
90: PetscLogEventEnd(VEC_SetRandom,x,rctx,0,0);
92: x->assembled = PETSC_TRUE;
93: PetscRandomDestroy(&randObj);
94: return(0);
95: }
100: /*@
101: MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix
103: Input Parameter:
104: . A - the matrix
106: Output Parameter:
107: . keptrows - the rows that are not completely zero
109: Level: intermediate
111: @*/
112: PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows)
113: {
118: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
119: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
120: if (!mat->ops->findnonzerorows) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not coded for this matrix type");
121: (*mat->ops->findnonzerorows)(mat,keptrows);
122: return(0);
123: }
127: /*@
128: MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling
130: Not Collective
132: Input Parameters:
133: . A - the matrix
135: Output Parameters:
136: . a - the diagonal part (which is a SEQUENTIAL matrix)
138: Notes: see the manual page for MatCreateAIJ() for more information on the "diagonal part" of the matrix.
140: Level: advanced
142: @*/
143: PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a)
144: {
145: PetscErrorCode ierr,(*f)(Mat,Mat*);
146: PetscMPIInt size;
152: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
153: MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);
154: PetscObjectQueryFunction((PetscObject)A,"MatGetDiagonalBlock_C",&f);
155: if (f) {
156: (*f)(A,a);
157: return(0);
158: } else if (size == 1) {
159: *a = A;
160: } else {
161: MatType mattype;
162: MatGetType(A,&mattype);
163: SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix type %s does not support getting diagonal block",mattype);
164: }
165: return(0);
166: }
170: /*@
171: MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries.
173: Collective on Mat
175: Input Parameters:
176: . mat - the matrix
178: Output Parameter:
179: . trace - the sum of the diagonal entries
181: Level: advanced
183: @*/
184: PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace)
185: {
187: Vec diag;
190: MatGetVecs(mat,&diag,NULL);
191: MatGetDiagonal(mat,diag);
192: VecSum(diag,trace);
193: VecDestroy(&diag);
194: return(0);
195: }
199: /*@
200: MatRealPart - Zeros out the imaginary part of the matrix
202: Logically Collective on Mat
204: Input Parameters:
205: . mat - the matrix
207: Level: advanced
210: .seealso: MatImaginaryPart()
211: @*/
212: PetscErrorCode MatRealPart(Mat mat)
213: {
219: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
220: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
221: if (!mat->ops->realpart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
222: MatCheckPreallocated(mat,1);
223: (*mat->ops->realpart)(mat);
224: #if defined(PETSC_HAVE_CUSP)
225: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
226: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
227: }
228: #endif
229: #if defined(PETSC_HAVE_VIENNACL)
230: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
231: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
232: }
233: #endif
234: return(0);
235: }
239: /*@C
240: MatGetGhosts - Get the global index of all ghost nodes defined by the sparse matrix
242: Collective on Mat
244: Input Parameter:
245: . mat - the matrix
247: Output Parameters:
248: + nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block)
249: - ghosts - the global indices of the ghost points
251: Notes: the nghosts and ghosts are suitable to pass into VecCreateGhost()
253: Level: advanced
255: @*/
256: PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[])
257: {
263: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
264: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
265: if (!mat->ops->getghosts) {
266: if (nghosts) *nghosts = 0;
267: if (ghosts) *ghosts = 0;
268: } else {
269: (*mat->ops->getghosts)(mat,nghosts,ghosts);
270: }
271: return(0);
272: }
277: /*@
278: MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part
280: Logically Collective on Mat
282: Input Parameters:
283: . mat - the matrix
285: Level: advanced
288: .seealso: MatRealPart()
289: @*/
290: PetscErrorCode MatImaginaryPart(Mat mat)
291: {
297: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
298: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
299: if (!mat->ops->imaginarypart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
300: MatCheckPreallocated(mat,1);
301: (*mat->ops->imaginarypart)(mat);
302: #if defined(PETSC_HAVE_CUSP)
303: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
304: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
305: }
306: #endif
307: #if defined(PETSC_HAVE_VIENNACL)
308: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
309: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
310: }
311: #endif
312: return(0);
313: }
317: /*@
318: MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices)
320: Collective on Mat
322: Input Parameter:
323: . mat - the matrix
325: Output Parameters:
326: + missing - is any diagonal missing
327: - dd - first diagonal entry that is missing (optional)
329: Level: advanced
332: .seealso: MatRealPart()
333: @*/
334: PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd)
335: {
341: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
342: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
343: if (!mat->ops->missingdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
344: (*mat->ops->missingdiagonal)(mat,missing,dd);
345: return(0);
346: }
350: /*@C
351: MatGetRow - Gets a row of a matrix. You MUST call MatRestoreRow()
352: for each row that you get to ensure that your application does
353: not bleed memory.
355: Not Collective
357: Input Parameters:
358: + mat - the matrix
359: - row - the row to get
361: Output Parameters:
362: + ncols - if not NULL, the number of nonzeros in the row
363: . cols - if not NULL, the column numbers
364: - vals - if not NULL, the values
366: Notes:
367: This routine is provided for people who need to have direct access
368: to the structure of a matrix. We hope that we provide enough
369: high-level matrix routines that few users will need it.
371: MatGetRow() always returns 0-based column indices, regardless of
372: whether the internal representation is 0-based (default) or 1-based.
374: For better efficiency, set cols and/or vals to NULL if you do
375: not wish to extract these quantities.
377: The user can only examine the values extracted with MatGetRow();
378: the values cannot be altered. To change the matrix entries, one
379: must use MatSetValues().
381: You can only have one call to MatGetRow() outstanding for a particular
382: matrix at a time, per processor. MatGetRow() can only obtain rows
383: associated with the given processor, it cannot get rows from the
384: other processors; for that we suggest using MatGetSubMatrices(), then
385: MatGetRow() on the submatrix. The row indix passed to MatGetRows()
386: is in the global number of rows.
388: Fortran Notes:
389: The calling sequence from Fortran is
390: .vb
391: MatGetRow(matrix,row,ncols,cols,values,ierr)
392: Mat matrix (input)
393: integer row (input)
394: integer ncols (output)
395: integer cols(maxcols) (output)
396: double precision (or double complex) values(maxcols) output
397: .ve
398: where maxcols >= maximum nonzeros in any row of the matrix.
401: Caution:
402: Do not try to change the contents of the output arrays (cols and vals).
403: In some cases, this may corrupt the matrix.
405: Level: advanced
407: Concepts: matrices^row access
409: .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatGetSubMatrices(), MatGetDiagonal()
410: @*/
411: PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
412: {
414: PetscInt incols;
419: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
420: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
421: if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
422: MatCheckPreallocated(mat,1);
423: PetscLogEventBegin(MAT_GetRow,mat,0,0,0);
424: (*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals);
425: if (ncols) *ncols = incols;
426: PetscLogEventEnd(MAT_GetRow,mat,0,0,0);
427: return(0);
428: }
432: /*@
433: MatConjugate - replaces the matrix values with their complex conjugates
435: Logically Collective on Mat
437: Input Parameters:
438: . mat - the matrix
440: Level: advanced
442: .seealso: VecConjugate()
443: @*/
444: PetscErrorCode MatConjugate(Mat mat)
445: {
446: #if defined(PETSC_USE_COMPLEX)
451: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
452: if (!mat->ops->conjugate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not provided for this matrix format, send email to petsc-maint@mcs.anl.gov");
453: (*mat->ops->conjugate)(mat);
454: #if defined(PETSC_HAVE_CUSP)
455: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
456: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
457: }
458: #endif
459: #if defined(PETSC_HAVE_VIENNACL)
460: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
461: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
462: }
463: #endif
464: return(0);
465: #else
466: return 0;
467: #endif
468: }
472: /*@C
473: MatRestoreRow - Frees any temporary space allocated by MatGetRow().
475: Not Collective
477: Input Parameters:
478: + mat - the matrix
479: . row - the row to get
480: . ncols, cols - the number of nonzeros and their columns
481: - vals - if nonzero the column values
483: Notes:
484: This routine should be called after you have finished examining the entries.
486: This routine zeros out ncols, cols, and vals. This is to prevent accidental
487: us of the array after it has been restored. If you pass NULL, it will
488: not zero the pointers. Use of cols or vals after MatRestoreRow is invalid.
490: Fortran Notes:
491: The calling sequence from Fortran is
492: .vb
493: MatRestoreRow(matrix,row,ncols,cols,values,ierr)
494: Mat matrix (input)
495: integer row (input)
496: integer ncols (output)
497: integer cols(maxcols) (output)
498: double precision (or double complex) values(maxcols) output
499: .ve
500: Where maxcols >= maximum nonzeros in any row of the matrix.
502: In Fortran MatRestoreRow() MUST be called after MatGetRow()
503: before another call to MatGetRow() can be made.
505: Level: advanced
507: .seealso: MatGetRow()
508: @*/
509: PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
510: {
516: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
517: if (!mat->ops->restorerow) return(0);
518: (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);
519: if (ncols) *ncols = 0;
520: if (cols) *cols = NULL;
521: if (vals) *vals = NULL;
522: return(0);
523: }
527: /*@
528: MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format.
529: You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag.
531: Not Collective
533: Input Parameters:
534: + mat - the matrix
536: Notes:
537: 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.
539: Level: advanced
541: Concepts: matrices^row access
543: .seealso: MatRestoreRowRowUpperTriangular()
544: @*/
545: PetscErrorCode MatGetRowUpperTriangular(Mat mat)
546: {
552: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
553: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
554: if (!mat->ops->getrowuppertriangular) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
555: MatCheckPreallocated(mat,1);
556: (*mat->ops->getrowuppertriangular)(mat);
557: return(0);
558: }
562: /*@
563: MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format.
565: Not Collective
567: Input Parameters:
568: + mat - the matrix
570: Notes:
571: This routine should be called after you have finished MatGetRow/MatRestoreRow().
574: Level: advanced
576: .seealso: MatGetRowUpperTriangular()
577: @*/
578: PetscErrorCode MatRestoreRowUpperTriangular(Mat mat)
579: {
584: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
585: if (!mat->ops->restorerowuppertriangular) return(0);
586: (*mat->ops->restorerowuppertriangular)(mat);
587: return(0);
588: }
592: /*@C
593: MatSetOptionsPrefix - Sets the prefix used for searching for all
594: Mat options in the database.
596: Logically Collective on Mat
598: Input Parameter:
599: + A - the Mat context
600: - prefix - the prefix to prepend to all option names
602: Notes:
603: A hyphen (-) must NOT be given at the beginning of the prefix name.
604: The first character of all runtime options is AUTOMATICALLY the hyphen.
606: Level: advanced
608: .keywords: Mat, set, options, prefix, database
610: .seealso: MatSetFromOptions()
611: @*/
612: PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[])
613: {
618: PetscObjectSetOptionsPrefix((PetscObject)A,prefix);
619: return(0);
620: }
624: /*@C
625: MatAppendOptionsPrefix - Appends to the prefix used for searching for all
626: Mat options in the database.
628: Logically Collective on Mat
630: Input Parameters:
631: + A - the Mat context
632: - prefix - the prefix to prepend to all option names
634: Notes:
635: A hyphen (-) must NOT be given at the beginning of the prefix name.
636: The first character of all runtime options is AUTOMATICALLY the hyphen.
638: Level: advanced
640: .keywords: Mat, append, options, prefix, database
642: .seealso: MatGetOptionsPrefix()
643: @*/
644: PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[])
645: {
650: PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);
651: return(0);
652: }
656: /*@C
657: MatGetOptionsPrefix - Sets the prefix used for searching for all
658: Mat options in the database.
660: Not Collective
662: Input Parameter:
663: . A - the Mat context
665: Output Parameter:
666: . prefix - pointer to the prefix string used
668: Notes: On the fortran side, the user should pass in a string 'prefix' of
669: sufficient length to hold the prefix.
671: Level: advanced
673: .keywords: Mat, get, options, prefix, database
675: .seealso: MatAppendOptionsPrefix()
676: @*/
677: PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[])
678: {
683: PetscObjectGetOptionsPrefix((PetscObject)A,prefix);
684: return(0);
685: }
689: /*@
690: MatSetUp - Sets up the internal matrix data structures for the later use.
692: Collective on Mat
694: Input Parameters:
695: . A - the Mat context
697: Notes:
698: If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used.
700: If a suitable preallocation routine is used, this function does not need to be called.
702: See the Performance chapter of the PETSc users manual for how to preallocate matrices
704: Level: beginner
706: .keywords: Mat, setup
708: .seealso: MatCreate(), MatDestroy()
709: @*/
710: PetscErrorCode MatSetUp(Mat A)
711: {
712: PetscMPIInt size;
717: if (!((PetscObject)A)->type_name) {
718: MPI_Comm_size(PetscObjectComm((PetscObject)A), &size);
719: if (size == 1) {
720: MatSetType(A, MATSEQAIJ);
721: } else {
722: MatSetType(A, MATMPIAIJ);
723: }
724: }
725: if (!A->preallocated && A->ops->setup) {
726: PetscInfo(A,"Warning not preallocating matrix storage\n");
727: (*A->ops->setup)(A);
728: }
729: A->preallocated = PETSC_TRUE;
730: return(0);
731: }
733: #if defined(PETSC_HAVE_SAWS)
734: #include <petscviewersaws.h>
735: #endif
738: /*@C
739: MatView - Visualizes a matrix object.
741: Collective on Mat
743: Input Parameters:
744: + mat - the matrix
745: - viewer - visualization context
747: Notes:
748: The available visualization contexts include
749: + PETSC_VIEWER_STDOUT_SELF - standard output (default)
750: . PETSC_VIEWER_STDOUT_WORLD - synchronized standard
751: output where only the first processor opens
752: the file. All other processors send their
753: data to the first processor to print.
754: - PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure
756: The user can open alternative visualization contexts with
757: + PetscViewerASCIIOpen() - Outputs matrix to a specified file
758: . PetscViewerBinaryOpen() - Outputs matrix in binary to a
759: specified file; corresponding input uses MatLoad()
760: . PetscViewerDrawOpen() - Outputs nonzero matrix structure to
761: an X window display
762: - PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
763: Currently only the sequential dense and AIJ
764: matrix types support the Socket viewer.
766: The user can call PetscViewerSetFormat() to specify the output
767: format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
768: PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen). Available formats include
769: + PETSC_VIEWER_DEFAULT - default, prints matrix contents
770: . PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
771: . PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
772: . PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse
773: format common among all matrix types
774: . PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific
775: format (which is in many cases the same as the default)
776: . PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
777: size and structure (not the matrix entries)
778: . PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about
779: the matrix structure
781: Options Database Keys:
782: + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
783: . -mat_view ::ascii_info_detail - Prints more detailed info
784: . -mat_view - Prints matrix in ASCII format
785: . -mat_view ::ascii_matlab - Prints matrix in Matlab format
786: . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
787: . -display <name> - Sets display name (default is host)
788: . -draw_pause <sec> - Sets number of seconds to pause after display
789: . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: Chapter 10 Using MATLAB with PETSc for details)
790: . -viewer_socket_machine <machine>
791: . -viewer_socket_port <port>
792: . -mat_view binary - save matrix to file in binary format
793: - -viewer_binary_filename <name>
794: Level: beginner
796: Notes: see the manual page for MatLoad() for the exact format of the binary file when the binary
797: viewer is used.
799: See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary
800: viewer is used.
802: One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure.
803: And then use the following mouse functions:
804: left mouse: zoom in
805: middle mouse: zoom out
806: right mouse: continue with the simulation
808: Concepts: matrices^viewing
809: Concepts: matrices^plotting
810: Concepts: matrices^printing
812: .seealso: PetscViewerSetFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(),
813: PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
814: @*/
815: PetscErrorCode MatView(Mat mat,PetscViewer viewer)
816: {
817: PetscErrorCode ierr;
818: PetscInt rows,cols,bs;
819: PetscBool iascii;
820: PetscViewerFormat format;
821: #if defined(PETSC_HAVE_SAWS)
822: PetscBool isams;
823: #endif
828: if (!viewer) {
829: PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);
830: }
833: MatCheckPreallocated(mat,1);
835: PetscLogEventBegin(MAT_View,mat,viewer,0,0);
836: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
837: PetscViewerGetFormat(viewer,&format);
838: if ((!iascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) {
839: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detailed");
840: }
842: #if defined(PETSC_HAVE_SAWS)
843: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&isams);
844: #endif
845: if (iascii) {
846: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
847: PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer);
848: if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
849: PetscViewerASCIIPushTab(viewer);
850: MatGetSize(mat,&rows,&cols);
851: MatGetBlockSize(mat,&bs);
852: if (bs != 1) {
853: PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,bs);
854: } else {
855: PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);
856: }
857: if (mat->factortype) {
858: const MatSolverPackage solver;
859: MatFactorGetSolverPackage(mat,&solver);
860: PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);
861: }
862: if (mat->ops->getinfo) {
863: MatInfo info;
864: MatGetInfo(mat,MAT_GLOBAL_SUM,&info);
865: PetscViewerASCIIPrintf(viewer,"total: nonzeros=%g, allocated nonzeros=%g\n",info.nz_used,info.nz_allocated);
866: PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls =%D\n",(PetscInt)info.mallocs);
867: }
868: if (mat->nullsp) {PetscViewerASCIIPrintf(viewer," has attached null space\n");}
869: if (mat->nearnullsp) {PetscViewerASCIIPrintf(viewer," has attached near null space\n");}
870: }
871: #if defined(PETSC_HAVE_SAWS)
872: } else if (isams) {
873: PetscMPIInt rank;
875: PetscObjectName((PetscObject)mat);
876: MPI_Comm_rank(PETSC_COMM_WORLD,&rank);
877: if (!((PetscObject)mat)->amsmem && !rank) {
878: PetscObjectViewSAWs((PetscObject)mat,viewer);
879: }
880: #endif
881: }
882: if (mat->ops->view) {
883: PetscViewerASCIIPushTab(viewer);
884: (*mat->ops->view)(mat,viewer);
885: PetscViewerASCIIPopTab(viewer);
886: }
887: if (iascii) {
888: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
889: PetscViewerGetFormat(viewer,&format);
890: if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
891: PetscViewerASCIIPopTab(viewer);
892: }
893: }
894: PetscLogEventEnd(MAT_View,mat,viewer,0,0);
895: return(0);
896: }
898: #if defined(PETSC_USE_DEBUG)
899: #include <../src/sys/totalview/tv_data_display.h>
900: PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat)
901: {
902: TV_add_row("Local rows", "int", &mat->rmap->n);
903: TV_add_row("Local columns", "int", &mat->cmap->n);
904: TV_add_row("Global rows", "int", &mat->rmap->N);
905: TV_add_row("Global columns", "int", &mat->cmap->N);
906: TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name);
907: return TV_format_OK;
908: }
909: #endif
913: /*@C
914: MatLoad - Loads a matrix that has been stored in binary format
915: with MatView(). The matrix format is determined from the options database.
916: Generates a parallel MPI matrix if the communicator has more than one
917: processor. The default matrix type is AIJ.
919: Collective on PetscViewer
921: Input Parameters:
922: + newmat - the newly loaded matrix, this needs to have been created with MatCreate()
923: or some related function before a call to MatLoad()
924: - viewer - binary file viewer, created with PetscViewerBinaryOpen()
926: Options Database Keys:
927: Used with block matrix formats (MATSEQBAIJ, ...) to specify
928: block size
929: . -matload_block_size <bs>
931: Level: beginner
933: Notes:
934: If the Mat type has not yet been given then MATAIJ is used, call MatSetFromOptions() on the
935: Mat before calling this routine if you wish to set it from the options database.
937: MatLoad() automatically loads into the options database any options
938: given in the file filename.info where filename is the name of the file
939: that was passed to the PetscViewerBinaryOpen(). The options in the info
940: file will be ignored if you use the -viewer_binary_skip_info option.
942: If the type or size of newmat is not set before a call to MatLoad, PETSc
943: sets the default matrix type AIJ and sets the local and global sizes.
944: If type and/or size is already set, then the same are used.
946: In parallel, each processor can load a subset of rows (or the
947: entire matrix). This routine is especially useful when a large
948: matrix is stored on disk and only part of it is desired on each
949: processor. For example, a parallel solver may access only some of
950: the rows from each processor. The algorithm used here reads
951: relatively small blocks of data rather than reading the entire
952: matrix and then subsetting it.
954: Notes for advanced users:
955: Most users should not need to know the details of the binary storage
956: format, since MatLoad() and MatView() completely hide these details.
957: But for anyone who's interested, the standard binary matrix storage
958: format is
960: $ int MAT_FILE_CLASSID
961: $ int number of rows
962: $ int number of columns
963: $ int total number of nonzeros
964: $ int *number nonzeros in each row
965: $ int *column indices of all nonzeros (starting index is zero)
966: $ PetscScalar *values of all nonzeros
968: PETSc automatically does the byte swapping for
969: machines that store the bytes reversed, e.g. DEC alpha, freebsd,
970: linux, Windows and the paragon; thus if you write your own binary
971: read/write routines you have to swap the bytes; see PetscBinaryRead()
972: and PetscBinaryWrite() to see how this may be done.
974: .keywords: matrix, load, binary, input
976: .seealso: PetscViewerBinaryOpen(), MatView(), VecLoad()
978: @*/
979: PetscErrorCode MatLoad(Mat newmat,PetscViewer viewer)
980: {
982: PetscBool isbinary,flg;
987: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);
988: if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()");
990: if (!((PetscObject)newmat)->type_name) {
991: MatSetType(newmat,MATAIJ);
992: }
994: if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type");
995: PetscLogEventBegin(MAT_Load,viewer,0,0,0);
996: (*newmat->ops->load)(newmat,viewer);
997: PetscLogEventEnd(MAT_Load,viewer,0,0,0);
999: flg = PETSC_FALSE;
1000: PetscOptionsGetBool(((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,NULL);
1001: if (flg) {
1002: MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);
1003: MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);
1004: }
1005: flg = PETSC_FALSE;
1006: PetscOptionsGetBool(((PetscObject)newmat)->prefix,"-matload_spd",&flg,NULL);
1007: if (flg) {
1008: MatSetOption(newmat,MAT_SPD,PETSC_TRUE);
1009: }
1010: return(0);
1011: }
1015: /*@
1016: MatDestroy - Frees space taken by a matrix.
1018: Collective on Mat
1020: Input Parameter:
1021: . A - the matrix
1023: Level: beginner
1025: @*/
1026: PetscErrorCode MatDestroy(Mat *A)
1027: {
1031: if (!*A) return(0);
1033: if (--((PetscObject)(*A))->refct > 0) {*A = NULL; return(0);}
1035: /* if memory was published with SAWs then destroy it */
1036: PetscObjectSAWsViewOff((PetscObject)*A);
1037: if ((*A)->ops->destroy) {
1038: (*(*A)->ops->destroy)(*A);
1039: }
1040: MatNullSpaceDestroy(&(*A)->nullsp);
1041: MatNullSpaceDestroy(&(*A)->nearnullsp);
1042: PetscLayoutDestroy(&(*A)->rmap);
1043: PetscLayoutDestroy(&(*A)->cmap);
1044: PetscHeaderDestroy(A);
1045: return(0);
1046: }
1050: /*@
1051: MatSetValues - Inserts or adds a block of values into a matrix.
1052: These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1053: MUST be called after all calls to MatSetValues() have been completed.
1055: Not Collective
1057: Input Parameters:
1058: + mat - the matrix
1059: . v - a logically two-dimensional array of values
1060: . m, idxm - the number of rows and their global indices
1061: . n, idxn - the number of columns and their global indices
1062: - addv - either ADD_VALUES or INSERT_VALUES, where
1063: ADD_VALUES adds values to any existing entries, and
1064: INSERT_VALUES replaces existing entries with new values
1066: Notes:
1067: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
1068: MatSetUp() before using this routine
1070: By default the values, v, are row-oriented. See MatSetOption() for other options.
1072: Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
1073: options cannot be mixed without intervening calls to the assembly
1074: routines.
1076: MatSetValues() uses 0-based row and column numbers in Fortran
1077: as well as in C.
1079: Negative indices may be passed in idxm and idxn, these rows and columns are
1080: simply ignored. This allows easily inserting element stiffness matrices
1081: with homogeneous Dirchlet boundary conditions that you don't want represented
1082: in the matrix.
1084: Efficiency Alert:
1085: The routine MatSetValuesBlocked() may offer much better efficiency
1086: for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1088: Level: beginner
1090: Concepts: matrices^putting entries in
1092: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1093: InsertMode, INSERT_VALUES, ADD_VALUES
1094: @*/
1095: PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1096: {
1098: #if defined(PETSC_USE_DEBUG)
1099: PetscInt i,j;
1100: #endif
1105: if (!m || !n) return(0); /* no values to insert */
1109: MatCheckPreallocated(mat,1);
1110: if (mat->insertmode == NOT_SET_VALUES) {
1111: mat->insertmode = addv;
1112: }
1113: #if defined(PETSC_USE_DEBUG)
1114: else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1115: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1116: if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1118: for (i=0; i<m; i++) {
1119: for (j=0; j<n; j++) {
1120: if (PetscIsInfOrNanScalar(v[i*n+j]))
1121: #if defined(PETSC_USE_COMPLEX)
1122: SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g+ig at matrix entry (%D,%D)",(double)PetscRealPart(v[i*n+j]),(double)PetscImaginaryPart(v[i*n+j]),idxm[i],idxn[j]);
1123: #else
1124: SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%D,%D)",(double)v[i*n+j],idxm[i],idxn[j]);
1125: #endif
1126: }
1127: }
1128: #endif
1130: if (mat->assembled) {
1131: mat->was_assembled = PETSC_TRUE;
1132: mat->assembled = PETSC_FALSE;
1133: }
1134: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1135: (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);
1136: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1137: #if defined(PETSC_HAVE_CUSP)
1138: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1139: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1140: }
1141: #endif
1142: #if defined(PETSC_HAVE_VIENNACL)
1143: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1144: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1145: }
1146: #endif
1147: return(0);
1148: }
1153: /*@
1154: MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
1155: values into a matrix
1157: Not Collective
1159: Input Parameters:
1160: + mat - the matrix
1161: . row - the (block) row to set
1162: - v - a logically two-dimensional array of values
1164: Notes:
1165: By the values, v, are column-oriented (for the block version) and sorted
1167: All the nonzeros in the row must be provided
1169: The matrix must have previously had its column indices set
1171: The row must belong to this process
1173: Level: intermediate
1175: Concepts: matrices^putting entries in
1177: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1178: InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping()
1179: @*/
1180: PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
1181: {
1183: PetscInt globalrow;
1189: ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);
1190: MatSetValuesRow(mat,globalrow,v);
1191: #if defined(PETSC_HAVE_CUSP)
1192: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1193: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1194: }
1195: #endif
1196: #if defined(PETSC_HAVE_VIENNACL)
1197: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1198: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1199: }
1200: #endif
1201: return(0);
1202: }
1206: /*@
1207: MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
1208: values into a matrix
1210: Not Collective
1212: Input Parameters:
1213: + mat - the matrix
1214: . row - the (block) row to set
1215: - v - a logically two-dimensional array of values
1217: Notes:
1218: The values, v, are column-oriented for the block version.
1220: All the nonzeros in the row must be provided
1222: THE MATRIX MUSAT HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually MatSetValues() is used.
1224: The row must belong to this process
1226: Level: advanced
1228: Concepts: matrices^putting entries in
1230: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1231: InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1232: @*/
1233: PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
1234: {
1240: MatCheckPreallocated(mat,1);
1242: #if defined(PETSC_USE_DEBUG)
1243: if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
1244: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1245: #endif
1246: mat->insertmode = INSERT_VALUES;
1248: if (mat->assembled) {
1249: mat->was_assembled = PETSC_TRUE;
1250: mat->assembled = PETSC_FALSE;
1251: }
1252: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1253: if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1254: (*mat->ops->setvaluesrow)(mat,row,v);
1255: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1256: #if defined(PETSC_HAVE_CUSP)
1257: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1258: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1259: }
1260: #endif
1261: #if defined(PETSC_HAVE_VIENNACL)
1262: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1263: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1264: }
1265: #endif
1266: return(0);
1267: }
1271: /*@
1272: MatSetValuesStencil - Inserts or adds a block of values into a matrix.
1273: Using structured grid indexing
1275: Not Collective
1277: Input Parameters:
1278: + mat - the matrix
1279: . m - number of rows being entered
1280: . idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
1281: . n - number of columns being entered
1282: . idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered
1283: . v - a logically two-dimensional array of values
1284: - addv - either ADD_VALUES or INSERT_VALUES, where
1285: ADD_VALUES adds values to any existing entries, and
1286: INSERT_VALUES replaces existing entries with new values
1288: Notes:
1289: By default the values, v, are row-oriented. See MatSetOption() for other options.
1291: Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
1292: options cannot be mixed without intervening calls to the assembly
1293: routines.
1295: The grid coordinates are across the entire grid, not just the local portion
1297: MatSetValuesStencil() uses 0-based row and column numbers in Fortran
1298: as well as in C.
1300: For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1302: In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1303: or call MatSetLocalToGlobalMapping() and MatSetStencil() first.
1305: The columns and rows in the stencil passed in MUST be contained within the
1306: ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1307: if you create a DMDA with an overlap of one grid level and on a particular process its first
1308: local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1309: first i index you can use in your column and row indices in MatSetStencil() is 5.
1311: In Fortran idxm and idxn should be declared as
1312: $ MatStencil idxm(4,m),idxn(4,n)
1313: and the values inserted using
1314: $ idxm(MatStencil_i,1) = i
1315: $ idxm(MatStencil_j,1) = j
1316: $ idxm(MatStencil_k,1) = k
1317: $ idxm(MatStencil_c,1) = c
1318: etc
1320: For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
1321: obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
1322: etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
1323: DM_BOUNDARY_PERIODIC boundary type.
1325: 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
1326: a single value per point) you can skip filling those indices.
1328: Inspired by the structured grid interface to the HYPRE package
1329: (http://www.llnl.gov/CASC/hypre)
1331: Efficiency Alert:
1332: The routine MatSetValuesBlockedStencil() may offer much better efficiency
1333: for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1335: Level: beginner
1337: Concepts: matrices^putting entries in
1339: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1340: MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil
1341: @*/
1342: PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1343: {
1345: PetscInt buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1346: PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1347: PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1350: if (!m || !n) return(0); /* no values to insert */
1357: if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1358: jdxm = buf; jdxn = buf+m;
1359: } else {
1360: PetscMalloc2(m,&bufm,n,&bufn);
1361: jdxm = bufm; jdxn = bufn;
1362: }
1363: for (i=0; i<m; i++) {
1364: for (j=0; j<3-sdim; j++) dxm++;
1365: tmp = *dxm++ - starts[0];
1366: for (j=0; j<dim-1; j++) {
1367: if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1368: else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1369: }
1370: if (mat->stencil.noc) dxm++;
1371: jdxm[i] = tmp;
1372: }
1373: for (i=0; i<n; i++) {
1374: for (j=0; j<3-sdim; j++) dxn++;
1375: tmp = *dxn++ - starts[0];
1376: for (j=0; j<dim-1; j++) {
1377: if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1378: else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1379: }
1380: if (mat->stencil.noc) dxn++;
1381: jdxn[i] = tmp;
1382: }
1383: MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);
1384: PetscFree2(bufm,bufn);
1385: return(0);
1386: }
1390: /*@
1391: MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1392: Using structured grid indexing
1394: Not Collective
1396: Input Parameters:
1397: + mat - the matrix
1398: . m - number of rows being entered
1399: . idxm - grid coordinates for matrix rows being entered
1400: . n - number of columns being entered
1401: . idxn - grid coordinates for matrix columns being entered
1402: . v - a logically two-dimensional array of values
1403: - addv - either ADD_VALUES or INSERT_VALUES, where
1404: ADD_VALUES adds values to any existing entries, and
1405: INSERT_VALUES replaces existing entries with new values
1407: Notes:
1408: By default the values, v, are row-oriented and unsorted.
1409: See MatSetOption() for other options.
1411: Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
1412: options cannot be mixed without intervening calls to the assembly
1413: routines.
1415: The grid coordinates are across the entire grid, not just the local portion
1417: MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran
1418: as well as in C.
1420: For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1422: In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1423: or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first.
1425: The columns and rows in the stencil passed in MUST be contained within the
1426: ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1427: if you create a DMDA with an overlap of one grid level and on a particular process its first
1428: local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1429: first i index you can use in your column and row indices in MatSetStencil() is 5.
1431: In Fortran idxm and idxn should be declared as
1432: $ MatStencil idxm(4,m),idxn(4,n)
1433: and the values inserted using
1434: $ idxm(MatStencil_i,1) = i
1435: $ idxm(MatStencil_j,1) = j
1436: $ idxm(MatStencil_k,1) = k
1437: etc
1439: Negative indices may be passed in idxm and idxn, these rows and columns are
1440: simply ignored. This allows easily inserting element stiffness matrices
1441: with homogeneous Dirchlet boundary conditions that you don't want represented
1442: in the matrix.
1444: Inspired by the structured grid interface to the HYPRE package
1445: (http://www.llnl.gov/CASC/hypre)
1447: Level: beginner
1449: Concepts: matrices^putting entries in
1451: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1452: MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil,
1453: MatSetBlockSize(), MatSetLocalToGlobalMapping()
1454: @*/
1455: PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1456: {
1458: PetscInt buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1459: PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1460: PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1463: if (!m || !n) return(0); /* no values to insert */
1470: if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1471: jdxm = buf; jdxn = buf+m;
1472: } else {
1473: PetscMalloc2(m,&bufm,n,&bufn);
1474: jdxm = bufm; jdxn = bufn;
1475: }
1476: for (i=0; i<m; i++) {
1477: for (j=0; j<3-sdim; j++) dxm++;
1478: tmp = *dxm++ - starts[0];
1479: for (j=0; j<sdim-1; j++) {
1480: if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1481: else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1482: }
1483: dxm++;
1484: jdxm[i] = tmp;
1485: }
1486: for (i=0; i<n; i++) {
1487: for (j=0; j<3-sdim; j++) dxn++;
1488: tmp = *dxn++ - starts[0];
1489: for (j=0; j<sdim-1; j++) {
1490: if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1491: else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1492: }
1493: dxn++;
1494: jdxn[i] = tmp;
1495: }
1496: MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);
1497: PetscFree2(bufm,bufn);
1498: #if defined(PETSC_HAVE_CUSP)
1499: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1500: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1501: }
1502: #endif
1503: #if defined(PETSC_HAVE_VIENNACL)
1504: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1505: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1506: }
1507: #endif
1508: return(0);
1509: }
1513: /*@
1514: MatSetStencil - Sets the grid information for setting values into a matrix via
1515: MatSetValuesStencil()
1517: Not Collective
1519: Input Parameters:
1520: + mat - the matrix
1521: . dim - dimension of the grid 1, 2, or 3
1522: . dims - number of grid points in x, y, and z direction, including ghost points on your processor
1523: . starts - starting point of ghost nodes on your processor in x, y, and z direction
1524: - dof - number of degrees of freedom per node
1527: Inspired by the structured grid interface to the HYPRE package
1528: (www.llnl.gov/CASC/hyper)
1530: For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the
1531: user.
1533: Level: beginner
1535: Concepts: matrices^putting entries in
1537: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1538: MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
1539: @*/
1540: PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1541: {
1542: PetscInt i;
1549: mat->stencil.dim = dim + (dof > 1);
1550: for (i=0; i<dim; i++) {
1551: mat->stencil.dims[i] = dims[dim-i-1]; /* copy the values in backwards */
1552: mat->stencil.starts[i] = starts[dim-i-1];
1553: }
1554: mat->stencil.dims[dim] = dof;
1555: mat->stencil.starts[dim] = 0;
1556: mat->stencil.noc = (PetscBool)(dof == 1);
1557: return(0);
1558: }
1562: /*@
1563: MatSetValuesBlocked - Inserts or adds a block of values into a matrix.
1565: Not Collective
1567: Input Parameters:
1568: + mat - the matrix
1569: . v - a logically two-dimensional array of values
1570: . m, idxm - the number of block rows and their global block indices
1571: . n, idxn - the number of block columns and their global block indices
1572: - addv - either ADD_VALUES or INSERT_VALUES, where
1573: ADD_VALUES adds values to any existing entries, and
1574: INSERT_VALUES replaces existing entries with new values
1576: Notes:
1577: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call
1578: MatXXXXSetPreallocation() or MatSetUp() before using this routine.
1580: The m and n count the NUMBER of blocks in the row direction and column direction,
1581: NOT the total number of rows/columns; for example, if the block size is 2 and
1582: you are passing in values for rows 2,3,4,5 then m would be 2 (not 4).
1583: The values in idxm would be 1 2; that is the first index for each block divided by
1584: the block size.
1586: Note that you must call MatSetBlockSize() when constructing this matrix (after
1587: preallocating it).
1589: By default the values, v, are row-oriented, so the layout of
1590: v is the same as for MatSetValues(). See MatSetOption() for other options.
1592: Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
1593: options cannot be mixed without intervening calls to the assembly
1594: routines.
1596: MatSetValuesBlocked() uses 0-based row and column numbers in Fortran
1597: as well as in C.
1599: Negative indices may be passed in idxm and idxn, these rows and columns are
1600: simply ignored. This allows easily inserting element stiffness matrices
1601: with homogeneous Dirchlet boundary conditions that you don't want represented
1602: in the matrix.
1604: Each time an entry is set within a sparse matrix via MatSetValues(),
1605: internal searching must be done to determine where to place the the
1606: data in the matrix storage space. By instead inserting blocks of
1607: entries via MatSetValuesBlocked(), the overhead of matrix assembly is
1608: reduced.
1610: Example:
1611: $ Suppose m=n=2 and block size(bs) = 2 The array is
1612: $
1613: $ 1 2 | 3 4
1614: $ 5 6 | 7 8
1615: $ - - - | - - -
1616: $ 9 10 | 11 12
1617: $ 13 14 | 15 16
1618: $
1619: $ v[] should be passed in like
1620: $ v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
1621: $
1622: $ If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then
1623: $ v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16]
1625: Level: intermediate
1627: Concepts: matrices^putting entries in blocked
1629: .seealso: MatSetBlockSize(), MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal()
1630: @*/
1631: PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1632: {
1638: if (!m || !n) return(0); /* no values to insert */
1642: MatCheckPreallocated(mat,1);
1643: if (mat->insertmode == NOT_SET_VALUES) {
1644: mat->insertmode = addv;
1645: }
1646: #if defined(PETSC_USE_DEBUG)
1647: else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1648: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1649: if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1650: #endif
1652: if (mat->assembled) {
1653: mat->was_assembled = PETSC_TRUE;
1654: mat->assembled = PETSC_FALSE;
1655: }
1656: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1657: if (mat->ops->setvaluesblocked) {
1658: (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);
1659: } else {
1660: PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn;
1661: PetscInt i,j,bs,cbs;
1662: MatGetBlockSizes(mat,&bs,&cbs);
1663: if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1664: iidxm = buf; iidxn = buf + m*bs;
1665: } else {
1666: PetscMalloc2(m*bs,&bufr,n*cbs,&bufc);
1667: iidxm = bufr; iidxn = bufc;
1668: }
1669: for (i=0; i<m; i++) {
1670: for (j=0; j<bs; j++) {
1671: iidxm[i*bs+j] = bs*idxm[i] + j;
1672: }
1673: }
1674: for (i=0; i<n; i++) {
1675: for (j=0; j<cbs; j++) {
1676: iidxn[i*cbs+j] = cbs*idxn[i] + j;
1677: }
1678: }
1679: MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv);
1680: PetscFree2(bufr,bufc);
1681: }
1682: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1683: #if defined(PETSC_HAVE_CUSP)
1684: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1685: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1686: }
1687: #endif
1688: #if defined(PETSC_HAVE_VIENNACL)
1689: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1690: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1691: }
1692: #endif
1693: return(0);
1694: }
1698: /*@
1699: MatGetValues - Gets a block of values from a matrix.
1701: Not Collective; currently only returns a local block
1703: Input Parameters:
1704: + mat - the matrix
1705: . v - a logically two-dimensional array for storing the values
1706: . m, idxm - the number of rows and their global indices
1707: - n, idxn - the number of columns and their global indices
1709: Notes:
1710: The user must allocate space (m*n PetscScalars) for the values, v.
1711: The values, v, are then returned in a row-oriented format,
1712: analogous to that used by default in MatSetValues().
1714: MatGetValues() uses 0-based row and column numbers in
1715: Fortran as well as in C.
1717: MatGetValues() requires that the matrix has been assembled
1718: with MatAssemblyBegin()/MatAssemblyEnd(). Thus, calls to
1719: MatSetValues() and MatGetValues() CANNOT be made in succession
1720: without intermediate matrix assembly.
1722: Negative row or column indices will be ignored and those locations in v[] will be
1723: left unchanged.
1725: Level: advanced
1727: Concepts: matrices^accessing values
1729: .seealso: MatGetRow(), MatGetSubMatrices(), MatSetValues()
1730: @*/
1731: PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1732: {
1738: if (!m || !n) return(0);
1742: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1743: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1744: if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1745: MatCheckPreallocated(mat,1);
1747: PetscLogEventBegin(MAT_GetValues,mat,0,0,0);
1748: (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);
1749: PetscLogEventEnd(MAT_GetValues,mat,0,0,0);
1750: return(0);
1751: }
1755: /*@
1756: MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and
1757: the same size. Currently, this can only be called once and creates the given matrix.
1759: Not Collective
1761: Input Parameters:
1762: + mat - the matrix
1763: . nb - the number of blocks
1764: . bs - the number of rows (and columns) in each block
1765: . rows - a concatenation of the rows for each block
1766: - v - a concatenation of logically two-dimensional arrays of values
1768: Notes:
1769: In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix.
1771: Level: advanced
1773: Concepts: matrices^putting entries in
1775: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1776: InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1777: @*/
1778: PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[])
1779: {
1787: #if defined(PETSC_USE_DEBUG)
1788: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1789: #endif
1791: PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);
1792: if (mat->ops->setvaluesbatch) {
1793: (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);
1794: } else {
1795: PetscInt b;
1796: for (b = 0; b < nb; ++b) {
1797: MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);
1798: }
1799: }
1800: PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);
1801: return(0);
1802: }
1806: /*@
1807: MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
1808: the routine MatSetValuesLocal() to allow users to insert matrix entries
1809: using a local (per-processor) numbering.
1811: Not Collective
1813: Input Parameters:
1814: + x - the matrix
1815: . rmapping - row mapping created with ISLocalToGlobalMappingCreate() or ISLocalToGlobalMappingCreateIS()
1816: - cmapping - column mapping
1818: Level: intermediate
1820: Concepts: matrices^local to global mapping
1821: Concepts: local to global mapping^for matrices
1823: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
1824: @*/
1825: PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
1826: {
1835: if (x->ops->setlocaltoglobalmapping) {
1836: (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);
1837: } else {
1838: PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);
1839: PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);
1840: }
1841: return(0);
1842: }
1847: /*@
1848: MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping()
1850: Not Collective
1852: Input Parameters:
1853: . A - the matrix
1855: Output Parameters:
1856: + rmapping - row mapping
1857: - cmapping - column mapping
1859: Level: advanced
1861: Concepts: matrices^local to global mapping
1862: Concepts: local to global mapping^for matrices
1864: .seealso: MatSetValuesLocal()
1865: @*/
1866: PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
1867: {
1873: if (rmapping) *rmapping = A->rmap->mapping;
1874: if (cmapping) *cmapping = A->cmap->mapping;
1875: return(0);
1876: }
1880: /*@
1881: MatGetLayouts - Gets the PetscLayout objects for rows and columns
1883: Not Collective
1885: Input Parameters:
1886: . A - the matrix
1888: Output Parameters:
1889: + rmap - row layout
1890: - cmap - column layout
1892: Level: advanced
1894: .seealso: MatGetVecs(), MatGetLocalToGlobalMapping()
1895: @*/
1896: PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap)
1897: {
1903: if (rmap) *rmap = A->rmap;
1904: if (cmap) *cmap = A->cmap;
1905: return(0);
1906: }
1910: /*@
1911: MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
1912: using a local ordering of the nodes.
1914: Not Collective
1916: Input Parameters:
1917: + x - the matrix
1918: . nrow, irow - number of rows and their local indices
1919: . ncol, icol - number of columns and their local indices
1920: . y - a logically two-dimensional array of values
1921: - addv - either INSERT_VALUES or ADD_VALUES, where
1922: ADD_VALUES adds values to any existing entries, and
1923: INSERT_VALUES replaces existing entries with new values
1925: Notes:
1926: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
1927: MatSetUp() before using this routine
1929: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine
1931: Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
1932: options cannot be mixed without intervening calls to the assembly
1933: routines.
1935: These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1936: MUST be called after all calls to MatSetValuesLocal() have been completed.
1938: Level: intermediate
1940: Concepts: matrices^putting entries in with local numbering
1942: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
1943: MatSetValueLocal()
1944: @*/
1945: PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
1946: {
1952: MatCheckPreallocated(mat,1);
1953: if (!nrow || !ncol) return(0); /* no values to insert */
1957: if (mat->insertmode == NOT_SET_VALUES) {
1958: mat->insertmode = addv;
1959: }
1960: #if defined(PETSC_USE_DEBUG)
1961: else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1962: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1963: if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1964: #endif
1966: if (mat->assembled) {
1967: mat->was_assembled = PETSC_TRUE;
1968: mat->assembled = PETSC_FALSE;
1969: }
1970: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1971: if (mat->ops->setvalueslocal) {
1972: (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);
1973: } else {
1974: PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
1975: if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1976: irowm = buf; icolm = buf+nrow;
1977: } else {
1978: PetscMalloc2(nrow,&bufr,ncol,&bufc);
1979: irowm = bufr; icolm = bufc;
1980: }
1981: ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);
1982: ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);
1983: MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);
1984: PetscFree2(bufr,bufc);
1985: }
1986: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1987: #if defined(PETSC_HAVE_CUSP)
1988: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1989: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1990: }
1991: #endif
1992: #if defined(PETSC_HAVE_VIENNACL)
1993: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1994: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1995: }
1996: #endif
1997: return(0);
1998: }
2002: /*@
2003: MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix,
2004: using a local ordering of the nodes a block at a time.
2006: Not Collective
2008: Input Parameters:
2009: + x - the matrix
2010: . nrow, irow - number of rows and their local indices
2011: . ncol, icol - number of columns and their local indices
2012: . y - a logically two-dimensional array of values
2013: - addv - either INSERT_VALUES or ADD_VALUES, where
2014: ADD_VALUES adds values to any existing entries, and
2015: INSERT_VALUES replaces existing entries with new values
2017: Notes:
2018: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
2019: MatSetUp() before using this routine
2021: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMapping()
2022: before using this routineBefore calling MatSetValuesLocal(), the user must first set the
2024: Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
2025: options cannot be mixed without intervening calls to the assembly
2026: routines.
2028: These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2029: MUST be called after all calls to MatSetValuesBlockedLocal() have been completed.
2031: Level: intermediate
2033: Concepts: matrices^putting blocked values in with local numbering
2035: .seealso: MatSetBlockSize(), MatSetLocalToGlobalMapping(), MatAssemblyBegin(), MatAssemblyEnd(),
2036: MatSetValuesLocal(), MatSetValuesBlocked()
2037: @*/
2038: PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2039: {
2045: MatCheckPreallocated(mat,1);
2046: if (!nrow || !ncol) return(0); /* no values to insert */
2050: if (mat->insertmode == NOT_SET_VALUES) {
2051: mat->insertmode = addv;
2052: }
2053: #if defined(PETSC_USE_DEBUG)
2054: else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2055: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2056: 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);
2057: #endif
2059: if (mat->assembled) {
2060: mat->was_assembled = PETSC_TRUE;
2061: mat->assembled = PETSC_FALSE;
2062: }
2063: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
2064: if (mat->ops->setvaluesblockedlocal) {
2065: (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);
2066: } else {
2067: PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2068: if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2069: irowm = buf; icolm = buf + nrow;
2070: } else {
2071: PetscMalloc2(nrow,&bufr,ncol,&bufc);
2072: irowm = bufr; icolm = bufc;
2073: }
2074: ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,irowm);
2075: ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,icolm);
2076: MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);
2077: PetscFree2(bufr,bufc);
2078: }
2079: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
2080: #if defined(PETSC_HAVE_CUSP)
2081: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
2082: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
2083: }
2084: #endif
2085: #if defined(PETSC_HAVE_VIENNACL)
2086: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
2087: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
2088: }
2089: #endif
2090: return(0);
2091: }
2095: /*@
2096: MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal
2098: Collective on Mat and Vec
2100: Input Parameters:
2101: + mat - the matrix
2102: - x - the vector to be multiplied
2104: Output Parameters:
2105: . y - the result
2107: Notes:
2108: The vectors x and y cannot be the same. I.e., one cannot
2109: call MatMult(A,y,y).
2111: Level: developer
2113: Concepts: matrix-vector product
2115: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2116: @*/
2117: PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y)
2118: {
2127: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2128: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2129: if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2130: MatCheckPreallocated(mat,1);
2132: if (!mat->ops->multdiagonalblock) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2133: (*mat->ops->multdiagonalblock)(mat,x,y);
2134: PetscObjectStateIncrease((PetscObject)y);
2135: return(0);
2136: }
2138: /* --------------------------------------------------------*/
2141: /*@
2142: MatMult - Computes the matrix-vector product, y = Ax.
2144: Neighbor-wise Collective on Mat and Vec
2146: Input Parameters:
2147: + mat - the matrix
2148: - x - the vector to be multiplied
2150: Output Parameters:
2151: . y - the result
2153: Notes:
2154: The vectors x and y cannot be the same. I.e., one cannot
2155: call MatMult(A,y,y).
2157: Level: beginner
2159: Concepts: matrix-vector product
2161: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2162: @*/
2163: PetscErrorCode MatMult(Mat mat,Vec x,Vec y)
2164: {
2172: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2173: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2174: if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2175: #if !defined(PETSC_HAVE_CONSTRAINTS)
2176: 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);
2177: 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);
2178: 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);
2179: #endif
2180: VecValidValues(x,2,PETSC_TRUE);
2181: MatCheckPreallocated(mat,1);
2183: if (!mat->ops->mult) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2184: PetscLogEventBegin(MAT_Mult,mat,x,y,0);
2185: (*mat->ops->mult)(mat,x,y);
2186: PetscLogEventEnd(MAT_Mult,mat,x,y,0);
2187: VecValidValues(y,3,PETSC_FALSE);
2188: return(0);
2189: }
2193: /*@
2194: MatMultTranspose - Computes matrix transpose times a vector.
2196: Neighbor-wise Collective on Mat and Vec
2198: Input Parameters:
2199: + mat - the matrix
2200: - x - the vector to be multilplied
2202: Output Parameters:
2203: . y - the result
2205: Notes:
2206: The vectors x and y cannot be the same. I.e., one cannot
2207: call MatMultTranspose(A,y,y).
2209: For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple,
2210: use MatMultHermitianTranspose()
2212: Level: beginner
2214: Concepts: matrix vector product^transpose
2216: .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose()
2217: @*/
2218: PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y)
2219: {
2228: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2229: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2230: if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2231: #if !defined(PETSC_HAVE_CONSTRAINTS)
2232: 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);
2233: 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);
2234: #endif
2235: VecValidValues(x,2,PETSC_TRUE);
2236: MatCheckPreallocated(mat,1);
2238: if (!mat->ops->multtranspose) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply tranpose defined");
2239: PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);
2240: (*mat->ops->multtranspose)(mat,x,y);
2241: PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);
2242: PetscObjectStateIncrease((PetscObject)y);
2243: VecValidValues(y,3,PETSC_FALSE);
2244: return(0);
2245: }
2249: /*@
2250: MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.
2252: Neighbor-wise Collective on Mat and Vec
2254: Input Parameters:
2255: + mat - the matrix
2256: - x - the vector to be multilplied
2258: Output Parameters:
2259: . y - the result
2261: Notes:
2262: The vectors x and y cannot be the same. I.e., one cannot
2263: call MatMultHermitianTranspose(A,y,y).
2265: Also called the conjugate transpose, complex conjugate transpose, or adjoint.
2267: For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical.
2269: Level: beginner
2271: Concepts: matrix vector product^transpose
2273: .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose()
2274: @*/
2275: PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y)
2276: {
2278: Vec w;
2286: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2287: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2288: if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2289: #if !defined(PETSC_HAVE_CONSTRAINTS)
2290: 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);
2291: 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);
2292: #endif
2293: MatCheckPreallocated(mat,1);
2295: PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);
2296: if (mat->ops->multhermitiantranspose) {
2297: (*mat->ops->multhermitiantranspose)(mat,x,y);
2298: } else {
2299: VecDuplicate(x,&w);
2300: VecCopy(x,w);
2301: VecConjugate(w);
2302: MatMultTranspose(mat,w,y);
2303: VecDestroy(&w);
2304: VecConjugate(y);
2305: }
2306: PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);
2307: PetscObjectStateIncrease((PetscObject)y);
2308: return(0);
2309: }
2313: /*@
2314: MatMultAdd - Computes v3 = v2 + A * v1.
2316: Neighbor-wise Collective on Mat and Vec
2318: Input Parameters:
2319: + mat - the matrix
2320: - v1, v2 - the vectors
2322: Output Parameters:
2323: . v3 - the result
2325: Notes:
2326: The vectors v1 and v3 cannot be the same. I.e., one cannot
2327: call MatMultAdd(A,v1,v2,v1).
2329: Level: beginner
2331: Concepts: matrix vector product^addition
2333: .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
2334: @*/
2335: PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2336: {
2346: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2347: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2348: if (mat->cmap->N != v1->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->cmap->N,v1->map->N);
2349: /* 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);
2350: 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); */
2351: 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);
2352: 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);
2353: if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2354: MatCheckPreallocated(mat,1);
2356: if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name);
2357: PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);
2358: (*mat->ops->multadd)(mat,v1,v2,v3);
2359: PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);
2360: PetscObjectStateIncrease((PetscObject)v3);
2361: return(0);
2362: }
2366: /*@
2367: MatMultTransposeAdd - Computes v3 = v2 + A' * v1.
2369: Neighbor-wise Collective on Mat and Vec
2371: Input Parameters:
2372: + mat - the matrix
2373: - v1, v2 - the vectors
2375: Output Parameters:
2376: . v3 - the result
2378: Notes:
2379: The vectors v1 and v3 cannot be the same. I.e., one cannot
2380: call MatMultTransposeAdd(A,v1,v2,v1).
2382: Level: beginner
2384: Concepts: matrix vector product^transpose and addition
2386: .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
2387: @*/
2388: PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2389: {
2399: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2400: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2401: if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2402: if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2403: if (mat->rmap->N != v1->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->rmap->N,v1->map->N);
2404: if (mat->cmap->N != v2->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->cmap->N,v2->map->N);
2405: if (mat->cmap->N != v3->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->cmap->N,v3->map->N);
2406: MatCheckPreallocated(mat,1);
2408: PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);
2409: (*mat->ops->multtransposeadd)(mat,v1,v2,v3);
2410: PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);
2411: PetscObjectStateIncrease((PetscObject)v3);
2412: return(0);
2413: }
2417: /*@
2418: MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1.
2420: Neighbor-wise Collective on Mat and Vec
2422: Input Parameters:
2423: + mat - the matrix
2424: - v1, v2 - the vectors
2426: Output Parameters:
2427: . v3 - the result
2429: Notes:
2430: The vectors v1 and v3 cannot be the same. I.e., one cannot
2431: call MatMultHermitianTransposeAdd(A,v1,v2,v1).
2433: Level: beginner
2435: Concepts: matrix vector product^transpose and addition
2437: .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult()
2438: @*/
2439: PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2440: {
2450: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2451: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2452: if (!mat->ops->multhermitiantransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2453: if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2454: if (mat->rmap->N != v1->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->rmap->N,v1->map->N);
2455: if (mat->cmap->N != v2->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->cmap->N,v2->map->N);
2456: if (mat->cmap->N != v3->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->cmap->N,v3->map->N);
2457: MatCheckPreallocated(mat,1);
2459: PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2460: (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);
2461: PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2462: PetscObjectStateIncrease((PetscObject)v3);
2463: return(0);
2464: }
2468: /*@
2469: MatMultConstrained - The inner multiplication routine for a
2470: constrained matrix P^T A P.
2472: Neighbor-wise Collective on Mat and Vec
2474: Input Parameters:
2475: + mat - the matrix
2476: - x - the vector to be multilplied
2478: Output Parameters:
2479: . y - the result
2481: Notes:
2482: The vectors x and y cannot be the same. I.e., one cannot
2483: call MatMult(A,y,y).
2485: Level: beginner
2487: .keywords: matrix, multiply, matrix-vector product, constraint
2488: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2489: @*/
2490: PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y)
2491: {
2498: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2499: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2500: if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2501: 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);
2502: 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);
2503: 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);
2505: PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2506: (*mat->ops->multconstrained)(mat,x,y);
2507: PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2508: PetscObjectStateIncrease((PetscObject)y);
2509: return(0);
2510: }
2514: /*@
2515: MatMultTransposeConstrained - The inner multiplication routine for a
2516: constrained matrix P^T A^T P.
2518: Neighbor-wise Collective on Mat and Vec
2520: Input Parameters:
2521: + mat - the matrix
2522: - x - the vector to be multilplied
2524: Output Parameters:
2525: . y - the result
2527: Notes:
2528: The vectors x and y cannot be the same. I.e., one cannot
2529: call MatMult(A,y,y).
2531: Level: beginner
2533: .keywords: matrix, multiply, matrix-vector product, constraint
2534: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2535: @*/
2536: PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2537: {
2544: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2545: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2546: if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2547: 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);
2548: 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);
2550: PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2551: (*mat->ops->multtransposeconstrained)(mat,x,y);
2552: PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2553: PetscObjectStateIncrease((PetscObject)y);
2554: return(0);
2555: }
2559: /*@C
2560: MatGetFactorType - gets the type of factorization it is
2562: Note Collective
2563: as the flag
2565: Input Parameters:
2566: . mat - the matrix
2568: Output Parameters:
2569: . t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT
2571: Level: intermediate
2573: .seealso: MatFactorType, MatGetFactor()
2574: @*/
2575: PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t)
2576: {
2580: *t = mat->factortype;
2581: return(0);
2582: }
2584: /* ------------------------------------------------------------*/
2587: /*@C
2588: MatGetInfo - Returns information about matrix storage (number of
2589: nonzeros, memory, etc.).
2591: Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag
2593: Input Parameters:
2594: . mat - the matrix
2596: Output Parameters:
2597: + flag - flag indicating the type of parameters to be returned
2598: (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2599: MAT_GLOBAL_SUM - sum over all processors)
2600: - info - matrix information context
2602: Notes:
2603: The MatInfo context contains a variety of matrix data, including
2604: number of nonzeros allocated and used, number of mallocs during
2605: matrix assembly, etc. Additional information for factored matrices
2606: is provided (such as the fill ratio, number of mallocs during
2607: factorization, etc.). Much of this info is printed to PETSC_STDOUT
2608: when using the runtime options
2609: $ -info -mat_view ::ascii_info
2611: Example for C/C++ Users:
2612: See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2613: data within the MatInfo context. For example,
2614: .vb
2615: MatInfo info;
2616: Mat A;
2617: double mal, nz_a, nz_u;
2619: MatGetInfo(A,MAT_LOCAL,&info);
2620: mal = info.mallocs;
2621: nz_a = info.nz_allocated;
2622: .ve
2624: Example for Fortran Users:
2625: Fortran users should declare info as a double precision
2626: array of dimension MAT_INFO_SIZE, and then extract the parameters
2627: of interest. See the file ${PETSC_DIR}/include/finclude/petscmat.h
2628: a complete list of parameter names.
2629: .vb
2630: double precision info(MAT_INFO_SIZE)
2631: double precision mal, nz_a
2632: Mat A
2633: integer ierr
2635: call MatGetInfo(A,MAT_LOCAL,info,ierr)
2636: mal = info(MAT_INFO_MALLOCS)
2637: nz_a = info(MAT_INFO_NZ_ALLOCATED)
2638: .ve
2640: Level: intermediate
2642: Concepts: matrices^getting information on
2644: Developer Note: fortran interface is not autogenerated as the f90
2645: interface defintion cannot be generated correctly [due to MatInfo]
2647: .seealso: MatStashGetInfo()
2649: @*/
2650: PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2651: {
2658: if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2659: MatCheckPreallocated(mat,1);
2660: (*mat->ops->getinfo)(mat,flag,info);
2661: return(0);
2662: }
2664: /* ----------------------------------------------------------*/
2668: /*@C
2669: MatLUFactor - Performs in-place LU factorization of matrix.
2671: Collective on Mat
2673: Input Parameters:
2674: + mat - the matrix
2675: . row - row permutation
2676: . col - column permutation
2677: - info - options for factorization, includes
2678: $ fill - expected fill as ratio of original fill.
2679: $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2680: $ Run with the option -info to determine an optimal value to use
2682: Notes:
2683: Most users should employ the simplified KSP interface for linear solvers
2684: instead of working directly with matrix algebra routines such as this.
2685: See, e.g., KSPCreate().
2687: This changes the state of the matrix to a factored matrix; it cannot be used
2688: for example with MatSetValues() unless one first calls MatSetUnfactored().
2690: Level: developer
2692: Concepts: matrices^LU factorization
2694: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2695: MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor()
2697: Developer Note: fortran interface is not autogenerated as the f90
2698: interface defintion cannot be generated correctly [due to MatFactorInfo]
2700: @*/
2701: PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2702: {
2704: MatFactorInfo tinfo;
2712: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2713: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2714: if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2715: MatCheckPreallocated(mat,1);
2716: if (!info) {
2717: MatFactorInfoInitialize(&tinfo);
2718: info = &tinfo;
2719: }
2721: PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);
2722: (*mat->ops->lufactor)(mat,row,col,info);
2723: PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);
2724: PetscObjectStateIncrease((PetscObject)mat);
2725: return(0);
2726: }
2730: /*@C
2731: MatILUFactor - Performs in-place ILU factorization of matrix.
2733: Collective on Mat
2735: Input Parameters:
2736: + mat - the matrix
2737: . row - row permutation
2738: . col - column permutation
2739: - info - structure containing
2740: $ levels - number of levels of fill.
2741: $ expected fill - as ratio of original fill.
2742: $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2743: missing diagonal entries)
2745: Notes:
2746: Probably really in-place only when level of fill is zero, otherwise allocates
2747: new space to store factored matrix and deletes previous memory.
2749: Most users should employ the simplified KSP interface for linear solvers
2750: instead of working directly with matrix algebra routines such as this.
2751: See, e.g., KSPCreate().
2753: Level: developer
2755: Concepts: matrices^ILU factorization
2757: .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
2759: Developer Note: fortran interface is not autogenerated as the f90
2760: interface defintion cannot be generated correctly [due to MatFactorInfo]
2762: @*/
2763: PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2764: {
2773: if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
2774: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2775: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2776: if (!mat->ops->ilufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2777: MatCheckPreallocated(mat,1);
2779: PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);
2780: (*mat->ops->ilufactor)(mat,row,col,info);
2781: PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);
2782: PetscObjectStateIncrease((PetscObject)mat);
2783: return(0);
2784: }
2788: /*@C
2789: MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
2790: Call this routine before calling MatLUFactorNumeric().
2792: Collective on Mat
2794: Input Parameters:
2795: + fact - the factor matrix obtained with MatGetFactor()
2796: . mat - the matrix
2797: . row, col - row and column permutations
2798: - info - options for factorization, includes
2799: $ fill - expected fill as ratio of original fill.
2800: $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2801: $ Run with the option -info to determine an optimal value to use
2804: Notes: See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
2806: Most users should employ the simplified KSP interface for linear solvers
2807: instead of working directly with matrix algebra routines such as this.
2808: See, e.g., KSPCreate().
2810: Level: developer
2812: Concepts: matrices^LU symbolic factorization
2814: .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
2816: Developer Note: fortran interface is not autogenerated as the f90
2817: interface defintion cannot be generated correctly [due to MatFactorInfo]
2819: @*/
2820: PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
2821: {
2831: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2832: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2833: if (!(fact)->ops->lufactorsymbolic) {
2834: const MatSolverPackage spackage;
2835: MatFactorGetSolverPackage(fact,&spackage);
2836: SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage);
2837: }
2838: MatCheckPreallocated(mat,2);
2840: PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);
2841: (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);
2842: PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);
2843: PetscObjectStateIncrease((PetscObject)fact);
2844: return(0);
2845: }
2849: /*@C
2850: MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
2851: Call this routine after first calling MatLUFactorSymbolic().
2853: Collective on Mat
2855: Input Parameters:
2856: + fact - the factor matrix obtained with MatGetFactor()
2857: . mat - the matrix
2858: - info - options for factorization
2860: Notes:
2861: See MatLUFactor() for in-place factorization. See
2862: MatCholeskyFactorNumeric() for the symmetric, positive definite case.
2864: Most users should employ the simplified KSP interface for linear solvers
2865: instead of working directly with matrix algebra routines such as this.
2866: See, e.g., KSPCreate().
2868: Level: developer
2870: Concepts: matrices^LU numeric factorization
2872: .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()
2874: Developer Note: fortran interface is not autogenerated as the f90
2875: interface defintion cannot be generated correctly [due to MatFactorInfo]
2877: @*/
2878: PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
2879: {
2887: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2888: if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) SETERRQ4(PetscObjectComm((PetscObject)mat),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);
2890: if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name);
2891: MatCheckPreallocated(mat,2);
2892: PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);
2893: (fact->ops->lufactornumeric)(fact,mat,info);
2894: PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);
2895: MatViewFromOptions(fact,NULL,"-mat_factor_view");
2896: PetscObjectStateIncrease((PetscObject)fact);
2897: return(0);
2898: }
2902: /*@C
2903: MatCholeskyFactor - Performs in-place Cholesky factorization of a
2904: symmetric matrix.
2906: Collective on Mat
2908: Input Parameters:
2909: + mat - the matrix
2910: . perm - row and column permutations
2911: - f - expected fill as ratio of original fill
2913: Notes:
2914: See MatLUFactor() for the nonsymmetric case. See also
2915: MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().
2917: Most users should employ the simplified KSP interface for linear solvers
2918: instead of working directly with matrix algebra routines such as this.
2919: See, e.g., KSPCreate().
2921: Level: developer
2923: Concepts: matrices^Cholesky factorization
2925: .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
2926: MatGetOrdering()
2928: Developer Note: fortran interface is not autogenerated as the f90
2929: interface defintion cannot be generated correctly [due to MatFactorInfo]
2931: @*/
2932: PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
2933: {
2941: if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
2942: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2943: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2944: if (!mat->ops->choleskyfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2945: MatCheckPreallocated(mat,1);
2947: PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);
2948: (*mat->ops->choleskyfactor)(mat,perm,info);
2949: PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);
2950: PetscObjectStateIncrease((PetscObject)mat);
2951: return(0);
2952: }
2956: /*@C
2957: MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
2958: of a symmetric matrix.
2960: Collective on Mat
2962: Input Parameters:
2963: + fact - the factor matrix obtained with MatGetFactor()
2964: . mat - the matrix
2965: . perm - row and column permutations
2966: - info - options for factorization, includes
2967: $ fill - expected fill as ratio of original fill.
2968: $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2969: $ Run with the option -info to determine an optimal value to use
2971: Notes:
2972: See MatLUFactorSymbolic() for the nonsymmetric case. See also
2973: MatCholeskyFactor() and MatCholeskyFactorNumeric().
2975: Most users should employ the simplified KSP interface for linear solvers
2976: instead of working directly with matrix algebra routines such as this.
2977: See, e.g., KSPCreate().
2979: Level: developer
2981: Concepts: matrices^Cholesky symbolic factorization
2983: .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
2984: MatGetOrdering()
2986: Developer Note: fortran interface is not autogenerated as the f90
2987: interface defintion cannot be generated correctly [due to MatFactorInfo]
2989: @*/
2990: PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
2991: {
3000: if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3001: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3002: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3003: if (!(fact)->ops->choleskyfactorsymbolic) {
3004: const MatSolverPackage spackage;
3005: MatFactorGetSolverPackage(fact,&spackage);
3006: SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage);
3007: }
3008: MatCheckPreallocated(mat,2);
3010: PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
3011: (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);
3012: PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
3013: PetscObjectStateIncrease((PetscObject)fact);
3014: return(0);
3015: }
3019: /*@C
3020: MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
3021: of a symmetric matrix. Call this routine after first calling
3022: MatCholeskyFactorSymbolic().
3024: Collective on Mat
3026: Input Parameters:
3027: + fact - the factor matrix obtained with MatGetFactor()
3028: . mat - the initial matrix
3029: . info - options for factorization
3030: - fact - the symbolic factor of mat
3033: Notes:
3034: Most users should employ the simplified KSP interface for linear solvers
3035: instead of working directly with matrix algebra routines such as this.
3036: See, e.g., KSPCreate().
3038: Level: developer
3040: Concepts: matrices^Cholesky numeric factorization
3042: .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
3044: Developer Note: fortran interface is not autogenerated as the f90
3045: interface defintion cannot be generated correctly [due to MatFactorInfo]
3047: @*/
3048: PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3049: {
3057: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3058: if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name);
3059: if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) SETERRQ4(PetscObjectComm((PetscObject)mat),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);
3060: MatCheckPreallocated(mat,2);
3062: PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);
3063: (fact->ops->choleskyfactornumeric)(fact,mat,info);
3064: PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);
3065: MatViewFromOptions(fact,NULL,"-mat_factor_view");
3066: PetscObjectStateIncrease((PetscObject)fact);
3067: return(0);
3068: }
3070: /* ----------------------------------------------------------------*/
3073: /*@
3074: MatSolve - Solves A x = b, given a factored matrix.
3076: Neighbor-wise Collective on Mat and Vec
3078: Input Parameters:
3079: + mat - the factored matrix
3080: - b - the right-hand-side vector
3082: Output Parameter:
3083: . x - the result vector
3085: Notes:
3086: The vectors b and x cannot be the same. I.e., one cannot
3087: call MatSolve(A,x,x).
3089: Notes:
3090: Most users should employ the simplified KSP interface for linear solvers
3091: instead of working directly with matrix algebra routines such as this.
3092: See, e.g., KSPCreate().
3094: Level: developer
3096: Concepts: matrices^triangular solves
3098: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
3099: @*/
3100: PetscErrorCode MatSolve(Mat mat,Vec b,Vec x)
3101: {
3111: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3112: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3113: if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3114: if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3115: 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);
3116: if (!mat->rmap->N && !mat->cmap->N) return(0);
3117: if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3118: MatCheckPreallocated(mat,1);
3120: PetscLogEventBegin(MAT_Solve,mat,b,x,0);
3121: (*mat->ops->solve)(mat,b,x);
3122: PetscLogEventEnd(MAT_Solve,mat,b,x,0);
3123: PetscObjectStateIncrease((PetscObject)x);
3124: return(0);
3125: }
3129: PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X)
3130: {
3132: Vec b,x;
3133: PetscInt m,N,i;
3134: PetscScalar *bb,*xx;
3135: PetscBool flg;
3138: PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);
3139: if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
3140: PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);
3141: if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");
3143: MatDenseGetArray(B,&bb);
3144: MatDenseGetArray(X,&xx);
3145: MatGetLocalSize(B,&m,NULL); /* number local rows */
3146: MatGetSize(B,NULL,&N); /* total columns in dense matrix */
3147: MatGetVecs(A,&x,&b);
3148: for (i=0; i<N; i++) {
3149: VecPlaceArray(b,bb + i*m);
3150: VecPlaceArray(x,xx + i*m);
3151: MatSolve(A,b,x);
3152: VecResetArray(x);
3153: VecResetArray(b);
3154: }
3155: VecDestroy(&b);
3156: VecDestroy(&x);
3157: MatDenseRestoreArray(B,&bb);
3158: MatDenseRestoreArray(X,&xx);
3159: return(0);
3160: }
3164: /*@
3165: MatMatSolve - Solves A X = B, given a factored matrix.
3167: Neighbor-wise Collective on Mat
3169: Input Parameters:
3170: + mat - the factored matrix
3171: - B - the right-hand-side matrix (dense matrix)
3173: Output Parameter:
3174: . X - the result matrix (dense matrix)
3176: Notes:
3177: The matrices b and x cannot be the same. I.e., one cannot
3178: call MatMatSolve(A,x,x).
3180: Notes:
3181: Most users should usually employ the simplified KSP interface for linear solvers
3182: instead of working directly with matrix algebra routines such as this.
3183: See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3184: at a time.
3186: When using SuperLU_Dist as a parallel solver PETSc will use the SuperLU_Dist functionality to solve multiple right hand sides simultaneously. For MUMPS
3187: it calls a separate solve for each right hand side since MUMPS does not yet support distributed right hand sides.
3189: Since the resulting matrix X must always be dense we do not support sparse representation of the matrix B.
3191: Level: developer
3193: Concepts: matrices^triangular solves
3195: .seealso: MatMatSolveAdd(), MatMatSolveTranspose(), MatMatSolveTransposeAdd(), MatLUFactor(), MatCholeskyFactor()
3196: @*/
3197: PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X)
3198: {
3208: if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3209: if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3210: if (A->cmap->N != X->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %D %D",A->cmap->N,X->rmap->N);
3211: if (A->rmap->N != B->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %D %D",A->rmap->N,B->rmap->N);
3212: 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);
3213: if (!A->rmap->N && !A->cmap->N) return(0);
3214: MatCheckPreallocated(A,1);
3216: PetscLogEventBegin(MAT_MatSolve,A,B,X,0);
3217: if (!A->ops->matsolve) {
3218: PetscInfo1(A,"Mat type %s using basic MatMatSolve",((PetscObject)A)->type_name);
3219: MatMatSolve_Basic(A,B,X);
3220: } else {
3221: (*A->ops->matsolve)(A,B,X);
3222: }
3223: PetscLogEventEnd(MAT_MatSolve,A,B,X,0);
3224: PetscObjectStateIncrease((PetscObject)X);
3225: return(0);
3226: }
3231: /*@
3232: MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or
3233: U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U,
3235: Neighbor-wise Collective on Mat and Vec
3237: Input Parameters:
3238: + mat - the factored matrix
3239: - b - the right-hand-side vector
3241: Output Parameter:
3242: . x - the result vector
3244: Notes:
3245: MatSolve() should be used for most applications, as it performs
3246: a forward solve followed by a backward solve.
3248: The vectors b and x cannot be the same, i.e., one cannot
3249: call MatForwardSolve(A,x,x).
3251: For matrix in seqsbaij format with block size larger than 1,
3252: the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3253: MatForwardSolve() solves U^T*D y = b, and
3254: MatBackwardSolve() solves U x = y.
3255: Thus they do not provide a symmetric preconditioner.
3257: Most users should employ the simplified KSP interface for linear solvers
3258: instead of working directly with matrix algebra routines such as this.
3259: See, e.g., KSPCreate().
3261: Level: developer
3263: Concepts: matrices^forward solves
3265: .seealso: MatSolve(), MatBackwardSolve()
3266: @*/
3267: PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x)
3268: {
3278: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3279: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3280: if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3281: if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3282: if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3283: 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);
3284: MatCheckPreallocated(mat,1);
3285: PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);
3286: (*mat->ops->forwardsolve)(mat,b,x);
3287: PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);
3288: PetscObjectStateIncrease((PetscObject)x);
3289: return(0);
3290: }
3294: /*@
3295: MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
3296: D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U,
3298: Neighbor-wise Collective on Mat and Vec
3300: Input Parameters:
3301: + mat - the factored matrix
3302: - b - the right-hand-side vector
3304: Output Parameter:
3305: . x - the result vector
3307: Notes:
3308: MatSolve() should be used for most applications, as it performs
3309: a forward solve followed by a backward solve.
3311: The vectors b and x cannot be the same. I.e., one cannot
3312: call MatBackwardSolve(A,x,x).
3314: For matrix in seqsbaij format with block size larger than 1,
3315: the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3316: MatForwardSolve() solves U^T*D y = b, and
3317: MatBackwardSolve() solves U x = y.
3318: Thus they do not provide a symmetric preconditioner.
3320: Most users should employ the simplified KSP interface for linear solvers
3321: instead of working directly with matrix algebra routines such as this.
3322: See, e.g., KSPCreate().
3324: Level: developer
3326: Concepts: matrices^backward solves
3328: .seealso: MatSolve(), MatForwardSolve()
3329: @*/
3330: PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x)
3331: {
3341: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3342: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3343: if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3344: if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3345: if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3346: 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);
3347: MatCheckPreallocated(mat,1);
3349: PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);
3350: (*mat->ops->backwardsolve)(mat,b,x);
3351: PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);
3352: PetscObjectStateIncrease((PetscObject)x);
3353: return(0);
3354: }
3358: /*@
3359: MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
3361: Neighbor-wise Collective on Mat and Vec
3363: Input Parameters:
3364: + mat - the factored matrix
3365: . b - the right-hand-side vector
3366: - y - the vector to be added to
3368: Output Parameter:
3369: . x - the result vector
3371: Notes:
3372: The vectors b and x cannot be the same. I.e., one cannot
3373: call MatSolveAdd(A,x,y,x).
3375: Most users should employ the simplified KSP interface for linear solvers
3376: instead of working directly with matrix algebra routines such as this.
3377: See, e.g., KSPCreate().
3379: Level: developer
3381: Concepts: matrices^triangular solves
3383: .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3384: @*/
3385: PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3386: {
3387: PetscScalar one = 1.0;
3388: Vec tmp;
3400: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3401: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3402: if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3403: if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3404: if (mat->rmap->N != y->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
3405: 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);
3406: 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);
3407: MatCheckPreallocated(mat,1);
3409: PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);
3410: if (mat->ops->solveadd) {
3411: (*mat->ops->solveadd)(mat,b,y,x);
3412: } else {
3413: /* do the solve then the add manually */
3414: if (x != y) {
3415: MatSolve(mat,b,x);
3416: VecAXPY(x,one,y);
3417: } else {
3418: VecDuplicate(x,&tmp);
3419: PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);
3420: VecCopy(x,tmp);
3421: MatSolve(mat,b,x);
3422: VecAXPY(x,one,tmp);
3423: VecDestroy(&tmp);
3424: }
3425: }
3426: PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);
3427: PetscObjectStateIncrease((PetscObject)x);
3428: return(0);
3429: }
3433: /*@
3434: MatSolveTranspose - Solves A' x = b, given a factored matrix.
3436: Neighbor-wise Collective on Mat and Vec
3438: Input Parameters:
3439: + mat - the factored matrix
3440: - b - the right-hand-side vector
3442: Output Parameter:
3443: . x - the result vector
3445: Notes:
3446: The vectors b and x cannot be the same. I.e., one cannot
3447: call MatSolveTranspose(A,x,x).
3449: Most users should employ the simplified KSP interface for linear solvers
3450: instead of working directly with matrix algebra routines such as this.
3451: See, e.g., KSPCreate().
3453: Level: developer
3455: Concepts: matrices^triangular solves
3457: .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
3458: @*/
3459: PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x)
3460: {
3470: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3471: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3472: if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3473: if (mat->rmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
3474: if (mat->cmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->cmap->N,b->map->N);
3475: MatCheckPreallocated(mat,1);
3476: PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);
3477: (*mat->ops->solvetranspose)(mat,b,x);
3478: PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);
3479: PetscObjectStateIncrease((PetscObject)x);
3480: return(0);
3481: }
3485: /*@
3486: MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
3487: factored matrix.
3489: Neighbor-wise Collective on Mat and Vec
3491: Input Parameters:
3492: + mat - the factored matrix
3493: . b - the right-hand-side vector
3494: - y - the vector to be added to
3496: Output Parameter:
3497: . x - the result vector
3499: Notes:
3500: The vectors b and x cannot be the same. I.e., one cannot
3501: call MatSolveTransposeAdd(A,x,y,x).
3503: Most users should employ the simplified KSP interface for linear solvers
3504: instead of working directly with matrix algebra routines such as this.
3505: See, e.g., KSPCreate().
3507: Level: developer
3509: Concepts: matrices^triangular solves
3511: .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3512: @*/
3513: PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3514: {
3515: PetscScalar one = 1.0;
3517: Vec tmp;
3528: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3529: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3530: if (mat->rmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
3531: if (mat->cmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->cmap->N,b->map->N);
3532: if (mat->cmap->N != y->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N);
3533: 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);
3534: MatCheckPreallocated(mat,1);
3536: PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);
3537: if (mat->ops->solvetransposeadd) {
3538: (*mat->ops->solvetransposeadd)(mat,b,y,x);
3539: } else {
3540: /* do the solve then the add manually */
3541: if (x != y) {
3542: MatSolveTranspose(mat,b,x);
3543: VecAXPY(x,one,y);
3544: } else {
3545: VecDuplicate(x,&tmp);
3546: PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);
3547: VecCopy(x,tmp);
3548: MatSolveTranspose(mat,b,x);
3549: VecAXPY(x,one,tmp);
3550: VecDestroy(&tmp);
3551: }
3552: }
3553: PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);
3554: PetscObjectStateIncrease((PetscObject)x);
3555: return(0);
3556: }
3557: /* ----------------------------------------------------------------*/
3561: /*@
3562: MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps.
3564: Neighbor-wise Collective on Mat and Vec
3566: Input Parameters:
3567: + mat - the matrix
3568: . b - the right hand side
3569: . omega - the relaxation factor
3570: . flag - flag indicating the type of SOR (see below)
3571: . shift - diagonal shift
3572: . its - the number of iterations
3573: - lits - the number of local iterations
3575: Output Parameters:
3576: . x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess)
3578: SOR Flags:
3579: . SOR_FORWARD_SWEEP - forward SOR
3580: . SOR_BACKWARD_SWEEP - backward SOR
3581: . SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3582: . SOR_LOCAL_FORWARD_SWEEP - local forward SOR
3583: . SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
3584: . SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3585: . SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
3586: upper/lower triangular part of matrix to
3587: vector (with omega)
3588: . SOR_ZERO_INITIAL_GUESS - zero initial guess
3590: Notes:
3591: SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3592: SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3593: on each processor.
3595: Application programmers will not generally use MatSOR() directly,
3596: but instead will employ the KSP/PC interface.
3598: Notes: for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing
3600: Notes for Advanced Users:
3601: The flags are implemented as bitwise inclusive or operations.
3602: For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3603: to specify a zero initial guess for SSOR.
3605: Most users should employ the simplified KSP interface for linear solvers
3606: instead of working directly with matrix algebra routines such as this.
3607: See, e.g., KSPCreate().
3609: Vectors x and b CANNOT be the same
3611: Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes
3613: Level: developer
3615: Concepts: matrices^relaxation
3616: Concepts: matrices^SOR
3617: Concepts: matrices^Gauss-Seidel
3619: @*/
3620: PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3621: {
3631: if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3632: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3633: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3634: if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3635: if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3636: 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);
3637: if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
3638: if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
3639: if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");
3641: MatCheckPreallocated(mat,1);
3642: PetscLogEventBegin(MAT_SOR,mat,b,x,0);
3643: ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);
3644: PetscLogEventEnd(MAT_SOR,mat,b,x,0);
3645: PetscObjectStateIncrease((PetscObject)x);
3646: return(0);
3647: }
3651: /*
3652: Default matrix copy routine.
3653: */
3654: PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
3655: {
3656: PetscErrorCode ierr;
3657: PetscInt i,rstart = 0,rend = 0,nz;
3658: const PetscInt *cwork;
3659: const PetscScalar *vwork;
3662: if (B->assembled) {
3663: MatZeroEntries(B);
3664: }
3665: MatGetOwnershipRange(A,&rstart,&rend);
3666: for (i=rstart; i<rend; i++) {
3667: MatGetRow(A,i,&nz,&cwork,&vwork);
3668: MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);
3669: MatRestoreRow(A,i,&nz,&cwork,&vwork);
3670: }
3671: MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
3672: MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);
3673: PetscObjectStateIncrease((PetscObject)B);
3674: return(0);
3675: }
3679: /*@
3680: MatCopy - Copys a matrix to another matrix.
3682: Collective on Mat
3684: Input Parameters:
3685: + A - the matrix
3686: - str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
3688: Output Parameter:
3689: . B - where the copy is put
3691: Notes:
3692: If you use SAME_NONZERO_PATTERN then the two matrices had better have the
3693: same nonzero pattern or the routine will crash.
3695: MatCopy() copies the matrix entries of a matrix to another existing
3696: matrix (after first zeroing the second matrix). A related routine is
3697: MatConvert(), which first creates a new matrix and then copies the data.
3699: Level: intermediate
3701: Concepts: matrices^copying
3703: .seealso: MatConvert(), MatDuplicate()
3705: @*/
3706: PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str)
3707: {
3709: PetscInt i;
3717: MatCheckPreallocated(B,2);
3718: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3719: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3720: if (A->rmap->N != B->rmap->N || A->cmap->N != B->cmap->N) SETERRQ4(PetscObjectComm((PetscObject)A),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);
3721: MatCheckPreallocated(A,1);
3723: PetscLogEventBegin(MAT_Copy,A,B,0,0);
3724: if (A->ops->copy) {
3725: (*A->ops->copy)(A,B,str);
3726: } else { /* generic conversion */
3727: MatCopy_Basic(A,B,str);
3728: }
3730: B->stencil.dim = A->stencil.dim;
3731: B->stencil.noc = A->stencil.noc;
3732: for (i=0; i<=A->stencil.dim; i++) {
3733: B->stencil.dims[i] = A->stencil.dims[i];
3734: B->stencil.starts[i] = A->stencil.starts[i];
3735: }
3737: PetscLogEventEnd(MAT_Copy,A,B,0,0);
3738: PetscObjectStateIncrease((PetscObject)B);
3739: return(0);
3740: }
3744: /*@C
3745: MatConvert - Converts a matrix to another matrix, either of the same
3746: or different type.
3748: Collective on Mat
3750: Input Parameters:
3751: + mat - the matrix
3752: . newtype - new matrix type. Use MATSAME to create a new matrix of the
3753: same type as the original matrix.
3754: - reuse - denotes if the destination matrix is to be created or reused. Currently
3755: MAT_REUSE_MATRIX is only supported for inplace conversion, otherwise use
3756: MAT_INITIAL_MATRIX.
3758: Output Parameter:
3759: . M - pointer to place new matrix
3761: Notes:
3762: MatConvert() first creates a new matrix and then copies the data from
3763: the first matrix. A related routine is MatCopy(), which copies the matrix
3764: entries of one matrix to another already existing matrix context.
3766: Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
3767: the MPI communicator of the generated matrix is always the same as the communicator
3768: of the input matrix.
3770: Level: intermediate
3772: Concepts: matrices^converting between storage formats
3774: .seealso: MatCopy(), MatDuplicate()
3775: @*/
3776: PetscErrorCode MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M)
3777: {
3779: PetscBool sametype,issame,flg;
3780: char convname[256],mtype[256];
3781: Mat B;
3787: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3788: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3789: MatCheckPreallocated(mat,1);
3790: MatSetOption(mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);
3792: PetscOptionsGetString(((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);
3793: if (flg) {
3794: newtype = mtype;
3795: }
3796: PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);
3797: PetscStrcmp(newtype,"same",&issame);
3798: if ((reuse == MAT_REUSE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_REUSE_MATRIX only supported for in-place conversion currently");
3800: if ((reuse == MAT_REUSE_MATRIX) && (issame || sametype)) return(0);
3802: if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
3803: (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);
3804: } else {
3805: PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL;
3806: const char *prefix[3] = {"seq","mpi",""};
3807: PetscInt i;
3808: /*
3809: Order of precedence:
3810: 1) See if a specialized converter is known to the current matrix.
3811: 2) See if a specialized converter is known to the desired matrix class.
3812: 3) See if a good general converter is registered for the desired class
3813: (as of 6/27/03 only MATMPIADJ falls into this category).
3814: 4) See if a good general converter is known for the current matrix.
3815: 5) Use a really basic converter.
3816: */
3818: /* 1) See if a specialized converter is known to the current matrix and the desired class */
3819: for (i=0; i<3; i++) {
3820: PetscStrcpy(convname,"MatConvert_");
3821: PetscStrcat(convname,((PetscObject)mat)->type_name);
3822: PetscStrcat(convname,"_");
3823: PetscStrcat(convname,prefix[i]);
3824: PetscStrcat(convname,issame ? ((PetscObject)mat)->type_name : newtype);
3825: PetscStrcat(convname,"_C");
3826: PetscObjectQueryFunction((PetscObject)mat,convname,&conv);
3827: if (conv) goto foundconv;
3828: }
3830: /* 2) See if a specialized converter is known to the desired matrix class. */
3831: MatCreate(PetscObjectComm((PetscObject)mat),&B);
3832: MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);
3833: MatSetType(B,newtype);
3834: for (i=0; i<3; i++) {
3835: PetscStrcpy(convname,"MatConvert_");
3836: PetscStrcat(convname,((PetscObject)mat)->type_name);
3837: PetscStrcat(convname,"_");
3838: PetscStrcat(convname,prefix[i]);
3839: PetscStrcat(convname,newtype);
3840: PetscStrcat(convname,"_C");
3841: PetscObjectQueryFunction((PetscObject)B,convname,&conv);
3842: if (conv) {
3843: MatDestroy(&B);
3844: goto foundconv;
3845: }
3846: }
3848: /* 3) See if a good general converter is registered for the desired class */
3849: conv = B->ops->convertfrom;
3850: MatDestroy(&B);
3851: if (conv) goto foundconv;
3853: /* 4) See if a good general converter is known for the current matrix */
3854: if (mat->ops->convert) {
3855: conv = mat->ops->convert;
3856: }
3857: if (conv) goto foundconv;
3859: /* 5) Use a really basic converter. */
3860: conv = MatConvert_Basic;
3862: foundconv:
3863: PetscLogEventBegin(MAT_Convert,mat,0,0,0);
3864: (*conv)(mat,newtype,reuse,M);
3865: PetscLogEventEnd(MAT_Convert,mat,0,0,0);
3866: }
3867: PetscObjectStateIncrease((PetscObject)*M);
3869: /* Copy Mat options */
3870: if (mat->symmetric) {MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);}
3871: if (mat->hermitian) {MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);}
3872: return(0);
3873: }
3877: /*@C
3878: MatFactorGetSolverPackage - Returns name of the package providing the factorization routines
3880: Not Collective
3882: Input Parameter:
3883: . mat - the matrix, must be a factored matrix
3885: Output Parameter:
3886: . type - the string name of the package (do not free this string)
3888: Notes:
3889: In Fortran you pass in a empty string and the package name will be copied into it.
3890: (Make sure the string is long enough)
3892: Level: intermediate
3894: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
3895: @*/
3896: PetscErrorCode MatFactorGetSolverPackage(Mat mat, const MatSolverPackage *type)
3897: {
3898: PetscErrorCode ierr, (*conv)(Mat,const MatSolverPackage*);
3903: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
3904: PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverPackage_C",&conv);
3905: if (!conv) {
3906: *type = MATSOLVERPETSC;
3907: } else {
3908: (*conv)(mat,type);
3909: }
3910: return(0);
3911: }
3915: /*@C
3916: MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic()
3918: Collective on Mat
3920: Input Parameters:
3921: + mat - the matrix
3922: . type - name of solver type, for example, superlu, petsc (to use PETSc's default)
3923: - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
3925: Output Parameters:
3926: . f - the factor matrix used with MatXXFactorSymbolic() calls
3928: Notes:
3929: Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
3930: such as pastix, superlu, mumps etc.
3932: PETSc must have been ./configure to use the external solver, using the option --download-package
3934: Level: intermediate
3936: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
3937: @*/
3938: PetscErrorCode MatGetFactor(Mat mat, const MatSolverPackage type,MatFactorType ftype,Mat *f)
3939: {
3940: PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
3941: char convname[256];
3947: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3948: MatCheckPreallocated(mat,1);
3950: PetscStrcpy(convname,"MatGetFactor_");
3951: PetscStrcat(convname,type);
3952: PetscStrcat(convname,"_C");
3953: PetscObjectQueryFunction((PetscObject)mat,convname,&conv);
3954: if (!conv) {
3955: PetscBool flag;
3956: MPI_Comm comm;
3958: PetscObjectGetComm((PetscObject)mat,&comm);
3959: PetscStrcasecmp(MATSOLVERPETSC,type,&flag);
3960: if (flag) SETERRQ2(comm,PETSC_ERR_SUP,"Matrix format %s does not have a built-in PETSc %s",((PetscObject)mat)->type_name,MatFactorTypes[ftype]);
3961: else 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);
3962: }
3963: (*conv)(mat,ftype,f);
3964: return(0);
3965: }
3969: /*@C
3970: MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type
3972: Not Collective
3974: Input Parameters:
3975: + mat - the matrix
3976: . type - name of solver type, for example, superlu, petsc (to use PETSc's default)
3977: - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
3979: Output Parameter:
3980: . flg - PETSC_TRUE if the factorization is available
3982: Notes:
3983: Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
3984: such as pastix, superlu, mumps etc.
3986: PETSc must have been ./configure to use the external solver, using the option --download-package
3988: Level: intermediate
3990: .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
3991: @*/
3992: PetscErrorCode MatGetFactorAvailable(Mat mat, const MatSolverPackage type,MatFactorType ftype,PetscBool *flg)
3993: {
3994: PetscErrorCode ierr, (*conv)(Mat,MatFactorType,PetscBool*);
3995: char convname[256];
4001: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4002: MatCheckPreallocated(mat,1);
4004: PetscStrcpy(convname,"MatGetFactorAvailable_");
4005: PetscStrcat(convname,type);
4006: PetscStrcat(convname,"_C");
4007: PetscObjectQueryFunction((PetscObject)mat,convname,&conv);
4008: if (!conv) {
4009: *flg = PETSC_FALSE;
4010: } else {
4011: (*conv)(mat,ftype,flg);
4012: }
4013: return(0);
4014: }
4019: /*@
4020: MatDuplicate - Duplicates a matrix including the non-zero structure.
4022: Collective on Mat
4024: Input Parameters:
4025: + mat - the matrix
4026: - op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy the numerical values in the matrix
4027: MAT_SHARE_NONZERO_PATTERN to share the nonzero patterns with the previous matrix and not copy them.
4029: Output Parameter:
4030: . M - pointer to place new matrix
4032: Level: intermediate
4034: Concepts: matrices^duplicating
4036: Notes: You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN.
4038: .seealso: MatCopy(), MatConvert()
4039: @*/
4040: PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4041: {
4043: Mat B;
4044: PetscInt i;
4050: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4051: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4052: MatCheckPreallocated(mat,1);
4054: *M = 0;
4055: if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type");
4056: PetscLogEventBegin(MAT_Convert,mat,0,0,0);
4057: (*mat->ops->duplicate)(mat,op,M);
4058: B = *M;
4060: B->stencil.dim = mat->stencil.dim;
4061: B->stencil.noc = mat->stencil.noc;
4062: for (i=0; i<=mat->stencil.dim; i++) {
4063: B->stencil.dims[i] = mat->stencil.dims[i];
4064: B->stencil.starts[i] = mat->stencil.starts[i];
4065: }
4067: B->nooffproczerorows = mat->nooffproczerorows;
4068: B->nooffprocentries = mat->nooffprocentries;
4070: PetscLogEventEnd(MAT_Convert,mat,0,0,0);
4071: PetscObjectStateIncrease((PetscObject)B);
4072: return(0);
4073: }
4077: /*@
4078: MatGetDiagonal - Gets the diagonal of a matrix.
4080: Logically Collective on Mat and Vec
4082: Input Parameters:
4083: + mat - the matrix
4084: - v - the vector for storing the diagonal
4086: Output Parameter:
4087: . v - the diagonal of the matrix
4089: Level: intermediate
4091: Note:
4092: Currently only correct in parallel for square matrices.
4094: Concepts: matrices^accessing diagonals
4096: .seealso: MatGetRow(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs()
4097: @*/
4098: PetscErrorCode MatGetDiagonal(Mat mat,Vec v)
4099: {
4106: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4107: if (!mat->ops->getdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4108: MatCheckPreallocated(mat,1);
4110: (*mat->ops->getdiagonal)(mat,v);
4111: PetscObjectStateIncrease((PetscObject)v);
4112: return(0);
4113: }
4117: /*@
4118: MatGetRowMin - Gets the minimum value (of the real part) of each
4119: row of the matrix
4121: Logically Collective on Mat and Vec
4123: Input Parameters:
4124: . mat - the matrix
4126: Output Parameter:
4127: + v - the vector for storing the maximums
4128: - idx - the indices of the column found for each row (optional)
4130: Level: intermediate
4132: Notes: The result of this call are the same as if one converted the matrix to dense format
4133: and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4135: This code is only implemented for a couple of matrix formats.
4137: Concepts: matrices^getting row maximums
4139: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(),
4140: MatGetRowMax()
4141: @*/
4142: PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4143: {
4150: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4151: if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4152: MatCheckPreallocated(mat,1);
4154: (*mat->ops->getrowmin)(mat,v,idx);
4155: PetscObjectStateIncrease((PetscObject)v);
4156: return(0);
4157: }
4161: /*@
4162: MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4163: row of the matrix
4165: Logically Collective on Mat and Vec
4167: Input Parameters:
4168: . mat - the matrix
4170: Output Parameter:
4171: + v - the vector for storing the minimums
4172: - idx - the indices of the column found for each row (or NULL if not needed)
4174: Level: intermediate
4176: Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
4177: row is 0 (the first column).
4179: This code is only implemented for a couple of matrix formats.
4181: Concepts: matrices^getting row maximums
4183: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4184: @*/
4185: PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4186: {
4193: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4194: if (!mat->ops->getrowminabs) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4195: MatCheckPreallocated(mat,1);
4196: if (idx) {PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));}
4198: (*mat->ops->getrowminabs)(mat,v,idx);
4199: PetscObjectStateIncrease((PetscObject)v);
4200: return(0);
4201: }
4205: /*@
4206: MatGetRowMax - Gets the maximum value (of the real part) of each
4207: row of the matrix
4209: Logically Collective on Mat and Vec
4211: Input Parameters:
4212: . mat - the matrix
4214: Output Parameter:
4215: + v - the vector for storing the maximums
4216: - idx - the indices of the column found for each row (optional)
4218: Level: intermediate
4220: Notes: The result of this call are the same as if one converted the matrix to dense format
4221: and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4223: This code is only implemented for a couple of matrix formats.
4225: Concepts: matrices^getting row maximums
4227: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4228: @*/
4229: PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4230: {
4237: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4238: if (!mat->ops->getrowmax) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4239: MatCheckPreallocated(mat,1);
4241: (*mat->ops->getrowmax)(mat,v,idx);
4242: PetscObjectStateIncrease((PetscObject)v);
4243: return(0);
4244: }
4248: /*@
4249: MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4250: row of the matrix
4252: Logically Collective on Mat and Vec
4254: Input Parameters:
4255: . mat - the matrix
4257: Output Parameter:
4258: + v - the vector for storing the maximums
4259: - idx - the indices of the column found for each row (or NULL if not needed)
4261: Level: intermediate
4263: Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
4264: row is 0 (the first column).
4266: This code is only implemented for a couple of matrix formats.
4268: Concepts: matrices^getting row maximums
4270: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4271: @*/
4272: PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4273: {
4280: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4281: if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4282: MatCheckPreallocated(mat,1);
4283: if (idx) {PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));}
4285: (*mat->ops->getrowmaxabs)(mat,v,idx);
4286: PetscObjectStateIncrease((PetscObject)v);
4287: return(0);
4288: }
4292: /*@
4293: MatGetRowSum - Gets the sum of each row of the matrix
4295: Logically Collective on Mat and Vec
4297: Input Parameters:
4298: . mat - the matrix
4300: Output Parameter:
4301: . v - the vector for storing the sum of rows
4303: Level: intermediate
4305: Notes: This code is slow since it is not currently specialized for different formats
4307: Concepts: matrices^getting row sums
4309: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4310: @*/
4311: PetscErrorCode MatGetRowSum(Mat mat, Vec v)
4312: {
4313: PetscInt start = 0, end = 0, row;
4314: PetscScalar *array;
4321: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4322: MatCheckPreallocated(mat,1);
4323: MatGetOwnershipRange(mat, &start, &end);
4324: VecGetArray(v, &array);
4325: for (row = start; row < end; ++row) {
4326: PetscInt ncols, col;
4327: const PetscInt *cols;
4328: const PetscScalar *vals;
4330: array[row - start] = 0.0;
4332: MatGetRow(mat, row, &ncols, &cols, &vals);
4333: for (col = 0; col < ncols; col++) {
4334: array[row - start] += vals[col];
4335: }
4336: MatRestoreRow(mat, row, &ncols, &cols, &vals);
4337: }
4338: VecRestoreArray(v, &array);
4339: PetscObjectStateIncrease((PetscObject) v);
4340: return(0);
4341: }
4345: /*@
4346: MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
4348: Collective on Mat
4350: Input Parameter:
4351: + mat - the matrix to transpose
4352: - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
4354: Output Parameters:
4355: . B - the transpose
4357: Notes:
4358: If you pass in &mat for B the transpose will be done in place, for example MatTranspose(mat,MAT_REUSE_MATRIX,&mat);
4360: Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed.
4362: Level: intermediate
4364: Concepts: matrices^transposing
4366: .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4367: @*/
4368: PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4369: {
4375: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4376: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4377: if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4378: MatCheckPreallocated(mat,1);
4380: PetscLogEventBegin(MAT_Transpose,mat,0,0,0);
4381: (*mat->ops->transpose)(mat,reuse,B);
4382: PetscLogEventEnd(MAT_Transpose,mat,0,0,0);
4383: if (B) {PetscObjectStateIncrease((PetscObject)*B);}
4384: return(0);
4385: }
4389: /*@
4390: MatIsTranspose - Test whether a matrix is another one's transpose,
4391: or its own, in which case it tests symmetry.
4393: Collective on Mat
4395: Input Parameter:
4396: + A - the matrix to test
4397: - B - the matrix to test against, this can equal the first parameter
4399: Output Parameters:
4400: . flg - the result
4402: Notes:
4403: Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4404: has a running time of the order of the number of nonzeros; the parallel
4405: test involves parallel copies of the block-offdiagonal parts of the matrix.
4407: Level: intermediate
4409: Concepts: matrices^transposing, matrix^symmetry
4411: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4412: @*/
4413: PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg)
4414: {
4415: PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4421: PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);
4422: PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);
4423: *flg = PETSC_FALSE;
4424: if (f && g) {
4425: if (f == g) {
4426: (*f)(A,B,tol,flg);
4427: } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4428: } else {
4429: MatType mattype;
4430: if (!f) {
4431: MatGetType(A,&mattype);
4432: } else {
4433: MatGetType(B,&mattype);
4434: }
4435: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
4436: }
4437: return(0);
4438: }
4442: /*@
4443: MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate.
4445: Collective on Mat
4447: Input Parameter:
4448: + mat - the matrix to transpose and complex conjugate
4449: - reuse - store the transpose matrix in the provided B
4451: Output Parameters:
4452: . B - the Hermitian
4454: Notes:
4455: If you pass in &mat for B the Hermitian will be done in place
4457: Level: intermediate
4459: Concepts: matrices^transposing, complex conjugatex
4461: .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4462: @*/
4463: PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
4464: {
4468: MatTranspose(mat,reuse,B);
4469: #if defined(PETSC_USE_COMPLEX)
4470: MatConjugate(*B);
4471: #endif
4472: return(0);
4473: }
4477: /*@
4478: MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,
4480: Collective on Mat
4482: Input Parameter:
4483: + A - the matrix to test
4484: - B - the matrix to test against, this can equal the first parameter
4486: Output Parameters:
4487: . flg - the result
4489: Notes:
4490: Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4491: has a running time of the order of the number of nonzeros; the parallel
4492: test involves parallel copies of the block-offdiagonal parts of the matrix.
4494: Level: intermediate
4496: Concepts: matrices^transposing, matrix^symmetry
4498: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
4499: @*/
4500: PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg)
4501: {
4502: PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4508: PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);
4509: PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);
4510: if (f && g) {
4511: if (f==g) {
4512: (*f)(A,B,tol,flg);
4513: } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
4514: }
4515: return(0);
4516: }
4520: /*@
4521: MatPermute - Creates a new matrix with rows and columns permuted from the
4522: original.
4524: Collective on Mat
4526: Input Parameters:
4527: + mat - the matrix to permute
4528: . row - row permutation, each processor supplies only the permutation for its rows
4529: - col - column permutation, each processor supplies only the permutation for its columns
4531: Output Parameters:
4532: . B - the permuted matrix
4534: Level: advanced
4536: Note:
4537: The index sets map from row/col of permuted matrix to row/col of original matrix.
4538: The index sets should be on the same communicator as Mat and have the same local sizes.
4540: Concepts: matrices^permuting
4542: .seealso: MatGetOrdering(), ISAllGather()
4544: @*/
4545: PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
4546: {
4555: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4556: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4557: if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
4558: MatCheckPreallocated(mat,1);
4560: (*mat->ops->permute)(mat,row,col,B);
4561: PetscObjectStateIncrease((PetscObject)*B);
4562: return(0);
4563: }
4567: /*@
4568: MatEqual - Compares two matrices.
4570: Collective on Mat
4572: Input Parameters:
4573: + A - the first matrix
4574: - B - the second matrix
4576: Output Parameter:
4577: . flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
4579: Level: intermediate
4581: Concepts: matrices^equality between
4582: @*/
4583: PetscErrorCode MatEqual(Mat A,Mat B,PetscBool *flg)
4584: {
4594: MatCheckPreallocated(B,2);
4595: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4596: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4597: if (A->rmap->N != B->rmap->N || A->cmap->N != B->cmap->N) SETERRQ4(PetscObjectComm((PetscObject)A),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);
4598: if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4599: if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4600: if (A->ops->equal != B->ops->equal) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"A is type: %s\nB is type: %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
4601: MatCheckPreallocated(A,1);
4603: (*A->ops->equal)(A,B,flg);
4604: return(0);
4605: }
4609: /*@
4610: MatDiagonalScale - Scales a matrix on the left and right by diagonal
4611: matrices that are stored as vectors. Either of the two scaling
4612: matrices can be NULL.
4614: Collective on Mat
4616: Input Parameters:
4617: + mat - the matrix to be scaled
4618: . l - the left scaling vector (or NULL)
4619: - r - the right scaling vector (or NULL)
4621: Notes:
4622: MatDiagonalScale() computes A = LAR, where
4623: L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
4624: The L scales the rows of the matrix, the R scales the columns of the matrix.
4626: Level: intermediate
4628: Concepts: matrices^diagonal scaling
4629: Concepts: diagonal scaling of matrices
4631: .seealso: MatScale()
4632: @*/
4633: PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
4634: {
4640: if (!mat->ops->diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4643: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4644: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4645: MatCheckPreallocated(mat,1);
4647: PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4648: (*mat->ops->diagonalscale)(mat,l,r);
4649: PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4650: PetscObjectStateIncrease((PetscObject)mat);
4651: #if defined(PETSC_HAVE_CUSP)
4652: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4653: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4654: }
4655: #endif
4656: #if defined(PETSC_HAVE_VIENNACL)
4657: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
4658: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
4659: }
4660: #endif
4661: return(0);
4662: }
4666: /*@
4667: MatScale - Scales all elements of a matrix by a given number.
4669: Logically Collective on Mat
4671: Input Parameters:
4672: + mat - the matrix to be scaled
4673: - a - the scaling value
4675: Output Parameter:
4676: . mat - the scaled matrix
4678: Level: intermediate
4680: Concepts: matrices^scaling all entries
4682: .seealso: MatDiagonalScale()
4683: @*/
4684: PetscErrorCode MatScale(Mat mat,PetscScalar a)
4685: {
4691: if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4692: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4693: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4695: MatCheckPreallocated(mat,1);
4697: PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4698: if (a != (PetscScalar)1.0) {
4699: (*mat->ops->scale)(mat,a);
4700: PetscObjectStateIncrease((PetscObject)mat);
4701: }
4702: PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4703: #if defined(PETSC_HAVE_CUSP)
4704: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4705: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4706: }
4707: #endif
4708: #if defined(PETSC_HAVE_VIENNACL)
4709: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
4710: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
4711: }
4712: #endif
4713: return(0);
4714: }
4718: /*@
4719: MatNorm - Calculates various norms of a matrix.
4721: Collective on Mat
4723: Input Parameters:
4724: + mat - the matrix
4725: - type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
4727: Output Parameters:
4728: . nrm - the resulting norm
4730: Level: intermediate
4732: Concepts: matrices^norm
4733: Concepts: norm^of matrix
4734: @*/
4735: PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
4736: {
4744: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4745: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4746: if (!mat->ops->norm) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4747: MatCheckPreallocated(mat,1);
4749: (*mat->ops->norm)(mat,type,nrm);
4750: return(0);
4751: }
4753: /*
4754: This variable is used to prevent counting of MatAssemblyBegin() that
4755: are called from within a MatAssemblyEnd().
4756: */
4757: static PetscInt MatAssemblyEnd_InUse = 0;
4760: /*@
4761: MatAssemblyBegin - Begins assembling the matrix. This routine should
4762: be called after completing all calls to MatSetValues().
4764: Collective on Mat
4766: Input Parameters:
4767: + mat - the matrix
4768: - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
4770: Notes:
4771: MatSetValues() generally caches the values. The matrix is ready to
4772: use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4773: Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4774: in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4775: using the matrix.
4777: ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the
4778: same flag of MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY for all processes. Thus you CANNOT locally change from ADD_VALUES to INSERT_VALUES, that is
4779: a global collective operation requring all processes that share the matrix.
4781: Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
4782: out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
4783: before MAT_FINAL_ASSEMBLY so the space is not compressed out.
4785: Level: beginner
4787: Concepts: matrices^assembling
4789: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
4790: @*/
4791: PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
4792: {
4798: MatCheckPreallocated(mat,1);
4799: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
4800: if (mat->assembled) {
4801: mat->was_assembled = PETSC_TRUE;
4802: mat->assembled = PETSC_FALSE;
4803: }
4804: if (!MatAssemblyEnd_InUse) {
4805: PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);
4806: if (mat->ops->assemblybegin) {(*mat->ops->assemblybegin)(mat,type);}
4807: PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);
4808: } else if (mat->ops->assemblybegin) {
4809: (*mat->ops->assemblybegin)(mat,type);
4810: }
4811: return(0);
4812: }
4816: /*@
4817: MatAssembled - Indicates if a matrix has been assembled and is ready for
4818: use; for example, in matrix-vector product.
4820: Not Collective
4822: Input Parameter:
4823: . mat - the matrix
4825: Output Parameter:
4826: . assembled - PETSC_TRUE or PETSC_FALSE
4828: Level: advanced
4830: Concepts: matrices^assembled?
4832: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
4833: @*/
4834: PetscErrorCode MatAssembled(Mat mat,PetscBool *assembled)
4835: {
4840: *assembled = mat->assembled;
4841: return(0);
4842: }
4846: /*@
4847: MatAssemblyEnd - Completes assembling the matrix. This routine should
4848: be called after MatAssemblyBegin().
4850: Collective on Mat
4852: Input Parameters:
4853: + mat - the matrix
4854: - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
4856: Options Database Keys:
4857: + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
4858: . -mat_view ::ascii_info_detail - Prints more detailed info
4859: . -mat_view - Prints matrix in ASCII format
4860: . -mat_view ::ascii_matlab - Prints matrix in Matlab format
4861: . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
4862: . -display <name> - Sets display name (default is host)
4863: . -draw_pause <sec> - Sets number of seconds to pause after display
4864: . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: Chapter 10 Using MATLAB with PETSc )
4865: . -viewer_socket_machine <machine>
4866: . -viewer_socket_port <port>
4867: . -mat_view binary - save matrix to file in binary format
4868: - -viewer_binary_filename <name>
4870: Notes:
4871: MatSetValues() generally caches the values. The matrix is ready to
4872: use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4873: Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4874: in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4875: using the matrix.
4877: Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
4878: out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
4879: before MAT_FINAL_ASSEMBLY so the space is not compressed out.
4881: Level: beginner
4883: .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
4884: @*/
4885: PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
4886: {
4887: PetscErrorCode ierr;
4888: static PetscInt inassm = 0;
4889: PetscBool flg = PETSC_FALSE;
4895: inassm++;
4896: MatAssemblyEnd_InUse++;
4897: if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
4898: PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);
4899: if (mat->ops->assemblyend) {
4900: (*mat->ops->assemblyend)(mat,type);
4901: }
4902: PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);
4903: } else if (mat->ops->assemblyend) {
4904: (*mat->ops->assemblyend)(mat,type);
4905: }
4907: /* Flush assembly is not a true assembly */
4908: if (type != MAT_FLUSH_ASSEMBLY) {
4909: mat->assembled = PETSC_TRUE; mat->num_ass++;
4910: }
4911: mat->insertmode = NOT_SET_VALUES;
4912: MatAssemblyEnd_InUse--;
4913: PetscObjectStateIncrease((PetscObject)mat);
4914: if (!mat->symmetric_eternal) {
4915: mat->symmetric_set = PETSC_FALSE;
4916: mat->hermitian_set = PETSC_FALSE;
4917: mat->structurally_symmetric_set = PETSC_FALSE;
4918: }
4919: #if defined(PETSC_HAVE_CUSP)
4920: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4921: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4922: }
4923: #endif
4924: #if defined(PETSC_HAVE_VIENNACL)
4925: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
4926: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
4927: }
4928: #endif
4929: if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
4930: MatViewFromOptions(mat,NULL,"-mat_view");
4932: if (mat->checksymmetryonassembly) {
4933: MatIsSymmetric(mat,mat->checksymmetrytol,&flg);
4934: if (flg) {
4935: PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);
4936: } else {
4937: PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);
4938: }
4939: }
4940: if (mat->nullsp && mat->checknullspaceonassembly) {
4941: MatNullSpaceTest(mat->nullsp,mat,NULL);
4942: }
4943: }
4944: inassm--;
4945: return(0);
4946: }
4950: /*@
4951: MatSetOption - Sets a parameter option for a matrix. Some options
4952: may be specific to certain storage formats. Some options
4953: determine how values will be inserted (or added). Sorted,
4954: row-oriented input will generally assemble the fastest. The default
4955: is row-oriented.
4957: Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
4959: Input Parameters:
4960: + mat - the matrix
4961: . option - the option, one of those listed below (and possibly others),
4962: - flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
4964: Options Describing Matrix Structure:
4965: + MAT_SPD - symmetric positive definite
4966: - MAT_SYMMETRIC - symmetric in terms of both structure and value
4967: . MAT_HERMITIAN - transpose is the complex conjugation
4968: . MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
4969: - MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
4970: you set to be kept with all future use of the matrix
4971: including after MatAssemblyBegin/End() which could
4972: potentially change the symmetry structure, i.e. you
4973: KNOW the matrix will ALWAYS have the property you set.
4976: Options For Use with MatSetValues():
4977: Insert a logically dense subblock, which can be
4978: . MAT_ROW_ORIENTED - row-oriented (default)
4980: Note these options reflect the data you pass in with MatSetValues(); it has
4981: nothing to do with how the data is stored internally in the matrix
4982: data structure.
4984: When (re)assembling a matrix, we can restrict the input for
4985: efficiency/debugging purposes. These options include:
4986: + MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow)
4987: . MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
4988: . MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
4989: . MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
4990: . MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
4991: + MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
4992: any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
4993: performance for very large process counts.
4995: Notes:
4996: Some options are relevant only for particular matrix types and
4997: are thus ignored by others. Other options are not supported by
4998: certain matrix types and will generate an error message if set.
5000: If using a Fortran 77 module to compute a matrix, one may need to
5001: use the column-oriented option (or convert to the row-oriented
5002: format).
5004: MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
5005: that would generate a new entry in the nonzero structure is instead
5006: ignored. Thus, if memory has not alredy been allocated for this particular
5007: data, then the insertion is ignored. For dense matrices, in which
5008: the entire array is allocated, no entries are ever ignored.
5009: Set after the first MatAssemblyEnd()
5011: MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5012: that would generate a new entry in the nonzero structure instead produces
5013: an error. (Currently supported for AIJ and BAIJ formats only.)
5015: MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5016: that would generate a new entry that has not been preallocated will
5017: instead produce an error. (Currently supported for AIJ and BAIJ formats
5018: only.) This is a useful flag when debugging matrix memory preallocation.
5020: MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for
5021: other processors should be dropped, rather than stashed.
5022: This is useful if you know that the "owning" processor is also
5023: always generating the correct matrix entries, so that PETSc need
5024: not transfer duplicate entries generated on another processor.
5026: MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5027: searches during matrix assembly. When this flag is set, the hash table
5028: is created during the first Matrix Assembly. This hash table is
5029: used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5030: to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5031: should be used with MAT_USE_HASH_TABLE flag. This option is currently
5032: supported by MATMPIBAIJ format only.
5034: MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries
5035: are kept in the nonzero structure
5037: MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
5038: a zero location in the matrix
5040: MAT_USE_INODES - indicates using inode version of the code - works with AIJ and
5041: ROWBS matrix types
5043: MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the
5044: zero row routines and thus improves performance for very large process counts.
5046: MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular
5047: part of the matrix (since they should match the upper triangular part).
5049: Notes: Can only be called after MatSetSizes() and MatSetType() have been set.
5051: Level: intermediate
5053: Concepts: matrices^setting options
5055: .seealso: MatOption, Mat
5057: @*/
5058: PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg)
5059: {
5065: if (op > 0) {
5068: }
5070: if (((int) op) <= MAT_OPTION_MIN || ((int) op) >= MAT_OPTION_MAX) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Options %d is out of range",(int)op);
5071: if (!((PetscObject)mat)->type_name) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_TYPENOTSET,"Cannot set options until type and size have been set, see MatSetType() and MatSetSizes()");
5073: switch (op) {
5074: case MAT_NO_OFF_PROC_ENTRIES:
5075: mat->nooffprocentries = flg;
5076: return(0);
5077: break;
5078: case MAT_NO_OFF_PROC_ZERO_ROWS:
5079: mat->nooffproczerorows = flg;
5080: return(0);
5081: break;
5082: case MAT_SPD:
5083: mat->spd_set = PETSC_TRUE;
5084: mat->spd = flg;
5085: if (flg) {
5086: mat->symmetric = PETSC_TRUE;
5087: mat->structurally_symmetric = PETSC_TRUE;
5088: mat->symmetric_set = PETSC_TRUE;
5089: mat->structurally_symmetric_set = PETSC_TRUE;
5090: }
5091: break;
5092: case MAT_SYMMETRIC:
5093: mat->symmetric = flg;
5094: if (flg) mat->structurally_symmetric = PETSC_TRUE;
5095: mat->symmetric_set = PETSC_TRUE;
5096: mat->structurally_symmetric_set = flg;
5097: break;
5098: case MAT_HERMITIAN:
5099: mat->hermitian = flg;
5100: if (flg) mat->structurally_symmetric = PETSC_TRUE;
5101: mat->hermitian_set = PETSC_TRUE;
5102: mat->structurally_symmetric_set = flg;
5103: break;
5104: case MAT_STRUCTURALLY_SYMMETRIC:
5105: mat->structurally_symmetric = flg;
5106: mat->structurally_symmetric_set = PETSC_TRUE;
5107: break;
5108: case MAT_SYMMETRY_ETERNAL:
5109: mat->symmetric_eternal = flg;
5110: break;
5111: default:
5112: break;
5113: }
5114: if (mat->ops->setoption) {
5115: (*mat->ops->setoption)(mat,op,flg);
5116: }
5117: return(0);
5118: }
5122: /*@
5123: MatZeroEntries - Zeros all entries of a matrix. For sparse matrices
5124: this routine retains the old nonzero structure.
5126: Logically Collective on Mat
5128: Input Parameters:
5129: . mat - the matrix
5131: Level: intermediate
5133: 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.
5134: See the Performance chapter of the users manual for information on preallocating matrices.
5136: Concepts: matrices^zeroing
5138: .seealso: MatZeroRows()
5139: @*/
5140: PetscErrorCode MatZeroEntries(Mat mat)
5141: {
5147: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5148: 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");
5149: if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5150: MatCheckPreallocated(mat,1);
5152: PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);
5153: (*mat->ops->zeroentries)(mat);
5154: PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);
5155: PetscObjectStateIncrease((PetscObject)mat);
5156: #if defined(PETSC_HAVE_CUSP)
5157: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5158: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5159: }
5160: #endif
5161: #if defined(PETSC_HAVE_VIENNACL)
5162: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5163: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5164: }
5165: #endif
5166: return(0);
5167: }
5171: /*@C
5172: MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal)
5173: of a set of rows and columns of a matrix.
5175: Collective on Mat
5177: Input Parameters:
5178: + mat - the matrix
5179: . numRows - the number of rows to remove
5180: . rows - the global row indices
5181: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5182: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5183: - b - optional vector of right hand side, that will be adjusted by provided solution
5185: Notes:
5186: This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5188: The user can set a value in the diagonal entry (or for the AIJ and
5189: row formats can optionally remove the main diagonal entry from the
5190: nonzero structure as well, by passing 0.0 as the final argument).
5192: For the parallel case, all processes that share the matrix (i.e.,
5193: those in the communicator used for matrix creation) MUST call this
5194: routine, regardless of whether any rows being zeroed are owned by
5195: them.
5197: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5198: list only rows local to itself).
5200: The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5202: Level: intermediate
5204: Concepts: matrices^zeroing rows
5206: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumnsIS()
5207: @*/
5208: PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5209: {
5216: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5217: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5218: if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5219: MatCheckPreallocated(mat,1);
5221: (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);
5222: MatViewFromOptions(mat,NULL,"-mat_view");
5223: PetscObjectStateIncrease((PetscObject)mat);
5224: #if defined(PETSC_HAVE_CUSP)
5225: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5226: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5227: }
5228: #endif
5229: #if defined(PETSC_HAVE_VIENNACL)
5230: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5231: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5232: }
5233: #endif
5234: return(0);
5235: }
5239: /*@C
5240: MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
5241: of a set of rows and columns of a matrix.
5243: Collective on Mat
5245: Input Parameters:
5246: + mat - the matrix
5247: . is - the rows to zero
5248: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5249: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5250: - b - optional vector of right hand side, that will be adjusted by provided solution
5252: Notes:
5253: This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5255: The user can set a value in the diagonal entry (or for the AIJ and
5256: row formats can optionally remove the main diagonal entry from the
5257: nonzero structure as well, by passing 0.0 as the final argument).
5259: For the parallel case, all processes that share the matrix (i.e.,
5260: those in the communicator used for matrix creation) MUST call this
5261: routine, regardless of whether any rows being zeroed are owned by
5262: them.
5264: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5265: list only rows local to itself).
5267: The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5269: Level: intermediate
5271: Concepts: matrices^zeroing rows
5273: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumns()
5274: @*/
5275: PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5276: {
5278: PetscInt numRows;
5279: const PetscInt *rows;
5286: ISGetLocalSize(is,&numRows);
5287: ISGetIndices(is,&rows);
5288: MatZeroRowsColumns(mat,numRows,rows,diag,x,b);
5289: ISRestoreIndices(is,&rows);
5290: return(0);
5291: }
5295: /*@C
5296: MatZeroRows - Zeros all entries (except possibly the main diagonal)
5297: of a set of rows of a matrix.
5299: Collective on Mat
5301: Input Parameters:
5302: + mat - the matrix
5303: . numRows - the number of rows to remove
5304: . rows - the global row indices
5305: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5306: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5307: - b - optional vector of right hand side, that will be adjusted by provided solution
5309: Notes:
5310: For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5311: but does not release memory. For the dense and block diagonal
5312: formats this does not alter the nonzero structure.
5314: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5315: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5316: merely zeroed.
5318: The user can set a value in the diagonal entry (or for the AIJ and
5319: row formats can optionally remove the main diagonal entry from the
5320: nonzero structure as well, by passing 0.0 as the final argument).
5322: For the parallel case, all processes that share the matrix (i.e.,
5323: those in the communicator used for matrix creation) MUST call this
5324: routine, regardless of whether any rows being zeroed are owned by
5325: them.
5327: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5328: list only rows local to itself).
5330: You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5331: owns that are to be zeroed. This saves a global synchronization in the implementation.
5333: Level: intermediate
5335: Concepts: matrices^zeroing rows
5337: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5338: @*/
5339: PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5340: {
5347: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5348: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5349: if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5350: MatCheckPreallocated(mat,1);
5352: (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);
5353: MatViewFromOptions(mat,NULL,"-mat_view");
5354: PetscObjectStateIncrease((PetscObject)mat);
5355: #if defined(PETSC_HAVE_CUSP)
5356: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5357: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5358: }
5359: #endif
5360: #if defined(PETSC_HAVE_VIENNACL)
5361: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5362: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5363: }
5364: #endif
5365: return(0);
5366: }
5370: /*@C
5371: MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5372: of a set of rows of a matrix.
5374: Collective on Mat
5376: Input Parameters:
5377: + mat - the matrix
5378: . is - index set of rows to remove
5379: . diag - value put in all diagonals of eliminated rows
5380: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5381: - b - optional vector of right hand side, that will be adjusted by provided solution
5383: Notes:
5384: For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5385: but does not release memory. For the dense and block diagonal
5386: formats this does not alter the nonzero structure.
5388: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5389: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5390: merely zeroed.
5392: The user can set a value in the diagonal entry (or for the AIJ and
5393: row formats can optionally remove the main diagonal entry from the
5394: nonzero structure as well, by passing 0.0 as the final argument).
5396: For the parallel case, all processes that share the matrix (i.e.,
5397: those in the communicator used for matrix creation) MUST call this
5398: routine, regardless of whether any rows being zeroed are owned by
5399: them.
5401: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5402: list only rows local to itself).
5404: You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5405: owns that are to be zeroed. This saves a global synchronization in the implementation.
5407: Level: intermediate
5409: Concepts: matrices^zeroing rows
5411: .seealso: MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5412: @*/
5413: PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5414: {
5415: PetscInt numRows;
5416: const PetscInt *rows;
5423: ISGetLocalSize(is,&numRows);
5424: ISGetIndices(is,&rows);
5425: MatZeroRows(mat,numRows,rows,diag,x,b);
5426: ISRestoreIndices(is,&rows);
5427: return(0);
5428: }
5432: /*@C
5433: MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
5434: of a set of rows of a matrix. These rows must be local to the process.
5436: Collective on Mat
5438: Input Parameters:
5439: + mat - the matrix
5440: . numRows - the number of rows to remove
5441: . rows - the grid coordinates (and component number when dof > 1) for matrix rows
5442: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5443: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5444: - b - optional vector of right hand side, that will be adjusted by provided solution
5446: Notes:
5447: For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5448: but does not release memory. For the dense and block diagonal
5449: formats this does not alter the nonzero structure.
5451: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5452: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5453: merely zeroed.
5455: The user can set a value in the diagonal entry (or for the AIJ and
5456: row formats can optionally remove the main diagonal entry from the
5457: nonzero structure as well, by passing 0.0 as the final argument).
5459: For the parallel case, all processes that share the matrix (i.e.,
5460: those in the communicator used for matrix creation) MUST call this
5461: routine, regardless of whether any rows being zeroed are owned by
5462: them.
5464: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5465: list only rows local to itself).
5467: The grid coordinates are across the entire grid, not just the local portion
5469: In Fortran idxm and idxn should be declared as
5470: $ MatStencil idxm(4,m)
5471: and the values inserted using
5472: $ idxm(MatStencil_i,1) = i
5473: $ idxm(MatStencil_j,1) = j
5474: $ idxm(MatStencil_k,1) = k
5475: $ idxm(MatStencil_c,1) = c
5476: etc
5478: For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5479: obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5480: etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5481: DM_BOUNDARY_PERIODIC boundary type.
5483: 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
5484: a single value per point) you can skip filling those indices.
5486: Level: intermediate
5488: Concepts: matrices^zeroing rows
5490: .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5491: @*/
5492: PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5493: {
5494: PetscInt dim = mat->stencil.dim;
5495: PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc);
5496: PetscInt *dims = mat->stencil.dims+1;
5497: PetscInt *starts = mat->stencil.starts;
5498: PetscInt *dxm = (PetscInt*) rows;
5499: PetscInt *jdxm, i, j, tmp, numNewRows = 0;
5507: PetscMalloc1(numRows, &jdxm);
5508: for (i = 0; i < numRows; ++i) {
5509: /* Skip unused dimensions (they are ordered k, j, i, c) */
5510: for (j = 0; j < 3-sdim; ++j) dxm++;
5511: /* Local index in X dir */
5512: tmp = *dxm++ - starts[0];
5513: /* Loop over remaining dimensions */
5514: for (j = 0; j < dim-1; ++j) {
5515: /* If nonlocal, set index to be negative */
5516: if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5517: /* Update local index */
5518: else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5519: }
5520: /* Skip component slot if necessary */
5521: if (mat->stencil.noc) dxm++;
5522: /* Local row number */
5523: if (tmp >= 0) {
5524: jdxm[numNewRows++] = tmp;
5525: }
5526: }
5527: MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);
5528: PetscFree(jdxm);
5529: return(0);
5530: }
5534: /*@C
5535: MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal)
5536: of a set of rows and columns of a matrix.
5538: Collective on Mat
5540: Input Parameters:
5541: + mat - the matrix
5542: . numRows - the number of rows/columns to remove
5543: . rows - the grid coordinates (and component number when dof > 1) for matrix rows
5544: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5545: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5546: - b - optional vector of right hand side, that will be adjusted by provided solution
5548: Notes:
5549: For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5550: but does not release memory. For the dense and block diagonal
5551: formats this does not alter the nonzero structure.
5553: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5554: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5555: merely zeroed.
5557: The user can set a value in the diagonal entry (or for the AIJ and
5558: row formats can optionally remove the main diagonal entry from the
5559: nonzero structure as well, by passing 0.0 as the final argument).
5561: For the parallel case, all processes that share the matrix (i.e.,
5562: those in the communicator used for matrix creation) MUST call this
5563: routine, regardless of whether any rows being zeroed are owned by
5564: them.
5566: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5567: list only rows local to itself, but the row/column numbers are given in local numbering).
5569: The grid coordinates are across the entire grid, not just the local portion
5571: In Fortran idxm and idxn should be declared as
5572: $ MatStencil idxm(4,m)
5573: and the values inserted using
5574: $ idxm(MatStencil_i,1) = i
5575: $ idxm(MatStencil_j,1) = j
5576: $ idxm(MatStencil_k,1) = k
5577: $ idxm(MatStencil_c,1) = c
5578: etc
5580: For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5581: obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5582: etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5583: DM_BOUNDARY_PERIODIC boundary type.
5585: 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
5586: a single value per point) you can skip filling those indices.
5588: Level: intermediate
5590: Concepts: matrices^zeroing rows
5592: .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5593: @*/
5594: PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5595: {
5596: PetscInt dim = mat->stencil.dim;
5597: PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc);
5598: PetscInt *dims = mat->stencil.dims+1;
5599: PetscInt *starts = mat->stencil.starts;
5600: PetscInt *dxm = (PetscInt*) rows;
5601: PetscInt *jdxm, i, j, tmp, numNewRows = 0;
5609: PetscMalloc1(numRows, &jdxm);
5610: for (i = 0; i < numRows; ++i) {
5611: /* Skip unused dimensions (they are ordered k, j, i, c) */
5612: for (j = 0; j < 3-sdim; ++j) dxm++;
5613: /* Local index in X dir */
5614: tmp = *dxm++ - starts[0];
5615: /* Loop over remaining dimensions */
5616: for (j = 0; j < dim-1; ++j) {
5617: /* If nonlocal, set index to be negative */
5618: if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5619: /* Update local index */
5620: else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5621: }
5622: /* Skip component slot if necessary */
5623: if (mat->stencil.noc) dxm++;
5624: /* Local row number */
5625: if (tmp >= 0) {
5626: jdxm[numNewRows++] = tmp;
5627: }
5628: }
5629: MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);
5630: PetscFree(jdxm);
5631: return(0);
5632: }
5636: /*@C
5637: MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
5638: of a set of rows of a matrix; using local numbering of rows.
5640: Collective on Mat
5642: Input Parameters:
5643: + mat - the matrix
5644: . numRows - the number of rows to remove
5645: . rows - the global row indices
5646: . diag - value put in all diagonals of eliminated rows
5647: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5648: - b - optional vector of right hand side, that will be adjusted by provided solution
5650: Notes:
5651: Before calling MatZeroRowsLocal(), the user must first set the
5652: local-to-global mapping by calling MatSetLocalToGlobalMapping().
5654: For the AIJ matrix formats this removes the old nonzero structure,
5655: but does not release memory. For the dense and block diagonal
5656: formats this does not alter the nonzero structure.
5658: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5659: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5660: merely zeroed.
5662: The user can set a value in the diagonal entry (or for the AIJ and
5663: row formats can optionally remove the main diagonal entry from the
5664: nonzero structure as well, by passing 0.0 as the final argument).
5666: You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5667: owns that are to be zeroed. This saves a global synchronization in the implementation.
5669: Level: intermediate
5671: Concepts: matrices^zeroing
5673: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5674: @*/
5675: PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5676: {
5683: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5684: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5685: MatCheckPreallocated(mat,1);
5687: if (mat->ops->zerorowslocal) {
5688: (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);
5689: } else {
5690: IS is, newis;
5691: const PetscInt *newRows;
5693: if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5694: ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
5695: ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);
5696: ISGetIndices(newis,&newRows);
5697: (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);
5698: ISRestoreIndices(newis,&newRows);
5699: ISDestroy(&newis);
5700: ISDestroy(&is);
5701: }
5702: PetscObjectStateIncrease((PetscObject)mat);
5703: #if defined(PETSC_HAVE_CUSP)
5704: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5705: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5706: }
5707: #endif
5708: #if defined(PETSC_HAVE_VIENNACL)
5709: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5710: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5711: }
5712: #endif
5713: return(0);
5714: }
5718: /*@C
5719: MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
5720: of a set of rows of a matrix; using local numbering of rows.
5722: Collective on Mat
5724: Input Parameters:
5725: + mat - the matrix
5726: . is - index set of rows to remove
5727: . diag - value put in all diagonals of eliminated rows
5728: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5729: - b - optional vector of right hand side, that will be adjusted by provided solution
5731: Notes:
5732: Before calling MatZeroRowsLocalIS(), the user must first set the
5733: local-to-global mapping by calling MatSetLocalToGlobalMapping().
5735: For the AIJ matrix formats this removes the old nonzero structure,
5736: but does not release memory. For the dense and block diagonal
5737: formats this does not alter the nonzero structure.
5739: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5740: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5741: merely zeroed.
5743: The user can set a value in the diagonal entry (or for the AIJ and
5744: row formats can optionally remove the main diagonal entry from the
5745: nonzero structure as well, by passing 0.0 as the final argument).
5747: You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5748: owns that are to be zeroed. This saves a global synchronization in the implementation.
5750: Level: intermediate
5752: Concepts: matrices^zeroing
5754: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5755: @*/
5756: PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5757: {
5759: PetscInt numRows;
5760: const PetscInt *rows;
5766: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5767: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5768: MatCheckPreallocated(mat,1);
5770: ISGetLocalSize(is,&numRows);
5771: ISGetIndices(is,&rows);
5772: MatZeroRowsLocal(mat,numRows,rows,diag,x,b);
5773: ISRestoreIndices(is,&rows);
5774: return(0);
5775: }
5779: /*@C
5780: MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
5781: of a set of rows and columns of a matrix; using local numbering of rows.
5783: Collective on Mat
5785: Input Parameters:
5786: + mat - the matrix
5787: . numRows - the number of rows to remove
5788: . rows - the global row indices
5789: . diag - value put in all diagonals of eliminated rows
5790: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5791: - b - optional vector of right hand side, that will be adjusted by provided solution
5793: Notes:
5794: Before calling MatZeroRowsColumnsLocal(), the user must first set the
5795: local-to-global mapping by calling MatSetLocalToGlobalMapping().
5797: The user can set a value in the diagonal entry (or for the AIJ and
5798: row formats can optionally remove the main diagonal entry from the
5799: nonzero structure as well, by passing 0.0 as the final argument).
5801: Level: intermediate
5803: Concepts: matrices^zeroing
5805: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5806: @*/
5807: PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5808: {
5810: IS is, newis;
5811: const PetscInt *newRows;
5817: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5818: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5819: MatCheckPreallocated(mat,1);
5821: if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5822: ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
5823: ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);
5824: ISGetIndices(newis,&newRows);
5825: (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);
5826: ISRestoreIndices(newis,&newRows);
5827: ISDestroy(&newis);
5828: ISDestroy(&is);
5829: PetscObjectStateIncrease((PetscObject)mat);
5830: #if defined(PETSC_HAVE_CUSP)
5831: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5832: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5833: }
5834: #endif
5835: #if defined(PETSC_HAVE_VIENNACL)
5836: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5837: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5838: }
5839: #endif
5840: return(0);
5841: }
5845: /*@C
5846: MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
5847: of a set of rows and columns of a matrix; using local numbering of rows.
5849: Collective on Mat
5851: Input Parameters:
5852: + mat - the matrix
5853: . is - index set of rows to remove
5854: . diag - value put in all diagonals of eliminated rows
5855: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5856: - b - optional vector of right hand side, that will be adjusted by provided solution
5858: Notes:
5859: Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
5860: local-to-global mapping by calling MatSetLocalToGlobalMapping().
5862: The user can set a value in the diagonal entry (or for the AIJ and
5863: row formats can optionally remove the main diagonal entry from the
5864: nonzero structure as well, by passing 0.0 as the final argument).
5866: Level: intermediate
5868: Concepts: matrices^zeroing
5870: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5871: @*/
5872: PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5873: {
5875: PetscInt numRows;
5876: const PetscInt *rows;
5882: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5883: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5884: MatCheckPreallocated(mat,1);
5886: ISGetLocalSize(is,&numRows);
5887: ISGetIndices(is,&rows);
5888: MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);
5889: ISRestoreIndices(is,&rows);
5890: return(0);
5891: }
5895: /*@
5896: MatGetSize - Returns the numbers of rows and columns in a matrix.
5898: Not Collective
5900: Input Parameter:
5901: . mat - the matrix
5903: Output Parameters:
5904: + m - the number of global rows
5905: - n - the number of global columns
5907: Note: both output parameters can be NULL on input.
5909: Level: beginner
5911: Concepts: matrices^size
5913: .seealso: MatGetLocalSize()
5914: @*/
5915: PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
5916: {
5919: if (m) *m = mat->rmap->N;
5920: if (n) *n = mat->cmap->N;
5921: return(0);
5922: }
5926: /*@
5927: MatGetLocalSize - Returns the number of rows and columns in a matrix
5928: stored locally. This information may be implementation dependent, so
5929: use with care.
5931: Not Collective
5933: Input Parameters:
5934: . mat - the matrix
5936: Output Parameters:
5937: + m - the number of local rows
5938: - n - the number of local columns
5940: Note: both output parameters can be NULL on input.
5942: Level: beginner
5944: Concepts: matrices^local size
5946: .seealso: MatGetSize()
5947: @*/
5948: PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
5949: {
5954: if (m) *m = mat->rmap->n;
5955: if (n) *n = mat->cmap->n;
5956: return(0);
5957: }
5961: /*@
5962: MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
5963: this processor. (The columns of the "diagonal block")
5965: Not Collective, unless matrix has not been allocated, then collective on Mat
5967: Input Parameters:
5968: . mat - the matrix
5970: Output Parameters:
5971: + m - the global index of the first local column
5972: - n - one more than the global index of the last local column
5974: Notes: both output parameters can be NULL on input.
5976: Level: developer
5978: Concepts: matrices^column ownership
5980: .seealso: MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
5982: @*/
5983: PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
5984: {
5990: MatCheckPreallocated(mat,1);
5991: if (m) *m = mat->cmap->rstart;
5992: if (n) *n = mat->cmap->rend;
5993: return(0);
5994: }
5998: /*@
5999: MatGetOwnershipRange - Returns the range of matrix rows owned by
6000: this processor, assuming that the matrix is laid out with the first
6001: n1 rows on the first processor, the next n2 rows on the second, etc.
6002: For certain parallel layouts this range may not be well defined.
6004: Not Collective
6006: Input Parameters:
6007: . mat - the matrix
6009: Output Parameters:
6010: + m - the global index of the first local row
6011: - n - one more than the global index of the last local row
6013: Note: Both output parameters can be NULL on input.
6014: $ This function requires that the matrix be preallocated. If you have not preallocated, consider using
6015: $ PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
6016: $ and then MPI_Scan() to calculate prefix sums of the local sizes.
6018: Level: beginner
6020: Concepts: matrices^row ownership
6022: .seealso: MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()
6024: @*/
6025: PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6026: {
6032: MatCheckPreallocated(mat,1);
6033: if (m) *m = mat->rmap->rstart;
6034: if (n) *n = mat->rmap->rend;
6035: return(0);
6036: }
6040: /*@C
6041: MatGetOwnershipRanges - Returns the range of matrix rows owned by
6042: each process
6044: Not Collective, unless matrix has not been allocated, then collective on Mat
6046: Input Parameters:
6047: . mat - the matrix
6049: Output Parameters:
6050: . ranges - start of each processors portion plus one more then the total length at the end
6052: Level: beginner
6054: Concepts: matrices^row ownership
6056: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
6058: @*/
6059: PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6060: {
6066: MatCheckPreallocated(mat,1);
6067: PetscLayoutGetRanges(mat->rmap,ranges);
6068: return(0);
6069: }
6073: /*@C
6074: MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6075: this processor. (The columns of the "diagonal blocks" for each process)
6077: Not Collective, unless matrix has not been allocated, then collective on Mat
6079: Input Parameters:
6080: . mat - the matrix
6082: Output Parameters:
6083: . ranges - start of each processors portion plus one more then the total length at the end
6085: Level: beginner
6087: Concepts: matrices^column ownership
6089: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
6091: @*/
6092: PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6093: {
6099: MatCheckPreallocated(mat,1);
6100: PetscLayoutGetRanges(mat->cmap,ranges);
6101: return(0);
6102: }
6106: /*@C
6107: MatGetOwnershipIS - Get row and column ownership as index sets
6109: Not Collective
6111: Input Arguments:
6112: . A - matrix of type Elemental
6114: Output Arguments:
6115: + rows - rows in which this process owns elements
6116: . cols - columns in which this process owns elements
6118: Level: intermediate
6120: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL, MatSetValues()
6121: @*/
6122: PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6123: {
6124: PetscErrorCode ierr,(*f)(Mat,IS*,IS*);
6127: MatCheckPreallocated(A,1);
6128: PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);
6129: if (f) {
6130: (*f)(A,rows,cols);
6131: } else { /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6132: if (rows) {ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);}
6133: if (cols) {ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);}
6134: }
6135: return(0);
6136: }
6140: /*@C
6141: MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6142: Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6143: to complete the factorization.
6145: Collective on Mat
6147: Input Parameters:
6148: + mat - the matrix
6149: . row - row permutation
6150: . column - column permutation
6151: - info - structure containing
6152: $ levels - number of levels of fill.
6153: $ expected fill - as ratio of original fill.
6154: $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6155: missing diagonal entries)
6157: Output Parameters:
6158: . fact - new matrix that has been symbolically factored
6160: Notes: See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
6162: Most users should employ the simplified KSP interface for linear solvers
6163: instead of working directly with matrix algebra routines such as this.
6164: See, e.g., KSPCreate().
6166: Level: developer
6168: Concepts: matrices^symbolic LU factorization
6169: Concepts: matrices^factorization
6170: Concepts: LU^symbolic factorization
6172: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6173: MatGetOrdering(), MatFactorInfo
6175: Developer Note: fortran interface is not autogenerated as the f90
6176: interface defintion cannot be generated correctly [due to MatFactorInfo]
6178: @*/
6179: PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6180: {
6190: if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6191: if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6192: if (!(fact)->ops->ilufactorsymbolic) {
6193: const MatSolverPackage spackage;
6194: MatFactorGetSolverPackage(fact,&spackage);
6195: SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6196: }
6197: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6198: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6199: MatCheckPreallocated(mat,2);
6201: PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);
6202: (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);
6203: PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);
6204: return(0);
6205: }
6209: /*@C
6210: MatICCFactorSymbolic - Performs symbolic incomplete
6211: Cholesky factorization for a symmetric matrix. Use
6212: MatCholeskyFactorNumeric() to complete the factorization.
6214: Collective on Mat
6216: Input Parameters:
6217: + mat - the matrix
6218: . perm - row and column permutation
6219: - info - structure containing
6220: $ levels - number of levels of fill.
6221: $ expected fill - as ratio of original fill.
6223: Output Parameter:
6224: . fact - the factored matrix
6226: Notes:
6227: Most users should employ the KSP interface for linear solvers
6228: instead of working directly with matrix algebra routines such as this.
6229: See, e.g., KSPCreate().
6231: Level: developer
6233: Concepts: matrices^symbolic incomplete Cholesky factorization
6234: Concepts: matrices^factorization
6235: Concepts: Cholsky^symbolic factorization
6237: .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
6239: Developer Note: fortran interface is not autogenerated as the f90
6240: interface defintion cannot be generated correctly [due to MatFactorInfo]
6242: @*/
6243: PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6244: {
6253: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6254: if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6255: if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6256: if (!(fact)->ops->iccfactorsymbolic) {
6257: const MatSolverPackage spackage;
6258: MatFactorGetSolverPackage(fact,&spackage);
6259: SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6260: }
6261: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6262: MatCheckPreallocated(mat,2);
6264: PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);
6265: (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);
6266: PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);
6267: return(0);
6268: }
6272: /*@C
6273: MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
6274: points to an array of valid matrices, they may be reused to store the new
6275: submatrices.
6277: Collective on Mat
6279: Input Parameters:
6280: + mat - the matrix
6281: . n - the number of submatrixes to be extracted (on this processor, may be zero)
6282: . irow, icol - index sets of rows and columns to extract (must be sorted)
6283: - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6285: Output Parameter:
6286: . submat - the array of submatrices
6288: Notes:
6289: MatGetSubMatrices() can extract ONLY sequential submatrices
6290: (from both sequential and parallel matrices). Use MatGetSubMatrix()
6291: to extract a parallel submatrix.
6293: Currently both row and column indices must be sorted to guarantee
6294: correctness with all matrix types.
6296: When extracting submatrices from a parallel matrix, each processor can
6297: form a different submatrix by setting the rows and columns of its
6298: individual index sets according to the local submatrix desired.
6300: When finished using the submatrices, the user should destroy
6301: them with MatDestroyMatrices().
6303: MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6304: original matrix has not changed from that last call to MatGetSubMatrices().
6306: This routine creates the matrices in submat; you should NOT create them before
6307: calling it. It also allocates the array of matrix pointers submat.
6309: For BAIJ matrices the index sets must respect the block structure, that is if they
6310: request one row/column in a block, they must request all rows/columns that are in
6311: that block. For example, if the block size is 2 you cannot request just row 0 and
6312: column 0.
6314: Fortran Note:
6315: The Fortran interface is slightly different from that given below; it
6316: requires one to pass in as submat a Mat (integer) array of size at least m.
6318: Level: advanced
6320: Concepts: matrices^accessing submatrices
6321: Concepts: submatrices
6323: .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6324: @*/
6325: PetscErrorCode MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6326: {
6328: PetscInt i;
6329: PetscBool eq;
6334: if (n) {
6339: }
6341: if (n && scall == MAT_REUSE_MATRIX) {
6344: }
6345: if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6346: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6347: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6348: MatCheckPreallocated(mat,1);
6350: PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6351: (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);
6352: PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6353: for (i=0; i<n; i++) {
6354: (*submat)[i]->factortype = MAT_FACTOR_NONE; /* in case in place factorization was previously done on submatrix */
6355: if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6356: ISEqual(irow[i],icol[i],&eq);
6357: if (eq) {
6358: if (mat->symmetric) {
6359: MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6360: } else if (mat->hermitian) {
6361: MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6362: } else if (mat->structurally_symmetric) {
6363: MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6364: }
6365: }
6366: }
6367: }
6368: return(0);
6369: }
6373: PetscErrorCode MatGetSubMatricesParallel(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6374: {
6376: PetscInt i;
6377: PetscBool eq;
6382: if (n) {
6387: }
6389: if (n && scall == MAT_REUSE_MATRIX) {
6392: }
6393: if (!mat->ops->getsubmatricesparallel) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6394: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6395: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6396: MatCheckPreallocated(mat,1);
6398: PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6399: (*mat->ops->getsubmatricesparallel)(mat,n,irow,icol,scall,submat);
6400: PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6401: for (i=0; i<n; i++) {
6402: if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6403: ISEqual(irow[i],icol[i],&eq);
6404: if (eq) {
6405: if (mat->symmetric) {
6406: MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6407: } else if (mat->hermitian) {
6408: MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6409: } else if (mat->structurally_symmetric) {
6410: MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6411: }
6412: }
6413: }
6414: }
6415: return(0);
6416: }
6420: /*@C
6421: MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().
6423: Collective on Mat
6425: Input Parameters:
6426: + n - the number of local matrices
6427: - mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6428: sequence of MatGetSubMatrices())
6430: Level: advanced
6432: Notes: Frees not only the matrices, but also the array that contains the matrices
6433: In Fortran will not free the array.
6435: .seealso: MatGetSubMatrices()
6436: @*/
6437: PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
6438: {
6440: PetscInt i;
6443: if (!*mat) return(0);
6444: if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6446: for (i=0; i<n; i++) {
6447: MatDestroy(&(*mat)[i]);
6448: }
6449: /* memory is allocated even if n = 0 */
6450: PetscFree(*mat);
6451: *mat = NULL;
6452: return(0);
6453: }
6457: /*@C
6458: MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
6460: Collective on Mat
6462: Input Parameters:
6463: . mat - the matrix
6465: Output Parameter:
6466: . matstruct - the sequential matrix with the nonzero structure of mat
6468: Level: intermediate
6470: .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
6471: @*/
6472: PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6473: {
6481: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6482: MatCheckPreallocated(mat,1);
6484: if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6485: PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6486: (*mat->ops->getseqnonzerostructure)(mat,matstruct);
6487: PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6488: return(0);
6489: }
6493: /*@C
6494: MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
6496: Collective on Mat
6498: Input Parameters:
6499: . mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
6500: sequence of MatGetSequentialNonzeroStructure())
6502: Level: advanced
6504: Notes: Frees not only the matrices, but also the array that contains the matrices
6506: .seealso: MatGetSeqNonzeroStructure()
6507: @*/
6508: PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
6509: {
6514: MatDestroy(mat);
6515: return(0);
6516: }
6520: /*@
6521: MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6522: replaces the index sets by larger ones that represent submatrices with
6523: additional overlap.
6525: Collective on Mat
6527: Input Parameters:
6528: + mat - the matrix
6529: . n - the number of index sets
6530: . is - the array of index sets (these index sets will changed during the call)
6531: - ov - the additional overlap requested
6533: Level: developer
6535: Concepts: overlap
6536: Concepts: ASM^computing overlap
6538: .seealso: MatGetSubMatrices()
6539: @*/
6540: PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6541: {
6547: if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6548: if (n) {
6551: }
6552: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6553: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6554: MatCheckPreallocated(mat,1);
6556: if (!ov) return(0);
6557: if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6558: PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
6559: (*mat->ops->increaseoverlap)(mat,n,is,ov);
6560: PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
6561: return(0);
6562: }
6566: /*@
6567: MatGetBlockSize - Returns the matrix block size; useful especially for the
6568: block row and block diagonal formats.
6570: Not Collective
6572: Input Parameter:
6573: . mat - the matrix
6575: Output Parameter:
6576: . bs - block size
6578: Notes:
6579: Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ.
6581: If the block size has not been set yet this routine returns -1.
6583: Level: intermediate
6585: Concepts: matrices^block size
6587: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
6588: @*/
6589: PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
6590: {
6594: *bs = PetscAbs(mat->rmap->bs);
6595: return(0);
6596: }
6600: /*@
6601: MatGetBlockSizes - Returns the matrix block row and column sizes;
6602: useful especially for the block row and block diagonal formats.
6604: Not Collective
6606: Input Parameter:
6607: . mat - the matrix
6609: Output Parameter:
6610: . rbs - row block size
6611: . cbs - coumn block size
6613: Notes:
6614: Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ.
6616: If a block size has not been set yet this routine returns -1.
6618: Level: intermediate
6620: Concepts: matrices^block size
6622: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
6623: @*/
6624: PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
6625: {
6630: if (rbs) *rbs = PetscAbs(mat->rmap->bs);
6631: if (cbs) *cbs = PetscAbs(mat->cmap->bs);
6632: return(0);
6633: }
6637: /*@
6638: MatSetBlockSize - Sets the matrix block size.
6640: Logically Collective on Mat
6642: Input Parameters:
6643: + mat - the matrix
6644: - bs - block size
6646: Notes:
6647: This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later
6649: Level: intermediate
6651: Concepts: matrices^block size
6653: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
6654: @*/
6655: PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
6656: {
6662: PetscLayoutSetBlockSize(mat->rmap,bs);
6663: PetscLayoutSetBlockSize(mat->cmap,bs);
6664: return(0);
6665: }
6669: /*@
6670: MatSetBlockSizes - Sets the matrix block row and column sizes.
6672: Logically Collective on Mat
6674: Input Parameters:
6675: + mat - the matrix
6676: - rbs - row block size
6677: - cbs - column block size
6679: Notes:
6680: This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later
6682: Level: intermediate
6684: Concepts: matrices^block size
6686: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
6687: @*/
6688: PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
6689: {
6696: PetscLayoutSetBlockSize(mat->rmap,rbs);
6697: PetscLayoutSetBlockSize(mat->cmap,cbs);
6698: return(0);
6699: }
6703: /*@
6704: MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices
6706: Logically Collective on Mat
6708: Input Parameters:
6709: + mat - the matrix
6710: . fromRow - matrix from which to copy row block size
6711: - fromCol - matrix from which to copy column block size (can be same as fromRow)
6713: Level: developer
6715: Concepts: matrices^block size
6717: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes()
6718: @*/
6719: PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)
6720: {
6727: if (fromRow->rmap->bs > 0) {PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);}
6728: if (fromCol->cmap->bs > 0) {PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);}
6729: return(0);
6730: }
6734: /*@
6735: MatResidual - Default routine to calculate the residual.
6737: Collective on Mat and Vec
6739: Input Parameters:
6740: + mat - the matrix
6741: . b - the right-hand-side
6742: - x - the approximate solution
6744: Output Parameter:
6745: . r - location to store the residual
6747: Level: developer
6749: .keywords: MG, default, multigrid, residual
6751: .seealso: PCMGSetResidual()
6752: @*/
6753: PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r)
6754: {
6763: MatCheckPreallocated(mat,1);
6764: PetscLogEventBegin(MAT_Residual,mat,0,0,0);
6765: if (!mat->ops->residual) {
6766: MatMult(mat,x,r);
6767: VecAYPX(r,-1.0,b);
6768: } else {
6769: (*mat->ops->residual)(mat,b,x,r);
6770: }
6771: PetscLogEventEnd(MAT_Residual,mat,0,0,0);
6772: return(0);
6773: }
6777: /*@C
6778: MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
6780: Collective on Mat
6782: Input Parameters:
6783: + mat - the matrix
6784: . shift - 0 or 1 indicating we want the indices starting at 0 or 1
6785: . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be symmetrized
6786: - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6787: inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6788: always used.
6790: Output Parameters:
6791: + n - number of rows in the (possibly compressed) matrix
6792: . ia - the row pointers [of length n+1]
6793: . ja - the column indices
6794: - done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
6795: are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
6797: Level: developer
6799: Notes: You CANNOT change any of the ia[] or ja[] values.
6801: Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values
6803: Fortran Node
6805: In Fortran use
6806: $ PetscInt ia(1), ja(1)
6807: $ PetscOffset iia, jja
6808: $ call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
6809: $
6810: $ or
6811: $
6812: $ PetscScalar, pointer :: xx_v(:)
6813: $ call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
6816: Acess the ith and jth entries via ia(iia + i) and ja(jja + j)
6818: .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
6819: @*/
6820: PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done)
6821: {
6831: MatCheckPreallocated(mat,1);
6832: if (!mat->ops->getrowij) *done = PETSC_FALSE;
6833: else {
6834: *done = PETSC_TRUE;
6835: PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);
6836: (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6837: PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);
6838: }
6839: return(0);
6840: }
6844: /*@C
6845: MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
6847: Collective on Mat
6849: Input Parameters:
6850: + mat - the matrix
6851: . shift - 1 or zero indicating we want the indices starting at 0 or 1
6852: . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6853: symmetrized
6854: . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6855: inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6856: always used.
6857: . n - number of columns in the (possibly compressed) matrix
6858: . ia - the column pointers
6859: - ja - the row indices
6861: Output Parameters:
6862: . done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
6864: Note:
6865: This routine zeros out n, ia, and ja. This is to prevent accidental
6866: us of the array after it has been restored. If you pass NULL, it will
6867: not zero the pointers. Use of ia or ja after MatRestoreColumnIJ() is invalid.
6869: Level: developer
6871: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6872: @*/
6873: PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done)
6874: {
6884: MatCheckPreallocated(mat,1);
6885: if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
6886: else {
6887: *done = PETSC_TRUE;
6888: (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6889: }
6890: return(0);
6891: }
6895: /*@C
6896: MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
6897: MatGetRowIJ().
6899: Collective on Mat
6901: Input Parameters:
6902: + mat - the matrix
6903: . shift - 1 or zero indicating we want the indices starting at 0 or 1
6904: . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6905: symmetrized
6906: . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6907: inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6908: always used.
6909: . n - size of (possibly compressed) matrix
6910: . ia - the row pointers
6911: - ja - the column indices
6913: Output Parameters:
6914: . done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
6916: Note:
6917: This routine zeros out n, ia, and ja. This is to prevent accidental
6918: us of the array after it has been restored. If you pass NULL, it will
6919: not zero the pointers. Use of ia or ja after MatRestoreRowIJ() is invalid.
6921: Level: developer
6923: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6924: @*/
6925: PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done)
6926: {
6935: MatCheckPreallocated(mat,1);
6937: if (!mat->ops->restorerowij) *done = PETSC_FALSE;
6938: else {
6939: *done = PETSC_TRUE;
6940: (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6941: if (n) *n = 0;
6942: if (ia) *ia = NULL;
6943: if (ja) *ja = NULL;
6944: }
6945: return(0);
6946: }
6950: /*@C
6951: MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
6952: MatGetColumnIJ().
6954: Collective on Mat
6956: Input Parameters:
6957: + mat - the matrix
6958: . shift - 1 or zero indicating we want the indices starting at 0 or 1
6959: - symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6960: symmetrized
6961: - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6962: inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6963: always used.
6965: Output Parameters:
6966: + n - size of (possibly compressed) matrix
6967: . ia - the column pointers
6968: . ja - the row indices
6969: - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
6971: Level: developer
6973: .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
6974: @*/
6975: PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done)
6976: {
6985: MatCheckPreallocated(mat,1);
6987: if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
6988: else {
6989: *done = PETSC_TRUE;
6990: (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6991: if (n) *n = 0;
6992: if (ia) *ia = NULL;
6993: if (ja) *ja = NULL;
6994: }
6995: return(0);
6996: }
7000: /*@C
7001: MatColoringPatch -Used inside matrix coloring routines that
7002: use MatGetRowIJ() and/or MatGetColumnIJ().
7004: Collective on Mat
7006: Input Parameters:
7007: + mat - the matrix
7008: . ncolors - max color value
7009: . n - number of entries in colorarray
7010: - colorarray - array indicating color for each column
7012: Output Parameters:
7013: . iscoloring - coloring generated using colorarray information
7015: Level: developer
7017: .seealso: MatGetRowIJ(), MatGetColumnIJ()
7019: @*/
7020: PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7021: {
7029: MatCheckPreallocated(mat,1);
7031: if (!mat->ops->coloringpatch) {
7032: ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,iscoloring);
7033: } else {
7034: (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);
7035: }
7036: return(0);
7037: }
7042: /*@
7043: MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
7045: Logically Collective on Mat
7047: Input Parameter:
7048: . mat - the factored matrix to be reset
7050: Notes:
7051: This routine should be used only with factored matrices formed by in-place
7052: factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7053: format). This option can save memory, for example, when solving nonlinear
7054: systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7055: ILU(0) preconditioner.
7057: Note that one can specify in-place ILU(0) factorization by calling
7058: .vb
7059: PCType(pc,PCILU);
7060: PCFactorSeUseInPlace(pc);
7061: .ve
7062: or by using the options -pc_type ilu -pc_factor_in_place
7064: In-place factorization ILU(0) can also be used as a local
7065: solver for the blocks within the block Jacobi or additive Schwarz
7066: methods (runtime option: -sub_pc_factor_in_place). See Users-Manual: ch_pc
7067: for details on setting local solver options.
7069: Most users should employ the simplified KSP interface for linear solvers
7070: instead of working directly with matrix algebra routines such as this.
7071: See, e.g., KSPCreate().
7073: Level: developer
7075: .seealso: PCFactorSetUseInPlace()
7077: Concepts: matrices^unfactored
7079: @*/
7080: PetscErrorCode MatSetUnfactored(Mat mat)
7081: {
7087: MatCheckPreallocated(mat,1);
7088: mat->factortype = MAT_FACTOR_NONE;
7089: if (!mat->ops->setunfactored) return(0);
7090: (*mat->ops->setunfactored)(mat);
7091: return(0);
7092: }
7094: /*MC
7095: MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.
7097: Synopsis:
7098: MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7100: Not collective
7102: Input Parameter:
7103: . x - matrix
7105: Output Parameters:
7106: + xx_v - the Fortran90 pointer to the array
7107: - ierr - error code
7109: Example of Usage:
7110: .vb
7111: PetscScalar, pointer xx_v(:,:)
7112: ....
7113: call MatDenseGetArrayF90(x,xx_v,ierr)
7114: a = xx_v(3)
7115: call MatDenseRestoreArrayF90(x,xx_v,ierr)
7116: .ve
7118: Level: advanced
7120: .seealso: MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90()
7122: Concepts: matrices^accessing array
7124: M*/
7126: /*MC
7127: MatDenseRestoreArrayF90 - Restores a matrix array that has been
7128: accessed with MatDenseGetArrayF90().
7130: Synopsis:
7131: MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7133: Not collective
7135: Input Parameters:
7136: + x - matrix
7137: - xx_v - the Fortran90 pointer to the array
7139: Output Parameter:
7140: . ierr - error code
7142: Example of Usage:
7143: .vb
7144: PetscScalar, pointer xx_v(:)
7145: ....
7146: call MatDenseGetArrayF90(x,xx_v,ierr)
7147: a = xx_v(3)
7148: call MatDenseRestoreArrayF90(x,xx_v,ierr)
7149: .ve
7151: Level: advanced
7153: .seealso: MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90()
7155: M*/
7158: /*MC
7159: MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.
7161: Synopsis:
7162: MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7164: Not collective
7166: Input Parameter:
7167: . x - matrix
7169: Output Parameters:
7170: + xx_v - the Fortran90 pointer to the array
7171: - ierr - error code
7173: Example of Usage:
7174: .vb
7175: PetscScalar, pointer xx_v(:,:)
7176: ....
7177: call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7178: a = xx_v(3)
7179: call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7180: .ve
7182: Level: advanced
7184: .seealso: MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90()
7186: Concepts: matrices^accessing array
7188: M*/
7190: /*MC
7191: MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7192: accessed with MatSeqAIJGetArrayF90().
7194: Synopsis:
7195: MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7197: Not collective
7199: Input Parameters:
7200: + x - matrix
7201: - xx_v - the Fortran90 pointer to the array
7203: Output Parameter:
7204: . ierr - error code
7206: Example of Usage:
7207: .vb
7208: PetscScalar, pointer xx_v(:)
7209: ....
7210: call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7211: a = xx_v(3)
7212: call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7213: .ve
7215: Level: advanced
7217: .seealso: MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90()
7219: M*/
7224: /*@
7225: MatGetSubMatrix - Gets a single submatrix on the same number of processors
7226: as the original matrix.
7228: Collective on Mat
7230: Input Parameters:
7231: + mat - the original matrix
7232: . isrow - parallel IS containing the rows this processor should obtain
7233: . 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.
7234: - cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7236: Output Parameter:
7237: . newmat - the new submatrix, of the same type as the old
7239: Level: advanced
7241: Notes:
7242: The submatrix will be able to be multiplied with vectors using the same layout as iscol.
7244: The rows in isrow will be sorted into the same order as the original matrix on each process.
7246: The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7247: the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
7248: to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7249: will reuse the matrix generated the first time. You should call MatDestroy() on newmat when
7250: you are finished using it.
7252: The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7253: the input matrix.
7255: If iscol is NULL then all columns are obtained (not supported in Fortran).
7257: Example usage:
7258: Consider the following 8x8 matrix with 34 non-zero values, that is
7259: assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7260: proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7261: as follows:
7263: .vb
7264: 1 2 0 | 0 3 0 | 0 4
7265: Proc0 0 5 6 | 7 0 0 | 8 0
7266: 9 0 10 | 11 0 0 | 12 0
7267: -------------------------------------
7268: 13 0 14 | 15 16 17 | 0 0
7269: Proc1 0 18 0 | 19 20 21 | 0 0
7270: 0 0 0 | 22 23 0 | 24 0
7271: -------------------------------------
7272: Proc2 25 26 27 | 0 0 28 | 29 0
7273: 30 0 0 | 31 32 33 | 0 34
7274: .ve
7276: Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6]. The resulting submatrix is
7278: .vb
7279: 2 0 | 0 3 0 | 0
7280: Proc0 5 6 | 7 0 0 | 8
7281: -------------------------------
7282: Proc1 18 0 | 19 20 21 | 0
7283: -------------------------------
7284: Proc2 26 27 | 0 0 28 | 29
7285: 0 0 | 31 32 33 | 0
7286: .ve
7289: Concepts: matrices^submatrices
7291: .seealso: MatGetSubMatrices()
7292: @*/
7293: PetscErrorCode MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7294: {
7296: PetscMPIInt size;
7297: Mat *local;
7298: IS iscoltmp;
7307: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7308: MatCheckPreallocated(mat,1);
7309: MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
7311: if (!iscol) {
7312: ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);
7313: } else {
7314: iscoltmp = iscol;
7315: }
7317: /* if original matrix is on just one processor then use submatrix generated */
7318: if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7319: MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);
7320: if (!iscol) {ISDestroy(&iscoltmp);}
7321: return(0);
7322: } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) {
7323: MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);
7324: *newmat = *local;
7325: PetscFree(local);
7326: if (!iscol) {ISDestroy(&iscoltmp);}
7327: return(0);
7328: } else if (!mat->ops->getsubmatrix) {
7329: /* Create a new matrix type that implements the operation using the full matrix */
7330: switch (cll) {
7331: case MAT_INITIAL_MATRIX:
7332: MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);
7333: break;
7334: case MAT_REUSE_MATRIX:
7335: MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);
7336: break;
7337: default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7338: }
7339: if (!iscol) {ISDestroy(&iscoltmp);}
7340: return(0);
7341: }
7343: if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7344: (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);
7345: if (!iscol) {ISDestroy(&iscoltmp);}
7346: if (*newmat && cll == MAT_INITIAL_MATRIX) {PetscObjectStateIncrease((PetscObject)*newmat);}
7347: return(0);
7348: }
7352: /*@
7353: MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7354: used during the assembly process to store values that belong to
7355: other processors.
7357: Not Collective
7359: Input Parameters:
7360: + mat - the matrix
7361: . size - the initial size of the stash.
7362: - bsize - the initial size of the block-stash(if used).
7364: Options Database Keys:
7365: + -matstash_initial_size <size> or <size0,size1,...sizep-1>
7366: - -matstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1>
7368: Level: intermediate
7370: Notes:
7371: The block-stash is used for values set with MatSetValuesBlocked() while
7372: the stash is used for values set with MatSetValues()
7374: Run with the option -info and look for output of the form
7375: MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7376: to determine the appropriate value, MM, to use for size and
7377: MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7378: to determine the value, BMM to use for bsize
7380: Concepts: stash^setting matrix size
7381: Concepts: matrices^stash
7383: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
7385: @*/
7386: PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7387: {
7393: MatStashSetInitialSize_Private(&mat->stash,size);
7394: MatStashSetInitialSize_Private(&mat->bstash,bsize);
7395: return(0);
7396: }
7400: /*@
7401: MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
7402: the matrix
7404: Neighbor-wise Collective on Mat
7406: Input Parameters:
7407: + mat - the matrix
7408: . x,y - the vectors
7409: - w - where the result is stored
7411: Level: intermediate
7413: Notes:
7414: w may be the same vector as y.
7416: This allows one to use either the restriction or interpolation (its transpose)
7417: matrix to do the interpolation
7419: Concepts: interpolation
7421: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7423: @*/
7424: PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7425: {
7427: PetscInt M,N,Ny;
7435: MatCheckPreallocated(A,1);
7436: MatGetSize(A,&M,&N);
7437: VecGetSize(y,&Ny);
7438: if (M == Ny) {
7439: MatMultAdd(A,x,y,w);
7440: } else {
7441: MatMultTransposeAdd(A,x,y,w);
7442: }
7443: return(0);
7444: }
7448: /*@
7449: MatInterpolate - y = A*x or A'*x depending on the shape of
7450: the matrix
7452: Neighbor-wise Collective on Mat
7454: Input Parameters:
7455: + mat - the matrix
7456: - x,y - the vectors
7458: Level: intermediate
7460: Notes:
7461: This allows one to use either the restriction or interpolation (its transpose)
7462: matrix to do the interpolation
7464: Concepts: matrices^interpolation
7466: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7468: @*/
7469: PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
7470: {
7472: PetscInt M,N,Ny;
7479: MatCheckPreallocated(A,1);
7480: MatGetSize(A,&M,&N);
7481: VecGetSize(y,&Ny);
7482: if (M == Ny) {
7483: MatMult(A,x,y);
7484: } else {
7485: MatMultTranspose(A,x,y);
7486: }
7487: return(0);
7488: }
7492: /*@
7493: MatRestrict - y = A*x or A'*x
7495: Neighbor-wise Collective on Mat
7497: Input Parameters:
7498: + mat - the matrix
7499: - x,y - the vectors
7501: Level: intermediate
7503: Notes:
7504: This allows one to use either the restriction or interpolation (its transpose)
7505: matrix to do the restriction
7507: Concepts: matrices^restriction
7509: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
7511: @*/
7512: PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
7513: {
7515: PetscInt M,N,Ny;
7522: MatCheckPreallocated(A,1);
7524: MatGetSize(A,&M,&N);
7525: VecGetSize(y,&Ny);
7526: if (M == Ny) {
7527: MatMult(A,x,y);
7528: } else {
7529: MatMultTranspose(A,x,y);
7530: }
7531: return(0);
7532: }
7536: /*@
7537: MatGetNullSpace - retrieves the null space to a matrix.
7539: Logically Collective on Mat and MatNullSpace
7541: Input Parameters:
7542: + mat - the matrix
7543: - nullsp - the null space object
7545: Level: developer
7547: Notes:
7548: This null space is used by solvers. Overwrites any previous null space that may have been attached
7550: Concepts: null space^attaching to matrix
7552: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace()
7553: @*/
7554: PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
7555: {
7560: *nullsp = mat->nullsp;
7561: return(0);
7562: }
7566: /*@
7567: MatSetNullSpace - attaches a null space to a matrix.
7568: This null space will be removed from the resulting vector whenever
7569: MatMult() is called
7571: Logically Collective on Mat and MatNullSpace
7573: Input Parameters:
7574: + mat - the matrix
7575: - nullsp - the null space object
7577: Level: advanced
7579: Notes:
7580: This null space is used by solvers. Overwrites any previous null space that may have been attached
7582: Concepts: null space^attaching to matrix
7584: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace()
7585: @*/
7586: PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp)
7587: {
7594: MatCheckPreallocated(mat,1);
7595: PetscObjectReference((PetscObject)nullsp);
7596: MatNullSpaceDestroy(&mat->nullsp);
7598: mat->nullsp = nullsp;
7599: return(0);
7600: }
7604: /*@
7605: MatSetNearNullSpace - attaches a null space to a matrix.
7606: This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.
7608: Logically Collective on Mat and MatNullSpace
7610: Input Parameters:
7611: + mat - the matrix
7612: - nullsp - the null space object
7614: Level: advanced
7616: Notes:
7617: Overwrites any previous near null space that may have been attached
7619: Concepts: null space^attaching to matrix
7621: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace()
7622: @*/
7623: PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
7624: {
7631: MatCheckPreallocated(mat,1);
7632: PetscObjectReference((PetscObject)nullsp);
7633: MatNullSpaceDestroy(&mat->nearnullsp);
7635: mat->nearnullsp = nullsp;
7636: return(0);
7637: }
7641: /*@
7642: MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()
7644: Not Collective
7646: Input Parameters:
7647: . mat - the matrix
7649: Output Parameters:
7650: . nullsp - the null space object, NULL if not set
7652: Level: developer
7654: Concepts: null space^attaching to matrix
7656: .seealso: MatSetNearNullSpace(), MatGetNullSpace()
7657: @*/
7658: PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
7659: {
7664: MatCheckPreallocated(mat,1);
7665: *nullsp = mat->nearnullsp;
7666: return(0);
7667: }
7671: /*@C
7672: MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
7674: Collective on Mat
7676: Input Parameters:
7677: + mat - the matrix
7678: . row - row/column permutation
7679: . fill - expected fill factor >= 1.0
7680: - level - level of fill, for ICC(k)
7682: Notes:
7683: Probably really in-place only when level of fill is zero, otherwise allocates
7684: new space to store factored matrix and deletes previous memory.
7686: Most users should employ the simplified KSP interface for linear solvers
7687: instead of working directly with matrix algebra routines such as this.
7688: See, e.g., KSPCreate().
7690: Level: developer
7692: Concepts: matrices^incomplete Cholesky factorization
7693: Concepts: Cholesky factorization
7695: .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
7697: Developer Note: fortran interface is not autogenerated as the f90
7698: interface defintion cannot be generated correctly [due to MatFactorInfo]
7700: @*/
7701: PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
7702: {
7710: if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
7711: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7712: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7713: if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7714: MatCheckPreallocated(mat,1);
7715: (*mat->ops->iccfactor)(mat,row,info);
7716: PetscObjectStateIncrease((PetscObject)mat);
7717: return(0);
7718: }
7722: /*@
7723: MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.
7725: Not Collective
7727: Input Parameters:
7728: + mat - the matrix
7729: . nl - leading dimension of v
7730: - v - the values compute with ADIFOR
7732: Level: developer
7734: Notes:
7735: Must call MatSetColoring() before using this routine. Also this matrix must already
7736: have its nonzero pattern determined.
7738: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7739: MatSetValues(), MatSetColoring()
7740: @*/
7741: PetscErrorCode MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
7742: {
7750: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7751: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
7752: if (!mat->ops->setvaluesadifor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7753: (*mat->ops->setvaluesadifor)(mat,nl,v);
7754: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
7755: PetscObjectStateIncrease((PetscObject)mat);
7756: return(0);
7757: }
7761: /*@
7762: MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
7763: ghosted ones.
7765: Not Collective
7767: Input Parameters:
7768: + mat - the matrix
7769: - diag = the diagonal values, including ghost ones
7771: Level: developer
7773: Notes: Works only for MPIAIJ and MPIBAIJ matrices
7775: .seealso: MatDiagonalScale()
7776: @*/
7777: PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
7778: {
7780: PetscMPIInt size;
7787: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7788: PetscLogEventBegin(MAT_Scale,mat,0,0,0);
7789: MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
7790: if (size == 1) {
7791: PetscInt n,m;
7792: VecGetSize(diag,&n);
7793: MatGetSize(mat,0,&m);
7794: if (m == n) {
7795: MatDiagonalScale(mat,0,diag);
7796: } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
7797: } else {
7798: PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));
7799: }
7800: PetscLogEventEnd(MAT_Scale,mat,0,0,0);
7801: PetscObjectStateIncrease((PetscObject)mat);
7802: return(0);
7803: }
7807: /*@
7808: MatGetInertia - Gets the inertia from a factored matrix
7810: Collective on Mat
7812: Input Parameter:
7813: . mat - the matrix
7815: Output Parameters:
7816: + nneg - number of negative eigenvalues
7817: . nzero - number of zero eigenvalues
7818: - npos - number of positive eigenvalues
7820: Level: advanced
7822: Notes: Matrix must have been factored by MatCholeskyFactor()
7825: @*/
7826: PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
7827: {
7833: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7834: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
7835: if (!mat->ops->getinertia) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7836: (*mat->ops->getinertia)(mat,nneg,nzero,npos);
7837: return(0);
7838: }
7840: /* ----------------------------------------------------------------*/
7843: /*@C
7844: MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
7846: Neighbor-wise Collective on Mat and Vecs
7848: Input Parameters:
7849: + mat - the factored matrix
7850: - b - the right-hand-side vectors
7852: Output Parameter:
7853: . x - the result vectors
7855: Notes:
7856: The vectors b and x cannot be the same. I.e., one cannot
7857: call MatSolves(A,x,x).
7859: Notes:
7860: Most users should employ the simplified KSP interface for linear solvers
7861: instead of working directly with matrix algebra routines such as this.
7862: See, e.g., KSPCreate().
7864: Level: developer
7866: Concepts: matrices^triangular solves
7868: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
7869: @*/
7870: PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
7871: {
7877: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
7878: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7879: if (!mat->rmap->N && !mat->cmap->N) return(0);
7881: if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7882: MatCheckPreallocated(mat,1);
7883: PetscLogEventBegin(MAT_Solves,mat,0,0,0);
7884: (*mat->ops->solves)(mat,b,x);
7885: PetscLogEventEnd(MAT_Solves,mat,0,0,0);
7886: return(0);
7887: }
7891: /*@
7892: MatIsSymmetric - Test whether a matrix is symmetric
7894: Collective on Mat
7896: Input Parameter:
7897: + A - the matrix to test
7898: - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
7900: Output Parameters:
7901: . flg - the result
7903: Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
7905: Level: intermediate
7907: Concepts: matrix^symmetry
7909: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
7910: @*/
7911: PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool *flg)
7912: {
7919: if (!A->symmetric_set) {
7920: if (!A->ops->issymmetric) {
7921: MatType mattype;
7922: MatGetType(A,&mattype);
7923: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7924: }
7925: (*A->ops->issymmetric)(A,tol,flg);
7926: if (!tol) {
7927: A->symmetric_set = PETSC_TRUE;
7928: A->symmetric = *flg;
7929: if (A->symmetric) {
7930: A->structurally_symmetric_set = PETSC_TRUE;
7931: A->structurally_symmetric = PETSC_TRUE;
7932: }
7933: }
7934: } else if (A->symmetric) {
7935: *flg = PETSC_TRUE;
7936: } else if (!tol) {
7937: *flg = PETSC_FALSE;
7938: } else {
7939: if (!A->ops->issymmetric) {
7940: MatType mattype;
7941: MatGetType(A,&mattype);
7942: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7943: }
7944: (*A->ops->issymmetric)(A,tol,flg);
7945: }
7946: return(0);
7947: }
7951: /*@
7952: MatIsHermitian - Test whether a matrix is Hermitian
7954: Collective on Mat
7956: Input Parameter:
7957: + A - the matrix to test
7958: - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
7960: Output Parameters:
7961: . flg - the result
7963: Level: intermediate
7965: Concepts: matrix^symmetry
7967: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
7968: MatIsSymmetricKnown(), MatIsSymmetric()
7969: @*/
7970: PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool *flg)
7971: {
7978: if (!A->hermitian_set) {
7979: if (!A->ops->ishermitian) {
7980: MatType mattype;
7981: MatGetType(A,&mattype);
7982: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7983: }
7984: (*A->ops->ishermitian)(A,tol,flg);
7985: if (!tol) {
7986: A->hermitian_set = PETSC_TRUE;
7987: A->hermitian = *flg;
7988: if (A->hermitian) {
7989: A->structurally_symmetric_set = PETSC_TRUE;
7990: A->structurally_symmetric = PETSC_TRUE;
7991: }
7992: }
7993: } else if (A->hermitian) {
7994: *flg = PETSC_TRUE;
7995: } else if (!tol) {
7996: *flg = PETSC_FALSE;
7997: } else {
7998: if (!A->ops->ishermitian) {
7999: MatType mattype;
8000: MatGetType(A,&mattype);
8001: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8002: }
8003: (*A->ops->ishermitian)(A,tol,flg);
8004: }
8005: return(0);
8006: }
8010: /*@
8011: MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
8013: Not Collective
8015: Input Parameter:
8016: . A - the matrix to check
8018: Output Parameters:
8019: + set - if the symmetric flag is set (this tells you if the next flag is valid)
8020: - flg - the result
8022: Level: advanced
8024: Concepts: matrix^symmetry
8026: Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
8027: if you want it explicitly checked
8029: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8030: @*/
8031: PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool *set,PetscBool *flg)
8032: {
8037: if (A->symmetric_set) {
8038: *set = PETSC_TRUE;
8039: *flg = A->symmetric;
8040: } else {
8041: *set = PETSC_FALSE;
8042: }
8043: return(0);
8044: }
8048: /*@
8049: MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
8051: Not Collective
8053: Input Parameter:
8054: . A - the matrix to check
8056: Output Parameters:
8057: + set - if the hermitian flag is set (this tells you if the next flag is valid)
8058: - flg - the result
8060: Level: advanced
8062: Concepts: matrix^symmetry
8064: Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8065: if you want it explicitly checked
8067: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8068: @*/
8069: PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg)
8070: {
8075: if (A->hermitian_set) {
8076: *set = PETSC_TRUE;
8077: *flg = A->hermitian;
8078: } else {
8079: *set = PETSC_FALSE;
8080: }
8081: return(0);
8082: }
8086: /*@
8087: MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
8089: Collective on Mat
8091: Input Parameter:
8092: . A - the matrix to test
8094: Output Parameters:
8095: . flg - the result
8097: Level: intermediate
8099: Concepts: matrix^symmetry
8101: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8102: @*/
8103: PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg)
8104: {
8110: if (!A->structurally_symmetric_set) {
8111: if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8112: (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);
8114: A->structurally_symmetric_set = PETSC_TRUE;
8115: }
8116: *flg = A->structurally_symmetric;
8117: return(0);
8118: }
8122: extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
8123: /*@
8124: MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8125: to be communicated to other processors during the MatAssemblyBegin/End() process
8127: Not collective
8129: Input Parameter:
8130: . vec - the vector
8132: Output Parameters:
8133: + nstash - the size of the stash
8134: . reallocs - the number of additional mallocs incurred.
8135: . bnstash - the size of the block stash
8136: - breallocs - the number of additional mallocs incurred.in the block stash
8138: Level: advanced
8140: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
8142: @*/
8143: PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8144: {
8148: MatStashGetInfo_Private(&mat->stash,nstash,reallocs);
8149: MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);
8150: return(0);
8151: }
8155: /*@C
8156: MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same
8157: parallel layout
8159: Collective on Mat
8161: Input Parameter:
8162: . mat - the matrix
8164: Output Parameter:
8165: + right - (optional) vector that the matrix can be multiplied against
8166: - left - (optional) vector that the matrix vector product can be stored in
8168: Level: advanced
8170: .seealso: MatCreate()
8171: @*/
8172: PetscErrorCode MatGetVecs(Mat mat,Vec *right,Vec *left)
8173: {
8179: MatCheckPreallocated(mat,1);
8180: if (mat->ops->getvecs) {
8181: (*mat->ops->getvecs)(mat,right,left);
8182: } else {
8183: PetscMPIInt size;
8184: PetscInt rbs,cbs;
8185: MPI_Comm_size(PetscObjectComm((PetscObject)mat), &size);
8186: MatGetBlockSizes(mat,&rbs,&cbs);
8187: if (right) {
8188: VecCreate(PetscObjectComm((PetscObject)mat),right);
8189: VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);
8190: VecSetBlockSize(*right,cbs);
8191: VecSetType(*right,VECSTANDARD);
8192: PetscLayoutReference(mat->cmap,&(*right)->map);
8193: }
8194: if (left) {
8195: VecCreate(PetscObjectComm((PetscObject)mat),left);
8196: VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);
8197: VecSetBlockSize(*left,rbs);
8198: VecSetType(*left,VECSTANDARD);
8199: PetscLayoutReference(mat->rmap,&(*left)->map);
8200: }
8201: }
8202: return(0);
8203: }
8207: /*@C
8208: MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8209: with default values.
8211: Not Collective
8213: Input Parameters:
8214: . info - the MatFactorInfo data structure
8217: Notes: The solvers are generally used through the KSP and PC objects, for example
8218: PCLU, PCILU, PCCHOLESKY, PCICC
8220: Level: developer
8222: .seealso: MatFactorInfo
8224: Developer Note: fortran interface is not autogenerated as the f90
8225: interface defintion cannot be generated correctly [due to MatFactorInfo]
8227: @*/
8229: PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
8230: {
8234: PetscMemzero(info,sizeof(MatFactorInfo));
8235: return(0);
8236: }
8240: /*@
8241: MatPtAP - Creates the matrix product C = P^T * A * P
8243: Neighbor-wise Collective on Mat
8245: Input Parameters:
8246: + A - the matrix
8247: . P - the projection matrix
8248: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8249: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P))
8251: Output Parameters:
8252: . C - the product matrix
8254: Notes:
8255: C will be created and must be destroyed by the user with MatDestroy().
8257: This routine is currently only implemented for pairs of AIJ matrices and classes
8258: which inherit from AIJ.
8260: Level: intermediate
8262: .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
8263: @*/
8264: PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
8265: {
8267: PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8268: PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
8269: PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
8270: PetscBool viatranspose=PETSC_FALSE,viamatmatmatmult=PETSC_FALSE;
8273: PetscOptionsGetBool(((PetscObject)A)->prefix,"-matptap_viatranspose",&viatranspose,NULL);
8274: PetscOptionsGetBool(((PetscObject)A)->prefix,"-matptap_viamatmatmatmult",&viamatmatmatmult,NULL);
8278: MatCheckPreallocated(A,1);
8279: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8280: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8283: MatCheckPreallocated(P,2);
8284: if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8285: if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8287: if (P->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
8288: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
8290: if (scall == MAT_REUSE_MATRIX) {
8293: if (viatranspose || viamatmatmatmult) {
8294: Mat Pt;
8295: MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);
8296: if (viamatmatmatmult) {
8297: MatMatMatMult(Pt,A,P,scall,fill,C);
8298: } else {
8299: Mat AP;
8300: MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);
8301: MatMatMult(Pt,AP,scall,fill,C);
8302: MatDestroy(&AP);
8303: }
8304: MatDestroy(&Pt);
8305: } else {
8306: PetscLogEventBegin(MAT_PtAP,A,P,0,0);
8307: PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
8308: (*(*C)->ops->ptapnumeric)(A,P,*C);
8309: PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
8310: PetscLogEventEnd(MAT_PtAP,A,P,0,0);
8311: }
8312: return(0);
8313: }
8315: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8316: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
8318: fA = A->ops->ptap;
8319: fP = P->ops->ptap;
8320: if (fP == fA) {
8321: if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name);
8322: ptap = fA;
8323: } else {
8324: /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
8325: char ptapname[256];
8326: PetscStrcpy(ptapname,"MatPtAP_");
8327: PetscStrcat(ptapname,((PetscObject)A)->type_name);
8328: PetscStrcat(ptapname,"_");
8329: PetscStrcat(ptapname,((PetscObject)P)->type_name);
8330: PetscStrcat(ptapname,"_C"); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
8331: PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);
8332: if (!ptap) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatPtAP requires A, %s, to be compatible with P, %s",((PetscObject)A)->type_name,((PetscObject)P)->type_name);
8333: }
8335: if (viatranspose || viamatmatmatmult) {
8336: Mat Pt;
8337: MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);
8338: if (viamatmatmatmult) {
8339: MatMatMatMult(Pt,A,P,scall,fill,C);
8340: PetscInfo(*C,"MatPtAP via MatMatMatMult\n");
8341: } else {
8342: Mat AP;
8343: MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);
8344: MatMatMult(Pt,AP,scall,fill,C);
8345: MatDestroy(&AP);
8346: PetscInfo(*C,"MatPtAP via MatTranspose and MatMatMult\n");
8347: }
8348: MatDestroy(&Pt);
8349: } else {
8350: PetscLogEventBegin(MAT_PtAP,A,P,0,0);
8351: (*ptap)(A,P,scall,fill,C);
8352: PetscLogEventEnd(MAT_PtAP,A,P,0,0);
8353: }
8354: return(0);
8355: }
8359: /*@
8360: MatPtAPNumeric - Computes the matrix product C = P^T * A * P
8362: Neighbor-wise Collective on Mat
8364: Input Parameters:
8365: + A - the matrix
8366: - P - the projection matrix
8368: Output Parameters:
8369: . C - the product matrix
8371: Notes:
8372: C must have been created by calling MatPtAPSymbolic and must be destroyed by
8373: the user using MatDeatroy().
8375: This routine is currently only implemented for pairs of AIJ matrices and classes
8376: which inherit from AIJ. C will be of type MATAIJ.
8378: Level: intermediate
8380: .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
8381: @*/
8382: PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C)
8383: {
8389: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8390: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8393: MatCheckPreallocated(P,2);
8394: if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8395: if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8398: MatCheckPreallocated(C,3);
8399: if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8400: if (P->cmap->N!=C->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->rmap->N);
8401: if (P->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
8402: if (A->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
8403: if (P->cmap->N!=C->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->cmap->N);
8404: MatCheckPreallocated(A,1);
8406: PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
8407: (*C->ops->ptapnumeric)(A,P,C);
8408: PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
8409: return(0);
8410: }
8414: /*@
8415: MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P
8417: Neighbor-wise Collective on Mat
8419: Input Parameters:
8420: + A - the matrix
8421: - P - the projection matrix
8423: Output Parameters:
8424: . C - the (i,j) structure of the product matrix
8426: Notes:
8427: C will be created and must be destroyed by the user with MatDestroy().
8429: This routine is currently only implemented for pairs of SeqAIJ matrices and classes
8430: which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using
8431: this (i,j) structure by calling MatPtAPNumeric().
8433: Level: intermediate
8435: .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
8436: @*/
8437: PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
8438: {
8444: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8445: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8446: if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
8449: MatCheckPreallocated(P,2);
8450: if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8451: if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8454: if (P->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
8455: if (A->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
8456: MatCheckPreallocated(A,1);
8457: PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);
8458: (*A->ops->ptapsymbolic)(A,P,fill,C);
8459: PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);
8461: /* MatSetBlockSize(*C,A->rmap->bs); NO! this is not always true -ma */
8462: return(0);
8463: }
8467: /*@
8468: MatRARt - Creates the matrix product C = R * A * R^T
8470: Neighbor-wise Collective on Mat
8472: Input Parameters:
8473: + A - the matrix
8474: . R - the projection matrix
8475: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8476: - fill - expected fill as ratio of nnz(C)/nnz(A)
8478: Output Parameters:
8479: . C - the product matrix
8481: Notes:
8482: C will be created and must be destroyed by the user with MatDestroy().
8484: This routine is currently only implemented for pairs of AIJ matrices and classes
8485: which inherit from AIJ.
8487: Level: intermediate
8489: .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
8490: @*/
8491: PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
8492: {
8498: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8499: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8502: MatCheckPreallocated(R,2);
8503: if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8504: if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8506: if (R->cmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)R),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N);
8507: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
8508: MatCheckPreallocated(A,1);
8510: if (!A->ops->rart) {
8511: MatType mattype;
8512: MatGetType(A,&mattype);
8513: SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix of type <%s> does not support RARt",mattype);
8514: }
8515: PetscLogEventBegin(MAT_RARt,A,R,0,0);
8516: (*A->ops->rart)(A,R,scall,fill,C);
8517: PetscLogEventEnd(MAT_RARt,A,R,0,0);
8518: return(0);
8519: }
8523: /*@
8524: MatRARtNumeric - Computes the matrix product C = R * A * R^T
8526: Neighbor-wise Collective on Mat
8528: Input Parameters:
8529: + A - the matrix
8530: - R - the projection matrix
8532: Output Parameters:
8533: . C - the product matrix
8535: Notes:
8536: C must have been created by calling MatRARtSymbolic and must be destroyed by
8537: the user using MatDeatroy().
8539: This routine is currently only implemented for pairs of AIJ matrices and classes
8540: which inherit from AIJ. C will be of type MATAIJ.
8542: Level: intermediate
8544: .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
8545: @*/
8546: PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C)
8547: {
8553: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8554: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8557: MatCheckPreallocated(R,2);
8558: if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8559: if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8562: MatCheckPreallocated(C,3);
8563: if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8564: if (R->rmap->N!=C->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->rmap->N,C->rmap->N);
8565: if (R->cmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N);
8566: if (A->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
8567: if (R->rmap->N!=C->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->rmap->N,C->cmap->N);
8568: MatCheckPreallocated(A,1);
8570: PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);
8571: (*A->ops->rartnumeric)(A,R,C);
8572: PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);
8573: return(0);
8574: }
8578: /*@
8579: MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T
8581: Neighbor-wise Collective on Mat
8583: Input Parameters:
8584: + A - the matrix
8585: - R - the projection matrix
8587: Output Parameters:
8588: . C - the (i,j) structure of the product matrix
8590: Notes:
8591: C will be created and must be destroyed by the user with MatDestroy().
8593: This routine is currently only implemented for pairs of SeqAIJ matrices and classes
8594: which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using
8595: this (i,j) structure by calling MatRARtNumeric().
8597: Level: intermediate
8599: .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
8600: @*/
8601: PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
8602: {
8608: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8609: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8610: if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
8613: MatCheckPreallocated(R,2);
8614: if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8615: if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8618: if (R->cmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N);
8619: if (A->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
8620: MatCheckPreallocated(A,1);
8621: PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);
8622: (*A->ops->rartsymbolic)(A,R,fill,C);
8623: PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);
8625: MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));
8626: return(0);
8627: }
8631: /*@
8632: MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
8634: Neighbor-wise Collective on Mat
8636: Input Parameters:
8637: + A - the left matrix
8638: . B - the right matrix
8639: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8640: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
8641: if the result is a dense matrix this is irrelevent
8643: Output Parameters:
8644: . C - the product matrix
8646: Notes:
8647: Unless scall is MAT_REUSE_MATRIX C will be created.
8649: MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8651: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8652: actually needed.
8654: If you have many matrices with the same non-zero structure to multiply, you
8655: should either
8656: $ 1) use MAT_REUSE_MATRIX in all calls but the first or
8657: $ 2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
8659: Level: intermediate
8661: .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(), MatMatTransposeMult(), MatPtAP()
8662: @*/
8663: PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8664: {
8666: PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8667: PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8668: PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
8673: MatCheckPreallocated(A,1);
8674: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8675: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8678: MatCheckPreallocated(B,2);
8679: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8680: if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8682: if (B->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
8683: if (scall == MAT_REUSE_MATRIX) {
8686: PetscLogEventBegin(MAT_MatMult,A,B,0,0);
8687: PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);
8688: (*(*C)->ops->matmultnumeric)(A,B,*C);
8689: PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);
8690: PetscLogEventEnd(MAT_MatMult,A,B,0,0);
8691: return(0);
8692: }
8693: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8694: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
8696: fA = A->ops->matmult;
8697: fB = B->ops->matmult;
8698: if (fB == fA) {
8699: if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
8700: mult = fB;
8701: } else {
8702: /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
8703: char multname[256];
8704: PetscStrcpy(multname,"MatMatMult_");
8705: PetscStrcat(multname,((PetscObject)A)->type_name);
8706: PetscStrcat(multname,"_");
8707: PetscStrcat(multname,((PetscObject)B)->type_name);
8708: PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
8709: PetscObjectQueryFunction((PetscObject)B,multname,&mult);
8710: if (!mult) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
8711: }
8712: PetscLogEventBegin(MAT_MatMult,A,B,0,0);
8713: (*mult)(A,B,scall,fill,C);
8714: PetscLogEventEnd(MAT_MatMult,A,B,0,0);
8715: return(0);
8716: }
8720: /*@
8721: MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
8722: of the matrix-matrix product C=A*B. Call this routine before calling MatMatMultNumeric().
8724: Neighbor-wise Collective on Mat
8726: Input Parameters:
8727: + A - the left matrix
8728: . B - the right matrix
8729: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
8730: if C is a dense matrix this is irrelevent
8732: Output Parameters:
8733: . C - the product matrix
8735: Notes:
8736: Unless scall is MAT_REUSE_MATRIX C will be created.
8738: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8739: actually needed.
8741: This routine is currently implemented for
8742: - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
8743: - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8744: - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
8746: Level: intermediate
8748: Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
8749: We should incorporate them into PETSc.
8751: .seealso: MatMatMult(), MatMatMultNumeric()
8752: @*/
8753: PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
8754: {
8756: PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*);
8757: PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*);
8758: PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL;
8763: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8764: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8768: MatCheckPreallocated(B,2);
8769: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8770: if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8773: if (B->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
8774: if (fill == PETSC_DEFAULT) fill = 2.0;
8775: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
8776: MatCheckPreallocated(A,1);
8778: Asymbolic = A->ops->matmultsymbolic;
8779: Bsymbolic = B->ops->matmultsymbolic;
8780: if (Asymbolic == Bsymbolic) {
8781: if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
8782: symbolic = Bsymbolic;
8783: } else { /* dispatch based on the type of A and B */
8784: char symbolicname[256];
8785: PetscStrcpy(symbolicname,"MatMatMultSymbolic_");
8786: PetscStrcat(symbolicname,((PetscObject)A)->type_name);
8787: PetscStrcat(symbolicname,"_");
8788: PetscStrcat(symbolicname,((PetscObject)B)->type_name);
8789: PetscStrcat(symbolicname,"_C");
8790: PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);
8791: if (!symbolic) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatMultSymbolic requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
8792: }
8793: PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);
8794: (*symbolic)(A,B,fill,C);
8795: PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);
8796: return(0);
8797: }
8801: /*@
8802: MatMatMultNumeric - Performs the numeric matrix-matrix product.
8803: Call this routine after first calling MatMatMultSymbolic().
8805: Neighbor-wise Collective on Mat
8807: Input Parameters:
8808: + A - the left matrix
8809: - B - the right matrix
8811: Output Parameters:
8812: . C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
8814: Notes:
8815: C must have been created with MatMatMultSymbolic().
8817: This routine is currently implemented for
8818: - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
8819: - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8820: - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
8822: Level: intermediate
8824: .seealso: MatMatMult(), MatMatMultSymbolic()
8825: @*/
8826: PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C)
8827: {
8831: MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);
8832: return(0);
8833: }
8837: /*@
8838: MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.
8840: Neighbor-wise Collective on Mat
8842: Input Parameters:
8843: + A - the left matrix
8844: . B - the right matrix
8845: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8846: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
8848: Output Parameters:
8849: . C - the product matrix
8851: Notes:
8852: C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
8854: MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8856: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8857: actually needed.
8859: This routine is currently only implemented for pairs of SeqAIJ matrices. C will be of type MATSEQAIJ.
8861: Level: intermediate
8863: .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
8864: @*/
8865: PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8866: {
8868: PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8869: PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8874: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8875: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8878: MatCheckPreallocated(B,2);
8879: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8880: if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8882: if (B->cmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, AN %D != BN %D",A->cmap->N,B->cmap->N);
8883: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8884: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
8885: MatCheckPreallocated(A,1);
8887: fA = A->ops->mattransposemult;
8888: if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
8889: fB = B->ops->mattransposemult;
8890: if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
8891: if (fB!=fA) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatTransposeMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
8893: PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);
8894: if (scall == MAT_INITIAL_MATRIX) {
8895: PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);
8896: (*A->ops->mattransposemultsymbolic)(A,B,fill,C);
8897: PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);
8898: }
8899: PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);
8900: (*A->ops->mattransposemultnumeric)(A,B,*C);
8901: PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);
8902: PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);
8903: return(0);
8904: }
8908: /*@
8909: MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.
8911: Neighbor-wise Collective on Mat
8913: Input Parameters:
8914: + A - the left matrix
8915: . B - the right matrix
8916: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8917: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
8919: Output Parameters:
8920: . C - the product matrix
8922: Notes:
8923: C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
8925: MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8927: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8928: actually needed.
8930: This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
8931: which inherit from SeqAIJ. C will be of same type as the input matrices.
8933: Level: intermediate
8935: .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
8936: @*/
8937: PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8938: {
8940: PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8941: PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8942: PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL;
8947: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8948: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8951: MatCheckPreallocated(B,2);
8952: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8953: if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8955: if (B->rmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->rmap->N);
8956: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8957: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
8958: MatCheckPreallocated(A,1);
8960: fA = A->ops->transposematmult;
8961: fB = B->ops->transposematmult;
8962: if (fB==fA) {
8963: if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
8964: transposematmult = fA;
8965: } else {
8966: /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
8967: char multname[256];
8968: PetscStrcpy(multname,"MatTransposeMatMult_");
8969: PetscStrcat(multname,((PetscObject)A)->type_name);
8970: PetscStrcat(multname,"_");
8971: PetscStrcat(multname,((PetscObject)B)->type_name);
8972: PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
8973: PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);
8974: if (!transposematmult) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatTransposeMatMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
8975: }
8976: PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);
8977: (*transposematmult)(A,B,scall,fill,C);
8978: PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);
8979: return(0);
8980: }
8984: /*@
8985: MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.
8987: Neighbor-wise Collective on Mat
8989: Input Parameters:
8990: + A - the left matrix
8991: . B - the middle matrix
8992: . C - the right matrix
8993: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8994: - fill - expected fill as ratio of nnz(D)/(nnz(A) + nnz(B)+nnz(C)), use PETSC_DEFAULT if you do not have a good estimate
8995: if the result is a dense matrix this is irrelevent
8997: Output Parameters:
8998: . D - the product matrix
9000: Notes:
9001: Unless scall is MAT_REUSE_MATRIX D will be created.
9003: MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call
9005: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9006: actually needed.
9008: If you have many matrices with the same non-zero structure to multiply, you
9009: should either
9010: $ 1) use MAT_REUSE_MATRIX in all calls but the first or
9011: $ 2) call MatMatMatMultSymbolic() once and then MatMatMatMultNumeric() for each product needed
9013: Level: intermediate
9015: .seealso: MatMatMult, MatPtAP()
9016: @*/
9017: PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
9018: {
9020: PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9021: PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9022: PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9023: PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9028: MatCheckPreallocated(A,1);
9029: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9030: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9033: MatCheckPreallocated(B,2);
9034: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9035: if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9038: MatCheckPreallocated(C,3);
9039: if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9040: if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9041: if (B->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
9042: if (C->rmap->N!=B->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",C->rmap->N,B->cmap->N);
9043: if (scall == MAT_REUSE_MATRIX) {
9046: PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);
9047: (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);
9048: PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);
9049: return(0);
9050: }
9051: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9052: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9054: fA = A->ops->matmatmult;
9055: fB = B->ops->matmatmult;
9056: fC = C->ops->matmatmult;
9057: if (fA == fB && fA == fC) {
9058: if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9059: mult = fA;
9060: } else {
9061: /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */
9062: char multname[256];
9063: PetscStrcpy(multname,"MatMatMatMult_");
9064: PetscStrcat(multname,((PetscObject)A)->type_name);
9065: PetscStrcat(multname,"_");
9066: PetscStrcat(multname,((PetscObject)B)->type_name);
9067: PetscStrcat(multname,"_");
9068: PetscStrcat(multname,((PetscObject)C)->type_name);
9069: PetscStrcat(multname,"_C");
9070: PetscObjectQueryFunction((PetscObject)B,multname,&mult);
9071: if (!mult) SETERRQ3(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatMatMult requires A, %s, to be compatible with B, %s, C, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name,((PetscObject)C)->type_name);
9072: }
9073: PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);
9074: (*mult)(A,B,C,scall,fill,D);
9075: PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);
9076: return(0);
9077: }
9081: /*@C
9082: MatGetRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
9084: Collective on Mat
9086: Input Parameters:
9087: + mat - the matrix
9088: . nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
9089: . subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used)
9090: - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9092: Output Parameter:
9093: . matredundant - redundant matrix
9095: Notes:
9096: MAT_REUSE_MATRIX can only be used when the nonzero structure of the
9097: original matrix has not changed from that last call to MatGetRedundantMatrix().
9099: This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
9100: calling it.
9102: Only MPIAIJ matrix is supported.
9104: Level: advanced
9106: Concepts: subcommunicator
9107: Concepts: duplicate matrix
9109: .seealso: MatDestroy()
9110: @*/
9111: PetscErrorCode MatGetRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant)
9112: {
9117: if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
9120: }
9121: if (!mat->ops->getredundantmatrix) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
9122: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9123: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9124: MatCheckPreallocated(mat,1);
9126: PetscLogEventBegin(MAT_GetRedundantMatrix,mat,0,0,0);
9127: (*mat->ops->getredundantmatrix)(mat,nsubcomm,subcomm,reuse,matredundant);
9128: PetscLogEventEnd(MAT_GetRedundantMatrix,mat,0,0,0);
9129: return(0);
9130: }
9134: /*@C
9135: MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
9136: a given 'mat' object. Each submatrix can span multiple procs.
9138: Collective on Mat
9140: Input Parameters:
9141: + mat - the matrix
9142: . subcomm - the subcommunicator obtained by com_split(comm)
9143: - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9145: Output Parameter:
9146: . subMat - 'parallel submatrices each spans a given subcomm
9148: Notes:
9149: The submatrix partition across processors is dictated by 'subComm' a
9150: communicator obtained by com_split(comm). The comm_split
9151: is not restriced to be grouped with consecutive original ranks.
9153: Due the comm_split() usage, the parallel layout of the submatrices
9154: map directly to the layout of the original matrix [wrt the local
9155: row,col partitioning]. So the original 'DiagonalMat' naturally maps
9156: into the 'DiagonalMat' of the subMat, hence it is used directly from
9157: the subMat. However the offDiagMat looses some columns - and this is
9158: reconstructed with MatSetValues()
9160: Level: advanced
9162: Concepts: subcommunicator
9163: Concepts: submatrices
9165: .seealso: MatGetSubMatrices()
9166: @*/
9167: PetscErrorCode MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
9168: {
9170: PetscMPIInt commsize,subCommSize;
9173: MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);
9174: MPI_Comm_size(subComm,&subCommSize);
9175: if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
9177: PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);
9178: (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);
9179: PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);
9180: return(0);
9181: }
9185: /*@
9186: MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
9188: Not Collective
9190: Input Arguments:
9191: mat - matrix to extract local submatrix from
9192: isrow - local row indices for submatrix
9193: iscol - local column indices for submatrix
9195: Output Arguments:
9196: submat - the submatrix
9198: Level: intermediate
9200: Notes:
9201: The submat should be returned with MatRestoreLocalSubMatrix().
9203: Depending on the format of mat, the returned submat may not implement MatMult(). Its communicator may be
9204: the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
9206: The submat always implements MatSetValuesLocal(). If isrow and iscol have the same block size, then
9207: MatSetValuesBlockedLocal() will also be implemented.
9209: .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef()
9210: @*/
9211: PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9212: {
9222: if (mat->ops->getlocalsubmatrix) {
9223: (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);
9224: } else {
9225: MatCreateLocalRef(mat,isrow,iscol,submat);
9226: }
9227: return(0);
9228: }
9232: /*@
9233: MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
9235: Not Collective
9237: Input Arguments:
9238: mat - matrix to extract local submatrix from
9239: isrow - local row indices for submatrix
9240: iscol - local column indices for submatrix
9241: submat - the submatrix
9243: Level: intermediate
9245: .seealso: MatGetLocalSubMatrix()
9246: @*/
9247: PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9248: {
9257: if (*submat) {
9259: }
9261: if (mat->ops->restorelocalsubmatrix) {
9262: (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);
9263: } else {
9264: MatDestroy(submat);
9265: }
9266: *submat = NULL;
9267: return(0);
9268: }
9270: /* --------------------------------------------------------*/
9273: /*@
9274: MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no entry in the matrix
9276: Collective on Mat
9278: Input Parameter:
9279: . mat - the matrix
9281: Output Parameter:
9282: . is - if any rows have zero diagonals this contains the list of them
9284: Level: developer
9286: Concepts: matrix-vector product
9288: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
9289: @*/
9290: PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is)
9291: {
9297: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9298: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9300: if (!mat->ops->findzerodiagonals) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find zero diagonals defined");
9301: (*mat->ops->findzerodiagonals)(mat,is);
9302: return(0);
9303: }
9307: /*@
9308: MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size)
9310: Collective on Mat
9312: Input Parameter:
9313: . mat - the matrix
9315: Output Parameter:
9316: . is - contains the list of rows with off block diagonal entries
9318: Level: developer
9320: Concepts: matrix-vector product
9322: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
9323: @*/
9324: PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is)
9325: {
9331: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9332: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9334: if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined");
9335: (*mat->ops->findoffblockdiagonalentries)(mat,is);
9336: return(0);
9337: }
9341: /*@C
9342: MatInvertBlockDiagonal - Inverts the block diagonal entries.
9344: Collective on Mat
9346: Input Parameters:
9347: . mat - the matrix
9349: Output Parameters:
9350: . values - the block inverses in column major order (FORTRAN-like)
9352: Note:
9353: This routine is not available from Fortran.
9355: Level: advanced
9356: @*/
9357: PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
9358: {
9363: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9364: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9365: if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
9366: (*mat->ops->invertblockdiagonal)(mat,values);
9367: return(0);
9368: }
9372: /*@C
9373: MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
9374: via MatTransposeColoringCreate().
9376: Collective on MatTransposeColoring
9378: Input Parameter:
9379: . c - coloring context
9381: Level: intermediate
9383: .seealso: MatTransposeColoringCreate()
9384: @*/
9385: PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c)
9386: {
9387: PetscErrorCode ierr;
9388: MatTransposeColoring matcolor=*c;
9391: if (!matcolor) return(0);
9392: if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; return(0);}
9394: PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);
9395: PetscFree(matcolor->rows);
9396: PetscFree(matcolor->den2sp);
9397: PetscFree(matcolor->colorforcol);
9398: PetscFree(matcolor->columns);
9399: if (matcolor->brows>0) {
9400: PetscFree(matcolor->lstart);
9401: }
9402: PetscHeaderDestroy(c);
9403: return(0);
9404: }
9408: /*@C
9409: MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
9410: a MatTransposeColoring context has been created, computes a dense B^T by Apply
9411: MatTransposeColoring to sparse B.
9413: Collective on MatTransposeColoring
9415: Input Parameters:
9416: + B - sparse matrix B
9417: . Btdense - symbolic dense matrix B^T
9418: - coloring - coloring context created with MatTransposeColoringCreate()
9420: Output Parameter:
9421: . Btdense - dense matrix B^T
9423: Options Database Keys:
9424: + -mat_transpose_coloring_view - Activates basic viewing or coloring
9425: . -mat_transpose_coloring_view_draw - Activates drawing of coloring
9426: - -mat_transpose_coloring_view_info - Activates viewing of coloring info
9428: Level: intermediate
9430: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy()
9432: .keywords: coloring
9433: @*/
9434: PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
9435: {
9443: if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
9444: (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);
9445: return(0);
9446: }
9450: /*@C
9451: MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
9452: a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
9453: in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
9454: Csp from Cden.
9456: Collective on MatTransposeColoring
9458: Input Parameters:
9459: + coloring - coloring context created with MatTransposeColoringCreate()
9460: - Cden - matrix product of a sparse matrix and a dense matrix Btdense
9462: Output Parameter:
9463: . Csp - sparse matrix
9465: Options Database Keys:
9466: + -mat_multtranspose_coloring_view - Activates basic viewing or coloring
9467: . -mat_multtranspose_coloring_view_draw - Activates drawing of coloring
9468: - -mat_multtranspose_coloring_view_info - Activates viewing of coloring info
9470: Level: intermediate
9472: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()
9474: .keywords: coloring
9475: @*/
9476: PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
9477: {
9485: if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
9486: (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);
9487: return(0);
9488: }
9492: /*@C
9493: MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.
9495: Collective on Mat
9497: Input Parameters:
9498: + mat - the matrix product C
9499: - iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring()
9501: Output Parameter:
9502: . color - the new coloring context
9504: Level: intermediate
9506: .seealso: MatTransposeColoringDestroy(), MatTransposeColoringSetFromOptions(), MatTransColoringApplySpToDen(),
9507: MatTransColoringApplyDenToSp(), MatTransposeColoringView(),
9508: @*/
9509: PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
9510: {
9511: MatTransposeColoring c;
9512: MPI_Comm comm;
9513: PetscErrorCode ierr;
9516: PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);
9517: PetscObjectGetComm((PetscObject)mat,&comm);
9518: PetscHeaderCreate(c,_p_MatTransposeColoring,int,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,0);
9520: c->ctype = iscoloring->ctype;
9521: if (mat->ops->transposecoloringcreate) {
9522: (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);
9523: } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type");
9525: *color = c;
9526: PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);
9527: return(0);
9528: }
9532: /*@
9533: MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the
9534: matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the
9535: same, otherwise it will be larger
9537: Not Collective
9539: Input Parameter:
9540: . A - the matrix
9542: Output Parameter:
9543: . state - the current state
9545: Notes: You can only compare states from two different calls to the SAME matrix, you cannot compare calls between
9546: different matrices
9548: Level: intermediate
9550: @*/
9551: PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state)
9552: {
9554: *state = mat->nonzerostate;
9555: return(0);
9556: }